|
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/libraries/ |
Upload File : |
<?php
defined('BASEPATH') or exit('No direct script access allowed');
/**
* Campaign Manager Library
* Business logic untuk handle promotional campaigns
*
*/
class CampaignManager
{
private $CI;
private $session_key = 'promotional_campaign';
private $cookie_name = 'promo_campaign';
private $cookie_expiry = 86400; // 24 hours
public function __construct()
{
$this->CI = &get_instance();
$this->CI->load->model('Promotional_campaign_m');
$this->CI->load->model('Promotional_campaign_log_m');
$this->CI->load->model('Promotional_campaign_usage_m');
}
/**
* Get active campaign by code
*
* @param string $code
* @return object|null
*/
public function get_active_campaign($code)
{
$campaign = $this->CI->Promotional_campaign_m->get_by_code($code);
// Check if campaign exists and active
if (!$campaign || $campaign->is_active != 1 || $campaign->deleted_at !== null) {
return null;
}
return $campaign;
}
/**
* Check if campaign is within valid date range
*
* @param object $campaign
* @return bool
*/
public function is_campaign_valid($campaign)
{
$now = new DateTime();
$start = new DateTime($campaign->start_date);
$end = new DateTime($campaign->end_date);
return ($now >= $start && $now <= $end);
}
/**
* Check if usage limit reached (global)
*
* @param object $campaign
* @return bool
*/
public function is_usage_limit_reached($campaign)
{
// No limit set
if ($campaign->max_usage === null) {
return false;
}
// Check current usage
return $campaign->current_usage >= $campaign->max_usage;
}
/**
* Check if user has reached personal usage limit
*
* @param int $campaign_id
* @param int $user_id (null for guest)
* @param string $session_id
* @return bool
*/
public function is_user_limit_reached($campaign_id, $user_id = null, $session_id = null)
{
$campaign = $this->CI->Promotional_campaign_m->get_by_id($campaign_id);
// No per-user limit
if ($campaign->max_usage_per_user === null) {
return false;
}
$usage_count = $this->CI->Promotional_campaign_usage_m->get_user_usage_count(
$campaign_id,
$user_id,
$session_id
);
return $usage_count >= $campaign->max_usage_per_user;
}
/**
* Set campaign data to session
*
* @param object $campaign
* @return void
*/
public function set_campaign_session($campaign)
{
$campaign_data = [
'id' => $campaign->id,
'code' => $campaign->code,
'name' => $campaign->name,
'discount_type' => $campaign->discount_type,
'discount_value' => $campaign->discount_value,
'min_purchase' => $campaign->min_purchase,
'max_discount' => $campaign->max_discount,
'started_at' => time(),
'expires_at' => strtotime($campaign->end_date),
];
// Set session
$this->CI->session->set_userdata($this->session_key, $campaign_data);
// Set cookie as backup (untuk persistent jika session expired)
$cookie_value = $this->_encrypt_campaign_data($campaign_data);
$this->CI->input->set_cookie([
'name' => $this->cookie_name,
'value' => $cookie_value,
'expire' => $this->cookie_expiry,
'path' => '/',
'secure' => is_https(),
'httponly' => true
]);
}
/**
* Get campaign from session
*
* @return object|null
*/
public function get_campaign_from_session()
{
// Try to get from session first
$campaign_data = $this->CI->session->userdata($this->session_key);
// If not in session, try cookie
if (!$campaign_data) {
$campaign_data = $this->_restore_from_cookie();
}
if (!$campaign_data) {
return null;
}
// Check if expired
if (time() > $campaign_data['expires_at']) {
$this->clear_campaign_session();
return null;
}
return (object) $campaign_data;
}
/**
* Clear campaign from session and cookie
*
* @return void
*/
public function clear_campaign_session()
{
$this->CI->session->unset_userdata($this->session_key);
delete_cookie($this->cookie_name);
}
/**
* Calculate discount for a product based on campaign
*
* @param object $product
* @param object $campaign
* @return array [original_price, discount_amount, final_price]
*/
public function calculate_discount($product, $campaign)
{
// Selalu gunakan harga asli (price) dari product_details
$original_price = (float) $product->price;
$discount_amount = 0;
$final_price = $original_price;
switch ($campaign->discount_type) {
case 'percentage':
$discount_amount = $original_price * ($campaign->discount_value / 100);
// Apply max discount jika ada
if (!empty($campaign->max_discount) && $discount_amount > $campaign->max_discount) {
$discount_amount = (float) $campaign->max_discount;
}
break;
case 'fixed_amount':
$discount_amount = (float) $campaign->discount_value;
// Jangan biarkan diskon lebih besar dari harga
if ($discount_amount > $original_price) {
$discount_amount = $original_price;
}
break;
case 'free_shipping':
// Ditangani di checkout
$discount_amount = 0;
break;
}
$final_price = $original_price - $discount_amount;
return [
'original_price' => $original_price,
'discount_amount' => $discount_amount,
'final_price' => max(0, $final_price), // Tidak boleh negatif
'discount_percentage' => $original_price > 0 ? round(($discount_amount / $original_price) * 100) : 0
];
}
/**
* Apply discount to array of products
*
* @param array $products
* @param object $campaign
* @return array
*/
public function apply_discount_to_products($products, $campaign)
{
foreach ($products as &$product) {
$discount_data = $this->calculate_discount($product, $campaign);
$product->original_price = $discount_data['original_price'];
$product->discount_amount = $discount_data['discount_amount'];
$product->discounted_price = $discount_data['final_price'];
$product->discount_percentage = $discount_data['discount_percentage'];
$product->has_campaign = true;
}
return $products;
}
/**
* Apply discount to array of products (associative array format)
*
* @param array $products (result_array format)
* @param object $campaign
* @return array
*/
public function apply_discount_to_products_array($products, $campaign)
{
foreach ($products as &$product) {
// Convert to object temporarily untuk calculate_discount
$product_obj = (object) $product;
$discount_data = $this->calculate_discount($product_obj, $campaign);
// Update array
$product['original_price'] = $discount_data['original_price'];
$product['discount_amount'] = $discount_data['discount_amount'];
$product['discounted_price'] = $discount_data['final_price'];
$product['discount_percentage'] = $discount_data['discount_percentage'];
$product['has_campaign'] = true;
}
return $products;
}
/**
* Log campaign access for analytics
*
* @param int $campaign_id
* @param string $action_type (view, click_product, add_to_cart, checkout)
* @param int $product_id (optional)
* @return void
*/
public function log_campaign_access($campaign_id, $action_type = 'view', $product_id = null)
{
$log_data = [
'campaign_id' => $campaign_id,
'user_id' => $this->CI->session->userdata('user_id'), // null if guest
'session_id' => session_id(),
'ip_address' => $this->CI->input->ip_address(),
'user_agent' => $this->CI->input->user_agent(),
'referrer' => $this->CI->input->server('HTTP_REFERER'),
'action_type' => $action_type,
'product_id' => $product_id,
];
$this->CI->Promotional_campaign_log_m->insert($log_data);
}
/**
* Record campaign usage (when order completed)
*
* @param int $campaign_id
* @param int $order_id
* @param float $discount_amount
* @return bool
*/
public function record_usage($campaign_id, $order_id, $discount_amount)
{
$usage_data = [
'campaign_id' => $campaign_id,
'user_id' => $this->CI->session->userdata('user_id'),
'session_id' => session_id(),
'ip_address' => $this->CI->input->ip_address(),
'order_id' => $order_id,
'discount_amount' => $discount_amount,
];
// Insert usage record
$this->CI->Promotional_campaign_usage_m->insert($usage_data);
// Increment campaign usage counter
$this->CI->Promotional_campaign_m->increment_usage($campaign_id);
return true;
}
/**
* Encrypt campaign data for cookie
*
* @param array $data
* @return string
*/
private function _encrypt_campaign_data($data)
{
$this->CI->load->library('encryption');
return base64_encode($this->CI->encryption->encrypt(json_encode($data)));
}
/**
* Decrypt campaign data from cookie
*
* @return array|null
*/
private function _restore_from_cookie()
{
$cookie_value = $this->CI->input->cookie($this->cookie_name);
if (!$cookie_value) {
return null;
}
try {
$this->CI->load->library('encryption');
$decrypted = $this->CI->encryption->decrypt(base64_decode($cookie_value));
$campaign_data = json_decode($decrypted, true);
// Restore to session
if ($campaign_data) {
$this->CI->session->set_userdata($this->session_key, $campaign_data);
}
return $campaign_data;
} catch (Exception $e) {
// Invalid cookie, delete it
delete_cookie($this->cookie_name);
return null;
}
}
}