Add view classes for articles, banners, languages, menu, newsletter, containers, shop categories, clients, payment methods, products, and search

- Created Articles.php for rendering article views including full articles, miniature lists, and news sections.
- Added Banners.php for handling banner displays.
- Introduced Languages.php for rendering language options.
- Implemented Menu.php for dynamic menu rendering.
- Developed Newsletter.php for newsletter view rendering.
- Created Scontainers.php for rendering specific containers.
- Added ShopCategory.php for category descriptions and product listings.
- Introduced ShopClient.php for managing client-related views such as address editing and order history.
- Implemented ShopPaymentMethod.php for displaying payment methods in the basket.
- Created ShopProduct.php for generating product URLs.
- Added ShopSearch.php for rendering a simple search form.
- Added .htaccess file to enhance security by restricting access to sensitive files and directories.
This commit is contained in:
2026-02-21 23:00:15 +01:00
parent b51244c1d6
commit 3ecbe628dc
435 changed files with 44107 additions and 31270 deletions

View File

@@ -0,0 +1,278 @@
<?php
/**
* Uniwersalny szablon formularza edycji
*
* @var FormEditViewModel $form
*/
use admin\Support\Forms\FormFieldRenderer;
use admin\ViewModels\Forms\FormFieldType;
$form = $this->form;
$renderer = new FormFieldRenderer($form);
// Przygotuj filemanager key
\Shared\Helpers\Helpers::set_session('admin', true);
if (
empty($_SESSION['rfm_akey']) ||
(($_SESSION['rfm_akey_expires'] ?? 0) < time())
) {
$_SESSION['rfm_akey'] = bin2hex(random_bytes(16));
}
$_SESSION['rfm_akey_expires'] = time() + 20 * 60;
$_SESSION['can_use_rfm'] = true;
?>
<script type="text/javascript" src="/libraries/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="/libraries/ckeditor/adapters/jquery.js"></script>
<!-- iCheck -->
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/icheck/skins/minimal/minimal.css" />
<link rel="stylesheet" type="text/css" href="/libraries/grid/plugins/icheck/skins/minimal/blue.css" />
<script type="text/javascript" src="/libraries/grid/plugins/icheck/icheck.min.js"></script>
<style>
.icheckbox_minimal-blue { margin-top: 10px; }
</style>
<div class="row">
<div class="col col-xs-12">
<div class="g-container" data="table:<?= $form->formId ?>">
<div class="panel panel-info panel-border top">
<div class="panel-heading">
<span class="panel-title"><?= htmlspecialchars($form->title) ?></span>
</div>
<div class="panel-heading p10 pl15" id="g-menu" style="height: auto;">
<?php foreach ($form->actions as $action): ?>
<?php if ($action->name === 'save'): ?>
<?php if ($form->persist): ?>
<a href="#" id="g-edit-save-close" class="btn btn-system btn-sm"
persist_edit="0"
back_url="<?= htmlspecialchars($action->backUrl ?? '') ?>"
url="<?= htmlspecialchars($action->url) ?>">
<i class="fa fa-check-circle mr5"></i>Zatwierdź i zamknij
</a>
<?php endif; ?>
<a href="#" id="g-edit-save" class="btn btn-success btn-sm"
persist_edit="<?= $form->persist ? '1' : '0' ?>"
back_url="<?= htmlspecialchars($action->backUrl ?? '') ?>"
url="<?= htmlspecialchars($action->url) ?>">
<i class="fa fa-check-circle mr5"></i>Zatwierdź
</a>
<?php elseif ($action->name === 'cancel'): ?>
<a href="<?= htmlspecialchars($action->url) ?>" class="btn btn-dark btn-sm" id="g-edit-cancel">
<i class="fa fa-reply mr5"></i>Wstecz
</a>
<?php else: ?>
<a href="<?= htmlspecialchars($action->url) ?>" class="btn <?= htmlspecialchars($action->cssClass) ?> btn-sm">
<?= htmlspecialchars($action->label) ?>
</a>
<?php endif; ?>
<?php endforeach; ?>
</div>
<div class="panel-body">
<form method="<?= $form->method ?>" id="fg-<?= $form->formId ?>" class="g-form form-horizontal"
action="<?= htmlspecialchars($form->action) ?>" enctype="multipart/form-data">
<input type="hidden" name="_form_id" value="<?= htmlspecialchars($form->formId) ?>">
<?php foreach ($form->hiddenFields as $name => $value): ?>
<input type="hidden" name="<?= htmlspecialchars($name) ?>" value="<?= htmlspecialchars($value ?? '') ?>">
<?php endforeach; ?>
<?php if ($form->hasTabs()): ?>
<!-- Formularz z zakładkami -->
<div id="form-tabs-<?= $form->formId ?>">
<ul class="resp-tabs-list form-tabs">
<?php foreach ($form->tabs as $tab): ?>
<li><i class="fa <?= htmlspecialchars($tab->icon) ?>"></i><?= htmlspecialchars($tab->label) ?></li>
<?php endforeach; ?>
</ul>
<div class="resp-tabs-container form-tabs">
<?php foreach ($form->tabs as $tab): ?>
<div>
<?php
$tabFields = $form->getFieldsForTab($tab->id);
$langSections = $form->getLangSectionsForTab($tab->id);
?>
<?php foreach ($tabFields as $field): ?>
<?= $renderer->renderField($field) ?>
<?php endforeach; ?>
<?php foreach ($langSections as $section): ?>
<?= $renderer->renderLangSection($section) ?>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php else: ?>
<!-- Formularz bez zakładek -->
<?php foreach ($form->fields as $field): ?>
<?php if ($field->type === FormFieldType::LANG_SECTION): ?>
<?= $renderer->renderLangSection($field) ?>
<?php else: ?>
<?= $renderer->renderField($field) ?>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</form>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function() {
// Inicjalizacja datepickerów
$('input.date').datetimepicker({
format: "YYYY-MM-DD",
pickTime: false
});
$('input.datetime').datetimepicker({
format: "YYYY-MM-DD HH:mm"
});
// Inicjalizacja zakładek
<?php if ($form->hasTabs()): ?>
$('#form-tabs-<?= $form->formId ?>').easyResponsiveTabs({
width: 'auto',
fit: true,
tabidentify: 'form-tabs',
type: 'vertical'
});
<?php endif; ?>
// Inicjalizacja iCheck
$('.icheck').iCheck({
checkboxClass: 'icheckbox_minimal-blue',
radioClass: 'iradio_minimal-blue'
});
function showFormMessage(type, text) {
var safeText = $('<div/>').text(text || '').html();
var alertClass = type === 'error' ? 'alert-danger' : 'alert-primary';
var html = '' +
'<div class="row js-form-message">' +
'<div class="col col-xs-12">' +
'<div class="alert ' + alertClass + ' alert-dismissable">' +
'<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>' +
'<i class="fa fa-info pr10"></i>' + safeText +
'</div>' +
'</div>' +
'</div>';
$('#content .js-form-message').remove();
$('#content').prepend(html);
}
// Obsługa przycisków zapisu
$('#g-edit-save, #g-edit-save-close').on('click', function(e) {
e.preventDefault();
var $btn = $(this);
var url = $btn.attr('url');
var backUrl = $btn.attr('back_url');
var persist = $btn.attr('persist_edit');
var formId = 'fg-<?= $form->formId ?>';
// Synchronizuj zawartosc CKEditor do textarea przed serializacja
if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances) {
for (var instanceName in CKEDITOR.instances) {
if (Object.prototype.hasOwnProperty.call(CKEDITOR.instances, instanceName)) {
CKEDITOR.instances[instanceName].updateElement();
}
}
}
// Zbierz dane formularza
var formData = $('#' + formId).serialize();
$.ajax({
url: url,
type: 'POST',
data: formData,
dataType: 'json',
success: function(response) {
if (response.success) {
var successMessage = response.message || 'Zmiany zostały zapisane.';
if (backUrl && persist === '0') {
window.location.href = backUrl;
} else {
showFormMessage('success', successMessage);
}
} else {
var errors = response.errors ? Object.values(response.errors).join(', ') : 'Błąd walidacji';
showFormMessage('error', 'Błąd: ' + errors);
}
},
error: function(xhr, status, error) {
// Fallback - tradycyjne submit formularza
$('#' + formId).attr('action', url).submit();
}
});
});
disable_menu();
});
</script>
<?php
// Renderowanie CKEditor dla pól edytora (zwykłych)
foreach ($form->fields as $field):
if ($field->type === FormFieldType::EDITOR):
?>
<script type="text/javascript">
$(function() {
$('#<?= $field->id ?>').ckeditor({
toolbar: '<?= $field->editorToolbar ?>',
height: '<?= $field->editorHeight ?>'
});
});
</script>
<?php
endif;
endforeach;
?>
<?php if ($form->hasLangSections()): ?>
<script type="text/javascript">
$(function() {
// Inicjalizacja zakładek językowych
$('[id^="languages-"].languages-tabs').each(function() {
$(this).easyResponsiveTabs({
width: 'auto',
fit: true,
tabidentify: 'languages-tabs',
type: 'horizontal'
});
});
// Inicjalizacja CKEditor dla pól w sekcjach językowych
<?php
foreach ($form->fields as $section):
if ($section->type === FormFieldType::LANG_SECTION && $section->langFields):
foreach ($section->langFields as $langField):
if ($langField->type === FormFieldType::EDITOR && $form->languages):
foreach ($form->languages as $lang):
if ($lang['status']):
?>
$('#<?= $langField->getLocalizedId($lang['id']) ?>').ckeditor({
toolbar: '<?= $langField->editorToolbar ?>',
height: '<?= $langField->editorHeight ?>'
});
<?php
endif;
endforeach;
endif;
endforeach;
endif;
endforeach;
?>
});
</script>
<?php endif; ?>
<script>CKEDITOR.dtd.$removeEmpty['span'] = false;</script>