3
0
mirror of https://github.com/snipe/snipe-it.git synced 2025-10-29 19:31:41 +00:00

Added CJK and Arabic font support

This commit is contained in:
snipe 2025-09-15 11:29:19 +01:00
parent ec47ee3573
commit 01f7b5d709
9 changed files with 577 additions and 407 deletions

View File

@ -435,6 +435,34 @@ class Helper
return $colors[$index];
}
/**
* Check if a string has any RTL characters
* @param $value
* @return bool
*/
public static function hasRtl($string) {
$rtlChar = '/[\x{0590}-\x{083F}]|[\x{08A0}-\x{08FF}]|[\x{FB1D}-\x{FDFF}]|[\x{FE70}-\x{FEFF}]/u';
return preg_match($rtlChar, $string) != 0;
}
// is chinese, japanese or korean language
public static function isCjk($string) {
return Helper::isChinese($string) || Helper::isJapanese($string) || Helper::isKorean($string);
}
public static function isChinese($string) {
return preg_match("/\p{Han}+/u", $string);
}
public static function isJapanese($string) {
return preg_match('/[\x{4E00}-\x{9FBF}\x{3040}-\x{309F}\x{30A0}-\x{30FF}]/u', $string);
}
public static function isKorean($string) {
return preg_match('/[\x{3130}-\x{318F}\x{AC00}-\x{D7AF}]/u', $string);
}
/**
* Increases or decreases the brightness of a color by a percentage of the current brightness.
*

View File

@ -30,11 +30,12 @@ use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use App\Http\Controllers\SettingsController;
use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
use \Illuminate\Contracts\View\View;
use \Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Log;
use TCPDF;
use App\Helpers\Helper;
class AcceptanceController extends Controller
{
@ -225,9 +226,9 @@ class AcceptanceController extends Controller
'item_status' => $item->assetstatus?->name,
'eula' => $item->getEula(),
'note' => $request->input('note'),
'check_out_date' => Carbon::parse($acceptance->created_at)->format('Y-m-d'),
'accepted_date' => Carbon::parse($acceptance->accepted_at)->format('Y-m-d'),
'assigned_to' => $assigned_user->present()->fullName,
'check_out_date' => Carbon::parse($acceptance->created_at)->format('Y-m-d H:i:s'),
'accepted_date' => Carbon::parse($acceptance->accepted_at)->format('Y-m-d H:i:s'),
'assigned_to' => $assigned_user->display_name,
'company_name' => $branding_settings->site_name,
'signature' => ($sig_filename) ? storage_path() . '/private_uploads/signatures/' . $sig_filename : null,
'logo' => $path_logo,
@ -237,12 +238,96 @@ class AcceptanceController extends Controller
];
if ($pdf_view_route!='') {
Log::debug($pdf_filename.' is the filename, and the route was specified.');
$pdf = Pdf::loadView($pdf_view_route, $data);
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf->output());
// set some language dependent data:
$lg = Array();
$lg['a_meta_charset'] = 'UTF-8';
$lg['w_page'] = 'page';
$pdf = new TCPDF('P', 'mm', 'A4', true, 'UTF-8', false);
// $pdf->SetHeaderData(PDF_HEADER_LOGO, 5, PDF_HEADER_TITLE.' 006', PDF_HEADER_STRING);
// $pdf->SetHeaderData('https://snipe-it.test/uploads/snipe-logo.png', '5', $data['company_name'], $item->company?->name);
//$pdf->headerText = ('Anything you want ' . date('c'));
$pdf->setRTL(false);
//$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, $data['company_name'], '');
$pdf->setLanguageArray($lg);
$pdf->SetFontSubsetting(true);
$pdf->SetCreator('Snipe-IT');
$pdf->SetAuthor($data['assigned_to']);
$pdf->SetTitle('Asset Acceptance: '.$data['item_tag']);
// $pdf->SetSubject('Document Subject');
//$pdf->SetKeywords('keywords, here');
$pdf->SetFont('dejavusans', '', 8, '', true);
// $pdf->SetFont('dejavusans', '', 14);
//
$pdf->SetPrintHeader(false);
$pdf->SetPrintFooter(false);
$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, '', PDF_FONT_SIZE_MAIN));
$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA, '', PDF_FONT_SIZE_DATA));
$pdf->AddPage();
$pdf->writeHTML('<img src="'.$path_logo.'" height="30">', true, 0, true, 0, '');
// $pdf->writeHTML(trans('general.date').': '.date($data['date_settings']), true, 0, true, 0, '');
$pdf->writeHTML("<strong>".trans('general.asset_tag').'</strong>: '.$data['item_tag'], true, 0, true, 0, '');
$pdf->writeHTML("<strong>".trans('general.asset_model').'</strong>: '.$data['item_model'], true, 0, true, 0, '');
$pdf->writeHTML("<strong>".trans('admin/hardware/form.serial').'</strong>: '.$data['item_serial'], true, 0, true, 0, '');
$pdf->writeHTML("<strong>".trans('general.assigned_date').'</strong>: '.$data['check_out_date'], true, 0, true, 0, '');
$pdf->writeHTML("<strong>".trans('general.assignee').'</strong>: '.$data['assigned_to'], true, 0, true, 0, '');
$pdf->Ln();
// $html = view($pdf_view_route, $data)->render();
// $pdf->writeHTML($html, true, 0, true, 0, '');
// $eula_lines = explode("\n\n", $item->getEula());
$eula_lines = preg_split("/\r\n|\n|\r/", $item->getEula());
foreach ($eula_lines as $eula_line) {
if (Helper::hasRtl($eula_line)) {
$pdf->setRTL(true);
} else {
$pdf->setRTL(false);
}
$acceptance->accept($sig_filename, $item->getEula(), $pdf_filename, $request->input('note'));
if (Helper::isCjk($eula_line)) {
$pdf->SetFont('cid0cs', '', 9);
} else {
$pdf->SetFont('dejavusans', '', 8, '', true);
}
$pdf->writeHTML(Helper::parseEscapedMarkedown($eula_line), true, 0, true, 0, '');
}
$pdf->Ln();
$pdf->Ln();
$pdf->setRTL(false);
$pdf->writeHTML('<br><br>', true, 0, true, 0, '');
if ($data['note'] != null) {
$pdf->writeHTML("<strong>".trans('general.notes') . '</strong>: ' . $data['note'], true, 0, true, 0, '');
$pdf->Ln();
}
if ($data['signature'] != null) {
$pdf->writeHTML('<img src="'.$data['signature'].'" style="max-width: 600px;">', true, 0, true, 0, '');
$pdf->writeHTML('<hr>', true, 0, true, 0, '');
}
$pdf->writeHTML("<strong>".trans('general.accepted_date').'</strong>: '.$data['accepted_date'], true, 0, true, 0, '');
$pdf_content = $pdf->Output($pdf_filename, 'S');
//$html = view($pdf_view_route, $data)->render();
//$pdf = PDF::writeHTML($html, true, false, true, false, '');
Storage::put('private_uploads/eula-pdfs/' .$pdf_filename, $pdf_content);
}
// $acceptance->accept($sig_filename, $item->getEula(), $pdf_filename, $request->input('note'));
// Send the PDF to the signing user
if (($request->input('send_copy') == '1') && ($assigned_user->email !='')) {

View File

@ -1037,9 +1037,9 @@ class Asset extends Depreciable
if (($this->model) && ($this->model->category)) {
if (($this->model->category->eula_text) && ($this->model->category->use_default_eula == 0)) {
return Helper::parseEscapedMarkedown($this->model->category->eula_text);
return $this->model->category->eula_text;
} elseif ($this->model->category->use_default_eula == 1) {
return Helper::parseEscapedMarkedown(Setting::getSettings()->default_eula_text);
return Setting::getSettings()->default_eula_text;
} else {
return false;

View File

@ -32,11 +32,11 @@
"arietimmerman/laravel-scim-server": "dev-laravel_11_compatibility",
"bacon/bacon-qr-code": "^2.0",
"barryvdh/laravel-debugbar": "^3.13",
"barryvdh/laravel-dompdf": "^2.0",
"doctrine/cache": "^1.10",
"doctrine/dbal": "^3.1",
"doctrine/instantiator": "^1.3",
"eduardokum/laravel-mail-auto-embed": "^2.0",
"elibyy/tcpdf-laravel": "^11.5",
"enshrined/svg-sanitize": "^0.22.0",
"erusev/parsedown": "^1.7",
"fakerphp/faker": "^1.24",
@ -73,6 +73,7 @@
"spatie/laravel-ignition": "^2.0",
"tabuna/breadcrumbs": "^4.2",
"tecnickcom/tc-lib-barcode": "^1.15",
"tecnickcom/tc-lib-pdf-font": "^2.6",
"tecnickcom/tcpdf": "^6.5",
"unicodeveloper/laravel-password": "^1.0",
"watson/validating": "^8.1"

822
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -300,7 +300,6 @@ return [
App\Providers\SnipeTranslationServiceProvider::class, //we REPLACE the default Laravel translator with our own
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class,
/*
* Package Service Providers...
@ -315,6 +314,8 @@ return [
Unicodeveloper\DumbPassword\DumbPasswordServiceProvider::class,
Eduardokum\LaravelMailAutoEmbed\ServiceProvider::class,
Laravel\Socialite\SocialiteServiceProvider::class,
Elibyy\TCPDF\ServiceProvider::class,
/*
* Application Service Providers...
@ -371,7 +372,7 @@ return [
'Mail' => Illuminate\Support\Facades\Mail::class,
'Notification' => Illuminate\Support\Facades\Notification::class,
'Password' => Illuminate\Support\Facades\Password::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
'PDF' => Elibyy\TCPDF\Facades\TCPDF::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,

17
config/pdf.php Normal file
View File

@ -0,0 +1,17 @@
<?php
return [
'mode' => 'utf-8',
'format' => 'A4',
'author' => '',
'subject' => '',
'keywords' => '',
'creator' => 'Snipe-IT',
'display_mode' => 'fullpage',
'tempDir' => base_path('../temp/'),
'pdf_a' => false,
'pdf_a_auto' => false,
'icc_profile_path' => '',
'defaultCssFile' => false,
'pdfWrapper' => 'misterspelik\LaravelPdf\Wrapper\PdfWrapper',
];

View File

@ -51,7 +51,7 @@
@if ($acceptance->checkoutable->getEula())
<div class="col-md-12" style="padding-top: 15px; padding-bottom: 15px;">
<div style="background-color: rgba(211,211,211,0.25); padding: 10px; border: lightgrey 1px solid;">
{!! str_replace('<p>', '<p dir="auto">', $acceptance->checkoutable->getEula()) !!}
{!! str_replace('<p>', '<p dir="auto">', Helper::parseEscapedMarkedown($acceptance->checkoutable->getEula())) !!}
</div>
</div>
@endif

View File

@ -1,6 +1,6 @@
<?php
namespace Tests\Feature\Users\Ui;
namespace Tests\Feature\Locations\Ui;
use App\Models\Consumable;
use Tests\TestCase;