Visualize Laravel App Data with Chartello

https://laravelnews.s3.amazonaws.com/images/chart-ln-orange.png

Chartello is a package to visualize your Laravel app data in simple dashboards:

You can create multiple dashboards to break up charts; for example, you could have a Sales dashboard and a Support dashboard. On the dashboards, you can create two kinds of panels:

  1. Trend Charts
  2. Tables

You can populate a trend chart using the following query, which contains placeholders for start and end dates:

SELECT DATE(created_at) AS x, COUNT(*) AS y

FROM users

WHERE created_at BETWEEN @start AND @end

GROUP BY x

ORDER BY x ASC

The placeholders mean your dashboards will adjust based on the selected date ranges for providing trend-based charts.

Table charts are more flexible as they can virtually accept any select combination of data and list the columns in a table:

This package also comes with a middleware to limit access to dashboards. You can configure authorization for the Chartello dashboard based on any custom logic you’d like.

You can see this package in action with the Read-only demo dashboard. You can learn more about this package, get full installation instructions, and view the source code on GitHub.

Laravel News

Mac package installer Homebrew updated with speed enhancements & more

https://photos5.appleinsider.com/gallery/53234-106658-lede-xl.jpg

Article Hero Image


AppleInsider may earn an affiliate commission on purchases made through links on our site.

Homebrew, the macOS package manager, has been updated to version 4.0, and includes speed enhancements, improvements to automatic updates, and more.

Version 4.0 of Homebrew has been released. The main improvements are better performance, and automatic updates now run daily.

Support for Windows Subsystem for Linux version 1 has been dropped. If you want to run the Linux version in WSL on Windows 10 or 11, you’ll need to upgrade to WSL 2.

The utility also now supports Glibc 2.13 or later. There’s also a new Homebrew formula to install Python 3.11.

How to upgrade your current Homebrew installation on Mac

  1. In Terminal type brew upgrade and press Return.
  2. To run the update, type in Terminal: brew update and press Return.
  3. Optionally, you can run brew doctor in Terminal to check that everything is installed and working by entering brew doctor and press Return.

At least a 64-bit Intel Mac and macOS Big Sur or later are required. Apple Silicon is fully supported. You will also need the Xcode command-line tools, which are detailed on the Installation page.

AppleInsider News

What is Data Transfer Object? Why do we use DTO in Laravel?

https://laravel-school.com/storage/asset/images/pbxT9woM6DFcbOkzD5xwZGMDE9yYNWF2gKNO25ob.png

The very first question comes in my mind is that, what exactly Data Transfer Object?

DTO stands for Data Transfer Object.
It is a design pattern used in software development to transfer data between different layers of an application.
DTOs are typically used to encapsulate data and transport it across different parts of the system.
They are commonly used in service-oriented architectures, where services communicate with each other by passing data through DTOs.
The use of DTOs helps to simplify the communication between different components of an application and improves its overall maintainability.

How to use DTO in laravel?

I am trying to visualize DTO in laravel with a real life example.

Suppose you have a Post model with the following properties:

class Post extends Model
{
    protected $fillable = [
        'title',
        'body',
        'published_at'
    ];
}

You want to create a new Post using the data submitted in a form.
However, you don’t want to pass the entire Request object to your Controller, because it may contain additional data that you don’t need. Instead, you want to create a DTO that contains only the necessary data, and pass it to your Controller.

1. Create a DTO:

I am creating a plain PHP class in the App\Http\DTO directory.

namespace App\Http\DTO;

class CreatePostDTO
{
    public string $title;
    public string $body;
    public ?DateTime $published_at;

    public function __construct(string $title, string $body, ?DateTime $published_at = null)
    {
        $this->title = $title;
        $this->body = $body;
        $this->published_at = $published_at;
    }
}

2. Use the DTO in your Controller:

Now in the PostController, I am using DTO instead of sending all the data from request.

namespace App\Http\Controllers;

use App\Http\DTO\CreatePostDTO;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    // Some other methods

    public function store(Request $request)
    {
        $postDto = new CreatePostDTO($request);

        $post = Post::create([
            'title' => $postDto->title,
            'body' => $postDto->body,
            'published_at' => $postDto->published_at,
        ]);

        return redirect()->route('posts.show', ['post' => $post]);
    }
}

In this example, we’re creating a new CreatePostDTO from the request data using constructor.
We then create a new Post object and set its properties from the DTO.
Finally, we save the Post object to the database.
This approach allows you to easily transfer data between the Controller and Model layers of your application, while optimizing for performance and maintainability.

Why do we use DTO?

We use DTOs (Data Transfer Objects) for several reasons in software development:

  • Easy Type-hint: When you use a DTO to transfer data between layers of your application, you can take advantage of PHP’s strong type system to ensure that the data being passed around is of the correct type. This can help catch errors early in the development process and improve the overall quality of your code.

  • Encapsulation: DTOs encapsulate data and protect it from unwanted modification or access. It allows for easy management and maintenance of data.

  • Data Transformation: DTOs can be used to transform data from one format to another format. This can be useful when communicating data between different layers of an application or when communicating data between different applications.

  • Separation of Concerns: DTOs help to separate the concerns of data storage from data presentation. This makes it easier to modify the data layer or the presentation layer of an application without affecting the other layer.

  • Improved Code Readability: DTOs can help improve code readability by providing a clear and concise representation of the data being transferred between layers. This can make it easier for developers to understand and work with the code.

  • Easier Testing: By using a DTO, you’re creating a clear separation between the layers of your application, which makes it easier to test each layer in isolation. This can improve the overall quality of your code and reduce the likelihood of introducing bugs into the system.

Conclusion:

In this article, I’ll demonstrate how to use DTOs in Laravel to improve the structure and organization of your codebase. By implementing DTOs, we can simplify data transfer between different layers of our application and create a more maintainable codebase.

Laravel News Links

Pinball: The Man Who Saved the Game (Trailer)

https://theawesomer.com/photos/2023/02/pinball_the_man_who_saved_the_game_t.jpg

Pinball: The Man Who Saved the Game (Trailer)

Link

This movie dramatizes the story of Roger Sharpe, an NYC journalist who escapes from his stress by playing pinball, only to realize that the game is still illegal in the city. In 1976, he helped mount a campaign to overturn the 34-year ban and prove that pinball is a game of skill, not a game of chance. In theaters 3.17.23.

The Awesomer

When to use Laravel global scopes

https://hashnode.com/utility/r?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1676907059595%2Fd3de6e98-b36d-4d65-b56b-50a8993b4fff.png%3Fw%3D1200%26auto%3Dcompress%2Cformat%26format%3Dwebp%26fm%3Dpng

Laravel global scopes are great, but I don’t see them used a lot. Instead, I see a lot of local scopes being used to achieve the same thing. With proper implementation of global scopes, the code and security would be greatly improved. Let me illustrate this with a simple example.

The local scope way

In our codebase, we have a model Transaction that stores transactions for our users. If we want to get the transaction for a logged-in user from the database, we could do it like this:

$transactions = Transaction::where('user_id', auth()->id())->get();

Since we would use this a lot throughout the codebase, it would make sense to create a local scope in the Transaction model like this:


namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Transaction extends Model
{
    

    public function scopeForLoggedInUser($query): void
    {
        $query->where('user_id', auth()->id());
    }
}

With this local scope, we can make the query like this:

$transactions = Transaction::forLoggedInUser()->get();

This is a nice DRY (Don’t Repeat Yourself) refactor that cleans it up a little.

A question you should ask yourself

Local scopes are awesome, I use them where I can to keep the code DRY. But I learned to ask myself this question when I create a local scope: “Will the majority of the queries for this model use this local scope”.

If the answer is no, keep the local scope. It makes a lot of sense to use it.

When the answer is yes

This would be the point when considering a global scope. A global scope is always applied to all queries of a given model. You can create a global scope simply by creating a class that implements Illuminate\Database\Eloquent\Scope.

<?php

namespace App\Models\Scopes;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;

class TransactionsForLoggedInUserScope implements Scope
{

    public function apply(Builder $builder, Model $model)
    {
        $builder->where('user_id', auth()->id());
    }
}

After that, you should let your model be aware of the global scope:

<?php

namespace App\Models;

use App\Models\Scopes\TransactionsForLoggedInUserScope;
use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
    

    protected static function booted(): void
    {
        static::addGlobalScope(new TransactionsForLoggedInUserScope());
    }
}

If you would now get all the transactions, it will only return the transactions of the logged-in user.

Transaction::all();

Removing a global scope

There are some scenarios thinkable where you want to create a Transaction query without the global scope applied. For example, in an admin overview or for some global statistic calculations. This can be done by using the withoutGlobalScope method:

Transaction::withoutGlobalScope(TransactionsForLoggedInUserScope::class)->get();

Anonymous Global Scopes

There is also a way to create a global scope without the use of an extra file. Instead of pointing to the TransactionsForLoggedInUserScope class, you can include the query like this:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
    

    protected static function booted(): void
    {
        static::addGlobalScope('for_logged_in_users', function (Builder $builder) {
            $builder->where('user_id', auth()->id());
        });
    }
}

Personally, I don’t like anonymous global scopes since it can bloat your model if the query is a bit complex. To be consistent throughout the entire codebase, I always tend to use the external file global scopes, even if the query is as simple as in our example.

The downside of global scopes

I won’t lie to you, if you’re working on a codebase with global scopes and are not aware of them, you might fall into situations where nothing makes sense anymore. It made me question my career choices one (very bad) day 😂. You will get totally unexpected results when tinkering. If this has happened once, you’ve learned that it is good to have the withoutGlobalScopes method in your tool belt while working in a codebase you’re not quite familiar with.

Security

If the security of your app relies on a global scope, it’s dangerous when you or a fellow developer will make changes to it in the future. Imagine in our example that someone would remove or change the global scope. Then all results for a user’s transactions would be completely faulty! This is why it’s really important to implement tests for global scopes, so this can’t happen. A typical (PEST) test for our example would look like this:

it("should only get the transactions for the logged-in user", function (){
    $user = User::factory()->create();
    $otherUser = User::factory()->create();

    $transaction_1 = Transaction::factory()->create(['user_id' => $user->id]);
    $transaction_2 = Transaction::factory()->create(['user_id' => $otherUser->id]);

    $this->actingAs($user);
    expect(Transaction::all())->toHaveCount(1)
        ->and($transaction_1->is(Transaction::first()));
});

Laravel News Links

NEW Primary Arms 3-18×44 & 4.5-27×56 FFP GLx Rifle Scopes Ready For Pre-Order

https://www.thefirearmblog.com/blog/wp-content/uploads/2023/02/PA-GLX-3-18X44F-ATHENA_04-180×180.jpg

GLx Rifle Scopes from Primary ArmsIf you’ve been visiting TFB regularly, you’ve probably noticed that Primary Arms has been busy releasing a number of new products this winter. We’ve recently announced new binoculars, a 1-6x LPVO optic, pistol red dot sights, and a 5x prism sight. Primary Arms has just announced the pre-order status for their new First Focal Plane […]

Read More …

The post NEW Primary Arms 3-18×44 & 4.5-27×56 FFP GLx Rifle Scopes Ready For Pre-Order appeared first on The Firearm Blog.

The Firearm Blog