feat: Enhance product saving functionality with security information and language support

- Added `security_information` parameter to `ShopProduct::save` method.
- Refactored language handling in product saving to utilize `Languages::languages_list`.
- Updated SEO link handling to ensure proper redirection and canonical URLs.
- Improved error handling and logging during the update process in `Update` class.
- Enhanced producer and product classes to include additional language data.
- Updated version to 0.233 and added update logs for better tracking.
This commit is contained in:
2026-01-27 23:46:36 +01:00
parent e3975262cd
commit 33c997ce0d
18 changed files with 661 additions and 164 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -2244,4 +2244,15 @@ textarea.form-control {
input[type="text"] {
height: 40px;
}
}
#integrationsDropdownBtn {
width: 50px;
text-align: center;
}
.dropdown-menu-right {
a {
font-size: 14px;
}
}

View File

@@ -0,0 +1 @@
YToyOntpOjA7aToxNzY5NTUwNzk2O2k6MTtzOjIwOiJwb215c2xvd2VwcmV6ZW50eS5wbCI7fQ==

View File

@@ -218,16 +218,48 @@ if ( $this -> next_order_id )
];
}
$grid -> buttons[] = [
'label' => 'Wyślij ponownie zamówienie do apilo.com',
'url' => '/admin/shop_order/send_order_to_apilo/order_id=' . $this -> order['id'],
'icon' => 'fa-refresh',
'class' => 'btn btn-primary btn-sm mr5 ml5 pull-right btn-send-order-to-apilo'
'label' => '',
'url' => '#',
'icon' => 'fa-ellipsis-v',
'class' => 'btn btn-primary',
'id' => 'integrationsDropdownBtn'
];
$grid -> default_buttons = false;
$grid -> external_code = $out;
echo $grid -> draw();
?>
<div class="dropdown-menu dropdown-menu-right" id="integrationsDropdownMenu">
<a class="dropdown-item btn-send-order-to-apilo" href="/admin/shop_order/send_order_to_apilo/order_id=<?= $this -> order['id'];?>">
<i class="fa fa-refresh"></i> Wyślij ponownie zamówienie do apilo.com
</a>
<a class="dropdown-item btn-toggle-trustmate" href="#">
<i class="fa fa-<?= $this -> order['trustmate_send'] ? 'times' : 'check';?>"></i>
<?= $this -> order['trustmate_send'] ? 'Odznacz zamówienie jako wysłane do trustmate.io' : 'Zaznacz zamówienie jako wysłane do trustmate.io';?>
</a>
</div>
<script type="text/javascript">
$( function() {
var btn = $( '#integrationsDropdownBtn' );
var menu = $( '#integrationsDropdownMenu' );
// Opakuj przycisk w dropdown wrapper
btn.wrap( '<div class="dropdown d-inline-block pull-right"></div>' );
menu.appendTo( btn.parent() );
// Ręczna obsługa toggle dropdown
btn.on( 'click', function(e) {
e.preventDefault();
e.stopPropagation();
menu.toggleClass( 'show' );
});
// Zamknij dropdown po kliknięciu poza nim
$( document ).on( 'click', function(e) {
if ( !btn.is( e.target ) && !menu.is( e.target ) && menu.has( e.target ).length === 0 ) {
menu.removeClass( 'show' );
}
});
});
$( function()
{
var timer = '';
@@ -603,4 +635,54 @@ function order_status_change($order_id, $status, $email) {
}
});
}
$( 'body' ).on( 'click', '.btn-toggle-trustmate', function(e) {
e.preventDefault();
var currentState = <?= $this -> order['trustmate_send'] ? 'true' : 'false';?>;
$.alert({
title: 'Potwierdź',
content: currentState ? 'Czy na pewno chcesz odznaczyć zamówienie jako wysłane do trustmate.io?' : 'Czy na pewno chcesz zaznaczyć zamówienie jako wysłane do trustmate.io?',
type: 'orange',
closeIcon: true,
closeIconClass: 'fa fa-times',
typeAnimated: true,
animation: 'opacity',
columnClass: 'col-12 col-lg-10',
theme: 'modern',
icon: 'fa fa-question',
buttons: {
confirm: {
text: 'Tak',
btnClass: 'btn-success',
keys: ['enter'],
action: function() {
$.ajax({
type: 'POST',
cache: false,
url: '/admin/shop_order/toggle_trustmate_send/',
data: {
order_id: <?= $this -> order['id'];?>
},
beforeSend: function() {
$( '#overlay' ).show();
},
success: function( response ) {
$( '#overlay' ).hide();
var data = jQuery.parseJSON( response );
if ( data.result === true ) {
location.reload();
}
}
});
}
},
cancel: {
text: 'Nie',
btnClass: 'btn-dark',
action: function() {}
}
}
});
});
</script>

View File

@@ -70,8 +70,20 @@ ob_start();
'value' => $this -> producer['languages'][$lg[ 'id']]['description'],
'inline' => true
] );?>
<?= \Html::textarea( [
'label' => 'Dane producenta',
'name' => 'data[' . $lg['id'] . ']',
'id' => 'data_' . $lg['id'],
'value' => $this -> producer['languages'][$lg[ 'id']]['data'],
'inline' => true
] );?>
<script type="text/javascript">
$(function () {
$( '#data_<?= $lg[ 'id' ];?>').ckeditor({
toolbar: 'MyToolbar',
height: '250'
});
$( '#description_<?= $lg[ 'id' ];?>').ckeditor({
toolbar: 'MyToolbar',
height: '250'

View File

@@ -32,6 +32,7 @@ ob_start();
<li><i class="fa fa-exchange"></i>Produkty powiązane</li>
<li><i class="fa fa-file-excel-o"></i>XML</li>
<li><i class="fa fa-file-o"></i>Dodatkowe pola</li>
<li><i class="fa fa-file-o"></i>GPSR</li>
</ul>
<div class="resp-tabs-container settings-tabs">
<div>
@@ -407,25 +408,13 @@ ob_start();
'value' => $this->product['additional_message_text']
]);
?>
<?
$producers[''] = '--- wybierz producenta ---';
foreach ($this->producers as $producer)
$producers[$producer['id']] = $producer['name'];
?>
<?= \Html::select([
'label' => 'Producent',
'name' => 'producer_id',
'id' => 'producer_id',
'values' => $producers,
'value' => $this->product['producer_id']
]); ?>
</div>
<div>
<div id="languages-seo">
<ul class="resp-tabs-list languages-seo htabs">
<? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?>
<? if ($lg['status']) : ?>
<li><? if ($lg['id'] == \front\factory\Languages::default_language()) echo '<i class="fa fa-star fa-lg text-system" title="Język domyślny"></i> '; ?><?= $lg['name']; ?></a></li>
<li><? if ($lg['id'] == \front\factory\Languages::default_language()) echo '<i class="fa fa-star fa-lg text-system" title="Język domyślny"></i> '; ?><?= $lg['name']; ?></li>
<? endif; ?>
<?
endforeach;
@@ -702,6 +691,52 @@ ob_start();
<? endforeach; endif;?>
</div>
</div>
<div>
<?
$producers[''] = '--- wybierz producenta ---';
foreach ($this->producers as $producer)
$producers[$producer['id']] = $producer['name'];
?>
<?= \Html::select([
'label' => 'Producent',
'name' => 'producer_id',
'id' => 'producer_id',
'values' => $producers,
'value' => $this->product['producer_id']
]); ?>
<div id="gpsr-seo">
<ul class="resp-tabs-list gpsr-seo htabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ($lg['status']) : ?>
<li><? if ($lg['id'] == \front\factory\Languages::default_language()) echo '<i class="fa fa-star fa-lg text-system" title="Język domyślny"></i> '; ?><?= $lg['name']; ?></li>
<? endif; ?>
<? endforeach; endif; ?>
</ul>
<div class="resp-tabs-container gpsr-seo">
<? if ( is_array ($this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<div>
<?= \Html::textarea( [
'label' => 'Informacje o bezpieczeństwie ('.$lg['name'].')',
'name' => 'security_information[' . $lg['id'] . ']',
'id' => 'security_information_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['security_information']
] );?>
</div>
<script type="text/javascript">
$(function () {
$( '#security_information_<?= $lg[ 'id' ];?>').ckeditor({
toolbar: 'MyToolbar',
height: '250'
});
});
</script>
<? endif; ?>
<? endforeach; endif;?>
</div>
<div class="clear"></div>
</div>
</div>
</div>
</div>
<?
@@ -951,6 +986,12 @@ echo $grid->draw();
tabidentify: 'languages-seo'
});
$('#gpsr-seo').easyResponsiveTabs({
width: 'auto',
fit: true,
tabidentify: 'gpsr-seo'
});
$('#languages-tabs').easyResponsiveTabs({
width: 'auto',
fit: true,