<?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: Faruk Nasir</title>
    <description>The latest articles on DEV Community by Faruk Nasir (@frknasir).</description>
    <link>https://dev.to/frknasir</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%2F98258%2Fcf16a777-ff4e-464b-8cd4-5be49e5c42c1.png</url>
      <title>DEV Community: Faruk Nasir</title>
      <link>https://dev.to/frknasir</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/frknasir"/>
    <language>en</language>
    <item>
      <title>Laravel 9.0: An Exhaustive Rundown Of What Is To Be Expected</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Wed, 19 Jan 2022 21:37:19 +0000</pubDate>
      <link>https://dev.to/frknasir/laravel-90-an-exhaustive-rundown-of-what-is-to-be-expected-6jk</link>
      <guid>https://dev.to/frknasir/laravel-90-an-exhaustive-rundown-of-what-is-to-be-expected-6jk</guid>
      <description>&lt;p&gt;The Laravel release cycle was updated to include one major release every year. Due to this change, Laravel 9––the next LTS version of Laravel––was expected to be released in September of 2021.&lt;/p&gt;

&lt;p&gt;That didn't happen.&lt;/p&gt;

&lt;p&gt;Taylor wrote in the Laravel blog that the Laravel team had decided to postpone the release of Laravel 9 to early 2022––couple of months after the release of Symphony 6.0––as that will allow them to upgrade the underlying Symphony components utilised by Laravel. Otherwise, they'd have to wait until September of 2022 for such upgrade. This means that we should expect the release of L10 in January of 2023.&lt;/p&gt;

&lt;p&gt;With L9 release nearly on us, I've decided to put together all that is contained within so far.&lt;/p&gt;

&lt;p&gt;PHP8.0: The Minimum Version of PHP For Laravel 9 Applications&lt;br&gt;
Symphony components will be updated to version 6.0 in L9. The minimum supported version of php in Symphony 6.0 is 8.0. So, automatically, the minimum supported version of PHP in L9 will, also, be 8.0.&lt;/p&gt;

&lt;p&gt;A Slick Upgrade For php artisan route:list&lt;br&gt;
route:list is that artisan command that allows for quick navigation of all routes in the terminal. But, If you have used it before, you'd agree with me that it's really been short in the navigation aspect, especially, on smaller screens. Routes are, extremely, difficult to spot––and that, single-handedly, defeats it's purpose.&lt;/p&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%2Ffwev1kw04cajedj4lobv.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%2Ffwev1kw04cajedj4lobv.png" alt="original route list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;L9 ships with a smooth upgrade that changes––for the better––how the routes are displayed. The new route:list command can be ran in two modes: default and verbose.&lt;/p&gt;

&lt;p&gt;To run in the default, use the same old syntax: php artisan route:list. This will display the routes beautifully in a table of columns: method, domain@uri and action. And, it is designed to be, truly, responsive even in smaller screens. To ensure the responsiveness, actions with long names are truncated.&lt;/p&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%2F3gm1ngojto5a7un1ay3q.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%2F3gm1ngojto5a7un1ay3q.png" alt="new route list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The verbose mode is activated by appending -v at the end of the default command. It should look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;php artisan route:list -v
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the verbose mode, in addition to the method, domain@uri and action, two more columns are displayed: name and middleware and no column is truncated. Even the verbose mode is far better than the old display.&lt;/p&gt;

&lt;p&gt;No changes in behaviour in all the options(sort, json etc) of the old command except with columns and compact that have been removed entirely.&lt;/p&gt;

&lt;p&gt;There is a breaking change introduced with this make-over. Read all about it here .&lt;/p&gt;

&lt;p&gt;L8's Anonymous Stub Migration Will Become The Default&lt;br&gt;
The release of Laravel 8.37 came with anonymous migration support.&lt;/p&gt;

&lt;p&gt;Imagine––during the course of your application development––you create an add_tags_column_to_post_table migration. In a following version, you decide to remove the tags column with a migration file remove_tags_column_to_post_table. In a future version, due to a change in requirements, you decide to put back the tags column using the migration file add_tags_column_to_post_table.&lt;/p&gt;

&lt;p&gt;Notice that the first and third migration files' names are the same.&lt;/p&gt;

&lt;p&gt;At this point of the migration history, running it is hardly a walk-in-the-park––as it should be, unless, you are running it––in a newly created database, while running tests or in an application that is well-tested. The most trouble is for large applications with quite a number of years in development that are poorly tested. This is the problem that Anonymous Migrations solves.&lt;/p&gt;

&lt;p&gt;In L9, it will replace the old way migration was handled. The feature is backward-compatible. That means, it can be used with previous versions of Laravel.&lt;/p&gt;

&lt;p&gt;The following is what an anonymous migration file looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table-&amp;gt;json('tags')-&amp;gt;nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('posts', function (Blueprint $table) {
            $table-&amp;gt;dropColumn('tags');
        });
    }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replacement of SwiftMailer by Symphony Mailer&lt;br&gt;
In August of 2019, Fabien Potencier wrote about his decision to replace Swiftmailer with Symphony Mailer in a short blog post. Laravel follows suite in version 9.0.&lt;/p&gt;

&lt;p&gt;Here is the PR that made it all happen.&lt;/p&gt;

&lt;p&gt;The server.php file in The Root Directory Can Be Safely Removed&lt;br&gt;
The server.php file, usually, found at the root of a Laravel application's folder is only used for the php artisan serve command. In L9, it can be safely removed as the command's implementation will be included inside the framework. Tiny but, gold!&lt;/p&gt;

&lt;p&gt;Replacement Of Str Functions' Internal Logic With PHP's methods&lt;br&gt;
PHP 8.0 shipped with 3 new saucy string functions: &lt;code&gt;str_contains&lt;/code&gt;, &lt;code&gt;str_starts_with&lt;/code&gt; and &lt;code&gt;str_ends_with&lt;/code&gt;. Since PHP 8.0 will be the minimum supported version in L9, it is only logical that their related functions in &lt;code&gt;\Illuminate\Support\Str&lt;/code&gt; class get updated as well. Here is the PR that made it all happen!&lt;/p&gt;

&lt;p&gt;The Latest Version of Spatie's Ignition Will Be Made Default&lt;br&gt;
The announcement was made in a tweet by Spatie's Freek Van der Harten:&lt;/p&gt;

&lt;p&gt;🚀 I'm proud to share that our team has released a new major version of Ignition. It's the most beautiful error page you ever seen, and it will be the default in @laravelphp 9&lt;/p&gt;

&lt;p&gt;👍You can also install it in Laravel 8!&lt;/p&gt;

&lt;p&gt;🧵 Let's take a look at all the features pic.twitter.com/jw9Dqdse9T&lt;/p&gt;

&lt;p&gt;— Freek Van der Herten 🔭 (&lt;a class="mentioned-user" href="https://dev.to/freekmurze"&gt;@freekmurze&lt;/a&gt;) January 18, 2022 " data-card-controls="0" data-card-theme="light"&amp;gt;&lt;br&gt;
🚀 I'm proud to share that our team has released a new major version of Ignition. It's the most beautiful error page you ever seen, and it will be the default in @laravelphp 9&lt;/p&gt;

&lt;p&gt;👍You can also install it in Laravel 8!&lt;/p&gt;

&lt;p&gt;🧵 Let's take a look at all the features pic.twitter.com/jw9Dqdse9T&lt;/p&gt;

&lt;p&gt;— Freek Van der Herten 🔭 (&lt;a class="mentioned-user" href="https://dev.to/freekmurze"&gt;@freekmurze&lt;/a&gt;) January 18, 2022&lt;br&gt;
A New Option For The artisan test Command&lt;br&gt;
Nuno Maduro announced in a tweet that the artisan test command will have a --coverage option in L9 that will instruct the test command to display the test coverage directly on the terminal.&lt;/p&gt;

&lt;p&gt;In @laravelphp v9.x, we will be introducing the &lt;code&gt;artisan test --coverage&lt;/code&gt; option. This option displays the test coverage directly on the terminal. 💫 pic.twitter.com/yKAMFwvwaZ&lt;/p&gt;

&lt;p&gt;— Nuno Maduro (@enunomaduro) January 18, 2022 " data-card-controls="0" data-card-theme="light"&amp;gt;&lt;br&gt;
In @laravelphp v9.x, we will be introducing the &lt;code&gt;artisan test --coverage&lt;/code&gt; option. This option displays the test coverage directly on the terminal. 💫 pic.twitter.com/yKAMFwvwaZ&lt;/p&gt;

&lt;p&gt;— Nuno Maduro (@enunomaduro) January 18, 2022&lt;br&gt;
This post is a work-in-progress. I will continue to update it as I get more information regarding Laravel 9.0 release. Thank you!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post is a work-in-progress. I will continue to update it as I get more information regarding Laravel 9.0 release. Thank you!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>larevel</category>
      <category>php</category>
    </item>
    <item>
      <title>A Law That Helps You Write Loosely Coupled Functions</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Sun, 01 Aug 2021 09:13:42 +0000</pubDate>
      <link>https://dev.to/frknasir/a-law-that-helps-you-write-loosely-coupled-functions-4noa</link>
      <guid>https://dev.to/frknasir/a-law-that-helps-you-write-loosely-coupled-functions-4noa</guid>
      <description>&lt;p&gt;There are &lt;em&gt;programming principles&lt;/em&gt; and there are &lt;em&gt;frameworks&lt;/em&gt; to help us stick to those principles. One of those frameworks is––&lt;strong&gt;Law of Demeter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Coupling is the degree of interdependence that exists between software components. Tightly coupled components are harder to maintain, modify and enhance overtime. For this reason, it's good to write loosely coupled functions as much as we can through out the development of a software program.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Honour thy functions and thy classes and keep them high up the altar away from undeserving stragers&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LoD or &lt;strong&gt;principle of least knowledge&lt;/strong&gt; is a design guideline for software development with the notion that a function or similar object should assume as little as possible about the properties and behaviours of components it comes in contact with. It is a novel way of loosely coupling software artifacts to make evolution much easier. It tries to prevent you from reaching into an object to gain access to a third object's methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakdown
&lt;/h2&gt;

&lt;p&gt;The law states that any method of an object should call only methods belonging to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;itself&lt;/li&gt;
&lt;li&gt;any parameters that were passed into the method&lt;/li&gt;
&lt;li&gt;any objects it created&lt;/li&gt;
&lt;li&gt;any directly held component objects
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Demeter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;private:&lt;/span&gt;
        &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nl"&gt;public:&lt;/span&gt;
        &lt;span class="c1"&gt;//...&lt;/span&gt;
        &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Demeter&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// itself&lt;/span&gt;

    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invert&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// any parameters that were passed in to the method&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;setActive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// any objects it created&lt;/span&gt;

    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// any directly held component objects&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Worth
&lt;/h2&gt;

&lt;p&gt;Theoretically, it sounds good. But, does it really help in writing more &lt;strong&gt;maintanable&lt;/strong&gt; and &lt;strong&gt;adaptable&lt;/strong&gt; code. Short answer––Yes. &lt;/p&gt;

&lt;p&gt;Since components are not very knoledgable of each other, you can easily make changes to one without affecting the other.&lt;/p&gt;

&lt;p&gt;There have been studies that show C++ classes with large response sets are more prone to error than classes with smaller response sets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a &lt;strong&gt;response set&lt;/strong&gt; is defined to be the number of functions directly invoked by methods of the class&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Downside
&lt;/h2&gt;

&lt;p&gt;Using the law of demeter will make your code more adaptable and robust, but at a cost: as a "general contractor", your module must delegate and manage any all subcontractors directly, without involving clients of your module. This means that you will be writing a large number of wrapper methods that simply forward the request on to a delegate. These wrapper methods will impose both a runtime cost and a space overhead, which may be significant––even prohibitive––in some applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Helpful Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Law_of_Demeter"&gt;WikiPedia: Law of Demeter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.infoworld.com/article/3136224/demystifying-the-law-of-demeter-principle.html"&gt;Demystifying the Law of Demeter Principle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://betterprogramming.pub/demeters-law-don-t-talk-to-strangers-87bb4af11694"&gt;Demeters Law: Dont Talk To Strangers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>javascript</category>
      <category>100daysofcode</category>
    </item>
    <item>
      <title>Javascript Iterators and the for-x Loops</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Wed, 14 Jul 2021 08:53:38 +0000</pubDate>
      <link>https://dev.to/frknasir/javascript-iterators-and-the-for-x-loops-5dj2</link>
      <guid>https://dev.to/frknasir/javascript-iterators-and-the-for-x-loops-5dj2</guid>
      <description>&lt;p&gt;This video discusses for-of loop–the most concise and accurate way to loop through an array in javascript, in comparison to other loop types.&lt;/p&gt;

</description>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Laravel: Easily Customize Email Verification URL</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Tue, 06 Jul 2021 15:12:03 +0000</pubDate>
      <link>https://dev.to/frknasir/laravel-easily-customize-email-verification-url-58f9</link>
      <guid>https://dev.to/frknasir/laravel-easily-customize-email-verification-url-58f9</guid>
      <description>&lt;p&gt;This is not something you'd want to do if you're building an application the &lt;em&gt;traditional laravel way&lt;/em&gt;––that is, a monolithic app. I've had to do this recently while working on a project that has the backend and frontend existing in different code bases.&lt;/p&gt;

&lt;p&gt;Normally, when you setup a laravel project for new users to verify their email, a temporarily signed url is generated and sent to them. The url is generated based on the project's set &lt;code&gt;APP_URL&lt;/code&gt; in the &lt;code&gt;.env&lt;/code&gt; file and, subsequently, in the &lt;code&gt;/config/app.php&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;The problem arises when you are building a SPA front end for a laravel backend api. In that case, you may have your frontend at, say, &lt;code&gt;http://cool-app.com&lt;/code&gt; and the backend at &lt;code&gt;http://api.cool-app.com&lt;/code&gt;. Because the user will not have a direct access to the api endpoints, it won't be ideal to generate a user-clickable link based on the api's base url. What you'd want is a url that is based on the frontend's base url. So, how can that be achieved? Easy.&lt;/p&gt;

&lt;p&gt;Create a custom method for generating the URL and pass it to the &lt;code&gt;createUrlUsing&lt;/code&gt; method of the &lt;code&gt;VerifyEmail&lt;/code&gt; notification class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
* Set a callback that should be used when creating the email verification URL.
*
* @param  \Closure  $callback
* @return void
*/&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createUrlUsing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$createUrlCallback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only other step that we have to take is to call this function inside the &lt;code&gt;AuthServiceProvider&lt;/code&gt; passing the callback that returns our custom URL. The complete code is as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
* Register any authentication / authorization services.
*
* @return void
*/&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="mf"&gt;...&lt;/span&gt;

    &lt;span class="nc"&gt;VerifyEmail&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;createUrlUsing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$notifiable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$frontendUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'http://cool-app.com/auth/email/verify'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nv"&gt;$verifyUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;temporarySignedRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s1"&gt;'verification.verify'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nc"&gt;Carbon&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addMinutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'auth.verification.expire'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$notifiable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                &lt;span class="s1"&gt;'hash'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$notifiable&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getEmailForVerification&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$frontendUrl&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'?verify_url='&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;urlencode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$verifyUrl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the frontend, you can have a page with a logic that makes a &lt;code&gt;GET&lt;/code&gt; http request to the &lt;code&gt;verify_url&lt;/code&gt;. And, there you have it––a customized email verification url!&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Fortify: How to Disable Auto-login After User Registration</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Tue, 06 Jul 2021 15:00:38 +0000</pubDate>
      <link>https://dev.to/frknasir/fortify-how-to-disable-auto-login-after-user-registration-4kf4</link>
      <guid>https://dev.to/frknasir/fortify-how-to-disable-auto-login-after-user-registration-4kf4</guid>
      <description>&lt;p&gt;With Fortify, a user is logged in, automatically, after registration. This might not be what you want for your application. Thankfully, the package is easily extensible.&lt;/p&gt;

&lt;p&gt;This post is a walk-through on how to override the default behaviour and disable the auto-login.&lt;/p&gt;

&lt;p&gt;Before we start, let's take a look at the package and try to understand what is happening behind the curtain. You register a user by hitting the &lt;code&gt;/register&lt;/code&gt; endpoint with the expected &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt; and &lt;code&gt;password_confirmation&lt;/code&gt; fields' values. On a successful login, you get redirected to the &lt;code&gt;home&lt;/code&gt; configuration option in your fortify's configuration file. The controller responsible for handling the registration request is &lt;code&gt;RegisteredUserController&lt;/code&gt;. Inside the controller class, there is another method–&lt;code&gt;store&lt;/code&gt; that handles the actual registration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Create a new registered user.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Laravel\Fortify\Contracts\CreatesNewUsers  $creator
 * @return \Laravel\Fortify\Contracts\RegisterResponse
 */&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="kt"&gt;CreatesNewUsers&lt;/span&gt; &lt;span class="nv"&gt;$creator&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;RegisterResponse&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Registered&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$creator&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;())));&lt;/span&gt;

    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RegisterResponse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that the registered user is logged in right after firing the &lt;code&gt;Registered&lt;/code&gt; event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A noob mentality will have you thinking you can easily comment out that line and you're good to go. Well, you could do that and your code temporarily behaves as expected but what happens when you run &lt;code&gt;composer update/install&lt;/code&gt; and your change is overridden––You are back to square one. You should never make changes to any code within the confines of the &lt;code&gt;vendor&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Create a folder and name it &lt;code&gt;Responses&lt;/code&gt; inside the &lt;code&gt;Http&lt;/code&gt; folder of your application. Inside, create a &lt;code&gt;RegisterResponse&lt;/code&gt; class that extends the &lt;code&gt;FortifyRegisterResponse&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Responses&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\JsonResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Http\Response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Fortify\Contracts\RegisterResponse&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;RegisterResponseContract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegisterResponse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FortifyRegisterResponse&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Create an HTTP response that represents the object.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Symfony\Component\HttpFoundation\Response
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;wantsJson&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                    &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JsonResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;intended&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'fortify.home'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take out everything inside the &lt;code&gt;toResponse&lt;/code&gt; method and replace it with code that will first log out the just logged in user by Fortify and then defers to the base class's implementation:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Responses&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Contracts\Auth\StatefulGuard&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Laravel\Fortify\Http\Responses\RegisterResponse&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;FortifyRegisterResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegisterResponse&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;FortifyRegisterResponse&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$guard&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StatefulGuard&lt;/span&gt; &lt;span class="nv"&gt;$guard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;guard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$guard&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;toResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;guard&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;toResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fortify's &lt;code&gt;RegisteredUserController&lt;/code&gt; accepts a stateful guard implementation on it's constructor. So, we are using the same approach so that the response object receives the same guard instance as that of the controller. Otherwise, we could have used the &lt;code&gt;Auth&lt;/code&gt; facade to logout the user.&lt;/p&gt;

&lt;p&gt;The final step is to register the implementation in Fortify's service provider's boot method as in the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
     * Bootstrap any application services.
     *
     * @return void
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mf"&gt;...&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;singleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Laravel\Fortify\Contracts\RegisterResponse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;App\Http\Responses\RegisterResponse&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all, folks!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post appeared &lt;a href="https://faruknasir.com"&gt;here&lt;/a&gt; first.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>laravel</category>
      <category>hotfix</category>
      <category>fortify</category>
    </item>
    <item>
      <title>Laravel: Hotfix for SQLite Drop Foreign Exception</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Tue, 06 Jul 2021 14:55:41 +0000</pubDate>
      <link>https://dev.to/frknasir/laravel-hotfix-for-sqlite-drop-foreign-exception-4md6</link>
      <guid>https://dev.to/frknasir/laravel-hotfix-for-sqlite-drop-foreign-exception-4md6</guid>
      <description>&lt;p&gt;By convention, you can not use &lt;code&gt;ALTER TABLE&lt;/code&gt; sql statement to drop a foreign key in sqlite. To do that, you will have to rename the table, create a new table without the foreign key, and then copy the data into the new table.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://giphy.com/gifs/tlc-network-90-day-fiance-happily-ever-after-VvMZkreP3TMqfvcCLP"&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This behaviour has been &lt;a href="https://github.com/laravel/framework/pull/24052"&gt;baked in to Laravel&lt;/a&gt; in the form of an exception since Laravelv5.7. Unfortunately, this removes the possibility to simply ignore foreign keys using the same migrations across different drivers. This has been a real bottleneck for me because I mostly use in-memory sqlite database for my tests and real world databases schema definitions are messy with lots of &lt;code&gt;changes&lt;/code&gt; and &lt;code&gt;droppings&lt;/code&gt; through out the lifetime of your project.&lt;/p&gt;

&lt;p&gt;If you are like me, you are in luck because I will be sharing with you &lt;a href="https://github.com/laravel/framework/issues/25475#issuecomment-439342648"&gt;a solution&lt;/a&gt; I found that does not involve you updating any migration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://giphy.com/gifs/simonrex-simon-rex-dirt-nasty-xT5P0WEiP5n4WMGUG4"&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;br&gt;
This example is for when you are using in-memory sqlite for tests!&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;TestCase&lt;/code&gt; class, create a function that calls the &lt;code&gt;Connection&lt;/code&gt; class &lt;code&gt;resolverFor&lt;/code&gt; method. It takes the &lt;strong&gt;driver's name&lt;/strong&gt; as the first parameter and a &lt;strong&gt;callback&lt;/strong&gt; as the second.&lt;/p&gt;

&lt;p&gt;The callback will return a new class extending &lt;code&gt;SQLiteConnection&lt;/code&gt; and override the &lt;code&gt;getSchemaBuilder&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hotfixSqlite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Illuminate\Database\Connection&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;resolverFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sqlite'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
            &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;SQLiteConnection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getSchemaBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;schemaGrammar&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;useDefaultSchemaGrammar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;SQLiteBuilder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createBlueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Closure&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Blueprint&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;dropForeign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                            &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Fluent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                            &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="p"&gt;};&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;};&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final step is to call the newly created function in the &lt;code&gt;TestCase&lt;/code&gt;'s constructor class. Your final &lt;code&gt;TestCase&lt;/code&gt; class should look like the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;BaseTestCase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$dataName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hotfixSqlite&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$dataName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     *
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hotfixSqlite&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nc"&gt;Illuminate\Database\Connection&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;resolverFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sqlite'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
            &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$database&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$prefix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
                &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;SQLiteConnection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getSchemaBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;schemaGrammar&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;useDefaultSchemaGrammar&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;

                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;SQLiteBuilder&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;createBlueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;Closure&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Blueprint&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;dropForeign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                                &lt;span class="p"&gt;{&lt;/span&gt;
                                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Fluent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                                &lt;span class="p"&gt;}&lt;/span&gt;
                            &lt;span class="p"&gt;};&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;};&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; &lt;br&gt;
For PHPUnit 9, it is important that you call the hotfix&lt;br&gt;
method before the parent constructor in the constructor method.&lt;/p&gt;


&lt;p&gt;&lt;a href="https://giphy.com/gifs/smile-done-Mp4hQy51LjY6A"&gt;via GIPHY&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This post appeared &lt;a href="https://faruknasir.com/2021/4/squash-commits-into-one-git"&gt;here&lt;/a&gt; first.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>laravel</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Too many commits? No worries, just squash them into one!</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Tue, 27 Apr 2021 10:56:49 +0000</pubDate>
      <link>https://dev.to/frknasir/too-many-commits-no-worries-just-squash-them-into-one-1pnp</link>
      <guid>https://dev.to/frknasir/too-many-commits-no-worries-just-squash-them-into-one-1pnp</guid>
      <description>&lt;p&gt;It's a beautiful Friday morning. It had just rained last night. You wake up feeling energetic and ready to build something great or make something better. You've filled your favourite mug with your favourite morning beverage, sat down on your desk and opened your laptop.&lt;/p&gt;

&lt;p&gt;The first open issue is your pick of the day. You dove right into it. The problem is understood. It's an open and close case.&lt;/p&gt;

&lt;p&gt;First commit. Tests are passing. You pushed to github!&lt;/p&gt;

&lt;p&gt;Shortly after, QA report comes through that your &lt;code&gt;PR&lt;/code&gt; is breaking another thing not covered by currently written tests. &lt;/p&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%2Fimages.unsplash.com%2Fphoto-1527631120902-378417754324%3Fixid%3DMnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8%26ixlib%3Drb-1.2.1%26auto%3Dformat%26fit%3Dcrop%26w%3D1650%26q%3D80" 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%2Fimages.unsplash.com%2Fphoto-1527631120902-378417754324%3Fixid%3DMnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8%26ixlib%3Drb-1.2.1%26auto%3Dformat%26fit%3Dcrop%26w%3D1650%26q%3D80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You create 3 more commits for the fix and some tests. More things break! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Shoooosh!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;By midday, half your screen is filled up with commit messages. The day is adamant on going down in history as proof that, "a wonderful morning does not guarantee a good evening". Literally.&lt;/p&gt;

&lt;p&gt;At the end, you manage to get everything to work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[x] Tests are passing&lt;/li&gt;
&lt;li&gt;[x] Static Analysis&lt;/li&gt;
&lt;li&gt;[x] QA Approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, Your PR has 11 commits. You can't send that for a review. Its too much work for a reviewer. Have some empathy.&lt;/p&gt;

&lt;p&gt;Luckily for you, you can fix that with the &lt;code&gt;squash-rebase workflow&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the squash-rebase workflow
&lt;/h3&gt;

&lt;p&gt;The principle here is, before you merge a working branch into the &lt;code&gt;main branch&lt;/code&gt;, all commits of the &lt;code&gt;working branch&lt;/code&gt; should be squashed into one single commit, then, rebased from the main branch.&lt;/p&gt;

&lt;p&gt;These are the steps:&lt;/p&gt;

&lt;h4&gt;
  
  
  Select the starting commit
&lt;/h4&gt;

&lt;p&gt;Couple of assumptions here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are working on a &lt;code&gt;feature branch&lt;/code&gt; you checked out from your project's up-to-date &lt;code&gt;main branch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You have made all necessary changes you need to make up to your final commit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the feature branch, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git log


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

&lt;/div&gt;

&lt;p&gt;This is to list all the commits we have made starting from the most recent one. You will get something similar to the following on your screen:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

commit e8f89c696596619678c819f9b7a34730cd3f41bb &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; chore/test-git-squashing, origin/chore/test-git-squashing&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="nt"&gt;---&lt;/span&gt; newer commit
Author: Faruk Nasir &amp;lt;user@example.com&amp;gt;
Date:   Tue Apr 27 09:41:30 2021 +0100

    fix: on and on and on we go

commit a8293a21f31b5fea688dc3ef65add3b9924b5f28
Author: Faruk Nasir &amp;lt;user@example.com&amp;gt;
Date:   Tue Apr 27 09:41:00 2021 +0100

    fix: and on we go

commit 3dc51a8a8f83d96cde7b0f9b2be33c694ca91a3d
Author: Faruk Nasir &amp;lt;user@example.com&amp;gt;
Date:   Tue Apr 27 09:40:33 2021 +0100

    fix: we are adding something

commit 5f561cc9380ddeafd6134cee31b4ee4f630eac4c
Author: Faruk Nasir &amp;lt;user@example.com&amp;gt;
Date:   Tue Apr 27 09:40:03 2021 +0100

    fix: deleted some things

commit 3c0ae097ef858d61ecc2110d84a413f77673d09a &lt;span class="o"&gt;(&lt;/span&gt;origin/main, main&lt;span class="o"&gt;)&lt;/span&gt;  &lt;span class="nt"&gt;---&lt;/span&gt; older commit
Author: Faruk Nasir &amp;lt;user@example.com&amp;gt;
Date:   Tue Apr 27 09:33:13 2021 +0100

    chore: fifth change


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

&lt;/div&gt;

&lt;p&gt;Above you can easily detect where your main branch stops and where your feature branch starts. The goal here is to count all the commits of your feature branch. This will then be used in the command to start the interactive rebasing. More on that in a bit. For a more compact result of the commits' log, we can try decorating the command as in the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git log&lt;span class="sb"&gt;`&lt;/span&gt; or &lt;span class="sb"&gt;`&lt;/span&gt;git log &lt;span class="nt"&gt;--graph&lt;/span&gt; &lt;span class="nt"&gt;--decorate&lt;/span&gt; &lt;span class="nt"&gt;--pretty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;oneline &lt;span class="nt"&gt;--abbrev-commit&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This will give us:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="k"&gt;*&lt;/span&gt; e8f89c6 &lt;span class="o"&gt;(&lt;/span&gt;HEAD -&amp;gt; chore/test-git-squashing, origin/chore/test-git-squashing&lt;span class="o"&gt;)&lt;/span&gt; fix: on and on and on we go
&lt;span class="k"&gt;*&lt;/span&gt; a8293a2 fix: and on we go
&lt;span class="k"&gt;*&lt;/span&gt; 3dc51a8 fix: we are adding something
&lt;span class="k"&gt;*&lt;/span&gt; 5f561cc fix: deleted some things
&lt;span class="k"&gt;*&lt;/span&gt; 3c0ae09 &lt;span class="o"&gt;(&lt;/span&gt;origin/main, main&lt;span class="o"&gt;)&lt;/span&gt; chore: fifth change
&lt;span class="k"&gt;*&lt;/span&gt; e1d0da7 chore: fourth change
&lt;span class="k"&gt;*&lt;/span&gt; e165870 chore: third change
&lt;span class="k"&gt;*&lt;/span&gt; f249883 chore: second change
&lt;span class="k"&gt;*&lt;/span&gt; 86b4fbd chore: first change


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

&lt;/div&gt;
&lt;h4&gt;
  
  
  Picking and Squashing
&lt;/h4&gt;

&lt;p&gt;After getting the number of commits you want to squash, you go ahead and run the following command to start the interactive:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

git rebase &lt;span class="nt"&gt;--interactive&lt;/span&gt; HEAD~[number of commits]

&lt;span class="c"&gt;# or&lt;/span&gt;

git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~[number of commits]


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

&lt;/div&gt;

&lt;p&gt;So, let's say you are trying to squash 4 commits, the command will look something like this:&lt;/p&gt;

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

git rebase -i HEAD~4


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

&lt;/div&gt;

&lt;p&gt;Alternatively, if you don't want to count the number of commits all the time, especially, when the commits are quite long, you can get the &lt;code&gt;hash&lt;/code&gt; of the commit just before the first one to rewrite from and run the &lt;code&gt;interactive rebasing&lt;/code&gt; command like this:&lt;/p&gt;

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

git rebase --interactive [commit-hash]


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

&lt;/div&gt;

&lt;p&gt;An editor will popup with something like the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pick e8f89c6 fix: on and on and on we go                &lt;span class="nt"&gt;---&lt;/span&gt; older commit
pick a8293a2 fix: and on we go
pick 3dc51a8 fix: we are adding something
pick 5f561cc fix: deleted some things                   &lt;span class="nt"&gt;---&lt;/span&gt; newer commit

...


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

&lt;/div&gt;

&lt;p&gt;Here, you are to edit the file leaving one commit as &lt;code&gt;pick&lt;/code&gt; (ususally the first one) and change all the other ones to &lt;code&gt;s&lt;/code&gt; or &lt;code&gt;squash&lt;/code&gt;. Save and exit the editor.&lt;/p&gt;

&lt;h4&gt;
  
  
  New Commit Creation
&lt;/h4&gt;

&lt;p&gt;You will be prompted again to enter a commit message for the final about to be created. You can choose to skip this and the name of the commit will be a list of all the intermediate commit. It will look like the following:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

on and on and on we go
and on we go
we are adding something
deleted some things


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

&lt;/div&gt;

&lt;p&gt;And, thats it! You have successfully squashed all your commits into one. Thank you for reading!&lt;/p&gt;

&lt;p&gt;This post first appeared (here)[&lt;a href="https://faruknasir.com/2021/4/squash-commits-into-one-git" rel="noopener noreferrer"&gt;https://faruknasir.com/2021/4/squash-commits-into-one-git&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>git</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Running Psalm With Github Actions</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Fri, 23 Apr 2021 08:27:46 +0000</pubDate>
      <link>https://dev.to/frknasir/running-psalm-with-github-actions-1ipk</link>
      <guid>https://dev.to/frknasir/running-psalm-with-github-actions-1ipk</guid>
      <description>&lt;p&gt;I have written about Psalm &lt;a href="https://faruknasir.com/2021/4/static-analysis-with-psalm"&gt;here&lt;/a&gt;. Here, I share my workflow for running Psalm in Github Actions:&lt;br&gt;
&lt;/p&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;Psalm&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;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**.php'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;psalm.xml.dist'&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;psalm&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;psalm&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&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 PHP&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;shivammathur/setup-php@v2&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;php-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;7.4'&lt;/span&gt;
          &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick&lt;/span&gt;
          &lt;span class="na"&gt;coverage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&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;Cache composer dependencies&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/cache@v2&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;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vendor&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;composer-${{ hashFiles('composer.lock') }}&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;Run composer install&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;composer install -n --prefer-dist&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;Run psalm&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./vendor/bin/psalm --output-format=github&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Let's Discuss What's Happening Above
&lt;/h3&gt;

&lt;p&gt;I start by specifying a name for the job. In this case, "Psalm".&lt;br&gt;
&lt;/p&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;Psalm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I, then, go on to describe when I want the job to run. I only want it to run when there is a new version of a php file or the psalm config file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**.php'&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;psalm.xml'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I go on to describe fully the actual job that needs to run. First, I specify the environment the job is going to run on. Then, I check out the code in the virtual machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;psalm&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;psalm&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;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is followed by setting up &lt;code&gt;PHP&lt;/code&gt;(using a third party action) and &lt;code&gt;Composer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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 PHP&lt;/span&gt;
        &lt;span class="s"&gt;uses&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;shivammathur/setup-php@v2&lt;/span&gt;
        &lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;php-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;7.4'&lt;/span&gt;
          &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick&lt;/span&gt;
          &lt;span class="na"&gt;coverage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&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;Cache composer dependencies&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/cache@v2&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;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vendor&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;composer-${{ hashFiles('composer.lock') }}&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;Run composer install&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;composer install -n --prefer-dist&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the job is finally executed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&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;Run psalm&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./vendor/bin/psalm --output-format=github&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, that's that!&lt;/p&gt;

&lt;p&gt;This post first appeared &lt;a href="https://faruknasir.com/2021/4/running-psalm-with-gh-actions"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>staticanalysis</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Static Analysis With Psalm</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Fri, 23 Apr 2021 08:20:24 +0000</pubDate>
      <link>https://dev.to/frknasir/static-analysis-with-psalm-1f44</link>
      <guid>https://dev.to/frknasir/static-analysis-with-psalm-1f44</guid>
      <description>&lt;p&gt;A &lt;code&gt;typo&lt;/code&gt; is never that serious unless it's in a software code base. A tiny mistake such as an omission of a comma can &lt;a href="https://www.inc.com/jeff-haden/how-1-missing-comma-just-cost-this-company-5-million-but-did-make-its-employees-5-million-richer.html"&gt;cause companies billions of dollars&lt;/a&gt;, &lt;a href="https://priceonomics.com/the-typo-that-destroyed-a-space-shuttle/"&gt;destroy a NASA rocket&lt;/a&gt; or even interrupt service for users of a SaaS product.&lt;/p&gt;

&lt;p&gt;Over the years there has been tremendous efforts towards development of automated tools and processes to prevent such catastrophic typos from finding their way into or making a home of our software code bases. Extensions of compiler technologies have been built to help us with automated reviews. &lt;/p&gt;

&lt;p&gt;In this post, I write about Psalm - a PHP static analysis tool, and how you can take advantage of its powerful features in stopping bad code from creeping into your source codes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Psalm
&lt;/h3&gt;

&lt;p&gt;Psalm is a VIMEO open-source project that helps you in catching bugs early and identifying problems in your code. It helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prevent type-related runtime errors&lt;/li&gt;
&lt;li&gt;enforce standard coding patterns&lt;/li&gt;
&lt;li&gt;autofix bugs&lt;/li&gt;
&lt;li&gt;detect PHP security vulnerabilities using &lt;a href="https://dzone.com/articles/what-is-taint-analysis-and-why-should-i-care#:~:text=Taint%20analysis%20identifies%20every%20source,mean%20all%20the%20way%20through."&gt;taint analysis&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a quick start and installation guide, head over &lt;a href="https://psalm.dev/docs/running_psalm/installation/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Psalm does not just flag a line of code as problematic, it includes links that you can follow to see explanation for the decision. It looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ERROR: InvalidArgument - &lt;span class="se"&gt;\n&lt;/span&gt;amespace&lt;span class="se"&gt;\f&lt;/span&gt;ile.php:8:19 - 
Argument 1 of getAttribute expects string, 
int provided &lt;span class="o"&gt;(&lt;/span&gt;see https://psalm.dev/004&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Support For Laravel
&lt;/h3&gt;

&lt;p&gt;Psalm v3 came with a new plugin framework that makes authoring integrations for third party packages much easier. That, with &lt;a href="https://github.com/barryvdh/laravel-ide-helper"&gt;Barry's IDE Helper&lt;/a&gt; made the &lt;a href="https://github.com/psalm/psalm-plugin-laravel"&gt;Laravel Plugin&lt;/a&gt; a reality according to Matt.&lt;/p&gt;

&lt;p&gt;It's super easy to setup. You only need two commands after successfully installing and setting up Psalm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer require --dev psalm/plugin-laravel
./vendor/bin/psalm-plugin enable psalm/plugin-laravel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, it runs the laravel IDE helper, get the stubs and feed them into Psalm. I, personally, would love it that the package exists independent of the IDE helper because a scenario in the future where issues would pile up in both repos because of some dependency mismatch or recent upgrade that stops a certain &lt;em&gt;"something"&lt;/em&gt; from working entirely is imminent.&lt;/p&gt;

&lt;p&gt;But, so far so good. I'm really happy with the developments and excited for what is in store for the future!&lt;/p&gt;

&lt;p&gt;This post first appeared &lt;a href="https://faruknasir.com/2021/4/static-analysis-with-psalm"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>PHP null-safe and null-coalescing operators</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Fri, 23 Apr 2021 08:10:50 +0000</pubDate>
      <link>https://dev.to/frknasir/php-null-safe-and-null-coalescing-operators-jg2</link>
      <guid>https://dev.to/frknasir/php-null-safe-and-null-coalescing-operators-jg2</guid>
      <description>&lt;h3&gt;
  
  
  Null-coalescing Operator (??)
&lt;/h3&gt;

&lt;p&gt;PHP7 came with syntactic flavourings we all have been savouring ever since its release - One of which is the null-coalescing operator. If you have ever had to use the &lt;code&gt;ternary&lt;/code&gt; operator together with &lt;code&gt;isset()&lt;/code&gt; method, then this was &lt;code&gt;tailor-made&lt;/code&gt; for you!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$developer_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$coding&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nv"&gt;$sleeping&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// is equivalent to&lt;/span&gt;
&lt;span class="nv"&gt;$developer_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$coding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;$coding&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$sleeping&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It returns the first operand if true, otherwise returns the second. It is also chainable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$developer_status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$coding&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nv"&gt;$sleeping&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nv"&gt;$eating&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Null-safe Operator (?-&amp;gt;)
&lt;/h3&gt;

&lt;p&gt;The null-safe is a PHP8 feature that, instead of throwing an exception, short-circuits to null when a chained property or method access is null and the rest of the chain is skipped. &lt;/p&gt;

&lt;p&gt;It is an &lt;code&gt;elegant&lt;/code&gt; way of wrapping &lt;code&gt;is_null&lt;/code&gt; around each property or method access.&lt;/p&gt;

&lt;p&gt;Let's examine the following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$recentlyActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;is_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$lastLoggedIn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;lastLoggedIn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;is_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lastLoggedIn&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$recentlyActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$lastLoggedIn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withinLast7Days&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With null-safe operator, we can be more efficient by writing less and clearer code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$recentlyActive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;lastLoggedIn&lt;/span&gt;&lt;span class="o"&gt;?-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withinLast7Days&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Versus
&lt;/h3&gt;

&lt;p&gt;What is the difference between null-safe operator and null-coalescing operator. &lt;code&gt;Hint: it's not just in the syntax, it is also in the semantics.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The null-safe operator supports method while the null-coalescing operator doesn't. The null-coalescing operator supports array while the null-safe operator doesn't.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// this works&lt;/span&gt;
&lt;span class="nv"&gt;$array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'mukulli'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;kofa&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="c1"&gt;// this throws a warning&lt;/span&gt;
&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'mukulli'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;?-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;kofa&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Warning: Undefined array key "key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Null-safe with methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;?Carbon&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* … */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// …&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nv"&gt;$order&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nb"&gt;var_dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Y-m-d'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This post first appeared &lt;a href="https://faruknasir.com/2021/4/php-nullsafe-null-coalescing-operators"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>php</category>
      <category>100daysofcode</category>
      <category>codenewbie</category>
      <category>webdev</category>
    </item>
    <item>
      <title>It's never easy knowing when to use exception handling. In this post I explain a simple rule</title>
      <dc:creator>Faruk Nasir</dc:creator>
      <pubDate>Wed, 07 Apr 2021 07:18:18 +0000</pubDate>
      <link>https://dev.to/frknasir/when-to-use-exceptions-41ec</link>
      <guid>https://dev.to/frknasir/when-to-use-exceptions-41ec</guid>
      <description>&lt;p&gt;It is good practice to check for every possible errors - especially, the unexpected ones. This can push us to write code that is hard to read. The logic of your program can end up being totally obscured by error handling, particularly, if you subscribe to, &lt;code&gt;"a function must have a single return statement"&lt;/code&gt; school of thought.&lt;/p&gt;

&lt;p&gt;Let's examine the code snippet below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4kNwjk-E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://faruknasir.com/images/blog/2021/if_else_nesting.png" class="article-body-image-wrapper"&gt;&lt;img alt="If else nesting" src="https://res.cloudinary.com/practicaldev/image/fetch/s--4kNwjk-E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://faruknasir.com/images/blog/2021/if_else_nesting.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Personally, I am not aware of any limitation to &lt;em&gt;if-else&lt;/em&gt; nesting but, deep &lt;em&gt;nestings&lt;/em&gt; could be an indication of terrible design. They could negatively impact readability which will make the job of the future maintainer a little bit more difficult.&lt;/p&gt;

&lt;p&gt;With most modern programming languages, we can, easily, refactor the above code snippet using &lt;strong&gt;exception&lt;/strong&gt; handling to increase readability:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gEvtnZ7F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://faruknasir.com/images/blog/2021/refactor_using_exception.png" class="article-body-image-wrapper"&gt;&lt;img alt="refactor using exception" src="https://res.cloudinary.com/practicaldev/image/fetch/s--gEvtnZ7F--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://faruknasir.com/images/blog/2021/refactor_using_exception.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is clearer with the main logic on one side and all the error handling moved to a single place. &lt;code&gt;But, my personal dilemma is the deciding factor of when wrapping a piece of code around a try and catch block is the right approach and when it isn't.&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Exceptional?
&lt;/h3&gt;

&lt;p&gt;"Exceptions should rarely be used as part of a program's normal flow; exceptions should be reserved for unexpected events".&lt;/p&gt;

&lt;p&gt;If your code tries to load a record from the database for some operations, and that record does not exist, should an exception be raised?&lt;/p&gt;

&lt;p&gt;That depends on the expected behaviour. &lt;/p&gt;

&lt;p&gt;Always assume that an uncaught exception will terminate your program and then ask yourself, "Will the code still run if I removed the exception handler?". If "no", then, maybe, exceptions are being used in non-exceptional circumstances.&lt;/p&gt;

&lt;p&gt;If the record should have been in the database, then an exception can be raised. This is because something unexpected happened - a record that your program expected to find in the database was not found.&lt;/p&gt;

&lt;p&gt;On the other hand, if you are unsure whether the record should exist or not, then not finding it in the database is not exceptional - not an unexpected behaviour, and an error return is appropriate.&lt;/p&gt;

&lt;blockquote&gt;
This post first appeared on &lt;a href="https://faruknasir.com"&gt;
https://faruknasir.com&lt;/a&gt;
&lt;/blockquote&gt;

</description>
      <category>article</category>
      <category>exceptions</category>
      <category>tips</category>
    </item>
  </channel>
</rss>
