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 : /proc/self/root/var/www/laciasmara.com/public_html/shop/application/controllers/admin/ |
Upload File : |
<?php if (!defined('BASEPATH')) { exit('No direct script access allowed'); } class Link extends Admin_Controller { function __construct() { parent::__construct(); $this->load->model('configuration_m'); $this->load->model('brand_m'); $this->load->model('category_m'); $this->load->model('product_m'); $this->load->helper('form'); } function index() { $data['userdata'] = $this->session->userdata(); $data['title'] = 'Link Generator | Laciasmara'; $data['links'] = $this->getUTMLinksWithStatistics(); $this->load->view('admin_new/layouts/header', $data); $this->load->view('admin_new/links/index'); $this->load->view('admin_new/layouts/footer'); } function add() { $data['userdata'] = $this->session->userdata(); $data['brands'] = $this->brand_m->get_all_brands(); $data['categories'] = $this->category_m->all_categories(); $data['products'] = $this->product_m->all_products(); $data['title'] = 'Add UTM Link | Laciasmara'; $this->load->view('admin_new/layouts/header', $data); $this->load->view('admin_new/links/add_link'); $this->load->view('admin_new/layouts/footer'); } /** * Create new UTM tracking link * * @return void */ public function create_link() { // Check CSRF token $this->form_validation->set_rules('link_type', 'Jenis Link', 'required'); $this->form_validation->set_rules('utm_source', 'Sumber Trafik', 'required'); $this->form_validation->set_rules('utm_medium', 'Jenis Trafik', 'required'); $this->form_validation->set_rules('utm_campaign', 'Nama Promosi', 'required'); if ($this->form_validation->run() == FALSE) { $this->session->set_flashdata('message_type', 'error'); $this->session->set_flashdata('message', 'Mohon lengkapi semua field yang wajib diisi!'); redirect('admin/marketing/link/add'); return; } // Get form data $link_type = $this->input->post('link_type'); $item_id = null; $alias = ''; // Get the appropriate ID and alias based on link type if ($link_type == 'product') { $item_id = $this->input->post('product_id'); $product = $this->db->get_where('products', ['id_products' => $item_id])->row(); if (!$product) { $this->session->set_flashdata('message_type', 'error'); $this->session->set_flashdata('message', 'Produk tidak ditemukan!'); redirect('admin/marketing/tracking-link/add'); return; } $alias = $product->alias; $base_segment = 'product'; } else if ($link_type == 'brand') { $item_id = $this->input->post('brand_id'); $brand = $this->db->get_where('brands', ['id_brands' => $item_id])->row(); if (!$brand) { $this->session->set_flashdata('message_type', 'error'); $this->session->set_flashdata('message', 'Merk tidak ditemukan!'); redirect('admin/marketing/tracking-link/add'); return; } $alias = $brand->alias; $base_segment = 'brand'; } else if ($link_type == 'category') { $item_id = $this->input->post('category_id'); $category = $this->db->get_where('categories', ['id_categories' => $item_id])->row(); if (!$category) { $this->session->set_flashdata('message_type', 'error'); $this->session->set_flashdata('message', 'Kategori tidak ditemukan!'); redirect('admin/marketing/tracking-link/add'); return; } $alias = $category->alias; $base_segment = 'category'; } else { $this->session->set_flashdata('message_type', 'error'); $this->session->set_flashdata('message', 'Jenis link tidak valid!'); redirect('admin/marketing/tracking-link/add'); return; } // Build UTM parameters $utm_params = [ 'utm_source' => $this->input->post('utm_source'), 'utm_medium' => $this->input->post('utm_medium'), 'utm_campaign' => $this->input->post('utm_campaign') ]; // Add optional UTM parameters if they exist if ($this->input->post('utm_content')) { $utm_params['utm_content'] = $this->input->post('utm_content'); } if ($this->input->post('utm_term')) { $utm_params['utm_term'] = $this->input->post('utm_term'); } // Build the final URL with UTM parameters $base_url = base_url($base_segment . '/' . $alias); $url = $base_url . '?' . http_build_query($utm_params); // Data to be inserted $data = [ 'url' => $url, 'item_id' => $item_id, 'item_type' => $link_type, 'utm_source' => $this->input->post('utm_source'), 'utm_medium' => $this->input->post('utm_medium'), 'utm_campaign' => $this->input->post('utm_campaign'), 'utm_content' => $this->input->post('utm_content'), 'utm_term' => $this->input->post('utm_term'), 'created_at' => date('Y-m-d H:i:s') ]; // Insert data to database $this->db->insert('utm_links', $data); // Set flash message and redirect $this->session->set_flashdata('message_type', 'success'); $this->session->set_flashdata('message', 'Link berhasil ditambahkan!'); redirect('admin/marketing/tracking-link'); } // Di controller public function get_utm_links() { $links = $this->getUTMLinksWithStatistics(); $this->output ->set_content_type('application/json') ->set_output(json_encode($links)); } private function getUTMLinksWithStatistics() { // Get filter parameters - tetap sama seperti sebelumnya $sort = $this->input->get('sort', true); $dateFilter = $this->input->get('date_filter', true); $startDate = $this->input->get('start_date', true); $endDate = $this->input->get('end_date', true); $page = (int) ($this->input->get('page', true) ?? 1); $limit = (int) ($this->input->get('limit', true) ?? 10); $offset = ($page - 1) * $limit; $isInstagram = filter_var($this->input->get('isInstagram', true), FILTER_VALIDATE_BOOLEAN); $isFacebook = filter_var($this->input->get('isFacebook', true), FILTER_VALIDATE_BOOLEAN); $isYoutube = filter_var($this->input->get('isYoutube', true), FILTER_VALIDATE_BOOLEAN); $isLinkedIn = filter_var($this->input->get('isLinkedIn', true), FILTER_VALIDATE_BOOLEAN); $isTiktok = filter_var($this->input->get('isTiktok', true), FILTER_VALIDATE_BOOLEAN); $isDuniaAsmara = filter_var($this->input->get('isDuniaAsmara', true), FILTER_VALIDATE_BOOLEAN); $isGoogleAds = filter_var($this->input->get('isGoogleAds', true), FILTER_VALIDATE_BOOLEAN); $isMeta = filter_var($this->input->get('isMeta', true), FILTER_VALIDATE_BOOLEAN); $isProduct = filter_var($this->input->get('isProduct', true), FILTER_VALIDATE_BOOLEAN); $isBrand = filter_var($this->input->get('isBrand', true), FILTER_VALIDATE_BOOLEAN); $isCategory = filter_var($this->input->get('isCategory', true), FILTER_VALIDATE_BOOLEAN); $searchTerm = $this->input->get('search', true); // OPTIMASI 1: Gunakan pendekatan dua langkah // Langkah 1: Ambil dulu ID UTM links berdasarkan filter $this->db->select('utm_links.id'); $this->db->from('utm_links'); // Join dengan items untuk pencarian item_name $this->db->join('( SELECT id_products AS item_id, title AS item_name, "product" AS type FROM products UNION ALL SELECT id_brands AS item_id, brand AS item_name, "brand" AS type FROM brands UNION ALL SELECT id_categories AS item_id, category AS item_name, "category" AS type FROM categories ) AS items', 'items.item_id = utm_links.item_id AND items.type = utm_links.item_type', 'left'); // Apply platform filters (sama seperti sebelumnya) $platformFilters = []; if ($isInstagram) $platformFilters[] = 'instagram'; if ($isFacebook) $platformFilters[] = 'facebook'; if ($isYoutube) $platformFilters[] = 'youtube'; if ($isLinkedIn) $platformFilters[] = 'linkedin'; if ($isTiktok) $platformFilters[] = 'tiktok'; if ($isDuniaAsmara) $platformFilters[] = 'duniaasmara'; if ($isGoogleAds) $platformFilters[] = 'google'; if ($isMeta) $platformFilters[] = 'meta'; if (!empty($platformFilters)) { $this->db->group_start(); foreach ($platformFilters as $index => $platform) { if ($index === 0) { $this->db->like('utm_links.utm_source', $platform); } else { $this->db->or_like('utm_links.utm_source', $platform); } } $this->db->group_end(); } // Apply item type filters (sama seperti sebelumnya) $itemTypeFilters = []; if ($isProduct) $itemTypeFilters[] = 'product'; if ($isBrand) $itemTypeFilters[] = 'brand'; if ($isCategory) $itemTypeFilters[] = 'category'; if (!empty($itemTypeFilters)) { $this->db->group_start(); foreach ($itemTypeFilters as $index => $itemType) { if ($index === 0) { $this->db->where('utm_links.item_type', $itemType); } else { $this->db->or_where('utm_links.item_type', $itemType); } } $this->db->group_end(); } // Apply search filter (sama seperti sebelumnya) if (!empty($searchTerm)) { $this->db->group_start(); $this->db->like('utm_links.url', $searchTerm); $this->db->or_like('utm_links.utm_source', $searchTerm); $this->db->or_like('utm_links.utm_medium', $searchTerm); $this->db->or_like('utm_links.utm_campaign', $searchTerm); $this->db->or_like('utm_links.utm_content', $searchTerm); $this->db->or_like('utm_links.utm_term', $searchTerm); $this->db->or_like('items.item_name', $searchTerm); $this->db->group_end(); } // Apply date filter (sama seperti sebelumnya) // if (!empty($dateFilter)) { // switch ($dateFilter) { // case 'today': // $this->db->where('DATE(utm_links.created_at) = CURDATE()'); // break; // case 'yesterday': // $this->db->where('DATE(utm_links.created_at) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)'); // break; // case 'last_7_days': // $this->db->where('utm_links.created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)'); // break; // case 'last_30_days': // $this->db->where('utm_links.created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)'); // break; // case 'this_month': // $this->db->where('MONTH(utm_links.created_at) = MONTH(CURDATE())'); // $this->db->where('YEAR(utm_links.created_at) = YEAR(CURDATE())'); // break; // case 'custom': // if (!empty($startDate) && !empty($endDate)) { // $this->db->where('DATE(utm_links.created_at) >=', date('Y-m-d', strtotime($startDate))); // $this->db->where('DATE(utm_links.created_at) <=', date('Y-m-d', strtotime($endDate))); // } // break; // } // } // OPTIMASI 2: Terapkan sorting dan pagination pada subquery ini if ($sort) { switch ($sort) { case 'total_click_banyak': case 'total_click_dikit': case 'unique_click_banyak': case 'unique_click_dikit': case 'order_banyak': case 'order_dikit': // Untuk sorting yang membutuhkan statistik, kita tetap gunakan default sort dulu $this->db->order_by('utm_links.id', 'DESC'); break; default: // Default sort by newest $this->db->order_by('utm_links.id', 'DESC'); } } else { $this->db->order_by('utm_links.id', 'DESC'); } // Terapkan pagination $this->db->limit($limit, $offset); // Eksekusi query untuk mendapatkan ID yang akan digunakan $id_query = $this->db->get(); $utm_link_ids = array_column($id_query->result_array(), 'id'); // Jika tidak ada hasil, return array kosong if (empty($utm_link_ids)) { return []; } // OPTIMASI 3: Query kedua untuk mengambil data utama dengan ID yang sudah difilter $this->db->select('utm_links.*, items.item_name'); $this->db->from('utm_links'); // Join dengan items untuk mendapatkan item_name $this->db->join('( SELECT id_products AS item_id, title AS item_name, "product" AS type FROM products UNION ALL SELECT id_brands AS item_id, brand AS item_name, "brand" AS type FROM brands UNION ALL SELECT id_categories AS item_id, category AS item_name, "category" AS type FROM categories ) AS items', 'items.item_id = utm_links.item_id AND items.type = utm_links.item_type', 'left'); // Filter berdasarkan ID yang sudah diambil $this->db->where_in('utm_links.id', $utm_link_ids); // Pertahankan urutan yang sama seperti subquery $order_ids = implode(',', $utm_link_ids); if (!empty($order_ids)) { $this->db->order_by("FIELD(utm_links.id, $order_ids)"); } $query = $this->db->get(); $utm_links = $query->result_array(); // OPTIMASI 4: Buat query terpisah untuk statistik clicks untuk setiap link foreach ($utm_links as &$link) { // Query click statistics untuk link ini saja dengan batasan waktu $url_base = $this->db->escape(substr($link['url'], 0, strpos($link['url'], '?') ?: strlen($link['url']))); // OPTIMASI 5: Batasi rentang waktu data link_tracks $timeLimit = ''; // Gunakan date filter yang sama dengan utm_links jika ada if (!empty($dateFilter)) { switch ($dateFilter) { case 'today': $timeLimit = " AND DATE(created_at) = CURDATE()"; break; case 'yesterday': $timeLimit = " AND DATE(created_at) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)"; break; case 'last_7_days': $timeLimit = " AND created_at >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)"; break; case 'last_30_days': $timeLimit = " AND created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)"; break; case 'this_month': $timeLimit = " AND MONTH(created_at) = MONTH(CURDATE()) AND YEAR(created_at) = YEAR(CURDATE())"; break; case 'custom': if (!empty($startDate) && !empty($endDate)) { $startDateFormatted = date('Y-m-d', strtotime($startDate)); $endDateFormatted = date('Y-m-d', strtotime($endDate)); $timeLimit = " AND DATE(created_at) >= '$startDateFormatted' AND DATE(created_at) <= '$endDateFormatted'"; } else { // Default: last 30 days if no date specified $timeLimit = " AND created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)"; } break; default: // Default: last 30 days $timeLimit = " AND created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)"; } } else { // Default: last 30 days $timeLimit = " AND created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)"; } // OPTIMASI 6: Gunakan query langsung untuk statistik klik // OPTIMASI 6: Gunakan query langsung untuk statistik klik dengan semua parameter UTM $utm_source = $this->db->escape($link['utm_source'] ?: ''); $utm_medium = $this->db->escape($link['utm_medium'] ?: ''); $utm_campaign = $this->db->escape($link['utm_campaign'] ?: ''); $utm_content = $this->db->escape($link['utm_content'] ?: ''); $utm_term = $this->db->escape($link['utm_term'] ?: ''); $clicks_query = $this->db->query( "SELECT COUNT(DISTINCT id) as total_clicks, COUNT(DISTINCT ip_address) as unique_clicks FROM link_tracks WHERE link_url = SUBSTRING_INDEX({$url_base}, '?', 1) AND ( (utm_source = $utm_source) OR ($utm_source = '' AND (utm_source IS NULL OR utm_source = 'none')) OR ($utm_source = 'none' AND (utm_source IS NULL OR utm_source = '')) ) AND ( (utm_medium = $utm_medium) OR ($utm_medium = '' AND (utm_medium IS NULL OR utm_medium = 'none')) OR ($utm_medium = 'none' AND (utm_medium IS NULL OR utm_medium = '')) ) AND ( (utm_campaign = $utm_campaign) OR ($utm_campaign = '' AND (utm_campaign IS NULL OR utm_campaign = 'none')) OR ($utm_campaign = 'none' AND (utm_campaign IS NULL OR utm_campaign = '')) ) AND ( (utm_content = $utm_content) OR ($utm_content = '' AND (utm_content IS NULL OR utm_content = 'none')) OR ($utm_content = 'none' AND (utm_content IS NULL OR utm_content = '')) ) AND ( (utm_term = $utm_term) OR ($utm_term = '' AND (utm_term IS NULL OR utm_term = 'none')) OR ($utm_term = 'none' AND (utm_term IS NULL OR utm_term = '')) ) $timeLimit" ); $clicks_result = $clicks_query->row_array(); $link['total_clicks'] = (int)$clicks_result['total_clicks']; $link['unique_clicks'] = (int)$clicks_result['unique_clicks']; // OPTIMASI 7: Gunakan query terpisah untuk orders $orders_query = $this->db->query( "SELECT COUNT(DISTINCT id_orders) as successful_orders, COALESCE(SUM(grand_total_amount), 0) as total_revenue FROM orders WHERE source = " . $this->db->escape($link['utm_source']) . " AND medium = " . $this->db->escape($link['utm_medium']) . " AND campaign = " . $this->db->escape($link['utm_campaign']) . " AND payment_status = 5 AND DATE(created_at) $timeLimit" ); $orders_result = $orders_query->row_array(); $link['successful_orders'] = (int)$orders_result['successful_orders']; $link['total_revenue'] = $orders_result['total_revenue']; // Calculate conversion rate $link['conversion_rate'] = $link['unique_clicks'] > 0 ? round(($link['successful_orders'] / $link['unique_clicks']) * 100, 2) : 0; // Format numbers for better readability $link['total_revenue'] = number_format($link['total_revenue'], 2); } // OPTIMASI 8: Terapkan post-sorting jika diperlukan if ($sort) { usort($utm_links, function ($a, $b) use ($sort) { switch ($sort) { case 'total_click_banyak': return $b['total_clicks'] - $a['total_clicks']; case 'total_click_dikit': return $a['total_clicks'] - $b['total_clicks']; case 'unique_click_banyak': return $b['unique_clicks'] - $a['unique_clicks']; case 'unique_click_dikit': return $a['unique_clicks'] - $b['unique_clicks']; case 'order_banyak': return $b['successful_orders'] - $a['successful_orders']; case 'order_dikit': return $a['successful_orders'] - $b['successful_orders']; default: return 0; // sudah diurutkan di query } }); } return $utm_links; } public function generate() { $this->data['subview'] = 'admin/link/index'; $this->load->view('admin/templates/header', $this->data_header); $this->load->view('admin/_layout_main', $this->data); $this->load->view('admin/templates/footer'); } public function save_link() { $data = [ 'url' => $this->input->post('url'), 'item_id' => $this->input->post('item_id'), 'item_type' => $this->input->post('item_type'), 'utm_source' => $this->input->post('utm_source'), 'utm_medium' => $this->input->post('utm_medium'), 'utm_campaign' => $this->input->post('utm_campaign') ]; $result = $this->insert($data); if ($result) { $response = [ 'success' => true, 'message' => 'Link berhasil disimpan', 'id' => $result ]; } else { $response = [ 'success' => false, 'message' => 'Gagal menyimpan link' ]; } $this->output->set_content_type('application/json') ->set_output(json_encode($response)); } private function insert($data) { $this->db->insert('utm_links', $data); return $this->db->insert_id(); } public function get_recent_links() { $this->db->order_by('created_at', 'DESC'); $results = $this->db->get('utm_links')->result(); echo json_encode($results); } }