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:
494
autoload/admin/Support/Forms/FormFieldRenderer.php
Normal file
494
autoload/admin/Support/Forms/FormFieldRenderer.php
Normal file
@@ -0,0 +1,494 @@
|
||||
<?php
|
||||
namespace admin\Support\Forms;
|
||||
|
||||
use admin\ViewModels\Forms\FormEditViewModel;
|
||||
use admin\ViewModels\Forms\FormField;
|
||||
use admin\ViewModels\Forms\FormFieldType;
|
||||
|
||||
/**
|
||||
* Renderer pól formularza
|
||||
*/
|
||||
class FormFieldRenderer
|
||||
{
|
||||
private FormEditViewModel $form;
|
||||
|
||||
public function __construct(FormEditViewModel $form)
|
||||
{
|
||||
$this->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pojedyncze pole
|
||||
*/
|
||||
public function renderField(FormField $field): string
|
||||
{
|
||||
$method = 'render' . ucfirst($field->type);
|
||||
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->$method($field);
|
||||
}
|
||||
|
||||
// Fallback dla nieznanych typów - renderuj jako text
|
||||
return $this->renderText($field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole tekstowe
|
||||
*/
|
||||
public function renderText(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
$error = $this->form->getError($field->name);
|
||||
|
||||
$params = [
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'text',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
];
|
||||
|
||||
if ($field->placeholder) {
|
||||
$params['placeholder'] = $field->placeholder;
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
$params['class'] .= ' error';
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole number
|
||||
*/
|
||||
public function renderNumber(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
$error = $this->form->getError($field->name);
|
||||
|
||||
$params = [
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'number',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
];
|
||||
|
||||
if ($error) {
|
||||
$params['class'] .= ' error';
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole email
|
||||
*/
|
||||
public function renderEmail(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
$error = $this->form->getError($field->name);
|
||||
|
||||
$params = [
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'email',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
];
|
||||
|
||||
if ($error) {
|
||||
$params['class'] .= ' error';
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole password
|
||||
*/
|
||||
public function renderPassword(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
return \Shared\Html\Html::input([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'password',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole daty
|
||||
*/
|
||||
public function renderDate(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
$error = $this->form->getError($field->name);
|
||||
|
||||
$params = [
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'text',
|
||||
'class' => 'date ' . ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
];
|
||||
|
||||
if ($error) {
|
||||
$params['class'] .= ' error';
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::input($params), $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole daty i czasu
|
||||
*/
|
||||
public function renderDatetime(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
return \Shared\Html\Html::input([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'text',
|
||||
'class' => 'datetime ' . ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje przełącznik (switch)
|
||||
*/
|
||||
public function renderSwitch(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
// Domyślna wartość dla nowego rekordu
|
||||
if ($value === null && $field->value === true) {
|
||||
$checked = true;
|
||||
} else {
|
||||
$checked = (bool) $value;
|
||||
}
|
||||
|
||||
return \Shared\Html\Html::input_switch([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'checked' => $checked,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje select
|
||||
*/
|
||||
public function renderSelect(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
$error = $this->form->getError($field->name);
|
||||
|
||||
$params = [
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'values' => $field->options,
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
];
|
||||
|
||||
if ($error) {
|
||||
$params['class'] .= ' error';
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::select($params), $error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje textarea
|
||||
*/
|
||||
public function renderTextarea(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
return \Shared\Html\Html::textarea([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'rows' => $field->attributes['rows'] ?? 4,
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje edytor (CKEditor)
|
||||
*/
|
||||
public function renderEditor(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
return \Shared\Html\Html::textarea([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'rows' => max(10, ($field->attributes['rows'] ?? 10)),
|
||||
'class' => 'editor ' . ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole obrazu z filemanagerem
|
||||
*/
|
||||
public function renderImage(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
$filemanagerUrl = $field->filemanagerUrl ?? $this->generateFilemanagerUrl($field->id);
|
||||
|
||||
return \Shared\Html\Html::input_icon([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'text',
|
||||
'icon_content' => 'przeglądaj',
|
||||
'icon_js' => "window.open('{$filemanagerUrl}', 'filemanager', 'location=1,status=1,scrollbars=1,width=1100,height=700')",
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole pliku
|
||||
*/
|
||||
public function renderFile(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
if ($field->useFilemanager) {
|
||||
$filemanagerUrl = $field->filemanagerUrl ?? $this->generateFilemanagerUrl($field->id);
|
||||
|
||||
return \Shared\Html\Html::input_icon([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'text',
|
||||
'icon_content' => 'przeglądaj',
|
||||
'icon_js' => "window.open('{$filemanagerUrl}', 'filemanager', 'location=1,status=1,scrollbars=1,width=1100,height=700')",
|
||||
]);
|
||||
}
|
||||
|
||||
return \Shared\Html\Html::input([
|
||||
'label' => $field->label,
|
||||
'name' => $field->name,
|
||||
'id' => $field->id,
|
||||
'type' => 'file',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje ukryte pole
|
||||
*/
|
||||
public function renderHidden(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
|
||||
return '<input type="hidden" name="' . htmlspecialchars($field->name) . '" ' .
|
||||
'id="' . htmlspecialchars($field->id) . '" ' .
|
||||
'value="' . htmlspecialchars($value ?? '') . '">';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole koloru (color picker + text input)
|
||||
*/
|
||||
public function renderColor(FormField $field): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field);
|
||||
$error = $this->form->getError($field->name);
|
||||
$colorValue = htmlspecialchars($value ?? '#000000', ENT_QUOTES, 'UTF-8');
|
||||
$fieldName = htmlspecialchars($field->name, ENT_QUOTES, 'UTF-8');
|
||||
$fieldId = htmlspecialchars($field->id, ENT_QUOTES, 'UTF-8');
|
||||
$label = htmlspecialchars($field->label, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
$html = '<div class="form-group row">';
|
||||
$html .= '<label class="col-lg-4 control-label">' . $label . ':</label>';
|
||||
$html .= '<div class="col-lg-8">';
|
||||
$html .= '<div style="display:flex;align-items:center;gap:8px;">';
|
||||
$html .= '<input type="color" id="' . $fieldId . '_picker" value="' . $colorValue . '" style="width:40px;height:34px;padding:2px;border:1px solid #ccc;cursor:pointer;" />';
|
||||
$html .= '<input type="text" name="' . $fieldName . '" id="' . $fieldId . '" value="' . $colorValue . '" class="form-control" style="max-width:150px;" />';
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
$html .= '</div>';
|
||||
$html .= '<script>$(function(){'
|
||||
. 'var $p=$("#' . $fieldId . '_picker"),$t=$("#' . $fieldId . '");'
|
||||
. '$p.on("input",function(){$t.val(this.value);});'
|
||||
. '$t.on("input",function(){var v=this.value;if(/^#[0-9a-fA-F]{6}$/.test(v))$p.val(v);});'
|
||||
. '});</script>';
|
||||
|
||||
return $this->wrapWithError($html, $error);
|
||||
}
|
||||
|
||||
public function renderCustom(FormField $field): string
|
||||
{
|
||||
return (string)($field->customHtml ?? '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje sekcję językową
|
||||
*/
|
||||
public function renderLangSection(FormField $section): string
|
||||
{
|
||||
if ($section->langFields === null || $this->form->languages === null) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$out = '<div id="languages-' . $section->name . '" class="languages-tabs">';
|
||||
|
||||
// Zakładki języków
|
||||
$out .= '<ul class="resp-tabs-list languages-tabs htabs">';
|
||||
foreach ($this->form->languages as $lang) {
|
||||
if ($lang['status']) {
|
||||
$out .= '<li>' . htmlspecialchars($lang['name']) . '</li>';
|
||||
}
|
||||
}
|
||||
$out .= '</ul>';
|
||||
|
||||
// Kontenery języków
|
||||
$out .= '<div class="resp-tabs-container languages-tabs">';
|
||||
foreach ($this->form->languages as $lang) {
|
||||
if ($lang['status']) {
|
||||
$out .= '<div>';
|
||||
foreach ($section->langFields as $field) {
|
||||
$out .= $this->renderLangField($field, $lang['id'], $section->name);
|
||||
}
|
||||
$out .= '</div>';
|
||||
}
|
||||
}
|
||||
$out .= '</div>';
|
||||
|
||||
$out .= '</div>';
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renderuje pole w sekcji językowej
|
||||
*/
|
||||
private function renderLangField(FormField $field, $languageId, string $sectionName): string
|
||||
{
|
||||
$value = $this->form->getFieldValue($field, $languageId, $field->name);
|
||||
$error = $this->form->getError($sectionName . '_' . $field->name, $languageId);
|
||||
|
||||
$name = $field->getLocalizedName($languageId);
|
||||
$id = $field->getLocalizedId($languageId);
|
||||
|
||||
switch ($field->type) {
|
||||
case FormFieldType::IMAGE:
|
||||
$filemanagerUrl = $field->filemanagerUrl ?? $this->generateFilemanagerUrl($id);
|
||||
return $this->wrapWithError(\Shared\Html\Html::input_icon([
|
||||
'label' => $field->label,
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'value' => $value ?? '',
|
||||
'type' => 'text',
|
||||
'icon_content' => 'przeglądaj',
|
||||
'icon_js' => "window.open('{$filemanagerUrl}', 'filemanager', 'location=1,status=1,scrollbars=1,width=1100,height=700')",
|
||||
]), $error);
|
||||
|
||||
case FormFieldType::TEXTAREA:
|
||||
case FormFieldType::EDITOR:
|
||||
return $this->wrapWithError(\Shared\Html\Html::textarea([
|
||||
'label' => $field->label,
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'value' => $value ?? '',
|
||||
'rows' => $field->type === FormFieldType::EDITOR ? 10 : ($field->attributes['rows'] ?? 4),
|
||||
'class' => $field->type === FormFieldType::EDITOR ? 'editor' : '',
|
||||
]), $error);
|
||||
|
||||
case FormFieldType::SWITCH:
|
||||
return \Shared\Html\Html::input_switch([
|
||||
'label' => $field->label,
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'checked' => (bool) $value,
|
||||
]);
|
||||
|
||||
case FormFieldType::SELECT:
|
||||
return $this->wrapWithError(\Shared\Html\Html::select([
|
||||
'label' => $field->label,
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'value' => $value ?? '',
|
||||
'values' => $field->options,
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]), $error);
|
||||
|
||||
default: // TEXT, URL, etc.
|
||||
if (!empty($field->attributes['icon_content'])) {
|
||||
$iconJs = (string)($field->attributes['icon_js'] ?? '');
|
||||
if ($iconJs !== '') {
|
||||
$iconJs = str_replace('{lang}', (string)$languageId, $iconJs);
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::input_icon([
|
||||
'label' => $field->label,
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'value' => $value ?? '',
|
||||
'type' => $field->type === FormFieldType::EMAIL ? 'email' : 'text',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
'icon_content' => (string)$field->attributes['icon_content'],
|
||||
'icon_class' => (string)($field->attributes['icon_class'] ?? ''),
|
||||
'icon_js' => $iconJs,
|
||||
]), $error);
|
||||
}
|
||||
|
||||
return $this->wrapWithError(\Shared\Html\Html::input([
|
||||
'label' => $field->label,
|
||||
'name' => $name,
|
||||
'id' => $id,
|
||||
'value' => $value ?? '',
|
||||
'type' => $field->type === FormFieldType::EMAIL ? 'email' : 'text',
|
||||
'class' => ($field->required ? 'require ' : '') . ($field->attributes['class'] ?? ''),
|
||||
]), $error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generuje URL do filemanagera
|
||||
*/
|
||||
private function generateFilemanagerUrl(string $fieldId): string
|
||||
{
|
||||
$rfmAkey = $_SESSION['rfm_akey'] ?? bin2hex(random_bytes(16));
|
||||
$_SESSION['rfm_akey'] = $rfmAkey;
|
||||
$_SESSION['rfm_akey_expires'] = time() + 20 * 60;
|
||||
$_SESSION['can_use_rfm'] = true;
|
||||
|
||||
$fieldIdParam = rawurlencode($fieldId);
|
||||
$akeyParam = rawurlencode($rfmAkey);
|
||||
return "/libraries/filemanager-9.14.2/dialog.php?type=1&popup=1&field_id={$fieldIdParam}&akey={$akeyParam}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Opakowuje pole w kontener błędu
|
||||
*/
|
||||
private function wrapWithError(string $html, ?string $error): string
|
||||
{
|
||||
if ($error) {
|
||||
return '<div class="field-with-error">' . $html .
|
||||
'<span class="error-message">' . htmlspecialchars($error) . '</span></div>';
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
152
autoload/admin/Support/Forms/FormRequestHandler.php
Normal file
152
autoload/admin/Support/Forms/FormRequestHandler.php
Normal file
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
namespace admin\Support\Forms;
|
||||
|
||||
use admin\ViewModels\Forms\FormEditViewModel;
|
||||
use admin\ViewModels\Forms\FormFieldType;
|
||||
use admin\Validation\FormValidator;
|
||||
|
||||
/**
|
||||
* Obsługa żądań formularza (POST, persist, walidacja)
|
||||
*/
|
||||
class FormRequestHandler
|
||||
{
|
||||
private FormValidator $validator;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->validator = new FormValidator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Przetwarza żądanie POST formularza
|
||||
*
|
||||
* @param FormEditViewModel $formViewModel
|
||||
* @param array $postData Dane z $_POST
|
||||
* @return array Wynik przetwarzania ['success' => bool, 'errors' => array, 'data' => array]
|
||||
*/
|
||||
public function handleSubmit(FormEditViewModel $formViewModel, array $postData): array
|
||||
{
|
||||
$result = [
|
||||
'success' => false,
|
||||
'errors' => [],
|
||||
'data' => []
|
||||
];
|
||||
|
||||
// Walidacja
|
||||
$errors = $this->validator->validate($postData, $formViewModel->fields, $formViewModel->languages);
|
||||
|
||||
if (!empty($errors)) {
|
||||
$result['errors'] = $errors;
|
||||
// Zapisz dane do persist przy błędzie walidacji
|
||||
if ($formViewModel->persist) {
|
||||
$formViewModel->saveToPersist($postData);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Przetwórz dane (np. konwersja typów)
|
||||
$processedData = $this->processData($postData, $formViewModel->fields);
|
||||
|
||||
$result['success'] = true;
|
||||
$result['data'] = $processedData;
|
||||
|
||||
// Wyczyść persist po sukcesie
|
||||
if ($formViewModel->persist) {
|
||||
$formViewModel->clearPersist();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Przetwarza dane z formularza (konwersja typów)
|
||||
*/
|
||||
private function processData(array $postData, array $fields): array
|
||||
{
|
||||
$processed = [];
|
||||
|
||||
foreach ($fields as $field) {
|
||||
$value = $postData[$field->name] ?? null;
|
||||
|
||||
// Konwersja typów
|
||||
switch ($field->type) {
|
||||
case FormFieldType::SWITCH:
|
||||
$processed[$field->name] = $value ? 1 : 0;
|
||||
break;
|
||||
|
||||
case FormFieldType::NUMBER:
|
||||
$processed[$field->name] = $value !== null && $value !== '' ? (float)$value : null;
|
||||
break;
|
||||
|
||||
case FormFieldType::LANG_SECTION:
|
||||
if ($field->langFields !== null) {
|
||||
$processed[$field->name] = $this->processLangSection($postData, $field);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$processed[$field->name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Przetwarza sekcję językową
|
||||
*/
|
||||
private function processLangSection(array $postData, $section): array
|
||||
{
|
||||
$result = [];
|
||||
|
||||
if ($section->langFields === null) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($section->langFields as $field) {
|
||||
$fieldName = $field->name;
|
||||
$langData = $postData[$fieldName] ?? [];
|
||||
|
||||
foreach ($langData as $langId => $value) {
|
||||
if (!isset($result[$langId])) {
|
||||
$result[$langId] = [];
|
||||
}
|
||||
|
||||
// Konwersja typów dla pól językowych
|
||||
switch ($field->type) {
|
||||
case FormFieldType::SWITCH:
|
||||
$result[$langId][$fieldName] = $value ? 1 : 0;
|
||||
break;
|
||||
case FormFieldType::NUMBER:
|
||||
$result[$langId][$fieldName] = $value !== null && $value !== '' ? (float)$value : null;
|
||||
break;
|
||||
default:
|
||||
$result[$langId][$fieldName] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Przywraca dane z persist do POST (przy błędzie walidacji)
|
||||
*/
|
||||
public function restoreFromPersist(FormEditViewModel $formViewModel): ?array
|
||||
{
|
||||
if (!$formViewModel->persist) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $_SESSION['form_persist'][$formViewModel->formId] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sprawdza czy żądanie jest submitowaniem formularza
|
||||
*/
|
||||
public function isFormSubmit(string $formId): bool
|
||||
{
|
||||
return $_SERVER['REQUEST_METHOD'] === 'POST' &&
|
||||
(isset($_POST['_form_id']) && $_POST['_form_id'] === $formId);
|
||||
}
|
||||
}
|
||||
100
autoload/admin/Support/class.TableListRequestFactory.php
Normal file
100
autoload/admin/Support/class.TableListRequestFactory.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
namespace admin\Support;
|
||||
|
||||
class TableListRequestFactory
|
||||
{
|
||||
public const DEFAULT_PER_PAGE_OPTIONS = [5, 10, 15, 25, 50, 100];
|
||||
public const DEFAULT_PER_PAGE = 15;
|
||||
|
||||
/**
|
||||
* Buduje kontekst listy (filtry, sortowanie, paginacja) z requestu.
|
||||
*
|
||||
* @return array{
|
||||
* page:int,
|
||||
* perPage:int,
|
||||
* perPageOptions:array<int,int>,
|
||||
* filters:array<string,string>,
|
||||
* viewFilters:array<int,array<string,mixed>>,
|
||||
* queryFilters:array<string,string>,
|
||||
* sortColumn:string,
|
||||
* sortDir:string
|
||||
* }
|
||||
*/
|
||||
public static function fromRequest(
|
||||
array $filterDefinitions,
|
||||
array $sortableColumns,
|
||||
string $defaultSortColumn = 'date_add',
|
||||
?array $perPageOptions = null,
|
||||
?int $defaultPerPage = null
|
||||
): array {
|
||||
if ($perPageOptions === null) {
|
||||
$perPageOptions = self::DEFAULT_PER_PAGE_OPTIONS;
|
||||
}
|
||||
|
||||
if ($defaultPerPage === null) {
|
||||
$defaultPerPage = self::DEFAULT_PER_PAGE;
|
||||
}
|
||||
|
||||
if (!in_array($defaultPerPage, $perPageOptions, true)) {
|
||||
$defaultPerPage = (int)$perPageOptions[0];
|
||||
}
|
||||
|
||||
$page = max(1, (int)\Shared\Helpers\Helpers::get('page'));
|
||||
$perPage = (int)\Shared\Helpers\Helpers::get('per_page');
|
||||
if (!in_array($perPage, $perPageOptions, true)) {
|
||||
$perPage = $defaultPerPage;
|
||||
}
|
||||
|
||||
$filters = [];
|
||||
$viewFilters = [];
|
||||
$queryFilters = [];
|
||||
|
||||
foreach ($filterDefinitions as $definition) {
|
||||
$key = (string)($definition['key'] ?? '');
|
||||
if ($key === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type = (string)($definition['type'] ?? 'text');
|
||||
$value = (string)\Shared\Helpers\Helpers::get($key);
|
||||
|
||||
$filters[$key] = $value;
|
||||
$queryFilters[$key] = $value;
|
||||
|
||||
$filterConfig = [
|
||||
'key' => $key,
|
||||
'label' => (string)($definition['label'] ?? $key),
|
||||
'type' => $type,
|
||||
'value' => $value,
|
||||
];
|
||||
|
||||
if ($type === 'select' && isset($definition['options']) && is_array($definition['options'])) {
|
||||
$filterConfig['options'] = $definition['options'];
|
||||
}
|
||||
|
||||
$viewFilters[] = $filterConfig;
|
||||
}
|
||||
|
||||
$sortColumn = trim((string)\Shared\Helpers\Helpers::get('sort'));
|
||||
if (!in_array($sortColumn, $sortableColumns, true)) {
|
||||
$sortColumn = $defaultSortColumn;
|
||||
}
|
||||
|
||||
$sortDir = strtoupper(trim((string)\Shared\Helpers\Helpers::get('dir')));
|
||||
if (!in_array($sortDir, ['ASC', 'DESC'], true)) {
|
||||
$sortDir = 'DESC';
|
||||
}
|
||||
|
||||
return [
|
||||
'page' => $page,
|
||||
'perPage' => $perPage,
|
||||
'perPageOptions' => $perPageOptions,
|
||||
'filters' => $filters,
|
||||
'viewFilters' => $viewFilters,
|
||||
'queryFilters' => $queryFilters,
|
||||
'sortColumn' => $sortColumn,
|
||||
'sortDir' => $sortDir,
|
||||
];
|
||||
}
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user