View Raw <?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
$configFile = __DIR__ . '/config.json';
$iconsDir = __DIR__ . '/icons';
$iconsMappingFile = __DIR__ . '/icons.json';
$extensionMapFile = __DIR__ . '/extensionMap.json';
function logRequest($endpoint, $params = [], $response = 'success') {
$logData = [
'timestamp' => date('Y-m-d H:i:s'),
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
'endpoint' => $endpoint,
'params' => $params,
'response' => $response
];
$logFile = '/web/admin/logs/indexer/api/requests.log';
$logDir = dirname($logFile);
if (!is_dir($logDir)) {
mkdir($logDir, 0755, true);
}
file_put_contents($logFile, json_encode($logData) . "\n", FILE_APPEND | LOCK_EX);
}
function jsonResponse($data, $status = 200) {
http_response_code($status);
echo json_encode($data, JSON_PRETTY_PRINT);
exit();
}
function errorResponse($message, $status = 400) {
logRequest($_GET['action'] ?? 'unknown', $_GET, 'error: ' . $message);
jsonResponse(['error' => $message, 'status' => $status], $status);
}
function loadExtensionMappings() {
global $extensionMapFile;
if (!file_exists($extensionMapFile)) {
return null;
}
$mappingData = file_get_contents($extensionMapFile);
$mappings = json_decode($mappingData, true);
return $mappings ?: null;
}
function loadIconMappings() {
global $iconsMappingFile;
if (!file_exists($iconsMappingFile)) {
return [];
}
$mappingData = file_get_contents($iconsMappingFile);
$mappings = json_decode($mappingData, true);
return $mappings ?: [];
}
function findIconForType($type, $extension = '') {
global $iconsDir;
$iconMappings = loadIconMappings();
if ($type === 'folder') {
$iconFile = isset($iconMappings['folder']) ? $iconMappings['folder'] : 'folder.png';
} else {
$extension = strtolower($extension);
$iconFile = isset($iconMappings[$extension]) ? $iconMappings[$extension] : 'text.png';
}
$iconPath = $iconsDir . '/' . $iconFile;
if (!file_exists($iconPath)) {
$iconFile = 'text.png';
$iconPath = $iconsDir . '/' . $iconFile;
if (!file_exists($iconPath)) {
return null;
}
}
return [
'filename' => $iconFile,
'url' => 'https://api.indexer.ccls.icu/icons/' . $iconFile,
'path' => $iconPath,
'size' => filesize($iconPath),
'last_modified' => filemtime($iconPath)
];
}
$action = $_GET['action'] ?? '';
switch ($action) {
case 'versionCheck':
handleVersionCheckRequest();
break;
case 'config':
handleConfigRequest();
break;
case 'icons':
handleIconsRequest();
break;
case 'icon':
handleSingleIconRequest();
break;
case 'findIcon':
handleFindIconRequest();
break;
case 'iconMappings':
handleIconMappingsRequest();
break;
case 'extensionMappings':
handleExtensionMappingsRequest();
break;
case 'getExtensionSetting':
handleGetExtensionSettingRequest();
break;
case 'configReference':
handleConfigReferenceRequest();
break;
case 'status':
handleStatusRequest();
break;
default:
handleDefaultRequest();
break;
}
function handleVersionCheckRequest() {
global $configFile;
$currentVersion = $_GET['current_version'] ?? '';
if (empty($currentVersion)) {
errorResponse('Current version parameter is required');
}
if (!file_exists($configFile)) {
errorResponse('Configuration file not found', 404);
}
$configData = file_get_contents($configFile);
$config = json_decode($configData, true);
if ($config === null) {
errorResponse('Invalid configuration file', 500);
}
$latestVersion = isset($config['version']) ? $config['version'] : '1.1.12';
$updateNeeded = version_compare($currentVersion, $latestVersion, '<');
$response = [
'success' => true,
'current_version' => $currentVersion,
'latest_version' => $latestVersion,
'update_needed' => $updateNeeded,
'timestamp' => date('Y-m-d H:i:s')
];
if ($updateNeeded) {
$response['message'] = "Update available: {$currentVersion} -> {$latestVersion}";
$response['config_url'] = 'https://api.indexer.ccls.icu/api.php?action=config';
} else {
$response['message'] = "You have the latest version: {$currentVersion}";
}
logRequest('versionCheck', ['current_version' => $currentVersion, 'latest_version' => $latestVersion, 'update_needed' => $updateNeeded]);
header('Cache-Control: public, max-age=900');
jsonResponse($response);
}
function handleExtensionMappingsRequest() {
$type = $_GET['type'] ?? 'all';
$extensionMappings = loadExtensionMappings();
if ($extensionMappings === null) {
errorResponse('Extension mappings not found or invalid', 404);
}
$response = [
'success' => true
];
switch ($type) {
case 'indexing':
$response['mappings'] = $extensionMappings['indexing'];
$response['count'] = count($extensionMappings['indexing']);
break;
case 'viewing':
$response['mappings'] = $extensionMappings['viewing'];
$response['count'] = count($extensionMappings['viewing']);
break;
case 'all':
default:
$response['mappings'] = $extensionMappings;
$response['indexing_count'] = count($extensionMappings['indexing']);
$response['viewing_count'] = count($extensionMappings['viewing']);
break;
}
logRequest('extensionMappings', ['type' => $type]);
header('Cache-Control: public, max-age=86400');
jsonResponse($response);
}
function handleGetExtensionSettingRequest() {
$extension = $_GET['extension'] ?? '';
$type = $_GET['type'] ?? 'indexing';
if (empty($extension)) {
errorResponse('Extension parameter is required');
}
$extensionMappings = loadExtensionMappings();
if ($extensionMappings === null) {
errorResponse('Extension mappings not found or invalid', 404);
}
$extension = strtolower($extension);
$setting = null;
if ($type === 'indexing' && isset($extensionMappings['indexing'][$extension])) {
$setting = $extensionMappings['indexing'][$extension];
} elseif ($type === 'viewing' && isset($extensionMappings['viewing'][$extension])) {
$setting = $extensionMappings['viewing'][$extension];
}
logRequest('getExtensionSetting', ['extension' => $extension, 'type' => $type]);
header('Cache-Control: public, max-age=86400');
jsonResponse([
'success' => true,
'extension' => $extension,
'type' => $type,
'setting' => $setting,
'found' => $setting !== null
]);
}
function handleFindIconRequest() {
$type = $_GET['type'] ?? 'file';
$extension = $_GET['extension'] ?? '';
if (empty($extension) && $type !== 'folder') {
errorResponse('Extension parameter is required for file types');
}
$iconInfo = findIconForType($type, $extension);
if ($iconInfo === null) {
errorResponse('Icon not found', 404);
}
logRequest('findIcon', ['type' => $type, 'extension' => $extension]);
header('Cache-Control: public, max-age=86400');
jsonResponse([
'success' => true,
'type' => $type,
'extension' => $extension,
'icon' => $iconInfo
]);
}
function handleIconMappingsRequest() {
$iconMappings = loadIconMappings();
if (empty($iconMappings)) {
errorResponse('Icon mappings not found or invalid', 404);
}
logRequest('iconMappings');
header('Cache-Control: public, max-age=86400');
jsonResponse([
'success' => true,
'mappings' => $iconMappings,
'count' => count($iconMappings)
]);
}
function handleConfigRequest() {
global $configFile;
if (!file_exists($configFile)) {
errorResponse('Configuration file not found', 404);
}
$configData = file_get_contents($configFile);
$config = json_decode($configData, true);
if ($config === null) {
errorResponse('Invalid configuration file', 500);
}
logRequest('config');
header('Cache-Control: public, max-age=3600');
jsonResponse([
'success' => true,
'config' => $config,
'version' => '1.1.12',
'last_modified' => filemtime($configFile)
]);
}
function handleIconsRequest() {
global $iconsDir;
if (!is_dir($iconsDir)) {
errorResponse('Icons directory not found', 404);
}
$icons = [];
$files = scandir($iconsDir);
foreach ($files as $file) {
if ($file === '.' || $file === '..') continue;
$filePath = $iconsDir . '/' . $file;
if (is_file($filePath) && preg_match('/\.(png|jpg|jpeg|gif|svg|webp)$/i', $file)) {
$icons[] = [
'filename' => $file,
'url' => 'https://api.indexer.ccls.icu/icons/' . $file,
'size' => filesize($filePath),
'last_modified' => filemtime($filePath)
];
}
}
logRequest('icons');
header('Cache-Control: public, max-age=86400');
jsonResponse([
'success' => true,
'icons' => $icons,
'count' => count($icons)
]);
}
function handleSingleIconRequest() {
global $iconsDir;
$iconName = $_GET['name'] ?? '';
if (empty($iconName)) {
errorResponse('Icon name not specified');
}
$iconName = basename($iconName);
if (!preg_match('/\.(png|jpg|jpeg|gif|svg|webp)$/i', $iconName)) {
errorResponse('Invalid icon file type');
}
$iconPath = $iconsDir . '/' . $iconName;
if (!file_exists($iconPath)) {
errorResponse('Icon not found', 404);
}
logRequest('icon', ['name' => $iconName]);
jsonResponse([
'success' => true,
'icon' => [
'filename' => $iconName,
'url' => 'https://api.indexer.ccls.icu/icons/' . $iconName,
'size' => filesize($iconPath),
'last_modified' => filemtime($iconPath)
]
]);
}
function handleStatusRequest() {
global $configFile, $iconsDir, $iconsMappingFile, $extensionMapFile;
$status = [
'success' => true,
'service' => 'Indexer API',
'version' => '1.1.12',
'timestamp' => date('Y-m-d H:i:s'),
'config_exists' => file_exists($configFile),
'icons_dir_exists' => is_dir($iconsDir),
'icon_mappings_exists' => file_exists($iconsMappingFile),
'extension_mappings_exists' => file_exists($extensionMapFile),
'icon_count' => 0,
'mapping_count' => 0,
'extension_mapping_count' => 0
];
if (is_dir($iconsDir)) {
$files = glob($iconsDir . '/*.{png,jpg,jpeg,gif,svg,webp}', GLOB_BRACE);
$status['icon_count'] = count($files);
}
if (file_exists($configFile)) {
$status['config_last_modified'] = filemtime($configFile);
}
if (file_exists($iconsMappingFile)) {
$status['mappings_last_modified'] = filemtime($iconsMappingFile);
$mappings = loadIconMappings();
$status['mapping_count'] = count($mappings);
}
if (file_exists($extensionMapFile)) {
$status['extension_mappings_last_modified'] = filemtime($extensionMapFile);
$extensionMappings = loadExtensionMappings();
if ($extensionMappings !== null) {
$status['extension_mapping_count'] = count($extensionMappings['indexing']) + count($extensionMappings['viewing']);
}
}
logRequest('status');
jsonResponse($status);
}
function handleConfigReferenceRequest() {
$referenceFile = __DIR__ . '/config-reference.txt';
if (!file_exists($referenceFile)) {
errorResponse('Configuration reference not found', 404);
}
$content = file_get_contents($referenceFile);
$lastModified = filemtime($referenceFile);
logRequest('configReference');
header('Cache-Control: public, max-age=86400');
jsonResponse([
'success' => true,
'content' => $content,
'last_modified' => $lastModified,
'version' => '1.1.12',
'format' => 'text'
]);
}
function handleDefaultRequest() {
$info = [
'success' => true,
'service' => 'Indexer API',
'version' => '1.1.12',
'description' => 'API for the custom indexer project',
'endpoints' => [
'versionCheck' => [
'url' => '?action=versionCheck¤t_version={version}',
'description' => 'Check if a config update is available',
'method' => 'GET'
],
'config' => [
'url' => '?action=config',
'description' => 'Get configuration file',
'method' => 'GET'
],
'icons' => [
'url' => '?action=icons',
'description' => 'List all available icons',
'method' => 'GET'
],
'icon' => [
'url' => '?action=icon&name={filename}',
'description' => 'Get information about a specific icon',
'method' => 'GET'
],
'findIcon' => [
'url' => '?action=findIcon&type={file|folder}&extension={ext}',
'description' => 'Find the appropriate icon for a file type or folder',
'method' => 'GET'
],
'iconMappings' => [
'url' => '?action=iconMappings',
'description' => 'Get all icon mappings from icons.json',
'method' => 'GET'
],
'extensionMappings' => [
'url' => '?action=extensionMappings&type={all|indexing|viewing}',
'description' => 'Get extension mappings for indexing or viewing',
'method' => 'GET'
],
'getExtensionSetting' => [
'url' => '?action=getExtensionSetting&extension={ext}&type={indexing|viewing}',
'description' => 'Get the configuration setting for a specific file extension',
'method' => 'GET'
],
'configReference' => [
'url' => '?action=configReference',
'description' => 'Get configuration reference documentation',
'method' => 'GET'
],
'status' => [
'url' => '?action=status',
'description' => 'Get API status and health information',
'method' => 'GET'
]
],
'icon_base_url' => 'https://api.indexer.ccls.icu/icons/',
'timestamp' => date('Y-m-d H:i:s')
];
logRequest('info');
jsonResponse($info);
}
?>