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,

View File

@@ -115,4 +115,19 @@ class ShopOrder
header( 'Location: /admin/shop_order/order_details/order_id=' . (int)\S::get( 'order_id' ) );
exit;
}
// toggle_trustmate_send
public static function toggle_trustmate_send()
{
global $mdb;
$order_id = (int)\S::get( 'order_id' );
$order = $mdb -> get( 'pp_shop_orders', [ 'trustmate_send' ], [ 'id' => $order_id ] );
$new_value = $order['trustmate_send'] ? 0 : 1;
$mdb -> update( 'pp_shop_orders', [ 'trustmate_send' => $new_value ], [ 'id' => $order_id ] );
echo json_encode( [ 'result' => true, 'trustmate_send' => $new_value ] );
exit;
}
}

View File

@@ -15,7 +15,7 @@ class ShopProducer
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania producenta wystąpił błąd. Proszę spróbować ponownie.' ];
$values = json_decode( \S::get( 'values' ), true );
if ( $producer_id = \admin\factory\ShopProducer::save( $values['id'], $values['name'], $values['status'] == 'on' ? 1 : 0, $values['img'], $values['description'], $values['meta_title'] ) )
if ( $producer_id = \admin\factory\ShopProducer::save( $values['id'], $values['name'], $values['status'] == 'on' ? 1 : 0, $values['img'], $values['description'], $values['data'], $values['meta_title'] ) )
$response = [ 'status' => 'ok', 'msg' => 'Producent został zapisany.', 'id' => $producer_id ];
echo json_encode( $response );

View File

@@ -186,7 +186,7 @@ class ShopProduct
$values['id'], $values['name'], $values['short_description'], $values['description'], $values['status'], $values['meta_description'], $values['meta_keywords'], $values['seo_link'],
$values['copy_from'], $values['categories'], $values['price_netto'], $values['price_brutto'], $values['vat'], $values['promoted'], $values['warehouse_message_zero'], $values['warehouse_message_nonzero'], $values['tab_name_1'],
$values['tab_description_1'], $values['tab_name_2'], $values['tab_description_2'], $values['layout_id'], $values['products_related'], (int) $values['set'], $values['price_netto_promo'], $values['price_brutto_promo'],
$values['new_to_date'], $values['stock_0_buy'], $values['wp'], $values['custom_label_0'], $values['custom_label_1'], $values['custom_label_2'], $values['custom_label_3'], $values['custom_label_4'], $values['additional_message'], (int)$values['quantity'], $values['additional_message_text'], $values['additional_message_required'] == 'on' ? 1 : 0, $values['canonical'], $values['meta_title'], $values['producer_id'], $values['sku'], $values['ean'], $values['product_unit'], $values['weight'], $values['xml_name'], $values['custom_field_name'], $values['custom_field_required']
$values['new_to_date'], $values['stock_0_buy'], $values['wp'], $values['custom_label_0'], $values['custom_label_1'], $values['custom_label_2'], $values['custom_label_3'], $values['custom_label_4'], $values['additional_message'], (int)$values['quantity'], $values['additional_message_text'], $values['additional_message_required'] == 'on' ? 1 : 0, $values['canonical'], $values['meta_title'], $values['producer_id'], $values['sku'], $values['ean'], $values['product_unit'], $values['weight'], $values['xml_name'], $values['custom_field_name'], $values['custom_field_required'], $values['security_information']
) ) {
$response = [ 'status' => 'ok', 'msg' => 'Produkt został zapisany.', 'id' => $id ];
}

View File

@@ -9,11 +9,11 @@ class Languages
global $mdb;
return $mdb -> delete( 'pp_langs_translations', [ 'id' => $translation_id ] );
}
public static function translation_save( $translation_id, $text, $languages )
{
global $mdb;
if ( $translation_id )
{
$mdb -> update( 'pp_langs_translations', [ 'text' => $text ], [ 'id' => $translation_id ] );
@@ -38,13 +38,13 @@ class Languages
return $translation_id;
}
}
public static function translation_details( $translation_id )
{
global $mdb;
return $mdb -> get( 'pp_langs_translations', '*', [ 'id' => $translation_id ] );
}
public static function language_delete( $language_id )
{
global $mdb;
@@ -127,10 +127,15 @@ class Languages
return $mdb -> get( 'pp_langs', '*', [ 'id' => $language_id ] );
}
public static function languages_list()
public static function languages_list( $only_active = false )
{
global $mdb;
return $mdb -> select( 'pp_langs', '*', [ 'ORDER' => [ 'o' => 'ASC' ] ] );
$where = [];
if ( $only_active )
$where['status'] = 1;
return $mdb -> select( 'pp_langs', '*', array_merge( [ 'ORDER' => [ 'o' => 'ASC' ] ], $where ) );
}
}
?>

View File

@@ -14,28 +14,30 @@ class ShopProducer
return $mdb -> delete( 'pp_shop_producer', [ 'id' => $producer_id ] );
}
static public function save( $producer_id, $name, int $status, $img, $description, $meta_title )
static public function save( $producer_id, $name, int $status, $img, $description, $data, $meta_title )
{
global $mdb;
if ( !$producer_id )
{
$mdb -> insert( 'pp_shop_producer', [
'name' => $name,
'status' => $status,
'img' => $img
] );
'name' => $name,
'status' => $status,
'img' => $img
] );
$id = $mdb -> id();
foreach ( $description as $key => $val )
$langs = \admin\factory\Languages::languages_list( true );
foreach ( $langs as $lg )
{
$mdb -> insert( 'pp_shop_producer_lang', [
'producer_id' => $id,
'lang_id' => $key,
'description' => $val,
'meta_title' => $meta_title[$key]
] );
'producer_id' => $id,
'lang_id' => $lg['id'],
'description' => $description[ $lg['id'] ] ?? null,
'data' => $data[ $lg['id'] ] ?? null,
'meta_title' => $meta_title[ $lg['id'] ] ?? null
] );
}
\S::htacces();
@@ -46,29 +48,36 @@ class ShopProducer
else
{
$mdb -> update( 'pp_shop_producer', [
'name' => $name,
'status' => $status,
'img' => $img
], [
'id' => (int) $producer_id
] );
'name' => $name,
'status' => $status,
'img' => $img
], [
'id' => (int) $producer_id
] );
foreach ( $description as $key => $val )
$langs = \admin\factory\Languages::languages_list( true );
foreach ( $langs as $lg )
{
if ( $translation_id = $mdb -> get( 'pp_shop_producer_lang', 'id', [ 'AND' => [ 'producer_id' => $producer_id, 'lang_id' => $key ] ] ) )
if ( $translation_id = $mdb -> get( 'pp_shop_producer_lang', 'id', [ 'AND' => [ 'producer_id' => $producer_id, 'lang_id' => $lg['id'] ] ] ) )
{
$mdb -> update( 'pp_shop_producer_lang', [
'description' => $val,
'meta_title' => $meta_title[$key]
'description' => $description[ $lg['id'] ] ?? null,
'meta_title' => $meta_title[ $lg['id'] ] ?? null,
'data' => $data[ $lg['id'] ] ?? null
], [
'id' => $translation_id
] );
}
else
{
$mdb -> insert( 'pp_shop_producer_lang', [
'producer_id' => $producer_id,
'lang_id' => $key,
'description' => $val,
'meta_title' => $meta_title[$key]
'lang_id' => $lg['id'],
'description' => $description[ $lg['id'] ] ?? null,
'data' => $data[ $lg['id'] ] ?? null,
'meta_title' => $meta_title[ $lg['id'] ] ?? null
] );
}
}
\S::htacces();

View File

@@ -761,7 +761,7 @@ class ShopProduct
}
public static function save(
$product_id, $name, $short_description, $description, $status, $meta_description, $meta_keywords, $seo_link, $copy_from, $categories, $price_netto, $price_brutto, $vat, $promoted, $warehouse_message_zero, $warehouse_message_nonzero, $tab_name_1, $tab_description_1, $tab_name_2, $tab_description_2, $layout_id, $products_related, int $set_id, $price_netto_promo, $price_brutto_promo, $new_to_date, $stock_0_buy, $wp, $custom_label_0, $custom_label_1, $custom_label_2, $custom_label_3, $custom_label_4, $additional_message, int $quantity, $additional_message_text, int $additional_message_required, $canonical, $meta_title, $producer_id, $sku, $ean, $product_unit, $weight, $xml_name, $custom_field_name, $custom_field_required
$product_id, $name, $short_description, $description, $status, $meta_description, $meta_keywords, $seo_link, $copy_from, $categories, $price_netto, $price_brutto, $vat, $promoted, $warehouse_message_zero, $warehouse_message_nonzero, $tab_name_1, $tab_description_1, $tab_name_2, $tab_description_2, $layout_id, $products_related, int $set_id, $price_netto_promo, $price_brutto_promo, $new_to_date, $stock_0_buy, $wp, $custom_label_0, $custom_label_1, $custom_label_2, $custom_label_3, $custom_label_4, $additional_message, int $quantity, $additional_message_text, int $additional_message_required, $canonical, $meta_title, $producer_id, $sku, $ean, $product_unit, $weight, $xml_name, $custom_field_name, $custom_field_required, $security_information
)
{
global $mdb, $user;
@@ -804,27 +804,29 @@ class ShopProduct
if ( $id )
{
foreach ( $name as $key => $val )
$langs = \admin\factory\Languages::languages_list( true );
foreach ( $langs as $lg )
{
$mdb -> insert( 'pp_shop_products_langs', [
'product_id' => (int) $id,
'lang_id' => $key,
'name' => '' !== $name[$key] ? $name[$key] : null,
'short_description' => '' !== $short_description[$key] ? $short_description[$key] : null,
'description' => '' !== $description[$key] ? $description[$key] : null,
'meta_description' => '' !== $meta_description[$key] ? $meta_description[$key] : null,
'meta_keywords' => '' !== $meta_keywords[$key] ? $meta_keywords[$key] : null,
'seo_link' => '' !== \S::seo($seo_link[$key]) ? \S::seo($seo_link[$key]) : null,
'copy_from' => '' !== $copy_from[$key] ? $copy_from[$key] : null,
'warehouse_message_zero' => '' !== $warehouse_message_zero[$key] ? $warehouse_message_zero[$key] : null,
'warehouse_message_nonzero' => '' !== $warehouse_message_nonzero[$key] ? $warehouse_message_nonzero[$key] : null,
'tab_name_1' => '' !== $tab_name_1[$key] ? $tab_name_1[$key] : null,
'tab_description_1' => '' !== $tab_description_1[$key] ? $tab_description_1[$key] : null,
'tab_name_2' => '' !== $tab_name_2[$key] ? $tab_name_2[$key] : null,
'tab_description_2' => '' !== $tab_description_2[$key] ? $tab_description_2[$key] : null,
'canonical' => '' !== $canonical[$key] ? $canonical[$key] : null,
'meta_title' => '' !== $meta_title[$key] ? $meta_title[$key] : null,
'xml_name' => '' !== $xml_name[$key] ? $xml_name[$key] : null,
'lang_id' => $lg['id'],
'name' => $name[$lg['id']] ? $name[$lg['id']] : null,
'short_description' => $short_description[$lg['id']] ? $short_description[$lg['id']] : null,
'description' => $description[$lg['id']] ? $description[$lg['id']] : null,
'meta_description' => $meta_description[$lg['id']] ? $meta_description[$lg['id']] : null,
'meta_keywords' => $meta_keywords[$lg['id']] ? $meta_keywords[$lg['id']] : null,
'seo_link' => $seo_link[$lg['id']] ? \S::seo($seo_link[$lg['id']]) : null,
'copy_from' => $copy_from[$lg['id']] ? $copy_from[$lg['id']] : null,
'warehouse_message_zero' => $warehouse_message_zero[$lg['id']] ? $warehouse_message_zero[$lg['id']] : null,
'warehouse_message_nonzero' => $warehouse_message_nonzero[$lg['id']] ? $warehouse_message_nonzero[$lg['id']] : null,
'tab_name_1' => $tab_name_1[$lg['id']] ? $tab_name_1[$lg['id']] : null,
'tab_description_1' => $tab_description_1[$lg['id']] ? $tab_description_1[$lg['id']] : null,
'tab_name_2' => $tab_name_2[$lg['id']] ? $tab_name_2[$lg['id']] : null,
'tab_description_2' => $tab_description_2[$lg['id']] ? $tab_description_2[$lg['id']] : null,
'canonical' => $canonical[$lg['id']] ? $canonical[$lg['id']] : null,
'meta_title' => $meta_title[$lg['id']] ? $meta_title[$lg['id']] : null,
'xml_name' => $xml_name[$lg['id']] ? $xml_name[$lg['id']] : null,
'security_information' => $security_information[$lg['id']] ? $security_information[$lg['id']] : null,
] );
}
@@ -1007,51 +1009,52 @@ class ShopProduct
\admin\factory\ShopProduct::update_product_combinations_prices( $product_id, $price_brutto, $vat, $price_brutto_promo );
foreach ( $name as $key => $val )
$langs = \admin\factory\Languages::languages_list( true );
foreach ( $langs as $lg )
{
if ( $translation_id = $mdb -> get( 'pp_shop_products_langs', 'id', [ 'AND' => [ 'product_id' => $product_id, 'lang_id' => $key ] ] ) )
if ( $translation_id = $mdb -> get( 'pp_shop_products_langs', 'id', [ 'AND' => [ 'product_id' => $product_id, 'lang_id' => $lg['id'] ] ] ) )
{
$current_seo_link = $mdb -> get( 'pp_shop_products_langs', 'seo_link', [ 'id' => $translation_id ] );
if ( $seo_link[$key] )
$new_seo_link = \S::seo( $seo_link[$key] );
if ( $seo_link[$lg['id']] )
$new_seo_link = \S::seo( $seo_link[$lg['id']] );
else
$new_seo_link = \S::seo( 'p-' . $product_id . '-' . $name[$key] );
$new_seo_link = \S::seo( 'p-' . $product_id . '-' . $name[$lg['id']] );
if ( $new_seo_link !== $current_seo_link and $current_seo_link != '' )
{
if ( !$mdb -> count( 'pp_redirects', [ 'from' => $current_seo_link, 'to' => $new_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] ) )
if ( !$mdb -> count( 'pp_redirects', [ 'from' => $current_seo_link, 'to' => $new_seo_link, 'lang_id' => $lg['id'], 'product_id' => $product_id ] ) )
{
if ( $mdb -> count( 'pp_redirects', [ 'from' => $new_seo_link, 'to' => $current_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] ) )
$mdb -> delete( 'pp_redirects', [ 'from' => $new_seo_link, 'to' => $current_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] );
if ( $mdb -> count( 'pp_redirects', [ 'from' => $new_seo_link, 'to' => $current_seo_link, 'lang_id' => $lg['id'], 'product_id' => $product_id ] ) )
$mdb -> delete( 'pp_redirects', [ 'from' => $new_seo_link, 'to' => $current_seo_link, 'lang_id' => $lg['id'], 'product_id' => $product_id ] );
else
{
if ( \S::canAddRedirect( $current_seo_link, $new_seo_link ) )
$mdb -> insert( 'pp_redirects', [ 'from' => $current_seo_link, 'to' => $new_seo_link, 'lang_id' => $key, 'product_id' => $product_id ] );
$mdb -> insert( 'pp_redirects', [ 'from' => $current_seo_link, 'to' => $new_seo_link, 'lang_id' => $lg['id'], 'product_id' => $product_id ] );
else
$mdb -> delete( 'pp_redirects', [ 'product_id' => $product_id, 'lang_id' => $key ] );
$mdb -> delete( 'pp_redirects', [ 'product_id' => $product_id, 'lang_id' => $lg['id'] ] );
}
}
}
$mdb -> update( 'pp_shop_products_langs', [
'lang_id' => $key,
'name' => '' !== $name[$key] ? $name[$key] : null,
'short_description' => '' !== $short_description[$key] ? $short_description[$key] : null,
'description' => '' !== $description[$key] ? $description[$key] : null,
'meta_description' => '' !== $meta_description[$key] ? $meta_description[$key] : null,
'meta_keywords' => '' !== $meta_keywords[$key] ? $meta_keywords[$key] : null,
'seo_link' => \S::seo( $seo_link[$key] ) != '' ? \S::seo( $seo_link[$key] ) : \S::seo( 'p-' . $product_id . '-' . $name[$key] ),
'copy_from' => '' !== $copy_from[$key] ? $copy_from[$key] : null,
'warehouse_message_zero' => '' !== $warehouse_message_zero[$key] ? $warehouse_message_zero[$key] : null,
'warehouse_message_nonzero' => '' !== $warehouse_message_nonzero[$key] ? $warehouse_message_nonzero[$key] : null,
'tab_name_1' => '' !== $tab_name_1[$key] ? $tab_name_1[$key] : null,
'tab_description_1' => '' !== $tab_description_1[$key] ? $tab_description_1[$key] : null,
'tab_name_2' => '' !== $tab_name_2[$key] ? $tab_name_2[$key] : null,
'tab_description_2' => '' !== $tab_description_2[$key] ? $tab_description_2[$key] : null,
'canonical' => '' !== $canonical[$key] ? $canonical[$key] : null,
'meta_title' => '' !== $meta_title[$key] ? $meta_title[$key] : null,
'xml_name' => '' !== $xml_name[$key] ? $xml_name[$key] : null,
'name' => $name[$lg['id']] ? $name[$lg['id']] : null,
'short_description' => $short_description[$lg['id']] ? $short_description[$lg['id']] : null,
'description' => $description[$lg['id']] ? $description[$lg['id']] : null,
'meta_description' => $meta_description[$lg['id']] ? $meta_description[$lg['id']] : null,
'meta_keywords' => $meta_keywords[$lg['id']] ? $meta_keywords[$lg['id']] : null,
'seo_link' => $seo_link[$lg['id']] ? \S::seo($seo_link[$lg['id']]) : null,
'copy_from' => $copy_from[$lg['id']] ? $copy_from[$lg['id']] : null,
'warehouse_message_zero' => $warehouse_message_zero[$lg['id']] ? $warehouse_message_zero[$lg['id']] : null,
'warehouse_message_nonzero' => $warehouse_message_nonzero[$lg['id']] ? $warehouse_message_nonzero[$lg['id']] : null,
'tab_name_1' => $tab_name_1[$lg['id']] ? $tab_name_1[$lg['id']] : null,
'tab_description_1' => $tab_description_1[$lg['id']] ? $tab_description_1[$lg['id']] : null,
'tab_name_2' => $tab_name_2[$lg['id']] ? $tab_name_2[$lg['id']] : null,
'tab_description_2' => $tab_description_2[$lg['id']] ? $tab_description_2[$lg['id']] : null,
'canonical' => $canonical[$lg['id']] ? $canonical[$lg['id']] : null,
'meta_title' => $meta_title[$lg['id']] ? $meta_title[$lg['id']] : null,
'xml_name' => $xml_name[$lg['id']] ? $xml_name[$lg['id']] : null,
'security_information' => $security_information[$lg['id']] ? $security_information[$lg['id']] : null,
], [
'id' => $translation_id
] );
@@ -1059,24 +1062,25 @@ class ShopProduct
else
{
$mdb -> insert( 'pp_shop_products_langs', [
'product_id' => (int)$product_id,
'lang_id' => $key,
'name' => '' !== $name[$key] ? $name[$key] : null,
'short_description' => '' !== $short_description[$key] ? $short_description[$key] : null,
'description' => '' !== $description[$key] ? $description[$key] : null,
'meta_description' => '' !== $meta_description[$key] ? $meta_description[$key] : null,
'meta_keywords' => '' !== $meta_keywords[$key] ? $meta_keywords[$key] : null,
'seo_link' => '' !== \S::seo($seo_link[$key]) ? \S::seo($seo_link[$key]) : null,
'copy_from' => '' !== $copy_from[$key] ? $copy_from[$key] : null,
'warehouse_message_zero' => '' !== $warehouse_message_zero[$key] ? $warehouse_message_zero[$key] : null,
'warehouse_message_nonzero' => '' !== $warehouse_message_nonzero[$key] ? $warehouse_message_nonzero[$key] : null,
'tab_name_1' => '' !== $tab_name_1[$key] ? $tab_name_1[$key] : null,
'tab_description_1' => '' !== $tab_description_1[$key] ? $tab_description_1[$key] : null,
'tab_name_2' => '' !== $tab_name_2[$key] ? $tab_name_2[$key] : null,
'tab_description_2' => '' !== $tab_description_2[$key] ? $tab_description_2[$key] : null,
'canonical' => '' !== $canonical[$key] ? $canonical[$key] : null,
'meta_title' => '' !== $meta_title[$key] ? $meta_title[$key] : null,
'xml_name' => '' !== $xml_name[$key] ? $xml_name[$key] : null,
'product_id' => (int) $product_id,
'lang_id' => $lg['id'],
'name' => $name[$lg['id']] ? $name[$lg['id']] : null,
'short_description' => $short_description[$lg['id']] ? $short_description[$lg['id']] : null,
'description' => $description[$lg['id']] ? $description[$lg['id']] : null,
'meta_description' => $meta_description[$lg['id']] ? $meta_description[$lg['id']] : null,
'meta_keywords' => $meta_keywords[$lg['id']] ? $meta_keywords[$lg['id']] : null,
'seo_link' => $seo_link[$lg['id']] ? \S::seo($seo_link[$lg['id']]) : null,
'copy_from' => $copy_from[$lg['id']] ? $copy_from[$lg['id']] : null,
'warehouse_message_zero' => $warehouse_message_zero[$lg['id']] ? $warehouse_message_zero[$lg['id']] : null,
'warehouse_message_nonzero' => $warehouse_message_nonzero[$lg['id']] ? $warehouse_message_nonzero[$lg['id']] : null,
'tab_name_1' => $tab_name_1[$lg['id']] ? $tab_name_1[$lg['id']] : null,
'tab_description_1' => $tab_description_1[$lg['id']] ? $tab_description_1[$lg['id']] : null,
'tab_name_2' => $tab_name_2[$lg['id']] ? $tab_name_2[$lg['id']] : null,
'tab_description_2' => $tab_description_2[$lg['id']] ? $tab_description_2[$lg['id']] : null,
'canonical' => $canonical[$lg['id']] ? $canonical[$lg['id']] : null,
'meta_title' => $meta_title[$lg['id']] ? $meta_title[$lg['id']] : null,
'xml_name' => $xml_name[$lg['id']] ? $xml_name[$lg['id']] : null,
'security_information' => $security_information[$lg['id']] ? $security_information[$lg['id']] : null,
] );
}
}

View File

@@ -7,101 +7,343 @@ class Update
{
global $mdb, $settings;
@file_put_contents( '../libraries/update_log.txt', '' );
$log = [];
$log[] = '[START] Rozpoczęcie aktualizacji - ' . date('Y-m-d H:i:s');
$log[] = '[INFO] Aktualna wersja: ' . \S::get_version();
\S::delete_session( 'new-version' );
$versions = file_get_contents( 'https://shoppro.project-dc.pl/updates/versions.php?key=' . $settings['update_key'] );
$versions_url = 'https://shoppro.project-dc.pl/updates/versions.php?key=' . $settings['update_key'];
$versions = @file_get_contents( $versions_url );
if ( $versions === false )
{
$log[] = '[ERROR] Nie udało się pobrać listy wersji z: ' . $versions_url;
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$log[] = '[OK] Pobrano listę wersji';
$versions = explode( PHP_EOL, $versions );
$log[] = '[INFO] Znaleziono ' . count($versions) . ' wersji do sprawdzenia';
foreach ( $versions as $ver )
{
$ver = trim( $ver );
if ( floatval( $ver ) > (float)\S::get_version() )
{
$log[] = '[INFO] Aktualizacja do wersji: ' . $ver;
if ( strlen( $ver ) == 5 )
$dir = substr( $ver, 0, strlen( $ver ) - 2 ) . 0;
else
$dir = substr( $ver, 0, strlen( $ver ) - 1 ) . 0;
$file = file_get_contents( 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '.zip' );
$zip_url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '.zip';
$log[] = '[INFO] Pobieranie pliku ZIP: ' . $zip_url;
$dlHandler = fopen( 'update.zip' , 'w' );
if ( !fwrite( $dlHandler, $file ) )
return false;
$file = @file_get_contents( $zip_url );
if ( $file === false )
{
$log[] = '[ERROR] Nie udało się pobrać pliku ZIP';
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$file_size = strlen( $file );
$log[] = '[OK] Pobrano plik ZIP, rozmiar: ' . $file_size . ' bajtów';
if ( $file_size < 100 )
{
$log[] = '[ERROR] Plik ZIP jest za mały (prawdopodobnie błąd pobierania)';
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$dlHandler = @fopen( 'update.zip' , 'w' );
if ( !$dlHandler )
{
$log[] = '[ERROR] Nie udało się otworzyć pliku update.zip do zapisu';
$log[] = '[INFO] Katalog roboczy: ' . getcwd();
$log[] = '[INFO] Uprawnienia katalogu: ' . substr(sprintf('%o', fileperms('.')), -4);
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$written = fwrite( $dlHandler, $file );
fclose( $dlHandler );
if ( $written === false || $written === 0 )
{
$log[] = '[ERROR] Nie udało się zapisać pliku ZIP (zapisano: ' . ($written === false ? 'false' : $written) . ' bajtów)';
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$log[] = '[OK] Zapisano plik ZIP (' . $written . ' bajtów)';
if ( !file_exists( 'update.zip' ) )
return false;
{
$log[] = '[ERROR] Plik update.zip nie istnieje po zapisie';
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$actual_size = filesize( 'update.zip' );
$log[] = '[OK] Plik update.zip istnieje, rozmiar na dysku: ' . $actual_size . ' bajtów';
/* aktualizacja bazy danych */
$sql_url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_sql.txt';
$log[] = '[INFO] Sprawdzanie aktualizacji SQL: ' . $sql_url;
$ch = curl_init( $sql_url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_HEADER, false );
$response = curl_exec( $ch );
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
$content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE );
curl_close( $ch );
$sql = [];
if ( $response && strpos( $content_type, 'text/plain' ) !== false )
{
$sql = explode( PHP_EOL, $response );
$log[] = '[OK] Pobrano ' . count($sql) . ' zapytań SQL';
}
else
{
/* aktualizacja bazy danych */
$url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_sql.txt';
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_HEADER, false );
$response = curl_exec( $ch );
$content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE );
$log[] = '[INFO] Brak aktualizacji SQL (HTTP: ' . $http_code . ')';
}
if ( $response and strpos( $content_type, 'text/plain' ) !== false )
$sql = explode( PHP_EOL, $response );
if ( is_array( $sql ) and !empty( $sql ) ) foreach ( $sql as $query )
if ( is_array( $sql ) && !empty( $sql ) )
{
$sql_success = 0;
$sql_errors = 0;
foreach ( $sql as $query )
{
if ( $sql )
$query = trim( $query );
if ( !empty( $query ) )
{
$result = $mdb -> query( $query );
$result = $mdb->query( $query );
if ( $result ) $sql_success++;
else $sql_errors++;
}
}
$log[] = '[INFO] Wykonano zapytania SQL - sukces: ' . $sql_success . ', błędy: ' . $sql_errors;
}
/* usuwanie zbędnych plików */
$url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_files.txt';
$ch = curl_init( $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_HEADER, false );
$response = curl_exec( $ch );
$content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE );
/* usuwanie zbędnych plików */
$files_url = 'https://shoppro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_files.txt';
$log[] = '[INFO] Sprawdzanie plików do usunięcia: ' . $files_url;
if ( $response and strpos( $content_type, 'text/plain' ) !== false )
$files = explode( PHP_EOL, $response );
$ch = curl_init( $files_url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_HEADER, false );
$response = curl_exec( $ch );
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
$content_type = curl_getinfo( $ch, CURLINFO_CONTENT_TYPE );
curl_close( $ch );
if ( is_array( $files ) and !empty( $files ) ) foreach ( $files as $file )
$files = [];
if ( $response && strpos( $content_type, 'text/plain' ) !== false )
$files = explode( PHP_EOL, $response );
$deleted_files = 0;
$deleted_dirs = 0;
if ( is_array( $files ) && !empty( $files ) )
{
foreach ( $files as $file )
{
if ( strpos( $file, 'F: ' ) !== false )
{
$file = substr( $file, 3, strlen( $file ) );
if ( file_exists( $file ) )
unlink( $file );
{
if ( @unlink( $file ) ) $deleted_files++;
else $log[] = '[WARNING] Nie udało się usunąć pliku: ' . $file;
}
}
if ( strpos( $file, 'D: ' ) !== false )
{
$dir = substr( $file, 3, strlen( $file ) );
if ( is_dir( $dir ) )
\S::delete_dir( $dir );
$dir_to_delete = substr( $file, 3, strlen( $file ) );
if ( is_dir( $dir_to_delete ) )
{
\S::delete_dir( $dir_to_delete );
$deleted_dirs++;
}
}
}
}
$log[] = '[INFO] Usunięto plików: ' . $deleted_files . ', katalogów: ' . $deleted_dirs;
/* wgrywanie nowych plików */
$file_name = 'update.zip';
$log[] = '[INFO] Rozpoczęcie rozpakowywania pliku ZIP';
$path = pathinfo( realpath( $file_name ), PATHINFO_DIRNAME );
$log[] = '[INFO] Ścieżka pathinfo: ' . $path;
$path = substr( $path, 0, strlen( $path ) - 5 );
$log[] = '[INFO] Ścieżka docelowa (po obcięciu): ' . $path;
if ( !is_dir( $path ) )
{
$log[] = '[ERROR] Ścieżka docelowa nie istnieje: ' . $path;
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
if ( !is_writable( $path ) )
{
$log[] = '[ERROR] Brak uprawnień do zapisu w: ' . $path;
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$log[] = '[OK] Ścieżka docelowa istnieje i jest zapisywalna';
$zip = new \ZipArchive;
$res = $zip->open( $file_name );
if ( $res !== true )
{
$zip_errors = [
\ZipArchive::ER_EXISTS => 'Plik już istnieje',
\ZipArchive::ER_INCONS => 'Archiwum ZIP jest niespójne',
\ZipArchive::ER_INVAL => 'Nieprawidłowy argument',
\ZipArchive::ER_MEMORY => 'Błąd alokacji pamięci',
\ZipArchive::ER_NOENT => 'Plik nie istnieje',
\ZipArchive::ER_NOZIP => 'Plik nie jest archiwum ZIP',
\ZipArchive::ER_OPEN => 'Nie można otworzyć pliku',
\ZipArchive::ER_READ => 'Błąd odczytu',
\ZipArchive::ER_SEEK => 'Błąd seek',
];
$error_msg = isset( $zip_errors[$res] ) ? $zip_errors[$res] : 'Nieznany błąd (' . $res . ')';
$log[] = '[ERROR] Nie udało się otworzyć pliku ZIP: ' . $error_msg;
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
$log[] = '[OK] Otwarto archiwum ZIP, liczba plików: ' . $zip->numFiles;
$extracted_count = 0;
$extract_errors = 0;
$skipped_dirs = 0;
for ( $i = 0; $i < $zip->numFiles; $i++ )
{
$filename = $zip->getNameIndex( $i );
$filename_clean = str_replace( '\\', '/', $filename );
if ( substr( $filename_clean, -1 ) === '/' )
{
$dir_path = $path . '/' . $filename_clean;
if ( !is_dir( $dir_path ) )
{
if ( @mkdir( $dir_path, 0755, true ) )
$log[] = '[DIR] Utworzono katalog: ' . $filename_clean;
else
$log[] = '[WARNING] Nie udało się utworzyć katalogu: ' . $filename_clean;
}
$skipped_dirs++;
continue;
}
$target_file = $path . '/' . $filename_clean;
$target_dir = dirname( $target_file );
if ( !is_dir( $target_dir ) )
{
if ( !@mkdir( $target_dir, 0755, true ) )
{
$log[] = '[ERROR] Nie udało się utworzyć katalogu dla: ' . $filename_clean;
$extract_errors++;
continue;
}
}
/* wgrywanie nowych plików */
$file_name = 'update.zip';
$file_existed = file_exists( $target_file );
$old_size = $file_existed ? filesize( $target_file ) : 0;
$old_mtime = $file_existed ? filemtime( $target_file ) : 0;
$path = pathinfo( realpath( $file_name ), PATHINFO_DIRNAME );
$path = substr( $path, 0, strlen( $path ) - 5 );
$zip = new \ZipArchive;
$res = $zip -> open( $file_name );
if ( $res === TRUE )
$content = $zip->getFromIndex( $i );
if ( $content === false )
{
$zip -> extractTo( $path );
$zip -> close();
unlink( $file_name );
$log[] = '[ERROR] Nie udało się odczytać z ZIP: ' . $filename_clean;
$extract_errors++;
continue;
}
$updateThis = fopen( '../libraries/version.ini', 'w' );
fwrite( $updateThis, $ver );
fclose( $updateThis );
$write_result = @file_put_contents( $target_file, $content );
return true;
if ( $write_result === false )
{
$log[] = '[ERROR] Nie udało się zapisać: ' . $filename_clean . ' (uprawnienia?)';
$extract_errors++;
}
else
{
$new_size = filesize( $target_file );
$new_mtime = filemtime( $target_file );
if ( $file_existed )
{
if ( $old_mtime !== $new_mtime || $old_size !== $new_size )
$log[] = '[UPDATED] ' . $filename_clean . ' (' . $old_size . ' -> ' . $new_size . ' bajtów)';
else
$log[] = '[UNCHANGED] ' . $filename_clean . ' (nie zmieniono - identyczny?)';
}
else
{
$log[] = '[NEW] ' . $filename_clean . ' (' . $new_size . ' bajtów)';
}
$extracted_count++;
}
}
$log[] = '[OK] Rozpakowano ' . $extracted_count . ' plików, błędów: ' . $extract_errors . ', katalogów: ' . $skipped_dirs;
$zip->close();
if ( @unlink( $file_name ) )
$log[] = '[OK] Usunięto plik update.zip';
else
$log[] = '[WARNING] Nie udało się usunąć pliku update.zip';
/* aktualizacja wersji */
$version_file = '../libraries/version.ini';
$updateThis = @fopen( $version_file, 'w' );
if ( !$updateThis )
{
$log[] = '[ERROR] Nie udało się otworzyć pliku version.ini do zapisu';
self::saveUpdateLog( $log );
return [ 'success' => false, 'log' => $log ];
}
fwrite( $updateThis, $ver );
fclose( $updateThis );
$log[] = '[OK] Zaktualizowano plik version.ini do wersji: ' . $ver;
$log[] = '[SUCCESS] Aktualizacja do wersji ' . $ver . ' zakończona pomyślnie';
self::saveUpdateLog( $log );
return [ 'success' => true, 'log' => $log ];
}
}
$log[] = '[INFO] Brak nowych wersji do zainstalowania';
self::saveUpdateLog( $log );
return [ 'success' => true, 'log' => $log, 'no_updates' => true ];
}
private static function saveUpdateLog( $log )
{
$log_content = implode( "\n", $log );
@file_put_contents( '../libraries/update_log.txt', $log_content );
}
public static function update0197()

View File

@@ -14,6 +14,7 @@ class Producer implements \ArrayAccess
foreach ( $rows as $row )
{
$languages[ $row['lang_id'] ]['description'] = $row['description'];
$languages[ $row['lang_id'] ]['data'] = $row['data'];
$languages[ $row['lang_id'] ]['meta_title'] = $row['meta_title'];
}

View File

@@ -80,7 +80,13 @@ class Product implements \ArrayAccess
}
}
$this -> producer = $mdb -> get( 'pp_shop_producer', '*', [ 'id' => (int) $this -> producer_id ] );
$producer = $mdb -> get( 'pp_shop_producer', '*', [ 'id' => (int) $this -> producer_id ] );
$producer_languages = $mdb -> get( 'pp_shop_producer_lang', '*', [ 'AND' => [ 'producer_id' => (int) $this -> producer_id, 'lang_id' => $lang_id ] ] );
$producer['description'] = $producer_languages['description'];
$producer['data'] = $producer_languages['data'];
$producer['meta_title'] = $producer_languages['meta_title'];
$this -> producer = $producer;
if ( $permutation_hash )
{

68
libraries/update_log.txt Normal file
View File

@@ -0,0 +1,68 @@
[START] Rozpoczęcie aktualizacji - 2026-01-27 22:17:12
[INFO] Aktualna wersja: 0.233
[OK] Pobrano listę wersji
[INFO] Znaleziono 235 wersji do sprawdzenia
[INFO] Aktualizacja do wersji: 0.234
[INFO] Pobieranie pliku ZIP: https://shoppro.project-dc.pl/updates/0.20/ver_0.234.zip
[OK] Pobrano plik ZIP, rozmiar: 899184 bajtów
[OK] Zapisano plik ZIP (899184 bajtów)
[OK] Plik update.zip istnieje, rozmiar na dysku: 899184 bajtów
[INFO] Sprawdzanie aktualizacji SQL: https://shoppro.project-dc.pl/updates/0.20/ver_0.234_sql.txt
[INFO] Brak aktualizacji SQL (HTTP: 200)
[INFO] Sprawdzanie plików do usunięcia: https://shoppro.project-dc.pl/updates/0.20/ver_0.234_files.txt
[INFO] Usunięto plików: 0, katalogów: 0
[INFO] Rozpoczęcie rozpakowywania pliku ZIP
[INFO] Ścieżka pathinfo: /home/host700513/domains/pomysloweprezenty.pl/public_html/admin
[INFO] Ścieżka docelowa (po obcięciu): /home/host700513/domains/pomysloweprezenty.pl/public_html/
[OK] Ścieżka docelowa istnieje i jest zapisywalna
[OK] Otwarto archiwum ZIP, liczba plików: 54
[UPDATED] admin/templates/shop-order/order-details.php (21729 -> 24396 bajtów)
[UPDATED] autoload/admin/controls/class.ShopOrder.php (3956 -> 4449 bajtów)
[UPDATED] admin/layout/.htaccess (542 -> 542 bajtów)
[UPDATED] admin/layout/icon/icon-menu/baseline-settings.svg (1056 -> 1056 bajtów)
[UPDATED] admin/layout/icon/icon-menu/baseline-sticky-note-2.svg (490 -> 490 bajtów)
[UPDATED] admin/layout/icon/icon-menu/burst-sale.svg (2348 -> 2348 bajtów)
[UPDATED] admin/layout/icon/icon-menu/bus.svg (1068 -> 1068 bajtów)
[UPDATED] admin/layout/icon/icon-menu/bx-at.svg (814 -> 814 bajtów)
[UPDATED] admin/layout/icon/icon-menu/bxs-category-alt.svg (634 -> 634 bajtów)
[UPDATED] admin/layout/icon/icon-menu/bxs-dashboard.svg (647 -> 647 bajtów)
[UPDATED] admin/layout/icon/icon-menu/calendar-settings.svg (950 -> 950 bajtów)
[UPDATED] admin/layout/icon/icon-menu/chevrons-right.svg (489 -> 489 bajtów)
[UPDATED] admin/layout/icon/icon-menu/chevrons-right_1.svg (489 -> 489 bajtów)
[UPDATED] admin/layout/icon/icon-menu/coins-fill.svg (671 -> 671 bajtów)
[UPDATED] admin/layout/icon/icon-menu/file-image-outlined.svg (802 -> 802 bajtów)
[UPDATED] admin/layout/icon/icon-menu/language.svg (1277 -> 1277 bajtów)
[UPDATED] admin/layout/icon/icon-menu/letter-aa.svg (537 -> 537 bajtów)
[UPDATED] admin/layout/icon/icon-menu/menu(1).svg (714 -> 714 bajtów)
[UPDATED] admin/layout/icon/icon-menu/note.svg (508 -> 508 bajtów)
[UPDATED] admin/layout/icon/icon-menu/package(1).svg (629 -> 629 bajtów)
[UPDATED] admin/layout/icon/icon-menu/people-fill.svg (617 -> 617 bajtów)
[UPDATED] admin/layout/icon/icon-menu/photo-video.svg (939 -> 939 bajtów)
[UPDATED] admin/layout/icon/icon-menu/piggy-bank-coins.svg (1153 -> 1153 bajtów)
[UPDATED] admin/layout/icon/icon-menu/shopping-basket.svg (1131 -> 1131 bajtów)
[UPDATED] admin/layout/icon/icon-menu/shopping-cart.svg (1187 -> 1187 bajtów)
[UPDATED] admin/layout/icon/icon-menu/star-filled.svg (738 -> 738 bajtów)
[UPDATED] admin/layout/icon/icon-menu/template(1).svg (680 -> 680 bajtów)
[UPDATED] admin/layout/icon/icon-menu/template.svg (679 -> 679 bajtów)
[UPDATED] admin/layout/icon/icon-menu/view-cols.svg (593 -> 593 bajtów)
[UPDATED] admin/layout/icon/user-avatar-filled.svg (909 -> 909 bajtów)
[UPDATED] admin/layout/images/bg-unlogged.png (283831 -> 283831 bajtów)
[UPDATED] admin/layout/images/home.svg (450 -> 450 bajtów)
[UPDATED] admin/layout/images/no-image.png (526318 -> 526318 bajtów)
[UPDATED] admin/layout/lang-de.jpg (2915 -> 2915 bajtów)
[UPDATED] admin/layout/lang-en.jpg (8030 -> 8030 bajtów)
[UPDATED] admin/layout/lang-pl.jpg (1582 -> 1582 bajtów)
[UPDATED] admin/layout/lang-ru.jpg (2449 -> 2449 bajtów)
[UPDATED] admin/layout/lang-uk.jpg (2410 -> 2410 bajtów)
[UPDATED] admin/layout/style-css/style.css (40647 -> 40647 bajtów)
[UPDATED] admin/layout/style-css/style.css.map (100994 -> 100994 bajtów)
[UPDATED] admin/layout/style-scss/style.css (11426 -> 11426 bajtów)
[UPDATED] admin/layout/style-scss/style.css.map (7404 -> 7404 bajtów)
[UPDATED] admin/layout/style-scss/style.scss (39762 -> 39762 bajtów)
[UPDATED] admin/layout/style-scss/_mixins.css (0 -> 0 bajtów)
[UPDATED] admin/layout/style-scss/_mixins.scss (3852 -> 3852 bajtów)
[UPDATED] admin/layout/user-icon.png (22055 -> 22055 bajtów)
[OK] Rozpakowano 46 plików, błędów: 0, katalogów: 8
[OK] Usunięto plik update.zip
[OK] Zaktualizowano plik version.ini do wersji: 0.234
[SUCCESS] Aktualizacja do wersji 0.234 zakończona pomyślnie

View File

@@ -1 +1 @@
0.152
0.233