Files
2026-09-11 18:42:12 +07:00

103 lines
2.9 KiB
PHP

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
require_once APPPATH . 'exceptions/BusinessException.php';
class CompanyContext
{
private $CI;
private $id;
public function __construct()
{
$this->CI =& get_instance();
}
public function id()
{
if ($this->id) {
return $this->id;
}
$userId = (int) $this->CI->session->userdata('user_id');
$selected = (int) $this->CI->session->userdata('company_id');
if ($selected && $this->hasAccess($userId, $selected)) {
return $this->id = $selected;
}
$access = $this->CI->db
->where('user_id', $userId)
->order_by('is_default', 'DESC')
->order_by('id', 'ASC')
->get('user_companies')
->row();
// Memulihkan user lama yang dibuat sebelum relasi perusahaan diterapkan.
// Auto-assignment hanya aman jika memang hanya ada satu perusahaan aktif.
if (!$access) {
$access = $this->assignSoleActiveCompany($userId);
}
if (!$access) {
throw new BusinessException('User belum diberi akses perusahaan. Hubungi administrator.');
}
$this->CI->session->set_userdata('company_id', (int) $access->company_id);
return $this->id = (int) $access->company_id;
}
public function assertAccess($companyId)
{
if (!$this->hasAccess((int) $this->CI->session->userdata('user_id'), (int) $companyId)) {
throw new BusinessException('Akses perusahaan ditolak.');
}
return true;
}
public function scope($builder, $column = 'company_id')
{
$builder->where($column, $this->id());
return $builder;
}
private function hasAccess($userId, $companyId)
{
return (bool) $this->CI->db->get_where('user_companies', array(
'user_id' => (int) $userId,
'company_id' => (int) $companyId,
))->row();
}
private function assignSoleActiveCompany($userId)
{
if ($userId < 1 || !$this->CI->db->table_exists('companies')) {
return null;
}
$companies = $this->CI->db
->select('id')
->where('is_active', 1)
->order_by('id', 'ASC')
->limit(2)
->get('companies')
->result();
if (count($companies) !== 1) {
return null;
}
$companyId = (int) $companies[0]->id;
$this->CI->db->query(
'INSERT IGNORE INTO user_companies (user_id, company_id, is_default, can_consolidate) VALUES (?, ?, 1, 0)',
array($userId, $companyId)
);
if (!$this->hasAccess($userId, $companyId)) {
throw new RuntimeException('Akses perusahaan pengguna gagal disiapkan.');
}
return (object) array('company_id' => $companyId);
}
}