diff --git a/config/db.php b/config/db.php
new file mode 100644
index 0000000..39e4664
--- /dev/null
+++ b/config/db.php
@@ -0,0 +1,20 @@
+ PDO::ERRMODE_EXCEPTION,
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
+];
+
+try {
+ $pdo = new PDO($dsn, $DB_USER, $DB_PASS, $options);
+} catch (PDOException $e) {
+ http_response_code(500);
+ echo 'Database connection failed.';
+ exit;
+}
diff --git a/contact_form/contact_form.php b/contact_form/contact_form.php
index 1245e89..29c153a 100644
--- a/contact_form/contact_form.php
+++ b/contact_form/contact_form.php
@@ -1,80 +1,104 @@
- 'Name', 'email' => 'Email', 'subject' => 'Subject', 'message' => 'Message'); // array variable name => Text to appear in the email. If you added or deleted a field in the contact form, edit this array.
-$okMessage = 'Contact form successfully submitted. Thank you, I will get back to you soon!';
-$errorMessage = 'There was an error while submitting the form. Please try again later';
-
-// let's do the sending
-
-if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])):
- //your site secret key
- $secret = '6LdqmCAUAAAAANONcPUkgVpTSGGqm60cabVMVaON';
- //get verify response data
-
- $c = curl_init('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
- curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
- $verifyResponse = curl_exec($c);
-
- $responseData = json_decode($verifyResponse);
- if($responseData->success):
-
- try
- {
- $emailText = nl2br("You have new message from Contact Form\n");
-
- foreach ($_POST as $key => $value) {
-
- if (isset($fields[$key])) {
- $emailText .= nl2br("$fields[$key]: $value\n");
- }
- }
-
- $headers = array('Content-Type: text/html; charset="UTF-8";',
- 'From: ' . $from,
- 'Reply-To: ' . $from,
- 'Return-Path: ' . $from,
- );
-
- mail($sendTo, $subject, $emailText, implode("\n", $headers));
-
- $responseArray = array('type' => 'success', 'message' => $okMessage);
- }
- catch (\Exception $e)
- {
- $responseArray = array('type' => 'danger', 'message' => $errorMessage);
- }
-
- if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
- $encoded = json_encode($responseArray);
-
- header('Content-Type: application/json');
-
- echo $encoded;
- }
- else {
- echo $responseArray['message'];
- }
-
- else:
- $errorMessage = 'Robot verification failed, please try again.';
- $responseArray = array('type' => 'danger', 'message' => $errorMessage);
- $encoded = json_encode($responseArray);
-
- header('Content-Type: application/json');
-
- echo $encoded;
- endif;
-else:
- $errorMessage = 'Please click on the reCAPTCHA box.';
- $responseArray = array('type' => 'danger', 'message' => $errorMessage);
- $encoded = json_encode($responseArray);
-
- header('Content-Type: application/json');
-
- echo $encoded;
-endif;
-
+prepare('SELECT email_to, email_from, recaptcha_secret FROM contact_meta WHERE profile_id = ? AND is_active = 1 LIMIT 1');
+$contactMetaStmt->execute([$profileId]);
+$contactMeta = $contactMetaStmt->fetch();
+
+$emailTo = $contactMeta['email_to'] ?? 'mgonzalez@linkedcorp.net';
+$emailFrom = $contactMeta['email_from'] ?? $emailTo;
+$recaptchaSecret = $contactMeta['recaptcha_secret'] ?? '';
+
+$subject = 'New message from contact form';
+$fields = array('name' => 'Name', 'email' => 'Email', 'subject' => 'Subject', 'message' => 'Message');
+$okMessage = 'Contact form successfully submitted. Thank you, I will get back to you soon!';
+$errorMessage = 'There was an error while submitting the form. Please try again later';
+
+function json_response($type, $message)
+{
+ $responseArray = array('type' => $type, 'message' => $message);
+ header('Content-Type: application/json');
+ echo json_encode($responseArray);
+ exit;
+}
+
+$name = trim($_POST['name'] ?? '');
+$email = trim($_POST['email'] ?? '');
+$userSubject = trim($_POST['subject'] ?? '');
+$message = trim($_POST['message'] ?? '');
+
+if ($name === '' || $email === '' || $userSubject === '' || $message === '') {
+ json_response('danger', 'All fields are required.');
+}
+
+if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ json_response('danger', 'Valid email is required.');
+}
+
+$insertStmt = $pdo->prepare('INSERT INTO contact_messages (profile_id, full_name, email, subject, message, send_status) VALUES (?, ?, ?, ?, ?, ?)');
+$insertStmt->execute([$profileId, $name, $email, $userSubject, $message, 'pending']);
+$messageId = (int) $pdo->lastInsertId();
+
+$sendStatus = 'failed';
+$sendError = null;
+$sentAt = null;
+
+if ($recaptchaSecret !== '') {
+ $recaptchaResponse = $_POST['g-recaptcha-response'] ?? '';
+ if ($recaptchaResponse === '') {
+ $sendError = 'recaptcha_missing';
+ $updateStmt = $pdo->prepare('UPDATE contact_messages SET send_status = ?, send_error = ? WHERE id = ?');
+ $updateStmt->execute([$sendStatus, $sendError, $messageId]);
+ json_response('danger', 'Please click on the reCAPTCHA box.');
+ }
+
+ $c = curl_init('https://www.google.com/recaptcha/api/siteverify?secret=' . $recaptchaSecret . '&response=' . $recaptchaResponse);
+ curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
+ $verifyResponse = curl_exec($c);
+ $responseData = json_decode($verifyResponse);
+ if (!$responseData || empty($responseData->success)) {
+ $sendError = 'recaptcha_failed';
+ $updateStmt = $pdo->prepare('UPDATE contact_messages SET send_status = ?, send_error = ? WHERE id = ?');
+ $updateStmt->execute([$sendStatus, $sendError, $messageId]);
+ json_response('danger', 'Robot verification failed, please try again.');
+ }
+}
+
+try {
+ $emailText = nl2br("You have new message from Contact Form\n");
+
+ foreach (['name' => $name, 'email' => $email, 'subject' => $userSubject, 'message' => $message] as $key => $value) {
+ if (isset($fields[$key])) {
+ $emailText .= nl2br($fields[$key] . ': ' . $value . "\n");
+ }
+ }
+
+ $headers = array(
+ 'Content-Type: text/html; charset="UTF-8"',
+ 'From: ' . $emailFrom,
+ 'Reply-To: ' . $email,
+ 'Return-Path: ' . $emailFrom,
+ );
+
+ $sent = mail($emailTo, $subject, $emailText, implode("\n", $headers));
+
+ if ($sent) {
+ $sendStatus = 'sent';
+ $sentAt = date('Y-m-d H:i:s');
+ } else {
+ $sendError = 'mail_failed';
+ }
+} catch (Exception $e) {
+ $sendError = $e->getMessage();
+}
+
+$updateStmt = $pdo->prepare('UPDATE contact_messages SET send_status = ?, send_error = ?, sent_at = ? WHERE id = ?');
+$updateStmt->execute([$sendStatus, $sendError, $sentAt, $messageId]);
+
+if ($sendStatus === 'sent') {
+ json_response('success', $okMessage);
+}
+
+json_response('danger', $errorMessage);
diff --git a/index.html b/index.html.bak
similarity index 100%
rename from index.html
rename to index.html.bak
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..d953095
--- /dev/null
+++ b/index.php
@@ -0,0 +1,809 @@
+prepare('SELECT * FROM profile WHERE id = ? AND is_active = 1 LIMIT 1');
+$profileStmt->execute([$profileId]);
+$profile = $profileStmt->fetch();
+
+$rolesStmt = $pdo->prepare('SELECT role_title FROM profile_roles WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$rolesStmt->execute([$profileId]);
+$roles = $rolesStmt->fetchAll();
+
+$menuItems = $pdo->query('SELECT label, anchor, icon_class FROM menu_items WHERE is_active = 1 ORDER BY sort_order, id')->fetchAll();
+
+$socialLinksStmt = $pdo->prepare('SELECT label, icon_class, url FROM social_links WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$socialLinksStmt->execute([$profileId]);
+$socialLinks = $socialLinksStmt->fetchAll();
+
+$aboutStmt = $pdo->prepare('SELECT description FROM about_me WHERE profile_id = ? AND is_active = 1 LIMIT 1');
+$aboutStmt->execute([$profileId]);
+$about = $aboutStmt->fetch();
+
+$personalInfoStmt = $pdo->prepare('SELECT label, value FROM personal_info_items WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$personalInfoStmt->execute([$profileId]);
+$personalInfo = $personalInfoStmt->fetchAll();
+
+$servicesStmt = $pdo->prepare('SELECT icon_class, title, description FROM services WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$servicesStmt->execute([$profileId]);
+$services = $servicesStmt->fetchAll();
+
+$testimonialsStmt = $pdo->prepare('SELECT author_name, company, photo_url, quote FROM testimonials WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$testimonialsStmt->execute([$profileId]);
+$testimonials = $testimonialsStmt->fetchAll();
+
+$clientsStmt = $pdo->prepare('SELECT name, logo_url, website_url FROM clients WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$clientsStmt->execute([$profileId]);
+$clients = $clientsStmt->fetchAll();
+
+$pricingPlansStmt = $pdo->prepare('SELECT id, name, price, billing_period, is_featured, button_label, button_url FROM pricing_plans WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$pricingPlansStmt->execute([$profileId]);
+$pricingPlans = $pricingPlansStmt->fetchAll();
+
+$pricingFeaturesStmt = $pdo->query('SELECT pricing_plan_id, feature_text FROM pricing_features WHERE is_active = 1 ORDER BY sort_order, id');
+$pricingFeaturesRaw = $pricingFeaturesStmt->fetchAll();
+$pricingFeatures = [];
+foreach ($pricingFeaturesRaw as $row) {
+ $pricingFeatures[(int) $row['pricing_plan_id']][] = $row['feature_text'];
+}
+
+$funFactsStmt = $pdo->prepare('SELECT icon_class, title, value FROM fun_facts WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$funFactsStmt->execute([$profileId]);
+$funFacts = $funFactsStmt->fetchAll();
+
+$educationStmt = $pdo->prepare('SELECT period_label, institution, degree_title, description FROM education WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$educationStmt->execute([$profileId]);
+$education = $educationStmt->fetchAll();
+
+$experienceStmt = $pdo->prepare('SELECT period_label, company, role_title, description FROM experience WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$experienceStmt->execute([$profileId]);
+$experience = $experienceStmt->fetchAll();
+
+$skillsStmt = $pdo->prepare('SELECT skill_type, name, proficiency FROM skills WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$skillsStmt->execute([$profileId]);
+$skillsRaw = $skillsStmt->fetchAll();
+$skills = ['design' => [], 'coding' => []];
+foreach ($skillsRaw as $row) {
+ $type = $row['skill_type'];
+ if (!isset($skills[$type])) {
+ $skills[$type] = [];
+ }
+ $skills[$type][] = $row;
+}
+
+$knowledgesStmt = $pdo->prepare('SELECT name FROM knowledges WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$knowledgesStmt->execute([$profileId]);
+$knowledges = $knowledgesStmt->fetchAll();
+
+$certificatesStmt = $pdo->prepare('SELECT title, membership_id, date_label, company, logo_url FROM certificates WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$certificatesStmt->execute([$profileId]);
+$certificates = $certificatesStmt->fetchAll();
+
+$portfolioCategories = $pdo->query('SELECT id, name, slug FROM portfolio_categories WHERE is_active = 1 ORDER BY sort_order, id')->fetchAll();
+
+$portfolioCategoryMap = [];
+foreach ($portfolioCategories as $cat) {
+ $portfolioCategoryMap[$cat['slug']] = $cat['name'];
+}
+
+$portfolioItemsStmt = $pdo->prepare('SELECT id, title, item_type, thumb_url, link_url, icon_class FROM portfolio_items WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$portfolioItemsStmt->execute([$profileId]);
+$portfolioItems = $portfolioItemsStmt->fetchAll();
+
+$portfolioItemCategoriesStmt = $pdo->query('SELECT pic.portfolio_item_id, pc.slug FROM portfolio_item_categories pic JOIN portfolio_categories pc ON pc.id = pic.portfolio_category_id WHERE pc.is_active = 1');
+$portfolioItemCategoriesRaw = $portfolioItemCategoriesStmt->fetchAll();
+$portfolioItemCategories = [];
+foreach ($portfolioItemCategoriesRaw as $row) {
+ $portfolioItemCategories[(int) $row['portfolio_item_id']][] = $row['slug'];
+}
+
+$blogPostsStmt = $pdo->prepare('SELECT bp.title, bp.slug, bp.cover_image_url, bp.published_date, bc.name AS category_name FROM blog_posts bp JOIN blog_categories bc ON bc.id = bp.category_id WHERE bp.profile_id = ? AND bp.is_active = 1 ORDER BY bp.published_date DESC, bp.id DESC');
+$blogPostsStmt->execute([$profileId]);
+$blogPosts = $blogPostsStmt->fetchAll();
+
+$contactInfoStmt = $pdo->prepare('SELECT label, value, icon_class FROM contact_info WHERE profile_id = ? AND is_active = 1 ORDER BY sort_order, id');
+$contactInfoStmt->execute([$profileId]);
+$contactInfo = $contactInfoStmt->fetchAll();
+
+$contactMetaStmt = $pdo->prepare('SELECT location_label, map_iframe_url, availability_label, recaptcha_site_key FROM contact_meta WHERE profile_id = ? AND is_active = 1 LIMIT 1');
+$contactMetaStmt->execute([$profileId]);
+$contactMeta = $contactMetaStmt->fetch();
+
+function e($value)
+{
+ return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
+}
+?>
+
+
+
+
+
+ BreezyCV - Resume / CV / vCard Template
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
About Me
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![<?php echo e($testimonial['author_name']); ?>](<?php echo e($testimonial['photo_url']); ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Resume
+
+
+
+
+
+
+
Education
+
+
+
+
+
+
+
+
Experience
+
+
+
+
+
+
+
+
+
+
+
Design Skills
+
+
+
+
+
+
+
+
+
+
Coding Skills
+
+
+
+
+
+
+
+
+
+
Knowledges
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
; ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Portfolio
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![<?php echo e($item['title']); ?>](<?php echo e($item['thumb_url']); ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Contact
+
+
+
+
+
+
+
+
+
+
+
+
+
+
How Can I Help You?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+