Refactor Scontainers management

- Removed legacy Scontainers controller and view files, transitioning to a new controller structure.
- Introduced ScontainersController to handle CRUD operations with improved dependency injection.
- Created ScontainersRepository for database interactions, encapsulating logic for container management.
- Updated container edit and list views to utilize new templating system.
- Added unit tests for ScontainersRepository and ScontainersController to ensure functionality.
- Enhanced form handling for container editing, including validation and error management.
This commit is contained in:
2026-02-12 23:54:56 +01:00
parent 6832009020
commit e984548516
15 changed files with 816 additions and 353 deletions

View File

@@ -0,0 +1,297 @@
<?php
namespace admin\Controllers;
use Domain\Languages\LanguagesRepository;
use Domain\Scontainers\ScontainersRepository;
use admin\ViewModels\Common\PaginatedTableViewModel;
use admin\ViewModels\Forms\FormAction;
use admin\ViewModels\Forms\FormEditViewModel;
use admin\ViewModels\Forms\FormField;
use admin\ViewModels\Forms\FormTab;
use admin\Support\Forms\FormRequestHandler;
class ScontainersController
{
private ScontainersRepository $repository;
private LanguagesRepository $languagesRepository;
private FormRequestHandler $formHandler;
public function __construct(ScontainersRepository $repository, LanguagesRepository $languagesRepository)
{
$this->repository = $repository;
$this->languagesRepository = $languagesRepository;
$this->formHandler = new FormRequestHandler();
}
public function list(): string
{
$sortableColumns = ['id', 'title', 'status'];
$filterDefinitions = [
[
'key' => 'title',
'label' => 'Tytul',
'type' => 'text',
],
[
'key' => 'status',
'label' => 'Aktywny',
'type' => 'select',
'options' => [
'' => '- aktywny -',
'1' => 'tak',
'0' => 'nie',
],
],
];
$listRequest = \admin\Support\TableListRequestFactory::fromRequest(
$filterDefinitions,
$sortableColumns,
'id'
);
$sortDir = $listRequest['sortDir'];
if (trim((string)\S::get('sort')) === '') {
$sortDir = 'DESC';
}
$result = $this->repository->listForAdmin(
$listRequest['filters'],
$listRequest['sortColumn'],
$sortDir,
$listRequest['page'],
$listRequest['perPage']
);
$rows = [];
$lp = ($listRequest['page'] - 1) * $listRequest['perPage'] + 1;
foreach ($result['items'] as $item) {
$id = (int)($item['id'] ?? 0);
$title = trim((string)($item['title'] ?? ''));
$rows[] = [
'lp' => $lp++ . '.',
'title' => '<a href="/admin/scontainers/container_edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>',
'code' => '[KONTENER:' . $id . ']',
'status' => ((int)($item['status'] ?? 0) === 1) ? 'tak' : '<span style="color: #FF0000;">nie</span>',
'_actions' => [
[
'label' => 'Edytuj',
'url' => '/admin/scontainers/container_edit/id=' . $id,
'class' => 'btn btn-xs btn-primary',
],
[
'label' => 'Usun',
'url' => '/admin/scontainers/container_delete/id=' . $id,
'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunac wybrany kontener?',
],
],
];
}
$total = (int)$result['total'];
$totalPages = max(1, (int)ceil($total / $listRequest['perPage']));
$viewModel = new PaginatedTableViewModel(
[
['key' => 'lp', 'label' => 'Lp.', 'class' => 'text-center', 'sortable' => false],
['key' => 'title', 'sort_key' => 'title', 'label' => 'Tytul', 'sortable' => true, 'raw' => true],
['key' => 'code', 'label' => 'Kod', 'sortable' => false],
['key' => 'status', 'sort_key' => 'status', 'label' => 'Aktywny', 'class' => 'text-center', 'sortable' => true, 'raw' => true],
],
$rows,
$listRequest['viewFilters'],
[
'column' => $listRequest['sortColumn'],
'dir' => $sortDir,
],
[
'page' => $listRequest['page'],
'per_page' => $listRequest['perPage'],
'total' => $total,
'total_pages' => $totalPages,
],
array_merge($listRequest['queryFilters'], [
'sort' => $listRequest['sortColumn'],
'dir' => $sortDir,
'per_page' => $listRequest['perPage'],
]),
$listRequest['perPageOptions'],
$sortableColumns,
'/admin/scontainers/view_list/',
'Brak danych w tabeli.',
'/admin/scontainers/container_edit/',
'Dodaj kontener'
);
return \Tpl::view('scontainers/containers-list', [
'viewModel' => $viewModel,
]);
}
public function view_list(): string
{
return $this->list();
}
public function edit(): string
{
$container = $this->repository->find((int)\S::get('id'));
$languages = $this->languagesRepository->languagesList();
$validationErrors = $_SESSION['form_errors'][$this->formId()] ?? null;
if ($validationErrors) {
unset($_SESSION['form_errors'][$this->formId()]);
}
return \Tpl::view('scontainers/container-edit', [
'form' => $this->buildFormViewModel($container, $languages, $validationErrors),
]);
}
public function container_edit(): string
{
return $this->edit();
}
public function save(): void
{
$legacyValues = \S::get('values');
if ($legacyValues) {
$values = json_decode((string)$legacyValues, true);
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania kontenera wystapil blad.'];
if (is_array($values)) {
$savedId = $this->repository->save($values);
if (!empty($savedId)) {
$response = ['status' => 'ok', 'msg' => 'Kontener zostal zapisany.', 'id' => $savedId];
}
}
echo json_encode($response);
exit;
}
$container = $this->repository->find((int)\S::get('id'));
$languages = $this->languagesRepository->languagesList();
$form = $this->buildFormViewModel($container, $languages);
$result = $this->formHandler->handleSubmit($form, $_POST);
if (!$result['success']) {
$_SESSION['form_errors'][$this->formId()] = $result['errors'];
echo json_encode(['success' => false, 'errors' => $result['errors']]);
exit;
}
$data = $result['data'];
$savedId = $this->repository->save([
'id' => (int)($data['id'] ?? 0),
'status' => $data['status'] ?? 0,
'show_title' => $data['show_title'] ?? 0,
'translations' => $data['translations'] ?? [],
]);
if ($savedId) {
echo json_encode([
'success' => true,
'id' => $savedId,
'message' => 'Kontener zostal zapisany.',
]);
exit;
}
echo json_encode([
'success' => false,
'errors' => ['general' => 'Podczas zapisywania kontenera wystapil blad.'],
]);
exit;
}
public function container_save(): void
{
$this->save();
}
public function delete(): void
{
if ($this->repository->delete((int)\S::get('id'))) {
\S::alert('Kontener zostal usuniety.');
}
header('Location: /admin/scontainers/view_list/');
exit;
}
public function container_delete(): void
{
$this->delete();
}
private function buildFormViewModel(array $container, array $languages, ?array $errors = null): FormEditViewModel
{
$id = (int)($container['id'] ?? 0);
$isNew = $id <= 0;
$data = [
'id' => $id,
'status' => (int)($container['status'] ?? 1),
'show_title' => (int)($container['show_title'] ?? 0),
'languages' => is_array($container['languages'] ?? null) ? $container['languages'] : [],
];
$fields = [
FormField::hidden('id', $id),
FormField::langSection('translations', 'content', [
FormField::text('title', [
'label' => 'Tytul',
]),
FormField::editor('text', [
'label' => 'Tresc',
'height' => 300,
]),
]),
FormField::switch('status', [
'label' => 'Aktywny',
'tab' => 'settings',
'value' => true,
]),
FormField::switch('show_title', [
'label' => 'Pokaz tytul',
'tab' => 'settings',
]),
];
$tabs = [
new FormTab('content', 'Tresc', 'fa-file'),
new FormTab('settings', 'Ustawienia', 'fa-wrench'),
];
$actionUrl = '/admin/scontainers/container_save/' . ($isNew ? '' : ('id=' . $id));
$actions = [
FormAction::save($actionUrl, '/admin/scontainers/view_list/'),
FormAction::cancel('/admin/scontainers/view_list/'),
];
return new FormEditViewModel(
$this->formId(),
'Edycja kontenera statycznego',
$data,
$fields,
$tabs,
$actions,
'POST',
$actionUrl,
'/admin/scontainers/view_list/',
true,
[],
$languages,
$errors
);
}
private function formId(): string
{
return 'scontainers-container-edit';
}
}

View File

@@ -66,11 +66,28 @@ class Pages
'parent_id' => \S::get( 'pid' ),
'menu_id' => \S::get( 'menu_id' ),
'menus' => \admin\factory\Pages::menu_lists(),
'layouts' => \admin\factory\Layouts::layouts_list(),
'layouts' => self::layouts_for_page_edit( $GLOBALS['mdb'] ),
'languages' => ( new \Domain\Languages\LanguagesRepository( $GLOBALS['mdb'] ) )->languagesList()
] );
}
private static function layouts_for_page_edit( $db )
{
if ( class_exists( '\Domain\Layouts\LayoutsRepository' ) )
{
$rows = ( new \Domain\Layouts\LayoutsRepository( $db ) ) -> listAll();
return is_array( $rows ) ? $rows : [];
}
if ( class_exists( '\admin\factory\Layouts' ) )
{
$rows = \admin\factory\Layouts::layouts_list();
return is_array( $rows ) ? $rows : [];
}
return [];
}
public static function menu_save()
{
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania menu wystąpił błąd. Proszę spróbować ponownie.' ];

View File

@@ -1,40 +0,0 @@
<?php
namespace admin\controls;
class Scontainers
{
public static function container_delete()
{
if ( \admin\factory\Scontainers::container_delete( \S::get( 'id' ) ) )
\S::alert( 'Kontener został usunięty.' );
header( 'Location: /admin/scontainers/view_list/' );
exit;
}
public static function container_save()
{
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania kontenera wystąpił błąd. Proszę spróbować ponownie.' ];
$values = json_decode( \S::get( 'values' ), true );
if ( $id = \admin\factory\Scontainers::container_save( $values['id'], $values['title'], $values['text'], $values['status'], $values['show_title'] ) )
$response = [ 'status' => 'ok', 'msg' => 'Kontener został zapisany.', 'id' => $id ];
echo json_encode( $response );
exit;
}
public static function container_edit()
{
return \admin\view\Scontainers::container_edit(
\admin\factory\Scontainers::container_details(
\S::get( 'id' )
),
( new \Domain\Languages\LanguagesRepository( $GLOBALS['mdb'] ) )->languagesList()
);
}
public static function view_list()
{
return \admin\view\Scontainers::containers_list();
}
}

View File

@@ -244,7 +244,7 @@ class ShopProduct
'product' => \admin\factory\ShopProduct::product_details( (int) \S::get( 'id' ) ),
'languages' => ( new \Domain\Languages\LanguagesRepository( $GLOBALS['mdb'] ) )->languagesList(),
'categories' => \admin\factory\ShopCategory::subcategories( null ),
'layouts' => \admin\factory\Layouts::layouts_list(),
'layouts' => self::layouts_for_product_edit( $mdb ),
'products' => \admin\factory\ShopProduct::products_list(),
'dlang' => \front\factory\Languages::default_language(),
'sets' => \shop\ProductSet::sets_list(),
@@ -254,6 +254,23 @@ class ShopProduct
] );
}
private static function layouts_for_product_edit( $db )
{
if ( class_exists( '\Domain\Layouts\LayoutsRepository' ) )
{
$rows = ( new \Domain\Layouts\LayoutsRepository( $db ) ) -> listAll();
return is_array( $rows ) ? $rows : [];
}
if ( class_exists( '\admin\factory\Layouts' ) )
{
$rows = \admin\factory\Layouts::layouts_list();
return is_array( $rows ) ? $rows : [];
}
return [];
}
// ajax_load_products ARCHIVE
static public function ajax_load_products_archive()
{

View File

@@ -3,86 +3,30 @@ namespace admin\factory;
class Scontainers
{
public static function container_delete( $container_id )
private static function repository(): \Domain\Scontainers\ScontainersRepository
{
global $mdb;
return $mdb -> delete( 'pp_scontainers', [ 'id' => (int)$container_id ] );
return new \Domain\Scontainers\ScontainersRepository($mdb);
}
public static function container_save( $container_id, $title, $text, $status, $show_title )
public static function container_delete($container_id)
{
global $mdb;
if ( !$container_id )
{
$mdb -> insert( 'pp_scontainers', [
'status' => $status == 'on' ? 1 : 0,
'show_title' => $show_title == 'on' ? 1 : 0
] );
$id = $mdb -> id();
if ( $id )
{
foreach ( $title as $key => $val )
{
$mdb -> insert( 'pp_scontainers_langs', [
'container_id' => (int)$id,
'lang_id' => $key,
'title' => $title[$key],
'text' => $text[$key]
] );
}
\S::delete_dir( '../temp/' );
return $id;
}
}
else
{
$mdb -> update( 'pp_scontainers', [
'status' => $status == 'on' ? 1 : 0,
'show_title' => $show_title == 'on' ? 1 : 0
], [
'id' => (int)$container_id
] );
foreach ( $title as $key => $val )
{
if ( $translation_id = $mdb -> get( 'pp_scontainers_langs', 'id', [ 'AND' => [ 'container_id' => $container_id, 'lang_id' => $key ] ] ) )
$mdb -> update( 'pp_scontainers_langs', [
'lang_id' => $key,
'title' => $title[$key],
'text' => $text[$key]
], [
'id' => $translation_id
] );
else
$mdb -> insert( 'pp_scontainers_langs', [
'container_id' => (int)$container_id,
'lang_id' => $key,
'title' => $title[$key],
'text' => $text[$key]
] );
}
\S::delete_dir( '../temp/' );
return $container_id;
}
return self::repository()->delete((int)$container_id);
}
public static function container_details( $container_id )
public static function container_save($container_id, $title, $text, $status, $show_title)
{
global $mdb;
$container = $mdb -> get( 'pp_scontainers', '*', [ 'id' => (int)$container_id ] );
$results = $mdb -> select( 'pp_scontainers_langs', '*', [ 'container_id' => (int)$container_id ] );
if ( is_array( $results ) ) foreach ( $results as $row )
$container['languages'][ $row['lang_id'] ] = $row;
return $container;
return self::repository()->save([
'id' => (int)$container_id,
'title' => is_array($title) ? $title : [],
'text' => is_array($text) ? $text : [],
'status' => $status,
'show_title' => $show_title,
]);
}
}
public static function container_details($container_id)
{
return self::repository()->find((int)$container_id);
}
}

View File

@@ -1,20 +0,0 @@
<?php
namespace admin\view;
class Scontainers
{
public static function container_edit( $container, $languages )
{
$tpl = new \Tpl;
$tpl -> container = $container;
$tpl -> languages = $languages;
return $tpl -> render( 'scontainers/container-edit' );
}
public static function containers_list()
{
$tpl = new \Tpl;
return $tpl -> render( 'scontainers/containers-list' );
}
}