Fix: Convert 03PovertyMapping from submodule to regular folder
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// config/bootstrap.php — with session support
|
||||
// ============================================================
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/config.php';
|
||||
require_once __DIR__ . '/database.php';
|
||||
require_once __DIR__ . '/../middleware/Response.php';
|
||||
require_once __DIR__ . '/../middleware/Validator.php';
|
||||
require_once __DIR__ . '/../models/AuditLog.php';
|
||||
require_once __DIR__ . '/../models/PovertyCalculator.php';
|
||||
|
||||
// ---- Error handling ----------------------------------------
|
||||
if (APP_DEBUG) {
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', '1');
|
||||
} else {
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', '0');
|
||||
}
|
||||
|
||||
set_exception_handler(function (Throwable $e) {
|
||||
$message = APP_DEBUG ? $e->getMessage() : 'Internal server error';
|
||||
Response::error($message, 500);
|
||||
});
|
||||
|
||||
// ---- CORS & Security Headers --------------------------------
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('X-Content-Type-Options: nosniff');
|
||||
header('X-Frame-Options: DENY');
|
||||
|
||||
if (APP_ENV === 'development') {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
|
||||
header('Access-Control-Allow-Headers: Content-Type');
|
||||
}
|
||||
|
||||
$requestMethod = $_SERVER['REQUEST_METHOD'] ?? '';
|
||||
if ($requestMethod === 'OPTIONS') {
|
||||
http_response_code(204);
|
||||
exit;
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
// ---- Session bootstrap (shared by all APIs) -----------------
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_name('webgis_sess');
|
||||
session_set_cookie_params([
|
||||
'lifetime' => 0, // until browser closes
|
||||
'path' => '/',
|
||||
'secure' => false, // set true if using HTTPS
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax',
|
||||
]);
|
||||
session_start();
|
||||
}
|
||||
|
||||
// ---- Session helper functions --------------------------------
|
||||
|
||||
/** Return current logged-in user array or null */
|
||||
function currentUser(): ?array
|
||||
{
|
||||
if (empty($_SESSION['user_id']) || empty($_SESSION['role'])) {
|
||||
return null;
|
||||
}
|
||||
return [
|
||||
'id' => (int)$_SESSION['user_id'],
|
||||
'name' => $_SESSION['name'] ?? '',
|
||||
'email' => $_SESSION['email'] ?? '',
|
||||
'role' => $_SESSION['role'],
|
||||
];
|
||||
}
|
||||
|
||||
/** Require authentication — returns user or sends 401 */
|
||||
function requireAuth(): array
|
||||
{
|
||||
$user = currentUser();
|
||||
if (!$user) {
|
||||
Response::error('Silakan login terlebih dahulu.', 401);
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
/** Require admin role — returns user or sends 403 */
|
||||
function requireAdmin(): array
|
||||
{
|
||||
$user = requireAuth();
|
||||
if ($user['role'] !== 'admin') {
|
||||
Response::error('Akses ditolak. Hanya admin yang dapat melakukan tindakan ini.', 403);
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// config/config.php
|
||||
// ============================================================
|
||||
declare(strict_types=1);
|
||||
|
||||
// ---- Environment -------------------------------------------
|
||||
// SET TO 'development' TEMPORARILY TO SEE ERROR DETAILS
|
||||
define('APP_ENV', getenv('APP_ENV') ?: 'development');
|
||||
define('APP_DEBUG', true); // <--- SET TRUE TO SEE ERRORS
|
||||
define('APP_NAME', 'WebGIS Poverty Mapping v2');
|
||||
define('BASE_URL', getenv('BASE_URL') ?: 'http://localhost/webgis-v2');
|
||||
|
||||
// ---- Database ----------------------------------------------
|
||||
define('DB_HOST', getenv('DB_HOST') ?: 'localhost');
|
||||
define('DB_PORT', getenv('DB_PORT') ?: '3306');
|
||||
define('DB_NAME', getenv('DB_NAME') ?: 'poverty_mapping');
|
||||
define('DB_USER', getenv('DB_USER') ?: 'root');
|
||||
define('DB_PASS', getenv('DB_PASS') ?: '');
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
|
||||
// ---- Pagination --------------------------------------------
|
||||
define('PAGE_SIZE', 500);
|
||||
|
||||
// ---- Poverty scoring thresholds ----------------------------
|
||||
define('POVERTY_THRESHOLD_NEAR', 30);
|
||||
define('POVERTY_THRESHOLD_POOR', 55);
|
||||
define('POVERTY_THRESHOLD_SEVERE', 75);
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
// ============================================================
|
||||
// config/database.php — PDO singleton
|
||||
// ============================================================
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/config.php';
|
||||
|
||||
class Database
|
||||
{
|
||||
private static ?PDO $instance = null;
|
||||
|
||||
public static function get(): PDO
|
||||
{
|
||||
if (self::$instance === null) {
|
||||
$dsn = sprintf(
|
||||
'mysql:host=%s;port=%s;dbname=%s;charset=%s',
|
||||
DB_HOST, DB_PORT, DB_NAME, DB_CHARSET
|
||||
);
|
||||
self::$instance = new PDO($dsn, DB_USER, DB_PASS, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => false,
|
||||
]);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/** Prevent cloning / serialisation */
|
||||
private function __clone() {}
|
||||
public function __wakeup(): never { throw new \Exception('Cannot unserialize singleton.'); }
|
||||
}
|
||||
Reference in New Issue
Block a user