GitDown Parsing Markdown in PHP

GitDown is a simple package for parsing (GitHub-flavored) Markdown in PHP by Caleb Porzio. It works by sending the provided markdown to a public GitHub API that parses it as HTML.

If you aren’t using Laravel, you can still use this package by Here’s the basic usage in a Laravel project:

GitDown::parse($markdown);

// Will be cached forever. (suggested)
GitDown::parseAndCache($markdown);

// Will be cached for 24 hours. (minutes in Laravel < 5.8, seconds otherwise)
GitDown::parseAndCache($markdown, $seconds = 86400);

// Pass in your own custom caching strategy.
GitDown::parseAndCache($markdown, function ($parse) {
    return Cache::rememberForever(sha1($markdown), function () use ($parse) {
        return $parse();
    });
});

You don’t have to use Laravel to use GitDown—you can create a GitDown\GitDown instance and bring your own caching strategy:

$gitDown = new GitDown\GitDown(
    $token = 'foo',
    $context = 'your/repo',
    $allowIframes = false
);

$gitDown->parse($markdown);

// Pass in your own custom caching strategy.
$gitDown->parseAndCache($markdown, function ($parse) {
    return Cache::rememberForever(sha1($markdown), function () use ($parse) {
        return $parse();
    });
});

It’s important to remember that without caching the results, you are going to run into GitHub rate limiting quickly and your pages will load super-slow.

On the frontend, you can benefit from the @gitdown directive in Laravel projects to the <head> of your layout, wrapping the markdown content in a .markdown-body class:

<head>
    [...]
    @gitdown
</head>
<body>
    <div class="markdown-body">
        {!! GitDown::parseAndCache($content) !!}
    </div>
</body>

If you’re not using Laravel, you can use the following:

<style><?php echo GitDown\GitDown::styles(); ?></style>

Check out the project’s README for detailed instructions on rendering styles.

To learn more about GitDown and the gory details of why you might want to use it, read Caleb’s writeup Parsing Markdown: The Easy Way (With Code Highlighting).

You can learn more about this package, get full installation instructions, and view the source code on GitHub at calebporzio/gitdown.

Snipe Migrations Laravel Package

Snipe Migrations is a Laravel package by Dustin Fraker for “blazing fast” database migrations for tests:

The package takes a snapshot of your mysql database and imports the schema to your test database rather than running all of your migrations when the test suite starts up.

On projects with many migration files, Snipe Migrations may have a huge speed improvement over migrating the database during setup.

It works by adding this method to your base test class that your other tests extend:

public function setUpTraits()
{
    parent::setUpTraits();

    $uses = array_flip(class_uses_recursive(static::class));

    if (isset($uses[DatabaseTransactions::class])) {
        (new Snipe())->importSnapshot();
    }
}

After you’ve added the setUpTraits() method, you then use it by importing the use DatabaseTransactions trait in your tests.

Learn More

In his writeup, Dustin talks about his reasons for creating Snipe Migrations. You should check out his full post about building the package, including a video at the end which goes over his use-case and how to set up the package.

You can learn more about the Snipe Migrations package at drfraker/snipe-migrations. To learn how to install and use the package, check out the Snipe Migration README file.

Congratulations on your first open-source Laravel package Dustin!

Laravel Tinker Server Package

Laravel Tinker Server is a package by Marcel Pociot that enables you to tinker with your variables in real-time while working on your Laravel app. This package collects data via calls to a tinker() helper that ships with the package and allow you to then interact with those variables on the fly.

Related: Laravel Dump Server

The best way to demonstrate this package is the following gif from the project’s README file:

The primary usage for this is first starting up a tinker server in a new console session:

php artisan tinker-server

Then when you call tinker() from within your code it will be instantly available in an interactive REPL shell. Here’s a basic example from the README:

$user = App\User::find(1);

tinker($user);

Using XDebug

An alternative approach that I use which has similar benefits is setting breakpoints during an XDebug session. If you’re using a client like PhpStorm’s client/UI, you can interactively inspect variables within the scope of the call stack and run code via a console.

The nice thing about using XDebug is that it works for all PHP projects, where this approach is specific to Laravel. You can see this technique in our Learn how to set up Xdebug for PhpStorm and Laravel Valet video.

Learn More

You can learn more about the Laravel Tinker Server package at beyondcode/laravel-tinker-server. To learn how to install and use the package, check out the Laravel Tinker Server README file.

Laravel Favicon Package

Laravel Favicon is a package by Marcel Pociot that enables you to create dynamic favicons based on your environment settings:


 
The package works by using a favicon() helper function in your template, which is then modified in the environments you configure:

<link rel="icon" type="image/png" sizes="32x32" href="{{ favicon(asset('favicon-32x32.png')) }}">

Here’s an example of the default enabled environment configuration at the time of writing to give you an idea the values you can specify:

'enabled_environments' => [
    'local' => [
        'text' => 'DEV',
        'color' => '#000000',
        'background_color' => '#ffffff',
    ],
],

It uses Intervention Image, which at the time of writing supports to processing extensions: gd and imagick. If you want to convert ICO files, you need to use the imagick configuration option.

The intended use of this package is for non-production environments. Environments that don’t have matching configuration values will return the original path/URI to the static icon.

Related: Laravel View X-Ray

You can learn more about the Laravel Favicon package at beyondcode/laravel-favicon. To learn how to install and use the package, check out the project’s README file.

Laravel Options Package

The Laravel Options package from Appstract is a global database key-value options store for Laravel. This package uses a simple options database table with a key and value field and an Option model available via a service provider.

Related: Storing Global Application Settings

Laravel Options has some helpers and a Facade for working with the options table, along with a common public API for creating, getting, setting, and deleting options by key:

// Get an option
option('someKey');

// Set option
option(['someKey' => 'someValue']);

// Check the option exists
option_exists('someKey');

The package ships with a console command to set global options via the command line:

php artisan option:set site_name "Laravel News"

Laravel Options takes away some boilerplate that you might have in your app to replicate a simple key-value store, but doesn’t have much functionality beyond setting simple key-values and you’ll be responsible for any data transformations.

For complete installation instructions check out appstract/laravel-options on GitHub.

Translate Laravel Languages with Google Sheets

Laravel Translation Sheet is a package by Nassif Bourguig for translating Laravel language files using Google Sheets. What I love about this idea/package, is how easy it makes the process of collaborating on language translations with a standard tool like Google Sheets.

Related: Building a Laravel Translation Package

The way that you interact with Google Sheets is through a series of artisan commands and the Google Sheets API:

# Setup and prep commands
php artisan translation_sheet:setup
php artisan translation_sheet:prepare

# Publish translation to Google Sheets
php artisan translation_sheet:push


Once the translations are ready to go, you can use the pull command to pull the translations from the spreadsheet and write to the language-specific files in your Laravel application:

php artisan translation_sheet:pull

Using the pull command syncs the translations from Google Sheets the configured language translation files. You are free to do a diff on them through version control, test them out, and finally commit them to your application.

Once you receive translations and have pulled them into your application, you can lock the sheet to avoid conflicts:

# Lock the sheet to avoid conflicts
php artisan translation_sheet:lock

You can learn more about Laravel Translation Sheet on GitHub at nikaia/translation-sheet. To learn how to install and use the package, check out the project’s README file.

Subdomain Multitenency Package for Laravel

Romega Digital released a package to make it easier to create subdomain-based multitenancy in your Laravel applications:

This package is meant to be a quick and easy way to add multitenancy to your Laravel application. It simply creates models and relationships for Tenants and models. The package identifies incoming traffic by subdomain, and finds a corresponding tenant in the Tenant table. If none are found or the user is not associated with a particular subdomain, the user is met with a 403 error.

Remega’s package provides multitenant support to your models through a trait called HasTenants, and also leverages Spatie’s permissions package for some functionality.

Related: Two Best Laravel Packages to Manage Roles/Permissions

Here’s an example from the readme:

use Spatie\Permission\Traits\HasRoles;
use RomegaDigital\Multitenancy\Traits\HasTenants;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasTenants, HasRoles;

    // ...
}

With the HasTenants trait in place, you can get the users associated with a Tenant model:

User::tenants()->get()

And finally here’s how you create tenants:

Tenant::createMany([
    [
        'name'    => 'An Identifying Name',
        'domain'  => 'tenant1'
    ],
    [
        'name'    => 'A Second Customer',
        'domain'  => 'tenant2'
    ]
]);

Along with this package, there’s an accompanying Nova package called Multitenency Nova Tool to manage the multitenancy functionality in your application.

To learn more about this Multitenancy package, you can check out the source code on GitHub at romegadigital/Multitenancy. To learn how to install and use the package, check out the Multitenency readme file.

See also: Laravel Tenancy – Multi-Tenant Package for Laravel

Five Hidden Features of the Laravel Excel Package

The Laravel Excel package recently celebrated a new milestone of version 3, with new features that help ease advanced use-cases, and is simple to use. Let’s explore some of these hidden features you might not know about, that make Laravel Excel a go-to package for working with Excel.

1. Exporting from HTML/Blade

Let’s imagine you already have a list page with HTML table:

And here’s the Blade code – resources/views/customers/table.blade.php:

<table class="table">
    <thead>
    <tr>
        <th></th>
        <th>First name</th>
        <th>Last name</th>
        <th>Email</th>
        <th>Created at</th>
        <th>Updated at</th>
    </tr>
    </thead>
    <tbody>
    @foreach ($customers as $customer)
    <tr>
        <td>{{ $customer->id }}</td>
        <td>{{ $customer->first_name }}</td>
        <td>{{ $customer->last_name }}</td>
        <td>{{ $customer->email }}</td>
        <td>{{ $customer->created_at }}</td>
        <td>{{ $customer->updated_at }}</td>
    </tr>
    @endforeach
    </tbody>
</table>

You can re-use it to export the same table into Excel.

Step 1. Generate Export class

php artisan make:export CustomersFromView --model=Customer

Step 2. Use FromView to perform the operation.

namespace App\Exports;

use App\Customer;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;

class CustomersExportView implements FromView
{
    public function view(): View
    {
        return view('customers.table', [
            'customers' => Customer::orderBy('id', 'desc')->take(100)->get()
        ]);
    }
}

Here’s the result Excel file:

Notice: you can export only HTML table, without any layout tags like html, body, div, etc.


2. Export to PDF, HTML, and others

Although the package is called Laravel Excel, it provides export to more formats. It’s straightforward to use, add one more parameter to the class:

return Excel::download(new CustomersExport(), 'customers.xlsx', 'Html');

Yes, you got it right. HTML. Here’s how it looks:

Not much styling, I know. And here’s the source:

Not only that, it allows to export to PDF, and you can even choose from three libraries for it. Again, all you need to do is specify the format as the last parameter – here’s screenshot from their docs:

Notice: you will also have to install a chosen PDF package via composer, like:

composer require dompdf/dompdf

Here’s how PDF looks like:


3. Format Cells However You Want

Laravel Excel package has a powerful “parent” – PhpSpreadsheet. So it adopts all the underneath functionality, including cell formatting in various ways.

Here’s how to use it in Laravel Export class, like app/Exports/CustomersExportStyling.php:

Step 1. Use appropriate classes in the header.

use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;

Step 2. Use WithEvents in implements section.

class CustomersExportStyling implements FromCollection, WithEvents 
{ 
    // ...

Step 3. Create registerEvents() method with AfterSheet event.

/**
 * @return array
 */
public function registerEvents(): array
{
    return [
        AfterSheet::class    => function(AfterSheet $event) {
            // ... HERE YOU CAN DO ANY FORMATTING
        },
    ];
}

Here’s an example:

/**
 * @return array
 */
public function registerEvents(): array
{
    return [
        AfterSheet::class    => function(AfterSheet $event) {
            // All headers - set font size to 14
            $cellRange = 'A1:W1'; 
            $event->sheet->getDelegate()->getStyle($cellRange)->getFont()->setSize(14);

            // Apply array of styles to B2:G8 cell range
            $styleArray = [
                'borders' => [
                    'outline' => [
                        'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK,
                        'color' => ['argb' => 'FFFF0000'],
                    ]
                ]
            ];
            $event->sheet->getDelegate()->getStyle('B2:G8')->applyFromArray($styleArray);

            // Set first row to height 20
            $event->sheet->getDelegate()->getRowDimension(1)->setRowHeight(20);

            // Set A1:D4 range to wrap text in cells
            $event->sheet->getDelegate()->getStyle('A1:D4')
                ->getAlignment()->setWrapText(true);
        },
    ];
}

The result of these “random” demo-styling examples looks like this:

All these examples, and many more, you can find in Recipes page of PhpSpreadsheet docs.


4. Hidden Fields From Model

Let’s imagine we’ve seeded a default Laravel 5.7 users table:

Let’s try to export this one with a simple class FromCollection:

class UsersExport implements FromCollection
{
    public function collection()
    {
        return User::all();
    }
}

In the result Excel, you will see some fields missing: password and remember_token:

This is because of this app/User.php property:

class User extends Authenticatable
{
    // ...

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

So, these fields are hidden by default, but it shows us Laravel Excel package behavior – if you want to protect some fields from export, you can do it directly in the model.


5. Formulas

For some reason, official Laravel Excel package documentation doesn’t mention anything about formulas. But that’s the whole point of using Excel!

Luckily, it’s straightforward to write formulas into our exported file. We need to set cell values like we would to in Excel, for example, =A2+1 or SUM(A1:A10).

One of the ways to do it is to use WithMapping:

use App\Customer;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithMapping;

class CustomersExportFormulas implements FromCollection, WithMapping
{
    public function collection()
    {
        return Customer::all();
    }

    /**
     * @var Customer $customer
     * @return array
     */
    public function map($customer): array
    {
        return [
            $customer->id,
            '=A2+1',
            $customer->first_name,
            $customer->last_name,
            $customer->email,
        ];
    }
}

So, these are just five less-known features of Laravel Excel. If you want to find out more, I have a unique online course called Excel Export/Import in Laravel, go check it out!

Accountant Laravel Package

Accountant is a Laravel accountably package for your Eloquent models by developer Quetzy Garcia. This package is a convenient way to keep track of Eloquent model changes:

Data discrepancies that may indicate business concerns suspect activities, and other actions that would otherwise pass unnoticed, can now be easily spotted.

At the time of writing, here are the key features according to the README:

  • Many-to-many (BelongsToMany and MorphToMany) relation support;
  • Event source style approach, by keeping complete snapshots of Recordable models when created, modified or retrieved;
  • Ability to recreate Recordable model instances in the exact state they were in when recorded;
  • Signed Ledger records for data integrity;
  • Effortless data integrity checks
  • Recording contexts
  • Huge customisation support
  • Easy to follow documentation and troubleshooting guide;
  • Laravel and Lumen 5.2+ support;

This package has a ton of features you can check it in the documentation. Here’s an example of the “Recordable” trait used to record model events:

<?php

namespace App\Models;

use Altek\Accountant\Contracts\Recordable;
use Illuminate\Database\Eloquent\Model;

class Article extends Model implements Recordable
{
    use \Altek\Accountant\Recordable;

    // ...
}

Accountant released v1.1.0 on January 1st, which introduced Many-to-many relationships, and forceDelete event support. You can even track pivot events – check the recordable model setup documentation for details on recording pivot events.

You can follow along with Accountant and view the source code on GitLab at Altek / Accountant, including the documentation which is available under version control in the same GitLab repository.

Learn More

Another package that we’ve covered on the topic of event sourcing is Spatie’s Laravel Event Projector. I suggest you read our article that contains links to the concepts around event sourcing if you’re not familiar. I am not sure which features differ between the two packages, but I’d check out both to further determine your needs.

Laravel WebSockets Package Released

Laravel WebSockets is a WebSockets server implemented in PHP for your Laravel projects. It’s also a drop-in replacement for Pusher via the Pusher protocol and Laravel Echo JavaScript server, which means all packages that work with Pusher will work with the Laravel WebSockets package.

Running a WebSocket server is at your fingertips with artisan:

php artisan websockets:serve

The package also comes with an excellent Debug Dashboard which can help you speed up development of WebSocket features in your applications:

Image credit: Official Debug Dashboard Documentation

The initial Laravel Websockets release is a collaborative effort by Marcel Pociot and Freek Van der Herten. Freek has a very detailed writeup Introducing laravel-websockets, an easy to use WebSocket server implemented in PHP that goes into great detail on the background of the package, how to use it, and many other aspects of the projects.

The documentation includes some benchmarks and the scale looks promising. Of course, your mileage will vary from project-to-project, including your specific application needs and usage patterns.

To learn more about the package and how to use it to check out the Laravel WebSockets documentation. The source code is available on GitHub at beyondcode/laravel-websockets.