First Commit
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* Authentication and User Management Helper Functions
|
||||
*/
|
||||
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a user is logged in.
|
||||
*/
|
||||
function is_logged_in() {
|
||||
return isset($_SESSION['user']) && !empty($_SESSION['user']['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current logged in user details.
|
||||
*/
|
||||
function current_user() {
|
||||
return $_SESSION['user'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logged in user is owner.
|
||||
*/
|
||||
function is_owner() {
|
||||
$user = current_user();
|
||||
return $user && ($user['role'] === 'owner');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if logged in user is admin (or owner).
|
||||
*/
|
||||
function is_admin() {
|
||||
$user = current_user();
|
||||
return $user && ($user['role'] === 'admin' || $user['role'] === 'owner');
|
||||
}
|
||||
|
||||
/**
|
||||
* Require login to access a page.
|
||||
*/
|
||||
function require_login() {
|
||||
if (!is_logged_in()) {
|
||||
header("Location: index.php?page=login");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Require admin role to access a page.
|
||||
*/
|
||||
function require_admin() {
|
||||
require_login();
|
||||
if (!is_admin()) {
|
||||
header("Location: index.php?page=home");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate user with username and password.
|
||||
*/
|
||||
function login_user($username, $password) {
|
||||
global $conn;
|
||||
|
||||
$username = trim($username);
|
||||
if (empty($username) || empty($password)) {
|
||||
return ['success' => false, 'message' => 'Inserisci sia username che password.'];
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("SELECT id, username, password, role, theme_pri, theme_sec, theme_thi, language, default_blocknote FROM users WHERE username = ? LIMIT 1");
|
||||
$stmt->bind_param("s", $username);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($row = $result->fetch_assoc()) {
|
||||
if (password_verify($password, $row['password'])) {
|
||||
$_SESSION['user'] = [
|
||||
'id' => $row['id'],
|
||||
'username' => $row['username'],
|
||||
'role' => $row['role'],
|
||||
'theme_pri' => $row['theme_pri'] ?? 98,
|
||||
'theme_sec' => $row['theme_sec'] ?? 207,
|
||||
'theme_thi' => $row['theme_thi'] ?? 280,
|
||||
'language' => $row['language'] ?? 'it',
|
||||
'default_blocknote' => $row['default_blocknote'] ?? ''
|
||||
];
|
||||
$stmt->close();
|
||||
return ['success' => true];
|
||||
}
|
||||
}
|
||||
$stmt->close();
|
||||
return ['success' => false, 'message' => 'Username o password errati.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout current user.
|
||||
*/
|
||||
function logout_user() {
|
||||
$_SESSION = array();
|
||||
if (ini_get("session.use_cookies")) {
|
||||
$params = session_get_cookie_params();
|
||||
setcookie(session_name(), '', time() - 42000,
|
||||
$params["path"], $params["domain"],
|
||||
$params["secure"], $params["httponly"]
|
||||
);
|
||||
}
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user password.
|
||||
*/
|
||||
function update_user_password($user_id, $new_password) {
|
||||
global $conn;
|
||||
if (strlen($new_password) < 4) {
|
||||
return ['success' => false, 'message' => 'La password deve contenere almeno 4 caratteri.'];
|
||||
}
|
||||
$hash = password_hash($new_password, PASSWORD_DEFAULT);
|
||||
$stmt = $conn->prepare("UPDATE users SET password = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $hash, $user_id);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
return $res ? ['success' => true, 'message' => 'Password aggiornata con successo!'] : ['success' => false, 'message' => 'Errore durante il salvataggio della password.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user language preference.
|
||||
*/
|
||||
function update_user_language($user_id, $lang) {
|
||||
global $conn;
|
||||
if (!in_array($lang, ['it', 'en', 'es', 'fr'])) {
|
||||
$lang = 'it';
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE users SET language = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $lang, $user_id);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if ($res) {
|
||||
if (isset($_SESSION['user']) && $_SESSION['user']['id'] == $user_id) {
|
||||
$_SESSION['user']['language'] = $lang;
|
||||
}
|
||||
return ['success' => true, 'message' => 'Lingua aggiornata con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore durante l\'aggiornamento della lingua.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user default landing blocknote preference.
|
||||
*/
|
||||
function update_user_default_blocknote($user_id, $bn_id) {
|
||||
global $conn;
|
||||
$bn_id = trim($bn_id);
|
||||
|
||||
$stmt = $conn->prepare("UPDATE users SET default_blocknote = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $bn_id, $user_id);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if ($res) {
|
||||
if (isset($_SESSION['user']) && $_SESSION['user']['id'] == $user_id) {
|
||||
$_SESSION['user']['default_blocknote'] = $bn_id;
|
||||
}
|
||||
return ['success' => true, 'message' => 'Pagina di avvio aggiornata con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore durante l\'aggiornamento della pagina di avvio.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update user interface theme colors (HSL).
|
||||
*/
|
||||
function update_user_theme($user_id, $pri, $sec, $thi) {
|
||||
global $conn;
|
||||
$pri = max(0, min(360, (int)$pri));
|
||||
$sec = max(0, min(360, (int)$sec));
|
||||
$thi = max(0, min(360, (int)$thi));
|
||||
|
||||
$stmt = $conn->prepare("UPDATE users SET theme_pri = ?, theme_sec = ?, theme_thi = ? WHERE id = ?");
|
||||
$stmt->bind_param("iiii", $pri, $sec, $thi, $user_id);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if ($res) {
|
||||
if (isset($_SESSION['user']) && $_SESSION['user']['id'] == $user_id) {
|
||||
$_SESSION['user']['theme_pri'] = $pri;
|
||||
$_SESSION['user']['theme_sec'] = $sec;
|
||||
$_SESSION['user']['theme_thi'] = $thi;
|
||||
}
|
||||
return ['success' => true, 'message' => 'Colori dell\'interfaccia aggiornati!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore durante l\'aggiornamento dei colori.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin: Get list of all registered users.
|
||||
*/
|
||||
function get_all_users() {
|
||||
global $conn;
|
||||
$result = $conn->query("SELECT id, username, role, created_at FROM users ORDER BY id ASC");
|
||||
$users = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$users[] = $row;
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin: Register a new user.
|
||||
*/
|
||||
function admin_create_user($username, $password, $role = 'user') {
|
||||
global $conn;
|
||||
$username = trim($username);
|
||||
if (empty($username) || empty($password)) {
|
||||
return ['success' => false, 'message' => 'Username e password sono obbligatori.'];
|
||||
}
|
||||
if (!in_array($role, ['user', 'admin', 'owner'])) {
|
||||
$role = 'user';
|
||||
}
|
||||
|
||||
if ($role === 'owner') {
|
||||
$check_owner = $conn->query("SELECT id FROM users WHERE role = 'owner'");
|
||||
if ($check_owner->num_rows > 0) {
|
||||
return ['success' => false, 'message' => 'Può esistere un solo account Owner nel sistema!'];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if exists
|
||||
$stmt = $conn->prepare("SELECT id FROM users WHERE username = ? LIMIT 1");
|
||||
$stmt->bind_param("s", $username);
|
||||
$stmt->execute();
|
||||
if ($stmt->get_result()->num_rows > 0) {
|
||||
$stmt->close();
|
||||
return ['success' => false, 'message' => 'Un utente con questo username esiste già.'];
|
||||
}
|
||||
$stmt->close();
|
||||
|
||||
$hash = password_hash($password, PASSWORD_DEFAULT);
|
||||
$stmt = $conn->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
|
||||
$stmt->bind_param("sss", $username, $hash, $role);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
return $res ? ['success' => true, 'message' => 'Utente creato con successo!'] : ['success' => false, 'message' => 'Impossibile creare l\'utente.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin: Delete a user by ID.
|
||||
*/
|
||||
function admin_delete_user($user_id) {
|
||||
global $conn;
|
||||
$user_id = (int)$user_id;
|
||||
|
||||
// Prevent self-deletion
|
||||
if (current_user() && current_user()['id'] == $user_id) {
|
||||
return ['success' => false, 'message' => 'Non puoi eliminare il tuo stesso account!'];
|
||||
}
|
||||
|
||||
// Check target user role - Owner can NEVER be deleted
|
||||
$stmt = $conn->prepare("SELECT role FROM users WHERE id = ? LIMIT 1");
|
||||
$stmt->bind_param("i", $user_id);
|
||||
$stmt->execute();
|
||||
$target_user = $stmt->get_result()->fetch_assoc();
|
||||
$stmt->close();
|
||||
|
||||
if ($target_user && $target_user['role'] === 'owner') {
|
||||
return ['success' => false, 'message' => 'L\'account Owner non può essere eliminato da nessuno!'];
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
|
||||
$stmt->bind_param("i", $user_id);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
return $res ? ['success' => true, 'message' => 'Utente eliminato.'] : ['success' => false, 'message' => 'Errore nell\'eliminazione dell\'utente.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Admin: Update user role.
|
||||
*/
|
||||
function admin_update_user_role($user_id, $role) {
|
||||
global $conn;
|
||||
$user_id = (int)$user_id;
|
||||
if (!in_array($role, ['admin', 'user', 'owner'])) return ['success' => false, 'message' => 'Ruolo non valido.'];
|
||||
|
||||
// Check target user role - Owner role cannot be changed
|
||||
$stmt = $conn->prepare("SELECT role FROM users WHERE id = ? LIMIT 1");
|
||||
$stmt->bind_param("i", $user_id);
|
||||
$stmt->execute();
|
||||
$target_user = $stmt->get_result()->fetch_assoc();
|
||||
$stmt->close();
|
||||
|
||||
if ($target_user && $target_user['role'] === 'owner') {
|
||||
return ['success' => false, 'message' => 'Il ruolo dell\'account Owner non può essere modificato!'];
|
||||
}
|
||||
|
||||
if ($role === 'owner') {
|
||||
$check_owner = $conn->query("SELECT id FROM users WHERE role = 'owner'");
|
||||
if ($check_owner->num_rows > 0) {
|
||||
return ['success' => false, 'message' => 'Può esistere un solo account Owner nel sistema!'];
|
||||
}
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE users SET role = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $role, $user_id);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
return $res ? ['success' => true, 'message' => 'Ruolo aggiornato.'] : ['success' => false, 'message' => 'Impossibile aggiornare il ruolo.'];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,421 @@
|
||||
<?php
|
||||
/**
|
||||
* Blocknotes JSON Storage Engine Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Ensure storage directory exists.
|
||||
*/
|
||||
function ensure_blocknotes_directory() {
|
||||
if (!is_dir(BLOCKNOTES_FOLD)) {
|
||||
@mkdir(BLOCKNOTES_FOLD, 0777, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan BLOCKNOTES_FOLD and load all JSON files.
|
||||
*/
|
||||
function get_all_blocknotes() {
|
||||
ensure_blocknotes_directory();
|
||||
$files = glob(BLOCKNOTES_FOLD . "*.json");
|
||||
$blocknotes = [];
|
||||
|
||||
if ($files) {
|
||||
foreach ($files as $filepath) {
|
||||
$content = file_get_contents($filepath);
|
||||
$data = json_decode($content, true);
|
||||
if (is_array($data) && isset($data['id'])) {
|
||||
$blocknotes[] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by updated_at descending
|
||||
usort($blocknotes, function($a, $b) {
|
||||
return strtotime($b['updated_at'] ?? 0) - strtotime($a['updated_at'] ?? 0);
|
||||
});
|
||||
|
||||
return $blocknotes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get blocknotes assigned to a specific user (or all if admin).
|
||||
*/
|
||||
function get_user_blocknotes($username, $is_admin = false) {
|
||||
$all = get_all_blocknotes();
|
||||
if ($is_admin) {
|
||||
return $all;
|
||||
}
|
||||
|
||||
return array_filter($all, function($bn) use ($username) {
|
||||
return isset($bn['username']) && strtolower($bn['username']) === strtolower($username);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Find blocknote by ID.
|
||||
*/
|
||||
function get_blocknote_by_id($id) {
|
||||
ensure_blocknotes_directory();
|
||||
$filename = BLOCKNOTES_FOLD . preg_replace('/[^a-zA-Z0-9_\-]/', '', $id) . ".json";
|
||||
|
||||
if (file_exists($filename)) {
|
||||
$content = file_get_contents($filename);
|
||||
$data = json_decode($content, true);
|
||||
if (is_array($data)) return $data;
|
||||
}
|
||||
|
||||
// Fallback search across all files if ID is stored inside
|
||||
$all = get_all_blocknotes();
|
||||
foreach ($all as $bn) {
|
||||
if (isset($bn['id']) && $bn['id'] === $id) {
|
||||
return $bn;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save blocknote to JSON file.
|
||||
*/
|
||||
function save_blocknote($data) {
|
||||
ensure_blocknotes_directory();
|
||||
if (empty($data['id'])) {
|
||||
$data['id'] = 'bn_' . uniqid();
|
||||
}
|
||||
$data['updated_at'] = date('Y-m-d H:i:s');
|
||||
if (empty($data['created_at'])) {
|
||||
$data['created_at'] = $data['updated_at'];
|
||||
}
|
||||
if (!isset($data['notes'])) {
|
||||
$data['notes'] = [];
|
||||
}
|
||||
|
||||
$filepath = BLOCKNOTES_FOLD . preg_replace('/[^a-zA-Z0-9_\-]/', '', $data['id']) . ".json";
|
||||
$json_string = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
return file_put_contents($filepath, $json_string) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new blocknote.
|
||||
*/
|
||||
function create_blocknote($title, $username) {
|
||||
$title = trim($title);
|
||||
if (empty($title)) {
|
||||
return ['success' => false, 'message' => 'Il titolo del blocknote è obbligatorio.'];
|
||||
}
|
||||
|
||||
$id = 'bn_' . uniqid();
|
||||
$data = [
|
||||
'id' => $id,
|
||||
'title' => $title,
|
||||
'username' => $username,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'notes' => []
|
||||
];
|
||||
|
||||
if (save_blocknote($data)) {
|
||||
return ['success' => true, 'id' => $id, 'message' => 'Blocknote creato con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio del file JSON.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Import a JSON string (supports standard format and legacy codes format).
|
||||
*/
|
||||
function import_blocknote_json($json_string, $username, $custom_title = '') {
|
||||
$data = json_decode($json_string, true);
|
||||
if (!is_array($data)) {
|
||||
return ['success' => false, 'message' => 'File JSON non valido o malformato.'];
|
||||
}
|
||||
|
||||
$id = 'bn_' . uniqid();
|
||||
$title = !empty($custom_title) ? trim($custom_title) : 'Blocknote Importato';
|
||||
|
||||
// Case 1: Standard format with 'notes' array
|
||||
if (isset($data['notes']) && is_array($data['notes'])) {
|
||||
$bn = [
|
||||
'id' => $id,
|
||||
'title' => !empty($data['title']) ? $data['title'] : $title,
|
||||
'username' => $username,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'notes' => $data['notes']
|
||||
];
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'id' => $id, 'message' => 'Blocknote importato con successo!'];
|
||||
}
|
||||
}
|
||||
|
||||
// Case 2: Legacy format (array of notes with 'title', 'description', 'codes')
|
||||
if (isset($data[0]) && is_array($data[0])) {
|
||||
$notes = [];
|
||||
foreach ($data as $n_idx => $legacy_note) {
|
||||
$note_id = 'note_' . ($n_idx + 1) . '_' . uniqid();
|
||||
$subnotes = [];
|
||||
|
||||
if (isset($legacy_note['codes']) && is_array($legacy_note['codes'])) {
|
||||
foreach ($legacy_note['codes'] as $s_idx => $legacy_code) {
|
||||
$subnotes[] = [
|
||||
'id' => 'sub_' . ($s_idx + 1) . '_' . uniqid(),
|
||||
'title' => $legacy_code['sub_title'] ?? 'Comando',
|
||||
'type' => 'command',
|
||||
'content' => $legacy_code['code'] ?? ''
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$notes[] = [
|
||||
'id' => $note_id,
|
||||
'title' => $legacy_note['title'] ?? 'Nota ' . ($n_idx + 1),
|
||||
'description' => $legacy_note['description'] ?? '',
|
||||
'subnotes' => $subnotes
|
||||
];
|
||||
}
|
||||
|
||||
$bn = [
|
||||
'id' => $id,
|
||||
'title' => $title,
|
||||
'username' => $username,
|
||||
'created_at' => date('Y-m-d H:i:s'),
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'notes' => $notes
|
||||
];
|
||||
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'id' => $id, 'message' => 'Blocknote in formato legacy importato e convertito con successo!'];
|
||||
}
|
||||
}
|
||||
|
||||
return ['success' => false, 'message' => 'Formato JSON non riconosciuto.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check permission on blocknote.
|
||||
*/
|
||||
function can_access_blocknote($bn, $username, $is_admin) {
|
||||
if (!$bn) return false;
|
||||
if ($is_admin) return true;
|
||||
return strtolower($bn['username'] ?? '') === strtolower($username);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename a blocknote.
|
||||
*/
|
||||
function rename_blocknote($id, $new_title, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) {
|
||||
return ['success' => false, 'message' => 'Non hai i permessi per modificare questo blocknote.'];
|
||||
}
|
||||
|
||||
$new_title = trim($new_title);
|
||||
if (empty($new_title)) return ['success' => false, 'message' => 'Il titolo non può essere vuoto.'];
|
||||
|
||||
$bn['title'] = $new_title;
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'message' => 'Blocknote rinominato con successo.'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio del file JSON.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a blocknote.
|
||||
*/
|
||||
function delete_blocknote($id, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) {
|
||||
return ['success' => false, 'message' => 'Non hai i permessi per eliminare questo blocknote.'];
|
||||
}
|
||||
|
||||
$filepath = BLOCKNOTES_FOLD . preg_replace('/[^a-zA-Z0-9_\-]/', '', $bn['id']) . ".json";
|
||||
if (file_exists($filepath)) {
|
||||
@unlink($filepath);
|
||||
}
|
||||
return ['success' => true, 'message' => 'Blocknote eliminato con successo.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new Note block to a Blocknote.
|
||||
*/
|
||||
function add_note($blocknote_id, $title, $description, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) return ['success' => false, 'message' => 'Permesso negato.'];
|
||||
|
||||
$title = trim($title);
|
||||
if (empty($title)) return ['success' => false, 'message' => 'Il titolo della nota è obbligatorio.'];
|
||||
|
||||
$note_id = 'note_' . uniqid();
|
||||
$new_note = [
|
||||
'id' => $note_id,
|
||||
'title' => $title,
|
||||
'description' => trim($description),
|
||||
'subnotes' => []
|
||||
];
|
||||
|
||||
$bn['notes'][] = $new_note;
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'note_id' => $note_id, 'message' => 'Nota aggiunta con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore durante il salvataggio.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit an existing Note block.
|
||||
*/
|
||||
function edit_note($blocknote_id, $note_id, $title, $description, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) return ['success' => false, 'message' => 'Permesso negato.'];
|
||||
|
||||
$title = trim($title);
|
||||
if (empty($title)) return ['success' => false, 'message' => 'Il titolo della nota è obbligatorio.'];
|
||||
|
||||
$found = false;
|
||||
foreach ($bn['notes'] as &$note) {
|
||||
if ($note['id'] === $note_id) {
|
||||
$note['title'] = $title;
|
||||
$note['description'] = trim($description);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) return ['success' => false, 'message' => 'Nota non trovata.'];
|
||||
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'message' => 'Nota modificata con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a Note block.
|
||||
*/
|
||||
function delete_note($blocknote_id, $note_id, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) return ['success' => false, 'message' => 'Permesso negato.'];
|
||||
|
||||
$initial_count = count($bn['notes']);
|
||||
$bn['notes'] = array_values(array_filter($bn['notes'], function($n) use ($note_id) {
|
||||
return $n['id'] !== $note_id;
|
||||
}));
|
||||
|
||||
if (count($bn['notes']) === $initial_count) {
|
||||
return ['success' => false, 'message' => 'Nota non trovata.'];
|
||||
}
|
||||
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'message' => 'Nota eliminata con successo.'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Subnote to a Note block.
|
||||
*/
|
||||
function add_subnote($blocknote_id, $note_id, $sub_title, $type, $content, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) return ['success' => false, 'message' => 'Permesso negato.'];
|
||||
|
||||
$sub_title = trim($sub_title);
|
||||
if (empty($sub_title)) return ['success' => false, 'message' => 'Il titolo della sottonota è obbligatorio.'];
|
||||
|
||||
$type = ($type === 'command') ? 'command' : 'text';
|
||||
$sub_id = 'sub_' . uniqid();
|
||||
|
||||
$found = false;
|
||||
foreach ($bn['notes'] as &$note) {
|
||||
if ($note['id'] === $note_id) {
|
||||
if (!isset($note['subnotes'])) $note['subnotes'] = [];
|
||||
$note['subnotes'][] = [
|
||||
'id' => $sub_id,
|
||||
'title' => $sub_title,
|
||||
'type' => $type,
|
||||
'content' => $content
|
||||
];
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) return ['success' => false, 'message' => 'Nota genitore non trovata.'];
|
||||
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'subnote_id' => $sub_id, 'message' => 'Sottonota aggiunta con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit a Subnote.
|
||||
*/
|
||||
function edit_subnote($blocknote_id, $note_id, $sub_id, $sub_title, $type, $content, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) return ['success' => false, 'message' => 'Permesso negato.'];
|
||||
|
||||
$sub_title = trim($sub_title);
|
||||
if (empty($sub_title)) return ['success' => false, 'message' => 'Il titolo della sottonota è obbligatorio.'];
|
||||
$type = ($type === 'command') ? 'command' : 'text';
|
||||
|
||||
$found = false;
|
||||
foreach ($bn['notes'] as &$note) {
|
||||
if ($note['id'] === $note_id) {
|
||||
if (isset($note['subnotes'])) {
|
||||
foreach ($note['subnotes'] as &$sub) {
|
||||
if ($sub['id'] === $sub_id) {
|
||||
$sub['title'] = $sub_title;
|
||||
$sub['type'] = $type;
|
||||
$sub['content'] = $content;
|
||||
$found = true;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) return ['success' => false, 'message' => 'Sottonota non trovata.'];
|
||||
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'message' => 'Sottonota modificata con successo!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio.'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a Subnote.
|
||||
*/
|
||||
function delete_subnote($blocknote_id, $note_id, $sub_id, $username, $is_admin) {
|
||||
$bn = get_blocknote_by_id($blocknote_id);
|
||||
if (!$bn) return ['success' => false, 'message' => 'Blocknote non trovato.'];
|
||||
if (!can_access_blocknote($bn, $username, $is_admin)) return ['success' => false, 'message' => 'Permesso negato.'];
|
||||
|
||||
$found = false;
|
||||
foreach ($bn['notes'] as &$note) {
|
||||
if ($note['id'] === $note_id && isset($note['subnotes'])) {
|
||||
$initial = count($note['subnotes']);
|
||||
$note['subnotes'] = array_values(array_filter($note['subnotes'], function($s) use ($sub_id) {
|
||||
return $s['id'] !== $sub_id;
|
||||
}));
|
||||
if (count($note['subnotes']) < $initial) {
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) return ['success' => false, 'message' => 'Sottonota non trovata.'];
|
||||
|
||||
if (save_blocknote($bn)) {
|
||||
return ['success' => true, 'message' => 'Sottonota eliminata con successo.'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Errore nel salvataggio.'];
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
### LIST OF FUNCTIONS TO INCLUDE ###
|
||||
Include in this array all the function files you may want to include.
|
||||
Include in this array all the function files you may want to include.
|
||||
You don't need to specify the extension .php, the system will automatically add it.
|
||||
*/
|
||||
|
||||
$fun_to_inc = array(
|
||||
//"example",
|
||||
"demo-example"
|
||||
"lang",
|
||||
"site_settings",
|
||||
"auth",
|
||||
"blocknotes"
|
||||
);
|
||||
|
||||
// DON'T CHANGE THE CODE BELOW!!!
|
||||
@@ -17,9 +19,6 @@ if (isset($fun_to_inc) && is_array($fun_to_inc) && !empty($fun_to_inc)){
|
||||
require_once(FUNCTIONS_FOLD . $fun . ".php");
|
||||
} else {
|
||||
debugStatusMes("Function file $fun.php not found in functions folder: '" . FUNCTIONS_FOLD . "'", "Medium");
|
||||
if ($fun === "demo-example") {
|
||||
debugStatusMes("The 'demo-example' function is only a demo. If you create a new function, needs to be included in the file specified above. Please remove the demo-example record from 'functions/functions.php' ", "Info");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,720 @@
|
||||
<?php
|
||||
/**
|
||||
* Multilingual System Helper (IT, EN, ES, FR)
|
||||
*/
|
||||
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current user language code.
|
||||
*/
|
||||
function get_current_lang() {
|
||||
$user = $_SESSION['user'] ?? null;
|
||||
$lang = $user['language'] ?? $_SESSION['guest_language'] ?? 'it';
|
||||
if (!in_array($lang, ['it', 'en', 'es', 'fr'])) {
|
||||
$lang = 'it';
|
||||
}
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set guest/active language.
|
||||
*/
|
||||
function set_active_lang($lang) {
|
||||
if (in_array($lang, ['it', 'en', 'es', 'fr'])) {
|
||||
if (isset($_SESSION['user'])) {
|
||||
$_SESSION['user']['language'] = $lang;
|
||||
global $conn;
|
||||
if (isset($conn) && !empty($_SESSION['user']['id'])) {
|
||||
$stmt = $conn->prepare("UPDATE users SET language = ? WHERE id = ?");
|
||||
$stmt->bind_param("si", $lang, $_SESSION['user']['id']);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
} else {
|
||||
$_SESSION['guest_language'] = $lang;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Translations Dictionary
|
||||
*/
|
||||
function get_translations() {
|
||||
return [
|
||||
'it' => [
|
||||
// Login Page
|
||||
'login_title' => 'Accedi a Blocknotes',
|
||||
'login_subtitle' => 'Gestisci le tue note e i tuoi comandi',
|
||||
'label_username' => 'Nome Utente',
|
||||
'label_password' => 'Password',
|
||||
'placeholder_username' => 'Inserisci username',
|
||||
'placeholder_password' => 'Inserisci password',
|
||||
'btn_submit_login' => '🔑 Accedi',
|
||||
'login_hint_footer' => 'Accredito predefinito per il primo accesso',
|
||||
'login_installed_success' => '🎉 Setup completato! Accedi con le credenziali create.',
|
||||
|
||||
// Navbar
|
||||
'nav_blocknotes' => '📓 Blocknotes',
|
||||
'nav_colors_profile' => '🎨 Colori & Profilo',
|
||||
'nav_admin' => '👑 Gestione Utenti',
|
||||
'nav_logout' => '🚪 Esci',
|
||||
'nav_login' => '🔑 Accedi',
|
||||
'nav_language' => '🌐 Lingua',
|
||||
|
||||
// Dashboard (home)
|
||||
'dashboard_title_user' => 'I Miei Blocknotes',
|
||||
'dashboard_title_admin' => 'Tutti i Blocknotes (Vista Admin)',
|
||||
'dashboard_desc_user' => 'Crea, organizza e consulta i tuoi blocknotes.',
|
||||
'dashboard_desc_admin' => 'In qualità di Admin puoi visualizzare, gestire ed eliminare i blocknotes di tutti gli utenti.',
|
||||
'btn_new_blocknote' => '➕ Nuovo Blocknote',
|
||||
'btn_import_json' => '📥 Importa JSON',
|
||||
'btn_export_json' => '💾 Esporta JSON',
|
||||
'btn_open_edit' => '👁️ Apri & Modifica',
|
||||
'btn_rename' => '✏️ Rinomina',
|
||||
'btn_delete' => '🗑️ Elimina',
|
||||
'empty_blocknotes_title' => 'Nessun Blocknote trovato',
|
||||
'empty_blocknotes_desc_user' => 'Non hai ancora creato nessun blocknote. Inizia subito!',
|
||||
'empty_blocknotes_desc_admin' => 'Non ci sono ancora blocknotes salvati nel sistema.',
|
||||
'modal_create_title' => '➕ Crea Nuovo Blocknote',
|
||||
'modal_rename_title' => '✏️ Rinomina Blocknote',
|
||||
'modal_import_title' => '📥 Importa Blocknote (JSON)',
|
||||
'label_title' => 'Titolo Blocknote',
|
||||
'label_file_json' => 'Carica File .json',
|
||||
'label_paste_json' => 'Oppure incolla qui il codice JSON',
|
||||
'btn_cancel' => 'Annulla',
|
||||
'btn_save' => 'Salva',
|
||||
'btn_create' => 'Crea Blocknote',
|
||||
'btn_import' => 'Importa Blocknote',
|
||||
'note_single' => 'Nota',
|
||||
'note_plural' => 'Note',
|
||||
|
||||
// View Blocknote
|
||||
'btn_back_list' => '⬅️ Torna ai Blocknotes',
|
||||
'btn_expand_all' => '📂 Espandi Tutte',
|
||||
'btn_collapse_all' => '📁 Riduci Tutte',
|
||||
'btn_new_note' => '➕ Nuova Nota',
|
||||
'btn_add_subnote' => '➕ Sottonota',
|
||||
'subnote_single' => 'sottonota',
|
||||
'subnote_plural' => 'sottonote',
|
||||
'badge_text' => '📄 Testo',
|
||||
'badge_command' => '⚡ Comando',
|
||||
'btn_copy' => '📋 Copia',
|
||||
'btn_copied' => '✓ Copiato!',
|
||||
'search_placeholder' => '🔍 Cerca note, sottonote o comandi in questo blocknote...',
|
||||
'btn_clear_search' => '❌ Annulla Cerca',
|
||||
'search_no_results' => 'Nessun risultato trovato',
|
||||
'search_no_results_desc' => 'Nessuna nota o comando corrisponde al termine cercato in questo blocknote.',
|
||||
'modal_add_note' => '➕ Nuova Nota a Blocchi',
|
||||
'modal_edit_note' => '✏️ Modifica Nota',
|
||||
'modal_add_subnote' => '➕ Aggiungi Sottonota',
|
||||
'modal_edit_subnote' => '✏️ Modifica Sottonota',
|
||||
'label_note_description' => 'Descrizione (opzionale)',
|
||||
'label_subnote_title' => 'Titolo Sottonota',
|
||||
'label_subnote_type' => 'Tipo di Sottonota',
|
||||
'label_subnote_content' => 'Contenuto',
|
||||
'type_option_text' => '📄 Testo generico',
|
||||
'type_option_command' => '⚡ Comando (con pulsante Copia)',
|
||||
|
||||
// Profile & Settings
|
||||
'profile_title' => '🎨 Impostazioni Profilo & Tema',
|
||||
'profile_desc' => 'Personalizza password, colori dell\'interfaccia, lingua e pagina di avvio.',
|
||||
'card_password_title' => '🔒 Cambio Password',
|
||||
'card_colors_title' => '🎨 Personalizza Colori Interfaccia (HSL)',
|
||||
'card_lang_title' => '🌍 Lingua dell\'Interfaccia',
|
||||
'card_landing_title' => '🏠 Pagina di Primo Accesso (Landing Page)',
|
||||
'label_new_pass' => 'Nuova Password',
|
||||
'label_confirm_pass' => 'Conferma Nuova Password',
|
||||
'label_select_lang' => 'Seleziona Lingua',
|
||||
'label_select_landing' => 'Seleziona Pagina di Avvio',
|
||||
'landing_option_dashboard' => '📋 Pagina Principale (Tutti i Blocknotes)',
|
||||
'landing_option_bn_prefix' => '📌 Apri direttamente: ',
|
||||
'btn_update_pass' => '🔑 Aggiorna Password',
|
||||
'btn_save_colors' => '💾 Salva Preferenze Colori',
|
||||
'btn_save_lang' => '🌍 Salva Lingua',
|
||||
'btn_save_landing' => '🏠 Salva Pagina di Avvio',
|
||||
|
||||
// Admin Users
|
||||
'admin_title' => '👑 Pannello Amministrazione Utenti',
|
||||
'admin_desc' => 'Crea, gestisci e modifica i ruoli e gli accessi degli utenti.',
|
||||
'btn_add_user' => '➕ Aggiungi Nuovo Utente',
|
||||
'col_username' => 'Nome Utente',
|
||||
'col_role' => 'Ruolo',
|
||||
'col_bns' => 'Blocknotes Creati',
|
||||
'col_created' => 'Data Registrazione',
|
||||
'col_actions' => 'Azioni Admin',
|
||||
'role_standard' => 'Standard User',
|
||||
'role_admin' => 'Administrator',
|
||||
'role_owner' => '👑 Owner (Proprietario)',
|
||||
'badge_owner' => '👑 Owner',
|
||||
'btn_reset_pass' => '🔑 Reset Pass',
|
||||
'modal_create_user' => '➕ Registra Nuovo Utente',
|
||||
'modal_reset_pass' => '🔑 Reset Password Utente',
|
||||
// Confirm Dialogs
|
||||
'confirm_delete_blocknote' => 'Sei sicuro di voler eliminare questo blocknote e tutte le sue note?',
|
||||
'confirm_delete_note' => 'Sei sicuro di voler eliminare questa nota e tutte le sue sottonote?',
|
||||
'confirm_delete_subnote' => 'Sei sicuro di voler eliminare questa sottonota?',
|
||||
'confirm_delete_user' => 'Sei sicuro di voler eliminare questo utente?',
|
||||
|
||||
// Placeholders
|
||||
'placeholder_bn_title' => 'Es. Comandi Server Linux, Note Progetto PHP...',
|
||||
'placeholder_rename_title' => 'Nuovo titolo...',
|
||||
'placeholder_import_title' => 'Es. Positive Internet',
|
||||
'placeholder_paste_json' => 'Incolla qui il JSON nel vecchio o nuovo formato...',
|
||||
'placeholder_note_title' => 'Es. Installazione MySQL, Server Setup...',
|
||||
'placeholder_note_desc' => 'Breve descrizione di questo blocco di note...',
|
||||
'placeholder_subnote_title' => 'Es. Comando creazione database, Note configurazione...',
|
||||
'placeholder_subnote_content' => 'Inserisci il testo o le istruzioni del comando...',
|
||||
'placeholder_site_title' => 'Es. Blocknotes, Enterprise Notes...',
|
||||
'placeholder_username_new' => 'es. mario, giuseppe...',
|
||||
'placeholder_password_new' => 'Inserisci nuova password',
|
||||
'placeholder_password_confirm' => 'Ripeti nuova password',
|
||||
|
||||
// Extra Labels
|
||||
'label_owner_prefix' => 'Proprietario: ',
|
||||
'label_updated_prefix' => 'Ultimo aggiornamento: ',
|
||||
'label_you' => 'Tu',
|
||||
'label_unknown' => 'Sconosciuto',
|
||||
'label_current_favicon' => 'Favicon Attuale: ',
|
||||
|
||||
// First Start Installer Setup
|
||||
'setup_title' => '🚀 Setup Iniziale Blocknotes',
|
||||
'setup_subtitle' => 'Configura il database MySQL e crea i primi utenti privilegiati (Owner & Admin).',
|
||||
'setup_sec1_title' => '1. Configurazione Database MySQL',
|
||||
'setup_db_host' => 'Host Database',
|
||||
'setup_db_name' => 'Nome Database',
|
||||
'setup_db_user' => 'Utente MySQL',
|
||||
'setup_db_pass' => 'Password MySQL',
|
||||
'setup_db_pass_placeholder' => 'Password (lascia vuoto se nessuna)',
|
||||
'setup_sec2_title' => '2. Account Owner (Proprietario Unico)',
|
||||
'setup_owner_user' => 'Username Owner',
|
||||
'setup_owner_pass' => 'Password Owner',
|
||||
'setup_owner_pass_placeholder' => 'Inserisci password per Owner',
|
||||
'setup_sec3_title' => '3. Primo Account Amministratore (Admin)',
|
||||
'setup_admin_user' => 'Username Admin',
|
||||
'setup_admin_pass' => 'Password Admin',
|
||||
'setup_admin_pass_placeholder' => 'Inserisci password per Admin',
|
||||
'setup_btn_submit' => '⚡ Completa Installazione & Configura Sistema',
|
||||
'err_setup_db_fields' => 'Compila tutti i dati di connessione al Database MySQL.',
|
||||
'err_setup_owner_fields' => 'Inserisci username e password per l\'utente Owner (Proprietario).',
|
||||
'err_setup_admin_fields' => 'Inserisci username e password per il primo utente Admin.',
|
||||
'err_setup_same_user' => 'L\'utente Owner e l\'utente Admin devono avere nomi utente differenti.'
|
||||
],
|
||||
|
||||
'en' => [
|
||||
// Login Page
|
||||
'login_title' => 'Login to Blocknotes',
|
||||
'login_subtitle' => 'Manage your notes and commands',
|
||||
'label_username' => 'Username',
|
||||
'label_password' => 'Password',
|
||||
'placeholder_username' => 'Enter username',
|
||||
'placeholder_password' => 'Enter password',
|
||||
'btn_submit_login' => '🔑 Login',
|
||||
'login_hint_footer' => 'Default first login credential',
|
||||
'login_installed_success' => '🎉 Setup completed! Login with your created credentials.',
|
||||
|
||||
// Navbar
|
||||
'nav_blocknotes' => '📓 Blocknotes',
|
||||
'nav_colors_profile' => '🎨 Colors & Profile',
|
||||
'nav_admin' => '👑 User Management',
|
||||
'nav_logout' => '🚪 Logout',
|
||||
'nav_login' => '🔑 Login',
|
||||
'nav_language' => '🌐 Language',
|
||||
|
||||
// Dashboard (home)
|
||||
'dashboard_title_user' => 'My Blocknotes',
|
||||
'dashboard_title_admin' => 'All Blocknotes (Admin View)',
|
||||
'dashboard_desc_user' => 'Create, organize, and view your blocknotes.',
|
||||
'dashboard_desc_admin' => 'As an Admin you can view, manage, and delete blocknotes of all users.',
|
||||
'btn_new_blocknote' => '➕ New Blocknote',
|
||||
'btn_import_json' => '📥 Import JSON',
|
||||
'btn_export_json' => '💾 Export JSON',
|
||||
'btn_open_edit' => '👁️ Open & Edit',
|
||||
'btn_rename' => '✏️ Rename',
|
||||
'btn_delete' => '🗑️ Delete',
|
||||
'empty_blocknotes_title' => 'No Blocknotes found',
|
||||
'empty_blocknotes_desc_user' => 'You haven\'t created any blocknote yet. Start now!',
|
||||
'empty_blocknotes_desc_admin' => 'There are no blocknotes saved in the system yet.',
|
||||
'modal_create_title' => '➕ Create New Blocknote',
|
||||
'modal_rename_title' => '✏️ Rename Blocknote',
|
||||
'modal_import_title' => '📥 Import Blocknote (JSON)',
|
||||
'label_title' => 'Blocknote Title',
|
||||
'label_file_json' => 'Upload .json File',
|
||||
'label_paste_json' => 'Or paste JSON code here',
|
||||
'btn_cancel' => 'Cancel',
|
||||
'btn_save' => 'Save',
|
||||
'btn_create' => 'Create Blocknote',
|
||||
'btn_import' => 'Import Blocknote',
|
||||
'note_single' => 'Note',
|
||||
'note_plural' => 'Notes',
|
||||
|
||||
// View Blocknote
|
||||
'btn_back_list' => '⬅️ Back to Blocknotes',
|
||||
'btn_expand_all' => '📂 Expand All',
|
||||
'btn_collapse_all' => '📁 Collapse All',
|
||||
'btn_new_note' => '➕ New Note',
|
||||
'btn_add_subnote' => '➕ Subnote',
|
||||
'subnote_single' => 'subnote',
|
||||
'subnote_plural' => 'subnotes',
|
||||
'badge_text' => '📄 Text',
|
||||
'badge_command' => '⚡ Command',
|
||||
'btn_copy' => '📋 Copy',
|
||||
'btn_copied' => '✓ Copied!',
|
||||
'search_placeholder' => '🔍 Search notes, subnotes, or commands in this blocknote...',
|
||||
'btn_clear_search' => '❌ Clear Search',
|
||||
'search_no_results' => 'No results found',
|
||||
'search_no_results_desc' => 'No notes or commands match your search term in this blocknote.',
|
||||
'modal_add_note' => '➕ New Block Note',
|
||||
'modal_edit_note' => '✏️ Edit Note',
|
||||
'modal_add_subnote' => '➕ Add Subnote',
|
||||
'modal_edit_subnote' => '✏️ Edit Subnote',
|
||||
'label_note_description' => 'Description (optional)',
|
||||
'label_subnote_title' => 'Subnote Title',
|
||||
'label_subnote_type' => 'Subnote Type',
|
||||
'label_subnote_content' => 'Content',
|
||||
'type_option_text' => '📄 Generic Text',
|
||||
'type_option_command' => '⚡ Command (with Copy button)',
|
||||
|
||||
// Profile & Settings
|
||||
'profile_title' => '🎨 Profile & Theme Settings',
|
||||
'profile_desc' => 'Customize password, UI colors, language, and default landing page.',
|
||||
'card_password_title' => '🔒 Change Password',
|
||||
'card_colors_title' => '🎨 Interface Colors (HSL)',
|
||||
'card_lang_title' => '🌍 Interface Language',
|
||||
'card_landing_title' => '🏠 Default Landing Page',
|
||||
'label_new_pass' => 'New Password',
|
||||
'label_confirm_pass' => 'Confirm New Password',
|
||||
'label_select_lang' => 'Select Language',
|
||||
'label_select_landing' => 'Select Landing Page',
|
||||
'landing_option_dashboard' => '📋 Main Selection Page (All Blocknotes)',
|
||||
'landing_option_bn_prefix' => '📌 Open directly: ',
|
||||
'btn_update_pass' => '🔑 Update Password',
|
||||
'btn_save_colors' => '💾 Save Color Preferences',
|
||||
'btn_save_lang' => '🌍 Save Language',
|
||||
'btn_save_landing' => '🏠 Save Landing Page',
|
||||
|
||||
// Admin Users
|
||||
'admin_title' => '👑 User Administration Panel',
|
||||
'admin_desc' => 'Create, manage, and edit user roles and access.',
|
||||
'btn_add_user' => '➕ Add New User',
|
||||
'col_username' => 'Username',
|
||||
'col_role' => 'Role',
|
||||
'col_bns' => 'Blocknotes Created',
|
||||
'col_created' => 'Created Date',
|
||||
'col_actions' => 'Admin Actions',
|
||||
'role_standard' => 'Standard User',
|
||||
'role_admin' => 'Administrator',
|
||||
'role_owner' => '👑 Owner',
|
||||
'badge_owner' => '👑 Owner',
|
||||
'btn_reset_pass' => '🔑 Reset Pass',
|
||||
'modal_create_user' => '➕ Register New User',
|
||||
'modal_reset_pass' => '🔑 Reset User Password',
|
||||
'card_site_settings_title' => '⚙️ Site Settings (Owner Only)',
|
||||
'label_site_title' => 'Global Application / Site Title',
|
||||
'label_favicon' => 'Site Favicon (High Resolution, min 64x64px)',
|
||||
'btn_save_site_title' => '💾 Save Site Title',
|
||||
'btn_upload_favicon' => '📤 Upload New Favicon',
|
||||
|
||||
// Confirm Dialogs
|
||||
'confirm_delete_blocknote' => 'Are you sure you want to delete this blocknote and all its notes?',
|
||||
'confirm_delete_note' => 'Are you sure you want to delete this note and all its subnotes?',
|
||||
'confirm_delete_subnote' => 'Are you sure you want to delete this subnote?',
|
||||
'confirm_delete_user' => 'Are you sure you want to delete this user?',
|
||||
|
||||
// Placeholders
|
||||
'placeholder_bn_title' => 'E.g. Linux Server Commands, PHP Notes...',
|
||||
'placeholder_rename_title' => 'New title...',
|
||||
'placeholder_import_title' => 'E.g. Positive Internet',
|
||||
'placeholder_paste_json' => 'Paste JSON here in old or new format...',
|
||||
'placeholder_note_title' => 'E.g. MySQL Installation, Server Setup...',
|
||||
'placeholder_note_desc' => 'Short description of this note block...',
|
||||
'placeholder_subnote_title' => 'E.g. Database creation command...',
|
||||
'placeholder_subnote_content' => 'Enter text or command instructions...',
|
||||
'placeholder_site_title' => 'E.g. Blocknotes, Enterprise Notes...',
|
||||
'placeholder_username_new' => 'e.g. john, mary...',
|
||||
'placeholder_password_new' => 'Enter new password',
|
||||
'placeholder_password_confirm' => 'Repeat new password',
|
||||
|
||||
// Extra Labels
|
||||
'label_owner_prefix' => 'Owner: ',
|
||||
'label_updated_prefix' => 'Last updated: ',
|
||||
'label_you' => 'You',
|
||||
'label_unknown' => 'Unknown',
|
||||
'label_current_favicon' => 'Current Favicon: ',
|
||||
|
||||
// First Start Installer Setup
|
||||
'setup_title' => '🚀 Blocknotes Initial Setup',
|
||||
'setup_subtitle' => 'Configure MySQL database and create the initial privileged users (Owner & Admin).',
|
||||
'setup_sec1_title' => '1. MySQL Database Configuration',
|
||||
'setup_db_host' => 'Database Host',
|
||||
'setup_db_name' => 'Database Name',
|
||||
'setup_db_user' => 'MySQL User',
|
||||
'setup_db_pass' => 'MySQL Password',
|
||||
'setup_db_pass_placeholder' => 'Password (leave empty if none)',
|
||||
'setup_sec2_title' => '2. Owner Account (Single Owner)',
|
||||
'setup_owner_user' => 'Owner Username',
|
||||
'setup_owner_pass' => 'Owner Password',
|
||||
'setup_owner_pass_placeholder' => 'Enter password for Owner',
|
||||
'setup_sec3_title' => '3. First Admin Account',
|
||||
'setup_admin_user' => 'Admin Username',
|
||||
'setup_admin_pass' => 'Admin Password',
|
||||
'setup_admin_pass_placeholder' => 'Enter password for Admin',
|
||||
'setup_btn_submit' => '⚡ Complete Installation & Configure System',
|
||||
'err_setup_db_fields' => 'Please fill in all MySQL database connection fields.',
|
||||
'err_setup_owner_fields' => 'Please enter username and password for the Owner user.',
|
||||
'err_setup_admin_fields' => 'Please enter username and password for the first Admin user.',
|
||||
'err_setup_same_user' => 'Owner user and Admin user must have different usernames.'
|
||||
],
|
||||
|
||||
'es' => [
|
||||
// Login Page
|
||||
'login_title' => 'Iniciar sesión en Blocknotes',
|
||||
'login_subtitle' => 'Gestiona tus notas y comandos',
|
||||
'label_username' => 'Nombre de Usuario',
|
||||
'label_password' => 'Contraseña',
|
||||
'placeholder_username' => 'Introduce nombre de usuario',
|
||||
'placeholder_password' => 'Introduce contraseña',
|
||||
'btn_submit_login' => '🔑 Iniciar Sesión',
|
||||
'login_hint_footer' => 'Credencial predeterminada para el primer acceso',
|
||||
'login_installed_success' => '🎉 ¡Configuración completada! Inicia sesión con tus credenciales.',
|
||||
|
||||
// Navbar
|
||||
'nav_blocknotes' => '📓 Blocknotes',
|
||||
'nav_colors_profile' => '🎨 Colores y Perfil',
|
||||
'nav_admin' => '👑 Gestión de Usuarios',
|
||||
'nav_logout' => '🚪 Salir',
|
||||
'nav_login' => '🔑 Iniciar Sesión',
|
||||
'nav_language' => '🌐 Idioma',
|
||||
|
||||
// Dashboard (home)
|
||||
'dashboard_title_user' => 'Mis Blocknotes',
|
||||
'dashboard_title_admin' => 'Todos los Blocknotes (Vista Admin)',
|
||||
'dashboard_desc_user' => 'Crea, organiza y consulta tus blocknotes.',
|
||||
'dashboard_desc_admin' => 'Como Admin puedes ver, gestionar y eliminar los blocknotes de todos los usuarios.',
|
||||
'btn_new_blocknote' => '➕ Nuevo Blocknote',
|
||||
'btn_import_json' => '📥 Importar JSON',
|
||||
'btn_export_json' => '💾 Exportar JSON',
|
||||
'btn_open_edit' => '👁️ Abrir y Editar',
|
||||
'btn_rename' => '✏️ Renombrar',
|
||||
'btn_delete' => '🗑️ Eliminar',
|
||||
'empty_blocknotes_title' => 'No se encontraron blocknotes',
|
||||
'empty_blocknotes_desc_user' => 'Aún no has creado ningún blocknote. ¡Empieza ahora!',
|
||||
'empty_blocknotes_desc_admin' => 'Aún no hay blocknotes guardados en el sistema.',
|
||||
'modal_create_title' => '➕ Crear Nuevo Blocknote',
|
||||
'modal_rename_title' => '✏️ Renombrar Blocknote',
|
||||
'modal_import_title' => '📥 Importar Blocknote (JSON)',
|
||||
'label_title' => 'Título del Blocknote',
|
||||
'label_file_json' => 'Subir archivo .json',
|
||||
'label_paste_json' => 'O pega el código JSON aquí',
|
||||
'btn_cancel' => 'Cancelar',
|
||||
'btn_save' => 'Guardar',
|
||||
'btn_create' => 'Crear Blocknote',
|
||||
'btn_import' => 'Importar Blocknote',
|
||||
'note_single' => 'Nota',
|
||||
'note_plural' => 'Notas',
|
||||
|
||||
// View Blocknote
|
||||
'btn_back_list' => '⬅️ Volver a Blocknotes',
|
||||
'btn_expand_all' => '📂 Expandir Todas',
|
||||
'btn_collapse_all' => '📁 Contraer Todas',
|
||||
'btn_new_note' => '➕ Nueva Nota',
|
||||
'btn_add_subnote' => '➕ Subnota',
|
||||
'subnote_single' => 'subnota',
|
||||
'subnote_plural' => 'subnotas',
|
||||
'badge_text' => '📄 Texto',
|
||||
'badge_command' => '⚡ Comando',
|
||||
'btn_copy' => '📋 Copiar',
|
||||
'btn_copied' => '✓ ¡Copiado!',
|
||||
'search_placeholder' => '🔍 Buscar notas, subnotas o comandos...',
|
||||
'btn_clear_search' => '❌ Cancelar Búsqueda',
|
||||
'search_no_results' => 'No se encontraron resultados',
|
||||
'search_no_results_desc' => 'Ninguna nota o comando coincide con tu búsqueda.',
|
||||
'modal_add_note' => '➕ Nueva Nota en Bloque',
|
||||
'modal_edit_note' => '✏️ Editar Nota',
|
||||
'modal_add_subnote' => '➕ Añadir Subnota',
|
||||
'modal_edit_subnote' => '✏️ Editar Subnota',
|
||||
'label_note_description' => 'Descripción (opcional)',
|
||||
'label_subnote_title' => 'Título de Subnota',
|
||||
'label_subnote_type' => 'Tipo de Subnota',
|
||||
'label_subnote_content' => 'Contenido',
|
||||
'type_option_text' => '📄 Texto genérico',
|
||||
'type_option_command' => '⚡ Comando (con botón Copiar)',
|
||||
|
||||
// Profile & Settings
|
||||
'profile_title' => '🎨 Ajustes de Perfil y Tema',
|
||||
'profile_desc' => 'Personaliza contraseña, colores de interfaz, idioma y página de inicio.',
|
||||
'card_password_title' => '🔒 Cambiar Contraseña',
|
||||
'card_colors_title' => '🎨 Colores de Interfaz (HSL)',
|
||||
'card_lang_title' => '🌍 Idioma de la Interfaz',
|
||||
'card_landing_title' => '🏠 Página de Inicio Predeterminada',
|
||||
'label_new_pass' => 'Nueva Contraseña',
|
||||
'label_confirm_pass' => 'Confirmar Nueva Contraseña',
|
||||
'label_select_lang' => 'Seleccionar Idioma',
|
||||
'label_select_landing' => 'Seleccionar Página de Inicio',
|
||||
'landing_option_dashboard' => '📋 Página Principal (Todos los Blocknotes)',
|
||||
'landing_option_bn_prefix' => '📌 Abrir directamente: ',
|
||||
'btn_update_pass' => '🔑 Actualizar Contraseña',
|
||||
'btn_save_colors' => '💾 Guardar Colores',
|
||||
'btn_save_lang' => '🌍 Guardar Idioma',
|
||||
'btn_save_landing' => '🏠 Guardar Página de Inicio',
|
||||
|
||||
// Admin Users
|
||||
'admin_title' => '👑 Panel de Administración de Usuarios',
|
||||
'admin_desc' => 'Crea, gestiona y edita roles de usuarios y accesos.',
|
||||
'btn_add_user' => '➕ Añadir Nuevo Usuario',
|
||||
'col_username' => 'Nombre de Usuario',
|
||||
'col_role' => 'Rol',
|
||||
'col_bns' => 'Blocknotes Creados',
|
||||
'col_created' => 'Fecha de Creación',
|
||||
'col_actions' => 'Acciones de Admin',
|
||||
'role_standard' => 'Usuario Estándar',
|
||||
'role_admin' => 'Administrador',
|
||||
'role_owner' => '👑 Propietario (Owner)',
|
||||
'badge_owner' => '👑 Propietario',
|
||||
'btn_reset_pass' => '🔑 Reset Pass',
|
||||
'modal_create_user' => '➕ Registrar Nuevo Usuario',
|
||||
'modal_reset_pass' => '🔑 Resetear Contraseña',
|
||||
'card_site_settings_title' => '⚙️ Ajustes del Sitio (Solo Propietario)',
|
||||
'label_site_title' => 'Título del Sitio / Aplicación',
|
||||
'label_favicon' => 'Favicon del Sitio (Alta resolución, mín 64x64px)',
|
||||
'btn_save_site_title' => '💾 Guardar Título',
|
||||
'btn_upload_favicon' => '📤 Subir Nueva Favicon',
|
||||
|
||||
// Confirm Dialogs
|
||||
'confirm_delete_blocknote' => '¿Estás seguro de que quieres eliminar este blocknote y todas sus notas?',
|
||||
'confirm_delete_note' => '¿Estás seguro de que quieres eliminar esta nota y todas sus subnotas?',
|
||||
'confirm_delete_subnote' => '¿Estás seguro de que quieres eliminar esta subnota?',
|
||||
'confirm_delete_user' => '¿Estás seguro de que quieres eliminar este usuario?',
|
||||
|
||||
// Placeholders
|
||||
'placeholder_bn_title' => 'Ej. Comandos Servidor Linux...',
|
||||
'placeholder_rename_title' => 'Nuevo título...',
|
||||
'placeholder_import_title' => 'Ej. Positive Internet',
|
||||
'placeholder_paste_json' => 'Pega el JSON aquí en formato antiguo o nuevo...',
|
||||
'placeholder_note_title' => 'Ej. Instalación MySQL...',
|
||||
'placeholder_note_desc' => 'Breve descripción de este bloque de notas...',
|
||||
'placeholder_subnote_title' => 'Ej. Comando creación base de datos...',
|
||||
'placeholder_subnote_content' => 'Introduce el texto o instrucciones del comando...',
|
||||
'placeholder_site_title' => 'Ej. Blocknotes...',
|
||||
'placeholder_username_new' => 'ej. mario, juan...',
|
||||
'placeholder_password_new' => 'Introduce nueva contraseña',
|
||||
'placeholder_password_confirm' => 'Repite nueva contraseña',
|
||||
|
||||
// Extra Labels
|
||||
'label_owner_prefix' => 'Propietario: ',
|
||||
'label_updated_prefix' => 'Última actualización: ',
|
||||
'label_you' => 'Tú',
|
||||
'label_unknown' => 'Desconocido',
|
||||
'label_current_favicon' => 'Favicon Actual: ',
|
||||
|
||||
// First Start Installer Setup
|
||||
'setup_title' => '🚀 Configuración Inicial de Blocknotes',
|
||||
'setup_subtitle' => 'Configura la base de datos MySQL y crea los primeros usuarios privilegiados (Propietario y Admin).',
|
||||
'setup_sec1_title' => '1. Configuración de Base de Datos MySQL',
|
||||
'setup_db_host' => 'Host de Base de Datos',
|
||||
'setup_db_name' => 'Nombre de la Base de Datos',
|
||||
'setup_db_user' => 'Usuario MySQL',
|
||||
'setup_db_pass' => 'Contraseña MySQL',
|
||||
'setup_db_pass_placeholder' => 'Contraseña (deja en blanco si no hay)',
|
||||
'setup_sec2_title' => '2. Cuenta de Propietario (Único)',
|
||||
'setup_owner_user' => 'Nombre de Usuario Propietario',
|
||||
'setup_owner_pass' => 'Contraseña de Propietario',
|
||||
'setup_owner_pass_placeholder' => 'Introduce contraseña para Propietario',
|
||||
'setup_sec3_title' => '3. Primera Cuenta de Administrador (Admin)',
|
||||
'setup_admin_user' => 'Nombre de Usuario Admin',
|
||||
'setup_admin_pass' => 'Contraseña de Admin',
|
||||
'setup_admin_pass_placeholder' => 'Introduce contraseña para Admin',
|
||||
'setup_btn_submit' => '⚡ Completar Instalación y Configurar Sistema',
|
||||
'err_setup_db_fields' => 'Por favor completa todos los campos de conexión a la base de datos MySQL.',
|
||||
'err_setup_owner_fields' => 'Por favor introduce nombre de usuario y contraseña para el Propietario.',
|
||||
'err_setup_admin_fields' => 'Por favor introduce nombre de usuario y contraseña para el primer Admin.',
|
||||
'err_setup_same_user' => 'El usuario Propietario y el usuario Admin deben tener nombres diferentes.'
|
||||
],
|
||||
|
||||
'fr' => [
|
||||
// Login Page
|
||||
'login_title' => 'Connexion à Blocknotes',
|
||||
'login_subtitle' => 'Gérez vos notes et vos commandes',
|
||||
'label_username' => 'Nom d\'Utilisateur',
|
||||
'label_password' => 'Mot de Passe',
|
||||
'placeholder_username' => 'Entrez nom d\'utilisateur',
|
||||
'placeholder_password' => 'Entrez mot de passe',
|
||||
'btn_submit_login' => '🔑 Connexion',
|
||||
'login_hint_footer' => 'Identifiant par défaut pour le premier accès',
|
||||
'login_installed_success' => '🎉 Configuration terminée! Connectez-vous avec vos identifiants.',
|
||||
|
||||
// Navbar
|
||||
'nav_blocknotes' => '📓 Blocknotes',
|
||||
'nav_colors_profile' => '🎨 Couleurs & Profil',
|
||||
'nav_admin' => '👑 Gestion des Utilisateurs',
|
||||
'nav_logout' => '🚪 Déconnexion',
|
||||
'nav_login' => '🔑 Connexion',
|
||||
'nav_language' => '🌐 Langue',
|
||||
|
||||
// Dashboard (home)
|
||||
'dashboard_title_user' => 'Mes Blocknotes',
|
||||
'dashboard_title_admin' => 'Tous les Blocknotes (Vue Admin)',
|
||||
'dashboard_desc_user' => 'Créez, organisez et consultez vos blocknotes.',
|
||||
'dashboard_desc_admin' => 'En tant qu\'Admin vous pouvez afficher, gérer et supprimer les blocknotes de tous les utilisateurs.',
|
||||
'btn_new_blocknote' => '➕ Nouveau Blocknote',
|
||||
'btn_import_json' => '📥 Importer JSON',
|
||||
'btn_export_json' => '💾 Exporter JSON',
|
||||
'btn_open_edit' => '👁️ Ouvrir & Modifier',
|
||||
'btn_rename' => '✏️ Renommer',
|
||||
'btn_delete' => '🗑️ Supprimer',
|
||||
'empty_blocknotes_title' => 'Aucun blocknote trouvé',
|
||||
'empty_blocknotes_desc_user' => 'Vous n\'avez pas encore créé de blocknote. Commencez dès maintenant!',
|
||||
'empty_blocknotes_desc_admin' => 'Il n\'y a encore aucun blocknote enregistré dans le système.',
|
||||
'modal_create_title' => '➕ Créer un Nouveau Blocknote',
|
||||
'modal_rename_title' => '✏️ Renommer le Blocknote',
|
||||
'modal_import_title' => '📥 Importer Blocknote (JSON)',
|
||||
'label_title' => 'Titre du Blocknote',
|
||||
'label_file_json' => 'Téléverser le fichier .json',
|
||||
'label_paste_json' => 'Ou collez le code JSON ici',
|
||||
'btn_cancel' => 'Annuler',
|
||||
'btn_save' => 'Enregistrer',
|
||||
'btn_create' => 'Créer Blocknote',
|
||||
'btn_import' => 'Importer Blocknote',
|
||||
'note_single' => 'Note',
|
||||
'note_plural' => 'Notes',
|
||||
|
||||
// View Blocknote
|
||||
'btn_back_list' => '⬅️ Retour aux Blocknotes',
|
||||
'btn_expand_all' => '📂 Tout Développer',
|
||||
'btn_collapse_all' => '📁 Tout Réduire',
|
||||
'btn_new_note' => '➕ Nouvelle Note',
|
||||
'btn_add_subnote' => '➕ Sous-note',
|
||||
'subnote_single' => 'sous-note',
|
||||
'subnote_plural' => 'sous-notes',
|
||||
'badge_text' => '📄 Texte',
|
||||
'badge_command' => '⚡ Commande',
|
||||
'btn_copy' => '📋 Copier',
|
||||
'btn_copied' => '✓ Copié!',
|
||||
'search_placeholder' => '🔍 Rechercher notes, sous-notes ou commandes...',
|
||||
'btn_clear_search' => '❌ Annuler la Recherche',
|
||||
'search_no_results' => 'Aucun résultat trouvé',
|
||||
'search_no_results_desc' => 'Aucune note ou commande ne correspond à votre recherche.',
|
||||
'modal_add_note' => '➕ Nouvelle Note par Bloc',
|
||||
'modal_edit_note' => '✏️ Modifier la Note',
|
||||
'modal_add_subnote' => '➕ Ajouter une Sous-note',
|
||||
'modal_edit_subnote' => '✏️ Modifier la Sous-note',
|
||||
'label_note_description' => 'Description (facultatif)',
|
||||
'label_subnote_title' => 'Titre de la Sous-note',
|
||||
'label_subnote_type' => 'Type de Sous-note',
|
||||
'label_subnote_content' => 'Contenu',
|
||||
'type_option_text' => '📄 Texte générique',
|
||||
'type_option_command' => '⚡ Commande (avec bouton Copier)',
|
||||
|
||||
// Profile & Settings
|
||||
'profile_title' => '🎨 Paramètres Profil & Thème',
|
||||
'profile_desc' => 'Personnalisez votre mot de passe, couleurs, langue et page d\'accueil.',
|
||||
'card_password_title' => '🔒 Changer le Mot de Passe',
|
||||
'card_colors_title' => '🎨 Couleurs de l\'Interface (HSL)',
|
||||
'card_lang_title' => '🌍 Langue de l\'Interface',
|
||||
'card_landing_title' => '🏠 Page d\'Accueil par Défaut',
|
||||
'label_new_pass' => 'Nouveau Mot de Passe',
|
||||
'label_confirm_pass' => 'Confirmer le Mot de Passe',
|
||||
'label_select_lang' => 'Sélectionner la Langue',
|
||||
'label_select_landing' => 'Sélectionner la Page d\'Accueil',
|
||||
'landing_option_dashboard' => '📋 Page Principale (Tous les Blocknotes)',
|
||||
'landing_option_bn_prefix' => '📌 Ouvrir directement: ',
|
||||
'btn_update_pass' => '🔑 Mettre à Jour',
|
||||
'btn_save_colors' => '💾 Enregistrer les Couleurs',
|
||||
'btn_save_lang' => '🌍 Enregistrer la Langue',
|
||||
'btn_save_landing' => '🏠 Enregistrer la Page d\'Accueil',
|
||||
|
||||
// Admin Users
|
||||
'admin_title' => '👑 Panneau d\'Administration Utilisateurs',
|
||||
'admin_desc' => 'Créez, gérez et modifiez les rôles et accès des utilisateurs.',
|
||||
'btn_add_user' => '➕ Ajouter un Utilisateur',
|
||||
'col_username' => 'Nom d\'Utilisateur',
|
||||
'col_role' => 'Rôle',
|
||||
'col_bns' => 'Blocknotes Créés',
|
||||
'col_created' => 'Date de Création',
|
||||
'col_actions' => 'Actions Admin',
|
||||
'role_standard' => 'Utilisateur Standard',
|
||||
'role_admin' => 'Administrateur',
|
||||
'role_owner' => '👑 Propriétaire (Owner)',
|
||||
'badge_owner' => '👑 Propriétaire',
|
||||
'btn_reset_pass' => '🔑 Réinit Pass',
|
||||
'modal_create_user' => '➕ Enregistrer un Utilisateur',
|
||||
'modal_reset_pass' => '🔑 Réinitialiser le Mot de Passe',
|
||||
'card_site_settings_title' => '⚙️ Paramètres du Site (Propriétaire Uniquement)',
|
||||
'label_site_title' => 'Titre Global du Site',
|
||||
'label_favicon' => 'Favicon du Site (Haute résolution, min 64x64px)',
|
||||
'btn_save_site_title' => '💾 Enregistrer le Titre',
|
||||
'btn_upload_favicon' => '📤 Téléverser la Favicon',
|
||||
|
||||
// Confirm Dialogs
|
||||
'confirm_delete_blocknote' => 'Êtes-vous sûr de vouloir supprimer ce blocknote et toutes ses notes?',
|
||||
'confirm_delete_note' => 'Êtes-vous sûr de vouloir supprimer cette note et toutes ses sous-notes?',
|
||||
'confirm_delete_subnote' => 'Êtes-vous sûr de vouloir supprimer cette sous-note?',
|
||||
'confirm_delete_user' => 'Êtes-vous sûr de vouloir supprimer cet utilisateur?',
|
||||
|
||||
// Placeholders
|
||||
'placeholder_bn_title' => 'Ex. Commandes Serveur Linux...',
|
||||
'placeholder_rename_title' => 'Nouveau titre...',
|
||||
'placeholder_import_title' => 'Ex. Positive Internet',
|
||||
'placeholder_paste_json' => 'Collez le JSON ici au format ancien ou nouveau...',
|
||||
'placeholder_note_title' => 'Ex. Installation MySQL...',
|
||||
'placeholder_note_desc' => 'Brève description de ce bloc de notes...',
|
||||
'placeholder_subnote_title' => 'Ex. Commande création base de données...',
|
||||
'placeholder_subnote_content' => 'Entrez le texte ou les instructions de la commande...',
|
||||
'placeholder_site_title' => 'Ex. Blocknotes...',
|
||||
'placeholder_username_new' => 'ex. pierre, marie...',
|
||||
'placeholder_password_new' => 'Entrez nouveau mot de passe',
|
||||
'placeholder_password_confirm' => 'Répétez le mot de passe',
|
||||
|
||||
// Extra Labels
|
||||
'label_owner_prefix' => 'Propriétaire: ',
|
||||
'label_updated_prefix' => 'Dernière mise à jour: ',
|
||||
'label_you' => 'Vous',
|
||||
'label_unknown' => 'Inconnu',
|
||||
'label_current_favicon' => 'Favicon Actuelle: ',
|
||||
|
||||
// First Start Installer Setup
|
||||
'setup_title' => '🚀 Configuration Initiale de Blocknotes',
|
||||
'setup_subtitle' => 'Configurez la base de données MySQL et créez les premiers utilisateurs privilégiés (Propriétaire et Admin).',
|
||||
'setup_sec1_title' => '1. Configuration de la Base de Données MySQL',
|
||||
'setup_db_host' => 'Hôte de la Base de Données',
|
||||
'setup_db_name' => 'Nom de la Base de Données',
|
||||
'setup_db_user' => 'Utilisateur MySQL',
|
||||
'setup_db_pass' => 'Mot de Passe MySQL',
|
||||
'setup_db_pass_placeholder' => 'Mot de passe (laissez vide si aucun)',
|
||||
'setup_sec2_title' => '2. Compte Propriétaire (Unique)',
|
||||
'setup_owner_user' => 'Nom d\'Utilisateur Propriétaire',
|
||||
'setup_owner_pass' => 'Mot de Passe Propriétaire',
|
||||
'setup_owner_pass_placeholder' => 'Entrez le mot de passe pour le Propriétaire',
|
||||
'setup_sec3_title' => '3. Premier Compte Administrateur (Admin)',
|
||||
'setup_admin_user' => 'Nom d\'Utilisateur Admin',
|
||||
'setup_admin_pass' => 'Mot de Passe Admin',
|
||||
'setup_admin_pass_placeholder' => 'Entrez le mot de passe pour Admin',
|
||||
'setup_btn_submit' => '⚡ Terminer l\'Installation et Configurer le Système',
|
||||
'err_setup_db_fields' => 'Veuillez remplir tous les champs de connexion à la base de données MySQL.',
|
||||
'err_setup_owner_fields' => 'Veuillez entrer le nom d\'utilisateur et le mot de passe pour le Propriétaire.',
|
||||
'err_setup_admin_fields' => 'Veuillez entrer le nom d\'utilisateur et le mot de passe pour le premier Admin.',
|
||||
'err_setup_same_user' => 'L\'utilisateur Propriétaire et l\'utilisateur Admin doivent avoir des noms différents.'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate key to current active language string.
|
||||
*/
|
||||
function __($key, $default = '') {
|
||||
$lang = get_current_lang();
|
||||
$translations = get_translations();
|
||||
|
||||
if (isset($translations[$lang][$key])) {
|
||||
return $translations[$lang][$key];
|
||||
}
|
||||
if (isset($translations['it'][$key])) {
|
||||
return $translations['it'][$key];
|
||||
}
|
||||
if (isset($translations['en'][$key])) {
|
||||
return $translations['en'][$key];
|
||||
}
|
||||
return !empty($default) ? $default : $key;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Global Site Settings & High-Resolution Favicon Management (Owner Exclusive)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get site setting value by key.
|
||||
*/
|
||||
function get_site_setting($key, $default = '') {
|
||||
global $conn;
|
||||
if (!isset($conn)) return $default;
|
||||
|
||||
$stmt = $conn->prepare("SELECT setting_value FROM site_settings WHERE setting_key = ? LIMIT 1");
|
||||
$stmt->bind_param("s", $key);
|
||||
$stmt->execute();
|
||||
$res = $stmt->get_result();
|
||||
|
||||
if ($row = $res->fetch_assoc()) {
|
||||
$stmt->close();
|
||||
return $row['setting_value'];
|
||||
}
|
||||
$stmt->close();
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update or insert site setting.
|
||||
*/
|
||||
function update_site_setting($key, $value) {
|
||||
global $conn;
|
||||
if (!isset($conn)) return false;
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO site_settings (setting_key, setting_value) VALUES (?, ?) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)");
|
||||
$stmt->bind_param("ss", $key, $value);
|
||||
$res = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload and validate high-resolution site Favicon.
|
||||
*/
|
||||
function upload_site_favicon($file) {
|
||||
if (empty($file) || $file['error'] !== UPLOAD_ERR_OK) {
|
||||
return ['success' => false, 'message' => 'Errore nel caricamento del file favicon.'];
|
||||
}
|
||||
|
||||
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
||||
$allowed_extensions = ['png', 'ico', 'webp', 'svg', 'jpeg', 'jpg'];
|
||||
|
||||
if (!in_array($ext, $allowed_extensions)) {
|
||||
return ['success' => false, 'message' => 'Formato favicon non supportato. Formati ammessi: PNG, ICO, WEBP, SVG, JPG.'];
|
||||
}
|
||||
|
||||
// High resolution dimension check for raster formats (PNG, WEBP, JPG, ICO)
|
||||
if (in_array($ext, ['png', 'webp', 'jpeg', 'jpg', 'ico'])) {
|
||||
$image_info = @getimagesize($file['tmp_name']);
|
||||
if ($image_info) {
|
||||
$width = $image_info[0];
|
||||
$height = $image_info[1];
|
||||
|
||||
// Minimum high resolution requirement: 64x64px
|
||||
if ($width < 64 || $height < 64) {
|
||||
return [
|
||||
'success' => false,
|
||||
'message' => "Risoluzione favicon troppo bassa ({$width}x{$height}px). Per garantire la massima qualità visiva, carica un'immagine ad alta risoluzione (almeno 64x64px)."
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure assets/img directory exists
|
||||
$img_dir = ROOT_DIR . "assets/img/";
|
||||
if (!is_dir($img_dir)) {
|
||||
@mkdir($img_dir, 0777, true);
|
||||
}
|
||||
|
||||
$new_filename = "favicon_" . time() . "." . $ext;
|
||||
$target_file = $img_dir . $new_filename;
|
||||
$relative_path = "assets/img/" . $new_filename;
|
||||
|
||||
if (move_uploaded_file($file['tmp_name'], $target_file)) {
|
||||
update_site_setting('site_favicon', $relative_path);
|
||||
return ['success' => true, 'message' => 'Favicon aggiornata con successo!'];
|
||||
}
|
||||
|
||||
return ['success' => false, 'message' => 'Impossibile salvare il file favicon su disco.'];
|
||||
}
|
||||
Reference in New Issue
Block a user