Add author management functionality and update routing rules

- Updated .htaccess rules to allow trailing slashes for specific routes.
- Introduced a new .gitignore file to exclude the cache directory.
- Created project configuration file for Serena with language and tool settings.
- Implemented Authors class for managing author data, including methods for saving, deleting, and editing authors.
- Added factory class for Authors to handle database interactions related to authors.
- Developed Article class to manage article data and interactions, including fetching articles and updating views.
- Created Page class with a placeholder method for sorting pages.
- Added front factory class for fetching author details with caching.
This commit is contained in:
2026-02-27 11:28:56 +01:00
parent 146bdb0b14
commit c9ed7b5d5d
29 changed files with 2996 additions and 1844 deletions

View File

@@ -1,71 +1,216 @@
<?php
namespace admin;
class Site
{
// define APP_SECRET_KEY
const APP_SECRET_KEY = 'c3cb2537d25c0efc9e573d059d79c3b8';
public static function special_actions()
{
$sa = \S::get( 's-action' );
$domain = preg_replace( '#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME'] );
$cookie_name = str_replace( '.', '-', $domain );
switch ( $sa )
$sa = \S::get('s-action');
$domain = preg_replace('#^(http(s)?://)?w{3}\.#', '$1', $_SERVER['SERVER_NAME']);
$cookie_name = str_replace('.', '-', $domain);
switch ($sa)
{
case 'user-logon':
$result = \admin\factory\Users::logon( \S::get( 'login' ), \S::get( 'password' ) );
if ( $result == 1 )
{
if(\S::get('remember'))
{
$password = md5( \S::get( 'password' ) );
$login = \S::get( 'login' );
$value = [ login => $login , hash => $password ];
$value = json_encode( $value );
setcookie( $cookie_name, $value, time() +(86400 * 14), "/", $domain );
}
\S::set_session( 'user', \admin\factory\Users::details( \S::get( 'login' ) ) );
}
else
{
if ( $result == -1 )
\S::alert( 'Z powodu nieudanych 5 prób logowania Twoje konto zostało zablokowane.' );
else
\S::alert( 'Podane hasło jest nieprawidłowe, lub brak użytkownika o podanym loginie.' );
}
header( 'Location: /admin/articles/view_list/' );
exit;
break;
case 'user-logout':
$login = \S::get('login');
$pass = \S::get('password');
setcookie( $cookie_name, "", time() -(86400), "/", $domain );
session_destroy();
header( 'Location: /admin/' );
exit;
break;
$result = \admin\factory\Users::logon($login, $pass);
if ($result == 1)
{
$user = \admin\factory\Users::details($login);
if ($user['twofa_enabled'] == 1)
{
\S::set_session('twofa_pending', [
'uid' => (int)$user['id'],
'login' => $login,
'remember' => (bool)\S::get('remember'),
'started' => time(),
]);
if (!\admin\factory\Users::send_twofa_code((int)$user['id']))
{
\S::alert('Nie udało się wysłać kodu 2FA. Spróbuj ponownie.');
\S::delete_session('twofa_pending');
header('Location: /admin/');
exit;
}
header('Location: /admin/user/twofa/');
exit;
}
else
{
$user = \admin\factory\Users::details($login);
self::finalize_admin_login(
$user,
$domain,
$cookie_name,
(bool)\S::get('remember')
);
header('Location: /admin/articles/view_list/');
exit;
}
}
else
{
if ($result == -1)
{
\S::alert('Z powodu 5 nieudanych prób Twoje konto zostało zablokowane.');
}
else
{
\S::alert('Podane hasło jest nieprawidłowe lub użytkownik nie istnieje.');
}
header('Location: /admin/');
exit;
}
}
break;
case 'user-2fa-verify':
{
$pending = \S::get_session('twofa_pending');
if (!$pending || empty($pending['uid']))
{
\S::alert('Sesja 2FA wygasła. Zaloguj się ponownie.');
header('Location: /admin/');
exit;
}
$code = trim((string)\S::get('twofa'));
if (!preg_match('/^\d{6}$/', $code))
{
\S::alert('Nieprawidłowy format kodu.');
header('Location: /admin/user/twofa/');
exit;
}
$ok = \admin\factory\Users::verify_twofa_code((int)$pending['uid'], $code);
if (!$ok)
{
\S::alert('Błędny lub wygasły kod.');
header('Location: /admin/user/twofa/');
exit;
}
// 2FA OK — finalna sesja
$user = \admin\factory\Users::details($pending['login']);
\S::set_session('user', $user);
\S::delete_session('twofa_pending');
// Remember me BEZPIECZNY podpis HMAC:
if (!empty($pending['remember']))
{
$payloadArr = ['login' => $user['login'], 'ts' => time()];
$json = json_encode($payloadArr, JSON_UNESCAPED_SLASHES);
$sig = hash_hmac('sha256', $json, APP_SECRET_KEY);
$payload = base64_encode($json . '.' . $sig);
setcookie($cookie_name, $payload, [
'expires' => time() + (86400 * 14),
'path' => '/',
'domain' => $domain,
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
}
header('Location: /admin/articles/view_list/');
exit;
}
break;
case 'user-2fa-resend':
{
$pending = \S::get_session('twofa_pending');
if (!$pending || empty($pending['uid']))
{
\S::alert('Sesja 2FA wygasła. Zaloguj się ponownie.');
header('Location: /admin/');
exit;
}
if (!\admin\factory\Users::send_twofa_code((int)$pending['uid'], true))
{
\S::alert('Kod można wysłać ponownie po krótkiej przerwie.');
}
else
{
\S::alert('Nowy kod został wysłany.');
}
header('Location: /admin/user/twofa/');
exit;
}
break;
case 'user-logout':
{
setcookie($cookie_name, "", time() - 86400, "/", $domain);
\S::delete_session('twofa_pending');
session_destroy();
header('Location: /admin/');
exit;
}
break;
}
}
public static function route()
{
{
$_SESSION['admin'] = true;
$class = '\admin\controls\\';
$results = explode( '_', \S::get( 'module' ) );
if ( is_array( $results ) ) foreach ( $results as $row )
$class .= ucfirst( $row );
$action = \S::get( 'action' );
if ( class_exists( $class ) and method_exists( new $class, $action ) )
return call_user_func_array( array( $class, $action ), array() );
$results = explode('_', \S::get('module'));
if (is_array($results)) foreach ($results as $row)
$class .= ucfirst($row);
$action = \S::get('action');
if (class_exists($class) and method_exists(new $class, $action))
return call_user_func_array(array($class, $action), array());
else
{
\S::alert( 'Nieprawidłowy adres url.' );
\S::alert('Nieprawidłowy adres url.');
return false;
}
}
static public function finalize_admin_login(array $user, string $domain, string $cookie_name, bool $remember = false) {
\S::set_session('user', $user);
\S::delete_session('twofa_pending');
if ($remember)
{
$payloadArr = [
'login' => $user['login'],
'ts' => time()
];
$json = json_encode($payloadArr, JSON_UNESCAPED_SLASHES);
$sig = hash_hmac('sha256', $json, self::APP_SECRET_KEY);
$payload = base64_encode($json . '.' . $sig);
setcookie($cookie_name, $payload, [
'expires' => time() + (86400 * 14),
'path' => '/',
'domain' => $domain,
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
}
}
}

View File

@@ -2,6 +2,17 @@
namespace admin\controls;
class Articles
{
//autorzy artykułów
static public function articles_authors()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
return \Tpl::view( 'articles/articles-authors' );
}
public static function duplicate_article()
{
global $user;
@@ -16,6 +27,22 @@ class Articles
exit;
}
static public function files_order_save()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
{
echo json_encode( [ 'status' => 'error', 'msg' => 'Nie masz uprawnień' ] );
exit;
}
if ( \admin\factory\Articles::files_order_save( \S::get( 'article_id' ), \S::get( 'order' ) ) )
echo json_encode( [ 'status' => 'ok', 'msg' => 'Artykuł został zapisany.' ] );
exit;
}
public static function gallery_order_save()
{
global $user;
@@ -32,6 +59,18 @@ class Articles
exit;
}
static public function article_url_browser()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
return \Tpl::view( 'articles/articles-browse-list', [
'modal' => true
] );
}
public static function browse_list()
{
global $user;
@@ -75,10 +114,10 @@ class Articles
$values['params'] = $params;
if ( $id = \admin\factory\Articles::article_save(
$values['id'], $values['title'], $values['entry'], $values['text'], $values['status'], $values['show_title'], $values['show_date_add'], $values['date_add'],
$values['show_date_modify'], $values['seo_link'], $values['meta_title'], $values['meta_description'], $values['meta_keywords'], $values['layout_id'],
$values['id'], $values['title'], $values['main_image'], $values['entry'], $values['text'], $values['table_of_contents'], $values['status'], $values['show_title'], $values['show_table_of_contents'], $values['show_date_add'], $values['date_add'],
$values['show_date_modify'], $values['date_modify'], $values['seo_link'], $values['meta_title'], $values['meta_description'], $values['meta_keywords'], $values['layout_id'],
$values['pages'], $values['noindex'], $values['repeat_entry'], $values['copy_from'], $values['social_icons'], $values['event_date'], $values['hidden-tags'], $values['block_direct_access'],
$values['priority'], $values['password'], $values['pixieset'], $params
$values['priority'], $values['password'], $values['pixieset'], $values['id_author'], $params
) )
$response = [ 'status' => 'ok', 'msg' => 'Artykuł został zapisany.', 'id' => $id ];
@@ -92,22 +131,23 @@ class Articles
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration',
$user['id'] ) )
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
\admin\factory\Articles::delete_nonassigned_images();
\admin\factory\Articles::delete_nonassigned_files();
return \admin\view\Articles::article_edit( [
'article' => \admin\factory\Articles::article_details( \S::get( 'id' ) ),
'menus' => \admin\factory\Pages::menus_list(),
'languages' => \admin\factory\Languages::languages_list(),
'layouts' => \admin\factory\Layouts::layouts_list(),
'additional_params_lon' => \admin\factory\Articles::additional_params( 1 ),
'additional_params_loff' => \admin\factory\Articles::additional_params( 0 ),
'settings' => \admin\factory\Settings::settings_details()
] );
'article' => \admin\factory\Articles::article_details( \S::get( 'id' ) ),
'menus' => \admin\factory\Pages::menus_list(),
'languages' => \admin\factory\Languages::languages_list(),
'layouts' => \admin\factory\Layouts::layouts_list(),
'additional_params_lon' => \admin\factory\Articles::additional_params( 1 ),
'additional_params_loff' => \admin\factory\Articles::additional_params( 0 ),
'settings' => \admin\factory\Settings::settings_details(),
'authors' => \admin\factory\Authors::get_simple_list(),
'user' => $user
] );
}
public static function view_list()
@@ -119,6 +159,5 @@ class Articles
return \admin\view\Articles::articles_list();
}
}
?>

View File

@@ -0,0 +1,65 @@
<?
namespace admin\controls;
class Authors
{
// usunięcie autora
static public function delete()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
$response = [ 'status' => 'error', 'msg' => 'Podczas usuwania autora wystąpił błąd. Proszę spróbować ponownie.' ];
$values = \S::json_to_array( \S::get( 'values' ) );
if ( \admin\factory\Authors::delete_author( \S::get( 'id' ) ) )
\S::alert( 'Autor został usunięty.' );
header( 'Location: /admin/authors/view_list/' );
exit;
}
// zapis autora
static public function save()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
$response = [ 'status' => 'error', 'msg' => 'Podczas zapisywania autora wystąpił błąd. Proszę spróbować ponownie.' ];
$values = \S::json_to_array( \S::get( 'values' ) );
if ( $author_id = \admin\factory\Authors::save_author( $values['id'], $values['author'], $values['image'], $values['description'] ) )
$response = [ 'status' => 'ok', 'msg' => 'Autor został zapisany.', 'id' => $author_id ];
echo json_encode( $response );
exit;
}
// edycja autora
static public function edit()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
return \Tpl::view( 'authors/author-edit', [
'author' => \admin\factory\Authors::get_single_author( \S::get( 'id' ) ),
'languages' => \admin\factory\Languages::languages_list()
] );
}
//autorzy artykułów
static public function view_list()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'article_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
return \Tpl::view( 'authors/view-list' );
}
}

View File

@@ -4,21 +4,20 @@ namespace admin\controls;
class Pages
{
public static function pages_url_browser()
static public function pages_url_browser()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'page_administration', $user['id'] ) )
return \S::alert( 'Nie masz uprawnień' );
echo \admin\view\Pages::browse_list(
\admin\factory\Pages::menus_list(),
\S::get( 'modal' )
);
exit;
return \Tpl::view( 'pages/pages-browse-list', [
'menus' => \admin\factory\Pages::menus_list(),
'modal' => true
] );
}
public static function browse_list()
static public function browse_list()
{
global $user;

View File

@@ -2,40 +2,73 @@
namespace admin\controls;
class Settings
{
{
public static function settings_save()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'settings_administration', $user['id'] ) )
return \S::alert('Nie masz uprawnień');
$settings = \admin\factory\Settings::settings_details();
$values = \S::json_to_array( \S::get( 'values' ) );
\admin\factory\Settings::settings_save(
$values['firm_name'], $values['firm_adress'], $values['additional_info'], $values['contact_form'], $values['contact_email'], $values['email_host'],
$values['email_port'], $values['email_login'], $values['email_password'], $values['google_maps'], $values['facebook_link'], $values['statistic_code'], $values['htaccess'],
$values['robots'], $settings['newsletter_header'], $settings['newsletter_footer_1'], $settings['newsletter_footer_2'], $values['google_map_key'], $values['google_search_console'], $values['update'], $values['devel'],
$values['news_limit'], $values['visit_counter'], $values['calendar'], $values['tags'], $values['ssl'], $values['mysql_debug'], $values['htaccess_cache'], $settings['visits'],
$values['links_structure'], $values['link_version'], $values['widget_phone'], $values['update_key'], $values['newsletter_cron']
\admin\factory\Settings::settings_save(
$values['firm_name'],
$values['firm_adress'],
$values['additional_info'],
$values['contact_form'] == 'on' ? 1 : 0,
$values['contact_email'],
$values['email_host'],
$values['email_port'],
$values['email_login'],
$values['email_password'],
$values['google_maps'],
$values['facebook_link'],
$values['statistic_code'],
$values['htaccess'],
$values['robots'],
$settings['newsletter_header'],
$settings['newsletter_footer_1'],
$settings['newsletter_footer_2'],
$values['google_map_key'],
$values['google_search_console'],
$values['update'],
$values['devel'],
$values['news_limit'],
$values['visit_counter'],
$values['calendar'],
$values['tags'],
$values['ssl'],
$values['mysql_debug'],
$values['htaccess_cache'],
$settings['visits'],
$values['links_structure'],
$values['link_version'],
$values['widget_phone'],
$values['update_key']
);
\admin\factory\Settings::settings_update( 'image_px', $values['image_px'] );
\admin\factory\Settings::settings_update( 'newsletter_cron', $values['newsletter_cron'] );
\admin\factory\Settings::settings_update( 'lazy_loading', $values['lazy_loading'] == 'on' ? 1 : 0 );
\admin\factory\Settings::settings_update( 'generate_webp', $values['generate_webp'] == 'on' ? 1 : 0 );
\admin\factory\Settings::settings_update( 'contact_form_captcha', $values['contact_form_captcha'] == 'on' ? 1 : 0 );
\admin\factory\Settings::settings_update( 'url_version', $values['url_version'] );
\S::alert( 'Ustawienia zostały zapisane.' );
echo json_encode( [ 'status' => 'ok', 'msg' => 'Ustawienia zostały zapisane.' ] );
exit;
}
public static function view()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'settings_administration', $user['id']))
return \S::alert('Nie masz uprawnień');
return \admin\view\Settings::view(
\admin\factory\Settings::settings_details()
);

View File

@@ -1,59 +1,65 @@
<?php
namespace admin\controls;
class Users
{
class Users
{
public static function user_delete()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'users_administration', $user['id'] ) )
return \S::alert('Nie masz uprawnień');
if ( \admin\factory\Users::user_delete( \S::get( 'id' ) ) )
\S::alert( 'Użytkownik został usunięty.' );
header( 'Location: /admin/users/view_list/' );
exit;
exit;
}
public static function user_save()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'users_administration', $user['id'] ) )
return \S::alert('Nie masz uprawnień');
$values = \S::json_to_array( \S::get( 'values' ) );
$response = \admin\factory\Users::user_save(
$values['id'], $values['login'], $values['status'], $values['active_to'], $values['password'], $values['password_re'], $values['admin'], $values['privileges']
$response = \admin\factory\Users::user_save(
$values['id'], $values['login'], $values['status'], $values['active_to'], $values['password'], $values['password_re'], $values['admin'], $values['privileges'], $values['twofa_enabled'], $values['twofa_email']
);
echo json_encode( $response );
exit;
}
public static function user_edit()
{
global $user;
if ( !\admin\factory\Users::check_privileges( 'users_administration', $user['id'] ) )
return \S::alert('Nie masz uprawnień');
return \admin\view\Users::user_edit(
\admin\factory\Users::user_details(
return \admin\view\Users::user_edit(
\admin\factory\Users::user_details(
\S::get( 'id' ) ),
\admin\factory\Users::user_privileges(
\admin\factory\Users::user_privileges(
\S::get( 'id' ) )
);
);
}
public static function view_list()
{
global $user;
if( !\admin\factory\Users::check_privileges( 'users_administration', $user['id']))
return \S::alert('Nie masz uprawnień');
return \admin\view\Users::users_list();
}
static public function twofa() {
return \Tpl::view( 'site/unlogged', [
'content' => \Tpl::view( 'users/user-2fa' )
] );
}
}
?>

View File

@@ -86,6 +86,24 @@ class Articles
return true;
}
static public function files_order_save( $article_id, $order )
{
global $mdb;
$order = explode( ';', $order );
if ( is_array( $order ) and !empty( $order ) ) foreach ( $order as $file_id )
{
$mdb -> update( 'pp_articles_files', [
'o' => (int)$i++
], [
'AND' => [
'article_id' => $article_id,
'id' => $file_id
]
] );
}
}
public static function gallery_order_save( $article_id, $order )
{
global $mdb;
@@ -222,7 +240,7 @@ class Articles
$article['languages'][ $row['lang_id'] ] = $row;
$article['images'] = $mdb -> select( 'pp_articles_images', '*', [ 'article_id' => (int)$article_id, 'ORDER' => [ 'o' => 'ASC', 'id' => 'ASC' ] ] );
$article['files'] = $mdb -> select( 'pp_articles_files', '*', [ 'article_id' => (int)$article_id ] );
$article['files'] = $mdb -> select( 'pp_articles_files', '*', [ 'article_id' => (int)$article_id, 'ORDER' => [ 'o' => 'ASC', 'id' => 'ASC' ] ] );
$article['pages'] = $mdb -> select( 'pp_articles_pages', 'page_id', [ 'article_id' => (int)$article_id ] );
$article['tags'] = $mdb -> select( 'pp_tags', [ '[><]pp_articles_tags' => [ 'id' => 'tag_id' ] ], 'name', [ 'article_id' => (int)$article_id ] );
$article['params'] = $mdb -> select( 'pp_articles_additional_values', [ 'param_id', 'value', 'language_id' ], [ 'article_id' => (int)$article_id ] );
@@ -238,9 +256,9 @@ class Articles
}
public static function article_save(
$article_id, $title, $entry, $text, $status, $show_title, $show_date_add, $date_add, $show_date_modify, $seo_link, $meta_title, $meta_description,
$article_id, $title, $main_image, $entry, $text, $table_of_contents, $status, $show_title, $show_table_of_contents, $show_date_add, $date_add, $show_date_modify, $date_modify, $seo_link, $meta_title, $meta_description,
$meta_keywords, $layout_id, $pages, $noindex, $repeat_entry, $copy_from, $social_icons, $event_date, $tags, $block_direct_access, $priority,
$password, $pixieset, $params )
$password, $pixieset, $id_author, $params )
{
global $mdb, $user;
@@ -251,10 +269,11 @@ class Articles
{
$mdb -> insert( 'pp_articles', [
'show_title' => $show_title == 'on' ? 1 : 0,
'show_table_of_contents' => $show_table_of_contents == 'on' ? 1 : 0,
'show_date_add' => $show_date_add == 'on' ? 1 : 0,
'show_date_modify' => $show_date_modify == 'on' ? 1 : 0,
'date_add' => $date_add ? $date_add : date( 'Y-m-d H:i:s' ),
'date_modify' => $date_add ? $date_add : date( 'Y-m-d H:i:s' ),
'date_add' => date( 'Y-m-d H:i:s' ),
'date_modify' => date( 'Y-m-d H:i:s' ),
'modify_by' => $user['id'],
'layout_id' => $layout_id ? (int)$layout_id : null,
'status' => $status == 'on' ? 1 : 0,
@@ -264,7 +283,8 @@ class Articles
'date_end' => $event_date[1] ? $event_date[1] : null,
'priority' => $priority == 'on' ? 1 : 0,
'password' => $password ? $password : null,
'pixieset' => $pixieset
'pixieset' => $pixieset,
'id_author' => $id_author ? $id_author : null
] );
$id = $mdb -> id();
@@ -281,8 +301,10 @@ class Articles
'article_id' => (int)$id,
'lang_id' => $row['id'],
'title' => $title[ $i ] != '' ? $title[ $i ] : null,
'main_image' => $main_image[$i] != '' ? $main_image[$i] : null,
'entry' => $entry[ $i ] != '' ? $entry[ $i ] : null,
'text' => $text[ $i ] != '' ? $text[ $i ] : null,
'table_of_contents' => $table_of_contents[$i] != '' ? $table_of_contents[$i] : null,
'meta_title' => $meta_title[ $i ] != '' ? $meta_title[ $i ] : null,
'meta_description' => $meta_description[ $i ] != '' ? $meta_description[ $i ] : null,
'meta_keywords' => $meta_keywords[ $i ] != '' ? $meta_keywords[ $i ] : null,
@@ -299,8 +321,10 @@ class Articles
'article_id' => (int)$id,
'lang_id' => $row['id'],
'title' => $title != '' ? $title : null,
'main_image' => $main_image != '' ? $main_image : null,
'entry' => $entry != '' ? $entry : null,
'text' => $text != '' ? $text : null,
'table_of_contents' => $table_of_contents != '' ? $table_of_contents : null,
'meta_title' => $meta_title != '' ? $meta_title : null,
'meta_description' => $meta_description != '' ? $meta_description : null,
'meta_keywords' => $meta_keywords != '' ? $meta_keywords : null,
@@ -430,9 +454,11 @@ class Articles
{
$mdb -> update( 'pp_articles', [
'show_title' => $show_title == 'on' ? 1 : 0,
'show_table_of_contents' => $show_table_of_contents == 'on' ? 1 : 0,
'show_date_add' => $show_date_add == 'on' ? 1 : 0,
'date_add' => $date_add,
'show_date_modify' => $show_date_modify == 'on' ? 1 : 0,
'date_modify' => date( 'Y-m-d H:i:s' ),
'date_modify' => $date_modify ? $date_modify : date( 'Y-m-d H:i:s' ),
'modify_by' => $user['id'],
'layout_id' => $layout_id ? (int)$layout_id : null,
'status' => $status == 'on' ? 1 : 0,
@@ -442,7 +468,8 @@ class Articles
'date_end' => $event_date[1] ? $event_date[1] : null,
'priority' => $priority == 'on' ? 1 : 0,
'password' => $password ? $password : null,
'pixieset' => $pixieset
'pixieset' => $pixieset,
'id_author' => $id_author ? $id_author : null
], [
'id' => (int)$article_id
] );
@@ -462,8 +489,10 @@ class Articles
'article_id' => (int)$article_id,
'lang_id' => $row['id'],
'title' => $title[ $i ] != '' ? $title[ $i ] : null,
'main_image' => $main_image[$i] != '' ? $main_image[$i] : null,
'entry' => $entry[ $i ] != '' ? $entry[ $i ] : null,
'text' => $text[ $i ] != '' ? $text[ $i ] : null,
'table_of_contents' => $table_of_contents[$i] != '' ? $table_of_contents[$i] : null,
'meta_title' => $meta_title[ $i ] != '' ? $meta_title[ $i ] : null,
'meta_description' => $meta_description[ $i ] != '' ? $meta_description[ $i ] : null,
'meta_keywords' => $meta_keywords[ $i ] != '' ? $meta_keywords[ $i ] : null,
@@ -480,8 +509,10 @@ class Articles
'article_id' => (int)$article_id,
'lang_id' => $row['id'],
'title' => $title != '' ? $title : null,
'main_image' => $main_image != '' ? $main_image : null,
'entry' => $entry != '' ? $entry : null,
'text' => $text != '' ? $text : null,
'table_of_contents' => $table_of_contents != '' ? $table_of_contents : null,
'meta_title' => $meta_title != '' ? $meta_title : null,
'meta_description' => $meta_description != '' ? $meta_description : null,
'meta_keywords' => $meta_keywords != '' ? $meta_keywords : null,

View File

@@ -0,0 +1,117 @@
<?
namespace admin\factory;
class Authors
{
// prosta lista autorów
static public function get_simple_list()
{
global $mdb;
return $mdb -> select( 'pp_authors', '*', [ 'ORDER' => [ 'author' => 'ASC' ] ] );
}
// usunięcie autora
static public function delete_author( $id_author )
{
global $mdb;
$result = $mdb -> delete( 'pp_authors', [ 'id' => (int)$id_author ] );
\S::delete_cache();
return $result;
}
// zapis autora
static public function save_author( $id_author, $author, $image, $description )
{
global $mdb;
if ( !$id_author )
{
$mdb -> insert( 'pp_authors', [
'author' => $author,
'image' => $image
] );
$id = $mdb -> id();
if ( $id )
{
$i = 0;
$results = $mdb -> select( 'pp_langs', [ 'id' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( is_array( $results ) and count( $results ) > 1 ) foreach ( $results as $row )
{
$mdb -> insert( 'pp_authors_langs', [
'id_author' => (int)$id,
'id_lang' => $row['id'],
'description' => $description[ $i ]
] );
$i++;
}
else if ( is_array( $results ) and count( $results ) == 1 ) foreach ( $results as $row )
{
$mdb -> insert( 'pp_authors_langs', [
'id_author' => (int)$id,
'id_lang' => $row['id'],
'description' => $description
] );
}
\S::delete_cache();
return $id;
}
}
else
{
$mdb -> update( 'pp_authors', [
'author' => $author,
'image' => $image
], [
'id' => (int)$id_author
] );
$mdb -> delete( 'pp_authors_langs', [ 'id_author' => (int)$id_author ] );
$i = 0;
$results = $mdb -> select( 'pp_langs', [ 'id' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( is_array( $results ) and count( $results ) > 1 ) foreach ( $results as $row )
{
$mdb -> insert( 'pp_authors_langs', [
'id_author' => (int)$id_author,
'id_lang' => $row['id'],
'description' => $description[ $i ]
] );
$i++;
}
else if ( is_array( $results ) and count( $results ) == 1 ) foreach ( $results as $row )
{
$mdb -> insert( 'pp_authors_langs', [
'id_author' => (int)$id_author,
'id_lang' => $row['id'],
'description' => $description
] );
}
\S::delete_cache();
return $id_author;
}
return false;
}
// szczególy autora
static public function get_single_author( $id_author )
{
global $mdb;
$author = $mdb -> get( 'pp_authors', '*', [ 'id' => (int)$id_author ] );
$results = $mdb -> select( 'pp_authors_langs', '*', [ 'id_author' => (int)$id_author ] );
if ( is_array( $results ) ) foreach ( $results as $row )
$author['languages'][$row['id_lang']] = $row;
return $author;
}
}

View File

@@ -123,7 +123,7 @@ class Pages
)
{
global $mdb;
if ( !$parent_id )
$parent_id = null;
@@ -131,60 +131,55 @@ class Pages
{
$order = self::max_order() + 1;
$mdb -> insert( 'pp_pages',
[
'menu_id' => (int) $menu_id,
'page_type' => $page_type,
'sort_type' => $sort_type,
$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,
'cache' => $cache == 'on' ? 1 : 0
] );
'show_title' => $show_title == 'on' ? 1 : 0,
'status' => $status == 'on' ? 1 : 0,
'o' => (int) $order,
'parent_id' => $parent_id,
'start' => $start == 'on' ? 1 : 0,
'cache' => $cache == 'on' ? 1 : 0
] );
$id = $mdb -> id();
if ( $id )
{
if ( $start )
$mdb -> update( 'pp_pages', [ 'start' => 0 ], [ 'id[!]' => (int) $id ] );
$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 ] );
$mdb -> insert( 'pp_layouts_pages', [ 'page_id' => (int) $id, 'layout_id' => (int)$layout_id ] );
$i = 0;
$results = $mdb -> select( 'pp_langs', [ 'id' ],
[ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( is_array( $results ) and count( $results ) > 1 )
foreach ( $results as $row )
{
$mdb -> insert( 'pp_pages_langs',
[
'page_id' => (int) $id,
'lang_id' => $row['id'],
'title' => $title[$i] != '' ? $title[$i] : null,
'meta_description' => $meta_description[$i] != '' ? $meta_description[$i] : null,
'meta_keywords' => $meta_keywords[$i] != '' ? $meta_keywords[$i] : null,
'meta_title' => $meta_title[$i] != '' ? $meta_title[$i] : null,
'seo_link' => \S::seo( $seo_link[$i] ) != '' ? \S::seo( $seo_link[$i] ) : null,
'noindex' => $noindex[$i],
'site_title' => $site_title[$i] != '' ? $site_title[$i] : null,
'link' => $link[$i] != '' ? $link[$i] : null,
'block_direct_access' => $block_direct_access[$i],
'canonical' => $canonical[$i] != '' ? $canonical[$i] : null
] );
$i++;
}
$results = $mdb -> select( 'pp_langs', [ 'id' ], [ 'status' => 1, 'ORDER' => [ 'o' => 'ASC' ] ] );
if ( is_array( $results ) and count( $results ) > 1 ) foreach ( $results as $row )
{
$mdb -> insert( 'pp_pages_langs', [
'page_id' => (int) $id,
'lang_id' => $row['id'],
'title' => $title[$i] != '' ? $title[$i] : null,
'meta_description' => $meta_description[$i] != '' ? $meta_description[$i] : null,
'meta_keywords' => $meta_keywords[$i] != '' ? $meta_keywords[$i] : null,
'meta_title' => $meta_title[$i] != '' ? $meta_title[$i] : null,
'seo_link' => \S::seo( $seo_link[$i] ) != '' ? \S::seo( $seo_link[$i] ) : null,
'noindex' => $noindex[$i],
'site_title' => $site_title[$i] != '' ? $site_title[$i] : null,
'link' => $link[$i] != '' ? $link[$i] : null,
'block_direct_access' => $block_direct_access[$i],
'canonical' => $canonical[$i] != '' ? $canonical[$i] : null
] );
$i++;
}
else if ( is_array( $results ) and count( $results ) == 1 )
{
foreach ( $results as $row )
{
$mdb -> insert( 'pp_pages_langs',
[
$mdb -> insert( 'pp_pages_langs', [
'page_id' => (int) $id,
'lang_id' => $row['id'],
'title' => $title != '' ? $title : null,
@@ -197,11 +192,11 @@ class Pages
'link' => $link != '' ? $link : null,
'block_direct_access' => $block_direct_access,
'canonical' => $canonical != '' ? $canonical : null
] );
] );
}
}
\S::htacces();
\S::delete_cache();
return $id;
@@ -381,10 +376,10 @@ class Pages
else
$seo = $seo . $seo_link;
}
if ( $prefix )
$seo = $prefix . $seo;
return $seo;
}

View File

@@ -5,20 +5,20 @@ class Settings
public static function settings_update( $param, $value )
{
global $mdb;
$mdb -> delete( 'pp_settings', [ 'param' => $param ] );
$mdb -> insert( 'pp_settings', [ 'param' => $param, 'value' => $value ] );
return true;
if ( $mdb -> count( 'pp_settings', [ 'param' => $param ] ) )
return $mdb -> update( 'pp_settings', [ 'value' => $value ], [ 'param' => $param ] );
else
return $mdb -> insert( 'pp_settings', [ 'param' => $param, 'value' => $value ] );
}
public static function settings_save(
$firm_name, $firm_adress, $additional_info, $contact_form, $contact_email, $email_host, $email_port, $email_login, $email_password, $google_maps,
$facebook_link, $statistic_code, $htaccess, $robots, $newsletter_header, $newsletter_footer_1, $newsletter_footer_2, $google_map_key, $google_search_console, $update, $devel,
$news_limit, $visit_counter, $calendar, $tags, $ssl, $mysql_debug, $htaccess_cache, $visits, $links_structure, $link_version, $widget_phone, $update_key, $newsletter_cron )
$news_limit, $visit_counter, $calendar, $tags, $ssl, $mysql_debug, $htaccess_cache, $visits, $links_structure, $link_version, $widget_phone, $update_key )
{
global $mdb;
$mdb -> query( 'TRUNCATE pp_settings' );
$mdb -> insert( 'pp_settings', [
@@ -33,7 +33,7 @@ class Settings
'value' => $additional_info
], [
'param' => 'contact_form',
'value' => $contact_form == 'on' ? 1 : 0
'value' => $contact_form
], [
'param' => 'contact_email',
'value' => $contact_email
@@ -111,7 +111,7 @@ class Settings
'value' => $visits
], [
'param' => 'links_structure',
'value' => $links_structure
'value' => $links_structure
], [
'param' => 'link_version',
'value' => $link_version
@@ -121,9 +121,6 @@ class Settings
], [
'param' => 'update_key',
'value' => $update_key
], [
'param' => 'newsletter_cron',
'value' => $newsletter_cron
]
]
);
@@ -138,11 +135,11 @@ class Settings
public static function settings_details()
{
global $mdb;
$results = $mdb -> select( 'pp_settings', '*', [ 'ORDER' => [ 'id' => 'ASC' ] ] );
if ( is_array( $results ) ) foreach ( $results as $row )
$settings[$row['param']] = $row['value'];
return $settings;
}

View File

@@ -6,12 +6,12 @@ class Update
public static function update()
{
global $mdb, $settings;
\S::delete_session( 'new-version' );
$versions = file_get_contents( 'http://www.cmspro.project-dc.pl/updates/versions.php?key=' . $settings['update_key'] );
$versions = file_get_contents( 'http://www.cmspro.project-dc.pl/updates/versions.php?key=' . $settings['update_key'] );
$versions = explode( PHP_EOL, $versions );
foreach ( $versions as $ver )
{
$ver = trim( $ver );
@@ -21,68 +21,136 @@ class Update
$dir = substr( $ver, 0, strlen( $ver ) - 2 ) . 0;
else
$dir = substr( $ver, 0, strlen( $ver ) - 1 ) . 0;
$file = file_get_contents( 'http://www.cmspro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '.zip' );
$baseUrl = 'http://www.cmspro.project-dc.pl/updates/' . $dir;
/* pobranie paczki ZIP */
$file = file_get_contents( $baseUrl . '/ver_' . $ver . '.zip' );
$dlHandler = fopen( 'update.zip' , 'w' );
if ( !fwrite( $dlHandler, $file ) )
return false;
fclose( $dlHandler );
if ( !file_exists( 'update.zip' ) )
return false;
/* pobranie manifestu JSON (nowy system) lub fallback na legacy _sql.txt / _files.txt */
$manifest = null;
$manifestJson = @file_get_contents( $baseUrl . '/ver_' . $ver . '_manifest.json' );
if ( $manifestJson )
{
if ( substr( $manifestJson, 0, 3 ) === "\xEF\xBB\xBF" )
$manifestJson = substr( $manifestJson, 3 );
$manifest = @json_decode( $manifestJson, true );
}
if ( is_array( $manifest ) )
{
/* weryfikacja checksum SHA256 */
if ( !empty( $manifest['checksum_zip'] ) )
{
$expectedHash = str_replace( 'sha256:', '', $manifest['checksum_zip'] );
$actualHash = hash_file( 'sha256', 'update.zip' );
if ( $expectedHash !== $actualHash )
{
unlink( 'update.zip' );
return false;
}
}
/* aktualizacja bazy danych z manifestu */
if ( !empty( $manifest['sql'] ) && is_array( $manifest['sql'] ) )
{
foreach ( $manifest['sql'] as $query )
{
$query = trim( $query );
if ( $query )
$mdb -> query( $query );
}
}
/* usuwanie plikow z manifestu */
if ( !empty( $manifest['files']['deleted'] ) && is_array( $manifest['files']['deleted'] ) )
{
foreach ( $manifest['files']['deleted'] as $filePath )
{
$fullPath = '../' . $filePath;
if ( file_exists( $fullPath ) )
unlink( $fullPath );
}
}
/* usuwanie katalogow z manifestu */
if ( !empty( $manifest['directories_deleted'] ) && is_array( $manifest['directories_deleted'] ) )
{
foreach ( $manifest['directories_deleted'] as $dirPath )
{
$fullPath = '../' . $dirPath;
if ( is_dir( $fullPath ) )
\S::delete_dir( $fullPath );
}
}
}
else
{
/* aktualizacja bazy danych */
$sql = file_get_contents( 'http://www.cmspro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_sql.txt' );
$sql = explode( PHP_EOL, $sql );
if ( is_array( $sql ) and !empty( $sql ) ) foreach ( $sql as $query )
/* legacy: aktualizacja bazy danych z _sql.txt */
$sql = @file_get_contents( $baseUrl . '/ver_' . $ver . '_sql.txt' );
if ( $sql )
{
if ( $sql )
$result = $mdb -> query( $query );
}
/* usuwanie zbędnych plików */
$lines = file_get_contents( 'http://www.cmspro.project-dc.pl/updates/' . $dir . '/ver_' . $ver . '_files.txt' );
$lines = explode( PHP_EOL, $lines );
if ( is_array( $lines ) ) foreach ( $lines as $line )
{
if ( strpos( $line, 'F: ' ) !== false )
$sql = explode( PHP_EOL, $sql );
if ( is_array( $sql ) ) foreach ( $sql as $query )
{
$file = substr( $line, 3, strlen( $line ) );
if ( file_exists( $file ) )
unlink( $file );
}
if ( strpos( $line, 'D: ' ) !== false )
{
$dir = substr( $line, 3, strlen( $line ) );
if ( is_dir( $dir ) )
\S::delete_dir( $dir );
$query = trim( $query );
if ( $query )
$mdb -> query( $query );
}
}
/* wgrywanie nowych plików */
$file_name = 'update.zip';
$path = pathinfo( realpath( $file_name ), PATHINFO_DIRNAME );
$path = substr( $path, 0, strlen( $path ) - 5 );
$zip = new \ZipArchive;
$res = $zip -> open( $file_name );
if ( $res === TRUE )
/* legacy: usuwanie zbednych plikow z _files.txt */
$lines = @file_get_contents( $baseUrl . '/ver_' . $ver . '_files.txt' );
if ( $lines )
{
$zip -> extractTo( $path );
$zip -> close();
unlink( $file_name );
}
$lines = explode( PHP_EOL, $lines );
if ( is_array( $lines ) ) foreach ( $lines as $line )
{
if ( strpos( $line, 'F: ' ) !== false )
{
$delFile = substr( $line, 3, strlen( $line ) );
if ( file_exists( $delFile ) )
unlink( $delFile );
}
$updateThis = fopen( '../libraries/version.ini', 'w' );
fwrite( $updateThis, $ver );
fclose( $updateThis );
return true;
if ( strpos( $line, 'D: ' ) !== false )
{
$delDir = substr( $line, 3, strlen( $line ) );
if ( is_dir( $delDir ) )
\S::delete_dir( $delDir );
}
}
}
}
/* wgrywanie nowych plikow */
$file_name = 'update.zip';
$path = pathinfo( realpath( $file_name ), PATHINFO_DIRNAME );
$path = substr( $path, 0, strlen( $path ) - 5 );
$zip = new \ZipArchive;
$res = $zip -> open( $file_name );
if ( $res === TRUE )
{
$zip -> extractTo( $path );
$zip -> close();
unlink( $file_name );
}
$updateThis = fopen( '../libraries/version.ini', 'w' );
fwrite( $updateThis, $ver );
fclose( $updateThis );
return true;
}
}
}
}
}

View File

@@ -1,185 +1,306 @@
<?php
namespace admin\factory;
class Users
class Users
{
public static function user_delete( $user_id )
public static function user_delete($user_id)
{
global $mdb;
return $mdb -> delete( 'pp_users', [ 'id' => (int)$user_id ] );
return $mdb->delete('pp_users', ['id' => (int)$user_id]);
}
public static function user_details( $user_id )
public static function user_details($user_id)
{
global $mdb;
return $mdb -> get( 'pp_users', '*', [ 'id' => (int)$user_id ] );
return $mdb->get('pp_users', '*', ['id' => (int)$user_id]);
}
public static function user_privileges( $user_id )
public static function user_privileges($user_id)
{
global $mdb;
return $mdb -> select( 'pp_users_privileges', '*', ['id_user' => (int)$user_id]);
return $mdb->select('pp_users_privileges', '*', ['id_user' => (int)$user_id]);
}
public static function user_save( $user_id, $login, $status, $active_to, $password, $password_re, $admin, $privileges )
public static function user_save($user_id, $login, $status, $active_to, $password, $password_re, $admin, $privileges, $twofa_enabled = 0, $twofa_email = '' )
{
global $mdb, $lang;
$mdb -> delete( 'pp_users_privileges', [ 'id_user' => (int) $user_id ] );
$mdb->delete('pp_users_privileges', ['id_user' => (int) $user_id]);
if ( !$user_id )
if (!$user_id)
{
if ( strlen( $password ) < 5 )
return $response = [ 'status' => 'error', 'msg' => 'Podane hasło jest zbyt krótkie.' ];
if (strlen($password) < 5)
return $response = ['status' => 'error', 'msg' => 'Podane hasło jest zbyt krótkie.'];
if ( $password != $password_re )
return $response = [ 'status' => 'error', 'msg' => 'Podane hasła są różne' ];
if ($password != $password_re)
return $response = ['status' => 'error', 'msg' => 'Podane hasła są różne'];
if ( $mdb -> insert( 'pp_users',
[
'login' => $login,
'status' => $status == 'on' ? 1 : 0,
'active_to' => $active_to == '' ? NULL : $active_to,
'admin' => $admin,
'password' => md5( $password ),
] ) )
$id_user = $mdb -> get( 'pp_users', 'id', [ 'ORDER' => [ 'id' => 'DESC' ] ] );
if ($mdb->insert(
'pp_users',
[
'login' => $login,
'status' => $status == 'on' ? 1 : 0,
'active_to' => $active_to == '' ? NULL : $active_to,
'admin' => $admin,
'password' => md5($password),
'twofa_enabled' => $twofa_enabled == 'on' ? 1 : 0,
'twofa_email' => $twofa_email
]
))
$id_user = $mdb->get('pp_users', 'id', ['ORDER' => ['id' => 'DESC']]);
if ( is_array( $privileges ) )
if (is_array($privileges))
{
foreach ( $privileges as $pri )
foreach ($privileges as $pri)
{
$mdb -> insert( 'pp_users_privileges',
[
'name' => $pri,
'id_user' => $id_user
] );
$mdb->insert(
'pp_users_privileges',
[
'name' => $pri,
'id_user' => $id_user
]
);
}
}
else
{
$mdb -> insert( 'pp_users_privileges',
[
'name' => $privileges,
'id_user' => $id_user
] );
$mdb->insert(
'pp_users_privileges',
[
'name' => $privileges,
'id_user' => $id_user
]
);
}
return $response = [ 'status' => 'ok', 'msg' => 'Użytkownik został zapisany.' ];
return $response = ['status' => 'ok', 'msg' => 'Użytkownik został zapisany.'];
}
else
{
if ( $password and strlen( $password ) < 5 )
return $response = [ 'status' => 'error', 'msg' => 'Podane hasło jest zbyt krótkie.' ];
if ($password and strlen($password) < 5)
return $response = ['status' => 'error', 'msg' => 'Podane hasło jest zbyt krótkie.'];
if ( $password and $password != $password_re )
return $response = [ 'status' => 'error', 'msg' => 'Podane hasła są różne' ];
if ($password and $password != $password_re)
return $response = ['status' => 'error', 'msg' => 'Podane hasła są różne'];
if ( $password )
$mdb -> update( 'pp_users', [
'password' => md5( $password )
], [
'id' => (int) $user_id
] );
if ($password)
$mdb->update('pp_users', [
'password' => md5($password)
], [
'id' => (int) $user_id
]);
$mdb -> update( 'pp_users', [
'login' => $login,
'admin' => $admin,
'status' => $status == 'on' ? 1 : 0,
'active_to' => $active_to == '' ? NULL : $active_to,
'error_logged_count' => 0
], [
'id' => (int) $user_id
] );
$mdb->update('pp_users', [
'login' => $login,
'admin' => $admin,
'status' => $status == 'on' ? 1 : 0,
'active_to' => $active_to == '' ? NULL : $active_to,
'error_logged_count' => 0,
'twofa_enabled' => $twofa_enabled == 'on' ? 1 : 0,
'twofa_email' => $twofa_email
], [
'id' => (int) $user_id
]);
if ( is_array( $privileges ) )
if (is_array($privileges))
{
foreach ( $privileges as $pri )
foreach ($privileges as $pri)
{
$mdb -> insert( 'pp_users_privileges', [
'name' => $pri,
'id_user' => $user_id
] );
$mdb->insert('pp_users_privileges', [
'name' => $pri,
'id_user' => $user_id
]);
}
}
else
{
$mdb -> insert( 'pp_users_privileges', [
'name' => $privileges,
'id_user' => $user_id
] );
$mdb->insert('pp_users_privileges', [
'name' => $privileges,
'id_user' => $user_id
]);
}
return $response = [ 'status' => 'ok', 'msg' => 'Uzytkownik został zapisany.' ];
return $response = ['status' => 'ok', 'msg' => 'Uzytkownik został zapisany.'];
}
\S::delete_cache();
}
public static function check_login( $login, $user_id )
public static function check_login($login, $user_id)
{
global $mdb;
if ( $mdb -> get( 'pp_users', 'login', [ 'AND' => [ 'login' => $login, 'id[!]' => (int)$user_id ] ] ) )
return $response = [ 'status' => 'error', 'msg' => 'Podany login jest już zajęty.' ];
return $response = [ 'status' => 'ok' ];
if ($mdb->get('pp_users', 'login', ['AND' => ['login' => $login, 'id[!]' => (int)$user_id]]))
return $response = ['status' => 'error', 'msg' => 'Podany login jest już zajęty.'];
return $response = ['status' => 'ok'];
}
public static function logon( $login, $password )
public static function logon($login, $password)
{
global $mdb;
if ( !$mdb -> get( 'pp_users', '*', [ 'login' => $login ] ) )
if (!$mdb->get('pp_users', '*', ['login' => $login]))
return 0;
if ( !$mdb -> get( 'pp_users', '*', [ 'AND' => [ 'login' => $login, 'status' => 1, 'error_logged_count[<]' => 5 ] ] ) )
return -1;
if ( $mdb -> get( 'pp_users', '*', [
'AND' => [
'login' => $login, 'status' => 1, 'password' => md5( $password ),
'OR' => [ 'active_to[>=]' => date('Y-m-d'), 'active_to' => null ]
]
] ) )
if (!$mdb->get('pp_users', '*', ['AND' => ['login' => $login, 'status' => 1, 'error_logged_count[<]' => 5]]))
return -1;
if ($mdb->get('pp_users', '*', [
'AND' => [
'login' => $login,
'status' => 1,
'password' => md5($password),
'OR' => ['active_to[>=]' => date('Y-m-d'), 'active_to' => null]
]
]))
{
$mdb -> update( 'pp_users', [ 'last_logged' => date( 'Y-m-d H:i:s' ), 'error_logged_count' => 0 ], [ 'login' => $login ] );
$mdb->update('pp_users', ['last_logged' => date('Y-m-d H:i:s'), 'error_logged_count' => 0], ['login' => $login]);
return 1;
}
else
{
$mdb -> update( 'pp_users', [ 'last_error_logged' => date( 'Y-m-d H:i:s' ), 'error_logged_count[+]' => 1 ], [ 'login' => $login ] );
if ( $mdb -> get( 'pp_users', 'error_logged_count', [ 'login' => $login ] ) >= 5 )
$mdb->update('pp_users', ['last_error_logged' => date('Y-m-d H:i:s'), 'error_logged_count[+]' => 1], ['login' => $login]);
if ($mdb->get('pp_users', 'error_logged_count', ['login' => $login]) >= 5)
{
$mdb -> update( 'pp_users', [ 'status' => 0 ], [ 'login' => $login ] );
$mdb->update('pp_users', ['status' => 0], ['login' => $login]);
return -1;
}
}
return 0;
}
public static function details( $login )
public static function details($login)
{
global $mdb;
return $mdb -> get( 'pp_users', '*', [ 'login' => $login ] );
return $mdb->get('pp_users', '*', ['login' => $login]);
}
public static function check_privileges( $name, $user_id )
public static function check_privileges($name, $user_id)
{
global $mdb;
if ( $user_id == 1 )
if ($user_id == 1)
return true;
else
{
if ( !$privilages = \Cache::fetch( "check_privileges:$user_id:$name-tmp" ) )
{
$privilages = $mdb -> count( 'pp_users_privileges', [ 'AND' => ['name' => $name, 'id_user' => (int)$user_id ]]);
\Cache::store( "check_privileges:$user_id:$name", $privilages );
}
return $privilages;
}
if (!$privilages = \Cache::fetch("check_privileges:$user_id:$name-tmp"))
{
$privilages = $mdb->count('pp_users_privileges', ['AND' => ['name' => $name, 'id_user' => (int)$user_id]]);
\Cache::store("check_privileges:$user_id:$name", $privilages);
}
return $privilages;
}
}
static public function get_by_id(int $userId): ?array
{
global $mdb;
return $mdb->get('pp_users', '*', ['id' => $userId]) ?: null;
}
static public function send_twofa_code(int $userId, bool $resend = false): bool
{
$user = self::get_by_id($userId);
if (!$user)
return false;
if ((int)$user['twofa_enabled'] !== 1)
{
return false;
}
$to = $user['twofa_email'] ?: $user['login'];
if (!filter_var($to, FILTER_VALIDATE_EMAIL))
{
return false;
}
if ($resend && !empty($user['twofa_sent_at']))
{
$last = strtotime($user['twofa_sent_at']);
if ($last && (time() - $last) < 30)
{
return false;
}
}
$code = random_int(100000, 999999);
$hash = password_hash((string)$code, PASSWORD_DEFAULT);
self::update_by_id($userId, [
'twofa_code_hash' => $hash,
'twofa_expires_at' => date('Y-m-d H:i:s', time() + 10 * 60), // 10 minut
'twofa_sent_at' => date('Y-m-d H:i:s'),
'twofa_failed_attempts' => 0,
]);
$subject = 'Twój kod logowania 2FA';
$body = "Twój kod logowania do panelu administratora: {$code}. Kod jest ważny przez 10 minut. Jeśli to nie Ty inicjowałeś logowanie zignoruj tę wiadomość i poinformuj administratora.";
$sent = \S::send_email($to, $subject, $body);
if (!$sent) {
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/plain; charset=UTF-8\r\n";
$headers .= "From: no-reply@" . ($_SERVER['HTTP_HOST'] ?? 'localhost') . "\r\n";
$encodedSubject = mb_encode_mimeheader($subject, 'UTF-8');
$sent = mail($to, $encodedSubject, $body, $headers);
}
return $sent;
}
static public function update_by_id(int $userId, array $data): bool
{
global $mdb;
return (bool)$mdb->update('pp_users', $data, ['id' => $userId]);
}
static public function verify_twofa_code(int $userId, string $code): bool
{
$user = self::get_by_id( $userId );
if (!$user) return false;
if ((int)$user['twofa_failed_attempts'] >= 5)
{
return false; // zbyt wiele prób
}
// sprawdź ważność
if (empty($user['twofa_expires_at']) || time() > strtotime($user['twofa_expires_at']))
{
// wyczyść po wygaśnięciu
self::update_by_id($userId, [
'twofa_code_hash' => null,
'twofa_expires_at' => null,
]);
return false;
}
$ok = (!empty($user['twofa_code_hash']) && password_verify($code, $user['twofa_code_hash']));
if ($ok)
{
// sukces: czyścimy wszystko
self::update_by_id($userId, [
'twofa_code_hash' => null,
'twofa_expires_at' => null,
'twofa_sent_at' => null,
'twofa_failed_attempts' => 0,
'last_logged' => date('Y-m-d H:i:s'),
]);
return true;
}
// zła próba — inkrementacja
self::update_by_id($userId, [
'twofa_failed_attempts' => (int)$user['twofa_failed_attempts'] + 1,
'last_error_logged' => date('Y-m-d H:i:s'),
]);
return false;
}
}
?>

View File

@@ -7,9 +7,13 @@ class Page {
{
global $user;
if ( $_GET['module'] == 'user' && $_GET['action'] == 'twofa' ) {
return \admin\controls\Users::twofa();
}
if ( !$user || !$user['admin'] )
return \admin\view\Users::login_form();
$tpl = new \Tpl;
$tpl -> content = \admin\Site::route();
return $tpl -> render( 'site/main-layout' );

View File

@@ -11,15 +11,15 @@ class Pages
$tpl -> step = $step;
return $tpl -> render( 'pages/subpages-browse-list' );
}
public static function browse_list( $menus, $modal = false )
static public function browse_list( $menus, $modal = false )
{
$tpl = new \Tpl;
$tpl -> menus = $menus;
$tpl -> modal = $modal;
return $tpl -> render( 'pages/pages-browse-list' );
return \Tpl::view( 'pages/pages-browse-list', [
'menus' => $menus,
'modal' => $modal
] );
}
public static function page_articles( $page_id, $articles )
{
$tpl = new \Tpl;
@@ -27,7 +27,7 @@ class Pages
$tpl -> articles = $articles;
return $tpl -> render( 'pages/page-articles' );
}
public static function page_edit( $page, $parent_id, $menu_id, $menus, $layouts, $languages, $settings )
{
$tpl = new \Tpl;
@@ -39,23 +39,23 @@ class Pages
$tpl -> languages = $languages;
$tpl -> settings = $settings;
return $tpl -> render( 'pages/page-edit' );
}
public static function menu_edit( $menu )
{
$tpl = new \Tpl;
$tpl -> menu = $menu;
return $tpl -> render( 'pages/menu-edit' );
}
public static function pages_list( $menus )
{
$tpl = new \Tpl;
$tpl -> menus = $menus;
return $tpl -> render( 'pages/pages-list' );
return $tpl -> render( 'pages/pages-list' );
}
public static function subpages_list( $pages, $parent_id = null, $step = 1 )
{
$tpl = new \Tpl();