Which Laravel authentication package to choose?

At its core, Laravel provides “guards” and “providers” to manage authentication. However, controllers, routes, and views still need to be implemented.

To achieve this, Laravel offers first-party packages that offer a complete authentication system, ready to use in just a few minutes. This is unique and the strength of Laravel: in no time, you can start developing your ideas.

However, multiple packages are related to authentication, and it can be challenging to know which one is adequate for your project.

Should you use Laravel Jetstream or Laravel Breeze? What are the differences between Laravel Passport and Laravel Sanctum? Is Laravel UI still an option?

To help you find your way around, I have made a diagram to help you understand their differences and make the best choice for your project.

Which Laravel authentication package to install for your project?

Laravel Breeze

Breeze is a minimal and simple implementation of Laravel’s authentication features. It works both for full-stack applications and APIs. This is an excellent choice if you like simplicity or are brand new to Laravel.

  • You can choose between Blade, Vue/React (with Inertia), or API
  • It uses Tailwind CSS when Blade or Inertia stacks are chosen
  • ✅ Registration
  • ✅ Login
  • ✅ Profile Management
  • ✅ Password Reset
  • ✅ Email Verification

Laravel Jetstream

More complete and stylish, Jetstream is an interesting alternative to Breeze. It provides more features but requires that your project uses Livewire or Inertia.

  • You can choose between Blade + Livewire or Vue/React + Inertia
  • It uses Tailwind CSS
  • ✅ Registration
  • ✅ Login
  • ✅ Profile Management
  • ✅ Password Reset
  • ✅ Email Verification
  • ✅ Two-Factor Authentication (2FA)
  • ✅ Teams Management
  • ✅ Browser Sessions Management (let users see where they’re logged-in)
  • ✅ API Tokens & Permissions (let users generate API tokens)

Laravel Fortify

Fortify is a front-end agnostic implementation of all authentication features. It provides all routes and controllers needed to implement your authentication logic but requires you to code the user interface yourself. There are no views out of the box!

This is a great choice if you don’t use Tailwind CSS, want to code your front end yourself, or are building an API.

  • ❌ No views, no user interface
  • ✅ Registration
  • ✅ Login
  • ✅ Profile Management
  • ✅ Password Reset
  • ✅ Email Verification
  • ✅ Two-Factor Authentication (2FA)
  • ✅ Teams Management
  • ✅ Browser Sessions Management (let users see where they’re connected and logout sessions)
  • ✅ API Tokens & Permissions (let users generate API tokens)

For info, Jetstream uses Fortify under the hood and adds the UI layer.


Laravel UI

Laravel UI is the legacy scaffolding and brings a basic authentication system built on the Bootstrap CSS framework. Today, the only reason to install it is that your project uses Bootstrap CSS.

  • You can choose between simple HTML, Vue, or React
  • ✅ Registration
  • ✅ Login
  • ✅ Password Reset
  • ✅ Email Verification

Laravel Passport

Passport provides a full OAuth2 server implementation


Laravel Sanctum

Sanctum offers a simple way to authenticate SPAs or mobile applications that need to communicate with your Laravel-powered API. If you don’t need full OAuth2 support, this is a much simpler alternative to Passport.

  • ✅ Middleware to authenticate your SPA (using cookie-based sessions)
  • ✅ Middleware to authenticate clients using API tokens
  • ✅ API tokens generation & permissions
  • ❌ No authentication routes or controllers

Using Sanctum, you still have to implement your own authentication logic (creating your routes and controllers) or use it in combination with Fortify.

If you use it to authenticate a SPA, it needs to be hosted on the same root domain as your API since it uses cookie-based sessions.


I hope that all the authentication packages and starter kits of Laravel have no more secrets for you and that this article has made your choice easier if you were hesitating between them.

👋 I offer tech consulting services for companies that need help with their Laravel applications. I can assist with upgrades, refactoring, testing, new features, or building new apps. Feel free to contact me through LinkedIn, or you can find my email on my GitHub profile.

sumber: https://medium.com/@antoine.lame/which-laravel-authentication-package-to-choose-290551a82a44

Querying Whois information with PHP

The wonderful world of Whois!, if you do not know what it is or what it is for, this is probably not the publication for you. But if you know what I’m talking about, then you’re going to be excited to know that you can stop using third-party services to check this information, with a little effort and love for programming you can create your own service! (I’m trying to add excitement to a query for information that, as necessary as it is, is quite common.)

Come on!, join me again to walk the yellow brick path… a path full of wonders!.

What is Whois?

Whois is a public service that allows you to check who owns a domain, its status, expiration dates, renewal and other information of interest.

You can use a Whois query to determine if a domain is available for purchase, for example. (Warning: Your mileage may vary, whois is generally quite reliable but can produce results you don’t expect), use it with caution.

Where can you find the Whois servers of a TLD?

IANA (the entity in charge of regulating the allocation of IP addresses and root DNS for address resolution) has a list at the following link:

Root Zone Database

The Root Zone Database represents the delegation details of top-level domains, including gTLDs such as .com, and…
www.iana.org

This list will help us later to scrape and extract information necessary for our PHP Whois query script.

Warning: Scraping itself is not bad, but misused it ruins everyone’s party, always be very responsible and respectful regarding the information you grab using this technique.

Structure of our solution

Our directory and solution files will be as follows:

/whois           # root directory (your web server must have access to it)
  /cache         # This directory will store json files that contain the whois
                 # server address for a given TLD, these files will be used to catch
                 # the scraping process results.
  - index.html   # This file will be our entry point and GUI interface to query
                 # whois information.
  - getwhois.php # This script will receive the whois request from index.html
                 # and return the result.
  - Whois.php    # Our class definition with all attributes and methods used
                 # to query whois information.

Remember that you must have a web development environment with PHP or at least that you can execute php scripts through a command console. This time we will use PHP 8.2 on an Apache web server.

We will write our code based on three large blocks as follows:

  • Scraping
  • Whois request/query
  • Interface and result presentation

1. Scraping

Let’s do some scraping to extract the Whois server from each domain type (TLD) available in https://www.iana.org/domains/root/db. We will do it “on demand”, we will only scrape as necessary, that is, when we do not have a previous cache file for the TLD, this way we will reduce traffic, respect the site where the information comes from and reduce response times while querying.

For example, we will visit the information of the TLD “.com”, the URL is https://www.iana.org/domains/root/db/com.html, general contact information will be shown and, at the bottom, the Whois server for this type of domains, like this:

iana.org whois

The address next to the text “WHOIS Server” will be the data of interest for our scrape process.

The first step will be to make a request to the website containing the required information and capture the HTML of the response. We can do this with our dear friend cURL like this:

    /** 
     * This function downloads HTML content from a URL 
     * 
     * @param string $url URL to be queried
     * 
     * @return string|bool HTML received in response from the website 
     * if an error occurs it will return false
     */
    function curlDownload(string $url): string|bool
    {

        $curl = curl_init();

        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36");
        curl_setopt($curl, CURLOPT_URL, $url);

        $html = curl_exec($curl);
        curl_close($curl);

        return $html;
    }

In the User-Agent header, we set a value that simulates a visit from a desktop browser.

Now that we have got the content of the site, it is necessary to extract from the HTML received the address of the whois server, this can be done with a very useful tool, a tool that generates panic or immense hatred in the depths of the brave ones that dare to look it straight into its eyes, regular expressions.

No matter how you feel about it, always try to remember “Macho man” Randy Savage wise words:

You may not like it, but accept it! — “Macho Man” Randy Savage wisdom

We are going to review the content and create the regular expression, keep in mind that we are not going to cover in detail how it works, we will cover what is important, that it works for our present objective.

Let’s look at the source code of the page where the name of the whois server is located. The section we are interested in has this structure:

    <p>
    
        <b>URL for registration services:</b> <a href="http://www.verisigninc.com">http://www.verisigninc.com</a><br/>
    
    
        <b>WHOIS Server:</b> whois.verisign-grs.com
    
    </p>

Now let’s create a regex to extract just the text “whois.verisign-grs.com”, it will be something like this:

$this->regexWhoisServer = '#(?s)(?<=\<b\>WHOIS Server\:\<\/b\>)(.+?)(?=\<\/p\>)#';

This expression looks for the text between the text pattern “<b>WHOIS Server:</b>” and the first match with the text “<p>”, using PHP we can capture the returned value and save it in a variable to use it later in our whois query.

Our sample code to understand this concept will look like this:

//Array that will be used to store the regex results.
$matchesWhois = array();

//Now we use our HTML download function created previously.
$html = curlDownload("https://www.iana.org/domains/root/db/com.html");
//Use the regex expression to extract the whois server from the HTML.
$resWhois = preg_match("#(?s)(?<=\<b\>WHOIS Server\:\<\/b\>)(.+?)(?=\<\/p\>)#", $html, $matchesWhois, PREG_OFFSET_CAPTURE);

//Now we remove the blank spaces from the result text, stored at the [0][0]
//element in the array
$matchesWhois[0][0] = trim($matchesWhois[0][0]);

//Finally assignt the whois server name to a variable.
$whoisServer = $matchesWhois[0][0];

2. Whois request/query

We already managed to query the name of the server to which we will request the whois information, now we need to implement the code to perform the query, for this we open a connection through sockets and send the domain name to receive a response with the whois data, like this:

//Open a connection to the whois server on port 43 with 20 seconds timeout limit.
$whoisSock = @fsockopen("whois.verisign-grs.com", 43, $errno, $errstr, 20);
//This variable will be used to store the whois result.
$whoisQueryResult = "";

//Send the domain name ending with new line.
fputs($whoisSock, "mytestdomain.com" . "\r\n");

$content = "";

//Read the server response.
while (!feof($whoisSock)) {
    $content .= fgets($whoisSock);
}

//Close the socket.
fclose($whoisSock);

//Convert the string to an array (one element for each line on the string)
$arrResponseLines = explode("\n", $content);

foreach ($arrResponseLines as $line) {

    $line = trim($line);

    //ignore if the line is empty or if it begins with "#" or "%"
    if (($line != '') && (!str_starts_with($line, '#')) && (!str_starts_with($line, '%'))) {
        //Append the line to the result variable.
        $whoisQueryResult .= $line . PHP_EOL;
    }
}

//Show the result.
echo $whoisQueryResult;

Now that we have the result, we will generate the code to query and display the result on the web.

3. Interface and result presentation

To query and show results we will create the Whois class that integrates the concepts previously shown, a file to receive query requests and the web interface to display the results.

Let’s start with our class, we will call it Whois.php and it has the following structure:

<?php

class Whois
{
    //Regex matches
    private array $matchesWhois;
    //Cache files path
    private string $_CACHE_PATH;
    //Regex used to detect the whois server while scraping the TLD URL
    private string $regexWhoisServer;
    //Cache files extension (.json)
    private string $_FILE_EXT;
    //Flag, True = using cache file, False = scraped result
    private bool $usingCache;
    //Domain name to being used to query the whois info.
    private string $domain;
    //Domain TLD
    private string $tld;
    //Cache file name
    private string $cacheFile;
    //URL used to scrape the whois server to be used.
    private string $urlWhoisDB;
    //Array that will contain the answer and errors generated during the whois query
    private array $response;
    //Array, contains the whois server address
    private array $whoisInfo;
    //Tag to be replaced by the domain TLD extracted from the domain name.
    private string $tldUrlTag;
    //Whois port, default 43
    private int $_WHOIS_PORT;
    //Whois query timeout in seconds, default 20
    private int $_WHOIS_TIMEOUT;
    //User Agent to be used to scrape the whois server info.
    private string $_CURL_USER_AGENT;


    /**
     * Class constructor
     */
    public function __construct()
    {
        $this->matchesWhois = array();
        $this->whoisInfo = array();
        $this->_CACHE_PATH = __DIR__ . "/cache/";
        $this->regexWhoisServer = '#(?s)(?<=\<b\>WHOIS Server\:\<\/b\>)(.+?)(?=\<\/p\>)#';
        $this->_FILE_EXT = ".json";
        $this->usingCache = false;
        $this->domain = "";
        $this->tld = "";
        $this->cacheFile = "";
        $this->tldUrlTag = "[TLD]";
        $this->urlWhoisDB = "https://www.iana.org/domains/root/db/{$this->tldUrlTag}.html";
        $this->response = array();
        $this->_WHOIS_PORT = 43;
        $this->_WHOIS_TIMEOUT = 20;
        $this->_CURL_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36";
    }


    /**
     * Domain validation
     * 
     * @param string $domain domain name to be validated i.e. "google.com"
     * 
     * @return bool
     */
    public function isDomain(string $domain): bool
    {
        return filter_var($domain, FILTER_VALIDATE_DOMAIN);
    }


    /**
     * Extracts the TLD from the domain name
     * 
     * @param mixed $domain domain name
     * 
     * @return string
     */
    private function extractTld($domain): string
    {
        $arrDomain = explode(".", $domain);

        return end($arrDomain);
    }

    /**
     * Sets the cache filename for a given TLD, it also checks if the file exists and loads its content
     * 
     * @param mixed $tld domain (TLD), i.e. "com", "net", "org". 
     * 
     * @return void
     */
    private function setCacheFileName($tld): void
    {
        $this->cacheFile = $this->_CACHE_PATH . $tld . $this->_FILE_EXT;

        if (file_exists($this->cacheFile)) {

            $tmpCache = file_get_contents($this->cacheFile);
            $this->whoisInfo = json_decode($tmpCache, true);

            $this->usingCache = true;
        }
    }

    /**
     * This function can be used to check if there where errors during the process
     * 
     * @return bool true = there are errors, false = no errors
     */
    public function hasErrors(): bool
    {
        return isset($this->response["errors"]);
    }

    /**
     * Returns the response received including erros (if any).
     * @param bool $json Allows to select the response format, false = array, true = json
     * 
     * @return array|string
     */
    public function getResponse(bool $json = false): array|string
    {
        return ($json) ? json_encode($this->response) : $this->response;
    }

    /**
     * This function downloads and returns the HTML returned from a URL
     * 
     * @param string $url URL adddress
     * 
     * @return string|bool string containing the HTML received, if there is an error return false.
     */
    private function curlDownload(string $url): string|bool
    {

        $curl = curl_init();

        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
        curl_setopt($curl, CURLOPT_USERAGENT, $this->_CURL_USER_AGENT);
        curl_setopt($curl, CURLOPT_URL, $url);

        $html = curl_exec($curl);
        curl_close($curl);

        return $html;
    }

    /**
     * Whois query entry point.
     * 
     * @param string $domain domain name for which you want to check the whois
     * 
     * @return void
     */
    public function getWhoisServerDetails(string $domain): void
    {

        $this->domain = $domain;
        $this->tld = $this->extractTld($domain);
        $this->setCacheFileName($this->tld);

        if (!$this->usingCache) {

            $urlWhoisDB = str_replace($this->tldUrlTag, $this->tld, $this->urlWhoisDB);
            $html = $this->curlDownload($urlWhoisDB);

            $resWhois = preg_match($this->regexWhoisServer, $html, $this->matchesWhois, PREG_OFFSET_CAPTURE);

            if ($resWhois != 1) {

                $this->response["errors"][] = array(
                    "error" => "TLD '{$this->tld}' not found!",
                    "domain" => $domain
                );

                return;
            }

            $this->matchesWhois[0][0] = trim($this->matchesWhois[0][0]);
            $this->whoisInfo["whois"] = $this->matchesWhois[0][0];

            file_put_contents($this->_CACHE_PATH . $this->tld . $this->_FILE_EXT, json_encode($this->whoisInfo, JSON_UNESCAPED_UNICODE));
        }

        if (!isset($this->whoisInfo["whois"])) {

            $this->response["errors"][] = array(
                "error" => "WhoIs Server for TLD {$this->tld} not found!.",
                "domain" => $domain
            );

            return;
        }

        $whoisSock = @fsockopen($this->whoisInfo["whois"], $this->_WHOIS_PORT, $errno, $errstr, $this->_WHOIS_TIMEOUT);
        $whoisQueryResult = "";

        if (!$whoisSock) {

            $this->response["errors"][] = array(
                "error" => "{$errstr} ({$errno})",
                "domain" => $domain
            );

            return;
        }

        fputs($whoisSock, $this->domain . "\r\n");

        $content = "";

        while (!feof($whoisSock)) {
            $content .= fgets($whoisSock);
        }

        fclose($whoisSock);

        if ((strpos(strtolower($content), "error") === false) && (strpos(strtolower($content), "not allocated") === false)) {

            $arrResponseLines = explode("\n", $content);

            foreach ($arrResponseLines as $line) {

                $line = trim($line);

                if (($line != '') && (!str_starts_with($line, '#')) && (!str_starts_with($line, '%'))) {
                    $whoisQueryResult .= $line . PHP_EOL;
                }
            }
        }

        $this->response["whoisinfo"] = $whoisQueryResult;
    }
}

In this class we will have all the main functions for scrape, whois server name extraction, domain name processing and final whois query. Note that error checking and handling routines were added, as well as functions to automate scraping from the domain type (TLD) queried and cache strategy to avoid making more queries than necessary to iana.org.

Now let’s create our file that will receive query requests, call it getwhois.php and it will have the following content:

<?php

//Include the class definition.
require("Whois.php");

//Decode the parameters received.
$paramsFetch = json_decode(
    file_get_contents("php://input"),
    true
);

//Create our whois object
$whoisObj = new Whois();
//Query the whois information
$whoisObj->getWhoisServerDetails($paramsFetch["domain"]);

//Return the response as JSON
echo $whoisObj->getResponse(true);
exit;

It is quite simple, it includes our Whois.php class, captures the parameters received from an HTML form that uses the javascript fetch function to send the request with the domain name, creates an instance of our class and makes the whois information query, then returns the result in JSON format and finishes the execution.

Now let’s go to the index.html file, this will be our graphical interface and the access point to the query and visualization of results. I use Bulma CSS for html controls an styling, it’s pretty straightforward, not intrusive, and you can generate results quickly. The file will look like this:

<?php

//Include the class definition.
require("Whois.php");

//Decode the parameters received.
$paramsFetch = json_decode(
    file_get_contents("php://input"),
    true
);

//Create our whois object
$whoisObj = new Whois();
//Query the whois information
$whoisObj->getWhoisServerDetails($paramsFetch["domain"]);

//Return the response as JSON
echo $whoisObj->getResponse(true);
exit;

It is quite simple, it includes our Whois.php class, captures the parameters received from an HTML form that uses the javascript fetch function to send the request with the domain name, creates an instance of our class and makes the whois information query, then returns the result in JSON format and finishes the execution.

Now let’s go to the index.html file, this will be our graphical interface and the access point to the query and visualization of results. I use Bulma CSS for html controls an styling, it’s pretty straightforward, not intrusive, and you can generate results quickly. The file will look like this:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Whois</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
    <script type="module">
        window.addEventListener('load', (event) => {
            //Event Handler for the search button.
            document.querySelector(".search").addEventListener('click', (event) => {
                //Show that the query is executing
                event.currentTarget.classList.add('is-loading');
                //disable the button
                event.currentTarget.disabled = true;

                //Hide the result sections.
                document.querySelector(".result").parentElement.classList.add("is-hidden");
                document.querySelector(".error").parentElement.classList.add("is-hidden");

                //Prepare the payload
                const payload = JSON.stringify({
                    "domain": document.querySelector(".domain").value
                });
                
                //Send the request to getwhois.php
                fetch('getwhois.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: payload,
                })
                    .then(response => response.json())
                    .then(data => {
                        //Process the response.
                        if (data.errors != undefined) {
                            document.querySelector(".error").parentElement.classList.remove("is-hidden");

                            for (const item in data.errors) {
                                document.querySelector(".error").innerText = data.errors[item].error + "\n";
                            }

                        } else {

                            document.querySelector(".result").parentElement.classList.remove("is-hidden");
                            document.querySelector(".result").innerText = data.whoisinfo;
                        }

                    })
                    .catch((error) => {
                        document.querySelector(".error").parentElement.classList.remove("is-hidden");
                        document.querySelector(".error").innerText = error;
                        console.error('Error:', error);
                    }).finally(() => {
                        document.querySelector(".search").classList.remove('is-loading');
                        document.querySelector(".search").disabled = false;
                    });
            });

        });
    </script>
</head>

<body>
    <section class="section">
        <div class="container">
            <div class="columns">
                <div class="column">
                    <div class="columns">
                        <div class="column"></div>
                        <div class="column has-text-centered">
                            <h1 class="title">
                                WhoIs Lookup
                            </h1>
                        </div>
                        <div class="column"></div>
                    </div>
                    <div class="columns">
                        <div class="column"></div>
                        <div class="column has-text-centered">
                            <div class="field is-grouped is-grouped-centered">
                                <div class="control">
                                    <input class="input domain" type="text" placeholder="Domain">
                                </div>
                                <div class="control">
                                    <button class="button is-info search">
                                        Search
                                    </button>
                                </div>
                            </div>
                        </div>
                        <div class="column"></div>
                    </div>
                </div>
            </div>
            <div class="columns box is-hidden">
                <div class="column result"></div>
            </div>
            <div class="columns box is-hidden">
                <div class="column notification is-danger error has-text-centered">
                </div>
            </div>
        </div>
    </section>
</body>

</html>

Testing

To perform tests it is only necessary point your browser to the path where our scripts are located, in my case http://localhost/whois, it will show the field to write the domain name and the “Search” button to request the Whois information. You can try a popular domain like “google.com”, the result will look like this:

After a successful whois query you will notice that in the /cache directory, a file will be created with the TLD, for example “com.json” and will contain the name of the corresponding whois server, this will allow us to avoid scraping again.

And that’s all, never forget that the one who is brave is really free, drink plenty of water, exercise and get enough sleep.

At Winkhosting.co we are much more than hosting. If you need shared hosting, domains or servers, stop by to visit us.

source: https://medium.com/winkhosting/querying-whois-information-with-php-f686baee8c7

Laravel: Automate Code Formatting!

Pint is one the newest members of Laravel first-party packages and will help us to have more readable and consistent codes.

Installing and Configuring Laravel Pint is so easy and It is built on top of PHP-CS-Fixer so it has tones of rules to fix code style issues. (You don’t need Laravel 9 to use Pint and it’s a zero dependency package)

But running Pint is quite painful because every time we want to push our changes to the remote repository we have to run below command manually:

./vendor/bin/pint --dirty

The --dirty flag will run PHP-CS-Fixer for changed files only. If we want to check styles for all files just remove --dirty flag.

In this article we want to simply automate running code styles check with Pint before committing any changed file so even team developers will have a well defined code structure and don’t need to run Laravel Pint every time before we push our codes to remote repo!

Before we start, be careful this is a very simple setup and you can add as many options as you want to Laravel Pint.

In order to run ./vendor/bin/pint --dirty just before every commit, we should use the pre-commit hook inside .git folder.

First of all we will create a scripts folder inside our root Laravel directory. In this folder we will have a setup.sh file and pre-commit file without any extension.

scripts/
setup.sh
pre-commit

Inside our setup.sh we have:

#! /usr/bin/env bash

cp scripts/pre-commit .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

And write the following lines on pre-commit file:

#! /usr/bin/env bash

echo "Check php code styles..."
echo "Running PHP cs-fixer"
 ./vendor/bin/pint --dirty
 git add .
echo "Done!"

Second of all, we should go to composer.json file and on the scripts object add this line: (If post-install-cmd key does not exist, you should create post-install-cmd part and then add below)

"post-install-cmd": [
            "bash scripts/setup.sh"
        ]

Third of all, we will require Pint package by this:

composer require laravel/pint --dev

And To be sure Don’t Forget to run:

composer install

The composer install command will add the pre-commit hook to our .git folder and after that we are ready to go!

From now on, we can simply write our code and just before we commit our changes the Pint command will run automatically and will fix our code styles!

Pint use Laravel code styles as defaultbut if you want to use psr-12 like me, you can create a pint.json file inside the root directory of your Laravel project and copy below json to have a more opinionated PHP code styles:

{
    "preset": "psr12",
    "rules": {
        "simplified_null_return": true,
        "blank_line_before_statement": {
            "statements": ["return", "try"]
        },
        "binary_operator_spaces": {
            "operators": {
                "=>": "align_single_space_minimal"
            }
        },
        "trim_array_spaces": false,
        "new_with_braces": {
            "anonymous_class": false
        }
    }
}

This is a simple config for our Pint command and will simplify null returns and define an equal indentation for arrays. You can check all PHP-CS-Fixer options here!

READ MORE:

demo-attachment-274-01-Featured

From Startup Creator to Serial Entrepre: A Journey Powered by Dropshipping

Amazon, which already charges some of the world’s lowest fees for Prime Video in India, is going a step further to win more users in the world’s second largest internet market. The e-commerce giant on Saturday launched miniTV, an ad-supported video streaming service that is available within the Amazon shopping app and is “completely free.” miniTV is currently available only in India, Amazon said.

miniTV features web-series, comedy shows, and content around tech news, food, beauty, fashion “to begin with,” Amazon said. Some of the titles currently available have been produced by leading studios such as TVF and Pocket Aces — two of the largest web studios in India — and comedians such as Ashish Chanchlani, Amit Bhadana, Round2Hell, Harsh Beniwal, Shruti Arjun Anand, Elvish Yadav, Prajakta Koli, Swagger Sharma, Aakash Gupta and Nishant Tanwar.

“Viewers will be informed on latest products and trends by tech expert Trakin Tech, fashion and beauty experts such as Sejal Kumar, Malvika Sitlani, Jovita George, Prerna Chhabra and ShivShakti. Food lovers can enjoy content from Kabita’s Kitchen, Cook with Nisha, and Gobble. In the coming months, miniTV will add many more new and exclusive videos,” the company added, without sharing its future roadmap plans. (Amazon began integrating reviews and other web clippings — from media houses — on its shopping service in India for more than two years ago.)

miniTV is currently available on Amazon’s Android app, and will arrive on the iOS counterpart and mobile web over the coming months, Amazon said.

Amazon’s move follows a similar step by Walmart’s Flipkart, the company’s marquee rival in India, which rolled out video streaming service within its app in 2019. In recent years, scores of firms in India including Zomato have explored adding a video streaming offering to their own apps.

Amazon has also aggressively pushed to expand its Prime Video offerings in India in recent quarters. The company — which partnered with Indian telecom network Airtel earlier this year to launch a new monthly mobile-only, single-user, standard definition (SD) tier (for $1.22) — has secured rights to stream some cricket matches in the country. Amazon also offers Prime Video as part of its Amazon Prime subscription in India.

demo-attachment-898-21
demo-attachment-2142-Writer

Mark Spenser |

Mark Spenser is a local NY resident and an avid geek. When he's not rediscovering his island state, he enjoys spending time at TechPhlox and review latest tech's world products and news. You can follow him on Twitter @MarkSpenser

RELATED ARTICLES

Resize ext4 file system

Using Growpart

$ growpart /dev/sda 1
CHANGED: partition=1 start=2048 old: size=39999455 end=40001503 new: size=80000991,end=80003039
$ resize2fs /dev/sda1
resize2fs 1.45.4 (23-Sep-2019)
Filesystem at /dev/sda1 is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 5
The filesystem on /dev/sda1 is now 10000123 (4k) blocks long.

Using Parted & resize2fs

apt-get -y install parted
parted /dev/vda unit s print all # print current data for a case
parted /dev/vda resizepart 2 yes -- -1s # resize /dev/vda2 first
parted /dev/vda resizepart 5 yes -- -1s # resize /dev/vda5
partprobe /dev/vda # re-read partition table
resize2fs /dev/vda5 # get your space

Parted doesn’t work on ext4 on Centos. I had to use fdisk to delete and recreate the partition, which (I validated) works without losing data. I followed the steps at http://geekpeek.net/resize-filesystem-fdisk-resize2fs/. Here they are, in a nutshell:

$ sudo fdisk /dev/sdx 
> c
> u
> p
> d
> p
> w
$ sudo fdisk /dev/sdx 
> c
> u
> p
> n
> p
> 1
> (default)
> (default)
> p
> w

sumber: https://serverfault.com/questions/509468/how-to-extend-an-ext4-partition-and-filesystem