|
Server : Apache/2.4.18 (Ubuntu) System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 User : oppastar ( 1041) PHP Version : 7.0.33-0ubuntu0.16.04.15 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, Directory : /var/www/laciasmara.com/public_html/shop/application/controllers/ |
Upload File : |
<?php defined('BASEPATH') or exit('No direct script access allowed');
class Welcome extends Public_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('GoogleClient');
$this->load->library('VisitorTracking');
$this->load->model('comment_m');
$this->load->library(['session', 'form_validation']);
$this->load->helper('url');
$this->load->model('customer_m');
$this->load->helper('cart');
$this->load->model('Top_banner_m');
$this->load->model('Statistic_m');
$this->load->model('Carousel_banner_m');
$this->load->model('Category_m');
$this->load->model('Review_m');
$this->load->model('Brand_m');
$this->load->model('Footer_m');
if ($this->session->userdata('site_lang') == 'english') {
$this->lang->load('register_login', 'english');
$this->lang->load('homepage', 'english');
$this->lang->load('mainpage', 'english');
} else {
$this->lang->load('register_login', 'indonesian');
$this->lang->load('homepage', 'indonesian');
$this->lang->load('mainpage', 'indonesian');
}
// $this->data['comments'] = $this->comment_m->get_comments();
$loginUrl = $this->googleclient->getLoginUrl();
$this->data_footer['googleUrl'] = $loginUrl;
$ip_address = $this->input->ip_address();
$this->visitortracking->trackVisitor();
}
public function index()
{
if ($this->session->userdata('site_lang') == 'english') {
$this->lang->load('mainpage', 'english');
} else {
$this->lang->load('mainpage', 'indonesian');
}
$this->visitortracking->trackVisitor();
if ($this->session->userdata('customer')) {
$id_customer = (int) $this->session->userdata('customer')['customer_id'];
$this->data['customer'] = $this->customer_m->get_customer($id_customer);
}
$static_content = [
'carousels' => $this->Carousel_banner_m->get_active_carousel(),
'banners' => $this->Top_banner_m->get_active_banners(),
'brands' => $this->Brand_m->get_all_brands(),
'comments' => $this->comment_m->get_comments()
];
$this->db->select('DISTINCT(stock.id_product) as id_product');
$this->db->from('stock');
$this->db->where('warehouse_id', 1);
$this->db->where('(stock - stock_keep) >', 0);
$available_products = $this->db->get_compiled_select();
$this->db->select('
product_review.id,
product_review.rating,
product_review.display_name as customer_name,
product_review.review as testimonial_text,
products.title as product_name,
products.alias as product_alias,
products.id_products as product_id,
customers.sex_type
');
$stock_subquery = "(SELECT SUM(stock - stock_keep)
FROM stock
WHERE stock.id_product = product_review.product_id
AND stock.warehouse_id = 1) as stock_sell";
$this->db->select($stock_subquery, FALSE);
$this->db->from('product_review');
$this->db->join('products', 'product_review.product_id = products.id_products');
$this->db->join('customers', 'product_review.customer_id = customers.id_customers');
$this->db->join("($available_products) as available_products", 'product_review.product_id = available_products.id_product');
$this->db->where('product_review.id IN (
SELECT MAX(pr.id)
FROM product_review pr
GROUP BY pr.product_id
)');
$this->db->order_by('product_review.id', 'DESC');
$this->db->limit(20);
$reviews = $this->db->get()->result();
$testimonials = [];
foreach ($reviews as $review) {
switch ($review->sex_type) {
case 'male':
$image = "https://storage.googleapis.com/laciasmara-photos/laciasmara_test/Laciasmara_testimonial/male.png";
break;
case 'female':
$image = "https://storage.googleapis.com/laciasmara-photos/laciasmara_test/Laciasmara_testimonial/female.png";
break;
default:
$image = "https://storage.googleapis.com/laciasmara-photos/laciasmara_test/Laciasmara_testimonial/others.png";
}
$testimonials[] = [
'customer_image' => $image,
'customer_name' => $review->customer_name,
'product_name' => $review->product_name,
'product_link' => base_url('product/' . $review->product_alias),
'star_rating' => $review->rating,
'testimonial_text' => $review->testimonial_text,
];
}
// Top seller products query
$this->db->select('
p.id_products,
p.title,
p.alias,
p.brand_id,
p.created_at,
pd.id AS id_detail,
pd.price,
pd.discounted_price,
pd.sku,
COALESCE(GROUP_CONCAT(DISTINCT CONCAT_WS(": ", pa.product_attribute, pad.attribute_detail) SEPARATOR "; "), "No variants available") AS variants,
pi.image AS image,
pi_secondary.image AS image_secondary,
pc.attribute_detail_id,
s.stock,
s.stock_keep,
(s.stock - s.stock_keep) AS stock_sell,
SUM(od.quantity) AS total_sales,
COUNT(pr.id) AS total_reviews,
CASE
WHEN pd.discounted_price IS NOT NULL AND pd.discounted_price > 0 AND pd.discounted_price < pd.price
THEN (pd.price - pd.discounted_price)
ELSE 0
END AS savings_amount,
CASE
WHEN pd.discounted_price IS NOT NULL AND pd.discounted_price > 0 AND pd.discounted_price < pd.price
THEN ROUND(((pd.price - pd.discounted_price) / pd.price) * 100, 0)
ELSE 0
END AS discount_percentage,
-- Badges Information (Added)
COALESCE(product_badges_data.badges_names, "") AS badges_names,
COALESCE(product_badges_data.badges_data, "") AS badges_data,
COALESCE(product_badges_data.badges_count, 0) AS badges_count
')
->from('products p')
->join('product_details pd', 'p.id_products = pd.product_id', 'left')
->join('product_images pi', 'pd.id = pi.product_details_id AND pi.priority = 1 AND pi.status = 1', 'left')
->join('product_images pi_secondary', 'pd.id = pi_secondary.product_details_id AND pi_secondary.priority = 2 AND pi_secondary.status = 1', 'left')
->join('stock s', 'pd.id = s.id_product_detail AND s.warehouse_id = 1', 'left')
->join('orders_detail od', 'od.item_id = pd.id AND od.warehouse_id = 1', 'left')
->join('product_combination pc', 'pd.id = pc.product_details_id', 'left')
->join('product_attributes pa', 'pc.attribute_id = pa.id', 'left')
->join('product_attributes_detail pad', 'pc.attribute_detail_id = pad.id', 'left')
->join('product_review pr', 'pr.product_id = p.id_products', 'left')
// Product Badges Join (Added)
->join('(SELECT
pb.product_id,
COUNT(pb.badge_id) AS badges_count,
GROUP_CONCAT(b.name ORDER BY pb.priority ASC SEPARATOR ", ") AS badges_names,
GROUP_CONCAT(
CONCAT(
b.id, ":",
b.name, ":",
b.slug, ":",
IFNULL(b.description, ""), ":",
IFNULL(b.background_color, "#FF6B6B"), ":",
IFNULL(b.text_color, "#FFFFFF"), ":",
IFNULL(b.icon, ""), ":",
pb.position, ":",
pb.priority
)
ORDER BY pb.priority ASC
SEPARATOR "|"
) AS badges_data
FROM product_badges pb
INNER JOIN badges b ON pb.badge_id = b.id
WHERE pb.is_active = 1
AND b.is_active = 1
AND (pb.start_date IS NULL OR pb.start_date <= NOW())
AND (pb.end_date IS NULL OR pb.end_date >= NOW())
GROUP BY pb.product_id) product_badges_data', 'p.id_products = product_badges_data.product_id', 'left')
->where('p.product_status', '1')
->where('p.deleted_at', null)
->where('s.stock > 1')
->where('(s.stock - s.stock_keep) > 0')
->group_by('p.id_products')
->order_by('total_reviews', 'DESC')
->limit(10);
$top_seller_products = $this->db->get()->result_array();
// New arrival products query
$this->db->select('
p.id_products,
p.title,
p.alias,
p.brand_id,
p.created_at,
pd.id AS id_detail,
pd.price,
pd.discounted_price,
pd.sku,
COALESCE(GROUP_CONCAT(DISTINCT CONCAT_WS(": ", pa.product_attribute, pad.attribute_detail) SEPARATOR "; "), "No variants available") AS variants,
pi.image AS image,
pi_secondary.image AS image_secondary,
pc.attribute_detail_id,
s.stock,
s.stock_keep,
s.stock_reject,
s.stock_sample,
(s.stock - s.stock_keep - COALESCE(s.stock_reject, 0) - COALESCE(s.stock_sample, 0)) as stock_sell,
SUM(od.quantity) AS total_sales,
COUNT(pr.id) AS total_reviews,
CASE
WHEN pd.discounted_price IS NOT NULL AND pd.discounted_price > 0 AND pd.discounted_price < pd.price
THEN (pd.price - pd.discounted_price)
ELSE 0
END AS savings_amount,
CASE
WHEN pd.discounted_price IS NOT NULL AND pd.discounted_price > 0 AND pd.discounted_price < pd.price
THEN ROUND(((pd.price - pd.discounted_price) / pd.price) * 100, 0)
ELSE 0
END AS discount_percentage,
-- Badges Information (Added)
COALESCE(product_badges_data.badges_names, "") AS badges_names,
COALESCE(product_badges_data.badges_data, "") AS badges_data,
COALESCE(product_badges_data.badges_count, 0) AS badges_count
')
->from('products p')
->join('product_details pd', 'p.id_products = pd.product_id', 'left')
->join('product_images pi', 'pd.id = pi.product_details_id AND pi.priority = 1 AND pi.status = 1', 'left')
->join('product_images pi_secondary', 'pd.id = pi_secondary.product_details_id AND pi_secondary.priority = 2 AND pi_secondary.status = 1', 'left')
->join('stock s', 'pd.id = s.id_product_detail AND s.warehouse_id = 1', 'left')
->join('orders_detail od', 'od.item_id = pd.id AND od.warehouse_id = 1', 'left')
->join('product_combination pc', 'pd.id = pc.product_details_id', 'left')
->join('product_attributes pa', 'pc.attribute_id = pa.id', 'left')
->join('product_attributes_detail pad', 'pc.attribute_detail_id = pad.id', 'left')
->join('product_review pr', 'pr.product_id = p.id_products', 'left')
->join('category_product cp', 'p.id_products = cp.id_product', 'inner')
->join('categories c', 'cp.id_category = c.id_categories', 'inner')
// Product Badges Join (Added)
->join('(SELECT
pb.product_id,
COUNT(pb.badge_id) AS badges_count,
GROUP_CONCAT(b.name ORDER BY pb.priority ASC SEPARATOR ", ") AS badges_names,
GROUP_CONCAT(
CONCAT(
b.id, ":",
b.name, ":",
b.slug, ":",
IFNULL(b.description, ""), ":",
IFNULL(b.background_color, "#FF6B6B"), ":",
IFNULL(b.text_color, "#FFFFFF"), ":",
IFNULL(b.icon, ""), ":",
pb.position, ":",
pb.priority
)
ORDER BY pb.priority ASC
SEPARATOR "|"
) AS badges_data
FROM product_badges pb
INNER JOIN badges b ON pb.badge_id = b.id
WHERE pb.is_active = 1
AND b.is_active = 1
AND (pb.start_date IS NULL OR pb.start_date <= NOW())
AND (pb.end_date IS NULL OR pb.end_date >= NOW())
GROUP BY pb.product_id) product_badges_data', 'p.id_products = product_badges_data.product_id', 'left')
->where('p.product_status', '1')
->where('p.deleted_at', null)
->where('s.stock > 1')
->where('(s.stock - s.stock_keep) > 0')
->where('c.alias', 'pendatang-baru')
->where('c.alias_en', 'new-arrivals')
->group_by('p.id_products')
->order_by('p.created_at', 'DESC')
->limit(10);
$new_arrival_products = $this->db->get()->result_array();
$campaign = $this->campaignmanager->get_campaign_from_session();
if ($campaign) {
$this->load->model('Promotional_campaign_m');
// Filter hanya produk yang eligible
foreach ($top_seller_products as $key => &$top_selling_product) {
$product_category = $this->db->select('id_category')
->from('category_product')
->where('id_product', $top_selling_product['id_products'])
->get()
->row();
if ($product_category) {
$is_eligible = $this->Promotional_campaign_m->is_product_eligible(
$campaign->id,
$top_selling_product['id_products'],
$product_category->id_category
);
if ($is_eligible) {
$top_selling_product['is_campaign_eligible'] = true;
}
}
}
// Apply discount ke semua yang eligible sekaligus
$top_seller_products = $this->campaignmanager->apply_discount_to_products_array(
$top_seller_products,
$campaign
);
// Filter hanya produk yang eligible
foreach ($new_arrival_products as $key => &$new_arrival_product) {
$product_category = $this->db->select('id_category')
->from('category_product')
->where('id_product', $new_arrival_product['id_products'])
->get()
->row();
if ($product_category) {
$is_eligible = $this->Promotional_campaign_m->is_product_eligible(
$campaign->id,
$new_arrival_product['id_products'],
$product_category->id_category
);
if ($is_eligible) {
$new_arrival_product['is_campaign_eligible'] = true;
}
}
}
// Apply discount ke semua yang eligible sekaligus
$new_arrival_products = $this->campaignmanager->apply_discount_to_products_array(
$new_arrival_products,
$campaign
);
}
// Prepare and format product data
$products_data = [
'top_seller_products' => $this->prepare_all_products_optimized($top_seller_products),
'new_products' => $this->prepare_all_products_optimized($new_arrival_products)
];
$this->data_header['carousels'] = $static_content['carousels'];
$this->data_header['banners'] = $static_content['banners'];
$this->data_header['brands'] = $static_content['brands'];
$this->data_header['testimonials'] = $testimonials;
$this->data_header['top_seller_products'] = $products_data['top_seller_products'];
$this->data_header['new_products'] = $products_data['new_products'];
$this->data['comments'] = $static_content['comments'];
// Load views
$this->load->view("themes/3/header_new", $this->data_header);
$this->load->view('themes/3/welcome');
$this->load->view("themes/3/footer_new", $this->data_footer);
}
function isMobile()
{
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$mobileKeywords = array(
'Mobile',
'Android',
'iPhone',
'iPod',
'BlackBerry',
'Windows Phone',
'Opera Mini'
);
foreach ($mobileKeywords as $keyword) {
if (strpos($userAgent, $keyword) !== false) {
return true;
}
}
return false;
}
private function prepare_all_products_optimized($products)
{
$customer = $this->session->userdata('customer');
$is_reseller = false;
$reseller_price_map = [];
// Get reseller information (existing code)
if (!empty($customer['customer_id'])) {
$customer_id = $customer['customer_id'];
$customer_data = $this->db->where('id_customers', $customer_id)->get('customers')->row_array();
if (!empty($customer_data['reseller_id'])) {
$reseller = $this->db->where('id_resellers', $customer_data['reseller_id'])->get('resellers')->row_array();
if ($reseller) {
$is_reseller = true;
$reseller_prices = $this->db->where('reseller_id', $reseller['id_resellers'])->get('resellers_price')->result_array();
foreach ($reseller_prices as $price) {
$reseller_price_map[$price['product_detail_id']] = $price['price'];
}
}
}
}
$formatted_products = [];
foreach ($products as $product) {
// Price calculations
$is_discounted = $product['discounted_price'] > 0;
$default_price = $product['price'];
$discounted_price = $product['discounted_price'];
$current_price = $is_discounted ? $discounted_price : $default_price;
$savings_amount = ($discounted_price > 0 && $discounted_price < $default_price)
? ($default_price - $discounted_price)
: 0;
$msrp_price = null;
// Handle reseller pricing
if ($is_reseller && isset($reseller_price_map[$product['id_detail']])) {
$msrp_price = $current_price;
$current_price = $reseller_price_map[$product['id_detail']];
}
// Get reviews
$review_data = $this->Review_m->get_product_reviews($product['id_products']);
$average_rating = isset($review_data['average_rating']) ? round($review_data['average_rating'], 1) : 0;
$total_reviews = isset($review_data['total_reviews']) ? $review_data['total_reviews'] : 0;
// Parse variants
$variants = !empty($product['variants']) ? explode('; ', $product['variants']) : [];
$badges = $this->parse_badges_data($product['badges_data'] ?? '');
$badges_names = $product['badges_names'] ?? '';
// Stock calculations - all done in SQL now, just ensure non-negative values
$current_variant_stock_sell = max(0, intval($product['current_variant_stock_sell'] ?? 0));
$total_stock_sell = max(0, intval($product['total_stock_sell'] ?? 0));
$formatted_products[] = [
'id' => $product['id_products'],
'title' => $product['title'],
'id_detail' => $product['id_detail'],
'alias' => $product['alias'],
'sku' => $product['sku'],
'current_price' => $current_price,
'original_price' => $is_discounted ? $default_price : null,
'msrp_price' => $msrp_price,
'image' => $product['image'],
'image_secondary' => $product['image_secondary'],
'stock' => $product['total_stock'],
'stock_sell' => $current_variant_stock_sell,
'total_stock_sell' => $total_stock_sell,
'average_rating' => $average_rating,
'total_reviews' => $total_reviews,
'variants' => $variants,
'is_wishlisted' => $this->_check_wishlist_status($product['id_products'], $customer['customer_id'] ?? null),
'created_at' => $product['created_at'],
'brand_priority' => $product['brand_priority'],
'savings_amount' => $savings_amount,
'is_discounted' => $is_discounted,
'discount_percentage' => $product['discount_percentage'],
// Stock flags - now calculated in SQL
'is_completely_sold_out' => (bool) $product['is_completely_sold_out'],
'current_variant_out_of_stock' => (bool) $product['current_variant_out_of_stock'],
'has_other_variants_available' => (bool) $product['has_other_variants_available'],
// Additional stock information
'total_variants' => (int) $product['total_variants'],
'available_variants' => (int) $product['available_variants'],
// Badges
'badges' => $badges,
'badges_names' => $badges_names, // Simple comma-separated names for quick display
'badges_count' => (int) ($product['badges_count'] ?? 0),
'has_badges' => !empty($badges),
// New arrivals flag for badges
'new_arrivals' => ($product['new_arrival'] === 'yes'),
'best_seller' => ($product['best_seller'] === 'yes'),
'popular_product' => ($product['popular_product'] === 'yes'),
];
}
return $formatted_products;
}
private function parse_badges_data($badges_data)
{
$badges = [];
if (empty($badges_data)) {
return $badges;
}
$badges_raw = explode('|', $badges_data);
foreach ($badges_raw as $badge_raw) {
if (empty($badge_raw)) continue;
$badge_parts = explode(':', $badge_raw);
if (count($badge_parts) >= 9) {
$badges[] = [
'id' => (int) $badge_parts[0],
'name' => $badge_parts[1],
'slug' => $badge_parts[2],
'description' => $badge_parts[3],
'background_color' => !empty($badge_parts[4]) ? $badge_parts[4] : '#FF6B6B',
'text_color' => !empty($badge_parts[5]) ? $badge_parts[5] : '#FFFFFF',
'icon' => $badge_parts[6],
'position' => $badge_parts[7],
'priority' => (int) $badge_parts[8],
// Additional computed properties
'css_class' => 'badge-' . $badge_parts[2],
'has_icon' => !empty($badge_parts[6]),
'style' => sprintf(
'background-color: %s; color: %s;',
!empty($badge_parts[4]) ? $badge_parts[4] : '#FF6B6B',
!empty($badge_parts[5]) ? $badge_parts[5] : '#FFFFFF'
)
];
}
}
// Already sorted by priority in SQL, but double check
usort($badges, function ($a, $b) {
return $a['priority'] - $b['priority'];
});
return $badges;
}
private function _check_wishlist_status($product_id, $customer_id)
{
if (!$customer_id) return false;
$exists = $this->db->where([
'customer_id' => $customer_id,
'product_id' => $product_id
])->get('wishlists')->num_rows();
return $exists > 0;
}
public function search()
{
header('Content-Type: application/json');
$query = $this->input->get('query', TRUE);
// Debug query
if (!$query) {
echo json_encode(['error' => 'No query provided']);
return;
}
$this->load->model('product_m');
$results = $this->product_m->search_products($query);
if (empty($results)) {
echo json_encode(['results' => []]);
return;
}
foreach ($results as &$result) {
$result['url'] = base_url('product/' . $result['alias']);
$result['image'] = base_url('uploads/product/' . $result['image']);
}
echo json_encode(['results' => $results]);
}
public function track_impression()
{
// Pastikan hanya menerima request AJAX
if (!$this->input->is_ajax_request()) {
show_error('No direct script access allowed', 403);
}
// Ambil data dari request
$banner_id = $this->input->post('bannerId');
if (!$banner_id) {
$this->output
->set_status_header(400)
->set_content_type('application/json')
->set_output(json_encode(['status' => 400, 'success' => false, 'message' => 'Banner ID is required']));
return;
}
$excluded_ips = ['110.137.195.77'];
$user_ip = $this->input->ip_address();
// Jika IP ada dalam daftar pengecualian, hentikan tracking
if (in_array($user_ip, $excluded_ips)) {
return $this->output
->set_status_header(200)
->set_content_type('application/json')
->set_output(json_encode([
'status' => 200,
'success' => false,
'message' => 'Tracking skipped for this IP'
]));
}
$data = [
'banner_id' => $banner_id,
'timestamp' => date('Y-m-d H:i:s'),
'session_id' => session_id(),
'user_agent' => $this->input->user_agent(),
'ip_address' => $user_ip
];
try {
$result = $this->Carousel_banner_m->save_impression($data);
if ($result) {
$this->output
->set_status_header(200)
->set_content_type('application/json')
->set_output(json_encode(['status' => 200, 'success' => true, 'message' => 'Impression tracked successfully']));
} else {
throw new Exception('Failed to save impression.');
}
} catch (Exception $e) {
log_message('error', 'Impression tracking failed: ' . $e->getMessage());
$this->output
->set_status_header(500)
->set_content_type('application/json')
->set_output(json_encode(['status' => 500, 'success' => false, 'message' => 'Server error: Unable to track impression']));
}
}
}