CMXX - Placeorder initial version

This commit is contained in:
“VeLiTi”
2025-02-13 11:23:15 +01:00
parent 2eaf83c3fe
commit 3424c9fadc
14 changed files with 446 additions and 377 deletions

View File

@@ -63,7 +63,7 @@ if (!empty($_POST)) {
$v = in_array(strtolower($v), ['true', 'false']) ? strtolower($v) : '\'' . $v . '\'';
$contents = preg_replace('/define\(\'' . $k . '\'\, ?(.*?)\)/s', 'define(\'' . $k . '\',' . $v . ')', $contents);
}
file_put_contents('../config.php', $contents);
file_put_contents('../custom/settings/config.php', $contents);
header('Location: index.php?page=settings&success_msg=1');
exit;
}

View File

@@ -145,7 +145,7 @@ $view = '
<td class="img">';
if (!empty($product['meta']['img'])){
$view .= ' <a href="'.url('index.php?page=product&id=' . $product['id']).'">
<img src="'.$img_url.$product['meta']['img'].'" width="50" height="50" alt="'.$product['meta']['name'].'">
<img src="'.img_url.$product['meta']['img'].'" width="50" height="50" alt="'.$product['meta']['name'].'">
</a>';
}
$view .= '</td>

View File

@@ -29,9 +29,9 @@ $weighttotal = 0;
$checkout_input = [
"selected_country" => isset($_POST['address_country']) ? $_POST['address_country'] : $account['address_country'],
"selected_shipment_method" => isset($_POST['shipping_method']) ? $_POST['shipping_method'] : null,
"selected_shipment_method" => isset($_POST['shipping_method']) ? $_POST['shipping_method'] : '',
"business_type" => 'b2c',
"discount_code" => isset($_SESSION['discount']) ? $_SESSION['discount'] : null
"discount_code" => isset($_SESSION['discount']) ? $_SESSION['discount'] : ''
];
$selected_shipping_method_name = '';
@@ -39,9 +39,9 @@ $shipping_methods_available = [];
// Error array, output errors on the form
$errors = [];
// ---------------------------------------
// ---------------------------------------
// ---------------------------------------
// ---------------------------------------------
// End defaults --------------------------------
// ---------------------------------------------
// Redirect the user if the shopping cart is empty
if (empty($_SESSION['cart'])) {
@@ -56,16 +56,17 @@ if (isset($_SESSION['account_loggedin'])) {
// Fetch the account from the database and return the result as an Array
$account = $stmt->fetch(PDO::FETCH_ASSOC);
}
// Update discount code
if (isset($_POST['discount_code']) && !empty($_POST['discount_code'])) {
$_SESSION['discount'] = $_POST['discount_code'];
} else if (isset($_POST['discount_code']) && empty($_POST['discount_code']) && isset($_SESSION['discount'])) {
unset($_SESSION['discount']);
}
//-------------------------------
// If there are products in cart handle the checkout
//-------------------------------
if ($products_in_cart) {
//Calculate shopping_cart
@@ -103,7 +104,6 @@ if ($products_in_cart) {
//-------------------------------
//Place order
//-------------------------------
// Make sure when the user submits the form all data was submitted and shopping cart is not empty
if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['address_street'], $_POST['address_city'], $_POST['address_state'], $_POST['address_zip'], $_POST['address_country'], $_POST['address_phone'], $_SESSION['cart']) && !isset($_POST['update'])) {
$account_id = null;
@@ -146,19 +146,28 @@ if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['a
}
if (!$errors && $products_in_cart) {
//Process checkout
//Calculate shopping_cart
$payload = json_encode(array("cart" => $products_in_cart, "checkout_input" => $checkout_input, "customer_details" => $account), JSON_UNESCAPED_UNICODE);
$place_order = ioAPIv2('/v2/placeorder/',$payload,$clientsecret);
$place_order = json_decode($products_in_cart,true);
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Process checkout => add payment_method to checkout_input array
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$checkout_input['payment_method'] = $_POST['method'];
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Calculate shopping_cart based on session
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
$payload = json_encode(array("cart" => $_SESSION['cart'], "checkout_input" => $checkout_input, "customer_details" => $account), JSON_UNESCAPED_UNICODE);
$place_order = ioAPIv2('/v2/placeorder/',$payload,$clientsecret);
$place_order = json_decode($place_order,true);
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//Check if transaction is succesfull and send order confirmation to customer
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if ($place_order['error'] == '' && $place_order['id'] != ''){
//SEND CONFIRMATION TO CUSTOMER
send_order_details_email(
$account['email'],
$products_in_cart,
$place_order['products_checked-out'],
$account['first_name'],
$account['last_name'],
$account['address_street'],
@@ -173,15 +182,7 @@ if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['a
$place_order['payment_amount'],
$place_order['transaction_id']
);
}
//Pay on delivery = 2
if (pay_on_delivery_enabled && $place_order['payment_method'] == 2){
//header('Location: ' . url('index.php?page=placeorder'));
//exit;
}
/*
//Disable giftcard
if (isset($_SESSION['discount'])){
if (preg_match("/[#][0-9]/", $_SESSION['discount']) == 1){
@@ -197,87 +198,22 @@ if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['a
$_SESSION['account_id'] = $account_id;
$_SESSION['account_role'] = $account ? $account['role'] : 'Member';
}
// Send order details to the specified email address
send_order_details_email(
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
$products_in_cart,
$_POST['first_name'],
$_POST['last_name'],
$_POST['address_street'],
$_POST['address_city'],
$_POST['address_state'],
$_POST['address_zip'],
$_POST['address_country'],
$subtotal,
$discounttotal,
$shippingtotal,
$taxtotal,
$payment_amount,
$order_id
);
header('Location: ' . url('index.php?page=placeorder'));
exit;
*/
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Mollie ++++++++++++++++++++++++++++++++++++++++++++++++++++
//Pay on delivery = 2
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (mollie_enabled && $_POST['method'] == 'mollie') {
// Process Normal Checkout
// Generate unique transaction ID
$transaction_id = strtoupper(uniqid('SC') . substr(md5(mt_rand()), 0, 5));
// Insert transaction into database
$stmt = $pdo->prepare('INSERT INTO transactions (txn_id, payment_amount, payment_status, created, payer_email, first_name, last_name, address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, shipping_method, shipping_amount, discount_code, address_phone, tax_amount) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
$stmt->execute([
$transaction_id,
$payment_amount,
default_payment_status,
date('Y-m-d H:i:s'),
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
$_POST['first_name'],
$_POST['last_name'],
$_POST['address_street'],
$_POST['address_city'],
$_POST['address_state'],
$_POST['address_zip'],
$_POST['address_country'],
$account_id,
'Debit/Credit',
$selected_shipping_method_name,
$shippingtotal,
isset($_SESSION['discount']) ? $_SESSION['discount'] : '',
$_POST['address_phone'],
$taxtotal
]);
// Get order ID
$order_id = $pdo->lastInsertId();
// Iterate products and deduct quantities
foreach ($products_in_cart as $product) {
// For every product in the shopping cart insert a new transaction into our database
$stmt = $pdo->prepare('INSERT INTO transactions_items (txn_id, item_id, item_price, item_quantity, item_options) VALUES (?,?,?,?,?)');
$stmt->execute([ $transaction_id, $product['id'], $product['final_price'], $product['quantity'], $product['options'] ]);
// Update product quantity in the products table
$stmt = $pdo->prepare('UPDATE products SET quantity = quantity - ? WHERE quantity > 0 AND id = ?');
$stmt->execute([ $product['quantity'], $product['id'] ]);
// Deduct option quantities
if ($product['options']) {
$options = explode(',', $product['options']);
foreach ($options as $opt) {
$option_name = explode('-', $opt)[0];
$option_value = explode('-', $opt)[1];
$stmt = $pdo->prepare('UPDATE products_options SET quantity = quantity - ? WHERE quantity > 0 AND title = ? AND (name = ? OR name = "")');
$stmt->execute([ $product['quantity'], $option_name, $option_value ]);
}
}
}
// Authenticate the user
if ($account_id != null) {
// Log the user in with the details provided
session_regenerate_id();
$_SESSION['account_loggedin'] = TRUE;
$_SESSION['account_id'] = $account_id;
$_SESSION['account_role'] = $account ? $account['role'] : 'Member';
}
if (pay_on_delivery_enabled && $place_order['payment_method'] == 2){
header('Location: ' . url('index.php?page=placeorder'));
exit;
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Mollie = 0 ++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (mollie_enabled && $_POST['method'] == 0) {
try {
/*
@@ -291,8 +227,8 @@ if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['a
* Generate a unique order id for this example. It is important to include this unique attribute
* in the redirectUrl (below) so a proper return page can be shown to the customer.
*/
$orderId = $transaction_id;
$value = number_format(($subtotal-$discounttotal)+$shippingtotal,2,'.','');
$orderId = $place_order['transaction_id'];
$value = number_format($place_order['payment_amount'],2,'.','');
/*
* Determine the url parts to these example files.
@@ -333,25 +269,6 @@ if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['a
* This request should always be a GET, thus we enforce 303 http response code
*/
// Send order details to the specified email address
send_order_details_email(
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
$products_in_cart,
$_POST['first_name'],
$_POST['last_name'],
$_POST['address_street'],
$_POST['address_city'],
$_POST['address_state'],
$_POST['address_zip'],
$_POST['address_country'],
$subtotal,
$discounttotal,
$shippingtotal,
$taxtotal,
$payment_amount,
$order_id
);
// Send customer to checkout
header("Location: " . $payment->getCheckoutUrl(), true, 303);
@@ -362,89 +279,36 @@ if (isset($_POST['method'], $_POST['first_name'], $_POST['last_name'], $_POST['a
}
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// PayPal Payment + +++++++++++++++++++++++++++++++++++++++++
// PayPal Payment = 1 +++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (paypal_enabled && $_POST['method'] == 'paypal') {
// Process Normal Checkout first then do PayPal related
// Generate unique transaction ID
$transaction_id = strtoupper(uniqid('SC') . substr(md5(mt_rand()), 0, 5));
// Insert transaction into database
$stmt = $pdo->prepare('INSERT INTO transactions (txn_id, payment_amount, payment_status, created, payer_email, first_name, last_name, address_street, address_city, address_state, address_zip, address_country, account_id, payment_method, shipping_method, shipping_amount, discount_code, address_phone, tax_amount) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)');
$stmt->execute([
$transaction_id,
$payment_amount,
default_payment_status,
date('Y-m-d H:i:s'),
isset($account['email']) && !empty($account['email']) ? $account['email'] : $_POST['email'],
$_POST['first_name'],
$_POST['last_name'],
$_POST['address_street'],
$_POST['address_city'],
$_POST['address_state'],
$_POST['address_zip'],
$_POST['address_country'],
$account_id,
'paypal',
$selected_shipping_method_name,
$shippingtotal,
isset($_SESSION['discount']) ? $_SESSION['discount'] : '',
$_POST['address_phone'],
$taxtotal
]);
// Get order ID
$order_id = $pdo->lastInsertId();
// Iterate products and deduct quantities
foreach ($products_in_cart as $product) {
// For every product in the shopping cart insert a new transaction into our database
$stmt = $pdo->prepare('INSERT INTO transactions_items (txn_id, item_id, item_price, item_quantity, item_options) VALUES (?,?,?,?,?)');
$stmt->execute([ $transaction_id, $product['id'], $product['final_price'], $product['quantity'], $product['options'] ]);
// Update product quantity in the products table
$stmt = $pdo->prepare('UPDATE products SET quantity = quantity - ? WHERE quantity > 0 AND id = ?');
$stmt->execute([ $product['quantity'], $product['id'] ]);
// Deduct option quantities
if ($product['options']) {
$options = explode(',', $product['options']);
foreach ($options as $opt) {
$option_name = explode('-', $opt)[0];
$option_value = explode('-', $opt)[1];
$stmt = $pdo->prepare('UPDATE products_options SET quantity = quantity - ? WHERE quantity > 0 AND title = ? AND (name = ? OR name = "")');
$stmt->execute([ $product['quantity'], $option_name, $option_value ]);
}
}
}
if ($account_id != null) {
// Log the user in with the details provided
session_regenerate_id();
$_SESSION['account_loggedin'] = TRUE;
$_SESSION['account_id'] = $account_id;
$_SESSION['account_role'] = $account ? $account['role'] : 'Member';
}
//Process Payment
require_once __DIR__."/lib/paypal/paypal.php";
$base = PAYPAL_URL;
$id = PAYPAL_CLIENT_ID;
$secret = PAYPAL_CLIENT_SECRET;
$base = PAYPAL_URL;
$id = PAYPAL_CLIENT_ID;
$secret = PAYPAL_CLIENT_SECRET;
//init input
$order = $transaction_id;
$price = $payment_amount;
$currency = "EUR";
//init input
$order = $place_order['transaction_id'];
$price = number_format($place_order['payment_amount'],2,'.','');
$currency = "EUR";
//make payment
$paypal = new paypalCurl();
$paypal->init($id,$secret,$base);
$result = $paypal->makePaymentURL($order,$price,$currency);
//make payment
$paypal = new paypalCurl();
$paypal->init($id,$secret,$base);
$result = $paypal->makePaymentURL($order,$price,$currency);
if ($result->status === true) {
header("location:". $result->url);
die;
}
else { //raise error
echo $result->msg;
die;
}
if ($result->status === true) {
header("location:". $result->url);
die;
}
else { //raise error
echo $result->msg;
die;
}
}
}
@@ -563,7 +427,7 @@ $view .= ' </select>
foreach($products_in_cart['cart_details']['products'] as $product){
$view .= ' <tr>
<td><img src="'.$img_url.$product['meta']['img'].'" width="35" height="35" alt="'.$product['meta']['name'].'"></td>
<td><img src="'.img_url.$product['meta']['img'].'" width="35" height="35" alt="'.$product['meta']['name'].'"></td>
<td>'.$product['quantity'].' x '.$product['meta']['name'].'</td>
<td class="price">'.currency_code.''.number_format($product['options_price'] * $product['quantity'],2).'</td>
</tr>';

View File

@@ -1586,7 +1586,7 @@ a.link-button {
}
.breadcrum a{
text-decoration: none;
color: #555555;
color: #4a90e2;
cursor: pointer;
font-family: inherit;
font-size: 0.8em;
@@ -1832,6 +1832,12 @@ input.banner_deny:hover {
.filtersection {
display: flex;
margin: 0 auto;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
background: white;
border-radius: 12px;
margin-bottom: 50px;
padding: 10px;
width: 95%;
}
/* Filter Section */
@@ -1871,3 +1877,132 @@ input.banner_deny:hover {
border-bottom: 1px solid #e0e0e0;
}
}
.news-section {
padding: 80px 20px;
background-color: #f8f8f8;
}
.news-container {
max-width: 1200px;
margin: 0 auto;
}
.news-header {
text-align: center;
margin-bottom: 50px;
}
.news-header h2 {
font-size: 2rem;
margin-bottom: 15px;
font-family: 'gerb', sans-serif;
}
.news-header p {
color: #666;
font-size: 1.1rem;
}
.news-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 30px;
margin-bottom: 50px;
}
.news-card {
background: white;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
transition: box-shadow 0.3s ease;
}
.news-card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.news-card-content {
padding: 20px;
}
.news-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.news-date {
color: #666;
font-size: 0.9rem;
}
.news-tag {
background: #e6f0ff;
color: #0066cc;
padding: 4px 12px;
border-radius: 15px;
font-size: 0.8rem;
}
.news-title {
font-size: 1.25rem;
margin-bottom: 15px;
color: #333;
font-weight: 600;
}
.news-preview {
color: #666;
margin-bottom: 20px;
line-height: 1.5;
}
.read-more {
color: #0066cc;
text-decoration: none;
display: inline-flex;
align-items: center;
font-weight: 500;
}
.read-more:hover {
color: #0052a3;
}
.read-more::after {
content: '>';
margin-left: 5px;
}
.view-all-container {
text-align: center;
}
.view-all-btn {
background: #0066cc;
color: white;
padding: 12px 24px;
border-radius: 4px;
text-decoration: none;
display: inline-block;
transition: background-color 0.3s ease;
}
.view-all-btn:hover {
background: #0052a3;
}
@media (max-width: 1024px) {
.news-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 768px) {
.news-grid {
grid-template-columns: 1fr;
}
}

View File

@@ -407,6 +407,12 @@ main .recentlyadded .products .product:hover .name, main .products .products-wra
main > .product {
display: flex;
padding: 40px 0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
background: white;
border-radius: 12px;
margin-bottom: 50px;
padding: 10px;
width: 95%;
}
main > .product h1 {
@@ -523,6 +529,15 @@ main > .product form .btn {
margin-top: 10px;
width: 400px;
text-transform: uppercase;
padding: 16px;
background: #4a90e2;
color: white;
border: none;
border-radius: 8px;
font-size: 1.1rem;
font-weight: 500;
cursor: pointer;
transition: background-color 0.2s;
}
main > .products h1 {

View File

@@ -250,6 +250,7 @@ function template_footer() {
echo <<<EOT
</main>
<footer>
<div class="container neutral-footer-section-1">
<div class="container neutral-footer-three-columns">
<div class="container description-logos-footer">

View File

@@ -38,13 +38,13 @@
</tr>
</thead>
<tbody>
<?php foreach($products_in_cart['cart_details']['products'] as $product): ?>
<?php foreach($products['products'] as $product): ?>
<tr>
<td><?=$product['meta']['name']?></td>
<td><?=$product['options']?></td>
<td><?=implode(", ", $product['options'])?></td>
<td><?=$product['quantity']?></td>
<td><?=currency_code?><?=number_format($product['option_price'],2)?></td>
<td style="text-align:right;"><?=number_format($product['option_price'] * $product['quantity'],2)?></td>
<td><?=currency_code?><?=number_format($product['options_price'],2)?></td>
<td style="text-align:right;"><?=number_format($product['options_price'] * $product['quantity'],2)?></td>
</tr>
<?php endforeach; ?>
<tr>

View File

@@ -39,13 +39,13 @@
</tr>
</thead>
<tbody>
<?php foreach($products_in_cart['cart_details']['products'] as $product): ?>
<?php foreach($products['products'] as $product): ?>
<tr>
<td><?=$product['meta']['name']?></td>
<td><?=$product['options']?></td>
<td><?=implode(", ", $product['options'])?></td>
<td><?=$product['quantity']?></td>
<td><?=currency_code?><?=number_format($product['option_price'],2)?></td>
<td style="text-align:right;"><?=number_format($product['option_price'] * $product['quantity'],2)?></td>
<td><?=currency_code?><?=number_format($product['options_price'],2)?></td>
<td style="text-align:right;"><?=number_format($product['options_price'] * $product['quantity'],2)?></td>
</tr>
<?php endforeach; ?>
<tr>

View File

@@ -133,18 +133,18 @@ define('footer_email','');
// The from email that will appear on the customer's order details email
define('mail_from','Name');
// Send mail to the customers, etc?
define('mail_enabled',false);
define('mail_enabled',true);
// Your email
define('email','');
define('email','info@gewoonlekkerspaans.nl');
// Receive email notifications?
define('email_notifications',false);
// Rewrite URL?
define('rewrite_url',true);
//Additional phpmailer-settings
define('email_host_name','');
define('email_reply_to','');
define('email_outgoing_pw','');
define('email_outgoing_port','587');
define('email_host_name','gewoonlekkerspaans.nl');
define('email_reply_to','info@gewoonlekkerspaans.nl');
define('email_outgoing_pw','o7f4t3E*5');
define('email_outgoing_port','465');
define('email_outgoing_security','ssl');
/* Database */
@@ -158,20 +158,20 @@ define('db_pass','4~gv71bM6');
define('db_name','shoppingcart_advanced'); //morvalwatches
// API BASE URL
define('api_url','https://dev.veliti.nl/api.php'); //morvalwatches
define('img_url',substr(api_url, 0, -8));
/* Payment options */
//Pay on Delivery
define('pay_on_delivery_enabled',false);
define('pay_on_delivery_default',false);
define('pay_on_delivery_enabled',true);
define('pay_on_delivery_default',true);
// Mollie
define('mollie_enabled',false);
define('mollie_default',false);
define('mollie_api_key','');
// Accept payments with PayPal?
define('paypal_enabled',true);
define('paypal_default',true);
define('paypal_enabled',false);
define('paypal_default',false);
define('PAYPAL_URL','');
define('PAYPAL_WEBHOOK','');
define('PAYPAL_CLIENT_ID','');

View File

@@ -31,6 +31,7 @@ $dompdf = new Dompdf($options);
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require dirname(__FILE__).'/lib/mail/PHPMailer.php';
require dirname(__FILE__).'/lib/mail/SMTP.php';
@@ -42,11 +43,13 @@ require dirname(__FILE__).'/lib/mail/Exception.php';
function send_mail_by_PHPMailer($to, $subject, $message, $attachment, $attachment_name){
// SEND MAIL by PHP MAILER
$mail = new PHPMailer();
$mail = new PHPMailer(true);
$mail->isSMTP(); // Use SMTP
$mail->CharSet = 'UTF-8';
//$mail->isSMTP(); // Use SMTP protocol
$mail->Host = email_host_name; // Specify SMTP server
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Use TLS encryption
$mail->SMTPAuth = true; // Auth. SMTP
//$mail->SMTPDebug = 3; // To view debug output
$mail->Username = email; // Mail who send by PHPMailer
$mail->Password = email_outgoing_pw; // your pass mail box
$mail->SMTPSecure = email_outgoing_security; // Accept SSL
@@ -63,10 +66,9 @@ function send_mail_by_PHPMailer($to, $subject, $message, $attachment, $attachmen
// SEND
if( !$mail->send() ){
// render error if it is
$tab = array('error' => 'Mailer Error: '.$mail->ErrorInfo );
echo json_encode($tab);
debuglog(json_encode($tab));
exit;
}
else{
@@ -138,7 +140,6 @@ function send_order_details_email($email, $products, $first_name, $last_name, $a
// Send payment notification to webmaster
$address_name = htmlspecialchars($first_name ?? '', ENT_QUOTES).' '.htmlspecialchars($last_name ?? '', ENT_QUOTES);
if (email_notifications) {
$subject = $subject_order_notification;
$headers = 'From: ' . mail_from . "\r\n" . 'Reply-To: ' . $email . "\r\n" . 'Return-Path: ' . mail_from . "\r\n" . 'X-Mailer: PHP/' . phpversion() . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-Type: text/html; charset=UTF-8' . "\r\n";
ob_start();
@@ -664,113 +665,105 @@ function getPictureID($pdo,$id,$config){
//++++++++++++++++++++++++++++++++++++++++
//HomePage Products
//++++++++++++++++++++++++++++++++++++++++
function highlightedProducts($pdo,$categoryID,$range){
function highlightedProducts($clientsecret,$categoryID,$range){
include './custom/translations/translations_'.strtoupper(language_code).'.php';
$stmt = $pdo->prepare('SELECT p.*, (SELECT m.full_path FROM products_media pm JOIN media m ON m.id = pm.media_id WHERE pm.product_id = p.id ORDER BY pm.position ASC LIMIT 1) AS img FROM products p JOIN products_categories pc ON pc.category_id = :category_id AND pc.product_id = p.id JOIN categories c ON c.id = pc.category_id WHERE p.status = 1');
$stmt->bindValue(':category_id', $categoryID, PDO::PARAM_INT);
$stmt->execute();
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
//GET CATALOG DATA
$products = ioAPIv2('/v2/catalog/category='.$categoryID,'',$clientsecret);
$products = json_decode($products,true);
$view = '
<h2>'.$range.'<span class="limited">Limited edition</span></h2>
<div class="products">';
foreach($products as $product){
foreach ($products as $product){
// Ensure product price is a numeric value
$product_price = isset($product['price']) && $product['price'] > 0 ? floatval($product['price']) : 0.00;
//SHOW LARGE PICTURE
$view .= '
<div class="product">';
if (empty($product['product_config'])){
$view .= '<a href="'.url('index.php?page=product&id=' . ($product['url_slug'] ? ($product['url_slug'] ) : $product['id'])).'" id="'.$product['id'].'A" class="product">';
}
else{//ADD related optionID when configuration is found
$option_id = getPictureID($pdo,$product['id'],$product['product_config']);
<div class="product">
<a href="'.url('index.php?page=product&rowID=' . ($product['url_slug'] ? ($product['url_slug'] ) : $product['rowID'])).'" id="'.$product['rowID'].'A" class="product">
<img src="'.img_url.$product['full_path'].'" id="'.$product['rowID'].'" width="200" height="" alt="'.(${$product['productname']} ?? $product['productname']).'">
</a>';
$view .= '<a href="'.url('index.php?page=product&id=' . ($product['url_slug'] ? ($product['url_slug'].'/'.$option_id ) : $product['id'])).'" id="'.$product['id'].'A" class="product">';
}
//CHECK IF CONFIGURATION SETTING IS FOUND AND NOT EMPTY => USE GROUP TO DISPLAY IMAGES
if (isset($product['configurations']) && isset($product['config_setting']) && $product['config_setting'] != ''){
if (!empty($product['img']) && file_exists($product['img'])){
if (empty($product['product_config'])){
$view .= '
<img src="'.$product['img'].'" width="" height="250" alt="'.$product['name'].'">';
$view .= '
</a>
<!-- Show small image below main image in case of not configured -->
<div class="" style="display:flex;justify-content: center">
<div>
<img class="img_config" src="'.base_url.$product['img'].'"/>
</div>
</div>';
} else {
$view .= '<img src="'.base_url.$product['img'].'" id="'.$product['id'].'" width="" height="250" alt="'.$product['name'].'">
</a>';
if (show_options_carrousel){
//GET THE CONFIG_SETTING GROuP AND DISPLAY
foreach ($product['configurations'] as $config){
//MATCH ASSIGNMENT WITH CONFIG SETTING
if($config['assignment'] == $product['config_setting']){
$view .= '<div class="" style="display:flex;justify-content: center">';
$option_profile = json_decode($product['product_config']);
foreach ($option_profile as $option){
//get all media
$stmt = $pdo->query('SELECT id, full_path FROM media');
$stmt->execute();
$media = $stmt->fetchAll(PDO::FETCH_ASSOC);
//GET ALL RELATED ATTRIBUTES
foreach ($config['attributes'] as $attribute){
$option_id = $attribute['attribute_id']; // ID of the LARGE IMAGE
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
foreach ($media as $media_item){
if ($media_item['id'] == $option->IMG_small_id){
$IMG_small_id = $media_item['full_path'];
}
if ($media_item['id'] == $option->IMG_large_id){
$IMG_large_id = $media_item['full_path'];
}
}
$option_id = ($option->option_id != '') ? $option->option_id : '';
// Ensure attribute price is a numeric value
$attribute_price = isset($attribute['price']) ? floatval($attribute['price']) : 0.00;
$option_price = isset($attribute['price'])
// If price modifier is 1, add prices; otherwise, subtract
? ((isset($attribute['price_modifier']) && $attribute['price_modifier'] == 1) ? currency_code . number_format(floatval($product_price + $attribute_price), 2) : currency_code . number_format(floatval($product_price - $attribute_price), 2))
// If product price is not zero, format it
: (($product_price != 0.00) ? currency_code . number_format(floatval($product_price), 2) : '');
$view .= '
<div>
<img class="img_config" src="'.url($IMG_small_id).'" id="'.$option->IMG_small_id.'" onclick="update(\''.$product['id'].'\',\''.url($IMG_large_id).'\',\''.url('index.php?page=product&id=' . ($product['url_slug'] ? $product['url_slug'].'/'.$option_id : $product['id'].'/'.$option_id )).'\')" />
</div>
';
}
$view .= '</div>';
<div>
<img class="img_config" src="'.$IMG_small_id.'" id="'.$attribute['item_media'].'" onclick="update(\''.$product['rowID'].'\',\''.$IMG_large_id.'\',\''.url('index.php?page=product&rowID=' . ($product['url_slug'] ? $product['url_slug'].'/'.$option_id : $product['rowID'].'/'.$option_id )).'\',\''.$option_price.'\')" />
</div>';
}
$view .= '</div>';
}
}
}
//Stock status
$stock_status = ($product['quantity'] != 0) ? $product_on_stock : $out_of_stock;
$style = ($stock_status == $product_on_stock) ? 'style="background-color: green;"' : 'style="background-color:gray;font-weight: lighter;"';
$view .=' <span class="stock">
<p '.$style.'> '.$stock_status.' </p>
</span>';
//Remove first characters from Productname
if (product_truncate_text != ''){
$productname = str_replace(product_truncate_text,'',$product['name']);
$productname = (product_truncate !=0)? substr($productname,product_truncate):$productname;
} else {
$productname = $product['name'];
//SHOW SMALL IMAGE
$view .= '<div class="" style="display:flex;justify-content: center">
<div>
<img class="img_config" src="'.img_url.$product['full_path'].'"/>
</div>
</div>';
}
//ADD related optionID when configuration is found
if (empty($product['product_config'])){
$option_id = '';
}else {
$option_id = '/'.getPictureID($pdo,$product['id'],$product['product_config']);
//Stock status
$stock_status = (isset($product['quantity']) && $product['quantity'] != 0) ? $product_on_stock : $out_of_stock;
$style = ($stock_status == $product_on_stock) ? 'style="background-color: green;"' : 'style="background-color:gray;font-weight: lighter;"';
$view .= '
<span class="stock">
<p '.$style.'> '.$stock_status.'</p>
</span>';
if (free_shipment_indicator){
$shipment = freeShipment($product_price,'span');
$view .= $shipment;
}
$view .= '
<a href="'.url('index.php?page=product&id=' . ($product['url_slug'] ? $product['url_slug'].$option_id : $product['id'])).'" id="'.$product['id'].'B" class="product">
<span class="productname">'.$productname.'</span>
<span class="productprice">'.currency_code.number_format($product['price'],2);
if ($product['rrp'] > 0) {
$view .= '<span class="productrrp">'.currency_code.number_format($product['rrp'],2).'</span>';
}
$view .= '
</span>
</a>
</div>';
$option_id ='';
$view .='<a href="'.url('index.php?page=product&rowID=' . ($product['url_slug'] ? $product['url_slug'].$option_id : $product['rowID'])).'" id="'.$product['rowID'].'B" class="product">
<span class="name">'.(${$product['productname']} ?? $product['productname']).'</span>';
if (isset($product_price)){
$view .= '<span class="price" id="'.$product['rowID'].'C">'.(($product_price != 0.00) ? currency_code.number_format($product_price,2) : '').'';
if (isset($product['rrp']) && $product['rrp'] > 0){
$view .= '<span class="rrp">'.currency_code.number_format($product['rrp'],2).'</span>';
}
$view .= '</span>';
}
$view .= '
</a>
</div>';
}
$view .= '</div>';

140
home.php
View File

@@ -8,50 +8,110 @@ $recently_added_products = $stmt->fetchAll(PDO::FETCH_ASSOC);
//LINK to products page:
$products_link = url(link_to_collection);
?>
<?=template_header_top($home_text)?>
<div class="featured" style="background-image:url(<?=featured_image?>);background-position: center center;">
<?=template_menu()?>
<h2><?=$h2_brand_name_1?></h2>
<p><?=$h2_brand_name_2?></p>
<a class="link-button action-btn" role="button" href="<?=$products_link?>" title="<?=$h2_brand_visit?>"><?=$h2_brand_visit?></a>
template_header_top($home_text);
$view = '
<div class="featured" style="background-image:url('.featured_image.');background-position: center center;">
'.template_menu().'
<h2>'.$h2_brand_name_1.'</h2>
<p>'.$h2_brand_name_2.'</p>
<a class="link-button action-btn" role="button" href="'.$products_link.'" title="'.$h2_brand_visit.'">'.$h2_brand_visit.'</a>
</div>
<div class="container highlight-section">
<h2 class="title-message" href="<?=$products_link?>">
<?=$h2_brand_wow?>
<h2 class="title-message" href="'.$products_link.'">
'.$h2_brand_wow.'
</h2>
<p class="paragraph neutral-paragraph-text" style="font-size: 30px;">
</p>
</div>
<?php
//SHOW OFFER
if(show_offer_home_page){
</div>';
echo '
<div class="" style="text-align: center;">
//SHOW OFFER
if(show_offer_home_page){
$view .='
<div class="" style="text-align: center;">
<p class="p.paragraph.neutral-paragraph-text-1" style="font-family:\'gerb\';font-size: 15px;">'.show_offer_home_text.'</p>
</div>';
}
$view .='
<section class="news-section">
<div class="news-container">
<div class="news-header">
<h2>Latest News</h2>
<p>Stay updated with the latest from Morval Watches</p>
</div>
';
}
?>
<section class="container neutral-cover-section-1" style="background-image:url(custom/assets/morval_checkout.jpg);background-size: cover;background-repeat: no-repeat;background-position: 50% 50%;">
<div class="recentlyadded">
<?php
$view = highlightedProducts($pdo,category_id_highlighted_products_1,highlighted_product_range_1);
echo $view;
?>
</div>
</section>
<div class="news-grid">
<article class="news-card">
<div class="news-card-content">
<div class="news-meta">
<span class="news-date">February 10, 2025</span>
<span class="news-tag">New Release</span>
</div>
<h3 class="news-title">New Thomas II Collection Released</h3>
<p class="news-preview">Discover our latest Thomas II collection featuring premium Swiss movements and unique colorways.</p>
<a href="#" class="read-more">Read More</a>
</div>
</article>
<article class="news-card">
<div class="news-card-content">
<div class="news-meta">
<span class="news-date">February 5, 2025</span>
<span class="news-tag">Limited Edition</span>
</div>
<h3 class="news-title">Limited Edition Navy Blue Now Available</h3>
<p class="news-preview">Experience the depth of our signature Navy Blue finish, now available in a special limited edition run.</p>
<a href="#" class="read-more">Read More</a>
</div>
</article>
<article class="news-card">
<div class="news-card-content">
<div class="news-meta">
<span class="news-date">January 28, 2025</span>
<span class="news-tag">Press</span>
</div>
<h3 class="news-title">Morval Featured in Watch Magazine</h3>
<p class="news-preview">Our commitment to Dutch craftsmanship and Swiss quality gains international recognition.</p>
<a href="#" class="read-more">Read More</a>
</div>
</article>
</div>
<div class="view-all-container">
<a href="#" class="view-all-btn">View All News</a>
</div>
</div>
</section>';
//SHOW HIGHLIGHTS
if (category_id_highlighted_products_1){
$view .='
<section class="container neutral-cover-section-1" style="background-image:url(custom/assets/morval_checkout.jpg);background-size: cover;background-repeat: no-repeat;background-position: 50% 50%;">
<div class="recentlyadded">';
$view .= highlightedProducts($clientsecret,category_id_highlighted_products_1,($highlight_1 ?? 'highlight 1'));
$view .='
</div>
</section>';
}
if (category_id_highlighted_products_2){
$view .='
<section class="container neutral-cover-section-1">
<div class="recentlyadded">
<?php
$view = highlightedProducts($pdo,category_id_highlighted_products_2,highlighted_product_range_2);
echo $view;
?>
</div>
</section>
<div class="recentlyadded"> ';
$view .= highlightedProducts($clientsecret,category_id_highlighted_products_2, ($highlight_2 ?? 'highlight 2'));
$view .='
</div>
</section>';
}
$view .='
<section class="container neutral-features-section-4-1" style="background-image:url(custom/assets/picture2.jpg);background-size: cover;background-repeat: no-repeat;background-position: 50% 50%;">
<div class="container neutral-three-columns-1">
<div class="container neutral-feature-wrapper-1 neutral-left-align-items-1">
@@ -61,7 +121,7 @@ $products_link = url(link_to_collection);
<p class="paragraph neutral-paragraph-text-1">
Morval Watches are unique, robust, stylish and timeless timepieces that will last for generations!
</p>
<a class="link-text neutral-text-link-1" href="<?=$products_link?>">shop now &gt;</a>
<a class="link-text neutral-text-link-1" href="'.$products_link.'">shop now &gt;</a>
</div>
<div class="container neutral-feature-wrapper-1 neutral-left-align-items-1">
<div class="container container-feature-icon-wrapper-1"><span class="icon"></span>
@@ -70,7 +130,7 @@ $products_link = url(link_to_collection);
<p class="paragraph neutral-paragraph-text-1">
Morval watches meet the highest quality requirements and can compete with the well-known Swiss brands. The parts are supplied by renowned manufacturers from Europe and beyond. A Morval contains a Swiss-made caliber (STP) that is known for its reliable quality.
</p>
<a class="link-text neutral-text-link-1" href="<?=$products_link?>">shop now &gt;</a>
<a class="link-text neutral-text-link-1" href="'.$products_link.'">shop now &gt;</a>
</div>
<div class="container neutral-feature-wrapper-1 neutral-left-align-items-1">
<div class="container container-feature-icon-wrapper-1"><span class="icon"></span>
@@ -79,10 +139,14 @@ $products_link = url(link_to_collection);
<p class="paragraph neutral-paragraph-text-1">
Morval stands for an excellent price-quality ratio
</p>
<a class="link-text neutral-text-link-1" href="<?=$products_link?>">shop now &gt;</a>
<a class="link-text neutral-text-link-1" href="'.$products_link.'">shop now &gt;</a>
</div>
</div>
</section>
</div>
</div>';
<?=template_footer()?>
//OUTPUT
echo $view;
template_footer()
?>

View File

@@ -26,9 +26,6 @@ $responses = ioAPIv2('/v2/authorization', $data,'');
if (!empty($responses)){$responses = json_decode($responses,true);}else{$responses = '400';}
$clientsecret = $responses['token'];
//IMAGE URL
$img_url = substr(api_url, 0, -8);
// Connect to MySQL database
$pdo = pdo_connect_mysql();
// Output error variable

View File

@@ -36,7 +36,7 @@ if (isset($_GET['id'])) {
<meta property="og:title" content="' . (${$product['productname']} ?? $product['productname']) . '">
';
if (isset($product['full_path'])) {
$meta .= '<meta property="og:image" content="'.$img_url.$product['full_path'].'">';
$meta .= '<meta property="og:image" content="'.img_url.$product['full_path'].'">';
}
//GET RELATED MEDIA
@@ -119,7 +119,7 @@ $view .='
$altTitle = $attribute['alternative_media_title'] ?? $attribute['title'];
$view .='
<div class="product-img-large">
<img src="'.$img_url.$fullPath.'" id="'.$product['rowID'].'" alt="'.$altTitle.'">
<img src="'.img_url.$fullPath.'" id="'.$product['rowID'].'" alt="'.$altTitle.'">
</div>';
break 2; // Exit all loops once found
}
@@ -130,7 +130,7 @@ $view .='
} elseif (isset($product['full_path']) && $product['full_path'] != ''){
$view .='
<div class="product-img-large">
<img src="'.$img_url.$product['full_path'].'" id="'.$product['rowID'].'" alt="'.(${$product['productname']} ?? $product['productname']).'">
<img src="'.img_url.$product['full_path'].'" id="'.$product['rowID'].'" alt="'.(${$product['productname']} ?? $product['productname']).'">
</div>';
}
$view .='
@@ -139,7 +139,7 @@ $view .='
foreach ($product_media as $media){
$view .=' <div class="product-img-small '.($media['position']==1?' selected':'').'">
<img src="'.$img_url.$media['full_path'].'" width="150" height="150" alt="">
<img src="'.img_url.$media['full_path'].'" width="150" height="150" alt="">
</div>';
}
$view .='
@@ -202,11 +202,11 @@ $view .='<form id="product-form" action="" method="post">';
//ADD updateOption to change pictures when GROUP is IN configuration
if(isset($product['config_setting']) && $product['config_setting'] == $configuration['assignment']){
$IMG_large_id = $img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$onclick = 'onclick="updateOption(\''.$product['rowID'].'\',\''.$IMG_large_id.'\')"';
}
$IMG_small_id = $img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$output .= '
<label class="picture_select_label">
@@ -237,11 +237,11 @@ $view .='<form id="product-form" action="" method="post">';
//ADD updateOption to change pictures when GROUP is IN configuration
if(isset($product['config_setting']) && $product['config_setting'] == $configuration['assignment']){
$IMG_large_id = $img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$onclick = 'onclick="updateOption(\''.$product['rowID'].'\',\''.$IMG_large_id.'\')"';
}
$IMG_small_id = $img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$output .= '
<label class="picture_select_label">
@@ -276,11 +276,11 @@ $view .='<form id="product-form" action="" method="post">';
//ADD updateOption to change pictures when GROUP is IN configuration
if(isset($product['config_setting']) && $product['config_setting'] == $configuration['assignment']){
$IMG_large_id = $img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$onclick = 'onclick="updateOption(\''.$product['rowID'].'\',\''.$IMG_large_id.'\')"';
}
$IMG_small_id = $img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$output .= '
<option id="'.$attribute['attribute_id'].'" value="'.$attribute['attribute_id'].'" data-price="'.($attribute['price'] ?? 0).'" data-rrp="'.($attribute['rrp'] ?? 0).'" data-modifier="'.($attribute['price_modifier'] ?? '').'">'.(${$attribute['item_name']} ?? $attribute['item_name']).'</option>';

View File

@@ -140,7 +140,7 @@ $view .= '<div class="products-wrapper">';
$view .= '
<div class="product">
<a href="'.url('index.php?page=product&rowID=' . ($product['url_slug'] ? ($product['url_slug'] ) : $product['rowID'])).'" id="'.$product['rowID'].'A" class="product">
<img src="'.$img_url.$product['full_path'].'" id="'.$product['rowID'].'" width="200" height="" alt="'.(${$product['productname']} ?? $product['productname']).'">
<img src="'.img_url.$product['full_path'].'" id="'.$product['rowID'].'" width="200" height="" alt="'.(${$product['productname']} ?? $product['productname']).'">
</a>';
//CHECK IF CONFIGURATION SETTING IS FOUND AND NOT EMPTY => USE GROUP TO DISPLAY IMAGES
@@ -158,8 +158,8 @@ $view .= '<div class="products-wrapper">';
//GET ALL RELATED ATTRIBUTES
foreach ($config['attributes'] as $attribute){
$option_id = $attribute['attribute_id']; // ID of the LARGE IMAGE
$IMG_small_id = $img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$IMG_large_id = $img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
$IMG_small_id = img_url.$attribute['full_path']; //URL TO SMALL IMAGE
$IMG_large_id = img_url.$attribute['alternative_media_full_path']; //URL TO LARGE IMAGE
// Ensure attribute price is a numeric value
$attribute_price = isset($attribute['price']) ? floatval($attribute['price']) : 0.00;
@@ -185,7 +185,7 @@ $view .= '<div class="products-wrapper">';
//SHOW SMALL IMAGE
$view .= '<div class="" style="display:flex;justify-content: center">
<div>
<img class="img_config" src="'.$img_url.$product['full_path'].'"/>
<img class="img_config" src="'.img_url.$product['full_path'].'"/>
</div>
</div>';
}