Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using BCrypt.Net; // Підключення бібліотеки для хешування паролів
- using MySql.Data.MySqlClient; // Підключення драйвера для роботи з MySQL
- using System; // Базові системні класи
- using System.Data; // Робота з даними та таблицями
- using System.Drawing; // Робота з графікою (розміри, кольори)
- using System.Windows.Forms; // Бібліотека для створення віконного інтерфейсу
- using System.Text.RegularExpressions; // Робота з регулярними виразами
- namespace lab8 // Оголошення простору імен проекту
- {
- public partial class UsersEdit : Form // Оголошення класу форми редагування користувачів
- {
- string connectionString = "server=localhost;database=lab;uid=root;pwd=;"; // Рядок підключення до бази даних
- int currentUserId = -1; // Змінна для зберігання ID поточного користувача (-1 означає створення нового)
- public UsersEdit(int id) // Конструктор форми, що приймає ID користувача
- {
- InitializeComponent(); // Ініціалізація компонентів інтерфейсу
- currentUserId = id; // Присвоєння отриманого ID внутрішній змінній
- Eye.ImageList = imageList1; // Прив'язка списку зображень до кнопки "око"
- Eye.ImageIndex = 4; // Встановлення початкової іконки (закрите око)
- Experience_Input.MaxLength = 200; // Обмеження довжини тексту в полі біографії
- }
- private void UsersEdit_Load(object sender, EventArgs e) // Обробник події завантаження форми
- {
- LoadRoles(); // Виклик методу завантаження ролей у випадаючий список
- if (currentUserId == -1) // Перевірка: якщо ми додаємо нового користувача
- {
- this.Text = "Додавання користувача"; // Зміна заголовка вікна
- Save.Text = " Додати"; // Зміна тексту на кнопці збереження
- Date_Input.Text = "Сформується автоматично"; // Підказка щодо дати реєстрації
- Date_Input.ForeColor = Color.Gray; // Встановлення сірого кольору для підказки
- }
- else // Якщо ми редагуємо існуючого користувача
- {
- this.Text = "Редагування користувача (ID: " + currentUserId + ")"; // Вивід ID у заголовок
- LoadUserData(); // Виклик методу завантаження даних користувача з БД
- }
- ToggleMentorFields(); // Налаштування видимості полів залежно від ролі
- }
- private void LoadRoles() // Метод для отримання списку ролей з бази даних
- {
- MySqlConnection conn = new MySqlConnection(connectionString); // Створення об'єкта підключення
- conn.Open(); // Відкриття з'єднання з БД
- string query = "SELECT id, role_name FROM roles"; // SQL-запит для отримання ролей
- MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn); // Адаптер для виконання запиту
- DataTable dt = new DataTable(); // Створення таблиці в пам'яті
- adapter.Fill(dt); // Заповнення таблиці даними з БД
- Role_Input.DataSource = dt; // Прив'язка таблиці до випадаючого списку
- Role_Input.DisplayMember = "role_name"; // Відображення назви ролі користувачу
- Role_Input.ValueMember = "id"; // Використання ID ролі як внутрішнього значення
- conn.Close(); // Закриття з'єднання
- }
- private void ToggleMentorFields() // Метод керування видимістю додаткових полів ментора
- {
- bool isMentor = false; // Прапорець, чи є вибрана роль ментором
- if (Role_Input.SelectedValue != null) // Перевірка, чи вибрано хоч якесь значення
- {
- if (Role_Input.SelectedValue.ToString() == "2") // Якщо ID ролі дорівнює 2 (Ментор)
- {
- isMentor = true; // Встановлюємо прапорець у true
- }
- }
- if (isMentor == true) // Якщо роль — ментор
- {
- Mentor_Info.Visible = true; // Показати групу полів інформації ментора
- Experience_Info.Visible = true; // Показати групу полів досвіду
- this.Size = new Size(898, 566); // Розширити вікно форми
- }
- else // Якщо роль — звичайний користувач
- {
- Mentor_Info.Visible = false; // Сховати поля ментора
- Experience_Info.Visible = false; // Сховати поля досвіду
- this.Size = new Size(463, 566); // Звузити вікно форми
- }
- }
- private void Role_Input_SelectedIndexChanged(object sender, EventArgs e) // Подія зміни ролі в списку
- {
- ToggleMentorFields(); // Перемикання видимості полів при зміні ролі
- }
- private void LoadUserData() // Метод завантаження повної інформації про користувача для редагування
- {
- MySqlConnection conn = new MySqlConnection(connectionString); // Створення підключення
- conn.Open(); // Відкриття з'єднання
- string query = "SELECT users.*, mentors.experience_years, mentors.biography, " +
- "mentors.website_url, mentors.linkedin_url, mentors.github_url " +
- "FROM users " +
- "LEFT JOIN mentors ON users.id = mentors.user_id " +
- "WHERE users.id = @id"; // SQL-запит з об'єднанням таблиць користувачів та менторів
- MySqlCommand cmd = new MySqlCommand(query, conn); // Створення команди
- cmd.Parameters.AddWithValue("@id", currentUserId); // Безпечна передача параметра ID
- MySqlDataReader dr = cmd.ExecuteReader(); // Виконання запиту та створення читача даних
- if (dr.Read()) // Якщо запис знайдено
- {
- Name_Input.Text = dr["full_name"].ToString(); // Заповнення поля ПІБ
- Email_Input.Text = dr["email"].ToString(); // Заповнення поля Email
- Role_Input.SelectedValue = dr["role_id"]; // Встановлення ролі в списку
- Date_Input.Text = dr["registration_date"].ToString(); // Вивід дати реєстрації
- if (dr["phone"] == DBNull.Value) // Перевірка на відсутність номера телефону
- {
- Phone_Input.Text = ""; // Очищення поля, якщо в БД NULL
- }
- else
- {
- Phone_Input.Text = dr["phone"].ToString(); // Заповнення номера телефону
- }
- if (dr["avatar_url"] == DBNull.Value) // Перевірка на відсутність посилання на аватар
- {
- Avatar_Input.Text = ""; // Очищення поля аватара
- }
- else
- {
- Avatar_Input.Text = dr["avatar_url"].ToString(); // Заповнення посилання
- }
- bool isActive = Convert.ToBoolean(dr["is_active"]); // Отримання статусу активності
- if (isActive == true) // Якщо користувач активний
- {
- Active.Checked = true; // Вибір радіокнопки "Активний"
- Inactive.Checked = false; // Зняття вибору з "Неактивний"
- }
- else // Якщо заблокований
- {
- Active.Checked = false; // Зняття вибору з "Активний"
- Inactive.Checked = true; // Вибір радіокнопки "Неактивний"
- }
- if (dr["experience_years"] == DBNull.Value) // Перевірка даних про роки досвіду
- {
- Years_Input.Value = 0; // Встановлення 0, якщо даних немає
- }
- else
- {
- Years_Input.Value = Convert.ToInt32(dr["experience_years"]); // Встановлення років досвіду
- }
- if (dr["biography"] == DBNull.Value) // Перевірка наявності біографії
- {
- Experience_Input.Text = ""; // Очищення поля
- }
- else
- {
- Experience_Input.Text = dr["biography"].ToString(); // Заповнення біографії
- }
- if (dr["website_url"] == DBNull.Value) // Перевірка посилання на сайт
- {
- Site_Input.Text = ""; // Очищення
- }
- else
- {
- Site_Input.Text = dr["website_url"].ToString(); // Заповнення сайту
- }
- if (dr["linkedin_url"] == DBNull.Value) // Перевірка LinkedIn
- {
- Linkedin_Input.Text = ""; // Очищення
- }
- else
- {
- Linkedin_Input.Text = dr["linkedin_url"].ToString(); // Заповнення LinkedIn
- }
- if (dr["github_url"] == DBNull.Value) // Перевірка GitHub
- {
- Github_Input.Text = ""; // Очищення
- }
- else
- {
- Github_Input.Text = dr["github_url"].ToString(); // Заповнення GitHub
- }
- }
- dr.Close(); // Закриття читача
- conn.Close(); // Закриття з'єднання
- }
- private bool IsValidUrl(string url) // Метод валідації посилань
- {
- if (string.IsNullOrWhiteSpace(url)) // Якщо рядок порожній
- {
- return true; // Вважаємо валідним (поле не обов'язкове)
- }
- if (url.Trim().ToLower().StartsWith("http")) // Перевірка, чи починається з http/https
- {
- return true; // Посилання коректне
- }
- return false; // Посилання некоректне
- }
- private void Save_Click(object sender, EventArgs e) // Головний метод збереження даних
- {
- if (Name_Input.Text == "" || Email_Input.Text == "") // Перевірка обов'язкових полів
- {
- MessageBox.Show("Заповніть обов'язкові поля."); // Вивід попередження
- return; // Зупинка збереження
- }
- if (currentUserId == -1) // Якщо створюється новий користувач
- {
- if (Password_Input.Text == "") // Перевірка наявності пароля
- {
- MessageBox.Show("Введіть пароль для нового користувача."); // Повідомлення про відсутність пароля
- return; // Зупинка
- }
- if (Password_Input.Text.Length < 8) // Перевірка мінімальної довжини
- {
- MessageBox.Show("Пароль має бути не менше 8 символів!"); // Попередження про короткий пароль
- return; // Зупинка
- }
- }
- else if (Password_Input.Text != "" && Password_Input.Text.Length < 8) // При редагуванні, якщо пароль змінюється
- {
- MessageBox.Show("Новий пароль має бути не менше 8 символів!"); // Попередження про довжину нового пароля
- return; // Зупинка
- }
- var oldFormat = Phone_Input.TextMaskFormat; // Збереження поточного формату маски телефону
- Phone_Input.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals; // Налаштування для отримання тільки цифр
- string plainPhone = Phone_Input.Text; // Отримання номера телефону без символів форматування
- Phone_Input.TextMaskFormat = oldFormat; // Повернення формату маски назад
- if (plainPhone != "" && plainPhone != "380") // Перевірка, чи введено номер телефону
- {
- if (Phone_Input.MaskFull == false) // Якщо маска заповнена не до кінця
- {
- MessageBox.Show("Номер телефону введено не повністю!"); // Попередження про неповний номер
- Phone_Input.Focus(); // Перевід фокусу на поле телефону
- return; // Зупинка
- }
- }
- if (IsValidUrl(Avatar_Input.Text) == false) // Перевірка посилання на аватар
- {
- MessageBox.Show("Некоректний URL аватара."); // Попередження про поганий URL
- return; // Зупинка
- }
- bool isMentor = false; // Визначення, чи є користувач ментором
- if (Role_Input.SelectedValue.ToString() == "2") // Якщо вибрано роль ID 2
- {
- isMentor = true; // Встановлюємо статус ментора
- }
- if (isMentor == true) // Якщо це ментор, перевіряємо його соцмережі
- {
- if (IsValidUrl(Site_Input.Text) == false || IsValidUrl(Linkedin_Input.Text) == false || IsValidUrl(Github_Input.Text) == false)
- {
- MessageBox.Show("Перевірте правильність посилань."); // Попередження про помилки в URL ментора
- return; // Зупинка
- }
- }
- MySqlConnection conn = new MySqlConnection(connectionString); // Створення з'єднання
- conn.Open(); // Відкриття з'єднання
- string checkEmailQuery = "SELECT COUNT(*) FROM users WHERE email = @email AND id != @id"; // Запит на унікальність пошти
- MySqlCommand checkCmd = new MySqlCommand(checkEmailQuery, conn); // Команда перевірки
- checkCmd.Parameters.AddWithValue("@email", Email_Input.Text.Trim()); // Передача Email
- checkCmd.Parameters.AddWithValue("@id", currentUserId); // Передача ID (щоб не сваритися на самого себе)
- int count = Convert.ToInt32(checkCmd.ExecuteScalar()); // Отримання кількості знайдених дублікатів
- if (count > 0) // Якщо такий Email вже є в іншого користувача
- {
- MessageBox.Show("Користувач з такою поштою вже існує!"); // Попередження про дублікат
- conn.Close(); // Закриття з'єднання
- return; // Зупинка
- }
- MySqlTransaction trans = conn.BeginTransaction(); // Початок транзакції для цілісності даних
- try
- {
- string userQuery = ""; // Рядок для SQL запиту користувача
- if (currentUserId == -1) // Якщо це новий запис
- {
- userQuery = "INSERT INTO users (full_name, email, phone, role_id, avatar_url, is_active, password_hash) " +
- "VALUES (@name, @email, @phone, @role, @avatar, @active, @pass); " +
- "SELECT LAST_INSERT_ID();"; // Додавання та отримання згенерованого ID
- }
- else // Якщо це оновлення існуючого
- {
- userQuery = "UPDATE users SET full_name=@name, email=@email, phone=@phone, role_id=@role, " +
- "avatar_url=@avatar, is_active=@active"; // Базова частина оновлення
- if (Password_Input.Text != "") // Якщо поле пароля не порожнє (пароль змінюють)
- {
- userQuery = userQuery + ", password_hash=@pass"; // Додаємо оновлення пароля до запиту
- }
- userQuery = userQuery + " WHERE id=@id"; // Умова за ID
- }
- MySqlCommand cmd = new MySqlCommand(userQuery, conn, trans); // Створення команди в межах транзакції
- cmd.Parameters.AddWithValue("@name", Name_Input.Text.Trim()); // Параметр імені
- cmd.Parameters.AddWithValue("@email", Email_Input.Text.Trim()); // Параметр Email
- cmd.Parameters.AddWithValue("@role", Role_Input.SelectedValue); // Параметр ролі
- if (Active.Checked == true) // Визначення бітового значення активності
- {
- cmd.Parameters.AddWithValue("@active", 1); // Активний
- }
- else
- {
- cmd.Parameters.AddWithValue("@active", 0); // Неактивний
- }
- if (Avatar_Input.Text == "") // Якщо посилання на аватар порожнє
- {
- cmd.Parameters.AddWithValue("@avatar", DBNull.Value); // Записуємо NULL в базу
- }
- else
- {
- cmd.Parameters.AddWithValue("@avatar", Avatar_Input.Text.Trim()); // Записуємо посилання
- }
- if (plainPhone == "" || plainPhone == "380") // Якщо телефон не введено
- {
- cmd.Parameters.AddWithValue("@phone", DBNull.Value); // Записуємо NULL
- }
- else
- {
- cmd.Parameters.AddWithValue("@phone", Phone_Input.Text); // Записуємо повний номер з маскою
- }
- if (Password_Input.Text != "") // Якщо потрібно зберегти пароль
- {
- string salt = BCrypt.Net.BCrypt.GenerateSalt(10); // Генерируємо "сіль" для безпеки
- string hashed = BCrypt.Net.BCrypt.HashPassword(Password_Input.Text, salt); // Хешуємо пароль
- cmd.Parameters.AddWithValue("@pass", hashed); // Передаємо хеш в параметри
- }
- if (currentUserId != -1) // Для існуючого користувача
- {
- cmd.Parameters.AddWithValue("@id", currentUserId); // Встановлюємо ID
- cmd.ExecuteNonQuery(); // Виконуємо оновлення
- }
- else // Для нового користувача
- {
- currentUserId = Convert.ToInt32(cmd.ExecuteScalar()); // Виконуємо вставку та отримуємо новий ID
- }
- if (isMentor == true) // Якщо користувач — ментор, оновлюємо додаткову таблицю
- {
- string deleteQuery = "DELETE FROM mentors WHERE user_id = @uid"; // Видаляємо старі дані ментора
- MySqlCommand dCmd = new MySqlCommand(deleteQuery, conn, trans); // Команда видалення
- dCmd.Parameters.AddWithValue("@uid", currentUserId); // Параметр ID
- dCmd.ExecuteNonQuery(); // Виконання видалення
- string mentorQuery = "INSERT INTO mentors (user_id, experience_years, biography, website_url, linkedin_url, github_url) " +
- "VALUES (@uid, @exp, @bio, @web, @link, @git)"; // Запит на додавання нових даних ментора
- MySqlCommand mCmd = new MySqlCommand(mentorQuery, conn, trans); // Створення команди
- mCmd.Parameters.AddWithValue("@uid", currentUserId); // Параметр ID
- mCmd.Parameters.AddWithValue("@exp", Years_Input.Value); // Кількість років досвіду
- if (Experience_Input.Text == "") // Обробка порожньої біографії
- {
- mCmd.Parameters.AddWithValue("@bio", DBNull.Value); // NULL
- }
- else
- {
- mCmd.Parameters.AddWithValue("@bio", Experience_Input.Text.Trim()); // Текст
- }
- if (Site_Input.Text == "") // Обробка порожнього сайту
- {
- mCmd.Parameters.AddWithValue("@web", DBNull.Value); // NULL
- }
- else
- {
- mCmd.Parameters.AddWithValue("@web", Site_Input.Text.Trim()); // Текст
- }
- if (Linkedin_Input.Text == "") // Обробка LinkedIn
- {
- mCmd.Parameters.AddWithValue("@link", DBNull.Value); // NULL
- }
- else
- {
- mCmd.Parameters.AddWithValue("@link", Linkedin_Input.Text.Trim()); // Текст
- }
- if (Github_Input.Text == "") // Обробка GitHub
- {
- mCmd.Parameters.AddWithValue("@git", DBNull.Value); // NULL
- }
- else
- {
- mCmd.Parameters.AddWithValue("@git", Github_Input.Text.Trim()); // Текст
- }
- mCmd.ExecuteNonQuery(); // Збереження даних ментора
- }
- trans.Commit(); // Підтвердження транзакції (збереження всіх змін)
- this.DialogResult = DialogResult.OK; // Встановлення результату успіху для виклику форми
- this.Close(); // Закриття вікна
- }
- catch (Exception ex) // Обробка помилок
- {
- trans.Rollback(); // Відкат усіх змін у разі помилки
- MessageBox.Show("Помилка збереження: " + ex.Message); // Повідомлення про помилку
- }
- conn.Close(); // Закриття з'єднання з БД
- }
- private void Exit_Click(object sender, EventArgs e) // Обробник кнопки "Скасувати" або "Вихід"
- {
- this.Close(); // Закриття вікна без збереження
- }
- private void Eye_Click(object sender, EventArgs e) // Керування видимістю пароля (кнопка з оком)
- {
- if (Password_Input.UseSystemPasswordChar == true) // Якщо пароль зараз прихований крапками
- {
- Password_Input.UseSystemPasswordChar = false; // Показати символи пароля
- Eye.ImageIndex = 5; // Змінити іконку на відкрите око
- }
- else // Якщо пароль зараз видно
- {
- Password_Input.UseSystemPasswordChar = true; // Сховати пароль крапками
- Eye.ImageIndex = 4; // Змінити іконку на закрите око
- }
- }
- private void Email_Input_Validating(object sender, System.ComponentModel.CancelEventArgs e) // Валідація Email при втраті фокусу
- {
- string pattern = @"^[^@\s]+@[^@\s]+\.[^@\s]+$"; // Регулярний вираз для перевірки формату пошти
- if (Email_Input.Text != "") // Якщо поле не порожнє
- {
- if (Regex.IsMatch(Email_Input.Text, pattern) == false) // Якщо текст не відповідає шаблону
- {
- MessageBox.Show("Введіть коректну адресу пошти."); // Повідомлення про помилку формату
- e.Cancel = true; // Заборона виходу з поля до виправлення помилки
- }
- }
- }
- private void OnlyLatin(object sender, KeyPressEventArgs e) // Обмеження вводу тільки латиницею
- {
- if (e.KeyChar > 127 || e.KeyChar == ' ') // Перевірка коду символу (ASCII) та заборона пробілів
- {
- e.Handled = true; // Скасування введення забороненого символу
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment