1000 Musicians Play Metallica

https://theawesomer.com/photos/2022/11/rockin_1000_metallica_t.jpg

1000 Musicians Play Metallica

Link

During their October 2022 stadium show in São Paulo, Brazil, the Rockin’ 1000 assembled their informal band of musicians from around the world. Their performance of Metallica’s Enter Sandman brought down the house with infectious energy. You’ll want to crank up the volume all the way for this one.

The Awesomer

PHPScraper now supports feeds

https://api.imageee.com/bold?text=PHP:%20Scraping%20Feeds%20Tags&bg_image=https://images.unsplash.com/photo-1542762933-ab3502717ce7

Scrape Feeds

PHPScraper can identify and process feeds (RSS feeds, sitemaps, etc.) for you. The following feed-specific features are implemented:

Websites can define RSS feeds in the head section of their markup. PHPScraper allows to identify the RSS feeds of the current page using rssUrls:

The rss()-method can be used to parse RSS feeds. If called without any parameter rssUrls will be used:

You can also parse RSS feeds by passing one or more URLs in:

This result contains an array-structure with selected properties. The array-structure contains instances of DataTransferObjects\FeedEntry with properties for link and title.

Complete Details

If you need all details, please fallback on $web->rssRaw(...). It can be called like $web->rss(...) and returns an array-structure.

Parse XML Sitemaps

You can parse XML sitemaps using sitemap():

This result contains only selected properties. It returns an array of DataTransferObjects\FeedEntry with the link property.

Complete Details

If you need all details, please fallback on $web->sitemapRaw(...). It can be called like $web->sitemap() and returns an array-structure.

Parse Static Search Indexes

You can parse static search indexes using searchIndex():

This result contains only selected properties. It returns an array of DataTransferObjects\FeedEntry with properties link, title, and description.

Complete Details

If you need all details, please fallback on $web->searchIndexRaw(...). It can be called like $web->searchIndex() and returns an array-structure.

Laravel News Links

Sharpie’s Stainless Steel Marker Case

https://s3files.core77.com/blog/images/1321714_81_117539_tRAgzyQpt.jpg

Remember that chunky stainless steel Sharpie case by Dango Products?

Dango Products

Dango Products

Perhaps in reaction to that, Sharpie is now offering their own Stainless Steel Marker Case.

A threaded collar locks your Sharpie into the barrel, and the stainless steel cap replaces the plastic cap (and has its own clip). It takes the standard Sharpie, not some special variant you have to buy.

It doesn’t appear to be sold as a standalone product, but is instead packaged with five markers. At press time I couldn’t find anyone who had these in stock, but they cost $18 per pack.

Anyone remember when Sharpie made refillable stainless steel Sharpies?

Core77

Introducing PHP 8.2: all new features and changes

https://freek.dev/og-images/e02ee09bf1c083028576d14244244726/2382.png

PHP 8.2 will be released on 8th December 2022, and is a minor release compared to 8.0 and 8.1. This can be partly attributed to the departure of Nikita Popov as one of the most significant contributors to the PHP language. The PHP language has a lot of maintainers and isn’t built by one person, but Nikita was one of the most active of them. Features like union types, typed properties, named arguments, and arrow functions, to name a few, were all added by Nikita.

This blog post is a slightly edited excerpt from Front Line PHP, a beautifully designed book by Spatie on how to build modern applications using PHP 8.2. It covers PHP’s type system, static analytics, how to use the latest features, and much more!

The news of the departure echoed through the PHP community, and a significant problem had to be acknowledged. Other languages like JavaScript/TypeScript, C#, and Java were backed by large companies with many assets at their disposal. In contrast to the PHP core team, which primarily relies on volunteers and a few small companies to pay some contributors.

The unclear future for the PHP language due to the recent news and a lack of paid core developers was the primary motivation to establish the PHP Foundation in November 2021. Their mission statement was as follows:

The PHP Foundation will be a non-profit organization whose mission is to ensure the long life and prosperity of the PHP language.

The PHP Foundation is backed by companies and individuals in the PHP community and will fund developers working on the PHP core to keep the language getting forward as it was in the past years.

I can proudly say that Spatie is sponsoring the PHP Foundation, and you can too, for as little as a cup of coffee!

The PHP 8.2 release falls right into the first year of the PHP Foundation, and some organizational structures had to be set up. The first developers were selected and eventually hired to work for the foundation during this period. These things take some time, so we consider the PHP 8.2 release one of the more minor releases because major things moved in the PHP core team. Luckily we know this is going to change thanks to the PHP Foundation. The future is looking bright for PHP!

Let’s go to a number of improvements included in PHP 8.2.

Dynamic properties

PHP has always had a dynamic nature. The community decided that some of the language’s earliest features were too dynamic of nature in the past years. An excellent example of such a dynamic feature are dynamic properties. It is currently allowed to set a property on any object that doesn’t exist in the class. For example, this is perfectly valid in PHP:

class User{}

$user = new User();
$user->email = 'info@spatie.be';

Dynamic properties provide an unseen amount of flexibility but also open the door to unexpected behavior and, thus, bugs that are difficult to fix. Let’s say you rename the property here. Then you should remember all the other places where this property is being used because it needs to be renamed. Static analysis and an IDE can assist you a bit here. But defining properties in your class will always provide more insight into these tools than dynamically setting them. And you’ll probably write a lot fewer bugs too!

Further, reading an undefined property will give you feedback that something went wrong because you’ll receive a warning. Whereas writing to an undefined property can be done without any warning. I always want to have a stable type system where I’m sure that properties exist because I strictly define them. Dynamic properties offend this rule, and that’s why I’m not using them.

Starting with PHP 8.2, dynamic properties were deprecated. The example above will now throw a deprecation warning. Notice that when you have implemented the magic __get() or __set() methods, getting and setting dynamic properties on an object is still perfectly valid.

Further, you can still enable the functionality of dynamic properties by adding the AllowDynamicProperties attribute to the class:

#[AllowDynamicProperties]
class User{}

$user = new User();
$user->email = 'info@spatie.be';

This attribute is inherited by all the children of the class and is added by default to the stdClass. So extending your class from stdClass will also enable this dynamic behavior:

class User extends stdClass{}

$user = new User();
$user->email = 'info@spatie.be';

Lastly, readonly classes can never have dynamic properties. Adding the AllowDynamicProperties attribute to a readonly class will result in an error.

Deprecations in string interpolation

String interpolation is a nifty feature that allows you to use variables in strings like this:

"Hello there, {$name}"

Did you know you could also do this:

"Hello there, ${name}"

I certainly did not. Though the syntax almost looks the same, it behaves quite differently. Due to these differences in semantics and enough options to use string interpolation, the feature was deprecated with the release of PHP 8.2.

Sensitive parameters

PHP allows you to look at the stack trace and all the parameters associated with each stack frame when something goes wrong. Which is extremely helpful for debugging but can be disastrous for sensitive data. Let’s say you have a function like this:

function login(
    string $name,
    string $password
) {
    throw new Exception('Whoops!');
}

The password is now included in the stack trace created by the exception, which means it is available for anyone to see when you’ve misconfigured your application. When you’ve configured an external bug tracking service to which you send your stack traces, the password will be sent to the external service with a bunch of debug data, which you want to avoid.

You can easily check this by catching the error and dumping the arguments from the first stack frame:

try {
    login('Freek', 'secret');
} catch (Exception $exception) {
    var_dump($exception->getTrace()[0]['args']);
}

Which will effectively output the following:

array(2) {
  [0]=> string(5) "Freek"
  [1]=> string(6) "secret"
}

In PHP 8.2, a SensitiveParameter attribute was added, replacing the parameter in stack traces. You can use it like this:

function login(
    string $name,
    #[SensitiveParameter]
    string $password
) {
    throw new Exception('Whoops!');
}

Now the output from catching the exception looks like this:

array(2) {
  [0]=> string(5) "Freek"
  [1]=> object(SensitiveParameterValue)#2 (0) {}
}

The PHP developers chose not to replace the parameter with a dubious string like ‘hidden’, but they created a new DTO, SensitiveParameterValue. This DTO allows you to retrieve the original sensitive value within your code when that would be required. Still, it makes it hard to expose the value accidentally to users of your application or an external service.

Constants in traits

Before PHP 8.2, it was not allowed to add constants to traits. Which was a language discrepancy since traits had access to the constants of the classes where they were being used. But you could strictly not define that a constant would exist in a class, luckily this has been fixed:

trait WithSpatieApi {
    protected const SPATIE_API_VERSION = 1;
}

PCRE no-capture modifier

A small addition to the PHP 8.2 regex extension is the no-capture modifier which will only capture named capture groups. You can add this modifier by appending n to the end of your regex. Let’s say you want to capture the abbreviation in these written numbers: 1st, 2nd, 3rd, and so on. You can write a regex like this:

// [0 => '5th',1 => '5', 2 => 'th']
preg_match('/([0-9]+)(st|nd|rd|th)/', '10th', $matches); 

With named capture groups, you can easily name the desired group:

// [0 => '5th', 1 => 5, 'abbreviation' => 'th', 2 => 'th']
preg_match('/([0-9]+)(?P<abbreviation>:st|nd|rd|th)/', '5th', $matches);

Using the no-capture modifier, PHP will only include the named group:

// [0 => '5th', 'abbreviation' => 'th', 1 => 'th']
preg_match('/([0-9]+)(?P<abbreviation>:st|nd|rd|th)/n', '5th', $matches);

Random extension

PHP 8.2 is bundled with a new extension which adds a more OOP-friendly way to work with random number generation and other randomizing operations. A new Randomizer class was added to enable the functionality. You can, for example, shuffle a string like this:

use Random\Randomizer;

$randomizer = new Randomizer();

$randomizer->shuffleBytes('Hello World'); // example output: "eWrdllHoo l"

Or shuffle an array:

$randomizer->shuffleBytes(['a', 'b', 'c', 'd']); // example output: ['b', 'd', 'a', 'c']

Getting a number in a certain interval can be done as such:

$randomizer->getInt(0, 100); // example output: 42

An added benefit is that you can provide a pseudo-random number generator (PRNG) to the randomizer. PHP has several PRNG engines built-in: Mt19937, PcgOneseq128XslRr64, Xoshiro256StarStar, and Secure. Notice that only the last engine is suitable for cryptographic random number generation. This engine model allows more safe/fast engines to be added quickly in the future. You can even create your engine to be used with the randomizer.

You can set the engine for the randomizer as such:

use Random\Engine\Mt19937;
use Random\Randomizer;

$randomizer = new Randomizer(new Mt19937());

Closing, you can now also set the seed of the engine being used for the randomizer. The seed is mostly a random value from which the other random values are derived. When you run this example twice, the number generated will be different every time:

$randomizer = new Randomizer();

$randomizer->getInt(0, 100);

When you set a value for the seed by using the Mt19937 engine, then the randomly generated value will each time be the same:

$randomizer = new Randomizer(new Mt19937(42));

$randomizer->getInt(0, 100);

This behavior can be helpful within a test or local environment, where it will be helpful if restarting a piece of code during debugging will provide the same outcome every time. Even when randomizing operations are being used.

Disjunctive normal form types

Union and intersection types added lots of benefits to the language. With the introduction of disjunctive normal form types (DNF types), you can construct even more complex types. DNF types were added in PHP 8.2, allowing you to make intersection and single types unions. This allows you to add even more granular type-checking to your code.

Let’s take a look at the example we had earlier. What if we had an interface like this:

interface WithUrlSegments
{
    public function getUrlSegments(): array;
}

A class Page can now implement this class:

class Page implements WithUrlSegments { /* … */ }

We can now extend the type of our URL function as follows:

function url((WithUuid&WithSlug)|WithUrlSegments $object): string { /* … */ }

The function now allows objects which implement both the WithUuid and WithSlug or objects implementing the single <hljs type WithUrlSegments interface.

The most prominent use case for DNF types will probably be to make intersection types nullable:

function url((WithUuid&WithSlug)|null $object): ?string { /* … */ }

DNF types must adhere to the rules of the DNF form, which means that you can only construct types as a union of intersections and single types. This means that a type like this is not allowed:

interface A {}
interface B {}
interface C {}

function url((A|B)&C $object): string { /* … */ }

It can be rewritten into a union of intersections as follows:

function url((C&A)&(C&B)$object): string { /* … */ }

Readonly classes

Sometimes you want to create a complete immutable DTO which only contains readonly properties. You could, in this case, create a class and define all the properties as readonly:

class CustomerDTO
{
    public function __construct(
        public readonly string $name, 
        public readonly string $email, 
        public readonly DateTimeImmutable $birth_date,
    ) {}
}

Doing this can be quite time-consuming, and every time you add a new property, you should remember to make it readonly. PHP 8.2 introduced a significantly better solution to this problem: readonly classes. With readonly classes, you declare a class as readonly once, and all properties within it will be readonly from that point on:

public readonly class CustomerDTO
{
    public function __construct(
        string $name, 
        string $email, 
        DateTimeImmutable $birth_date,
    ) {}
}

The individual properties of the readonly class behave as readonly properties, so all the behavior we described earlier still applies. Further, it is also impossible to add static properties to a readonly class, resulting in a fatal error.

You can only create a readonly class that extends from a readonly class. This rule implies that it is prohibited to make a readonly class that extends from a non-readonly class and the other way around where you create a non-readonly class that extends from a readonly class. Both these cases will result in a fatal error.

Improvements to enums

When enums were introduced, it was impossible to fetch the name and value properties from an enum in a constant expression. We’ve summed up some cases of constant expressions where this was the case:

class Post
{
    #[DefaultValue(Status::Draft->name)]
    public string $status = Status::Draft->name;

    public function updateStatus(string $status = Status::Draft->name): void
    {
        /** … */
    }
}

const STATUS = Status::Draft->name;

As from PHP 8.2, all these syntaxes are valid and will not throw errors anymore.

Deprecations in partially supported callable syntax

PHP 8.2 will deprecate some callable syntaxes because they are inconsistent:

"self::method"
"parent::method"
"static::method"
["self", "method"]
["parent", "method"]
["static", "method"]
["Foo", "Bar::method"]
[new Foo, "Bar::method"]

These syntaxes could be used with the callable type and the functions is_callable() and call_user_func(). Oddly, these syntaxes could be used in some cases but not with the $callable() syntax like this:

class Manager
{
    public function execute(string $method)
    {
        $callable = "self::{$method}";

        $callable();
    }

    private function destruct(){ /** ... */ }
}

Further, these syntaxes are context-dependent. The types behind self and static can change depending on the location from where they were called, which could result in unexpected behavior when they call private methods.

That’s why they’ve been deprecated from being used with the callable type and is_callable() and call_user_func() functions. Updating the example above can be quickly done as such:

class Manager
{
    public function execute(string $method)
    {
        $callable = self::class . "::{$method}";

        $callable();
    }

    private function destruct(){ /** ... */ }
}

Other callable syntaxes like these are still valid to be used:

'function'
['SomeClass', 'someMethod']
'SomeClass:: someMethod']
[new SomeClass(), 'someMethod']
[$this, 'someMethod']
Closure::fromCallable()
function(...)

A function to reset the memory peak usage

In PHP, it has been possible to measure peak memory usage. It was previously never possible to reset this peak, so measuring a second peak after a first one was impossible.

For example, when you create two arrays and want to measure the memory peak usage for the second array, the value will be equal to the memory usage peak from the creation of the first array:

range(0, 100_000);

memory_get_peak_usage(); // 2509760

range(0, 100);

memory_get_peak_usage(); // 2509760

The memory_reset_peak_usage function was added in PHP 8.2 allows you to reset this peak so you can measure it again:

range(0, 100_000);

memory_get_peak_usage(); // 2509760

memory_reset_peak_usage();

range(0, 100);

memory_get_peak_usage(); // 398792

The mysqli::execute_query method

PHP 8.2 adds a new method to the mysqli extension allowing you to prepare, bind parameters, and execute the SQL statement in one method. In the past, a lot of operations were required to perform a query:

$query = 'SELECT * FROM posts WHERE id = ?';
$statement = $connection->prepare($query);
$statement->bind_param('i', $id);
$statement->execute();
$result = $statement->get_result();

This code can now be rewritten as such:

$result = $mysqli->execute_query('SELECT * FROM posts WHERE id = ?', [$id]);

In closing

Even though PHP 8.2 is a smaller release than usual, it still packs a few niceties and bugfixes. To learn more about modern PHP check out Front Line PHP, a beautifully designed book on how to build modern applications using PHP 8.2. It covers PHP’s type system, static analysis, how to use the latestest features, and much more.

We’ve also created a handy cheat sheet that showcases all modern PHP features.

If you are a visual learner, you can opt to watch this video on new PHP 8.2 by JetBrains.

Laravel News Links

How to Build a Live Search using Laravel, Livewire, and Meilisearch

https://www.iankumu.com/blog/wp-content/uploads/2022/10/Laravel-Search.png

Free Laravel Guide

Grab your free Laravel Guide today and see how to boost your Laravel Experience

One of the most powerful features of Laravel is its ability to integrate with many different services. By default, Laravel integrates with the Meilisearch service. This allows you to easily query your data using the Laravel Eloquent ORM. But what if you want to build a custom search page? Well, it’s easy to do with a couple of tweaks. This article will show you how to create a custom search page using Laravel, Livewire, and Meilisearch.

What is Meilisearch?

Meilisearch is an open-source search engine that is built using Rust and can be integrated into any application to provide Full-Text Search. It comes with a lot of features that we can use to our advantage as developers. Because it is built using Rust, it is blazing fast making it a useful utility for any application. Laravel, through Laravel Scout, comes with an already implemented solution for meilisearch making it easy to use.

But What is Laravel Scout?

Laravel Scout is a first-party Package developed by Taylor Otwell that can be used to add Full-Text Search to your Eloquent Models. It makes it easy to search through your Eloquent Models and return the search results in a clean fashion.

Let’s get started.

How to integrate Full-Text Search into Laravel

Before we start, we need a couple of things;

Once you have created a new Laravel Application and downloaded and installed Meilisearch, you can now follow these steps.

Install Laravel Breeze

If you have created a new Laravel Application, you can install a starter kit. I will install Laravel breeze in this tutorial.

composer require laravel/breeze 

Prepare Model and Migration

We now need a Model to work with. I am going to use an Article Model which will contain an article name, author name and article content

php artisan make:model Articles -m

This command will create an Article Model and its corresponding migration file.

//App/Models/Articles.php
<?php

namespace App\Models;

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

class Articles extends Model
{
    use HasFactory;

    protected $fillable = [
        'name', 'author', 'content'
    ];
}
<?php

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::create('articles', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->longText('content');
            $table->string('author');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('articles');
    }
};

Seed the Database

When testing, I usually use Factories and Seeders to speed up my development process. To do so, we can create an Article Factory

php artisan make:factory ArticleFactory 

We can use faker to seed the database and then register the factory in the Database seeder

//database/factories/ArticlesFactory.php
<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Articles>
 */
class ArticlesFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition()
    {
        return [
            'name' => $this->faker->words(2, true),
            'content' => $this->faker->sentence(),
            'author' => $this->faker->name()
        ];
    }
}
//database/seeders/DatabaseSeeder.php
<?php

namespace Database\Seeders;

// use Illuminate\Database\Console\Seeds\WithoutModelEvents;

use App\Models\Articles;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        Articles::factory(20)->create();
    }
}

To seed the database, db:seed command will be of help

php artisan db:seed 

Install and Configure Livewire

The next step is to install the livewire package. Livewire will be a major help in adding reactivity to our application.

composer require livewire/livewire

We then need to include the livewire Javascripts in the app.blade.php file in the resources/views/components folder.

...
    @livewireStyles
</head>
<body>
    ...
 
    @livewireScripts
</body>
</html>

Create Article Component

Livewire helps us scaffold components fast using the make:livewire command.

php artisan make:livewire Articles

This creates a Component which we can reuse in multiple places.

This command creates two files, one in the App/Http/Livewire Folder and another one in the resources/views/livewire folder. These two will be essential in creating our full-text search

Through laravel breeze, Laravel scaffolded authentication and a dashboard which we can now use to display the Articles.

We can fetch records from the database and display them using the Articles Component.


<x-app-layout>
    <x-slot name="header">
        <h2 class="font-semibold text-xl text-gray-800 leading-tight">
            
        </h2>
    </x-slot>

    <div class="py-12">
        <div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                   @livewire('articles')
                </div>
            </div>
        </div>
    </div>
</x-app-layout>

Install and Set up Laravel Scout

The next step is to install the Laravel scout package using composer

composer require laravel/scout

We can then publish the configurations

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider" 

Laravel Scout allows us to use any search driver such as database, algolia or meilisearch etc Meilisearch is a popular search engine because it is open source and can be self-hosted. It makes search easy because it handles all the technical bits such as typos.

Laravel Scout helps with all the other factors in search including indexing, updating the index and returning the results in a Laravel Friendly way. Under the hood, Scout uses Model Observers to update the records and re-index the search results in Meilisearch.

To set up Scout in our Models, we will need to include the Searchable trait in our Model

//App/Models/Articles.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable; //import the trait

class Articles extends Model
{
    use HasFactory;
    use Searchable; //add this trait

    protected $fillable = [
        'name', 'author', 'content'
    ];
}

We also need to install a few packages to be able to interact with meilisearch

composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle

We can then set the environment variables to now use Meilisearch

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey

Add Search Logic

Before performing a Search, we need to index our records in meilisearch using the scout:import command

php artisan scout:import "App\Models\Articles"

Now, we can use Eloquent to perform a search on our records

We can update our Livewire Component to include the Search Logic

//App/Livewire/Articles.php
<?php

namespace App\Http\Livewire;

use App\Models\Articles as ModelsArticles;
use Livewire\Component;


class Articles extends Component
{

    public $search = '';
    public $articles;

    public function render()
    {
        if (empty($this->search)) {

            $this->articles = ModelsArticles::get();
        } else {
            $this->articles = ModelsArticles::search($this->search)->get();
        }

        return view('livewire.articles');
    }
}

Add Search Input Field

On the Articles Table, we can add a search input field that will receive the query and send it to the backend.

Livewire provides a cool way to perform data binding which we can use to our advantage. Using the wire:model property, we can pass the query onto the server and get the results back synchronously.

We can use one of the tailwind components templates to scaffold a view.

<!-- resources/view/livewire/articles.blade.php -->
<div>
     <!-- component -->
     <link rel="stylesheet" href="https://demos.creative-tim.com/notus-js/assets/styles/tailwind.css">
     <link rel="stylesheet" href="https://demos.creative-tim.com/notus-js/assets/vendor/@fortawesome/fontawesome-free/css/all.min.css">

       <section class="py-1 bg-blueGray-50">
           <div class="w-full xl:w-8/12 mb-12 xl:mb-0 px-4 mx-auto mt-24">
           <div class="relative flex flex-col min-w-0 break-words bg-white w-full mb-6 shadow-lg rounded ">
               <div class="rounded-t mb-0 px-4 py-3 border-0">
               <div class="flex flex-wrap items-center">
                   <div class="relative w-full px-4 max-w-full flex-grow flex-1">
                   <h3 class="font-semibold text-base text-blueGray-700">Articles</h3>
                   </div>
                   <div class="relative w-full px-4 max-w-full flex-grow flex-1 text-right">
                <input type="text" placeholder="Search..." wire:model="search">
                </div>
               </div>
               </div>

               <div class="block w-full overflow-x-auto">
               <table class="items-center bg-transparent w-full border-collapse ">
                   <thead>
                   <tr>
                       <th class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
                                   Article name
                        </th>
                   <th class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
                                   Content
                    </th>
                   <th class="px-6 bg-blueGray-50 text-blueGray-500 align-middle border border-solid border-blueGray-100 py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left">
                                   Author
                    </th>
                   </thead>

                   <tbody>
                        @if (!$articles->isEmpty())
                            @foreach ($articles as $article)

                                <tr>
                                    <th class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4 text-left text-blueGray-700 ">
                                    
                                    </th>
                                    <td class="border-t-0 px-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap p-4 ">
                                        
                                    </td>
                                    <td class="border-t-0 px-6 align-center border-l-0 border-r-0 text-xs whitespace-nowrap p-4">
                                        
                                    </td>
                                </tr>
                            @endforeach
                        @else
                            <td class="border-t-0 px-6 align-center border-l-0 border-r-0 text-xs whitespace-nowrap p-4">
                            No Results Found
                            </td>
                        @endif
                   </tbody>

               </table>
               </div>
           </div>
           </div>

       </section>
</div>

Livewire handles getting the query from the input field, makes an ajax request to the backend and returns the results back to the frontend.

This makes it easy to create a live search with minimal effort.

Live Search

Display Results

Once Scout returns the results, Livewire takes care of displaying them on the table.

Laravel Search
Searched Results

Conclusion

In this article, we have covered how to create a live search using Laravel Livewire and Meilisearch. We covered how to set up your application and include all the features needed for Full-Text Search. I hope this article was insightful. Thank you for reading

Free Laravel Guide

Grab your free Laravel Guide today and see how to boost your Laravel Experience

Laravel News Links

Are You Nuts? Know your Fishing Knots! – Alberto Knot

https://www.alloutdoor.com/wp-content/uploads/2022/11/20221117_203049-e1668736058426.jpg

This week I’m covering another line-to-line connection knot, the Alberto Knot. This knot was invented by “Crazy Alberto” Alberto Knie for the specific purpose of connecting braided lines to monofilament lines. Being an avid surf fisherman from the east coast, often fishing in windy conditions Alberto wanted a strong knot that you can easily tie in the wind. The Alberto knot is similar to the Albright Knot from last week in which it also is tied to a doubled leader line. They also share the trait of being able to run through guides easily. For demonstration purposes, the black paracord is a stand-in for the thicker monofilament leader and the pink braid is a stand-in for your braided mainline.

Editor’s Note: I’m a novice at knot tying and enjoyed this step-by-step writeup from Eugene. I have also found the Animated Knots website to be helpful in the past.

Alberto Knot – Step 1

Start off with your main braided line and your thicker monofilament leader line, and then double up your monofilament leader line into a loop.

Are You Nuts? Know your Fishing Knots! – Alberto Knot

Step 2

The braided line is then run through the loop of the thicker leader line. You want to run about 10″ of the braided line through that loop.

Are You Nuts? Know your Fishing Knots! – Alberto Knot

Step 3

Holding the loop of the leader line with your left hand, start wrapping the braided line around the doubled leader line. You want to make 7 even wraps around the doubled loop of line.

Are You Nuts? Know your Fishing Knots! – Alberto Knot

Step 4

Once you finish the first seven wraps up the loop, you’re going to make seven more wraps back down the loop. Make sure the wraps are going right over the previous loops. Then run the tag end of the braided line back through the loop of your leader.

Are You Nuts? Know your Fishing Knots! – Alberto Knot

Step 5

Once the tag end is back in the original loop, evenly start pulling the Alberto Knot to tighten up the wraps. Once the wraps are all tight you can then cut off the tag ends and your Alberto Knot is ready to be fished.

Are You Nuts? Know your Fishing Knots! – Alberto Knot

The post Are You Nuts? Know your Fishing Knots! – Alberto Knot appeared first on AllOutdoor.com.

AllOutdoor.com

Hidden #Laravel Tip – The Fluent Class

http://img.youtube.com/vi/8PqgRoCe0N0/0.jpgHere, we will be looking at one of the hidden Laravel features that you might not know about. It is Fluent class. The best way to access array related data.Laravel News Links

The Best Air Fryer Toaster Oven

https://cdn.thewirecutter.com/wp-content/media/2022/11/airfryertoasterovens-2048px-1826-3×2-1.jpg?auto=webp&quality=60&width=630&dpr=2

The Best Air Fryer Toaster Oven

Air frying has come full circle. When we started testing pod-shaped air fryers in 2017, we concluded that they were too cramped and not versatile. We’ve since come around, but we still think convection toaster ovens (which use the same technology) can cook a wider variety of foods more evenly, if a little slower. Now, more and more companies are bridging the gap by making amped-up convection toaster ovens—sold as “air fryer toaster ovens”—with extra-powerful fans that produce crispy results in shorter times. After testing dozens of models, we think the Breville Smart Oven Air Fryer Pro is the only one that’s both an excellent air fryer and an excellent toaster oven—but it’s pricey.

Dismiss

Wirecutter: Reviews for the Real World

10 Commandments of Concealed Carry

https://cdn.athlonoutdoors.com/wp-content/uploads/sites/8/2008/10/10-Commandments-of-Concealed-Carry-2.jpg

Carrying a lethal weapon in public confers a grave power that carries with it great responsibilities. Those who lawfully engage in the practice realize that. Those who are considering concealed carry need to know what those experienced people know.

1 – If You Carry Concealed, Always Carry

The criminal is the actor, and the armed citizen is the reactor. The typical violent criminal arms himself only when he intends to do something with it. He picks the time and place of the assault, and initiates the attack. Therefore, he doesn’t need to worry about self-defense.

The armed citizen, the intended victim, does not know when or where that attack will come. Therefore, he or she must be constantly prepared and constantly vigilant. The “pistol-packer” learns to pick a comfortable holster and an appropriately sized handgun, and “dress around the firearm.” After a few days, or a few weeks, it becomes second nature to wear it.

When the defender does not know when the attack will come, the only reasonable expectation of safety lies in being always armed.

2 – Don’t Carry Concealed If You Aren’t Prepared To Use It

There is a great irony that attaches to the defensive firearm. When you analyze a great many defensive gun usages (DGUs) you discover that the great majority of the time, the protection weapon does its job with no blood being shed. Usually, the offender who is confronted with the prospect of being shot in self-defense either breaks off and runs or surrenders at gunpoint.

“The person who is prepared to kill if he or she must, is the person who is least likely to have to do so…”

Its most important asset turns out to be its power to deter. The irony is the fact that its power to deter comes directly from its power to kill.

Understand that criminals do not fear guns. They are, after all, an armed subculture themselves. What they fear is the resolutely armed man or woman who points that gun at them. Criminals are predators, and their stock in trade is their ability to read people and recognize victims. They are very, very good at reading “body language” and determining another’s intent to fight, or lack thereof. In short, you’re not likely to bluff them.

The Message You Send

If you carry a gun, you must be absolutely certain that you can use deadly force. The person who is hesitant or unwilling to do so will, in the moment of truth, communicate that vacillation to the hardened criminal they are attempting to hold at gunpoint. In such a case, it is quite likely that the offender will jump them, disarm them, and use the hesitant defenders’ own weapons against them.

If, however, that same criminal realizes that he is facing a resolute person who will, in fact, shoot him if he takes one more transgressive step, he is most unlikely to take that step.

The irony: The person who is prepared to kill if he or she must, is the person who is least likely to have to do so.

3 – Don’t Let The Gun Make You Reckless

Circa 1970, armed citizen Richard Davis invented the Second Chance vest, concealable body armor that for the first time could be worn constantly on duty, under the uniform, by any police officer. Some alarmists speculated that “being made bulletproof” would cause cops to become reckless. Those fears turned out to be totally unfounded. As any officer who has worn armor can attest, the vest is a constant reminder of danger and, if anything, makes its wearer more cautious.

“Like an officer’s body armor, the armed citizen’s gun is a reminder of danger, a symbol of the need for caution…”

It is much the same with concealed firearms in the hands of responsible private citizens. People unfamiliar with the practice fear that “the trigger will pull the finger,” of the carrier. As a result, armed citizens will go looking for a chance to exercise their deadly power. This, too, is a largely unfounded belief.

A Symbol of the Need for Caution

The collective experience of ordinary, law-abiding people who carry guns is that they don’t feel a sudden urge to go into Central Park at three o’clock in the morning and troll for muggers. They learn that being armed, they are held to “a higher standard of care,” in the eyes of the law. And are expected to avoid situations like traffic arguments. This is because they could escalate and, with a deadly weapon present, turn into killing situations.

Like an officer’s body armor, the armed citizen’s gun is a reminder of danger. A symbol of the need for caution. The late, great big game hunter and gun writer Finn Aagard once wrote, “Yet my pistol is more than just security. Like an Orthodox Jewish yarmulke or a Christian cross, it is a symbol of who I am, what I believe, and the moral standards by which I live.”

4 – Get The License!

You’ll hear some absolutists say, “No government has the right to permit me to carry a gun! I don’t need no stinking permit! The Second Amendment is my license to carry!”

“If you carry, make sure you carry legally…”

That is the sound of someone asking to go to jail. Like it or not, the laws of the land require, in 46 of the 50 states, a license to carry concealed. In two states, there is no legal provision for the ordinary citizen to carry at all. Realize that things are not as we wish they were; things are as they are. If things were as we wish they would be, we wouldn’t need to carry guns at all.

If you are diligent about studying carry license reciprocity, and about seeking non-resident concealed carry permits in states that don’t have reciprocity, you can become legal to carry in some forty or more states. It can get expensive, and it can get tiresome. However, allowing yourself to be made into a felon and being ramrodded through the courts is much more expensive. Not to mention far more tiresome.

Bottom line: if you carry, make sure you carry legally.

Know what to do with your carry gun. Above, the live-fire portion of an LFI-I class is in progress in Wisconsin.
Know what to do with your carry gun. Above, the live-fire portion of an LFI-I class is in progress in Wisconsin.

5 – Know What You’re Doing

You wouldn’t drive an automobile without knowing the rules of the road. Do not keep or carry lethal weapons for defense without knowing the rules of engagement. It is a myth to believe that you can shoot anyone in your home. When Florida rescinded the requirement to retreat before using deadly force if attacked in public, the anti-gun Brady Center introduced a publicity campaign claiming that the new law allowed Floridians to shoot anyone who frightened them. This, of course, was blatantly untrue, but a great many people believed it to be so because “they heard it on TV” or “they saw it in the paper.” Such dangerous misconceptions can cause the tragic death of people who don’t deserve to be shot, and can get good people sent to prison.

“A person who opens fire with a gun they don’t know how to shoot is a danger to all…”

It is the practitioner’s responsibility to “learn the rules of the road” when they take the path toward armed self-defense. There are many firearms training schools. At least one, the author’s Lethal Force Institute, specializes in teaching the rules of engagement. Information is available under the LFI section at www.ayoob.com. It is wise to take local classes that emphasize the rules of “deadly force decision-making.”

Understand the ramifications of concealed carry. Psychologist Aprill explains the emotional aftermath of using deadly force at an LFI-I class in Florida.
Understand the ramifications of concealed carry. Psychologist Aprill explains the emotional aftermath of using deadly force at an LFI-I class in Florida.

A Trained Shooter is a Safe Shooter

Similarly, a person who opens fire with a gun they don’t know how to shoot is a danger to all. If you need the firearm for its intended purpose, you will be under extreme stress. Learn to shoot under pressure. Quick drawing from concealment, safe holstering, proper tactics, and much more are on the curriculum. Likewise, they require practice if you’re serious about defending yourself and your loved ones to the best of your ability.

6 – Concealed Carry Means Concealed

A very few people carrying guns for the first time feel an irresistible urge to let others see that “they’ve got the power.” First-time carriers and rookie cops, usually young in both cases, may fall into this trap. It is a practice to avoid for several reasons.

“A harasser who has picked you as his victim and knows you carry a gun can create a situation where there are no other witnesses present…It is his word against yours…”

In most of this society, the only people the general public sees carrying guns in public are uniformed “protector figures,” such as police officers and security guards. When they see someone not identifiable as such, who is carrying a lethal weapon, they tend to panic. This makes no friends among the voting public for the gun owners’ rights movement—you do not make people into friends and sympathizers, by frightening them—and can lead to a panicky observer getting the wrong idea and reporting you to the police as a “man with a gun.” This can lead to all sorts of unpleasant confrontations.

False Accusations

Moreover, a harasser who has picked you as his victim and knows you carry a gun can create a situation where there are no other witnesses present. He can then make the false claim that you threatened him with the weapon. This is a very serious felony called Aggravated Assault. It is his word against yours. The fact that you are indeed carrying the gun he describes you pointing at him can make his lie more believable than your truth, to the ears of judge and jury.

MCRGO On Open Carry

MCRGO, Michigan Coalition of Responsible Gun Owners, is directly responsible for getting reform concealed carry legislation enacted in their state. Likewise, it has been in the forefront of fighting for the rights of armed citizens in that state. MCRGO’s Steve Dulan, in the organization’s Weekly E’News of 6/23/08, had some cogent points to make on the topic of private citizens carrying handguns visibly in public:

“Open carry of firearms, subject to MCL 750.234d, it is legal to carry a visible pistol in public. MCRGO has not adopted an official position on this subject,” wrote Dulan, who continued, “I agree with Ted Nugent and many others that it is a bad idea in almost every situation. Tactically, you are giving up the element of surprise should you face a deadly force situation. Furthermore, you run the risk of being called in to 9-1-1 as a ‘man with a gun.’ I have been on police ride-alongs when this call comes over the radio. It creates a very dangerous situation for all concerned. I do not carry openly. I have a CPL (Concealed Pistol License) and take care to choose a gun and holster that, along with appropriate clothing, allow me to keep my gun concealed unless/until I need it to save a life.”

The Open Carry Emergency Option

As cogent and valid as Steve Dulan’s arguments are, it still makes sense to have legal open carry available as an emergency option. If the wind blows your coat open and reveals the gun, an open carry provision assures you’ve committed no crime. If someone who has not yet felt the need to get a concealed carry license suddenly begins getting death threats, open carry provides an emergency avenue of self-protection until the paperwork can be processed to acquire the license to carry the weapon discreetly out of sight.

7 – Maximize Your Firearms Familiarity

The more you work with the firearm, the more reflexively skilled you’ll become in its emergency use and safe handling. If your home defense shotgun is a Remington 870, then when you go claybird shooting or hunting, use an 870 pump gun with a barrel and choke appropriate for each task. However, if you are a target shooter who uses the 1911 pistol platform at bull’s-eye matches and have become deeply familiar with it, it makes sense to acquire a concealable 1911 to use as your concealed carry gun, so that the ingrained skill will directly transfer. Likewise, if a double-action .44 Magnum is your hunting revolver, and another double-action revolver is your home defense gun, it makes sense to choose a carry-size revolver as your concealment handgun when you’re out and about.

Consider training classes or competition shoots where your chosen defensive firearm is appropriate to the course of fire. This skill-building will translate to self-defense ability if you ever have to use your concealed carry gun for defense. If training ammunition is too expensive, consider a .22 conversion unit for your semiautomatic pistol. Or you can purchase a .22 caliber revolver the same size as your defensive .38 or .357. The more trigger time you have with a similar gun, the more confidence/competence you’ll have with your carry gun. Especially if you can’t afford to practice as much as you’d like with the carry gun itself.

It’s “asking for trouble” to “go where you’re not wanted.” Taking time to read the fine print on the door of this jewelry store in the usually gun-friendly NH…

8 – Understand The Fine Points

Every state has different laws insofar as where you can and can’t carry a gun. It’s your responsibility to know all the details. In one state, it may be against the law to carry a weapon in a posted “no-gun” zone. In another, that sign may have no weight of law at all behind it. However, in a third, they may ask you to leave if they spot your gun. If you do not depart, you will be subject to arrest for Trespass After Warning.

In New Hampshire, it’s perfectly legal to carry your gun into a bar and sit down to have a drink. If you do the same in Florida, it’s an arrestable offense. Although you may have a cocktail in a restaurant with a liquor license. However, you must sit in a part of the establishment that earns less than 50% of its income from selling alcoholic beverages by the drink. In North Carolina, you can’t even walk into a restaurant that has a liquor license, with a gun on. And, perhaps strangest of all, in the state of Virginia, it’s illegal to enter a tavern with a concealed handgun. But it’s perfectly legal to belly up to the bar and sip a whiskey while open carrying a loaded handgun.

You can find a superb current compendium of gun laws in the 50 states at www.handgunlaw.us. Review it frequently for possible changes.

9 – Carry An Adequate Firearm

If you carry a single-shot, .22 Short caliber derringer, law enforcement will consider you armed with a deadly weapon. However, you will not be adequately prepared to stop a predictable attack by multiple armed assailants. Most experts recommend a five-shot revolver as the absolute minimum in firepower. Likewise, the .380/9mm/.38SPL range is the minimum potency level in terms of handgun caliber.

“Once you’ve found a carry gun that works for your needs, it’s a good idea to acquire another that’s identical or at least very similar…”

It is a good idea to carry spare ammunition. Many people in their first gunfight have quickly found themselves soon clicking an empty gun. A firearm without spare ammunition is a temporary gun. Moreover, many malfunctions in semiautomatic pistols require a fresh (spare) magazine to rectify. Some fear that carrying spare ammo will make them look paranoid. They need to realize that those who don’t like guns and dislike the people who carry them, will consider carrying the gun without spare ammunition to still be paranoid. It’s an easy argument to win in court. Cops carry spare ammunition. So should you.

Carrying a Concealed Backup

Carrying a second gun has saved the lives of many good people. For example, when a criminal’s bullet hits the primary weapon, rendering it unshootable. Or when it is knocked out of the defender’s hand, or a criminal snatches it away. Also, when the first gun runs out of ammo and there is no time to reload. The list of reasons is endless. It suffices to remember the words of street-savvy Phil Engeldrum: “If you need to carry a gun, you probably need to carry two of them.”

At the very least, once you’ve found a carry gun that works for your needs, it’s a good idea to acquire another that’s identical or at least very similar. If you have to use the first gun for self-defense, it will go into evidence for some time. But you want something you can immediately put on to protect yourself from vengeful cronies of the criminal you had to shoot. If the primary gun has to go in for repair, you don’t want to be helpless or carrying something less satisfactory while you’re waiting to get it back.

10 – Use Common Sense

The gun carries with it the power of life and death. That power belongs only in the hands of responsible people who care about consequences. Likewise, those who are respectful of life and limb and human safety. Carrying a gun is a practice that is becoming increasingly common among ordinary American citizens. Common sense must always accompany it.

Didn’t find what you were looking for?

The post 10 Commandments of Concealed Carry appeared first on Tactical Life Gun Magazine: Gun News and Gun Reviews.

Tactical Life Gun Magazine: Gun News and Gun Reviews