baks-dev/products-sign
Laravel/PHP module for handling “Честный знак” product marking codes. Installs with baks-dev/barcode, stores uploaded codes in public/upload/product_sign_code, supports PDF cropping (pdftk/pdfcrop) and ImageMagick PDF read/write for generating/processing labels.
composer require baks-dev/barcode baks-dev/products-sign
mkdir -p public/upload/product_sign_code
chown -R www-data:www-data public/upload/product_sign_code
pdftk and texlive-extra-utils (Linux)./etc/ImageMagick-6/policy.xml) to allow PDF processing.pdfcrop (if needed):
sudo visudo
Add:
unit ALL=(ALL) NOPASSWD: /usr/bin/pdfcrop
php bin/console baks:assets:install
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
Generate a product signature for a new product:
use BaksDev\ProductsSign\Services\SignatureCreator;
$creator = new SignatureCreator();
$signature = $creator
->setProduct($product) // Assuming Product model with required fields
->setExpiryDate(now()->addYear())
->generate();
return $signature->getPath(); // Returns path to generated PDF/QR
$signature = app(SignatureCreator::class)
->setProduct($product)
->setCustomFields(['manufacturer_id' => 123])
->generate();
dispatch(new GenerateProductSignature($product, $expiryDate));
Use Laravel Queues with a worker:
php artisan queue:work
$validator = app(SignatureValidator::class);
$result = $validator->validate($signature);
$results = $validator->validateBatch($productSignatures);
// Returns array of ValidationResult objects
PRODUCT_SIGN_DISK=local
PRODUCT_SIGN_PATH=public/upload/product_sign_code
PRODUCT_SIGN_DISK=s3
AWS_BUCKET=my-compliance-signs
AWS_REGION=eu-central-1
routes/api.php):
Route::post('/api/signatures/validate', [SignatureController::class, 'validate']);
public function validate(Request $request, SignatureValidator $validator)
{
$results = $validator->validateBatch($request->products);
return response()->json($results);
}
Laravel Nova Integration: Create a custom Nova resource for managing product signatures:
public static $title = 'signature';
public static $search = ['product_id', 'qr_code'];
public function fields(Request $request)
{
return [
ID::make(),
Text::make('Product ID')->onlyOnDetail(),
Text::make('QR Code')->onlyOnDetail(),
Text::make('Expiry Date'),
Boolean::make('Is Valid'),
Actions::make('Validate', ValidateSignature::class),
];
}
Event-Based Workflows: Listen for product creation to auto-generate signatures:
ProductCreated::dispatch($product)
->then(function ($product) {
app(SignatureCreator::class)->setProduct($product)->generate();
});
Testing: Use the provided test group:
php bin/phpunit --group=products-sign
Mock external tools (pdftk, ImageMagick) in tests:
$this->mockPdfTools()->shouldReceive('crop')->andReturn(true);
Custom Templates: Extend the default PDF template by publishing and overriding:
php artisan vendor:publish --tag=products-sign-views
Modify resources/views/vendor/products-sign/signature.blade.php.
System Tooling Dependencies:
pdftk or ImageMagick may fail silently if not properly configured.Permission Errors:
www-data) may lack write permissions to public/upload/product_sign_code.chown -R www-data:www-data public/upload/product_sign_code
chmod -R 755 public/upload/product_sign_code
PDF Processing Timeouts:
dispatchSync(new GenerateProductSignature($product));
Validation API Changes:
--group=products-sign test suite before upgrading:
php bin/phpunit --group=products-sign
QR Code Standards:
SignatureCreator class.Enable Debug Logging:
Add to config/logging.php:
'channels' => [
'products_sign' => [
'driver' => 'single',
'path' => storage_path('logs/products_sign.log'),
'level' => env('APP_DEBUG') ? 'debug' : 'info',
],
],
Then log in your service classes:
\Log::channel('products_sign')->debug('Generating signature for product ID: ' . $product->id);
Validate PDF Output:
Use pdftk to inspect generated PDFs:
pdftk public/upload/product_sign_code/signature_123.pdf dump_data
Check ImageMagick Policies: If PDF processing fails, verify policies:
grep -A5 -B5 "PDF" /etc/ImageMagick-6/policy.xml
Ensure it allows read/write:
<policy domain="coder" rights="read|write" pattern="PDF" />
Custom Signature Fields:
Extend the SignatureCreator to include additional fields:
class CustomSignatureCreator extends SignatureCreator
{
public function setCustomField(string $key, $value): self
{
$this->customFields[$key] = $value;
return $this;
}
}
Validation Rules:
Add custom validation logic by extending SignatureValidator:
class CustomValidator extends SignatureValidator
{
protected function validateCustomRules(Signature $signature): void
{
if (!$signature->isExpiryValid()) {
$this->errors[] = 'Signature expired';
}
}
}
Storage Adapters: Implement a custom storage adapter for cloud providers:
class GoogleCloudStorageAdapter implements StorageAdapterInterface
{
public function store(string $path, string $content): string
{
// Upload to Google Cloud Storage
}
public function retrieve(string $path): string
{
// Retrieve from Google Cloud Storage
}
}
Webhook Notifications: Dispatch events for signature generation/validation:
event(new SignatureGenerated($signature));
Listen for events in another service:
SignatureGenerated::listen(function ($event) {
// Send notification to sellers
});
Environment Variables:
Ensure these are set in .env:
PRODUCT_SIGN_ENABLED=true
PRODUCT_SIGN_DISK=local
PRODUCT_SIGN_PATH=public/upload/product_sign_code
PRODUCT_SIGN_PDFTK_PATH=/usr/bin/pdftk
PRODUCT_SIGN_IMAGEMAGICK_POLICY=/etc/ImageMagick-6/policy.xml
Queue Configuration:
For async processing, configure queues in .env:
QUEUE_CONNECTION=database
PRODUCT_SIGN_QUEUE_CONNECTION=redis
**Barcode
How can I help you explore Laravel packages today?