QR codes are a practical tool for sharing data, and implementing them in a Laravel application can be straightforward and scalable. This blog post will guide you through building a QR code generation system using contracts, traits, and action classes.
Before we dive into the code, let’s install the necessary packages and dependencies.
Step 1: Install SimpleSoftwareIO QR Code Package
To generate QR codes in Laravel, we will use the SimpleSoftwareIO QR Code package. It provides an easy-to-use API for creating QR codes in various formats, such as PNG, SVG, and more.
Run the following command to install the package:
composer require simplesoftwareio/simple-qrcode
After installation, you’ll be able to use the QrCode
facade to generate QR codes within your application.
Step 2: Install Imagick for PNG Format
If you are generating QR codes in PNG format (as we are in this example), it’s recommended to install the Imagick extension. Imagick provides support for image processing, and the SimpleSoftwareIO QR Code package relies on it for creating and manipulating PNG files.
To install Imagick on your system, follow these steps:
For Ubuntu:
sudo apt-get install php-imagick
For macOS (using Homebrew):
brew install imagemagick
brew install php@8.3-imagick # or php@your-version-imagick
After installation, ensure that the imagick
extension is enabled in your php.ini
file.
For PHP environments, you may need to restart the server to reflect the changes:
php artisan serve
Now that the package and Imagick are set up, let’s proceed with the implementation.
Step 3: Define the QR Code Contract
We start by defining a contract (interface) that enforces the methods required for generating a QR code. This contract ensures that any model implementing it will have the necessary functionality for handling QR code generation.
namespace AppContracts;
interface QrCode
{
public function generateQrCode(): self;
public function getQrCodeColumnName(): string;
public function getQrCodeIdentifier(): string;
public function getQrCodeFormat(): string;
public function getQrCodeSize(): string;
public function getQrCodeLogo(): string;
public function getQrCodePath(): string;
public function getQrCodeContent(): string;
}
This interface defines all the methods related to QR code creation, from specifying the QR code’s format and size to providing the content and file path.
Step 4: Implement the Trait for QR Code Interaction
Now, we create a trait to implement the logic that interacts with the QR code generation action class.
namespace AppConcerns;
use AppActionsQrGenerateQrCode;
use AppContractsQrCode;
use IlluminateDatabaseEloquentModel;
use SpatieMediaLibraryHasMedia;
trait InteractsWithQrCode
{
public static function bootInteractsWithQrCode()
{
static::creating(function (Model $model) {
if ($model instanceof QrCode) {
$model->generateQrCode();
}
});
}
public function generateQrCode(bool $force = false): self
{
$generator = new GenerateQrCode(
$this->getQrCodeContent(),
$this->getQrCodePath(),
$this->getQrCodeFormat(),
$this->getQrCodeSize(),
$this->getQrCodeLogo(),
$force
);
$generator->execute();
if ($this instanceof HasMedia) {
$this->copyMedia($this->getQrCodePath())->toMediaCollection('qr-code');
}
return $this;
}
public function getQrCodeColumnName(): string
{
return isset($this->qr_code) ? $this->qr_code : 'qr_code';
}
public function getQrCodeIdentifier(): string
{
return isset($this->qr_code_identifier) ? $this->qr_code_identifier : 'uuid';
}
public function getQrCodeFormat(): string
{
return isset($this->qr_code_format) ? $this->qr_code_format : 'png';
}
public function getQrCodeSize(): string
{
return isset($this->qr_code_size) ? $this->qr_code_size : '256';
}
public function getQrCodeLogo(): string
{
return file_exists(public_path('assets/logo.png')) ? public_path('assets/logo.png') : '';
}
public function getQrCodePath(): string
{
return storage_path(
'/data/qr-codes/'.
$this->{$this->getQrCodeIdentifier()}.
'.'.
$this->getQrCodeFormat()
);
}
public function getQrCodeContent(): string
{
return data_get($this, $this->getQrCodeColumnName(), '');
}
}
This trait handles the QR code generation process, calling the GenerateQrCode
action and storing the generated code.
Step 5: Create the Action Class to Generate QR Codes
We encapsulate the QR code generation logic into an action class. This class generates and saves the QR code to the specified path.
namespace AppActionsQr;
use CleaniqueCodersLaravelContractContractsExecute;
use SimpleSoftwareIOQrCodeFacadesQrCode;
class GenerateQrCode implements Execute
{
public function __construct(
protected string $content,
protected string $path,
protected string $format = 'png',
protected string $size = '256',
protected string $logo = '',
protected bool $force = false) {}
public function execute()
{
try {
$path = $this->path;
$content = $this->content;
if (file_exists($path) && ! $this->force) {
return;
}
if ($this->force && file_exists($path)) {
unlink($path);
}
$qrCode = QrCode::format($this->format)
->size($this->size)
->eye('square')
->margin(5)
->style('dot', 0.9);
if ($this->logo) {
$qrCode->merge($this->logo, .25, true);
}
file_put_contents(
$this->path, $qrCode->generate($content)
);
} catch (Throwable $th) {
throw $th;
}
}
}
This action class uses the SimpleSoftwareIO QrCode
facade to generate a QR code with the specified format, size, and content. It also allows you to optionally include a logo and overwrite existing QR codes.
Step 6: Use the Contract and Trait in a Model
Lastly, integrate the QrCode
contract and InteractsWithQrCode
trait in a model that requires QR code generation, such as an Asset
model.
namespace AppModels;
use AppConcernsInteractsWithQrCode;
use AppContractsQrCode;
use AppModelsBase as Model;
class Asset extends Model implements QrCode
{
use InteractsWithQrCode;
public function getQrCodeContent(): string
{
return route('assets.qr', $this->{$this->getRouteKeyName()});
}
}
In this example, the Asset
model generates a QR code containing a URL to access the asset, and the QR code is created when a new asset is created.
Conclusion
By combining contracts, traits, and action classes, this implementation provides a scalable and maintainable solution for QR code generation in Laravel. With the help of the SimpleSoftwareIO QR Code package and Imagick for image handling, you can easily customize and extend this setup for any QR code generation needs.
Don’t forget to install the necessary dependencies and ensure that the Imagick extension is enabled for PNG format support. Happy coding!
Source link
lol