103 lines
2.9 KiB
PHP
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);
|
|
}
|
|
}
|