02794e565e
A tool for authoring, sharing, and curating social protocols. Features: - Protocol library with search, tag filtering, and sort by date/relevance - Protocol authoring with structured fields (title, description, steps, outcome, practice, source, tags) - Protocol forking with provenance tracking - Collection creation with searchable protocol picker and ordering - User accounts with roles (admin, member, viewer) - YAML import/export for portability - Self-hostable on LAMP/Cloudron, works in subdirectories - Responsive design with hamburger menu on mobile - About page Security: - CSRF protection via Origin/Referer validation - Session regeneration on login/register - Secure session cookie params (HttpOnly, SameSite, Secure) - Visibility enforcement on private/unlisted items - YAML object injection hardening - Login rate limiting - Path traversal protection - Input validation and length clamping - Vote value constraining Stack: PHP 8.x + MySQL/MariaDB, vanilla JS frontend, no external dependencies. Hippocratic License (HL3-CORE).
51 lines
1.5 KiB
PHP
Executable File
51 lines
1.5 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Config helpers — read/write site configuration from the config table.
|
|
*/
|
|
|
|
function config_get(string $key, $default = null) {
|
|
$row = db_one("SELECT value FROM config WHERE `key` = ?", [$key]);
|
|
return $row ? $row['value'] : $default;
|
|
}
|
|
|
|
function config_set(string $key, string $value): void {
|
|
db_query(
|
|
"INSERT INTO config (`key`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)",
|
|
[$key, $value]
|
|
);
|
|
}
|
|
|
|
function config_all(): array {
|
|
$rows = db_all("SELECT `key`, `value` FROM config");
|
|
$cfg = [];
|
|
foreach ($rows as $row) {
|
|
$cfg[$row['key']] = $row['value'];
|
|
}
|
|
return $cfg;
|
|
}
|
|
|
|
function site_config(): array {
|
|
return [
|
|
'name' => config_get('site_name', 'Protocol Droid'),
|
|
'tagline' => config_get('site_tagline', 'A commons of social protocols'),
|
|
'registration_enabled' => config_get('registration_enabled', 'true') === 'true',
|
|
'require_approval' => config_get('require_approval', 'false') === 'true',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Load a config.yaml file if present (for whitelabel customization).
|
|
* Merges with database config (database takes precedence).
|
|
*/
|
|
function load_yaml_config(): array {
|
|
$path = __DIR__ . '/../config.yaml';
|
|
if (!file_exists($path)) return [];
|
|
$yaml_text = file_get_contents($path);
|
|
return yaml_parse($yaml_text) ?: [];
|
|
}
|
|
|
|
function merged_config(): array {
|
|
$yaml_cfg = load_yaml_config();
|
|
$db_cfg = site_config();
|
|
return array_merge($yaml_cfg, $db_cfg);
|
|
} |