PHP Classes

File: public_html/webdoors/_doorsdk/php/helpers.php

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   public_html/webdoors/_doorsdk/php/helpers.php   Download  
File: public_html/webdoors/_doorsdk/php/helpers.php
Role: Example script
Content type: text/plain
Description: Example script
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 7,966 bytes
 

Contents

Class file image Download
<?php

/**
 * WebDoor SDK - PHP Helper Functions
 *
 * Common server-side utilities for WebDoor games.
 *
 * This file bootstraps the BinktermPHP environment for WebDoors.
 */
namespace WebDoorSDK;

// Define base directory if not already defined
if (!defined('BINKTERMPHP_BASEDIR')) {
   
define('BINKTERMPHP_BASEDIR', dirname(__DIR__, 4));
}

// Load BinktermPHP autoloader
require_once BINKTERMPHP_BASEDIR . '/vendor/autoload.php';

// Initialize database connection
\BinktermPHP\Database::getInstance();

// Start session if not already started
if (!headers_sent() && session_status() !== PHP_SESSION_ACTIVE) {
   
session_start();
}


/**
 * Get the current authenticated user from the session
 *
 * @return array|null User data or null if not authenticated
 *
 * @example
 * $user = \WebDoorSDK\getCurrentUser();
 * if ($user) {
 * echo "Hello, " . $user['username'];
 * }
 */
function getCurrentUser(): ?array
{
   
$auth = new \BinktermPHP\Auth();
    return
$auth->getCurrentUser();
}

/**
 * Require authentication and return the current user
 * Sends 401 response and exits if not authenticated
 *
 * @return array User data
 *
 * @example
 * $user = \WebDoorSDK\requireAuth();
 * // User is guaranteed to be authenticated here
 */
function requireAuth(): array
{
   
$user = getCurrentUser();

    if (!
$user) {
       
http_response_code(401);
       
header('Content-Type: application/json');
        echo
json_encode(['error' => 'Authentication required']);
        exit;
    }

    return
$user;
}

/**
 * Send a JSON response and exit
 *
 * @param mixed $data Data to send as JSON
 * @param int $statusCode HTTP status code (default: 200)
 *
 * @example
 * \WebDoorSDK\jsonResponse(['success' => true, 'score' => 100]);
 */
function jsonResponse($data, int $statusCode = 200): void
{
   
http_response_code($statusCode);
   
header('Content-Type: application/json');
    echo
json_encode($data);
    exit;
}

/**
 * Send a JSON error response and exit
 *
 * @param string $message Error message
 * @param int $statusCode HTTP status code (default: 400)
 *
 * @example
 * \WebDoorSDK\jsonError('Invalid input', 400);
 */
function jsonError(string $message, int $statusCode = 400): void
{
   
jsonResponse(['error' => $message], $statusCode);
}

/**
 * Validate required fields in an array (typically $_POST or JSON input)
 *
 * @param array $data Input data to validate
 * @param array $requiredFields List of required field names
 * @return bool True if all required fields are present and non-empty
 *
 * @example
 * $input = json_decode(file_get_contents('php://input'), true);
 * if (!\WebDoorSDK\validateRequired($input, ['username', 'score'])) {
 * \WebDoorSDK\jsonError('Missing required fields');
 * }
 */
function validateRequired(array $data, array $requiredFields): bool
{
    foreach (
$requiredFields as $field) {
        if (!isset(
$data[$field]) || $data[$field] === '') {
            return
false;
        }
    }
    return
true;
}

/**
 * Get the WebDoor's configuration from webdoors.json
 *
 * @param string $doorId The door identifier (e.g., 'netrealm')
 * @return array|null Door configuration or null if not found
 *
 * @example
 * $config = \WebDoorSDK\getDoorConfig('mygame');
 * $maxTurns = $config['max_turns'] ?? 100;
 */
function getDoorConfig(string $doorId): ?array
{
   
$configPath = __DIR__ . '/../../../../config/webdoors.json';

    if (!
file_exists($configPath)) {
        return
null;
    }

   
$config = json_decode(file_get_contents($configPath), true);

    if (!
$config || !isset($config[$doorId])) {
        return
null;
    }

    return
$config[$doorId];
}

/**
 * Check if a WebDoor is enabled
 *
 * @param string $doorId The door identifier
 * @return bool True if door is enabled
 *
 * @example
 * if (!\WebDoorSDK\isDoorEnabled('mygame')) {
 * \WebDoorSDK\jsonError('Game is disabled', 403);
 * }
 */
function isDoorEnabled(string $doorId): bool
{
   
$config = getDoorConfig($doorId);
    return
$config && ($config['enabled'] ?? false) === true;
}

/**
 * Get a database connection
 *
 * @return \PDO Database connection
 *
 * @example
 * $db = \WebDoorSDK\getDatabase();
 * $stmt = $db->prepare('SELECT * FROM game_scores WHERE user_id = ?');
 */
function getDatabase(): \PDO
{
   
// Assuming BinktermPHP Database class is available
   
return \BinktermPHP\Database::getInstance()->getPdo();
}

/**
 * Sanitize user input for display (prevent XSS)
 *
 * @param string $input User input to sanitize
 * @return string Sanitized output
 *
 * @example
 * $safeName = \WebDoorSDK\sanitize($_POST['name']);
 * echo "Hello, " . $safeName;
 */
function sanitize(string $input): string
{
    return
htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
}

/**
 * Load data from a WebDoor's storage slot for the current user.
 * Returns an empty array if no data has been saved yet.
 * Calls jsonError(401) and exits if no user is authenticated.
 *
 * @param string $doorId Door identifier (e.g. 'gemini-browser')
 * @param int $slot Storage slot (default 0)
 * @return array
 *
 * @example
 * $data = \WebDoorSDK\storageLoad('mygame');
 * $score = $data['high_score'] ?? 0;
 */
function storageLoad(string $doorId, int $slot = 0): array
{
   
$user = getCurrentUser();
    if (!
$user) {
       
jsonError('Not authenticated', 401);
    }

   
$userId = (int)($user['user_id'] ?? $user['id'] ?? 0);
   
$db = getDatabase();
   
$stmt = $db->prepare(
       
'SELECT data FROM webdoor_storage WHERE user_id = ? AND game_id = ? AND slot = ?'
   
);
   
$stmt->execute([$userId, $doorId, $slot]);
   
$row = $stmt->fetch(\PDO::FETCH_ASSOC);
    if (!
$row) {
        return [];
    }
   
$data = json_decode($row['data'], true);
    return
is_array($data) ? $data : [];
}

/**
 * Save data to a WebDoor's storage slot for the current user (upsert).
 * Calls jsonError(401) and exits if no user is authenticated.
 *
 * @param string $doorId Door identifier (e.g. 'gemini-browser')
 * @param array $data Data to store
 * @param int $slot Storage slot (default 0)
 *
 * @example
 * \WebDoorSDK\storageSave('mygame', ['high_score' => 9001]);
 */
function storageSave(string $doorId, array $data, int $slot = 0): void
{
   
$user = getCurrentUser();
    if (!
$user) {
       
jsonError('Not authenticated', 401);
    }

   
$userId = (int)($user['user_id'] ?? $user['id'] ?? 0);
   
$db = getDatabase();
   
$stmt = $db->prepare('
        INSERT INTO webdoor_storage (user_id, game_id, slot, data, saved_at)
        VALUES (?, ?, ?, ?::jsonb, NOW())
        ON CONFLICT (user_id, game_id, slot)
        DO UPDATE SET data = EXCLUDED.data, saved_at = NOW()
    '
);
   
$stmt->execute([
       
$userId,
       
$doorId,
       
$slot,
       
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
    ]);
}

/**
 * Log a message to the WebDoor log file
 *
 * @param string $doorId Door identifier
 * @param string $message Log message
 * @param string $level Log level (INFO, WARNING, ERROR)
 *
 * @example
 * \WebDoorSDK\log('mygame', 'User completed level 5', 'INFO');
 */
function log(string $doorId, string $message, string $level = 'INFO'): void
{
   
// Sanitize doorId to prevent path traversal attacks
    // Only allow alphanumerics, dots, underscores, and dashes
   
$safeDoorId = preg_replace('/[^a-zA-Z0-9._-]/', '', $doorId);

   
// If sanitization removed all characters or doorId is empty, use fallback
   
if ($safeDoorId === '' || $safeDoorId !== $doorId) {
       
// Use hash of original doorId as fallback for invalid names
       
$safeDoorId = 'invalid_' . substr(hash('sha256', $doorId), 0, 16);
    }

   
$logDir = __DIR__ . '/../../../../data/logs';
    if (!
is_dir($logDir)) {
       
mkdir($logDir, 0755, true);
    }

   
$logFile = $logDir . '/webdoor_' . $safeDoorId . '.log';
   
$timestamp = date('Y-m-d H:i:s');
   
$logMessage = "[{$timestamp}] [{$level}] {$message}\n";

   
file_put_contents($logFile, $logMessage, FILE_APPEND | LOCK_EX);
}