forked from NoahY/q2a-network
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathqa-network-apply.php
More file actions
131 lines (111 loc) · 3.58 KB
/
qa-network-apply.php
File metadata and controls
131 lines (111 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
if (!defined('QA_VERSION')) {
header('Location: ../../');
exit;
}
class qa_network_apply_page
{
/**
* Apply key-value pairs to a table across all network sites.
* @param array $options Associative array of name => value pairs
* @param string $table_suffix Table name without prefix (default: 'options')
* @param string $key_col Column name for the key (default: 'title')
* @param string $val_col Column name for the value (default: 'content')
* @return array Results per site
*/
static function apply_to_network($options, $table_suffix = 'options', $key_col = 'title', $val_col = 'content')
{
// Validate column names: alphanumeric and underscores only
if (!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $key_col) ||
!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $val_col) ||
!preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $table_suffix)) {
return array('error' => 'Invalid table or column name');
}
// Gather network site prefixes
$prefixes = array();
$idx = 0;
while (qa_opt('network_site_' . $idx . '_url')) {
$prefix = qa_opt('network_site_' . $idx . '_prefix');
$title = qa_opt('network_site_' . $idx . '_title');
if (strlen($prefix)) {
$prefixes[] = array('prefix' => $prefix, 'title' => $title);
}
$idx++;
}
if (empty($prefixes)) {
return array('error' => 'No network sites configured');
}
$results = array();
foreach ($prefixes as $site) {
$table = $site['prefix'] . $table_suffix;
$applied = 0;
$errors = array();
foreach ($options as $name => $value) {
// Validate option name: alphanumeric, hyphens, underscores only
if (!preg_match('/^[a-zA-Z0-9_\-]+$/', $name)) {
$errors[] = 'Invalid option name: ' . $name;
continue;
}
try {
qa_db_query_raw(
"INSERT INTO " . qa_db_escape_string($table) .
" (" . $key_col . ", " . $val_col . ") VALUES ('" . qa_db_escape_string($name) .
"', '" . qa_db_escape_string($value) .
"') ON DUPLICATE KEY UPDATE " . $val_col . " = VALUES(" . $val_col . ")"
);
$applied++;
} catch (Exception $e) {
$errors[] = $name . ': ' . $e->getMessage();
}
}
$results[] = array(
'site' => $site['title'],
'applied' => $applied,
'errors' => $errors,
);
}
return array('status' => 'ok', 'results' => $results);
}
function match_request($request)
{
return $request === 'network-apply-settings';
}
function process_request($request)
{
header('Content-Type: application/json; charset=utf-8');
if (!qa_is_logged_in() || qa_get_logged_in_level() < QA_USER_LEVEL_SUPER) {
echo json_encode(['error' => 'Super admin access required']);
return null;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['error' => 'POST required']);
return null;
}
$raw = qa_post_text('options');
if ($raw === null || $raw === '') {
echo json_encode(['error' => 'No options provided']);
return null;
}
$options = json_decode($raw, true);
if (!is_array($options) || empty($options)) {
echo json_encode(['error' => 'Invalid options']);
return null;
}
// Optional: custom table suffix (default: 'options')
$table_suffix = qa_post_text('table');
if ($table_suffix === null || $table_suffix === '') {
$table_suffix = 'options';
}
$key_col = qa_post_text('key_col');
if ($key_col === null || $key_col === '') {
$key_col = 'title';
}
$val_col = qa_post_text('val_col');
if ($val_col === null || $val_col === '') {
$val_col = 'content';
}
$result = self::apply_to_network($options, $table_suffix, $key_col, $val_col);
echo json_encode($result);
return null;
}
}