ver 0.262 - pages module refactor and admin UX fixes

This commit is contained in:
2026-02-13 21:17:21 +01:00
parent 26ebf59849
commit 67705f1f56
44 changed files with 2235 additions and 1803 deletions

View File

@@ -471,3 +471,11 @@ Aktualnie w suite są też testy modułów `Dictionaries`, `Articles` i `Users`
- **UPDATE:** potwierdzenia usuwania zdjec i zalacznikow w edycji artykulu ujednolicone wizualnie z dialogiem usuwania z listy (jquery-confirm, `table-list-confirm-dialog`). - **UPDATE:** potwierdzenia usuwania zdjec i zalacznikow w edycji artykulu ujednolicone wizualnie z dialogiem usuwania z listy (jquery-confirm, `table-list-confirm-dialog`).
- **FIX:** dodane ladowanie biblioteki `jquery-impromptu` w widoku edycji artykulu (kompatybilnosc dla `$.prompt`). - **FIX:** dodane ladowanie biblioteki `jquery-impromptu` w widoku edycji artykulu (kompatybilnosc dla `$.prompt`).
- Testy: 178 tests, 443 assertions. - Testy: 178 tests, 443 assertions.
## Aktualizacja 2026-02-13 (Pages)
- NOWE: `Domain\\Pages\\PagesRepository` (menu/page CRUD, drzewo stron, sortowanie, SEO, endpointy pomocnicze).
- NOWE: `admin\\Controllers\\PagesController` (DI) dla modulu `/admin/pages/*`.
- UPDATE: widoki `admin/templates/pages/*` dzialaja bez `admin\\factory\\Pages` i `admin\\view\\Pages`.
- UPDATE: routing DI (`admin\\Site`) ma fabryke kontrolera `Pages`.
- UPDATE: zalezne endpointy `cookie_*` i `generate_seo_link` przepiete na `/admin/pages/*`.
- CLEANUP: usuniete legacy pliki `autoload/admin/controls/class.Pages.php`, `autoload/admin/view/class.Pages.php`, `autoload/admin/factory/class.Pages.php`, `admin/ajax/pages.php`.

View File

@@ -682,3 +682,21 @@ Gdy `persist = true`:
- UPDATE: potwierdzenia usuwania zdjec i zalacznikow przepiete na `jquery-confirm` ze stylem `table-list-confirm-dialog` (jak na liscie artykulow). - UPDATE: potwierdzenia usuwania zdjec i zalacznikow przepiete na `jquery-confirm` ze stylem `table-list-confirm-dialog` (jak na liscie artykulow).
- FIX: dolaczona biblioteka `jquery-impromptu` w widoku edycji artykulu dla kompatybilnosci. - FIX: dolaczona biblioteka `jquery-impromptu` w widoku edycji artykulu dla kompatybilnosci.
- Testy po zmianie: **178 tests, 443 assertions**. - Testy po zmianie: **178 tests, 443 assertions**.
## Plan 2026-02-13 - Refaktoryzacja `/admin/pages/`
- [x] Dodac `Domain\Pages\PagesRepository` (CRUD menu/stron, drzewo stron, sortowanie, SEO, operacje AJAX).
- [x] Dodac `admin\Controllers\PagesController` (DI) i przepiac routing `/admin/pages/*` na nowy kontroler.
- [x] Przebudowac widoki `admin/templates/pages/*` tak, aby nie korzystaly z `admin\factory\Pages` i `admin\view\Pages`.
- [x] Przepiac endpointy AJAX z `/admin/ajax.php?a=*` na `/admin/pages/*` (`save_pages_order`, `save_articles_order`, `generate_seo_link`, `cookie_*`).
- [x] Przeszukac i zaktualizowac zaleznosci w innych modulach (`articles`, `layouts`, helpery) powiazane z Pages.
- [x] Usunac legacy klasy/pliki Pages (`autoload/admin/controls/class.Pages.php`, `autoload/admin/view/class.Pages.php`, `autoload/admin/factory/class.Pages.php`, `admin/ajax/pages.php`) po odpieciu zaleznosci.
- [x] Dodac/uzupelnic testy (`PagesRepository`, `PagesController`) i uruchomic testy.
## Aktualizacja 2026-02-13 - Pages (/admin/pages)
- NOWE: `Domain\Pages\PagesRepository` (CRUD menu/stron, drzewo stron, porzadkowanie, SEO link, URL preview, cookies tree-state).
- NOWE: `admin\Controllers\PagesController` (DI) dla akcji: `view_list/list`, `browse_list`, `pages_url_browser`, `menu_*`, `page_*`, `save_*_order`, `generate_seo_link`, `cookie_*`.
- UPDATE: `/admin/pages/*` dziala bez legacy `admin\controls\Pages` i `admin\view\Pages`.
- UPDATE: widoki `admin/templates/pages/*` przepiete na dane z kontrolera/repozytorium (bez `admin\factory\Pages`).
- UPDATE: endpointy zalezne od Pages w innych modulach (`articles`, `layouts`, `shop-category`, `shop-product`) przepiete z `admin/ajax.php?a=*` na `/admin/pages/*`.
- CLEANUP: usuniete `autoload/admin/controls/class.Pages.php`, `autoload/admin/view/class.Pages.php`, `autoload/admin/factory/class.Pages.php`, `admin/ajax/pages.php`; `admin/ajax.php` nie includuje juz `ajax/pages.php`.
- Testy: **OK (186 tests, 478 assertions)**.

View File

@@ -267,3 +267,17 @@ OK (178 tests, 443 assertions)
Nowe testy/rozszerzenia 2026-02-13: Nowe testy/rozszerzenia 2026-02-13:
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (nowe przypadki dla `saveFilesOrder`) - `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (nowe przypadki dla `saveFilesOrder`)
## Aktualizacja suite (Pages migration)
Ostatnio zweryfikowano: 2026-02-13
```text
OK (186 tests, 478 assertions)
```
Nowe testy dodane 2026-02-13:
- `tests/Unit/Domain/Pages/PagesRepositoryTest.php`
- `tests/Unit/admin/Controllers/PagesControllerTest.php`
Zaktualizowane testy 2026-02-13:
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (konstruktor z `Domain\\Pages\\PagesRepository`)

View File

@@ -37,7 +37,6 @@ $mdb = new medoo( [
'charset' => 'utf8' 'charset' => 'utf8'
] ); ] );
require_once 'ajax/pages.php';
require_once 'ajax/shop-category.php'; require_once 'ajax/shop-category.php';
require_once 'ajax/users.php'; require_once 'ajax/users.php';
require_once 'ajax/shop.php'; require_once 'ajax/shop.php';

View File

@@ -1,63 +0,0 @@
<?php
$a = \S::get( 'a' );
if ( $a == 'save_articles_order' )
{
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania kolejności wyświetlania artykułów wystąpił błąd. Proszę spróbować ponownie.' ];
if ( \admin\factory\Pages::save_articles_order( \S::get( 'page_id' ), \S::get( 'articles' ) ) )
$response = [ 'status' => 'ok' ];
echo json_encode( $response );
exit;
}
if ( $a == 'save_pages_order' )
{
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania kolejności stron wystąpił błąd. Proszę spróbować ponownie.' ];
if ( \admin\factory\Pages::save_pages_order( \S::get( 'menu_id' ), \S::get( 'pages' ) ) )
$response = [ 'status' => 'ok' ];
echo json_encode( $response );
exit;
}
if ( $a == 'generate_seo_link' )
{
$response = [ 'status' => 'error', 'msg' => 'Podczas generowania pola "seo link" wystąpił błąd. Proszę spróbować ponownie.' ];
if ( $seo_link = \admin\factory\Pages::generate_seo_link( \S::get( 'title' ), \S::get( 'page_id' ), \S::get( 'article_id' ), \S::get( 'category_id' ) ) )
$response = [ 'status' => 'ok', 'seo_link' => $seo_link ];
echo json_encode( $response );
exit;
}
if ( $a == 'cookie_menus' )
{
$array = unserialize( $_COOKIE[ 'cookie_menus' ] );
if ( $array[ \S::get( 'menu_id' ) ] == 0 )
$array[ \S::get( 'menu_id' ) ] = 1;
else
$array[ \S::get( 'menu_id' ) ] = 0;
$array = serialize( $array );
setcookie( 'cookie_menus', $array, time() + 3600 * 24 * 365 );
}
if ( $a == 'cookie_pages' )
{
$array = unserialize( $_COOKIE[ 'cookie_pages' ] );
if ( $array[ \S::get( 'page_id' ) ] == 0 )
$array[ \S::get( 'page_id' ) ] = 1;
else
$array[ \S::get( 'page_id' ) ] = 0;
$array = serialize( $array );
setcookie( 'cookie_pages', $array, time() + 3600 * 24 * 365 );
}

View File

@@ -225,7 +225,7 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/articles/gallery_order_save/', url: '/admin/articles/galleryOrderSave/',
data: { data: {
article_id: article_id, article_id: article_id,
order: order order: order
@@ -256,7 +256,7 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/articles/files_order_save/', url: '/admin/articles/filesOrderSave/',
data: { data: {
article_id: article_id, article_id: article_id,
order: order order: order
@@ -404,20 +404,18 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/cookieMenus/',
data: { data: {
a: 'cookie_menus',
menu_id: menu_id menu_id: menu_id
} }
}); });
} else { } else {
var page_id = $(this).parent('div').parent('li').attr('id'); var page_id = $(this).parent('div').parent('li').attr('id').replace('list_', '');
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/cookiePages/',
data: { data: {
a: 'cookie_pages',
page_id: page_id page_id: page_id
} }
}); });
@@ -438,7 +436,7 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/articles/article_image_alt_change/', url: '/admin/articles/imageAltChange/',
data: { data: {
image_id: image_id, image_id: image_id,
image_alt: image_alt image_alt: image_alt
@@ -463,7 +461,7 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/articles/article_file_name_change/', url: '/admin/articles/fileNameChange/',
data: { data: {
file_id: file_id, file_id: file_id,
file_name: file_name file_name: file_name
@@ -489,7 +487,7 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/articles/article_file_delete/', url: '/admin/articles/fileDelete/',
data: { data: {
file_id: file_id file_id: file_id
}, },
@@ -519,7 +517,7 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/articles/article_image_delete/', url: '/admin/articles/imageDelete/',
data: { data: {
image_id: image_id image_id: image_id
}, },
@@ -555,9 +553,8 @@ if (!empty($_COOKIE['cookie_menus'])) {
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/generateSeoLink/',
data: { data: {
a: 'generate_seo_link',
title: title, title: title,
article_id: article_id article_id: article_id
}, },
@@ -581,3 +578,4 @@ if (!empty($_COOKIE['cookie_menus'])) {
}); });
} }
</script> </script>

View File

@@ -150,8 +150,8 @@ $grid -> fields = [
]; ];
$grid -> external_code = $out; $grid -> external_code = $out;
$grid -> actions = [ $grid -> actions = [
'save' => [ 'url' => '/admin/banners/banner_save/', 'back_url' => '/admin/banners/view_list/' ], 'save' => [ 'url' => '/admin/banners/save/', 'back_url' => '/admin/banners/list/' ],
'cancel' => [ 'url' => '/admin/banners/view_list/' ] 'cancel' => [ 'url' => '/admin/banners/list/' ]
]; ];
$grid -> persist_edit = true; $grid -> persist_edit = true;
$grid -> id_param = 'id'; $grid -> id_param = 'id';

View File

@@ -92,9 +92,8 @@
{ {
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/cookieMenus/',
data: { data: {
a: 'cookie_menus',
menu_id: menu_id menu_id: menu_id
} }
}); });
@@ -107,10 +106,9 @@
{ {
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/cookiePages/',
data: { data: {
a: 'cookie_pages', page_id: page_id.replace( 'list_', '' )
page_id: page_id
} }
}); });
} }
@@ -159,14 +157,14 @@ ob_start();
);?> );?>
<?= \Html::input_switch( <?= \Html::input_switch(
array( array(
'label' => 'Szablon domyślny', 'label' => 'Szablon domy&#347;lny',
'name' => 'status', 'name' => 'status',
'checked' => $this -> layout['status'] == 1 ? true : false 'checked' => $this -> layout['status'] == 1 ? true : false
) )
);?> );?>
<?= \Html::input_switch( <?= \Html::input_switch(
array( array(
'label' => 'Szablon domyślny (kategorie)', 'label' => 'Szablon domy&#347;lny (kategorie)',
'name' => 'categories_default', 'name' => 'categories_default',
'checked' => $this -> layout['categories_default'] == 1 ? true : false 'checked' => $this -> layout['categories_default'] == 1 ? true : false
) )
@@ -246,8 +244,8 @@ $grid -> fields = [
] ]
]; ];
$grid -> actions = [ $grid -> actions = [
'save' => [ 'url' => '/admin/layouts/layout_save/', 'back_url' => '/admin/layouts/view_list/' ], 'save' => [ 'url' => '/admin/layouts/save/', 'back_url' => '/admin/layouts/list/' ],
'cancel' => [ 'url' => '/admin/layouts/view_list/' ] 'cancel' => [ 'url' => '/admin/layouts/list/' ]
]; ];
$grid -> external_code = $out; $grid -> external_code = $out;
$grid -> persist_edit = true; $grid -> persist_edit = true;
@@ -255,3 +253,4 @@ $grid -> id_param = 'id';
echo $grid -> draw(); echo $grid -> draw();
?> ?>

View File

@@ -1,42 +1 @@
<?php <?= \Tpl::view('components/form-edit', ['form' => $this->form]); ?>
global $gdb;
$grid = new \gridEdit;
$grid -> gdb_opt = $gdb;
$grid -> include_plugins = true;
$grid -> title = 'Zapisz menu';
$grid -> fields = [
[
'db' => 'id',
'type' => 'hidden',
'value' => $this -> menu['id']
],
[
'name' => 'Nazwa',
'db' => 'name',
'type' => 'text',
'value' => $this -> menu['name'],
'params' => [ 'class' => 'require' ]
],
[
'name' => 'Aktywne',
'db' => 'status',
'type' => 'input_switch',
'checked' => $this -> menu['status'] ? true : false,
'replace' => [ 'array' => [ 0 => 'nie', 1 => 'tak' ] ]
]
];
$grid -> actions = [
'save' => [ 'url' => '/admin/pages/menu_save/', 'back_url' => '/admin/pages/view_list/' ],
'cancel' => [ 'url' => '/admin/pages/view_list/' ]
];
$grid -> persist_edit = true;
$grid -> id_param = 'id';
echo $grid -> draw();
?>
<script type="text/javascript">
$( document ).ready( function()
{
disable_menu();
});
</script>

View File

@@ -1,89 +1,87 @@
<? <?php
global $gdb; global $gdb;
$pageId = (int)($this->page_id ?? 0);
$articles = is_array($this->articles ?? null) ? $this->articles : [];
ob_start(); ob_start();
?> ?>
<ol class="sortable" id="article-list"> <ol class="sortable" id="article-list">
<? <?php foreach ($articles as $article): ?>
if ( is_array( $this -> articles ) ) foreach ( $this -> articles as $article ) <?php
{ $articleId = (int)($article['article_id'] ?? 0);
?> $title = (string)($article['title'] ?? '');
<li id="list_<?= $article['article_id'];?>"> $status = (int)($article['status'] ?? 0);
<div class="content <? if ( !$article['status'] ) echo 'text-danger';?>"><span class="disclose"><span></span></span> <?= $article['title'];?></div>
</li>
<?
}
?> ?>
</ol> <li id="list_<?= $articleId; ?>">
<? <div class="content <?= $status === 1 ? '' : 'text-danger'; ?>"><span class="disclose"><span></span></span> <?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?></div>
</li>
<?php endforeach; ?>
</ol>
<?php
$out = ob_get_clean(); $out = ob_get_clean();
$grid = new \gridEdit; $grid = new \gridEdit;
$grid -> gdb_opt = $gdb; $grid->gdb_opt = $gdb;
$grid -> include_plugins = true; $grid->include_plugins = true;
$grid -> default_buttons = false; $grid->default_buttons = false;
$grid -> external_code = $out; $grid->external_code = $out;
$grid -> title = 'Lista artykułów'; $grid->title = 'Lista artyku&#322;&#243;w';
$grid -> buttons = [ $grid->buttons = [
[ [
'label' => 'Wstecz', 'label' => 'Wstecz',
'url' => '/admin/pages/view_list/', 'url' => '/admin/pages/list/',
'icon' => 'fa-reply', 'icon' => 'fa-reply',
'class' => 'btn-dark' 'class' => 'btn-dark',
] ],
]; ];
echo $grid -> draw(); echo $grid->draw();
?> ?>
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script> <script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
<script type="text/javascript"> <script type="text/javascript">
$( document ).ready( function() $(document).ready(function() {
{ $('ol.sortable').nestedSortable({
$( 'ol.sortable' ).nestedSortable( forcePlaceholderSize: true,
{ handle: 'div',
forcePlaceholderSize: true, helper: 'clone',
handle: 'div', items: 'li',
helper: 'clone', opacity: 0.6,
items: 'li', placeholder: 'placeholder',
opacity: .6, revert: 250,
placeholder: 'placeholder', tabSize: 25,
revert: 250, tolerance: 'pointer',
tabSize: 25, toleranceElement: '> div',
tolerance: 'pointer', maxLevels: 1,
toleranceElement: '> div', isTree: true,
maxLevels: 1, expandOnHover: 700,
isTree: true,
expandOnHover: 700,
save_articles_order: true save_articles_order: true
}); });
}); });
function save_articles_order() function save_articles_order() {
{ var articles = $('ol.sortable').nestedSortable('toArray', { startDepthCount: 0 });
articles = $( 'ol.sortable' ).nestedSortable( 'toArray', { startDepthCount: 0 } );
$.ajax({
$.ajax(
{
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/saveArticlesOrder/',
data: data: {
{ page_id: <?= $pageId; ?>,
a: 'save_articles_order',
page_id: <?= $this -> page_id;?>,
articles: articles articles: articles
}, },
beforeSend: function() beforeSend: function() {
{ $.prompt('Trwa zapisywanie...', { title: 'Prosz\\u0119 czeka\\u0107' });
$.prompt( 'Trwa zapisywanie...', { title: 'Proszę czekać' } );
}, },
success: function( data ) success: function(data) {
{ $('.jqibox').remove();
$( '.jqibox' ).remove(); var response = jQuery.parseJSON(data);
response = jQuery.parseJSON( data );
if ( response.status === 'error' ) if (response.status === 'error') {
create_error( response.msg ); create_error(response.msg);
}
} }
}); });
} }
</script> </script>

View File

@@ -1,400 +1 @@
<script type="text/javascript"> <?= \Tpl::view('components/form-edit', ['form' => $this->form]); ?>
var link_lang = '';
$( function()
{
disable_menu();
$('body').on( 'change', '#page_type', function ()
{
var page_type = $(this).val();
if ( page_type == 0 || page_type == 1 || page_type == 2 )
{
$( '#articles_limit' ).parents( '.form-group' ).show();
$( '#link-content' ).addClass( 'hide' );
$( '#category-content' ).addClass( 'hide' );
$( '#sort_type' ).parents( '.form-group' ).show();
}
else if ( page_type == 3 )
{
$( '#link-content' ).removeClass( 'hide' );
$( '#articles_limit' ).parents( '.form-group' ).hide();
$( '#sort_type' ).parents( '.form-group' ).hide();
$( '#category-content' ).addClass( 'hide' );
}
else if ( page_type == 5 )
{
$( '#category-content' ).removeClass( 'hide' );
$( '#articles_limit' ).parents( '.form-group' ).hide();
$( '#sort_type' ).parents( '.form-group' ).hide();
$( '#link-content' ).addClass( 'hide' );
}
else
{
$( '#articles_limit' ).parents( '.form-group' ).hide();
$( '#link-content' ).addClass( 'hide' );
$( '#category-content' ).addClass( 'hide' );
$( '#sort_type' ).parents( '.form-group' ).hide();
}
});
$( '#settings-tabs' ).easyResponsiveTabs({
width: 'auto',
fit: true,
tabidentify: 'settings-tabs',
type: 'vertical'
});
$( '#page_type' ).trigger( 'change' );
$( 'body').on( 'click', '.url-select', function() {
$( '#link_' + link_lang ).val( $( this ).attr( 'url' ) );
$.magnificPopup.close();
});
$( 'body').on( 'click', '.category-select', function() {
$( '#category_id' ).val( $( this ).attr( 'category-id' ) );
$( '#category_title' ).val( $( this ).attr( 'category-title' ) );
$.magnificPopup.close();
});
});
function generate_seo_links( lang, title, page_id )
{
if ( title === '' )
return false;
$.ajax(
{
type: 'POST',
cache: false,
url: '/admin/ajax.php',
data: {
a: 'generate_seo_link',
title: title,
page_id: page_id
},
beforeSend: function()
{
$( '#overlay' ).show();
},
success: function( data )
{
$( '#overlay' ).hide();
response = jQuery.parseJSON( data );
if ( response.status === 'ok' )
$( '#seo_link_' + lang ).val( response.seo_link );
else
create_error( response.msg );
}
});
}
function pages_url_browser( lang_id ) {
link_lang = lang_id;
$.magnificPopup.open({
removalDelay: 500,
items: {
src: '/admin/pages/pages_url_browser/modal=true'
},
type: 'ajax',
overflowY: 'scroll'
});
}
function category_url_browser() {
$.magnificPopup.open({
removalDelay: 500,
items: {
src: '/admin/shop_category/category_url_browser/modal=true'
},
type: 'ajax',
overflowY: 'scroll'
});
}
</script>
<?
global $db;
ob_start();
?>
<div id="settings-tabs">
<ul class="resp-tabs-list settings-tabs">
<li><i class="fa fa-file"></i>Treść</li>
<li><i class="fa fa-wrench"></i>Ustawienia</li>
<li><i class="fa fa-globe"></i>SEO</li>
</ul>
<div class="resp-tabs-container settings-tabs">
<div>
<div class="panel">
<div class="panel-heading">
<ul class="nav panel-tabs-border panel-tabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<li>
<a href="#laguages-main-<?= $lg['id'];?>" data-toggle="tab" aria-expanded="true"><? 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>
<? endif;?>
<? endforeach; endif;?>
</ul>
</div>
<div class="panel-body">
<div class="tab-content pn br-n">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<div id="laguages-main-<?= $lg['id'];?>" class="tab-pane <? if ( !$z01++ ):?>active<? endif;?>">
<?= \Html::input(
array(
'label' => 'Nazwa strony',
'name' => 'title[' . $lg['id'] . ']',
'id' => 'title_' . $lg['id'],
'value' => $this -> page[ 'languages' ][ $lg['id'] ]['title'],
)
);?>
</div>
<? endif;?>
<? endforeach; endif;?>
</div>
</div>
</div>
</div>
<div style="padding: 15px;">
<?
if ( is_array( $this -> menus ) ): foreach ( $this -> menus as $menu ):
$menus[ $menu['id'] ] = $menu['name'];
endforeach; endif;
?>
<?= \Html::select(
array(
'label' => 'Menu',
'name' => 'menu_id',
'values' => $menus,
'value' => $this -> page['id'] ? $this -> page['menu_id'] : $this -> menu_id
)
);?>
<?= \Html::select(
array(
'label' => 'Typ strony',
'name' => 'page_type',
'id' => 'page_type',
'values' => \admin\factory\Pages::$_page_types,
'value' => $this -> page['page_type']
)
);?>
<div id="link-content" class="hide">
<div class="panel">
<div class="panel-heading">
<ul class="nav panel-tabs-border panel-tabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<li>
<a href="#languages-links-<?= $lg['id'];?>" data-toggle="tab" aria-expanded="true"><? 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>
<? endif;?>
<? endforeach; endif;?>
</ul>
</div>
<div class="panel-body">
<div class="tab-content pn br-n">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<div id="languages-links-<?= $lg['id'];?>" class="tab-pane <? if ( !$z02++ ):?>active<? endif;?>">
<?= \Html::input_icon( [
'label' => 'Link',
'name' => 'link[' . $lg['id'] . ']',
'id' => 'link_' . $lg['id'],
'value' => $this -> page['languages'][$lg['id']]['link'],
'icon_class' => 'fa fa-link',
'icon_js' => 'pages_url_browser( "' . $lg['id'] . '");'
] );
?>
</div>
<? endif;?>
<? endforeach; endif;?>
</div>
</div>
</div>
</div>
<div id="category-content" class="hide">
<div id="languages-category">
<?= \Html::input(
array(
'type' => 'hidden',
'name' => 'category_id',
'id' => 'category_id',
'value' => $this -> page['category_id']
)
);
?>
<?= \Html::input_icon(
array(
'label' => 'Kategoria',
'name' => 'category_title',
'id' => 'category_title',
'value' => $this -> page['category_id'] ? \admin\factory\ShopCategory::category_title( $this -> page['category_id'] ) : '',
'icon_class' => 'fa fa-link',
'icon_js' => 'category_url_browser();'
)
);
?>
</div>
</div>
<?= \Html::select(
array(
'label' => 'Sortowanie artykułów',
'name' => 'sort_type',
'id' => 'sort_type',
'values' => \admin\factory\Pages::$_sort_types,
'value' => $this -> page['sort_type']
)
);?>
<?
$layouts[''] = '---- szablon ----';
if ( is_array( $this -> layouts ) ): foreach ( $this -> layouts as $layout ):
$layouts[ $layout['id'] ] = $layout['name'];
endforeach; endif;
?>
<?= \Html::select(
array(
'label' => 'Szablon',
'name' => 'layout_id',
'id' => 'layout_id',
'values' => $layouts,
'value' => $this -> page['layout_id']
)
);?>
<?= \Html::input(
array(
'label' => 'Liczba artykułów na stronę',
'name' => 'articles_limit',
'id' => 'articles_limit',
'value' => $this -> page['articles_limit'] ? $this -> page['articles_limit'] : 2
)
);?>
<?= \Html::input_switch(
array(
'label' => 'Pokaż tytuł',
'name' => 'show_title',
'checked' => $this -> page['show_title'] == 1 or !$this -> page['id'] ? true : false
)
);?>
<?= \Html::input_switch(
array(
'label' => 'Aktywna',
'name' => 'status',
'checked' => $this -> page['status'] == 1 or !$this -> page['id'] ? true : false
)
);?>
<?= \Html::input_switch(
array(
'label' => 'Strona startowa',
'name' => 'start',
'checked' => $this -> page['start'] == 1 ? true : false
)
);?>
</div>
<div>
<div class="panel">
<div class="panel-heading">
<ul class="nav panel-tabs-border panel-tabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<li>
<a href="#languages-seo-<?= $lg['id'];?>" data-toggle="tab" aria-expanded="true"><? 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>
<? endif;?>
<? endforeach; endif;?>
</ul>
</div>
<div class="panel-body">
<div class="tab-content pn br-n">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?>
<div id="languages-seo-<?= $lg['id'];?>" class="tab-pane <? if ( !$z03++ ):?>active<? endif;?>">
<?= \Html::input_icon( [
'label' => 'Link SEO',
'name' => 'seo_link[' . $lg['id'] . ']',
'id' => 'seo_link_' . $lg['id'],
'value' => $this -> page['languages' ][ $lg['id'] ]['seo_link'],
'icon_content' => 'generuj',
'icon_js' => 'generate_seo_links( "' . $lg['id'] . '", $( "#title_' . $lg['id'] . '" ).val(), ' . (int)$this -> page['id'] . ' );'
] );?>
<?= \Html::input( [
'label' => 'Tytuł strony (h1)',
'name' => 'page_title[' . $lg['id'] . ']',
'id' => 'page_title_' . $lg['id'],
'value' => $this -> page['languages' ][ $lg['id'] ]['page_title']
] );?>
<?= \Html::input( [
'label' => 'Meta title',
'name' => 'meta_title[' . $lg['id'] . ']',
'id' => 'meta_title_' . $lg['id'],
'value' => $this -> page['languages'][ $lg['id'] ]['meta_title']
] );?>
<?= \Html::textarea( [
'label' => 'Meta description',
'name' => 'meta_description[' . $lg['id'] . ']',
'id' => 'meta_description_' . $lg['id'],
'value' => $this -> page['languages'][ $lg['id'] ]['meta_description']
] );?>
<?= \Html::textarea( [
'label' => 'Meta keywords',
'name' => 'meta_keywords[' . $lg['id'] . ']',
'id' => 'meta_keywords_' . $lg['id'],
'value' => $this -> page['languages'][ $lg['id'] ]['meta_keywords']
] );?>
<?= \Html::select( [
'label' => 'Blokuj indeksację',
'name' => 'noindex[' . $lg['id'] . ']',
'id' => 'noindex_' . $lg['id'],
'values' => [ 0 => 'nie', 1 => 'tak' ],
'value' => $this -> page['languages'][ $lg['id'] ]['noindex'] == 1 ? 1 : 0
] );?>
<?= \Html::input( [
'label' => 'Rel canonical',
'name' => 'canonical[' . $lg['id'] . ']',
'id' => 'canonical_' . $lg['id'],
'value' => $this -> page['languages'][ $lg['id'] ]['canonical']
] );?>
</div>
<? endif;?>
<? endforeach; endif;?>
</div>
</div>
</div>
</div>
</div>
<div class="clear"></div>
<?
$out = ob_get_clean();
$grid = new \gridEdit;
$grid -> id = 'page-edit';
$grid -> gdb_opt = $gdb;
$grid -> include_plugins = true;
$grid -> title = 'Edycja strony';
$grid -> fields = [
[
'db' => 'id',
'type' => 'hidden',
'value' => $this -> page['id']
],
[
'db' => 'parent_id',
'type' => 'hidden',
'value' => $this -> page['id'] ? $this -> page['parent_id'] : $this -> parent_id
]
];
$grid -> actions = [
'save' => [ 'url' => '/admin/pages/page_save/', 'back_url' => '/admin/pages/view_list/' ],
'cancel' => [ 'url' => '/admin/pages/view_list/' ]
];
$grid -> external_code = $out;
$grid -> persist_edit = true;
$grid -> id_param = 'id';
echo $grid -> draw();
?>

View File

@@ -1,48 +1,57 @@
<? <?php
global $gdb; global $gdb;
ob_start(); $menus = is_array($this->menus ?? null) ? $this->menus : [];
if ( is_array( $this -> menus ) ) foreach ( $this -> menus as $menu ) $modal = !empty($this->modal);
{ $cookiePages = is_array($this->cookie_pages ?? null) ? $this->cookie_pages : [];
?> $cookieMenus = is_array($this->cookie_menus ?? null) ? $this->cookie_menus : [];
<div class="menu_sortable">
<ol class="sortable" id="sortable_<?= $menu['id'];?>" menu-id="<?= $menu['id'];?>">
<li id="list_<?= $menu['id'];?>" class="menu_<?= $menu['id'];?>" menu="<?= $menu['id'];?>">
<div class="context_0 content content_menu">
<span class="disclose"><span></span></span>
<? if ( !$menu['status'] ) echo '<i class="fa fa-ban fa-lg text-danger" title="Menu nieaktywne"></i>';?>
Menu: <b><?= $menu['name'];?></b>
</div>
<?= \admin\view\Pages::subpages_browse_list( \admin\factory\Pages::menu_pages( $menu['id'] ) );?>
</li>
</ol>
</div>
<?
}
ob_start();
foreach ($menus as $menu):
$menuId = (int)($menu['id'] ?? 0);
$menuName = (string)($menu['name'] ?? '');
$menuStatus = (int)($menu['status'] ?? 0);
?>
<div class="menu_sortable">
<ol class="sortable" id="sortable_<?= $menuId; ?>" menu-id="<?= $menuId; ?>">
<li id="list_<?= $menuId; ?>" class="menu_<?= $menuId; ?>" menu="<?= $menuId; ?>">
<div class="context_0 content content_menu">
<span class="disclose"><span></span></span>
<?php if ($menuStatus !== 1): ?><i class="fa fa-ban fa-lg text-danger" title="Menu nieaktywne"></i><?php endif; ?>
Menu: <b><?= htmlspecialchars($menuName, ENT_QUOTES, 'UTF-8'); ?></b>
</div>
<?= \Tpl::view('pages/subpages-browse-list', [
'pages' => $menu['pages'] ?? [],
'step' => 1,
]); ?>
</li>
</ol>
</div>
<?php
endforeach;
$out = ob_get_clean(); $out = ob_get_clean();
$grid = new \gridEdit; $grid = new \gridEdit;
$grid -> id = 'pages-list'; $grid->id = 'pages-list';
$grid -> gdb_opt = $gdb; $grid->gdb_opt = $gdb;
$grid -> include_plugins = true; $grid->include_plugins = true;
$grid -> title = 'Lista stron'; $grid->title = 'Lista stron';
$grid -> default_buttons = false; $grid->default_buttons = false;
$grid -> external_code = $out; $grid->external_code = $out;
echo $grid -> draw(); echo $grid->draw();
?> ?>
<style type="text/css"> <style type="text/css">
<? if ( $this -> modal ): echo '.mfp-container'; endif;?> body.sb-top.sb-top-sm .navbar.navbar-fixed-top + #sidebar_left + #content_wrapper { <?php if ($modal): ?>.mfp-container<?php endif; ?> body.sb-top.sb-top-sm .navbar.navbar-fixed-top + #sidebar_left + #content_wrapper {
padding-top: 0; padding-top: 0;
} }
<? if ( $this -> modal ): echo '.mfp-container'; endif;?> #content { <?php if ($modal): ?>.mfp-container<?php endif; ?> #content {
padding: 27px 0 0; padding: 27px 0 0;
} }
<? if ( $this -> modal ): echo '.mfp-container'; endif;?> #content > .row { <?php if ($modal): ?>.mfp-container<?php endif; ?> #content > .row {
margin: 0; margin: 0;
} }
<? if ( $this -> modal ): echo '.mfp-container'; endif;?> #content > .row > .col-lg-9 { <?php if ($modal): ?>.mfp-container<?php endif; ?> #content > .row > .col-lg-9 {
padding: 0; padding: 0;
width: 100%; width: 100%;
float: none; float: none;
@@ -50,113 +59,88 @@ echo $grid -> draw();
</style> </style>
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script> <script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var menu_id = 0; var cookiePages = <?= json_encode($cookiePages, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
var cookieMenus = <?= json_encode($cookieMenus, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
function getUrlParam(paramName)
{ function getUrlParam(paramName) {
var reParam = new RegExp('(?:[\?&]|&amp;)' + paramName + '=([^&]+)', 'i'); var reParam = new RegExp('(?:[\\?&]|&amp;)' + paramName + '=([^&]+)', 'i');
var match = window.location.search.match(reParam); var match = window.location.search.match(reParam);
return (match && match.length > 1) ? match[1] : ''; return (match && match.length > 1) ? match[1] : '';
} }
$( document ).ready( function() $(document).ready(function() {
{ <?php if (!$modal): ?>
<? if ( !$this -> modal ):?> $('#sidebar_left, .navbar-fixed-top').hide();
$( '#sidebar_left, .navbar-fixed-top' ).hide(); <?php endif; ?>
<? endif;?>
var funcNum = getUrlParam('CKEditorFuncNum'); var funcNum = getUrlParam('CKEditorFuncNum');
$( 'body' ).on( 'click', '.button', function() $('body').on('click', '.button', function() {
{ if (funcNum) {
if ( funcNum ) window.opener.CKEDITOR.tools.callFunction(funcNum, $(this).attr('url'));
{
window.opener.CKEDITOR.tools.callFunction(funcNum, $( this ).attr( 'url' ) );
window.close(); window.close();
} }
}); });
$( 'ol.sortable' ).nestedSortable(
{
forcePlaceholderSize: true,
handle: 'div',
helper: 'clone',
items: 'li',
opacity: .9,
placeholder: 'placeholder',
revert: 250,
tabSize: 45,
tolerance: 'pointer',
toleranceElement: '> div',
maxLevels: 3,
isTree: true,
expandOnHover: 700,
stop: function() {
save_pages_order();
}
});
$( '.disclose' ).on( 'click', function() $('ol.sortable').nestedSortable({
{ forcePlaceholderSize: true,
$( this ).closest( 'li' ).toggleClass( 'sort-collapsed' ).toggleClass( 'sort-expanded' ); handle: 'div',
}); helper: 'clone',
items: 'li',
$( ".sortable *" ).mousedown( function(e) opacity: 0.9,
{ placeholder: 'placeholder',
menu_id = $( this ).parents( 'ol.sortable' ).attr( 'menu-id' ); revert: 250,
}); tabSize: 45,
tolerance: 'pointer',
$( '.disclose' ).mousedown( function(e) toleranceElement: '> div',
{ maxLevels: 3,
if ( e.which === 1 ) { isTree: true,
if ( $( this ).parent( 'div' ).hasClass( 'content_menu' ) ) expandOnHover: 700,
{ isAllowed: function() {
var menu_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'menu' ); return false;
}
$.ajax( });
{
type: 'POST', $('.disclose').on('click', function() {
cache: false, $(this).closest('li').toggleClass('sort-collapsed').toggleClass('sort-expanded');
url: '/admin/ajax.php', });
data: {
a: 'cookie_menus', $('.disclose').mousedown(function(e) {
menu_id: menu_id if (e.which !== 1) {
} return;
}); }
}
else if ($(this).parent('div').hasClass('content_menu')) {
{ var menuId = $(this).parent('div').parent('li').attr('menu');
var page_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'id' ); $.ajax({
type: 'POST',
$.ajax( cache: false,
{ url: '/admin/pages/cookieMenus/',
type: 'POST', data: { menu_id: menuId }
cache: false, });
url: '/admin/ajax.php', } else {
data: { var pageId = $(this).parent('div').parent('li').attr('id').replace('list_', '');
a: 'cookie_pages', $.ajax({
page_id: page_id type: 'POST',
} cache: false,
}); url: '/admin/pages/cookiePages/',
} data: { page_id: pageId }
});
}
});
Object.keys(cookiePages || {}).forEach(function(key) {
if (String(cookiePages[key]) === '1') {
$('.list_' + key).children('div').children('span.disclose').click();
}
});
Object.keys(cookieMenus || {}).forEach(function(key) {
if (String(cookieMenus[key]) === '1') {
$('.menu_' + key).children('div').children('span.disclose').click();
} }
}); });
<?php
$array = unserialize( $_COOKIE[ 'cookie_pages' ] );
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
if ( $val ):
?>$( '.<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
endif;
endforeach; endif;
$array = unserialize( $_COOKIE[ 'cookie_menus' ] );
if ( is_array( $array ) ): foreach ( $array as $key => $val ):
if ( $val ):
?>$( '.menu_<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<?
endif;
endforeach; endif;
?>
}); });
</script> </script>

View File

@@ -1,208 +1,249 @@
<? <?php
global $gdb; global $gdb;
ob_start(); $menus = is_array($this->menus ?? null) ? $this->menus : [];
if ( is_array( $this -> menus ) ) foreach ( $this -> menus as $menu ) $cookiePages = is_array($this->cookie_pages ?? null) ? $this->cookie_pages : [];
{ $cookieMenus = is_array($this->cookie_menus ?? null) ? $this->cookie_menus : [];
?>
<div class="menu_sortable">
<ol class="sortable" id="sortable_<?= $menu['id'];?>" menu-id="<?= $menu['id'];?>">
<li id="list_<?= $menu['id'];?>" class="menu_<?= $menu['id'];?>" menu="<?= $menu['id'];?>">
<div class="context_0 content content_menu">
<span class="disclose"><span></span></span>
<? if ( !$menu['status'] ) echo '<i class="fa fa-ban fa-lg text-danger" title="Menu nieaktywne"></i>';?>
<b>Menu: <?= $menu['name'];?></b>
<div class="btn-group ml20 pull-right">
<a href="/admin/pages/menu_edit/id=<?= $menu['id'];?>" title="Edytuj menu" class="btn btn-sm btn-system">
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj menu</span>
</a>
<a href="#" title="Usuń menu" class="btn btn-sm btn-danger menu-delete" menu-id="<?= $menu['id'];?>">
<i class="fa fa-trash"></i> <span class="hidden-xs">Usuń menu</span>
</a>
<a href="/admin/pages/page_edit/pid=0&menu_id=<?= $menu['id'];?>" title="Dodaj stronę" class="btn btn-sm btn-success">
<i class="fa fa-plus-circle"></i> <span class="hidden-xs">Dodaj stronę</span>
</a>
</div>
</div>
<?= \Tpl::view( 'pages/subpages-list', [
'pages' => \admin\factory\Pages::menu_pages( $menu['id'] ),
'menu_id' => $menu['id']
] );
?>
</li>
</ol>
</div>
<?
}
ob_start();
foreach ($menus as $menu):
$menuId = (int)($menu['id'] ?? 0);
$menuName = (string)($menu['name'] ?? '');
$menuStatus = (int)($menu['status'] ?? 0);
?>
<div class="menu_sortable">
<ol class="sortable" id="sortable_<?= $menuId; ?>" menu-id="<?= $menuId; ?>">
<li id="list_<?= $menuId; ?>" class="menu_<?= $menuId; ?>" menu="<?= $menuId; ?>">
<div class="context_0 content content_menu">
<span class="disclose"><span></span></span>
<?php if ($menuStatus !== 1): ?><i class="fa fa-ban fa-lg text-danger" title="Menu nieaktywne"></i><?php endif; ?>
<b>Menu: <?= htmlspecialchars($menuName, ENT_QUOTES, 'UTF-8'); ?></b>
<div class="btn-group ml20 pull-right">
<a href="/admin/pages/menuEdit/id=<?= $menuId; ?>" title="Edytuj menu" class="btn btn-sm btn-system">
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj menu</span>
</a>
<a href="#" title="Usu&#324; menu" class="btn btn-sm btn-danger menu-delete" menu-id="<?= $menuId; ?>">
<i class="fa fa-trash"></i> <span class="hidden-xs">Usu&#324; menu</span>
</a>
<a href="/admin/pages/edit/pid=0&menu_id=<?= $menuId; ?>" title="Dodaj stron&#281;" class="btn btn-sm btn-success">
<i class="fa fa-plus-circle"></i> <span class="hidden-xs">Dodaj stron&#281;</span>
</a>
</div>
</div>
<?= \Tpl::view('pages/subpages-list', [
'pages' => $menu['pages'] ?? [],
'step' => 1,
]); ?>
</li>
</ol>
</div>
<?php
endforeach;
$out = ob_get_clean(); $out = ob_get_clean();
$grid = new \gridEdit; $grid = new \gridEdit;
$grid -> id = 'pages-list'; $grid->id = 'pages-list';
$grid -> gdb_opt = $gdb; $grid->gdb_opt = $gdb;
$grid -> include_plugins = true; $grid->include_plugins = true;
$grid -> title = 'Lista stron'; $grid->title = 'Lista stron';
$grid -> default_buttons = false; $grid->default_buttons = false;
$grid -> buttons = [ $grid->buttons = [
[ [
'label' => 'Dodaj menu', 'label' => 'Dodaj menu',
'url' => '/admin/pages/menu_edit/', 'url' => '/admin/pages/menuEdit/',
'icon' => 'fa-plus-circle', 'icon' => 'fa-plus-circle',
'class' => 'btn-success' 'class' => 'btn-success',
] ],
]; ];
$grid -> external_code = $out; $grid->external_code = $out;
echo $grid -> draw(); echo $grid->draw();
?> ?>
<script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script> <script type="text/javascript" src="/libraries/jquery-nested-sortable/jquery.mjs.nestedSortable.js"></script>
<style type="text/css">
.jconfirm.table-list-confirm-dialog .jconfirm-row {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.jconfirm.table-list-confirm-dialog .jconfirm-box-container {
width: 100%;
max-width: 560px;
padding-left: 12px;
padding-right: 12px;
margin: 0 auto;
}
.jconfirm.table-list-confirm-dialog .jconfirm-box {
width: 100% !important;
}
</style>
<script type="text/javascript"> <script type="text/javascript">
var menu_id = 0; var menu_id = 0;
var cookiePages = <?= json_encode($cookiePages, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
var cookieMenus = <?= json_encode($cookieMenus, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?>;
$( document ).ready( function() $(document).ready(function() {
{ function confirmDialog(message, onConfirm) {
$( 'body' ).on( 'click', '.menu-delete', function() if (typeof $.confirm === 'function') {
{ $.confirm({
var menu_id = $( this ).attr( 'menu-id' ); title: 'Potwierdzenie',
content: String(message),
type: 'red',
boxWidth: '560px',
useBootstrap: false,
animation: 'scale',
closeAnimation: 'scale',
backgroundDismissAnimation: 'shake',
container: 'body',
theme: 'modern',
columnClass: '',
typeAnimated: true,
lazyOpen: false,
draggable: false,
closeIcon: true,
containerFluid: true,
escapeKey: true,
backgroundDismiss: true,
animationBounce: 1.1,
watchInterval: 100,
offsetTop: 0,
offsetBottom: 0,
customClass: 'table-list-confirm-dialog',
buttons: {
cancel: {
text: 'Anuluj',
btnClass: 'btn-default'
},
confirm: {
text: 'Usuń',
btnClass: 'btn-danger',
action: function() {
if (typeof onConfirm === 'function') {
onConfirm();
}
}
}
}
});
return;
}
$.prompt( "Na pewno chcesz usunąć wybrane menu?", if (window.confirm(message) && typeof onConfirm === 'function') {
{ onConfirm();
title: "Potwierdź?", }
buttons: { "Tak": true, "Nie": false }, }
submit: function( e, v, m, f )
{ $('body').on('click', '.menu-delete', function() {
if ( v === true ) var selectedMenuId = $(this).attr('menu-id');
document.location.href = '/admin/pages/menu_delete/id=' + menu_id;
} confirmDialog('Na pewno chcesz usunąć wybrane menu?', function() {
document.location.href = '/admin/pages/menuDelete/id=' + selectedMenuId;
}); });
}); });
$( 'body' ).on( 'click', '.page-delete', function() $('body').on('click', '.page-delete', function() {
{ var pageId = $(this).attr('page-id');
var page_id = $( this ).attr( 'page-id' );
$.prompt( "Na pewno chcesz usunąć wybraną stronę?", confirmDialog('Na pewno chcesz usunąć wybraną stronę?', function() {
{ document.location.href = '/admin/pages/delete/id=' + pageId;
title: "Potwierdź?",
buttons: { "Tak": true, "Nie": false },
submit: function( e, v, m, f )
{
if ( v === true )
document.location.href = '/admin/pages/page_delete/id=' + page_id;
}
}); });
}); });
$( 'ol.sortable' ).nestedSortable( $('ol.sortable').nestedSortable({
{ forcePlaceholderSize: true,
forcePlaceholderSize: true, handle: 'div',
handle: 'div', helper: 'clone',
helper: 'clone', items: 'li',
items: 'li', opacity: 0.9,
opacity: .9, placeholder: 'placeholder',
placeholder: 'placeholder', revert: 250,
revert: 250, tabSize: 45,
tabSize: 45, tolerance: 'pointer',
tolerance: 'pointer', toleranceElement: '> div',
toleranceElement: '> div', maxLevels: 4,
maxLevels: 4, isTree: true,
isTree: true, expandOnHover: 700,
expandOnHover: 700,
stop: function() { stop: function() {
save_pages_order(); save_pages_order();
} }
});
$( '.disclose' ).on( 'click', function()
{
$( this ).closest( 'li' ).toggleClass( 'sort-collapsed' ).toggleClass( 'sort-expanded' );
});
$( ".sortable *" ).mousedown( function(e)
{
menu_id = $( this ).parents( 'ol.sortable' ).attr( 'menu-id' );
}); });
$( '.disclose' ).mousedown( function(e) $('.disclose').on('click', function() {
{ $(this).closest('li').toggleClass('sort-collapsed').toggleClass('sort-expanded');
if ( e.which === 1 ) { });
if ( $( this ).parent( 'div' ).hasClass( 'content_menu' ) )
{
var menu_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'menu' );
$.ajax( $('.sortable *').mousedown(function() {
{ menu_id = $(this).parents('ol.sortable').attr('menu-id');
type: 'POST', });
cache: false,
url: '/admin/ajax.php',
data: {
a: 'cookie_menus',
menu_id: menu_id
}
});
}
else
{
var page_id = $( this ).parent( 'div' ).parent( 'li' ).attr( 'id' );
$.ajax( $('.disclose').mousedown(function(e) {
{ if (e.which !== 1) {
type: 'POST', return;
cache: false, }
url: '/admin/ajax.php',
data: { if ($(this).parent('div').hasClass('content_menu')) {
a: 'cookie_pages', var selectedMenuId = $(this).parent('div').parent('li').attr('menu');
page_id: page_id $.ajax({
} type: 'POST',
}); cache: false,
} url: '/admin/pages/cookieMenus/',
data: { menu_id: selectedMenuId }
});
} else {
var pageId = $(this).parent('div').parent('li').attr('id').replace('list_', '');
$.ajax({
type: 'POST',
cache: false,
url: '/admin/pages/cookiePages/',
data: { page_id: pageId }
});
} }
}); });
<?php Object.keys(cookiePages || {}).forEach(function(key) {
$array = unserialize( $_COOKIE[ 'cookie_pages' ] ); if (String(cookiePages[key]) === '1') {
if ( is_array( $array ) ): foreach ( $array as $key => $val ): $('.list_' + key).children('div').children('span.disclose').click();
if ( $val ): }
?>$( '.<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<? });
endif;
endforeach; endif;
$array = unserialize( $_COOKIE[ 'cookie_menus' ] ); Object.keys(cookieMenus || {}).forEach(function(key) {
if ( is_array( $array ) ): foreach ( $array as $key => $val ): if (String(cookieMenus[key]) === '1') {
if ( $val ): $('.menu_' + key).children('div').children('span.disclose').click();
?>$( '.menu_<?= $key;?>' ).children( 'div' ).children( 'span.disclose' ).click();<? }
endif; });
endforeach; endif;
?>
}); });
function save_pages_order( ) function save_pages_order() {
{ if (!menu_id) {
pages = $( '#sortable_' + menu_id ).nestedSortable( 'toArray', { startDepthCount: 0 } ); return;
}
$.ajax( var pages = $('#sortable_' + menu_id).nestedSortable('toArray', { startDepthCount: 0 });
{
$.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/savePagesOrder/',
data: data: {
{
a: 'save_pages_order',
menu_id: menu_id, menu_id: menu_id,
pages: pages pages: pages
}, },
beforeSend: function() beforeSend: function() {
{ $.prompt('Trwa zapisywanie...', { title: 'Prosz\\u0119 czeka\\u0107' });
$.prompt( 'Trwa zapisywanie...', { title: 'Proszę czekać' } );
}, },
success: function( data ) success: function(data) {
{ $('.jqibox').remove();
$( '.jqibox' ).remove();
response = jQuery.parseJSON( data );
if ( response.status === 'error' ) var response = jQuery.parseJSON(data);
create_error( response.msg ); if (response.status === 'error') {
create_error(response.msg);
}
} }
}); });
} }
</script> </script>

View File

@@ -1,77 +1,60 @@
<? if ( is_array( $this -> pages ) ):?> <?php
<? $settings = \front\factory\Settings::settings_details();?> $pages = is_array($this->pages ?? null) ? $this->pages : [];
<ol> $step = (int)($this->step ?? 1);
<? foreach ( $this -> pages as $page ):?>
<li id="list_<?= $page['id'];?>" idk="<?= $page['id'];?>" class="list_<?= $page['id'];?>" menu="<?= $page['menu_id'];?>">
<div class="content">
<span class="disclose"><span></span></span>
<?
if ( !$page['status'] )
echo '<i class="fa fa-ban fa-lg text-danger" title="Strona nieaktywna"></i>';
if ( $page['start'] ) if (empty($pages)) {
echo '<i class="fa fa-star fa-lg text-system" title="Strona startowa"></i>'; return;
}
echo $page['title']; ?>
<ol>
if ( is_array( $page['languages'] ) ): <?php foreach ($pages as $page): ?>
echo '<div class="btn-group flags" style="display: inline-block;">'; <?php
foreach ( $page['languages'] as $lg ) $pageId = (int)($page['id'] ?? 0);
echo '<img src="/admin/layout/lang-' . $lg['lang_id'] . '.jpg" />'; $menuId = (int)($page['menu_id'] ?? 0);
echo '</div>'; $title = (string)($page['title'] ?? '');
endif; $status = (int)($page['status'] ?? 0);
$start = (int)($page['start'] ?? 0);
$default_language = \front\factory\Languages::default_language(); $languages = is_array($page['languages'] ?? null) ? $page['languages'] : [];
if ( is_array( $page['languages'] ) ): $previewUrls = is_array($page['preview_urls'] ?? null) ? $page['preview_urls'] : [];
foreach ( $page['languages'] as $lg ):
echo '<div class="btn-group ml20 pull-right">';
echo '<a href="#" title="Wybierz stronę" class="btn btn-sm btn-system button url-select" url="';
if ( $settings['links_structure'] )
{
if ( $lg['seo_link'] )
{
$seo = '/' . \admin\factory\Pages::google_url_preview( $page['id'],
$lg['title'], $lg['lang_id'], 0, 0,
$lg['seo_link'] );
echo $seo;
}
else
{
$seo = '/' . \admin\factory\Pages::google_url_preview( $page['id'],
$lg['title'], $lg['lang_id'], 0, 0, 0 );
echo $seo;
}
}
else
{
if ( $lg['seo_link'] )
{
if ( $default_language != $lg['lang_id'] )
echo '/' . $lg['lang_id'];
echo '/' . $lg['seo_link'];
}
else
{
if ( $default_language != $lg['lang_id'] )
echo '/' . $lg['lang_id'];
echo '/s-' . $page['id'] . '-' . \S::seo( $lg['title'] );
}
}
echo '">';
echo '<i class="fa fa-check"></i> <span class="hidden-xs">' . strtoupper( $lg['lang_id'] ) . '</span>';
echo '</a>';
echo '</div>';
endforeach;
endif;
?>
</div>
<?
if ( is_array( $page['subpages'] ) )
echo \admin\view\Pages::subpages_browse_list( $page['subpages'],
$page['id'], $this -> step + 1 );
?> ?>
</li> <li id="list_<?= $pageId; ?>" class="list_<?= $pageId; ?>" menu="<?= $menuId; ?>">
<? endforeach;?> <div class="content">
</ol> <span class="disclose"><span></span></span>
<? endif;?> <?php if ($status !== 1): ?><i class="fa fa-ban fa-lg text-danger" title="Strona nieaktywna"></i><?php endif; ?>
<?php if ($start === 1): ?><i class="fa fa-star fa-lg text-system" title="Strona startowa"></i><?php endif; ?>
<?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?>
<?php if (!empty($languages)): ?>
<div class="btn-group flags" style="display: inline-block;">
<?php foreach ($languages as $language): ?>
<?php $langId = (string)($language['lang_id'] ?? ''); ?>
<?php if ($langId !== ''): ?>
<img src="/admin/layout/lang-<?= htmlspecialchars($langId, ENT_QUOTES, 'UTF-8'); ?>.jpg" />
<?php endif; ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php foreach ($languages as $language): ?>
<?php
$langId = (string)($language['lang_id'] ?? '');
if ($langId === '') {
continue;
}
$url = (string)($previewUrls[$langId] ?? '#');
?>
<div class="btn-group ml20 pull-right">
<a href="#" title="Wybierz stronę" class="btn btn-sm btn-system button url-select" url="<?= htmlspecialchars($url, ENT_QUOTES, 'UTF-8'); ?>">
<i class="fa fa-check"></i> <span class="hidden-xs"><?= strtoupper(htmlspecialchars($langId, ENT_QUOTES, 'UTF-8')); ?></span>
</a>
</div>
<?php endforeach; ?>
</div>
<?= \Tpl::view('pages/subpages-browse-list', [
'pages' => $page['subpages'] ?? [],
'step' => $step + 1,
]); ?>
</li>
<?php endforeach; ?>
</ol>

View File

@@ -1,60 +1,75 @@
<? if ( is_array( $this -> pages ) ):?> <?php
<ol> $pages = is_array($this->pages ?? null) ? $this->pages : [];
<? foreach ( $this -> pages as $page ):?> $step = (int)($this->step ?? 1);
<li id="list_<?= $page['id'];?>" idk="<?= $page['id'];?>" class="list_<?= $page['id'];?>" menu="<?= $page['menu_id'];?>">
<div class="content"> if (empty($pages)) {
<div class="menu-box-title"> return;
}
?>
<ol>
<?php foreach ($pages as $page): ?>
<?php
$pageId = (int)($page['id'] ?? 0);
$menuId = (int)($page['menu_id'] ?? 0);
$title = (string)($page['title'] ?? '');
$status = (int)($page['status'] ?? 0);
$start = (int)($page['start'] ?? 0);
$languages = is_array($page['languages'] ?? null) ? $page['languages'] : [];
?>
<li id="list_<?= $pageId; ?>" class="list_<?= $pageId; ?>" menu="<?= $menuId; ?>">
<div class="content">
<div class="menu-box-title">
<span class="disclose"><span></span></span> <span class="disclose"><span></span></span>
<? if ( !$page['status'] ) echo '<i class="fa fa-ban fa-lg text-danger" title="Strona nieaktywna"></i>';?> <?php if ($status !== 1): ?><i class="fa fa-ban fa-lg text-danger" title="Strona nieaktywna"></i><?php endif; ?>
<? if ( $page['start'] ) echo '<i class="fa fa-star fa-lg text-system" title="Strona startowa"></i>';?> <?php if ($start === 1): ?><i class="fa fa-star fa-lg text-system" title="Strona startowa"></i><?php endif; ?>
<?= $page['title'];?> <?= htmlspecialchars($title, ENT_QUOTES, 'UTF-8'); ?>
<?
if ( is_array( $page['languages'] ) ): <?php if (!empty($languages)): ?>
echo '<div class="btn-group flags" style="display: inline-block;">'; <div class="btn-group flags" style="display: inline-block;">
foreach ( $page['languages'] as $lg ) <?php foreach ($languages as $language): ?>
echo '<img src="/admin/layout/lang-' . $lg['lang_id'] . '.jpg" />'; <?php $langId = (string)($language['lang_id'] ?? ''); ?>
echo '</div>'; <?php if ($langId !== ''): ?>
endif; <img src="/admin/layout/lang-<?= htmlspecialchars($langId, ENT_QUOTES, 'UTF-8'); ?>.jpg" />
?> <?php endif; ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div> </div>
<? if ( $this -> step < 3 ):?> <?php if ($step < 3): ?>
<div class="btn-group ml20 pull-right"> <div class="btn-group ml20 pull-right">
<a href="/admin/pages/page_edit/id=<?= $page['id'];?>&menu_id=<?= $page['menu_id'];?>" title="Edytuj stronę" class="btn btn-sm btn-system"> <a href="/admin/pages/edit/id=<?= $pageId; ?>&menu_id=<?= $menuId; ?>" title="Edytuj stron&#281;" class="btn btn-sm btn-system">
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj stronę</span> <i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj stron&#281;</span>
</a> </a>
<a href="#" title="Usuń stronę" class="btn btn-sm btn-danger page-delete" page-id="<?= $page['id'];?>"> <a href="#" title="Usu&#324; stron&#281;" class="btn btn-sm btn-danger page-delete" page-id="<?= $pageId; ?>">
<i class="fa fa-trash"></i> <span class="hidden-xs">Usuń stronę</span> <i class="fa fa-trash"></i> <span class="hidden-xs">Usu&#324; stron&#281;</span>
</a> </a>
<a href="/admin/pages/page_articles/id=<?= $page['id'];?>" title="Lista artykułów" class="btn btn-sm btn-info" page-id="<?= $page['id'];?>"> <a href="/admin/pages/pageArticles/id=<?= $pageId; ?>" title="Lista artyku&#322;&#243;w" class="btn btn-sm btn-info" page-id="<?= $pageId; ?>">
<i class="fa fa-bars"></i> <span class="hidden-xs">Lista artykułów</span> <i class="fa fa-bars"></i> <span class="hidden-xs">Lista artyku&#322;&#243;w</span>
</a> </a>
<a href="/admin/pages/page_edit/pid=<?= $page['id'];?>&menu_id=<?= $page['menu_id'];?>" title="Dodaj podstronę" class="btn btn-sm btn-success"> <a href="/admin/pages/edit/pid=<?= $pageId; ?>&menu_id=<?= $menuId; ?>" title="Dodaj podstron&#281;" class="btn btn-sm btn-success">
<i class="fa fa-plus-circle"></i> <span class="hidden-xs">Dodaj podstronę</span> <i class="fa fa-plus-circle"></i> <span class="hidden-xs">Dodaj podstron&#281;</span>
</a> </a>
</div> </div>
<? else:?> <?php else: ?>
<div class="btn-group ml20 pull-right"> <div class="btn-group ml20 pull-right">
<a href="/admin/pages/page_edit/id=<?= $page['id'];?>&menu_id=<?= $page['menu_id'];?>" title="Edytuj stronę" class="btn btn-sm btn-system"> <a href="/admin/pages/edit/id=<?= $pageId; ?>&menu_id=<?= $menuId; ?>" title="Edytuj stron&#281;" class="btn btn-sm btn-system">
<i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj stronę</span> <i class="fa fa-file-text"></i> <span class="hidden-xs">Edytuj stron&#281;</span>
</a> </a>
<a href="#" title="Usuń stronę" class="btn btn-sm btn-danger page-delete" page-id="<?= $page['id'];?>"> <a href="#" title="Usu&#324; stron&#281;" class="btn btn-sm btn-danger page-delete" page-id="<?= $pageId; ?>">
<i class="fa fa-trash"></i> <span class="hidden-xs">Usuń stronę</span> <i class="fa fa-trash"></i> <span class="hidden-xs">Usu&#324; stron&#281;</span>
</a> </a>
<a href="/admin/pages/page_articles/id=<?= $page['id'];?>" title="Lista artykułów" class="btn btn-sm btn-info" page-id="<?= $page['id'];?>"> <a href="/admin/pages/pageArticles/id=<?= $pageId; ?>" title="Lista artyku&#322;&#243;w" class="btn btn-sm btn-info" page-id="<?= $pageId; ?>">
<i class="fa fa-bars"></i> <span class="hidden-xs">Lista artykułów</span> <i class="fa fa-bars"></i> <span class="hidden-xs">Lista artyku&#322;&#243;w</span>
</a> </a>
</div> </div>
<? endif;?> <?php endif; ?>
</div> </div>
<?= \Tpl::view( 'pages/subpages-list', [ <?= \Tpl::view('pages/subpages-list', [
'pages' => \admin\factory\Pages::menu_pages( $this -> menu_id, $page['id'] ), 'pages' => $page['subpages'] ?? [],
'menu_id' => $this -> menu_id, 'step' => $step + 1,
'parent_id' => $page['id'], ]); ?>
'step' => $this -> step + 1 </li>
] ); <?php endforeach; ?>
?> </ol>
</li>
<? endforeach;?>
</ol>
<? endif;?>

View File

@@ -361,7 +361,7 @@ $grid -> gdb_opt = $gdb;
$grid -> include_plugins = true; $grid -> include_plugins = true;
$grid -> title = 'Edycja ustawień'; $grid -> title = 'Edycja ustawień';
$grid -> actions = [ $grid -> actions = [
'save' => [ 'url' => '/admin/settings/settings_save/', 'back_url' => '' ], 'save' => [ 'url' => '/admin/settings/save/', 'back_url' => '' ],
]; ];
$grid -> persist_edit = true; $grid -> persist_edit = true;
$grid -> external_code = $out; $grid -> external_code = $out;
@@ -378,4 +378,4 @@ echo $grid -> draw();
html: true html: true
}); });
}); });
</script> </script>

View File

@@ -36,9 +36,8 @@
{ {
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/generateSeoLink/',
data: { data: {
a: 'generate_seo_link',
title: title, title: title,
category_id: category_id category_id: category_id
}, },
@@ -67,7 +66,7 @@ ob_start();
?> ?>
<div id="settings-tabs"> <div id="settings-tabs">
<ul class="resp-tabs-list settings-tabs"> <ul class="resp-tabs-list settings-tabs">
<li><i class="fa fa-file"></i>Treść</li> <li><i class="fa fa-file"></i>Treść</li>
<li><i class="fa fa-wrench"></i>Ustawienia</li> <li><i class="fa fa-wrench"></i>Ustawienia</li>
<li><i class="fa fa-globe"></i>SEO</li> <li><i class="fa fa-globe"></i>SEO</li>
</ul> </ul>
@@ -77,7 +76,7 @@ ob_start();
<ul class="resp-tabs-list languages-main htabs"> <ul class="resp-tabs-list languages-main htabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?> <? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?> <? 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'];?></a></li>
<? endif;?> <? endif;?>
<? endforeach; endif;?> <? endforeach; endif;?>
</ul> </ul>
@@ -105,7 +104,7 @@ ob_start();
);?> );?>
<?= \Html::textarea( <?= \Html::textarea(
array( array(
'label' => 'Opis kategorii (rozwinięcie)', 'label' => 'Opis kategorii (rozwiniÄ™cie)',
'name' => 'text_hidden[' . $lg['id'] . ']', 'name' => 'text_hidden[' . $lg['id'] . ']',
'id' => 'text_hidden_' . $lg['id'], 'id' => 'text_hidden_' . $lg['id'],
'value' => $this -> category['languages'][ $lg['id'] ]['text_hidden'], 'value' => $this -> category['languages'][ $lg['id'] ]['text_hidden'],
@@ -144,7 +143,7 @@ ob_start();
);?> );?>
<?= \Html::select( <?= \Html::select(
[ [
'label' => 'Sortowanie produktów', 'label' => 'Sortowanie produktĂłw',
'name' => 'sort_type', 'name' => 'sort_type',
'id' => 'sort_type', 'id' => 'sort_type',
'values' => \admin\factory\ShopCategory::$_sort_types, 'values' => \admin\factory\ShopCategory::$_sort_types,
@@ -153,7 +152,7 @@ ob_start();
);?> );?>
<?= \Html::input_switch( <?= \Html::input_switch(
array( array(
'label' => 'Wyświetlić podkategorie', 'label' => 'WyĹ›wietlić podkategorie',
'name' => 'view_subcategories', 'name' => 'view_subcategories',
'checked' => $this -> category['view_subcategories'] == 1 ? true : false 'checked' => $this -> category['view_subcategories'] == 1 ? true : false
) )
@@ -164,7 +163,7 @@ ob_start();
<ul class="resp-tabs-list languages-seo htabs"> <ul class="resp-tabs-list languages-seo htabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?> <? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ( $lg['status'] ):?> <? 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'];?></a></li>
<? endif;?> <? endif;?>
<? endforeach; endif;?> <? endforeach; endif;?>
</ul> </ul>
@@ -184,7 +183,7 @@ ob_start();
);?> );?>
<?= \Html::input( <?= \Html::input(
array( array(
'label' => 'Tytuł kategorii (h1)', 'label' => 'TytuĹ‚ kategorii (h1)',
'name' => 'category_title[' . $lg['id'] . ']', 'name' => 'category_title[' . $lg['id'] . ']',
'id' => 'category_title_' . $lg['id'], 'id' => 'category_title_' . $lg['id'],
'value' => $this -> category['languages' ][ $lg['id'] ]['category_title'] 'value' => $this -> category['languages' ][ $lg['id'] ]['category_title']
@@ -216,7 +215,7 @@ ob_start();
);?> );?>
<?= \Html::select( <?= \Html::select(
array( array(
'label' => 'Blokuj indeksację', 'label' => 'Blokuj indeksacjÄ™',
'name' => 'noindex[' . $lg['id'] . ']', 'name' => 'noindex[' . $lg['id'] . ']',
'id' => 'noindex_' . $lg['id'], 'id' => 'noindex_' . $lg['id'],
'values' => array( 'values' => array(
@@ -263,4 +262,5 @@ $grid -> persist_edit = true;
$grid -> id_param = 'id'; $grid -> id_param = 'id';
echo $grid -> draw(); echo $grid -> draw();
?> ?>

View File

@@ -21,15 +21,15 @@ ob_start();
<div id="settings-tabs"> <div id="settings-tabs">
<ul class="resp-tabs-list settings-tabs"> <ul class="resp-tabs-list settings-tabs">
<li><i class="fa fa-file"></i>Opis</li> <li><i class="fa fa-file"></i>Opis</li>
<li><i class="fa fa-file"></i>Zakładki</li> <li><i class="fa fa-file"></i>ZakĹ‚adki</li>
<li><i class="fa fa-dollar"></i>Cena</li> <li><i class="fa fa-dollar"></i>Cena</li>
<li><i class="fa fa-home"></i>Magazyn</li> <li><i class="fa fa-home"></i>Magazyn</li>
<li><i class="fa fa-wrench"></i>Ustawienia</li> <li><i class="fa fa-wrench"></i>Ustawienia</li>
<li><i class="fa fa-globe"></i>SEO</li> <li><i class="fa fa-globe"></i>SEO</li>
<li><i class="fa fa-share-alt"></i>Wyświetlanie</li> <li><i class="fa fa-share-alt"></i>WyĹ›wietlanie</li>
<li><i class="fa fa-file-image-o"></i>Galeria</li> <li><i class="fa fa-file-image-o"></i>Galeria</li>
<li><i class="fa fa-file-archive-o"></i>Załączniki</li> <li><i class="fa fa-file-archive-o"></i>Załączniki</li>
<li><i class="fa fa-exchange"></i>Produkty powiązane</li> <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-excel-o"></i>XML</li>
<li><i class="fa fa-file-o"></i>Dodatkowe pola</li> <li><i class="fa fa-file-o"></i>Dodatkowe pola</li>
<li><i class="fa fa-file-o"></i>GPSR</li> <li><i class="fa fa-file-o"></i>GPSR</li>
@@ -40,7 +40,7 @@ ob_start();
<ul class="resp-tabs-list languages-main htabs"> <ul class="resp-tabs-list languages-main htabs">
<? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?> <? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?>
<? if ($lg['status']) : ?> <? 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']; ?></a></li>
<? endif; ?> <? endif; ?>
<? <?
endforeach; endforeach;
@@ -52,7 +52,7 @@ ob_start();
<? <?
$languages = array(); $languages = array();
$languages[''] = '---- wersja językowa ----'; $languages[''] = '---- wersja jÄ™zykowa ----';
if (is_array($this->languages)) if (is_array($this->languages))
foreach ($this->languages as $lg_tmp) foreach ($this->languages as $lg_tmp)
{ {
@@ -65,7 +65,7 @@ ob_start();
<?= <?=
\Html::select( \Html::select(
array( array(
'label' => 'Wyświetlaj treść z wersji', 'label' => 'WyĹ›wietlaj treść z wersji',
'name' => 'copy_from[' . $lg['id'] . ']', 'name' => 'copy_from[' . $lg['id'] . ']',
'values' => $languages, 'values' => $languages,
'value' => $this->product['languages'][$lg['id']]['copy_from'], 'value' => $this->product['languages'][$lg['id']]['copy_from'],
@@ -86,7 +86,7 @@ ob_start();
<?= <?=
\Html::input( \Html::input(
array( array(
'label' => 'Komunikat gdy stan magazynowy równy 0', 'label' => 'Komunikat gdy stan magazynowy rĂłwny 0',
'name' => 'warehouse_message_zero[' . $lg['id'] . ']', 'name' => 'warehouse_message_zero[' . $lg['id'] . ']',
'id' => 'warehouse_message_zero_' . $lg['id'], 'id' => 'warehouse_message_zero_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['warehouse_message_zero'], 'value' => $this->product['languages'][$lg['id']]['warehouse_message_zero'],
@@ -97,7 +97,7 @@ ob_start();
<?= <?=
\Html::input( \Html::input(
array( array(
'label' => 'Komunikat gdy stan magazynowy większy niż 0', 'label' => 'Komunikat gdy stan magazynowy wiÄ™kszy niĹĽ 0',
'name' => 'warehouse_message_nonzero[' . $lg['id'] . ']', 'name' => 'warehouse_message_nonzero[' . $lg['id'] . ']',
'id' => 'warehouse_message_nonzero_' . $lg['id'], 'id' => 'warehouse_message_nonzero_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['warehouse_message_nonzero'], 'value' => $this->product['languages'][$lg['id']]['warehouse_message_nonzero'],
@@ -108,7 +108,7 @@ ob_start();
<?= <?=
\Html::textarea( \Html::textarea(
array( array(
'label' => 'Krótki opis', 'label' => 'KrĂłtki opis',
'name' => 'short_description[' . $lg['id'] . ']', 'name' => 'short_description[' . $lg['id'] . ']',
'id' => 'short_description_' . $lg['id'], 'id' => 'short_description_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['short_description'], 'value' => $this->product['languages'][$lg['id']]['short_description'],
@@ -154,7 +154,7 @@ ob_start();
<ul class="resp-tabs-list languages-tabs htabs"> <ul class="resp-tabs-list languages-tabs htabs">
<? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?> <? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?>
<? if ($lg['status']) : ?> <? 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']; ?></a></li>
<? endif; ?> <? endif; ?>
<? <?
endforeach; endforeach;
@@ -166,7 +166,7 @@ ob_start();
<? <?
$languages = array(); $languages = array();
$languages[''] = '---- wersja językowa ----'; $languages[''] = '---- wersja jÄ™zykowa ----';
if (is_array($this->languages)) if (is_array($this->languages))
foreach ($this->languages as $lg_tmp) foreach ($this->languages as $lg_tmp)
{ {
@@ -179,7 +179,7 @@ ob_start();
<?= <?=
\Html::input( \Html::input(
array( array(
'label' => 'Nazwa zakładki (1)', 'label' => 'Nazwa zakĹ‚adki (1)',
'name' => 'tab_name_1[' . $lg['id'] . ']', 'name' => 'tab_name_1[' . $lg['id'] . ']',
'id' => 'tab_name_1_' . $lg['id'], 'id' => 'tab_name_1_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['tab_name_1'], 'value' => $this->product['languages'][$lg['id']]['tab_name_1'],
@@ -190,7 +190,7 @@ ob_start();
<?= <?=
\Html::textarea( \Html::textarea(
array( array(
'label' => 'Zawartość zakładki (1)', 'label' => 'Zawartość zakĹ‚adki (1)',
'name' => 'tab_description_1[' . $lg['id'] . ']', 'name' => 'tab_description_1[' . $lg['id'] . ']',
'id' => 'tab_description_1_' . $lg['id'], 'id' => 'tab_description_1_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['tab_description_1'], 'value' => $this->product['languages'][$lg['id']]['tab_description_1'],
@@ -201,7 +201,7 @@ ob_start();
<?= <?=
\Html::input( \Html::input(
array( array(
'label' => 'Nazwa zakładki (2)', 'label' => 'Nazwa zakĹ‚adki (2)',
'name' => 'tab_name_2[' . $lg['id'] . ']', 'name' => 'tab_name_2[' . $lg['id'] . ']',
'id' => 'tab_name_2_' . $lg['id'], 'id' => 'tab_name_2_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['tab_name_2'], 'value' => $this->product['languages'][$lg['id']]['tab_name_2'],
@@ -212,7 +212,7 @@ ob_start();
<?= <?=
\Html::textarea( \Html::textarea(
array( array(
'label' => 'Zawartość zakładki (2)', 'label' => 'Zawartość zakĹ‚adki (2)',
'name' => 'tab_description_2[' . $lg['id'] . ']', 'name' => 'tab_description_2[' . $lg['id'] . ']',
'id' => 'tab_description_2_' . $lg['id'], 'id' => 'tab_description_2_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['tab_description_2'], 'value' => $this->product['languages'][$lg['id']]['tab_description_2'],
@@ -305,7 +305,7 @@ ob_start();
?> ?>
<? <?
$units[] = '--- wybierze jednostkę miary ---'; $units[] = '--- wybierze jednostkÄ™ miary ---';
foreach ($this->units as $unit) foreach ($this->units as $unit)
$units[$unit['id']] = $unit['text']; $units[$unit['id']] = $unit['text'];
?> ?>
@@ -317,7 +317,7 @@ ob_start();
'value' => $this->product['product_unit_id'] 'value' => $this->product['product_unit_id']
]); ?> ]); ?>
<?= \Html::input([ <?= \Html::input([
'label' => 'Waga/pojemność', 'label' => 'Waga/pojemność',
'name' => 'weight', 'name' => 'weight',
'id' => 'weight', 'id' => 'weight',
'class' => 'number-format', 'class' => 'number-format',
@@ -336,14 +336,14 @@ ob_start();
?> ?>
<?= <?=
\Html::input_switch([ \Html::input_switch([
'label' => 'Pozwól zamawiać gdy stan 0', 'label' => 'PozwĂłl zamawiać gdy stan 0',
'name' => 'stock_0_buy', 'name' => 'stock_0_buy',
'checked' => $this->product['stock_0_buy'] == 1 ? true : false 'checked' => $this->product['stock_0_buy'] == 1 ? true : false
]); ]);
?> ?>
<?= <?=
\Html::input([ \Html::input([
'label' => 'Współczynnik WP', 'label' => 'Współczynnik WP',
'name' => 'wp', 'name' => 'wp',
'id' => 'wp', 'id' => 'wp',
'class' => 'number-format', 'class' => 'number-format',
@@ -382,7 +382,7 @@ ob_start();
?> ?>
<?= <?=
\Html::input([ \Html::input([
'label' => 'Nowość do dnia', 'label' => 'Nowość do dnia',
'name' => 'new_to_date', 'name' => 'new_to_date',
'id' => 'new_to_date', 'id' => 'new_to_date',
'class' => 'date', 'class' => 'date',
@@ -390,19 +390,19 @@ ob_start();
]); ]);
?> ?>
<?= \Html::input_switch([ <?= \Html::input_switch([
'label' => 'Wyświetlaj pole na dodatkową wiadomość', 'label' => 'WyĹ›wietlaj pole na dodatkowÄ… wiadomość',
'name' => 'additional_message', 'name' => 'additional_message',
'checked' => $this->product['additional_message'] == 1 ? true : false 'checked' => $this->product['additional_message'] == 1 ? true : false
]); ]);
?> ?>
<?= \Html::input_switch([ <?= \Html::input_switch([
'label' => 'Dodatkowa wiadomość jest wymagana', 'label' => 'Dodatkowa wiadomość jest wymagana',
'name' => 'additional_message_required', 'name' => 'additional_message_required',
'checked' => $this->product['additional_message_required'] == 1 ? true : false 'checked' => $this->product['additional_message_required'] == 1 ? true : false
]); ]);
?> ?>
<?= \Html::input([ <?= \Html::input([
'label' => 'Dodatkowa wiadomość (treść komunikatu)', 'label' => 'Dodatkowa wiadomość (treść komunikatu)',
'name' => 'additional_message_text', 'name' => 'additional_message_text',
'id' => 'additional_message_text', 'id' => 'additional_message_text',
'value' => $this->product['additional_message_text'] 'value' => $this->product['additional_message_text']
@@ -414,7 +414,7 @@ ob_start();
<ul class="resp-tabs-list languages-seo htabs"> <ul class="resp-tabs-list languages-seo htabs">
<? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?> <? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?>
<? if ($lg['status']) : ?> <? 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> <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; ?> <? endif; ?>
<? <?
endforeach; endforeach;
@@ -481,7 +481,7 @@ ob_start();
</div> </div>
<div> <div>
<? <?
$layouts[''] = '---- szablon domyślny ----'; $layouts[''] = '---- szablon domyĹ›lny ----';
if (is_array($this->layouts)) : foreach ($this->layouts as $layout) : if (is_array($this->layouts)) : foreach ($this->layouts as $layout) :
$layouts[$layout['id']] = $layout['name']; $layouts[$layout['id']] = $layout['name'];
endforeach; endforeach;
@@ -497,7 +497,7 @@ ob_start();
]); ]);
?> ?>
<div class="form-group row"> <div class="form-group row">
<label class="col-md-4 control-label">Wyświetlaj w:</label> <label class="col-md-4 control-label">WyĹ›wietlaj w:</label>
<div class="col-md-8"> <div class="col-md-8">
<div class="menu_sortable"> <div class="menu_sortable">
<ol class="sortable" id="sortable"> <ol class="sortable" id="sortable">
@@ -580,7 +580,7 @@ ob_start();
</div> </div>
<div> <div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-4 control-label">Wybierz zdefiniowany komplet produktów:</label> <label class="col-lg-4 control-label">Wybierz zdefiniowany komplet produktĂłw:</label>
<div class="col-lg-8"> <div class="col-lg-8">
<select id="set" class="form-control" name="set"> <select id="set" class="form-control" name="set">
<option value="">wybierz komplet...</option> <option value="">wybierz komplet...</option>
@@ -591,9 +591,9 @@ ob_start();
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-4 control-label">Produkty powiązane:</label> <label class="col-lg-4 control-label">Produkty powiÄ…zane:</label>
<div class="col-lg-8"> <div class="col-lg-8">
<select id="products_related" multiple name="products_related[]" placeholder="produkty powiązane"> <select id="products_related" multiple name="products_related[]" placeholder="produkty powiÄ…zane">
<option value="">wybierz produkt...</option> <option value="">wybierz produkt...</option>
<? foreach ($this->products as $key => $val) : ?> <? foreach ($this->products as $key => $val) : ?>
<? if ($key != $this->product['id']) : ?> <? if ($key != $this->product['id']) : ?>
@@ -622,7 +622,7 @@ ob_start();
<? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?> <? if (is_array($this->languages)) : foreach ($this->languages as $lg) : ?>
<? if ($lg['status']) : ?> <? if ($lg['status']) : ?>
<div id="xml_name_<?= $this->i; ?>_<?= $lg['id']; ?>" class="tab-pane <? if (!$z++) : ?>active<? endif; ?>"> <div id="xml_name_<?= $this->i; ?>_<?= $lg['id']; ?>" class="tab-pane <? if (!$z++) : ?>active<? endif; ?>">
<label class="col-lg-4 control-label">Nazwa produktu XML (150 znaków):</label> <label class="col-lg-4 control-label">Nazwa produktu XML (150 znakĂłw):</label>
<div class="col-lg-8"> <div class="col-lg-8">
<input type="text" class="form-control" name="xml_name[<?= $lg['id']; ?>]" value="<?= $this->product['languages'][$lg['id']]['xml_name']; ?>"> <input type="text" class="form-control" name="xml_name[<?= $lg['id']; ?>]" value="<?= $this->product['languages'][$lg['id']]['xml_name']; ?>">
</div> </div>
@@ -700,7 +700,7 @@ ob_start();
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-sm-12 text-right"> <div class="col-sm-12 text-right">
<span class="input-group-addon btn btn-info" onclick="remove_custom_filed( $( this ) );">usuń</span> <span class="input-group-addon btn btn-info" onclick="remove_custom_filed( $( this ) );">usuĹ„</span>
</div> </div>
</div> </div>
</div> </div>
@@ -724,7 +724,7 @@ ob_start();
<ul class="resp-tabs-list gpsr-seo htabs"> <ul class="resp-tabs-list gpsr-seo htabs">
<? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?> <? if ( is_array( $this -> languages ) ): foreach ( $this -> languages as $lg ):?>
<? if ($lg['status']) : ?> <? 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> <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; ?> <? endif; ?>
<? endforeach; endif; ?> <? endforeach; endif; ?>
</ul> </ul>
@@ -733,7 +733,7 @@ ob_start();
<? if ( $lg['status'] ):?> <? if ( $lg['status'] ):?>
<div> <div>
<?= \Html::textarea( [ <?= \Html::textarea( [
'label' => 'Informacje o bezpieczeństwie ('.$lg['name'].')', 'label' => 'Informacje o bezpieczeĹ„stwie ('.$lg['name'].')',
'name' => 'security_information[' . $lg['id'] . ']', 'name' => 'security_information[' . $lg['id'] . ']',
'id' => 'security_information_' . $lg['id'], 'id' => 'security_information_' . $lg['id'],
'value' => $this->product['languages'][$lg['id']]['security_information'] 'value' => $this->product['languages'][$lg['id']]['security_information']
@@ -776,7 +776,7 @@ $grid->actions = [
]; ];
$grid->buttons = [ $grid->buttons = [
[ [
'label' => 'Podgląd', 'label' => 'PodglÄ…d',
'id' => 'product-preview', 'id' => 'product-preview',
'url' => '#', 'url' => '#',
'icon' => 'fa-search', 'icon' => 'fa-search',
@@ -845,7 +845,7 @@ echo $grid->draw();
html += '</div>'; html += '</div>';
html += '<div class="form-group row">'; html += '<div class="form-group row">';
html += '<div class="col-sm-12 text-right">'; html += '<div class="col-sm-12 text-right">';
html += '<span class="input-group-addon btn btn-info" onclick="remove_custom_filed( $( this ) );">usuń</span>'; html += '<span class="input-group-addon btn btn-info" onclick="remove_custom_filed( $( this ) );">usuĹ„</span>';
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
html += '</div>'; html += '</div>';
@@ -1138,8 +1138,8 @@ echo $grid->draw();
$(this).blur(); $(this).blur();
var file_id = $(this).attr('file_id'); var file_id = $(this).attr('file_id');
$.prompt('Na pewno chcesz usunąć wybrany plik?', { $.prompt('Na pewno chcesz usunąć wybrany plik?', {
title: 'Potwierdź?', title: 'PotwierdĹş?',
submit: function(e, v, m, f) { submit: function(e, v, m, f) {
if (v === true) { if (v === true) {
$.ajax({ $.ajax({
@@ -1178,8 +1178,8 @@ echo $grid->draw();
$(this).blur(); $(this).blur();
var image_id = $(this).attr('image-id'); var image_id = $(this).attr('image-id');
$.prompt('Na pewno chcesz usunąć wybrane zdjęcie?', { $.prompt('Na pewno chcesz usunąć wybrane zdjÄ™cie?', {
title: 'Potwierdź?', title: 'PotwierdĹş?',
submit: function(e, v, m, f) { submit: function(e, v, m, f) {
if (v === true) { if (v === true) {
$.ajax({ $.ajax({
@@ -1316,9 +1316,8 @@ echo $grid->draw();
$.ajax({ $.ajax({
type: 'POST', type: 'POST',
cache: false, cache: false,
url: '/admin/ajax.php', url: '/admin/pages/generateSeoLink/',
data: { data: {
a: 'generate_seo_link',
title: title, title: title,
article_id: article_id article_id: article_id
}, },
@@ -1346,3 +1345,4 @@ echo $grid->draw();
<script> <script>
CKEDITOR.dtd.$removeEmpty['span'] = false; CKEDITOR.dtd.$removeEmpty['span'] = false;
</script> </script>

View File

@@ -6,7 +6,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="author" content="www.project-pro.pl - internetowe rozwiązania dla biznesu"> <meta name="author" content="www.project-pro.pl - internetowe rozwi&#261;zania dla biznesu">
<link rel='stylesheet' type="text/css" href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700'> <link rel='stylesheet' type="text/css" href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700'>
<link rel="stylesheet" type="text/css" href="/libraries/framework/skin/default_skin/css/theme.css"> <link rel="stylesheet" type="text/css" href="/libraries/framework/skin/default_skin/css/theme.css">
<link rel="stylesheet" type="text/css" href="/libraries/framework/vendor/plugins/magnific/magnific-popup.css"> <link rel="stylesheet" type="text/css" href="/libraries/framework/vendor/plugins/magnific/magnific-popup.css">
@@ -54,7 +54,7 @@
Sklep Sklep
</div> </div>
<ul> <ul>
<li> <a href="/admin/shop_order/view_list/"><img src="/admin/layout/icon/icon-menu/shopping-cart.svg">Zamówienia</a></li> <li> <a href="/admin/shop_order/view_list/"><img src="/admin/layout/icon/icon-menu/shopping-cart.svg">Zam&#243;wienia</a></li>
<li> <a href="/admin/shop_clients/view_list/"><img src="/admin/layout/icon/icon-menu/people-fill.svg">Klienci</a></li> <li> <a href="/admin/shop_clients/view_list/"><img src="/admin/layout/icon/icon-menu/people-fill.svg">Klienci</a></li>
<li><a href="/admin/shop_category/view_list/"><img src="/admin/layout/icon/icon-menu/bxs-category-alt.svg">Kategorie</a></li> <li><a href="/admin/shop_category/view_list/"><img src="/admin/layout/icon/icon-menu/bxs-category-alt.svg">Kategorie</a></li>
<li><a href="/admin/shop_product/view_list/"><img src="/admin/layout/icon/icon-menu/shopping-basket.svg">Produkty</a></li> <li><a href="/admin/shop_product/view_list/"><img src="/admin/layout/icon/icon-menu/shopping-basket.svg">Produkty</a></li>
@@ -66,24 +66,24 @@
</li> </li>
<li> <li>
<a href="/admin/shop_product_sets/view_list/"> <a href="/admin/shop_product_sets/view_list/">
<i class="fa fa-bars"></i>Komplety Produktów <i class="fa fa-bars"></i>Komplety Produkt&#243;w
</a> </a>
</li> </li>
<li><a href="/admin/shop_attribute/view_list/"><img src="/admin/layout/icon/icon-menu/star-filled.svg">Cechy produktów</a></li> <li><a href="/admin/shop_attribute/view_list/"><img src="/admin/layout/icon/icon-menu/star-filled.svg">Cechy produkt&#243;w</a></li>
<li><a href="/admin/shop_transport/view_list/"><img src="/admin/layout/icon/icon-menu/bus.svg">Rodzaje transportu</a></li> <li><a href="/admin/shop_transport/view_list/"><img src="/admin/layout/icon/icon-menu/bus.svg">Rodzaje transportu</a></li>
<li><a href="/admin/shop_payment_method/view_list/"><img src="/admin/layout/icon/icon-menu/coins-fill.svg">Metody płatności</a></li> <li><a href="/admin/shop_payment_method/view_list/"><img src="/admin/layout/icon/icon-menu/coins-fill.svg">Metody p&#322;atno&#347;ci</a></li>
<li> <li>
<a href="/admin/shop_statuses/view_list/"><i class="fa fa-bars"></i>Statusy zamówień</a> <a href="/admin/shop_statuses/view_list/"><i class="fa fa-bars"></i>Statusy zam&#243;wie&#324;</a>
</li> </li>
<li><a href="/admin/shop_coupon/view_list/"><img src="/admin/layout/icon/icon-menu/piggy-bank-coins.svg">Kody rabatowe</a></li> <li><a href="/admin/shop_coupon/view_list/"><img src="/admin/layout/icon/icon-menu/piggy-bank-coins.svg">Kody rabatowe</a></li>
<li><a href="/admin/shop_promotion/view_list/"><img src="/admin/layout/icon/icon-menu/burst-sale.svg">Promocje</a></li> <li><a href="/admin/shop_promotion/view_list/"><img src="/admin/layout/icon/icon-menu/burst-sale.svg">Promocje</a></li>
</ul> </ul>
<div class="title">Zawartość</div> <div class="title">Zawarto&#347;&#263;</div>
<ul> <ul>
<li><a href="/admin/pages/view_list/"><img src="/admin/layout/icon/icon-menu/menu(1).svg">Konfiguracja menu</a></li> <li><a href="/admin/pages/list/"><img src="/admin/layout/icon/icon-menu/menu(1).svg">Konfiguracja menu</a></li>
<li><a href="/admin/articles/view_list/"><img src="/admin/layout/icon/icon-menu/note.svg">Artykuły</a></li> <li><a href="/admin/articles/list/"><img src="/admin/layout/icon/icon-menu/note.svg">Artyku&#322;y</a></li>
<li><a href="/admin/articles_archive/view_list/"><img src="/admin/layout/icon/icon-menu/baseline-sticky-note-2.svg">Archiwum artykułów</a></li> <li><a href="/admin/articles_archive/list/"><img src="/admin/layout/icon/icon-menu/baseline-sticky-note-2.svg">Archiwum artyku&#322;&#243;w</a></li>
<li><a href="/admin/scontainers/view_list/"><img src="/admin/layout/icon/icon-menu/view-cols.svg">Zawartość statyczna</a></li> <li><a href="/admin/scontainers/list/"><img src="/admin/layout/icon/icon-menu/view-cols.svg">Zawarto&#347;&#263; statyczna</a></li>
</ul> </ul>
<div class="title"> <div class="title">
Newsletter Newsletter
@@ -94,28 +94,28 @@
<li><a href="/admin/newsletter/settings/"><img src="/admin/layout/icon/icon-menu/baseline-settings.svg">Ustawienia</a></li> <li><a href="/admin/newsletter/settings/"><img src="/admin/layout/icon/icon-menu/baseline-settings.svg">Ustawienia</a></li>
</ul> </ul>
<div class="title"> <div class="title">
Pozostałe Pozosta&#322;e
</div> </div>
<ul> <ul>
<li><a href="/admin/filemanager/draw/"><img src="/admin/layout/icon/icon-menu/file-image-outlined.svg">Manadżer plików</a></li> <li><a href="/admin/filemanager/draw/"><img src="/admin/layout/icon/icon-menu/file-image-outlined.svg">Menad&#380;er plik&#243;w</a></li>
<li><a href="/admin/banners/view_list/"><img src="/admin/layout/icon/icon-menu/photo-video.svg">Banery</a></li> <li><a href="/admin/banners/list/"><img src="/admin/layout/icon/icon-menu/photo-video.svg">Banery</a></li>
</ul> </ul>
<div class="title"> <div class="title">
Konfiguracja Konfiguracja
</div> </div>
<ul> <ul>
<li><a href="/admin/users/view_list/"><img src="/admin/layout/icon/icon-menu/people-fill.svg">Użytkownicy</a></li> <li><a href="/admin/users/view_list/"><img src="/admin/layout/icon/icon-menu/people-fill.svg">U&#380;ytkownicy</a></li>
<li><a href="/admin/languages/view_list/"><img src="/admin/layout/icon/icon-menu/letter-aa.svg">Jęzki</a></li> <li><a href="/admin/languages/view_list/"><img src="/admin/layout/icon/icon-menu/letter-aa.svg">J&#281;zyki</a></li>
<li><a href="/admin/languages/translation_list/"><img src="/admin/layout/icon/icon-menu/language.svg">Tłumaczenia</a></li> <li><a href="/admin/languages/translation_list/"><img src="/admin/layout/icon/icon-menu/language.svg">T&#322;umaczenia</a></li>
<li><a href="/admin/settings/view/"><img src="/admin/layout/icon/icon-menu/baseline-settings.svg">Ustawienia</a></li> <li><a href="/admin/settings/view/"><img src="/admin/layout/icon/icon-menu/baseline-settings.svg">Ustawienia</a></li>
<li><a href="/admin/layouts/view_list/"><img src="/admin/layout/icon/icon-menu/calendar-settings.svg">Szablony</a></li> <li><a href="/admin/layouts/list/"><img src="/admin/layout/icon/icon-menu/calendar-settings.svg">Szablony</a></li>
</ul> </ul>
<div class="title"> <div class="title">
Słowniki S&#322;owniki
</div> </div>
<ul> <ul>
<li> <li>
<a href="/admin/dictionaries/view_list/"> <a href="/admin/dictionaries/list/">
<i class="fa fa-puzzle-piece" aria-hidden="true"></i>Jednostki miary <i class="fa fa-puzzle-piece" aria-hidden="true"></i>Jednostki miary
</a> </a>
</li> </li>
@@ -125,7 +125,7 @@
</div> </div>
<ul> <ul>
<li> <li>
<a href="/admin/product_archive/products_list/"> <a href="/admin/product_archive/list/">
<i class="fa fa-trash" aria-hidden="true"></i>Produkty <i class="fa fa-trash" aria-hidden="true"></i>Produkty
</a> </a>
</li> </li>
@@ -157,7 +157,7 @@
</ul> </ul>
</div> </div>
<div class="preview"> <div class="preview">
<a href="/" target="_blank"><img src="/admin/layout/icon/icon-menu/chevrons-right.svg">Podgląd</a> <a href="/" target="_blank"><img src="/admin/layout/icon/icon-menu/chevrons-right.svg">Podgl&#261;d</a>
</div> </div>
</div> </div>
<div class="mobile-menu-btn" id="mobile-menu-btn"> <div class="mobile-menu-btn" id="mobile-menu-btn">
@@ -167,7 +167,7 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-12 col-md-3 col-lg-2"> <div class="col-12 col-md-3 col-lg-2">
<button id="clear-cache-btn" class="btn btn-danger mt-3">Wyczyść cache</button> <button id="clear-cache-btn" class="btn btn-danger mt-3">Wyczy&#347;&#263; cache</button>
</div> </div>
<div class="col-12 col-md-9 col-lg-10 top-user"> <div class="col-12 col-md-9 col-lg-10 top-user">
<div class="dropdown"> <div class="dropdown">
@@ -179,7 +179,7 @@
?> ?>
<img src="/admin/layout/icon/user-avatar-filled.svg" alt="avatar" > <img src="/admin/layout/icon/user-avatar-filled.svg" alt="avatar" >
<div class="dropdown-content"> <div class="dropdown-content">
<a href="/admin/?s-action=user-logout"><span class="fa fa-power-off"></span>Wyloguj się</a> <a href="/admin/?s-action=user-logout"><span class="fa fa-power-off"></span>Wyloguj si&#281;</a>
</div> </div>
</div> </div>
</div> </div>
@@ -191,7 +191,7 @@
<div class="row"> <div class="row">
<div class=" col-12"> <div class=" col-12">
<div class="alert alert-danger alert-dismissable"> <div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-info pr10"></i> <i class="fa fa-info pr10"></i>
<?= $alert;?> <?= $alert;?>
</div> </div>
@@ -228,41 +228,41 @@
} }
}); });
// Obsługa przycisku czyszczenia cache // Cache clear button handler
$('#clear-cache-btn').on('click', function(e) { $('#clear-cache-btn').on('click', function(e) {
e.preventDefault(); e.preventDefault();
var $btn = $(this); var $btn = $(this);
var originalText = $btn.text(); var originalText = $btn.text();
// Wyświetl komunikat o czyszczeniu // Show pending state
$btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Czyszczę cache...'); $btn.prop('disabled', true).html('<i class="fa fa-spinner fa-spin"></i> Czyszcz\u0119 cache...');
// Wyślij żądanie AJAX // Send AJAX request
$.ajax({ $.ajax({
url: '/admin/settings/clear_cache_ajax/', url: '/admin/settings/clearCacheAjax/',
type: 'POST', type: 'POST',
dataType: 'json', dataType: 'json',
success: function(response) { success: function(response) {
if (response.status === 'success') { if (response.status === 'success') {
// Zmień komunikat na "wyczyszczono" // Show success state
$btn.html('<i class="fa fa-check"></i> Cache wyczyszczony!').removeClass('btn-danger').addClass('btn-success'); $btn.html('<i class="fa fa-check"></i> Cache wyczyszczony!').removeClass('btn-danger').addClass('btn-success');
// Po 2 sekundach przywróć pierwotny stan // Restore original state after delay
setTimeout(function() { setTimeout(function() {
$btn.prop('disabled', false).html(originalText).removeClass('btn-success').addClass('btn-danger'); $btn.prop('disabled', false).html(originalText).removeClass('btn-success').addClass('btn-danger');
}, 2000); }, 2000);
} else { } else {
// Obsługa błędu // Request failed on server
$btn.html('<i class="fa fa-exclamation-triangle"></i> Błąd!').removeClass('btn-danger').addClass('btn-warning'); $btn.html('<i class="fa fa-exclamation-triangle"></i> B\u0142\u0105d!').removeClass('btn-danger').addClass('btn-warning');
setTimeout(function() { setTimeout(function() {
$btn.prop('disabled', false).html(originalText).removeClass('btn-warning').addClass('btn-danger'); $btn.prop('disabled', false).html(originalText).removeClass('btn-warning').addClass('btn-danger');
}, 2000); }, 2000);
} }
}, },
error: function() { error: function() {
// Obsługa błędu połączenia // Network or transport error
$btn.html('<i class="fa fa-exclamation-triangle"></i> Błąd połączenia!').removeClass('btn-danger').addClass('btn-warning'); $btn.html('<i class="fa fa-exclamation-triangle"></i> B\u0142\u0105d po\u0142\u0105czenia!').removeClass('btn-danger').addClass('btn-warning');
setTimeout(function() { setTimeout(function() {
$btn.prop('disabled', false).html(originalText).removeClass('btn-warning').addClass('btn-danger'); $btn.prop('disabled', false).html(originalText).removeClass('btn-warning').addClass('btn-danger');
}, 2000); }, 2000);

View File

@@ -0,0 +1,626 @@
<?php
namespace Domain\Pages;
class PagesRepository
{
/**
* @var array<int, string>
*/
private const PAGE_TYPES = [
0 => 'pelne artykuly',
1 => 'wprowadzenia',
2 => 'miniaturki',
3 => 'link',
4 => 'kontakt',
5 => 'kategoria sklepu',
];
/**
* @var array<int, string>
*/
private const SORT_TYPES = [
0 => 'data dodania - najstarsze na poczatku',
1 => 'data dodania - najnowsze na poczatku',
2 => 'data modyfikacji - rosnaco',
3 => 'data modyfikacji - malejaco',
4 => 'reczne',
5 => 'alfabetycznie - A - Z',
6 => 'alfabetycznie - Z - A',
];
private $db;
public function __construct($db)
{
$this->db = $db;
}
/**
* @return array<int, string>
*/
public function pageTypes(): array
{
return self::PAGE_TYPES;
}
/**
* @return array<int, string>
*/
public function sortTypes(): array
{
return self::SORT_TYPES;
}
/**
* @return array<int, array<string, mixed>>
*/
public function menusList(): array
{
$rows = $this->db->select('pp_menus', '*', ['ORDER' => ['id' => 'ASC']]);
return is_array($rows) ? $rows : [];
}
/**
* @return array<int, array<string, mixed>>
*/
public function menusWithPages(): array
{
$menus = $this->menusList();
foreach ($menus as $index => $menu) {
$menuId = (int)($menu['id'] ?? 0);
$menus[$index]['pages'] = $this->menuPages($menuId);
}
return $menus;
}
/**
* @return array<int, array<string, mixed>>
*/
public function menuPages(int $menuId, ?int $parentId = null): array
{
if ($menuId <= 0) {
return [];
}
$rows = $this->db->select('pp_pages', ['id', 'menu_id', 'status', 'parent_id', 'start'], [
'AND' => [
'menu_id' => $menuId,
'parent_id' => $parentId,
],
'ORDER' => ['o' => 'ASC'],
]);
if (!is_array($rows)) {
return [];
}
$pages = [];
foreach ($rows as $row) {
$pageId = (int)($row['id'] ?? 0);
if ($pageId <= 0) {
continue;
}
$row['title'] = $this->pageTitle($pageId);
$row['languages'] = $this->pageLanguages($pageId);
$row['subpages'] = $this->menuPages($menuId, $pageId);
$pages[] = $row;
}
return $pages;
}
public function menuDelete(int $menuId): bool
{
if ($menuId <= 0) {
return false;
}
if ((int)$this->db->count('pp_pages', ['menu_id' => $menuId]) > 0) {
return false;
}
return (bool)$this->db->delete('pp_menus', ['id' => $menuId]);
}
public function pageDelete(int $pageId): bool
{
if ($pageId <= 0) {
return false;
}
if ((int)$this->db->count('pp_pages', ['parent_id' => $pageId]) > 0) {
return false;
}
return (bool)$this->db->delete('pp_pages', ['id' => $pageId]);
}
/**
* @return array<string, mixed>
*/
public function menuDetails(int $menuId): array
{
if ($menuId <= 0) {
return [
'id' => 0,
'name' => '',
'status' => 1,
];
}
$menu = $this->db->get('pp_menus', '*', ['id' => $menuId]);
if (!is_array($menu)) {
return [
'id' => 0,
'name' => '',
'status' => 1,
];
}
return $menu;
}
public function menuSave(int $menuId, string $name, $status): bool
{
$statusValue = $this->toSwitchValue($status);
if ($menuId <= 0) {
$result = $this->db->insert('pp_menus', [
'name' => $name,
'status' => $statusValue,
]);
return (bool)$result;
}
$this->db->update('pp_menus', [
'name' => $name,
'status' => $statusValue,
], [
'id' => $menuId,
]);
return true;
}
/**
* @return array<string, mixed>
*/
public function pageDetails(int $pageId): array
{
if ($pageId <= 0) {
return $this->defaultPage();
}
$page = $this->db->get('pp_pages', '*', ['id' => $pageId]);
if (!is_array($page)) {
return $this->defaultPage();
}
$translations = $this->db->select('pp_pages_langs', '*', ['page_id' => $pageId]);
if (is_array($translations)) {
foreach ($translations as $row) {
$langId = (string)($row['lang_id'] ?? '');
if ($langId !== '') {
$page['languages'][$langId] = $row;
}
}
}
$page['layout_id'] = (int)$this->db->get('pp_layouts_pages', 'layout_id', ['page_id' => $pageId]);
return $page;
}
/**
* @return array<int, array<string, mixed>>
*/
public function pageArticles(int $pageId): array
{
if ($pageId <= 0) {
return [];
}
$sql = '
SELECT
ap.article_id,
ap.o,
a.status,
(
SELECT title
FROM pp_articles_langs AS pal
JOIN pp_langs AS pl ON pal.lang_id = pl.id
WHERE pal.article_id = ap.article_id
AND pal.title != ""
ORDER BY pl.o ASC
LIMIT 1
) AS title
FROM pp_articles_pages AS ap
JOIN pp_articles AS a ON a.id = ap.article_id
WHERE ap.page_id = :page_id
AND a.status != -1
ORDER BY ap.o ASC
';
$stmt = $this->db->query($sql, [':page_id' => $pageId]);
$rows = $stmt ? $stmt->fetchAll() : [];
return is_array($rows) ? $rows : [];
}
public function saveArticlesOrder(int $pageId, $articles): bool
{
if ($pageId <= 0) {
return false;
}
if (!is_array($articles)) {
return true;
}
$this->db->update('pp_articles_pages', ['o' => 0], ['page_id' => $pageId]);
$position = 0;
foreach ($articles as $item) {
$articleId = (int)($item['item_id'] ?? 0);
if ($articleId <= 0) {
continue;
}
$position++;
$this->db->update('pp_articles_pages', ['o' => $position], [
'AND' => [
'page_id' => $pageId,
'article_id' => $articleId,
],
]);
}
return true;
}
public function savePagesOrder(int $menuId, $pages): bool
{
if ($menuId <= 0) {
return false;
}
if (!is_array($pages)) {
return true;
}
$this->db->update('pp_pages', ['o' => 0], ['menu_id' => $menuId]);
$position = 0;
foreach ($pages as $item) {
$itemId = (int)($item['item_id'] ?? 0);
$depth = (int)($item['depth'] ?? 0);
if ($itemId <= 0 || $depth <= 1) {
continue;
}
$parentId = (int)($item['parent_id'] ?? 0);
if ($depth === 2) {
$parentId = null;
}
$position++;
$this->db->update('pp_pages', [
'o' => $position,
'parent_id' => $parentId,
], [
'id' => $itemId,
]);
}
\S::delete_dir('../temp/');
return true;
}
public function pageSave(array $data): ?int
{
$pageId = (int)($data['id'] ?? 0);
$menuId = (int)($data['menu_id'] ?? 0);
$parentId = $this->normalizeNullableInt($data['parent_id'] ?? null);
$pageType = (int)($data['page_type'] ?? 0);
$sortType = (int)($data['sort_type'] ?? 0);
$layoutId = (int)($data['layout_id'] ?? 0);
$articlesLimit = (int)($data['articles_limit'] ?? 0);
$showTitle = $this->toSwitchValue($data['show_title'] ?? 0);
$status = $this->toSwitchValue($data['status'] ?? 0);
$start = $this->toSwitchValue($data['start'] ?? 0);
$categoryId = $this->normalizeNullableInt($data['category_id'] ?? null);
if ($pageType !== 5) {
$categoryId = null;
}
if ($pageId <= 0) {
$order = $this->maxPageOrder() + 1;
$result = $this->db->insert('pp_pages', [
'menu_id' => $menuId,
'page_type' => $pageType,
'sort_type' => $sortType,
'articles_limit' => $articlesLimit,
'show_title' => $showTitle,
'status' => $status,
'o' => $order,
'parent_id' => $parentId,
'start' => $start,
'category_id' => $categoryId,
]);
if (!$result) {
return null;
}
$pageId = (int)$this->db->id();
if ($pageId <= 0) {
return null;
}
} else {
$this->db->update('pp_pages', [
'menu_id' => $menuId,
'page_type' => $pageType,
'sort_type' => $sortType,
'articles_limit' => $articlesLimit,
'show_title' => $showTitle,
'status' => $status,
'parent_id' => $parentId,
'start' => $start,
'category_id' => $categoryId,
], [
'id' => $pageId,
]);
}
if ($start === 1) {
$this->db->update('pp_pages', ['start' => 0], ['id[!]' => $pageId]);
$this->db->update('pp_pages', ['start' => 1], ['id' => $pageId]);
}
$this->db->delete('pp_layouts_pages', ['page_id' => $pageId]);
if ($layoutId > 0) {
$this->db->insert('pp_layouts_pages', [
'layout_id' => $layoutId,
'page_id' => $pageId,
]);
}
$this->saveTranslations($pageId, $pageType, $data);
$this->updateSubpagesMenuId($pageId, $menuId);
\S::htacces();
\S::delete_dir('../temp/');
return $pageId;
}
public function generateSeoLink(string $title, int $pageId = 0, int $articleId = 0, int $categoryId = 0): string
{
$base = trim((string)\S::seo($title));
if ($base === '') {
return '';
}
$candidate = $base;
$suffix = 0;
while ($this->isSeoLinkUsed('pp_pages_langs', 'page_id', $candidate, $pageId)
|| $this->isSeoLinkUsed('pp_articles_langs', 'article_id', $candidate, $articleId)
|| $this->isSeoLinkUsed('pp_shop_categories_langs', 'category_id', $candidate, $categoryId)) {
$suffix++;
$candidate = $base . '-' . $suffix;
}
return $candidate;
}
public function pageUrlPreview(int $pageId, string $langId, string $title, string $seoLink, string $defaultLanguageId): string
{
$url = trim($seoLink) !== ''
? '/' . ltrim($seoLink, '/')
: '/s-' . $pageId . '-' . \S::seo($title);
if ($langId !== '' && $langId !== $defaultLanguageId && $url !== '#') {
$url = '/' . $langId . $url;
}
return $url;
}
public function toggleCookieValue(string $cookieName, int $itemId): void
{
if ($cookieName === '' || $itemId <= 0) {
return;
}
$state = [];
if (!empty($_COOKIE[$cookieName])) {
$decoded = @unserialize((string)$_COOKIE[$cookieName], ['allowed_classes' => false]);
if (is_array($decoded)) {
$state = $decoded;
}
}
$state[$itemId] = empty($state[$itemId]) ? 1 : 0;
setcookie($cookieName, serialize($state), time() + 3600 * 24 * 365);
}
public function pageTitle(int $pageId): string
{
if ($pageId <= 0) {
return '';
}
$rows = $this->db->select('pp_pages_langs', [
'[><]pp_langs' => ['lang_id' => 'id'],
], 'title', [
'AND' => [
'page_id' => $pageId,
'title[!]' => '',
],
'ORDER' => ['o' => 'ASC'],
'LIMIT' => 1,
]);
if (!is_array($rows) || !isset($rows[0])) {
return '';
}
return (string)$rows[0];
}
/**
* @return array<int, array<string, mixed>>
*/
public function pageLanguages(int $pageId): array
{
if ($pageId <= 0) {
return [];
}
$rows = $this->db->select('pp_pages_langs', '*', [
'AND' => [
'page_id' => $pageId,
'title[!]' => null,
],
]);
return is_array($rows) ? $rows : [];
}
/**
* @return array<string, mixed>
*/
private function defaultPage(): array
{
return [
'id' => 0,
'menu_id' => 0,
'page_type' => 0,
'sort_type' => 0,
'articles_limit' => 2,
'show_title' => 1,
'status' => 1,
'start' => 0,
'parent_id' => null,
'category_id' => null,
'layout_id' => 0,
'languages' => [],
];
}
private function saveTranslations(int $pageId, int $pageType, array $data): void
{
$titles = is_array($data['title'] ?? null) ? $data['title'] : [];
$seoLinks = is_array($data['seo_link'] ?? null) ? $data['seo_link'] : [];
$metaTitles = is_array($data['meta_title'] ?? null) ? $data['meta_title'] : [];
$metaDescriptions = is_array($data['meta_description'] ?? null) ? $data['meta_description'] : [];
$metaKeywords = is_array($data['meta_keywords'] ?? null) ? $data['meta_keywords'] : [];
$noindexValues = is_array($data['noindex'] ?? null) ? $data['noindex'] : [];
$pageTitles = is_array($data['page_title'] ?? null) ? $data['page_title'] : [];
$links = is_array($data['link'] ?? null) ? $data['link'] : [];
$canonicals = is_array($data['canonical'] ?? null) ? $data['canonical'] : [];
foreach ($titles as $langId => $title) {
$langId = (string)$langId;
if ($langId === '') {
continue;
}
$row = [
'lang_id' => $langId,
'title' => $this->nullIfEmpty($title),
'meta_description' => $this->nullIfEmpty($metaDescriptions[$langId] ?? null),
'meta_keywords' => $this->nullIfEmpty($metaKeywords[$langId] ?? null),
'meta_title' => $this->nullIfEmpty($metaTitles[$langId] ?? null),
'seo_link' => $this->nullIfEmpty(\S::seo((string)($seoLinks[$langId] ?? ''))),
'noindex' => (int)($noindexValues[$langId] ?? 0),
'page_title' => $this->nullIfEmpty($pageTitles[$langId] ?? null),
'link' => $pageType === 3 ? $this->nullIfEmpty($links[$langId] ?? null) : null,
'canonical' => $this->nullIfEmpty($canonicals[$langId] ?? null),
];
$translationId = (int)$this->db->get('pp_pages_langs', 'id', [
'AND' => [
'page_id' => $pageId,
'lang_id' => $langId,
],
]);
if ($translationId > 0) {
$this->db->update('pp_pages_langs', $row, ['id' => $translationId]);
} else {
$row['page_id'] = $pageId;
$this->db->insert('pp_pages_langs', $row);
}
}
}
private function updateSubpagesMenuId(int $parentId, int $menuId): void
{
if ($parentId <= 0 || $menuId <= 0) {
return;
}
$this->db->update('pp_pages', ['menu_id' => $menuId], ['parent_id' => $parentId]);
$children = $this->db->select('pp_pages', ['id'], ['parent_id' => $parentId]);
if (!is_array($children)) {
return;
}
foreach ($children as $row) {
$childId = (int)($row['id'] ?? 0);
if ($childId > 0) {
$this->updateSubpagesMenuId($childId, $menuId);
}
}
}
private function isSeoLinkUsed(string $table, string $idColumn, string $seoLink, int $exceptId): bool
{
$where = [
'seo_link' => $seoLink,
];
if ($exceptId > 0) {
$where[$idColumn . '[!]'] = $exceptId;
}
return (int)$this->db->count($table, ['AND' => $where]) > 0;
}
private function maxPageOrder(): int
{
$max = $this->db->max('pp_pages', 'o');
return $max ? (int)$max : 0;
}
private function toSwitchValue($value): int
{
if ($value === 'on' || $value === '1' || $value === 1 || $value === true) {
return 1;
}
return 0;
}
private function normalizeNullableInt($value): ?int
{
if ($value === null || $value === '' || (int)$value === 0) {
return null;
}
return (int)$value;
}
private function nullIfEmpty($value): ?string
{
$value = trim((string)$value);
return $value === '' ? null : $value;
}
}

View File

@@ -48,13 +48,13 @@ class ArticlesArchiveController
$rows[] = [ $rows[] = [
'lp' => $lp++ . '.', 'lp' => $lp++ . '.',
'title' => '<a href="/admin/articles/article_edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>', 'title' => '<a href="/admin/articles/edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>',
'date_add' => !empty($item['date_add']) ? date('Y-m-d H:i', strtotime((string)$item['date_add'])) : '-', 'date_add' => !empty($item['date_add']) ? date('Y-m-d H:i', strtotime((string)$item['date_add'])) : '-',
'date_modify' => !empty($item['date_modify']) ? date('Y-m-d H:i', strtotime((string)$item['date_modify'])) : '-', 'date_modify' => !empty($item['date_modify']) ? date('Y-m-d H:i', strtotime((string)$item['date_modify'])) : '-',
'_actions' => [ '_actions' => [
[ [
'label' => 'Przywroc', 'label' => 'Przywroc',
'url' => '/admin/articles_archive/article_restore/id=' . $id, 'url' => '/admin/articles_archive/restore/id=' . $id,
'class' => 'btn btn-xs btn-success', 'class' => 'btn btn-xs btn-success',
'confirm' => 'Na pewno chcesz przywrocic wybrany artykul?', 'confirm' => 'Na pewno chcesz przywrocic wybrany artykul?',
'confirm_ok' => 'Przywroc', 'confirm_ok' => 'Przywroc',
@@ -62,7 +62,7 @@ class ArticlesArchiveController
], ],
[ [
'label' => 'Usun', 'label' => 'Usun',
'url' => '/admin/articles_archive/article_delete/id=' . $id, 'url' => '/admin/articles_archive/delete/id=' . $id,
'class' => 'btn btn-xs btn-danger', 'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz trwale usunac wybrany artykul?', 'confirm' => 'Na pewno chcesz trwale usunac wybrany artykul?',
'confirm_ok' => 'Usun', 'confirm_ok' => 'Usun',
@@ -101,7 +101,7 @@ class ArticlesArchiveController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/articles_archive/view_list/', '/admin/articles_archive/list/',
'Brak danych w tabeli.' 'Brak danych w tabeli.'
); );
@@ -121,7 +121,7 @@ class ArticlesArchiveController
\S::alert('Artykul zostal przywrocony.'); \S::alert('Artykul zostal przywrocony.');
} }
header('Location: /admin/articles_archive/view_list/'); header('Location: /admin/articles_archive/list/');
exit; exit;
} }
@@ -136,7 +136,7 @@ class ArticlesArchiveController
\S::alert('Artykul zostal trwale usuniety.'); \S::alert('Artykul zostal trwale usuniety.');
} }
header('Location: /admin/articles_archive/view_list/'); header('Location: /admin/articles_archive/list/');
exit; exit;
} }

View File

@@ -4,6 +4,7 @@ namespace admin\Controllers;
use Domain\Article\ArticleRepository; use Domain\Article\ArticleRepository;
use Domain\Languages\LanguagesRepository; use Domain\Languages\LanguagesRepository;
use Domain\Layouts\LayoutsRepository; use Domain\Layouts\LayoutsRepository;
use Domain\Pages\PagesRepository;
use admin\ViewModels\Forms\FormAction; use admin\ViewModels\Forms\FormAction;
use admin\ViewModels\Forms\FormEditViewModel; use admin\ViewModels\Forms\FormEditViewModel;
use admin\ViewModels\Forms\FormField; use admin\ViewModels\Forms\FormField;
@@ -14,16 +15,19 @@ class ArticlesController
private ArticleRepository $repository; private ArticleRepository $repository;
private LanguagesRepository $languagesRepository; private LanguagesRepository $languagesRepository;
private LayoutsRepository $layoutsRepository; private LayoutsRepository $layoutsRepository;
private PagesRepository $pagesRepository;
public function __construct( public function __construct(
ArticleRepository $repository, ArticleRepository $repository,
LanguagesRepository $languagesRepository, LanguagesRepository $languagesRepository,
LayoutsRepository $layoutsRepository LayoutsRepository $layoutsRepository,
PagesRepository $pagesRepository
) )
{ {
$this->repository = $repository; $this->repository = $repository;
$this->languagesRepository = $languagesRepository; $this->languagesRepository = $languagesRepository;
$this->layoutsRepository = $layoutsRepository; $this->layoutsRepository = $layoutsRepository;
$this->pagesRepository = $pagesRepository;
} }
/** /**
@@ -83,7 +87,7 @@ class ArticlesController
$rows[] = [ $rows[] = [
'lp' => $lp++ . '.', 'lp' => $lp++ . '.',
'title' => '<a href="/admin/articles/article_edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>' 'title' => '<a href="/admin/articles/edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>'
. '<small class="text-muted">' . htmlspecialchars($pages, ENT_QUOTES, 'UTF-8') . '</small>', . '<small class="text-muted">' . htmlspecialchars($pages, ENT_QUOTES, 'UTF-8') . '</small>',
'status' => ((int)$item['status'] === 1) ? 'tak' : '<span style="color: #FF0000;">nie</span>', 'status' => ((int)$item['status'] === 1) ? 'tak' : '<span style="color: #FF0000;">nie</span>',
'date_add' => !empty($item['date_add']) ? date('Y-m-d H:i', strtotime((string)$item['date_add'])) : '-', 'date_add' => !empty($item['date_add']) ? date('Y-m-d H:i', strtotime((string)$item['date_add'])) : '-',
@@ -92,12 +96,12 @@ class ArticlesController
'_actions' => [ '_actions' => [
[ [
'label' => 'Edytuj', 'label' => 'Edytuj',
'url' => '/admin/articles/article_edit/id=' . $id, 'url' => '/admin/articles/edit/id=' . $id,
'class' => 'btn btn-xs btn-primary', 'class' => 'btn btn-xs btn-primary',
], ],
[ [
'label' => 'Usun', 'label' => 'Usun',
'url' => '/admin/articles/article_delete/id=' . $id, 'url' => '/admin/articles/delete/id=' . $id,
'class' => 'btn btn-xs btn-danger', 'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunac wybrany element?', 'confirm' => 'Na pewno chcesz usunac wybrany element?',
], ],
@@ -136,9 +140,9 @@ class ArticlesController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/articles/view_list/', '/admin/articles/list/',
'Brak danych w tabeli.', 'Brak danych w tabeli.',
'/admin/articles/article_edit/', '/admin/articles/edit/',
'Dodaj artykul' 'Dodaj artykul'
); );
@@ -259,7 +263,7 @@ class ArticlesController
\S::alert('Artykul zostal przeniesiony do archiwum.'); \S::alert('Artykul zostal przeniesiony do archiwum.');
} }
header('Location: /admin/articles/view_list/'); header('Location: /admin/articles/list/');
exit; exit;
} }
@@ -280,7 +284,7 @@ class ArticlesController
$article = $this->repository->find((int)\S::get('id')) ?: ['id' => 0, 'languages' => [], 'images' => [], 'files' => [], 'pages' => []]; $article = $this->repository->find((int)\S::get('id')) ?: ['id' => 0, 'languages' => [], 'images' => [], 'files' => [], 'pages' => []];
$languages = $this->languagesRepository->languagesList(); $languages = $this->languagesRepository->languagesList();
$menus = \admin\factory\Pages::menus_list(); $menus = $this->pagesRepository->menusList();
$layouts = $this->layoutsRepository->listAll(); $layouts = $this->layoutsRepository->listAll();
$viewModel = $this->buildFormViewModel($article, $languages, $menus, $layouts); $viewModel = $this->buildFormViewModel($article, $languages, $menus, $layouts);
@@ -400,8 +404,8 @@ class ArticlesController
]; ];
$actions = [ $actions = [
FormAction::save('/admin/articles/article_save/' . ($articleId > 0 ? 'id=' . $articleId : ''), '/admin/articles/view_list/'), FormAction::save('/admin/articles/save/' . ($articleId > 0 ? 'id=' . $articleId : ''), '/admin/articles/list/'),
FormAction::cancel('/admin/articles/view_list/'), FormAction::cancel('/admin/articles/list/'),
]; ];
return new FormEditViewModel( return new FormEditViewModel(
@@ -412,8 +416,8 @@ class ArticlesController
$tabs, $tabs,
$actions, $actions,
'POST', 'POST',
'/admin/articles/article_save/' . ($articleId > 0 ? 'id=' . $articleId : ''), '/admin/articles/save/' . ($articleId > 0 ? 'id=' . $articleId : ''),
'/admin/articles/view_list/', '/admin/articles/list/',
true, true,
['id' => $articleId], ['id' => $articleId],
$languages $languages
@@ -430,7 +434,7 @@ class ArticlesController
$menuId = (int)($menu['id'] ?? 0); $menuId = (int)($menu['id'] ?? 0);
$menuName = $this->escapeHtml((string)($menu['name'] ?? '')); $menuName = $this->escapeHtml((string)($menu['name'] ?? ''));
$menuStatus = (int)($menu['status'] ?? 0); $menuStatus = (int)($menu['status'] ?? 0);
$menuPages = \admin\factory\Pages::menu_pages($menuId); $menuPages = $this->pagesRepository->menuPages($menuId);
$html .= '<div class="menu_sortable">'; $html .= '<div class="menu_sortable">';
$html .= '<ol class="sortable" id="sortable_' . $menuId . '">'; $html .= '<ol class="sortable" id="sortable_' . $menuId . '">';

View File

@@ -92,7 +92,7 @@ class BannerController
$rows[] = [ $rows[] = [
'lp' => $lp++ . '.', 'lp' => $lp++ . '.',
'thumbnail' => $thumbnail, 'thumbnail' => $thumbnail,
'name' => '<a href="/admin/banners/banner_edit/id=' . $id . '">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</a>', 'name' => '<a href="/admin/banners/edit/id=' . $id . '">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</a>',
'status' => $isActive ? 'tak' : '<span style="color: #FF0000;">nie</span>', 'status' => $isActive ? 'tak' : '<span style="color: #FF0000;">nie</span>',
'home_page' => $homePage === 1 ? '<span class="text-system">tak</span>' : 'nie', 'home_page' => $homePage === 1 ? '<span class="text-system">tak</span>' : 'nie',
'slider' => $homePage === 1 ? 'nie' : '<span class="text-system">tak</span>', 'slider' => $homePage === 1 ? 'nie' : '<span class="text-system">tak</span>',
@@ -101,12 +101,12 @@ class BannerController
'_actions' => [ '_actions' => [
[ [
'label' => 'Edytuj', 'label' => 'Edytuj',
'url' => '/admin/banners/banner_edit/id=' . $id, 'url' => '/admin/banners/edit/id=' . $id,
'class' => 'btn btn-xs btn-primary', 'class' => 'btn btn-xs btn-primary',
], ],
[ [
'label' => 'Usun', 'label' => 'Usun',
'url' => '/admin/banners/banner_delete/id=' . $id, 'url' => '/admin/banners/delete/id=' . $id,
'class' => 'btn btn-xs btn-danger', 'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunac wybrany element?', 'confirm' => 'Na pewno chcesz usunac wybrany element?',
], ],
@@ -147,9 +147,9 @@ class BannerController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/banners/view_list/', '/admin/banners/list/',
'Brak danych w tabeli.', 'Brak danych w tabeli.',
'/admin/banners/banner_edit/', '/admin/banners/edit/',
'Dodaj baner', 'Dodaj baner',
'banners/banners-list-custom-script' 'banners/banners-list-custom-script'
); );
@@ -235,7 +235,7 @@ class BannerController
\S::alert('Baner zostal usuniety.'); \S::alert('Baner zostal usuniety.');
} }
header('Location: /admin/banners/view_list/'); header('Location: /admin/banners/list/');
exit; exit;
} }
@@ -307,10 +307,10 @@ class BannerController
$actions = [ $actions = [
FormAction::save( FormAction::save(
'/admin/banners/banner_save/' . ($isNew ? '' : 'id=' . $bannerId), '/admin/banners/save/' . ($isNew ? '' : 'id=' . $bannerId),
'/admin/banners/view_list/' '/admin/banners/list/'
), ),
FormAction::cancel('/admin/banners/view_list/'), FormAction::cancel('/admin/banners/list/'),
]; ];
return new FormEditViewModel( return new FormEditViewModel(
@@ -321,8 +321,8 @@ class BannerController
$tabs, $tabs,
$actions, $actions,
'POST', 'POST',
'/admin/banners/banner_save/' . ($isNew ? '' : 'id=' . $bannerId), '/admin/banners/save/' . ($isNew ? '' : 'id=' . $bannerId),
'/admin/banners/view_list/', '/admin/banners/list/',
true, true,
['id' => $bannerId], ['id' => $bannerId],
$languages, $languages,

View File

@@ -61,16 +61,16 @@ class DictionariesController
$rows[] = [ $rows[] = [
'lp' => $lp++ . '.', 'lp' => $lp++ . '.',
'text' => '<a href="/admin/dictionaries/unit_edit/id=' . $id . '">' . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . '</a>', 'text' => '<a href="/admin/dictionaries/edit/id=' . $id . '">' . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . '</a>',
'_actions' => [ '_actions' => [
[ [
'label' => 'Edytuj', 'label' => 'Edytuj',
'url' => '/admin/dictionaries/unit_edit/id=' . $id, 'url' => '/admin/dictionaries/edit/id=' . $id,
'class' => 'btn btn-xs btn-primary', 'class' => 'btn btn-xs btn-primary',
], ],
[ [
'label' => 'Usun', 'label' => 'Usun',
'url' => '/admin/dictionaries/unit_delete/id=' . $id, 'url' => '/admin/dictionaries/delete/id=' . $id,
'class' => 'btn btn-xs btn-danger', 'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunac wybrana jednostke miary?', 'confirm' => 'Na pewno chcesz usunac wybrana jednostke miary?',
], ],
@@ -105,9 +105,9 @@ class DictionariesController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/dictionaries/view_list/', '/admin/dictionaries/list/',
'Brak danych w tabeli.', 'Brak danych w tabeli.',
'/admin/dictionaries/unit_edit/', '/admin/dictionaries/edit/',
'Dodaj jednostke miary' 'Dodaj jednostke miary'
); );
@@ -192,7 +192,7 @@ class DictionariesController
\S::alert('Jednostka miary zostala usunieta.'); \S::alert('Jednostka miary zostala usunieta.');
} }
header('Location: /admin/dictionaries/view_list/'); header('Location: /admin/dictionaries/list/');
exit; exit;
} }
@@ -226,10 +226,10 @@ class DictionariesController
]), ]),
]; ];
$actionUrl = '/admin/dictionaries/unit_save/' . ($isNew ? '' : ('id=' . $unitId)); $actionUrl = '/admin/dictionaries/save/' . ($isNew ? '' : ('id=' . $unitId));
$actions = [ $actions = [
FormAction::save($actionUrl, '/admin/dictionaries/view_list/'), FormAction::save($actionUrl, '/admin/dictionaries/list/'),
FormAction::cancel('/admin/dictionaries/view_list/'), FormAction::cancel('/admin/dictionaries/list/'),
]; ];
return new FormEditViewModel( return new FormEditViewModel(
@@ -241,7 +241,7 @@ class DictionariesController
$actions, $actions,
'POST', 'POST',
$actionUrl, $actionUrl,
'/admin/dictionaries/view_list/', '/admin/dictionaries/list/',
true, true,
['id' => $unitId], ['id' => $unitId],
$languages, $languages,

View File

@@ -74,18 +74,18 @@ class LayoutsController
$rows[] = [ $rows[] = [
'lp' => $lp++ . '.', 'lp' => $lp++ . '.',
'name' => '<a href="/admin/layouts/layout_edit/id=' . $id . '">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</a>', 'name' => '<a href="/admin/layouts/edit/id=' . $id . '">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</a>',
'status' => ((int)($item['status'] ?? 0) === 1) ? '<span class="text-system">tak</span>' : 'nie', 'status' => ((int)($item['status'] ?? 0) === 1) ? '<span class="text-system">tak</span>' : 'nie',
'categories_default' => ((int)($item['categories_default'] ?? 0) === 1) ? '<span class="text-system">tak</span>' : 'nie', 'categories_default' => ((int)($item['categories_default'] ?? 0) === 1) ? '<span class="text-system">tak</span>' : 'nie',
'_actions' => [ '_actions' => [
[ [
'label' => 'Edytuj', 'label' => 'Edytuj',
'url' => '/admin/layouts/layout_edit/id=' . $id, 'url' => '/admin/layouts/edit/id=' . $id,
'class' => 'btn btn-xs btn-primary', 'class' => 'btn btn-xs btn-primary',
], ],
[ [
'label' => 'Usun', 'label' => 'Usun',
'url' => '/admin/layouts/layout_delete/id=' . $id, 'url' => '/admin/layouts/delete/id=' . $id,
'class' => 'btn btn-xs btn-danger', 'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunac wybrany szablon?', 'confirm' => 'Na pewno chcesz usunac wybrany szablon?',
], ],
@@ -122,9 +122,9 @@ class LayoutsController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/layouts/view_list/', '/admin/layouts/list/',
'Brak danych w tabeli.', 'Brak danych w tabeli.',
'/admin/layouts/layout_edit/', '/admin/layouts/edit/',
'Dodaj szablon' 'Dodaj szablon'
); );
@@ -165,7 +165,7 @@ class LayoutsController
\S::alert('Szablon zostal usuniety.'); \S::alert('Szablon zostal usuniety.');
} }
header('Location: /admin/layouts/view_list/'); header('Location: /admin/layouts/list/');
exit; exit;
} }

View File

@@ -0,0 +1,660 @@
<?php
namespace admin\Controllers;
use Domain\Pages\PagesRepository;
use Domain\Languages\LanguagesRepository;
use Domain\Layouts\LayoutsRepository;
use admin\ViewModels\Forms\FormAction;
use admin\ViewModels\Forms\FormEditViewModel;
use admin\ViewModels\Forms\FormField;
use admin\ViewModels\Forms\FormTab;
class PagesController
{
private PagesRepository $repository;
private LanguagesRepository $languagesRepository;
private LayoutsRepository $layoutsRepository;
public function __construct(
PagesRepository $repository,
LanguagesRepository $languagesRepository,
LayoutsRepository $layoutsRepository
) {
$this->repository = $repository;
$this->languagesRepository = $languagesRepository;
$this->layoutsRepository = $layoutsRepository;
}
public function list(): string
{
return \Tpl::view('pages/pages-list', [
'menus' => $this->repository->menusWithPages(),
'cookie_pages' => $this->cookieState('cookie_pages'),
'cookie_menus' => $this->cookieState('cookie_menus'),
]);
}
public function browseList(): string
{
$menus = $this->repository->menusWithPages();
$defaultLanguage = $this->languagesRepository->defaultLanguageId();
foreach ($menus as $index => $menu) {
$menus[$index]['pages'] = $this->withPreviewUrls($menu['pages'] ?? [], $defaultLanguage);
}
return \Tpl::view('pages/pages-browse-list', [
'menus' => $menus,
'modal' => \S::get('modal'),
'cookie_pages' => $this->cookieState('cookie_pages'),
'cookie_menus' => $this->cookieState('cookie_menus'),
]);
}
public function pagesUrlBrowser(): string
{
return $this->browseList();
}
public function menuEdit(): string
{
$menu = $this->repository->menuDetails((int)\S::get('id'));
return \Tpl::view('pages/menu-edit', [
'form' => $this->buildMenuFormViewModel($menu),
]);
}
public function menuSave(): void
{
$legacyValues = \S::get('values');
if ($legacyValues) {
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania menu wystapil blad. Prosze sprobowac ponownie.'];
$values = json_decode((string)$legacyValues, true);
if (is_array($values) && $this->repository->menuSave(
(int)($values['id'] ?? 0),
(string)($values['name'] ?? ''),
$values['status'] ?? 0
)) {
$response = ['status' => 'ok', 'msg' => 'Menu zostalo zapisane.'];
}
echo json_encode($response);
exit;
}
$menuId = (int)\S::get('id');
$name = trim((string)\S::get('name'));
$status = \S::get('status');
if ($name === '') {
echo json_encode([
'success' => false,
'errors' => ['name' => 'Pole "Nazwa" jest wymagane.'],
]);
exit;
}
if ($this->repository->menuSave($menuId, $name, $status)) {
echo json_encode([
'success' => true,
'message' => 'Menu zostalo zapisane.',
]);
exit;
}
echo json_encode([
'success' => false,
'errors' => ['general' => 'Podczas zapisywania menu wystapil blad. Prosze sprobowac ponownie.'],
]);
exit;
}
/**
* @param array<string, mixed> $menu
*/
private function buildMenuFormViewModel(array $menu): FormEditViewModel
{
$menuId = (int)($menu['id'] ?? 0);
$actionUrl = '/admin/pages/menuSave/' . ($menuId > 0 ? ('id=' . $menuId) : '');
$fields = [
FormField::hidden('id', $menuId),
FormField::text('name', [
'label' => 'Nazwa',
'required' => true,
'attributes' => ['class' => 'require'],
'value' => (string)($menu['name'] ?? ''),
]),
FormField::switch('status', [
'label' => 'Aktywne',
'value' => (int)($menu['status'] ?? 0) === 1,
]),
];
$actions = [
FormAction::save($actionUrl, '/admin/pages/list/'),
FormAction::cancel('/admin/pages/list/'),
];
return new FormEditViewModel(
'pages-menu-edit',
'Zapisz menu',
$menu,
$fields,
[],
$actions,
'POST',
$actionUrl,
'/admin/pages/list/',
true,
['id' => $menuId]
);
}
public function menuDelete(): void
{
if ($this->repository->menuDelete((int)\S::get('id'))) {
\S::set_message('Menu zostało usunięte.');
} else {
\S::alert('Podczas usuwania menu wystąpił błąd. Aby usunąć menu, nie może ono posiadać przypiętych stron.');
}
header('Location: /admin/pages/list/');
exit;
}
public function edit(): string
{
$page = $this->repository->pageDetails((int)\S::get('id'));
$parentId = (int)\S::get('pid');
$menuId = (int)\S::get('menu_id');
$menus = $this->repository->menusList();
$layouts = $this->layoutsRepository->listAll();
$languages = $this->languagesRepository->languagesList();
return \Tpl::view('pages/page-edit', [
'form' => $this->buildPageFormViewModel(
$page,
$parentId,
$menuId,
$menus,
$layouts,
$languages
),
]);
}
public function save(): void
{
$legacyValues = \S::get('values');
if ($legacyValues) {
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania strony wystapil blad. Prosze sprobowac ponownie.'];
$values = json_decode((string)$legacyValues, true);
if (is_array($values)) {
$id = $this->repository->pageSave($values);
if (!empty($id)) {
$response = [
'status' => 'ok',
'msg' => 'Strona zostala zapisana.',
'id' => (int)$id,
];
}
}
echo json_encode($response);
exit;
}
$data = $_POST;
if (!isset($data['id']) || $data['id'] === '') {
$data['id'] = (int)\S::get('id');
}
if (!isset($data['parent_id']) || $data['parent_id'] === '') {
$data['parent_id'] = (int)\S::get('pid');
}
if ((!isset($data['menu_id']) || $data['menu_id'] === '') && (int)\S::get('menu_id') > 0) {
$data['menu_id'] = (int)\S::get('menu_id');
}
$savedId = $this->repository->pageSave($data);
if (!empty($savedId)) {
echo json_encode([
'success' => true,
'message' => 'Strona zostala zapisana.',
'id' => (int)$savedId,
]);
exit;
}
echo json_encode([
'success' => false,
'errors' => ['general' => 'Podczas zapisywania strony wystapil blad. Prosze sprobowac ponownie.'],
]);
exit;
}
/**
* @param array<string, mixed> $page
* @param array<int, array<string, mixed>> $menus
* @param array<int, array<string, mixed>> $layouts
* @param array<int, array<string, mixed>> $languages
*/
private function buildPageFormViewModel(
array $page,
int $parentId,
int $menuId,
array $menus,
array $layouts,
array $languages
): FormEditViewModel {
$pageId = (int)($page['id'] ?? 0);
$isNew = $pageId <= 0;
$resolvedParentId = $pageId > 0 ? (int)($page['parent_id'] ?? 0) : $parentId;
$resolvedMenuId = $pageId > 0 ? (int)($page['menu_id'] ?? 0) : $menuId;
$menuOptions = [];
foreach ($menus as $menu) {
$id = (int)($menu['id'] ?? 0);
if ($id <= 0) {
continue;
}
$menuOptions[$id] = (string)($menu['name'] ?? '');
}
$layoutOptions = ['' => '---- szablon ----'];
foreach ($layouts as $layout) {
$id = (int)($layout['id'] ?? 0);
if ($id <= 0) {
continue;
}
$layoutOptions[$id] = (string)($layout['name'] ?? '');
}
$data = [
'id' => $pageId,
'parent_id' => $resolvedParentId > 0 ? $resolvedParentId : '',
'menu_id' => $resolvedMenuId > 0 ? $resolvedMenuId : '',
'page_type' => (int)($page['page_type'] ?? 0),
'sort_type' => (int)($page['sort_type'] ?? 0),
'layout_id' => (int)($page['layout_id'] ?? 0),
'articles_limit' => (int)($page['articles_limit'] ?? 2),
'show_title' => (int)($page['show_title'] ?? 1),
'status' => (int)($page['status'] ?? 1),
'start' => (int)($page['start'] ?? 0),
'category_id' => (int)($page['category_id'] ?? 0),
'languages' => [],
];
foreach ($languages as $language) {
$langId = (string)($language['id'] ?? '');
if ($langId === '') {
continue;
}
$translation = is_array($page['languages'][$langId] ?? null) ? $page['languages'][$langId] : [];
$data['languages'][$langId] = [
'title' => (string)($translation['title'] ?? ''),
'link' => (string)($translation['link'] ?? ''),
'seo_link' => (string)($translation['seo_link'] ?? ''),
'page_title' => (string)($translation['page_title'] ?? ''),
'meta_title' => (string)($translation['meta_title'] ?? ''),
'meta_description' => (string)($translation['meta_description'] ?? ''),
'meta_keywords' => (string)($translation['meta_keywords'] ?? ''),
'noindex' => (int)($translation['noindex'] ?? 0),
'canonical' => (string)($translation['canonical'] ?? ''),
];
}
$tabs = [
new FormTab('content', 'Tresc', 'fa-file'),
new FormTab('settings', 'Ustawienia', 'fa-wrench'),
new FormTab('seo', 'SEO', 'fa-globe'),
];
$fields = [
FormField::hidden('id', $pageId),
FormField::hidden('parent_id', $resolvedParentId > 0 ? $resolvedParentId : ''),
FormField::langSection('page_content', 'content', [
FormField::text('title', [
'label' => 'Nazwa strony',
'required' => true,
]),
]),
FormField::select('menu_id', [
'label' => 'Menu',
'tab' => 'settings',
'options' => $menuOptions,
'value' => $resolvedMenuId > 0 ? $resolvedMenuId : '',
]),
FormField::select('page_type', [
'label' => 'Typ strony',
'tab' => 'settings',
'options' => $this->repository->pageTypes(),
'attributes' => ['id' => 'page_type'],
'value' => (int)($page['page_type'] ?? 0),
]),
FormField::langSection('page_links', 'settings', [
FormField::text('link', [
'label' => 'Link',
]),
]),
FormField::text('category_id', [
'label' => 'ID kategorii',
'tab' => 'settings',
'attributes' => ['id' => 'category_id'],
'value' => (int)($page['category_id'] ?? 0),
]),
FormField::select('sort_type', [
'label' => 'Sortowanie artykulow',
'tab' => 'settings',
'attributes' => ['id' => 'sort_type'],
'options' => $this->repository->sortTypes(),
'value' => (int)($page['sort_type'] ?? 0),
]),
FormField::select('layout_id', [
'label' => 'Szablon',
'tab' => 'settings',
'attributes' => ['id' => 'layout_id'],
'options' => $layoutOptions,
'value' => (int)($page['layout_id'] ?? 0),
]),
FormField::text('articles_limit', [
'label' => 'Liczba artykulow na stronie',
'tab' => 'settings',
'attributes' => ['id' => 'articles_limit'],
'value' => (int)($page['articles_limit'] ?? 2),
]),
FormField::switch('show_title', [
'label' => 'Pokaz tytul',
'tab' => 'settings',
'value' => (int)($page['show_title'] ?? 0) === 1 || $isNew,
]),
FormField::switch('status', [
'label' => 'Aktywna',
'tab' => 'settings',
'value' => (int)($page['status'] ?? 0) === 1 || $isNew,
]),
FormField::switch('start', [
'label' => 'Strona startowa',
'tab' => 'settings',
'value' => (int)($page['start'] ?? 0) === 1,
]),
FormField::langSection('page_seo', 'seo', [
FormField::text('seo_link', [
'label' => 'Link SEO',
'attributes' => [
'icon_content' => 'generuj',
'icon_js' => 'generateSeoLinkForButton(\'{lang}\')',
],
]),
FormField::text('page_title', [
'label' => 'Tytul strony (h1)',
]),
FormField::text('meta_title', [
'label' => 'Meta title',
]),
FormField::textarea('meta_description', [
'label' => 'Meta description',
]),
FormField::textarea('meta_keywords', [
'label' => 'Meta keywords',
]),
FormField::select('noindex', [
'label' => 'Blokuj indeksacje',
'options' => [0 => 'nie', 1 => 'tak'],
]),
FormField::text('canonical', [
'label' => 'Rel canonical',
]),
]),
FormField::custom('page_edit_script', '
<script type="text/javascript">
(function () {
function toggleByType() {
var pageType = String($(\'#page_type\').val() || \'\');
var $links = $(\'#languages-page_links\');
var $category = $(\'#category_id\').closest(\'.form-group\');
var $articlesLimit = $(\'#articles_limit\').closest(\'.form-group\');
var $sortType = $(\'#sort_type\').closest(\'.form-group\');
if (pageType === \'0\' || pageType === \'1\' || pageType === \'2\') {
$articlesLimit.show();
$sortType.show();
$links.addClass(\'hide\');
$category.hide();
} else if (pageType === \'3\') {
$links.removeClass(\'hide\');
$articlesLimit.hide();
$sortType.hide();
$category.hide();
} else if (pageType === \'5\') {
$category.show();
$links.addClass(\'hide\');
$articlesLimit.hide();
$sortType.hide();
} else {
$links.addClass(\'hide\');
$category.hide();
$articlesLimit.hide();
$sortType.hide();
}
}
function generateSeoLink(langId, title) {
if (!title) {
return;
}
$.ajax({
type: \'POST\',
cache: false,
url: \'/admin/pages/generateSeoLink/\',
data: {
title: title,
page_id: ' . $pageId . '
},
success: function (data) {
var response = data;
if (typeof data === \'string\') {
try { response = JSON.parse(data); } catch (e) { response = null; }
}
if (response && response.status === \'ok\') {
$(\'#seo_link_\' + langId).val(response.seo_link || \'\');
}
}
});
}
window.generateSeoLinkForButton = function (langId) {
var title = $(\'#title_\' + langId).val() || \'\';
generateSeoLink(langId, title);
};
$(function () {
$(\'#page_type\').on(\'change\', toggleByType);
toggleByType();
$(\'[id^=title_]\').on(\'blur\', function () {
var fieldId = $(this).attr(\'id\') || \'\';
var langId = fieldId.replace(/^title_/, \'\');
if (!langId) {
return;
}
var $seo = $(\'#seo_link_\' + langId);
if ($seo.length && !$seo.val()) {
generateSeoLink(langId, $(this).val());
}
});
});
})();
</script>', [
'tab' => 'settings',
]),
];
$actionUrl = '/admin/pages/save/' . ($pageId > 0 ? ('id=' . $pageId) : '');
$actions = [
FormAction::save($actionUrl, '/admin/pages/list/'),
FormAction::cancel('/admin/pages/list/'),
];
return new FormEditViewModel(
'pages-page-edit',
'Edycja strony',
$data,
$fields,
$tabs,
$actions,
'POST',
$actionUrl,
'/admin/pages/list/',
true,
[
'id' => $pageId,
'parent_id' => $resolvedParentId > 0 ? $resolvedParentId : '',
],
$languages
);
}
public function delete(): void
{
if ($this->repository->pageDelete((int)\S::get('id'))) {
\S::set_message('Strona zostala usunieta.');
} else {
\S::alert('Podczas usuwania strony wystapil blad. Aby usunac strone nie moze ona posiadac przypietych podstron.');
}
header('Location: /admin/pages/list/');
exit;
}
public function pageArticles(): string
{
$pageId = (int)\S::get('id');
return \Tpl::view('pages/page-articles', [
'page_id' => $pageId,
'articles' => $this->repository->pageArticles($pageId),
]);
}
public function savePagesOrder(): void
{
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania kolejnosci stron wystapil blad. Prosze sprobowac ponownie.'];
if ($this->repository->savePagesOrder((int)\S::get('menu_id'), \S::get('pages'))) {
$response = ['status' => 'ok'];
}
echo json_encode($response);
exit;
}
public function saveArticlesOrder(): void
{
$response = ['status' => 'error', 'msg' => 'Podczas zapisywania kolejnosci wyswietlania artykulow wystapil blad. Prosze sprobowac ponownie.'];
if ($this->repository->saveArticlesOrder((int)\S::get('page_id'), \S::get('articles'))) {
$response = ['status' => 'ok'];
}
echo json_encode($response);
exit;
}
public function generateSeoLink(): void
{
$response = ['status' => 'error', 'msg' => 'Podczas generowania pola "seo link" wystapil blad. Prosze sprobowac ponownie.'];
$seoLink = $this->repository->generateSeoLink(
(string)\S::get('title'),
(int)\S::get('page_id'),
(int)\S::get('article_id'),
(int)\S::get('category_id')
);
if ($seoLink !== '') {
$response = [
'status' => 'ok',
'seo_link' => $seoLink,
];
}
echo json_encode($response);
exit;
}
public function cookieMenus(): void
{
$this->repository->toggleCookieValue('cookie_menus', (int)\S::get('menu_id'));
exit;
}
public function cookiePages(): void
{
$this->repository->toggleCookieValue('cookie_pages', (int)\S::get('page_id'));
exit;
}
/**
* @param array<int, array<string, mixed>> $pages
* @return array<int, array<string, mixed>>
*/
private function withPreviewUrls(array $pages, string $defaultLanguage): array
{
foreach ($pages as $index => $page) {
$pageId = (int)($page['id'] ?? 0);
$languages = is_array($page['languages'] ?? null) ? $page['languages'] : [];
$previewUrls = [];
foreach ($languages as $languageRow) {
$langId = (string)($languageRow['lang_id'] ?? '');
if ($langId === '') {
continue;
}
$previewUrls[$langId] = $this->repository->pageUrlPreview(
$pageId,
$langId,
(string)($languageRow['title'] ?? ''),
(string)($languageRow['seo_link'] ?? ''),
$defaultLanguage
);
}
$page['preview_urls'] = $previewUrls;
$page['subpages'] = $this->withPreviewUrls($page['subpages'] ?? [], $defaultLanguage);
$pages[$index] = $page;
}
return $pages;
}
/**
* @return array<int, int>
*/
private function cookieState(string $cookieName): array
{
if (empty($_COOKIE[$cookieName])) {
return [];
}
$decoded = @unserialize((string)$_COOKIE[$cookieName], ['allowed_classes' => false]);
if (!is_array($decoded)) {
return [];
}
$state = [];
foreach ($decoded as $key => $value) {
$state[(int)$key] = (int)$value;
}
return $state;
}
}

View File

@@ -140,7 +140,7 @@ class ProductArchiveController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/product_archive/products_list/', '/admin/product_archive/list/',
'Brak danych w tabeli.', 'Brak danych w tabeli.',
null, null,
null, null,
@@ -159,7 +159,7 @@ class ProductArchiveController
else else
\S::alert( 'Podczas przywracania produktu z archiwum wystąpił błąd. Proszę spróbować ponownie' ); \S::alert( 'Podczas przywracania produktu z archiwum wystąpił błąd. Proszę spróbować ponownie' );
header( 'Location: /admin/product_archive/products_list/' ); header( 'Location: /admin/product_archive/list/' );
exit; exit;
} }
} }

View File

@@ -71,18 +71,18 @@ class ScontainersController
$rows[] = [ $rows[] = [
'lp' => $lp++ . '.', 'lp' => $lp++ . '.',
'title' => '<a href="/admin/scontainers/container_edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>', 'title' => '<a href="/admin/scontainers/edit/id=' . $id . '">' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '</a>',
'code' => '[KONTENER:' . $id . ']', 'code' => '[KONTENER:' . $id . ']',
'status' => ((int)($item['status'] ?? 0) === 1) ? 'tak' : '<span style="color: #FF0000;">nie</span>', 'status' => ((int)($item['status'] ?? 0) === 1) ? 'tak' : '<span style="color: #FF0000;">nie</span>',
'_actions' => [ '_actions' => [
[ [
'label' => 'Edytuj', 'label' => 'Edytuj',
'url' => '/admin/scontainers/container_edit/id=' . $id, 'url' => '/admin/scontainers/edit/id=' . $id,
'class' => 'btn btn-xs btn-primary', 'class' => 'btn btn-xs btn-primary',
], ],
[ [
'label' => 'Usun', 'label' => 'Usun',
'url' => '/admin/scontainers/container_delete/id=' . $id, 'url' => '/admin/scontainers/delete/id=' . $id,
'class' => 'btn btn-xs btn-danger', 'class' => 'btn btn-xs btn-danger',
'confirm' => 'Na pewno chcesz usunac wybrany kontener?', 'confirm' => 'Na pewno chcesz usunac wybrany kontener?',
], ],
@@ -119,9 +119,9 @@ class ScontainersController
]), ]),
$listRequest['perPageOptions'], $listRequest['perPageOptions'],
$sortableColumns, $sortableColumns,
'/admin/scontainers/view_list/', '/admin/scontainers/list/',
'Brak danych w tabeli.', 'Brak danych w tabeli.',
'/admin/scontainers/container_edit/', '/admin/scontainers/edit/',
'Dodaj kontener' 'Dodaj kontener'
); );
@@ -218,7 +218,7 @@ class ScontainersController
\S::alert('Kontener zostal usuniety.'); \S::alert('Kontener zostal usuniety.');
} }
header('Location: /admin/scontainers/view_list/'); header('Location: /admin/scontainers/list/');
exit; exit;
} }
@@ -266,10 +266,10 @@ class ScontainersController
new FormTab('settings', 'Ustawienia', 'fa-wrench'), new FormTab('settings', 'Ustawienia', 'fa-wrench'),
]; ];
$actionUrl = '/admin/scontainers/container_save/' . ($isNew ? '' : ('id=' . $id)); $actionUrl = '/admin/scontainers/save/' . ($isNew ? '' : ('id=' . $id));
$actions = [ $actions = [
FormAction::save($actionUrl, '/admin/scontainers/view_list/'), FormAction::save($actionUrl, '/admin/scontainers/list/'),
FormAction::cancel('/admin/scontainers/view_list/'), FormAction::cancel('/admin/scontainers/list/'),
]; ];
return new FormEditViewModel( return new FormEditViewModel(
@@ -281,7 +281,7 @@ class ScontainersController
$actions, $actions,
'POST', 'POST',
$actionUrl, $actionUrl,
'/admin/scontainers/view_list/', '/admin/scontainers/list/',
true, true,
[], [],
$languages, $languages,

View File

@@ -309,7 +309,7 @@ class SettingsController
]; ];
$actions = [ $actions = [
FormAction::save('/admin/settings/settings_save/', ''), FormAction::save('/admin/settings/save/', ''),
]; ];
return new FormEditViewModel( return new FormEditViewModel(
@@ -320,7 +320,7 @@ class SettingsController
$tabs, $tabs,
$actions, $actions,
'POST', 'POST',
'/admin/settings/settings_save/', '/admin/settings/save/',
null, null,
false, false,
[], [],

View File

@@ -405,6 +405,25 @@ class FormFieldRenderer
]), $error); ]), $error);
default: // TEXT, URL, etc. 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(\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(\Html::input([ return $this->wrapWithError(\Html::input([
'label' => $field->label, 'label' => $field->label,
'name' => $name, 'name' => $name,

View File

@@ -85,7 +85,7 @@ class Site
(bool)\S::get('remember') (bool)\S::get('remember')
); );
header('Location: /admin/articles/view_list/'); header('Location: /admin/articles/list/');
exit; exit;
} }
} }
@@ -130,7 +130,7 @@ class Site
exit; exit;
} }
// 2FA OK finalna sesja // 2FA OK - finalna sesja
$user = $users->details($pending['login']); $user = $users->details($pending['login']);
self::finalize_admin_login( self::finalize_admin_login(
@@ -140,7 +140,7 @@ class Site
$pending['remember'] ? true : false $pending['remember'] ? true : false
); );
header('Location: /admin/articles/view_list/'); header('Location: /admin/articles/list/');
exit; exit;
} }
break; break;
@@ -208,7 +208,8 @@ class Site
return new \admin\Controllers\ArticlesController( return new \admin\Controllers\ArticlesController(
new \Domain\Article\ArticleRepository( $mdb ), new \Domain\Article\ArticleRepository( $mdb ),
new \Domain\Languages\LanguagesRepository( $mdb ), new \Domain\Languages\LanguagesRepository( $mdb ),
new \Domain\Layouts\LayoutsRepository( $mdb ) new \Domain\Layouts\LayoutsRepository( $mdb ),
new \Domain\Pages\PagesRepository( $mdb )
); );
}, },
'ArticlesArchive' => function() { 'ArticlesArchive' => function() {
@@ -241,7 +242,7 @@ class Site
new \Domain\Product\ProductRepository( $mdb ) new \Domain\Product\ProductRepository( $mdb )
); );
}, },
// Alias dla starego modułu /admin/archive/products_list/ // Alias dla starego modułu /admin/archive/list/
'Archive' => function() { 'Archive' => function() {
global $mdb; global $mdb;
@@ -301,6 +302,15 @@ class Site
new \Domain\Languages\LanguagesRepository( $mdb ) new \Domain\Languages\LanguagesRepository( $mdb )
); );
}, },
'Pages' => function() {
global $mdb;
return new \admin\Controllers\PagesController(
new \Domain\Pages\PagesRepository( $mdb ),
new \Domain\Languages\LanguagesRepository( $mdb ),
new \Domain\Layouts\LayoutsRepository( $mdb )
);
},
]; ];
return self::$newControllers; return self::$newControllers;
@@ -324,40 +334,7 @@ class Site
return $factory(); return $factory();
} }
/**
* Mapowanie nazw akcji: stara_nazwa => nowa_nazwa
* Potrzebne gdy stary routing używa innej konwencji nazw
*/
private static $actionMap = [
'gallery_order_save' => 'galleryOrderSave',
'files_order_save' => 'filesOrderSave',
'view_list' => 'list',
'article_edit' => 'edit',
'article_save' => 'save',
'article_delete' => 'delete',
'article_restore' => 'restore',
'article_image_alt_change' => 'imageAltChange',
'article_file_name_change' => 'fileNameChange',
'article_image_delete' => 'imageDelete',
'article_file_delete' => 'fileDelete',
'banner_edit' => 'edit',
'banner_save' => 'save',
'banner_delete' => 'delete',
'clear_cache' => 'clearCache',
'clear_cache_ajax' => 'clearCacheAjax',
'settings_save' => 'save',
'products_list' => 'list',
'unit_edit' => 'edit',
'unit_save' => 'save',
'unit_delete' => 'delete',
'layout_edit' => 'edit',
'layout_save' => 'save',
'layout_delete' => 'delete',
'container_edit' => 'edit',
'container_save' => 'save',
'container_delete' => 'delete',
];
public static function route() public static function route()
{ {
$_SESSION['admin'] = true; $_SESSION['admin'] = true;
@@ -382,12 +359,9 @@ class Site
$controller = self::createController( $moduleName ); $controller = self::createController( $moduleName );
if ( $controller ) if ( $controller )
{ {
// Mapuj nazwę akcji (stara → nowa) lub użyj oryginalnej if ( method_exists( $controller, $action ) )
$newAction = self::$actionMap[$action] ?? $action;
if ( method_exists( $controller, $newAction ) )
{ {
return $controller->$newAction(); return $controller->$action();
} }
} }
@@ -422,3 +396,4 @@ class Site
} }
} }
} }

View File

@@ -1,117 +0,0 @@
<?php
namespace admin\controls;
class Pages
{
public static function pages_url_browser()
{
echo \Tpl::view( 'pages/pages-browse-list', [
'menus' => \admin\factory\Pages::menus_list(),
'modal' => \S::get( 'modal' )
] );
exit;
}
public static function browse_list()
{
return \admin\view\Pages::browse_list(
\admin\factory\Pages::menus_list()
);
}
public static function menu_delete()
{
if ( \admin\factory\Pages::menu_delete( \S::get( 'id' ) ) )
\S::set_message( 'Menu zostało usunięte.' );
else
\S::alert( 'Podczas usuwania menu wystąpił błąd. Aby usunąć menu nie może ono posiadać przypiętych stron.' );
header( 'Location: /admin/pages/view_list/' );
exit;
}
public static function page_delete()
{
if ( \admin\factory\Pages::page_delete( \S::get( 'id' ) ) )
\S::set_message( 'Strona została usunięta.' );
else
\S::alert( 'Podczas usuwania strony wystąpił błąd. Aby usunąć stronę nie może ona posiadać przypiętych podstron.' );
header( 'Location: /admin/pages/view_list/' );
exit;
}
public static function page_articles()
{
return \admin\view\Pages::page_articles( \S::get( 'id' ), \admin\factory\Pages::page_articles( \S::get( 'id' ) ) );
}
public static function page_save()
{
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania strony wystąpił błąd. Proszę spróbować ponownie.' ];
$values = json_decode( \S::get( 'values' ), true );
if ( $id = \admin\factory\Pages::page_save(
$values['id'], $values['title'], $values['seo_link'], $values['meta_title'], $values['meta_description'], $values['meta_keywords'], $values['menu_id'], $values['parent_id'], $values['page_type'],
$values['sort_type'], $values['layout_id'], $values['articles_limit'], $values['show_title'], $values['status'], $values['link'], $values['noindex'], $values['start'], $values['page_title'],
$values['canonical'], $values['category_id']
) )
$response = [ 'status' => 'ok', 'msg' => 'Strona została zapisana.', 'id' => $id ];
echo json_encode( $response );
exit;
}
public static function page_edit()
{
return \Tpl::view( 'pages/page-edit', [
'page' => \admin\factory\Pages::page_details( \S::get( 'id' ) ),
'parent_id' => \S::get( 'pid' ),
'menu_id' => \S::get( 'menu_id' ),
'menus' => \admin\factory\Pages::menu_lists(),
'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.' ];
$values = json_decode( \S::get( 'values' ), true );
if ( \admin\factory\Pages::menu_save( $values['id'], $values['name'], $values['status'] ) )
$response = [ 'status' => 'ok', 'msg' => 'Menu zostało zapisane.' ];
echo json_encode( $response );
exit;
}
public static function menu_edit()
{
return \admin\view\Pages::menu_edit(
\admin\factory\Pages::menu_details( \S::get( 'id' ) )
);
}
public static function view_list()
{
return \Tpl::view( 'pages/pages-list', [
'menus' => \admin\factory\Pages::menus_list()
] );
}
}
?>

View File

@@ -203,7 +203,7 @@ class ShopProduct
else else
\S::alert( 'Podczas przywracania produktu z archiwum wystąpił błąd. Proszę spróbować ponownie' ); \S::alert( 'Podczas przywracania produktu z archiwum wystąpił błąd. Proszę spróbować ponownie' );
header( 'Location: /admin/product_archive/products_list/' ); header( 'Location: /admin/product_archive/list/' );
exit; exit;
} }
@@ -276,8 +276,8 @@ class ShopProduct
{ {
echo json_encode( [ echo json_encode( [
'status' => 'deprecated', 'status' => 'deprecated',
'msg' => 'Endpoint nie jest juz wspierany. Uzyj /admin/product_archive/products_list/.', 'msg' => 'Endpoint nie jest juz wspierany. Uzyj /admin/product_archive/list/.',
'redirect_url' => '/admin/product_archive/products_list/' 'redirect_url' => '/admin/product_archive/list/'
] ); ] );
exit; exit;
} }

View File

@@ -61,6 +61,7 @@ class Articles
public static function article_pages( $article_id ) public static function article_pages( $article_id )
{ {
global $mdb; global $mdb;
$pagesRepository = new \Domain\Pages\PagesRepository( $mdb );
$results = $mdb -> query( "SELECT page_id FROM pp_articles_pages WHERE article_id = " . (int)$article_id ) -> fetchAll(); $results = $mdb -> query( "SELECT page_id FROM pp_articles_pages WHERE article_id = " . (int)$article_id ) -> fetchAll();
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row ) if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
@@ -68,7 +69,7 @@ class Articles
if ( $out == '' ) if ( $out == '' )
$out .= ' - '; $out .= ' - ';
$out .= \admin\factory\Pages::page_title( $row['page_id'] ); $out .= $pagesRepository->pageTitle( (int)$row['page_id'] );
if ( end( $results ) != $row ) if ( end( $results ) != $row )
$out .= ' / '; $out .= ' / ';

View File

@@ -2,6 +2,7 @@
namespace admin\factory; namespace admin\factory;
use Domain\Layouts\LayoutsRepository; use Domain\Layouts\LayoutsRepository;
use Domain\Pages\PagesRepository;
class Layouts class Layouts
{ {
@@ -47,21 +48,8 @@ class Layouts
public static function menus_list() public static function menus_list()
{ {
$menus = \admin\factory\Pages::menus_list(); global $mdb;
if (!is_array($menus)) { return (new PagesRepository($mdb))->menusWithPages();
return [];
}
foreach ($menus as $key => $menu) {
$menuId = (int)($menu['id'] ?? 0);
if ($menuId <= 0) {
continue;
}
$menus[$key]['pages'] = \admin\factory\Pages::menu_pages($menuId);
}
return $menus;
} }
public static function layouts_list() public static function layouts_list()
@@ -75,4 +63,3 @@ class Layouts
return new LayoutsRepository($mdb); return new LayoutsRepository($mdb);
} }
} }

View File

@@ -1,407 +0,0 @@
<?
namespace admin\factory;
class Pages
{
public static $_page_types = [ 0 => 'pełne artykuły', 1 => 'wprowadzenia', 2 => 'miniaturki', 3 => 'link', 4 => 'kontakt', 5 => 'kategoria sklepu' ];
public static $_sort_types = [
0 => 'data dodania - najstarsze na początku',
1 => 'data dodania - najnowsze na początku',
2 => 'data modyfikacji - rosnąco',
3 => 'data mofyfikacji - malejąco',
4 => 'ręczne',
5 => 'alfabetycznie - A - Z',
6 => 'alfabetycznie - Z - A'
];
public static function save_articles_order( $page_id, $articles )
{
global $mdb;
if ( is_array( $articles ) )
{
$mdb -> update( 'pp_articles_pages', [ 'o' => 0 ], [ 'page_id' => (int)$page_id ] );
for ( $i = 0; $i < count( $articles ); $i++ )
{
if ( $articles[$i]['item_id'] )
{
$x++;
$mdb -> update( 'pp_articles_pages', [ 'o' => $x ], [ 'AND' => [ 'page_id' => (int)$page_id, 'article_id' => $articles[ $i ]['item_id'] ] ] );
}
}
}
return true;
}
public static function page_articles( $page_id )
{
global $mdb;
$results = $mdb -> query( 'SELECT '
. 'article_id, o, status '
. 'FROM '
. 'pp_articles_pages AS ap '
. 'INNER JOIN pp_articles AS a ON a.id = ap.article_id '
. 'WHERE '
. 'page_id = ' . (int)$page_id . ' AND status != -1 '
. 'ORDER BY '
. 'o ASC' ) -> fetchAll();
if ( is_array( $results ) ) foreach ( $results as $row )
{
$row['title'] = \admin\factory\Articles::article_title( $row['article_id'] );
$articles[] = $row;
}
return $articles;
}
public static function menus_list()
{
global $mdb;
return $mdb -> select( 'pp_menus', '*', [ 'ORDER' => [ 'id' => 'ASC' ] ] );
}
public static function save_pages_order( $menu_id, $pages )
{
global $mdb;
if ( is_array( $pages ) )
{
$mdb -> update( 'pp_pages', [ 'o' => 0 ], [ 'menu_id' => (int)$menu_id ] );
for ( $i = 0; $i < count( $pages ); $i++ )
{
if ( $pages[$i]['item_id'] )
{
$pages[$i]['parent_id'] ? $parent_id = $pages[$i]['parent_id'] : $parent_id = 0;
if ( $pages[$i]['item_id'] && $pages[$i]['depth'] > 1 )
{
if ( $pages[$i]['depth'] == 2 )
$parent_id = null;
$x++;
$mdb -> update( 'pp_pages', [ 'o' => $x, 'parent_id' => $parent_id ], [ 'id' => (int)$pages[ $i ]['item_id'] ] );
}
}
}
}
\S::delete_dir( '../temp/' );
return true;
}
public static function page_delete( $page_id )
{
global $mdb;
if ( $mdb -> count( 'pp_pages', [ 'parent_id' => (int)$page_id ] ) )
return false;
return $mdb -> delete( 'pp_pages', [ 'id' => (int)$page_id ] );
}
public static function max_order()
{
global $mdb;
return $mdb -> max( 'pp_pages', 'o' );
}
public static function page_save(
$page_id, $title, $seo_link, $meta_title, $meta_description, $meta_keywords, $menu_id, $parent_id, $page_type, $sort_type, $layout_id, $articles_limit, $show_title, $status,
$link, $noindex, $start, $page_title, $canonical, $category_id
)
{
global $mdb;
if ( !$parent_id )
$parent_id = null;
if ( !$page_id )
{
$order = self::max_order() + 1;
$mdb -> insert( 'pp_pages', [
'menu_id' => (int)$menu_id,
'page_type' => $page_type,
'sort_type' => $sort_type,
'articles_limit' => $articles_limit,
'show_title' => $show_title == 'on' ? 1 : 0,
'status' => $status == 'on' ? 1 : 0,
'o' => (int)$order,
'parent_id' => $parent_id,
'start' => $start == 'on' ? 1 : 0,
'category_id' => ( $category_id and $page_type == 5 ) ? $category_id : null
] );
$id = $mdb -> id();
if ( $id )
{
if ( $start )
$mdb -> update( 'pp_pages', [ 'start' => 0 ], [ 'id[!]' => (int)$id ] );
if ( $layout_id )
$mdb -> insert( 'pp_layouts_pages', [ 'page_id' => (int)$id, 'layout_id' => (int)$layout_id ] );
foreach ( $title as $key => $val )
{
$mdb -> insert( 'pp_pages_langs', [
'page_id' => (int)$id,
'lang_id' => $key,
'title' => $title[$key] != '' ? $title[$key] : null,
'meta_description' => $meta_description[$key] != '' ? $meta_description[$key] : null,
'meta_keywords' => $meta_keywords[$key] != '' ? $meta_keywords[$key] : null,
'meta_title' => $meta_title[$key] != '' ? $meta_title[$key] : null,
'seo_link' => \S::seo( $seo_link[$key] ) != '' ? \S::seo( $seo_link[$key] ) : null,
'noindex' => $noindex[$key],
'page_title' => $page_title[$key] != '' ? $page_title[$key] : null,
'link' => ( $link[$key] and $page_type == 3 ) ? $link[$key] : null,
'canonical' => $canonical[$key] != '' ? $canonical[$key] : null
] );
}
\S::htacces();
\S::delete_dir( '../temp/' );
return $id;
}
}
else
{
$mdb -> update( 'pp_pages', [
'menu_id' => (int)$menu_id,
'page_type' => $page_type,
'sort_type' => $sort_type,
'articles_limit' => $articles_limit,
'show_title' => $show_title == 'on' ? 1 : 0,
'status' => $status == 'on' ? 1 : 0,
'parent_id' => $parent_id,
'start' => $start == 'on' ? 1 : 0,
'category_id' => ( $category_id and $page_type == 5 ) ? $category_id : null
], [
'id' => (int)$page_id
] );
if ( $layout_id )
{
$mdb -> delete( 'pp_layouts_pages', [ 'page_id' => (int)$page_id ] );
$mdb -> insert( 'pp_layouts_pages', [ 'layout_id' => (int)$layout_id, 'page_id' => (int)$page_id ] );
}
if ( $start )
$mdb -> update( 'pp_pages', [ 'start' => 0 ], [ 'id[!]' => (int)$page_id ] );
foreach ( $title as $key => $val )
{
if ( $translation_id = $mdb -> get( 'pp_pages_langs', 'id', [ 'AND' => [ 'page_id' => $page_id, 'lang_id' => $key ] ] ) )
$mdb -> update( 'pp_pages_langs', [
'lang_id' => $key,
'title' => $title[$key] != '' ? $title[$key] : null,
'meta_description' => $meta_description[$key] != '' ? $meta_description[$key] : null,
'meta_keywords' => $meta_keywords[$key] != '' ? $meta_keywords[$key] : null,
'meta_title' => $meta_title[$key] != '' ? $meta_title[$key] : null,
'seo_link' => \S::seo( $seo_link[$key] ) != '' ? \S::seo( $seo_link[$key] ) : null,
'noindex' => $noindex[$key],
'page_title' => $page_title[$key] != '' ? $page_title[$key] : null,
'link' => ( $link[$key] and $page_type == 3 ) ? $link[$key] : null,
'canonical' => $canonical[$key] != '' ? $canonical[$key] : null
], [
'id' => $translation_id
] );
else
$mdb -> insert( 'pp_pages_langs', [
'page_id' => (int)$page_id,
'lang_id' => $key,
'title' => $title[$key] != '' ? $title[$key] : null,
'meta_description' => $meta_description[$key] != '' ? $meta_description[$key] : null,
'meta_keywords' => $meta_keywords[$key] != '' ? $meta_keywords[$key] : null,
'meta_title' => $meta_title[$key] != '' ? $meta_title[$key] : null,
'seo_link' => \S::seo( $seo_link[$key] ) != '' ? \S::seo( $seo_link[$key] ) : null,
'noindex' => $noindex[$key],
'page_title' => $page_title[$key] != '' ? $page_title[$key] : null,
'link' => ( $link[$key] and $page_type == 3 ) ? $link[$key] : null,
'canonical' => $canonical[$key] != '' ? $canonical[$key] : null
] );
}
self::update_supages_menu_id( $page_id, $menu_id );
\S::htacces();
\S::delete_dir( '../temp/' );
return $page_id;
}
return false;
}
public static function update_supages_menu_id( $parent_id, $menu_id )
{
global $mdb;
$mdb -> update( 'pp_pages', [ 'menu_id' => (int)$menu_id ], [ 'parent_id' => $parent_id ] );
$results = $mdb -> select( 'pp_pages', [ 'id' ], [ 'parent_id' => $parent_id ] );
if ( is_array( $results ) ) foreach ( $results as $row )
self::update_supages_menu_id( $row['id'], $menu_id );
}
public static function generate_seo_link( $title, $page_id, $article_id, $category_id )
{
global $mdb;
$seo_link = \S::seo( $title );
while ( !$seo_link_check )
{
if ( $mdb -> count( 'pp_pages_langs', [ 'AND' => [ 'seo_link' => $seo_link, 'page_id[!]' => (int)$page_id ] ] ) )
$seo_link = \S::seo( $title ) . '-' . ( ++$i );
else
$seo_link_check = true;
}
$seo_link_check = false;
while ( !$seo_link_check )
{
if ( $mdb -> count( 'pp_articles_langs', [ 'AND' => [ 'seo_link' => $seo_link, 'article_id[!]' => (int)$article_id ] ] ) )
$seo_link = \S::seo( $title ) . '-' . ( ++$i );
else
$seo_link_check = true;
}
$seo_link_check = false;
while ( !$seo_link_check )
{
if ( $mdb -> count( 'pp_shop_categories_langs', [ 'AND' => [ 'seo_link' => $seo_link, 'category_id[!]' => (int)$category_id ] ] ) )
$seo_link = \S::seo( $title ) . '-' . ( ++$i );
else
$seo_link_check = true;
}
return $seo_link;
}
public static function menu_delete( $menu_id )
{
global $mdb;
if ( $mdb -> count( 'pp_pages', [ 'menu_id' => (int)$menu_id ] ) )
return false;
return $mdb -> delete( 'pp_menus', [ 'id' => (int)$menu_id ] );
}
public static function menu_details( $menu_id )
{
global $mdb;
return $mdb -> get( 'pp_menus', '*', [ 'id' => (int)$menu_id ] );
}
public static function menu_save( $menu_id, $name, $status )
{
global $mdb;
$status == 'on' ? $status = 1 : $status = 0;
if ( !$menu_id )
{
return $mdb -> insert( 'pp_menus', [
'name' => $name,
'status' => $status
] );
}
else
{
$mdb -> update( 'pp_menus', [
'name' => $name,
'status' => $status
], [
'id' => (int)$menu_id
] );
return true;
}
return false;
}
public static function menu_lists()
{
global $mdb;
return $mdb -> select( 'pp_menus', '*', [ 'ORDER' => [ 'id' => 'ASC' ] ] );
}
public static function page_details( $page_id )
{
global $mdb;
$page = $mdb -> get( 'pp_pages', '*', [ 'id' => (int)$page_id ] );
$results = $mdb -> select( 'pp_pages_langs', '*', [ 'page_id' => (int)$page_id ] );
if ( is_array( $results ) ) foreach ( $results as $row )
$page['languages'][ $row['lang_id'] ] = $row;
$page['layout_id'] = $mdb -> get( 'pp_layouts_pages', 'layout_id', [ 'page_id' => (int)$page_id ] );
return $page;
}
public static function page_url( $page_id )
{
global $mdb;
$results = $mdb -> query( "SELECT seo_link FROM pp_pages_langs AS ppl, pp_langs AS pl WHERE lang_id = pl.id AND page_id = " . (int)$page_id . " AND seo_link != '' ORDER BY o ASC LIMIT 1" ) -> fetchAll();
if ( !$results[0]['seo_link'] )
{
$title = self::page_title( $article_id );
return 's-' . $page_id . '-' . \S::seo( $title );
}
else
return $results[0]['seo_link'];
}
public static function page_title( $page_id )
{
global $mdb;
$result = $mdb -> select( 'pp_pages_langs', [
'[><]pp_langs' => [ 'lang_id' => 'id' ]
], 'title', [
'AND' => [
'page_id' => (int)$page_id, 'title[!]' => ''
],
'ORDER' => [ 'o' => 'ASC' ],
'LIMIT' => 1
] );
return $result[0];
}
public static function page_languages( $page_id )
{
global $mdb;
return $mdb -> select( 'pp_pages_langs', '*',
[ 'AND' => [ 'page_id' => (int) $page_id, 'title[!]' => null ] ] );
}
public static function menu_pages( $menu_id, $parent_id = null )
{
global $mdb;
$results = $mdb -> select( 'pp_pages',
[ 'id', 'menu_id', 'status', 'parent_id', 'start' ],
[ 'AND' => [ 'menu_id' => $menu_id, 'parent_id' => $parent_id ], 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( is_array( $results ) ) foreach ( $results as $row )
{
$row['title'] = self::page_title( $row['id'] );
$row['languages'] = self::page_languages( $row['id'] );
$row['subpages'] = self::menu_pages( $menu_id, $row['id'] );
$pages[] = $row;
}
return $pages;
}
}
?>

View File

@@ -1,37 +0,0 @@
<?
namespace admin\view;
class Pages
{
public static function subpages_browse_list( $pages, $parent_id = null, $step = 1 )
{
$tpl = new \Tpl();
$tpl -> pages = $pages;
$tpl -> parent_id = $parent_id;
$tpl -> step = $step;
return $tpl -> render( 'pages/subpages-browse-list' );
}
public static function browse_list( $menus )
{
$tpl = new \Tpl;
$tpl -> menus = $menus;
return $tpl -> render( 'pages/pages-browse-list' );
}
public static function page_articles( $page_id, $articles )
{
$tpl = new \Tpl;
$tpl -> page_id = $page_id;
$tpl -> articles = $articles;
return $tpl -> render( 'pages/page-articles' );
}
public static function menu_edit( $menu )
{
$tpl = new \Tpl;
$tpl -> menu = $menu;
return $tpl -> render( 'pages/menu-edit' );
}
}
?>

View File

@@ -0,0 +1,66 @@
<?php
namespace Tests\Unit\Domain\Pages;
use Domain\Pages\PagesRepository;
use PHPUnit\Framework\TestCase;
class PagesRepositoryTest extends TestCase
{
public function testMenusListReturnsArray(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->once())
->method('select')
->with('pp_menus', '*', ['ORDER' => ['id' => 'ASC']])
->willReturn([
['id' => 1, 'name' => 'Main'],
]);
$repository = new PagesRepository($mockDb);
$menus = $repository->menusList();
$this->assertCount(1, $menus);
$this->assertSame(1, (int)$menus[0]['id']);
$this->assertSame('Main', (string)$menus[0]['name']);
}
public function testMenuDeleteReturnsFalseWhenMenuHasPages(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->once())
->method('count')
->with('pp_pages', ['menu_id' => 3])
->willReturn(2);
$mockDb->expects($this->never())->method('delete');
$repository = new PagesRepository($mockDb);
$this->assertFalse($repository->menuDelete(3));
}
public function testGenerateSeoLinkAddsSuffixWhenBaseSlugExists(): void
{
$mockDb = $this->createMock(\medoo::class);
$mockDb->expects($this->exactly(4))
->method('count')
->willReturnOnConsecutiveCalls(1, 0, 0, 0);
$repository = new PagesRepository($mockDb);
$seoLink = $repository->generateSeoLink('test title', 0, 0, 0);
$this->assertSame('test title-1', $seoLink);
}
public function testPageUrlPreviewBuildsLanguagePrefixedUrlForNonDefaultLanguage(): void
{
$mockDb = $this->createMock(\medoo::class);
$repository = new PagesRepository($mockDb);
$url = $repository->pageUrlPreview(5, 'en', 'About us', 'about-us', 'pl');
$this->assertSame('/en/about-us', $url);
}
}

View File

@@ -6,12 +6,14 @@ use admin\Controllers\ArticlesController;
use Domain\Article\ArticleRepository; use Domain\Article\ArticleRepository;
use Domain\Languages\LanguagesRepository; use Domain\Languages\LanguagesRepository;
use Domain\Layouts\LayoutsRepository; use Domain\Layouts\LayoutsRepository;
use Domain\Pages\PagesRepository;
class ArticlesControllerTest extends TestCase class ArticlesControllerTest extends TestCase
{ {
private $mockRepository; private $mockRepository;
private $mockLanguagesRepository; private $mockLanguagesRepository;
private $mockLayoutsRepository; private $mockLayoutsRepository;
private $mockPagesRepository;
private $controller; private $controller;
protected function setUp(): void protected function setUp(): void
@@ -19,10 +21,12 @@ class ArticlesControllerTest extends TestCase
$this->mockRepository = $this->createMock(ArticleRepository::class); $this->mockRepository = $this->createMock(ArticleRepository::class);
$this->mockLanguagesRepository = $this->createMock(LanguagesRepository::class); $this->mockLanguagesRepository = $this->createMock(LanguagesRepository::class);
$this->mockLayoutsRepository = $this->createMock(LayoutsRepository::class); $this->mockLayoutsRepository = $this->createMock(LayoutsRepository::class);
$this->mockPagesRepository = $this->createMock(PagesRepository::class);
$this->controller = new ArticlesController( $this->controller = new ArticlesController(
$this->mockRepository, $this->mockRepository,
$this->mockLanguagesRepository, $this->mockLanguagesRepository,
$this->mockLayoutsRepository $this->mockLayoutsRepository,
$this->mockPagesRepository
); );
} }
@@ -36,7 +40,8 @@ class ArticlesControllerTest extends TestCase
$controller = new ArticlesController( $controller = new ArticlesController(
$this->mockRepository, $this->mockRepository,
$this->mockLanguagesRepository, $this->mockLanguagesRepository,
$this->mockLayoutsRepository $this->mockLayoutsRepository,
$this->mockPagesRepository
); );
$this->assertInstanceOf(ArticlesController::class, $controller); $this->assertInstanceOf(ArticlesController::class, $controller);
} }
@@ -124,9 +129,10 @@ class ArticlesControllerTest extends TestCase
$constructor = $reflection->getConstructor(); $constructor = $reflection->getConstructor();
$params = $constructor->getParameters(); $params = $constructor->getParameters();
$this->assertCount(3, $params); $this->assertCount(4, $params);
$this->assertEquals('Domain\Article\ArticleRepository', $params[0]->getType()->getName()); $this->assertEquals('Domain\Article\ArticleRepository', $params[0]->getType()->getName());
$this->assertEquals('Domain\Languages\LanguagesRepository', $params[1]->getType()->getName()); $this->assertEquals('Domain\Languages\LanguagesRepository', $params[1]->getType()->getName());
$this->assertEquals('Domain\Layouts\LayoutsRepository', $params[2]->getType()->getName()); $this->assertEquals('Domain\Layouts\LayoutsRepository', $params[2]->getType()->getName());
$this->assertEquals('Domain\Pages\PagesRepository', $params[3]->getType()->getName());
} }
} }

View File

@@ -0,0 +1,82 @@
<?php
namespace Tests\Unit\admin\Controllers;
use admin\Controllers\PagesController;
use Domain\Languages\LanguagesRepository;
use Domain\Layouts\LayoutsRepository;
use Domain\Pages\PagesRepository;
use PHPUnit\Framework\TestCase;
class PagesControllerTest extends TestCase
{
private $mockRepository;
private $mockLanguagesRepository;
private $mockLayoutsRepository;
private $controller;
protected function setUp(): void
{
$this->mockRepository = $this->createMock(PagesRepository::class);
$this->mockLanguagesRepository = $this->createMock(LanguagesRepository::class);
$this->mockLayoutsRepository = $this->createMock(LayoutsRepository::class);
$this->controller = new PagesController(
$this->mockRepository,
$this->mockLanguagesRepository,
$this->mockLayoutsRepository
);
}
public function testConstructorAcceptsRepositories(): void
{
$controller = new PagesController(
$this->mockRepository,
$this->mockLanguagesRepository,
$this->mockLayoutsRepository
);
$this->assertInstanceOf(PagesController::class, $controller);
}
public function testHasMainActionMethods(): void
{
$this->assertTrue(method_exists($this->controller, 'list'));
$this->assertTrue(method_exists($this->controller, 'edit'));
$this->assertTrue(method_exists($this->controller, 'save'));
$this->assertTrue(method_exists($this->controller, 'delete'));
$this->assertTrue(method_exists($this->controller, 'menuEdit'));
$this->assertTrue(method_exists($this->controller, 'menuSave'));
$this->assertTrue(method_exists($this->controller, 'menuDelete'));
$this->assertTrue(method_exists($this->controller, 'savePagesOrder'));
$this->assertTrue(method_exists($this->controller, 'saveArticlesOrder'));
$this->assertTrue(method_exists($this->controller, 'generateSeoLink'));
}
public function testActionMethodReturnTypes(): void
{
$reflection = new \ReflectionClass($this->controller);
$this->assertEquals('string', (string)$reflection->getMethod('list')->getReturnType());
$this->assertEquals('string', (string)$reflection->getMethod('edit')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('save')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('delete')->getReturnType());
$this->assertEquals('string', (string)$reflection->getMethod('menuEdit')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('menuSave')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('menuDelete')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('savePagesOrder')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('saveArticlesOrder')->getReturnType());
$this->assertEquals('void', (string)$reflection->getMethod('generateSeoLink')->getReturnType());
}
public function testConstructorRequiresPagesLanguagesAndLayoutsRepositories(): void
{
$reflection = new \ReflectionClass(PagesController::class);
$constructor = $reflection->getConstructor();
$params = $constructor->getParameters();
$this->assertCount(3, $params);
$this->assertEquals('Domain\Pages\PagesRepository', $params[0]->getType()->getName());
$this->assertEquals('Domain\Languages\LanguagesRepository', $params[1]->getType()->getName());
$this->assertEquals('Domain\Layouts\LayoutsRepository', $params[2]->getType()->getName());
}
}

BIN
updates/0.20/ver_0.262.zip Normal file

Binary file not shown.

View File

@@ -0,0 +1,4 @@
F: ../admin/ajax/pages.php
F: ../autoload/admin/controls/class.Pages.php
F: ../autoload/admin/factory/class.Pages.php
F: ../autoload/admin/view/class.Pages.php

View File

@@ -1,4 +1,11 @@
<b>ver. 0.261 - 13.02.2026</b><br /> <b>ver. 0.262 - 13.02.2026</b><br />
- NEW - migracja modulu `Pages` do architektury Domain + DI (`Domain\\Pages\\PagesRepository`, `admin\\Controllers\\PagesController`)
- UPDATE - widoki `/admin/pages/*` przepiete na nowy routing i komponent `components/form-edit` (menu/page edit)
- FIX - przywrocony przycisk generowania linku SEO w edycji strony (zakladka SEO, pola jezykowe)
- FIX - popup potwierdzenia usuwania menu/strony ujednolicony z `table-list-confirm-dialog` + poprawione polskie znaki
- CLEANUP - usuniete legacy pliki Pages: `admin/ajax/pages.php`, `autoload/admin/controls/class.Pages.php`, `autoload/admin/factory/class.Pages.php`, `autoload/admin/view/class.Pages.php`
- UPDATE - pliki aktualizacji: `updates/0.20/ver_0.262.zip`, `ver_0.262_files.txt`
<hr><b>ver. 0.261 - 13.02.2026</b><br />
- UPDATE - finalizacja refaktoryzacji modulu `Articles` (`/admin/articles`) w warstwie Domain + DI - UPDATE - finalizacja refaktoryzacji modulu `Articles` (`/admin/articles`) w warstwie Domain + DI
- UPDATE - nowe akcje AJAX w `admin\Controllers\ArticlesController` (m.in. `files_order_save`) - UPDATE - nowe akcje AJAX w `admin\Controllers\ArticlesController` (m.in. `files_order_save`)
- UPDATE - sortowanie zalacznikow i zdjec w edycji artykulu (drag&drop + zapis kolejnosci przy pierwszym zapisie) - UPDATE - sortowanie zalacznikow i zdjec w edycji artykulu (drag&drop + zapis kolejnosci przy pierwszym zapisie)
@@ -430,3 +437,4 @@

View File

@@ -1,5 +1,5 @@
<? <?
$current_ver = 261; $current_ver = 262;
for ($i = 1; $i <= $current_ver; $i++) for ($i = 1; $i <= $current_ver; $i++)
{ {
@@ -46,3 +46,4 @@ else
} }