Streamlining Data Processing with Laravel’s Pipeline Pattern

https://www.harrisrafto.eu/content/images/2024/08/20-08-2024-pipelines.png

The Pipeline pattern in Laravel provides an elegant way to pass data through a series of operations. This pattern is particularly useful for complex workflows or when you need to apply a sequence of transformations to your data. Let’s explore how to implement and leverage the Pipeline pattern in your Laravel applications.

Basic Pipeline Usage

Here’s a basic example of using Laravel’s pipeline:

use Illuminate\Support\Facades\Pipeline;

$result = Pipeline::send($order)
    ->through([
        ValidateOrder::class,
        ApplyDiscount::class,
        CalculateTax::class,
        ProcessPayment::class,
    ])
    ->then(fn ($order) => $order->complete());

In this example, an $order object is passed through a series of operations before being completed.

Creating Pipeline Steps

Each step in the pipeline should be a class with an __invoke method:

class ValidateOrder
{
    public function __invoke($order, $next)
    {
        // Perform validation logic
        if (!$order->isValid()) {
            throw new InvalidOrderException();
        }

        return $next($order);
    }
}

Passing Additional Parameters

You can pass additional parameters to your pipeline steps:

$result = Pipeline::send($order)
    ->through([
        ValidateOrder::class,
        [ApplyDiscount::class, $discountCode],
        [CalculateTax::class, $taxRate],
        ProcessPayment::class,
    ])
    ->then(fn ($order) => $order->complete());

In your pipeline step:

class ApplyDiscount
{
    public function __invoke($order, $next, $discountCode)
    {
        // Apply discount logic using $discountCode
        return $next($order);
    }
}

Using the Pipeline in Controllers

Implement the pipeline in your controller for clean, modular code:

class OrderController extends Controller
{
    public function store(Request $request)
    {
        $order = new Order($request->all());

        return Pipeline::send($order)
            ->through([
                ValidateOrder::class,
                SaveOrder::class,
                NotifyCustomer::class,
            ])
            ->then(fn ($order) => response()->json($order, 201));
    }
}

Error Handling in Pipelines

Handle exceptions within your pipeline steps:

class ProcessPayment
{
    public function __invoke($order, $next)
    {
        try {
            // Process payment logic
            PaymentGateway::charge($order->total);
        } catch (PaymentFailedException $e) {
            return response()->json(['error' => 'Payment failed'], 400);
        }

        return $next($order);
    }
}

Creating Reusable Pipelines

For frequently used pipelines, create a dedicated class:

class OrderProcessingPipeline
{
    public function __invoke($order)
    {
        return Pipeline::send($order)
            ->through([
                ValidateOrder::class,
                ApplyDiscount::class,
                CalculateTax::class,
                ProcessPayment::class,
            ])
            ->then(fn ($order) => $order->complete());
    }
}

Use it in your controller:

public function store(Request $request, OrderProcessingPipeline $pipeline)
{
    $order = new Order($request->all());
    return $pipeline($order);
}

Conditional Pipeline Steps

Add or remove steps based on conditions:

$steps = [ValidateOrder::class, SaveOrder::class];

if ($request->has('discount_code')) {
    $steps[] = ApplyDiscount::class;
}

$steps[] = ProcessPayment::class;

return Pipeline::send($order)
    ->through($steps)
    ->then(fn ($order) => response()->json($order, 201));

The Pipeline pattern in Laravel offers a clean, modular approach to handling complex workflows. By breaking down your logic into small, focused steps, you can create more maintainable and testable code. This pattern is particularly useful for processes like order processing, user registration, or any scenario where you need to apply a series of operations to your data in a specific order.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Laravel News Links

Count Cells With Specific Text in Excel Using the COUNTIF Formula

https://static1.makeuseofimages.com/wordpress/wp-content/uploads/2024/09/smartphone-with-logo-of-spreadsheet-editor-microsoft-excel-on-screen-in-front-of-company-website.jpg

Key Takeaways

  • Excel’s COUNT function produces a number of cells containing any value, but only COUNTIF and COUNTIFS can use conditions to narrow your results.
  • The COUNTIF function is used for one condition, while COUNTIFS allows multiple conditions to be specified in Excel.

When you’re staring at a massive spreadsheet, counting cells manually isn’t just tedious—it’s a recipe for mistakes. Thankfully, Microsoft Excel’s COUNTIF formula swoops in to save the day. It lets you count cells based on specific text or conditions, turning your spreadsheet chaos into organized data magic.

How to Count Excel Cells Based on a Condition

Not to be confused with the SUM function, which adds up numerical values within a group of cells, the COUNT function on Excel establishes the number of cells that contain a value.

In the image above, the COUNT function produces the number of paychecks released in a single week. But in its basic form, this function will only take you so far. Its sister functions, COUNTIF and COUNTIFS, can narrow those results into only the cells that meet a condition or have a specific string.

For example, you might need to calculate only the number of checks over a certain dollar amount or paychecks related to particular people. In these cases, you’ll need to use COUNTIF and COUNTIFS.

Excel’s COUNTIF and COUNTIFS functions are exactly how they sound: they will count cells for you IF those cells meet criteria that you specify.

How to Count Cells With COUNTIF

You should use COUNTIF when you have just one condition to factor in. This function is handy when you need to count cells that exceed (or fall under) a specified number.

In the above image, an Excel sheet breaks down the payroll for two separate pay weeks. An Earned column contains a formula that calculates the amount of money a performer earned depending on a session fee and number of sessions. On a week during which a performer had no sessions, their total earned was 0, meaning they did not receive a paycheck.

Whereas the basic COUNT function would consider a 0 to be a numerical value and hence count it as a paycheck, I can instead use COUNTIF to clarify that I only want to count cells with numerical values over 0.

To use COUNTIF:

  1. Select the cell in which you’d like to display your COUNTIF output.
  2. Type in the =COUNTIF function.
  3. Within a set of parentheses, you should first include a cell range of where you want the function to look, a comma, and then what (a value, for instance) you want the function to look for.
  4. Hit Enter.

If I want to know how many paychecks were released during that week, I use the following formula:

=COUNTIF(E3:E8, >"0") 

The COUNTIF function is also useful when you have a dataset that contains repetitive values. Say I was looking at a statement of paychecks over a wide date range, and I needed to quickly count checks per person.

I could establish a column with each performer’s name, and use that cell number as the condition to count their paychecks:

=COUNTIF(A3:A9, F3) 

If I didn’t want to include a name column, I could alternatively use the exact text of their names in the COUNTIF function instead:

=COUNTIF(A3:A9, "P. King") 

Both of these functions will output the same result.

How to Count Cells With COUNTIFS

Maybe you’re set at this stage, or perhaps you need to implement additional conditions. Luckily for you, COUNTIF walked so COUNTIFS could run. Regarding the differences between COUNTIF and COUNTIFS, the gist is that COUNTIFS allows you to use multiple conditions instead of just one.

To use COUNTIFS:

  1. Select the cell in which you’d like to display your COUNTIFS output.
  2. Type in the =COUNTIFS function.
  3. A set of parentheses includes a cell range, a comma, the first value or condition you’d like the program to look for, a comma, a second cell range, a comma, and another condition.
  4. Hit Enter.

Here’s one example of what the formula might look like:

=COUNTIFS(B3:B18, G3, E3:E18, ">0") 

In this example, the spreadsheet calculates the number of paychecks per performer over multiple weeks by first specifying the person and secondarily establishing that we’re looking for any value over 0.

You might also want to not only separate paychecks per performer but also separate lower paycheck values from higher paycheck values.

In this example, which is based on a list of payroll checks released over a range of dates, the following function will establish the amount of high-value paychecks that were over $1,000 for a specific performer:

=COUNTIFS(A3:A9, "P. King", B3:B9, ">1000") 

Of course, the possibilities of the COUNTIF and COUNTIFS functions are virtually endless. You can take these functions to the next level by combining them with Excel’s wildcard symbols and nested IF statements in Excel. Ultimately, the right function for you depends on your dataset and what information you need to analyze.

MakeUseOf

🔴 Watch: Trump Town Hall LIVE!

https://www.louderwithcrowder.com/media-library/image.png?id=53590081&width=980

President Donald Trump speaks to Americans through Pennsylvania voters in the capitol city of the cradle of liberty at the New Holland Arena in Harrisburg. Fox News’ Sean Hannity moderates. The President will address voter issues including but not limited to the state of inflation in our economy thanks to Bidenomics & Kamalanomics, gun crime, abortion rights, illegal immigration at our southern border, and the overall state of democracy in America. We have special drinking game rules for you, Josh Firestine is here, and so much more! Strap in, people! We have two months to go till Election 2024 in America!

Subscribe to Louder with Crowder on Rumble! Download the app on Apple and Google Play.

RUSSIA

ABORTION

SAVE Act (Safeguard American Voter Eligibility Act)

ECONOMY/INFLATION

ENERGY

GUNS

LEGAL TROUBLES

MIDDLE EAST

TAXES

KAMALA FLIP FLOPS THUS FAR

Louder With Crowder

Laravel package for using Microsoft mail, OneDrive, Teams, Excel, Calendars and Contacts

https://opengraph.githubassets.com/64df237792f136c48c459cc2b4214519830c794a15e07213670c1933719513b1/LLoadout/microsoftgraph

Latest Version on Packagist
Total Downloads

Laravel package for using Microsoft mail, OneDrive, Teams, Excel, Calendars and Contacts

This package makes a wrapper around the Microsoft Graph API.

  1. It provides a Mail driver for Microsoft mail.
  2. It provides a storage driver for OneDrive.
  3. It provides functionality to interact with Microsoft Teams.
  4. It provides the possibility to work with Excel, making it possible to write and read Excel files.
  5. It allows you to manage calendar events.
  6. It allows you to manage contacts.
  7. It allows you to read and handle mail.

You need to register an app in the Microsoft Azure Portal to use this package. Follow the steps in the Microsoft docs:
https://docs.microsoft.com/en-us/graph/auth-register-app-v2

You can install the package via composer:

composer require lloadout/microsoftgraph

Add this to your .env file and fill it with the values you specified in Microsoft Azure Portal app registration.
If you created a multi-tenant app in Azure AD than you don’t put your tentant id into the MS_TENANT_ID variable but you set it to common.

MS_TENANT_ID=
MS_CLIENT_ID=
MS_CLIENT_SECRET=
MS_GRAPH_API_VERSION=v1.0
MS_REDIRECT_URL=https://your-url.com/microsoft/callback

The package uses OAuth and provides two routes

The first redirects you to the consent screen of Microsoft

https://your-url.com/microsoft/connect

The second is the callback url you need to specify in Microsoft Azure Portal app registration as redirect uri

https://your-url.com/microsoft/callback

The callback will fire an MicrosoftGraphCallbackReceived event, you have to listen for this event in your EventServiceProvider and store the accessData to a session variable microsoftgraph-access-data.
You can add your token store logic in a listener for this event.

public function boot()
{
    Event::listen(function (MicrosoftGraphCallbackReceived $event) {
        session()->put('microsoftgraph-access-data', $event->accessData); 
    });
}

The package will search for a session variable name microsoftgraph-access-data for establishing the connection. So
please provide this variable with your accessData as value when logging in.
For example: On login, you get your accesData from the database and store it into the session
variable microsoftgraph-access-data.

You have to provide this API permissions: Mail.send

Set the environment variable MAIL_MAILER in your .env file

MAIL_MAILER=microsoftgraph

note: make sure your from address is the address you gave the consent to

Mail::send(new YourMailable());

Mail::raw('The body of my first test message', function($message) {
    $message->to('john@doe.com', 'John Doe')->subject('A mail send via lloadout/microsoftgraph');
});

Reading and handling mail

You have to provide this API permissions: Mail.Read, Mail.ReadWrite, Mail.ReadBasic

    getMailFolders(): array|GraphResponse|mixed
    getSubFolders(id): array|GraphResponse|mixed
    getMailMessagesFromFolder([folder: string = 'inbox'], [isRead: true = true], [skip: int = 0], [limit: int = 20]): array
    updateMessage(id, data): array|GraphResponse|mixed
    moveMessage(id, destinationId): array|GraphResponse|mixed
    getMessage(id): array|GraphResponse|mixed
    getMessageAttachements(id): array|GraphResponse|mixed
    $mail = app(Mail::class);

    collect($mail->getMailFolders())->each(function($folder){
        echo $folder['displayName']."<br />";
    });

    //get all unread messages from inbox
    collect($mail->getMailMessagesFromFolder('inbox', isRead: false))->each(function($message) use ($mail){
        echo $message['subject']."<br />";
    });
        

You have to provide this API permissions: Files.ReadWrite.all

add the onedrive root to your .env file:

MS_ONEDRIVE_ROOT="me/drive/root"

All methods from the Laravel Storage facade are available. https://laravel.com/docs/8.x/filesystem#configuration

The package created a disk called onedrive. This means that you can use all the methods as described in the Laravel docs: https://laravel.com/docs/8.x/filesystem#configuration

$disk = Storage::disk('onedrive');
#create a dir
$disk->makeDirectory('Test folder');
#storing files
$disk->put('Test folder/file1.txt','Content of file 1');
$disk->put('Test folder/file2.txt','Content of file 2');
#getting files
Storage::disk('onedrive')->get('Test folder/file1.txt');

You have to provide this API permissions: Chat.ReadWrite

    getJoinedTeams(): array|GraphResponse|mixed
    getChannels(team): array|GraphResponse|mixed
    getChats(): array|GraphResponse|mixed
    getChat(id): array|GraphResponse|mixed
    getMembersInChat(chat): array|GraphResponse|mixed
    send(teamOrChat, message): array|GraphResponse|mixed

First instantiate the Teams class

$teamsClass = new Teams();

Get all the teams you are a member of ( additional permissions needed: Group.Read.All )

$joinedTeams = $teamsClass->getJoinedTeams();

Get alle the channels for a team ( additional permissions needed: Group.Read.All )

$channels = $teamsClass->getChannels($team);

Get all the chats for a user ( additional permissions needed: Chat.Read.All )

$chats = $teamsClass->getChats(); 

Get a chat by a given id ( additional permissions needed: Chat.Read.All )

$chats = $teamsClass->getChat('your-chat-id'); 

Get all the members in a channel ( additional permissions needed: ChannelMessage.Read.All )

$members = $teamsClass->getMembersInChat($chat));

Send a message to a channel ( additional permissions needed: ChannelMessage.Send )

$teamsClass->send($teamOrChat,'Hello world!');

You have to provide this API permissions: Files.ReadWrite.all

    loadFile(file): void
    loadFileById(fileId): void
    setCellValues(cellRange, values: array): void
    getCellValues(cellRange): array
    recalculate(): void
    createSession(fileId): string

First instantiate the Excel class

$excelClass = new Excel();

Load a file from OneDrive

$excelClass->loadFile('Test folder/file1.xlsx');

Load a file by its id

$excelClass->loadFileById($fileId);

Set cell values of a range

$values = ['B1' => null, 'B2' => '01.01.23', 'B3' => 3, 'B4' => '250', 'B5' => '120', 'B6' => '30 cm', 'B7' => null, 'B8' => null, 'B9' => null, 'B10' => null, 'B11' => null, 'B12' => 2];
$excelClass->setCellValues('B1:B12', $values);
$excelClass->getCellValues('H1:H20');

You have to provide this API permissions: Calendars.ReadWrite

    getCalendars(): array
    getCalendarEvents(calendar: Calendar): array
    saveEventToCalendar(calendar: Calendar, event: Event): GraphResponse|mixed
    makeEvent(starttime: string, endtime: string, timezone: string, subject: string, body: string, [attendees: array = [...]], [isOnlineMeeting: bool = false]): Event

First instantiate the Calendar class

$calendarClass = new Calendar();

Get all the calendars

$calendars = $calendarClass->getCalendars();

Get all the events for a calendar

$events = $calendarClass->getCalendarEvents($calendar);

Save an event to a calendar, the event object is a MicrosoftGraphEvent object
We made a helper function to create an event
object Calendar::makeEvent(string $starttime, string $endtime, string $timezone, string $subject, string $body, array $attendees = [], bool $isOnlineMeeting = false)

$calendarClass->saveEvent($calendar, $event);

You have to provide this API permissions: Contacts.ReadWrite

First instantiate the Contacts class

$contactsClass = new Contacts();

Get all the contacts

$contacts = $contactsClass->getContacts();

Please see CHANGELOG for more information on what has changed recently.

Please see CONTRIBUTING for details.

Please review our security policy on how to report security vulnerabilities.

The MIT License (MIT). Please see License File for more information.

Laravel News Links

Floor 496

https://theawesomer.com/photos/2024/09/floor496_t.jpgEach visit to Floor796 is like exploring world&#8217;s largest Where&#8217;s Waldo image. The website consists of a constantly-expanding isometric animation of life on the 796th floor of a huge space station. It&#8217;s packed with pop culture references, and the entire animation has been drawn by a single artist using a special browser-based editing tool. (Thanks, [&#8230;]The Awesomer

MySQL Inside: Using the PS error_log table for a quick peak!

Just thought I’d share a script I use daily and helps me redirect my attention if needed.

This is but a mere pointer, guideline and starting point in any task. I just thought I’d share and hope someone else’s day becomes slightly easier thanks to some brief investigation and command tweaking.

Now the really handy thing here is that I only hard code the router01 node name, as I’m using that as a potential endpoint (thinking cloud, XaaS, etc…) where it could also be a VIP, LBR or similar. It’s the entry point so I can query the P_S table error_log so I can get different views and act accordingly.

For example:

  • First, give me the InnoDB Cluster ordered server list so I can take a step back from my usual pains and worries, and see the architecture view. And make me type “Y” or similar to move on. Here if there were any server missing, I’d see the summary right away so I don’t really need to worry about the error_log and a good ol’ CTRL-C is struck.
    • Now, give me a list of errors that appear in the log for the last:

30 minutes

4 hours

24 hours

    And then a summary & count, so I can prioritize my investigation time.

    Some explanations as to what’s being used:

    “–login-path” is how I have configured my env for added simplicity. Feel free to use user@host:port or whatever tickles the proverbial.

    “-A” when call mysqlsh means I won’t search any cached data.

    “–sqlc” means I’ll execute SQL.

    And at the end I’m curious as to since when the instance has been recording the error_log, so I add it in, for the hell of it.

    Sharing is good, hence the script:

    $ cat error_log.sh
    
    
    
    #!/bin/bash
    
    MYSQLUSER=icadmin
    MYROUTER1=router01
    
    MYSQLSH="mysqlsh --login-path=$MYSQLUSER -h$MYROUTER1 --table -A --sqlc -e "
    
    echo
    echo "Current time:" date
    echo
    echo "Remember: login-path needs to be defined."
    MYSQLUSER=icadmin
    MYSQLSH="mysqlsh --login-path=$MYSQLUSER -h$HOSTNAME --tabbed -A --sqlc -e "
    MYSQLLOGIN="mysqlsh --login-path=$MYSQLUSER -h"
    
    MYROUTER1=$MYSQLSH "select min(address) from mysql_innodb_cluster_metadata.routers" | grep -v address
    MYROUTER2=$MYSQLSH "select max(address) from mysql_innodb_cluster_metadata.routers" | grep -v address
    HOST1=$MYSQLSH "select MEMBER_HOST from performance_schema.replication_group_members where MEMBER_ROLE = 'PRIMARY';" | grep -v MEMBER
    HOST2=$MYSQLSH "select min(MEMBER_HOST) from performance_schema.replication_group_members where MEMBER_ROLE != 'PRIMARY';" | grep -v MEMBER
    HOST3=$MYSQLSH "select max(MEMBER_HOST) from performance_schema.replication_group_members where MEMBER_ROLE != 'PRIMARY';" | grep -v MEMBER
    echo
    echo "We have the following information: "
    echo " "$MYROUTER1" & "$MYROUTER2
    echo " "$HOST1" & "$HOST2" & "$HOST3
    echo " "$HOSTNAME" is the current host."
    echo
    read -p "Continue? (Y/N): " confirm && [[ $confirm == [yY] || $confirm == [yY][eE][sS] ]] || exit 1
    
    
    echo ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    echo
    echo $HOST1
    MYSQLSH="mysqlsh --login-path=$MYSQLUSER -h$HOST1 --table -A --sqlc -e "
    
    echo "Errors in the last 30 mins:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 30 MINUTE)"
    echo
    echo "Errors in the last 4 hours:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 4 HOUR)"
    echo
    echo "Errors for the last 24 hours:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY)"
    echo
    echo "Summary of the latest errors for the last 24h in the error_log:"
    $MYSQLSH "select count(*) from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY)" $MYSQLSH "select ERROR_CODE, SUBSYSTEM, DATA, count() from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY) group by ERROR_CODE, SUBSYSTEM, DATA"
    echo
    echo "Summary of error log:"
    $MYSQLSH "select min(LOGGED) as Earliest, max(LOGGED) as Last, count(*) as Count from performance_schema.error_log "
    echo
    echo ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    echo
    echo $HOST2
    MYSQLSH="mysqlsh --login-path=$MYSQLUSER -h$HOST2 --table -A --sqlc -e "
    echo
    echo "Current time:"date
    echo
    echo "Errors in the last 30 mins:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 30 MINUTE)"
    echo
    echo "Errors in the last 4 hours:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 4 HOUR)"
    echo
    echo "Errors for the last 24 hours:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY)"
    echo
    echo "Summary of the latest errors for the last 24h in the error_log:"
    $MYSQLSH "select count(*) from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY)" $MYSQLSH "select ERROR_CODE, SUBSYSTEM, DATA, count() from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY) group by ERROR_CODE, SUBSYSTEM, DATA"
    echo
    echo "Summary of error log:"
    $MYSQLSH "select min(LOGGED) as Earliest, max(LOGGED) as Last, count(*) as Count from performance_schema.error_log "
    echo
    
    echo ----------------------------------------------------------------------------------------------------------------------------------------------------------------
    echo
    echo $HOST3
    MYSQLSH="mysqlsh --login-path=$MYSQLUSER -h$HOST3 --table -A --sqlc -e "
    echo
    echo "Current time:"date
    echo
    echo "Errors in the last 30 mins:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 30 MINUTE)"
    echo
    echo "Errors in the last 4 hours:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 4 HOUR)"
    echo
    echo "Errors for the last 24 hours:"
    $MYSQLSH "select * from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY)"
    echo
    echo "Summary of the latest errors for the last 24h in the error_log:"
    $MYSQLSH "select count(*) from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY)" $MYSQLSH "select ERROR_CODE, SUBSYSTEM, DATA, count() from performance_schema.error_log where logged > (NOW() - INTERVAL 1 DAY) group by ERROR_CODE, SUBSYSTEM, DATA"
    echo
    echo "Summary of error log:"
    $MYSQLSH "select min(LOGGED) as Earliest, max(LOGGED) as Last, count(*) as Count from performance_schema.error_log "
    echo
    echo "End!"

    Planet MySQL

    Laravel ERD generator

    https://opengraph.githubassets.com/d5fcf2928c5bfc84c7e461d6ca2b9ba567fc369f37486ee3f043952f6437531f/recca0120/laravel-erd

    Latest Version on Packagist
    GitHub Tests Action Status
    Total Downloads

    Laravel ERD automatically generates Entity-Relationship Diagrams from your Laravel models and displays them
    using erd-editor.

    Here’s a sample of what you can expect, generated from migrations
    and models:

    View Live Demo

    erd-editor

    Lang Version
    PHP 7.4, 8.0, 8.1, 8.2, 8.3
    Laravel 8, 9, 10, 11

    Install the package via Composer:

    composer require recca0120/laravel-erd:^0.1 --dev

    Run the following command:

    Step 2: View the ERD

    Open the following URL in your browser:

    http://localhost/laravel-erd

    Exclude Tables and Save to a Different Filename

    Run the command:

    php artisan erd:generate --file=exclude-users.sql --exclude=users

    Open the URL:

    http://localhost/laravel-erd/exclude-users

    Install erd-go
    and graphviz-dot.js using:

    Generate the SVG file:

    php artisan generate --file=laravel-erd.svg

    View the SVG version:

    http://localhost/laravel-erd/laravel-erd.svg

    svg

    The SVG file can be found at storage/framework/cache/laravel-erd.

    Feel free to ask if you have any questions or need further assistance!

    Laravel News Links

    Backup Tables

    https://repository-images.githubusercontent.com/844615628/cd7a488d-4e57-454c-9694-f994c1962fc7

    Package cover

    Latest Version on Packagist
    Total Downloads
    GitHub Code Style Action Status
    GitHub Tests For Laravel Versions Action Status
    GitHub Tests For Databases Action Status

    Backup single or multiple database tables with ease.

    Note: if you want a full database backup with many features go for Spatie Laravel Backup.

    You can install the package via Composer:

    composer require watheqalshowaiter/backup-tables

    Use the BackupTables::generateBackup($tableToBackup) Facade anywhere in your application and it will
    generate $tableToBackup_backup_2024_08_22_17_40_01 table in the database with all the data and structure. Note that
    the datetime 2024_08_22_17_40_01 will be varied based on your datetime.

    use WatheqAlshowaiter\BackupTables\BackupTables; // import the facade
    
    class ChangeSomeData
    {
        public function handle()
        {
            BackupTables::generateBackup('users'); // will result: users_backup_2024_08_22_17_40_01
           
            // change some data.. 
        }
    }

    And More Customizations

    • You can use an array to backup more than one table
    BackupTables::generateBackup(['users', 'posts']); 
    // users_backup_2024_08_22_17_40_01
    // posts_backup_2024_08_22_17_40_01 
    • Or add Classes as parameters, It will backup their tables
    BackupTables::generateBackup(User::class); // users_backup_2024_08_22_17_40_01
    // or
    BackupTables::generateBackup([User::class, Post::class]); // users_backup_2024_08_22_17_40_01, posts_backup_2024_08_22_17_40_01 
     
    • You can customize the $dataTime format to whatever you want
    BackupTables::generateBackup('users', 'Y_d_m_H_i'); // users_backup_2024_22_08_17_40

    *Note: be aware if you customize the datetime to wide datetime the package will check the backup datetime file and
    will be skipped
    the exact same datetime, so most of the time the default will be fine
    For example: if you use this Y_d_m_H you can not generate the same backup in the same hour

    BackupTables::generateBackup('users', 'Y_d_m_H'); // can not generate the same backup in the same hour
    BackupTables::generateBackup('users', 'Y_d_m'); // can not generate the same backup in the same day

    Sometimes you want to backup some database tables before changing data for whatever reason, this package serves this
    need. I used it personally before adding foreign keys for tables that required the removal of unlinked fields for parent tables.
    You may find some situation where you play with table data or you’re afraid of missing data so you backup these tables
    beforehand.

    ✅ Supports Laravel versions: 11, 10, 9, 8, 7, and 6.

    ✅ Supports PHP versions: 8.2, 8.1, 8.0, and 7.4.

    ✅ Supports SQL databases: SQLite, MySQL/MariaDB, PostgreSQL, and SQL Server.

    ✅ Fully automated tested with PHPUnit.

    ✅ Full GitHub Action CI pipeline to format code and test against all Laravel and PHP versions.

    Please see CHANGELOG for more information on what has changed recently.

    If you have any ideas or suggestions to improve it or fix bugs, your contribution is welcome. I encourage you to look at todos which are the most important features that need to be added. If you have something different, submit an issue first to discuss or report a bug, then do a pull request.

    If you find any security vulnerabilities don’t hesitate to contact me at watheqalshowaiter[at]gmail[dot]com to fix
    them.

    And a special thanks to The King Creative for the logo ✨

    The MIT License (MIT). Please see License File for more information.

    Laravel News Links

    Pinkary is now fully open source

    https://picperf.io/https://laravelnews.s3.amazonaws.com/featured-images/pinkary-featured.png

    Pinkary is now fully open source

    Pest creator and Laravel core team member Nuno Maduro announced recently that Pinkary is now fully open source, and you can also find us on it at @laravelnews.

    Built with Laravel, Livewire, Tailwind, and more, Pinkary is an excellent example of a full Laravel application you can learn from and contribute to:

    Pinkary is already a thriving project, with over 400+ submitted pull requests, and is encouraging open-source contributions and giving you the installation instructions you need to go from project setup to pull request. Pinkary is already using Pest 3, and as the creator of Pest, the code has plenty of examples you can learn from to level up your testing skills.

    On the user side of this project, Pinkary is a landing page for all your links and a place where you can connect with like-minded people without the noise of other social media applications. It went from a new project to over a thousand users very quickly and is known for using a SQLite database for application data, sessions, queues, cache, etc.

    Start learning from the Pinkary source code today! Visit pinkary-project/pinkary.com on GitHub and join this exciting open-source project.


    The post Pinkary is now fully open source appeared first on Laravel News.

    Join the Laravel Newsletter to get all the latest
    Laravel articles like this directly in your inbox.

    Laravel News