1<?php
2/**
3 * Title: Plugin settings
4 * Icon: fa-sliders
5 * Group: Settings
6 * Order: 21
7 * Description: Auto-generated configuration page for a plugin's settings.json.
8 * Hidden: true
9 */
10
11/*
12 * Not linked from the sidebar - reached from the "Settings" button on a
13 * plugin's row in Admin Panel > Plugins. A plugin gets this page for free by
14 * shipping plugins/<name>/settings.json instead of hand-coding a form; see
15 * engine/function/plugin_settings.php for the schema.
16 */
17
18if (!defined('ACP_ROOT')) {
19 http_response_code(403);
20 die('Direct access denied.');
21}
22
23$plugin = znote_plugin_sanitize((string)($_GET['plugin'] ?? $_POST['plugin'] ?? ''));
24$known = znote_plugins();
25
26if ($plugin === '' || !isset($known[$plugin]) || !znote_plugin_settings_has($plugin)) {
27 acp_flash_error(t_default('acp.plgset.no_such', 'That plugin has no settings.json.'));
28 acp_redirect('plugins');
29}
30
31$manifest = $known[$plugin];
32$schema = znote_plugin_settings_schema($plugin);
33
34if ($_SERVER['REQUEST_METHOD'] === 'POST') {
35 if (!acp_verify_csrf()) {
36 acp_flash_error(t_default('acp.csrf_failed', 'Your session expired, please try again.'));
37 acp_redirect('plugin_settings', array('plugin' => $plugin));
38 }
39
40 $errors = znote_plugin_settings_save($plugin, $_POST);
41
42 if ($errors) {
43 acp_flash_error(t_default('acp.plgset.save_failed', 'Some fields were not valid and kept their previous value: {fields}.', ['fields' => implode(', ', $errors)]));
44 } else {
45 acp_log('plugin.settings_save', $plugin);
46 acp_flash_success(t_default('acp.plgset.saved', 'Settings saved.'));
47 }
48
49 acp_redirect('plugin_settings', array('plugin' => $plugin));
50}
51
52$values = znote_plugin_settings_get($plugin);
53?>
54
55<?php acp_card_open(t_default('acp.plgset.title', '{plugin} settings', ['plugin' => h($manifest['name'])]), h($manifest['description'])); ?>
56
57 <form method="post">
58 <?= acp_csrf_field() ?>
59 <input type="hidden" name="plugin" value="<?= h($plugin) ?>">
60
61 <?php if (!$schema): ?>
62 <?php acp_empty(t_default('acp.plgset.empty', 'settings.json has no valid fields.'), 'fa-sliders'); ?>
63 <?php endif; ?>
64
65 <?php foreach ($schema as $key => $field):
66 $value = $values[$key] ?? $field['default'];
67 $id = 'plgset_' . $key;
68 ?>
69 <div class="acp-field">
70 <label for="<?= h($id) ?>"><?= h($field['label']) ?></label>
71
72 <?php if ($field['type'] === 'bool'): ?>
73 <label class="acp-inline">
74 <input type="checkbox" id="<?= h($id) ?>" name="<?= h($key) ?>" value="1" <?= $value === '1' ? 'checked' : '' ?>>
75 </label>
76
77 <?php elseif ($field['type'] === 'textarea'): ?>
78 <textarea id="<?= h($id) ?>" name="<?= h($key) ?>" rows="4" class="acp-input"><?= h($value) ?></textarea>
79
80 <?php elseif ($field['type'] === 'password'): ?>
81 <input type="password" id="<?= h($id) ?>" name="<?= h($key) ?>" value="<?= h($value) ?>" class="acp-input" autocomplete="off">
82
83 <?php elseif ($field['type'] === 'int'): ?>
84 <input type="number" id="<?= h($id) ?>" name="<?= h($key) ?>" value="<?= h($value) ?>" class="acp-input"
85 <?= $field['min'] !== null ? 'min="' . (int)$field['min'] . '"' : '' ?>
86 <?= $field['max'] !== null ? 'max="' . (int)$field['max'] . '"' : '' ?>>
87
88 <?php elseif ($field['type'] === 'select'): ?>
89 <select id="<?= h($id) ?>" name="<?= h($key) ?>" class="acp-input">
90 <?php foreach ($field['options'] as $optValue => $optLabel): ?>
91 <option value="<?= h($optValue) ?>" <?= $value === $optValue ? 'selected' : '' ?>><?= h($optLabel) ?></option>
92 <?php endforeach; ?>
93 </select>
94
95 <?php elseif ($field['type'] === 'color'): ?>
96 <div class="acp-inline" style="gap:8px;">
97 <input type="color" value="<?= h($value !== '' ? $value : '#000000') ?>"
98 onchange="document.getElementById('<?= h($id) ?>').value=this.value;">
99 <input type="text" id="<?= h($id) ?>" name="<?= h($key) ?>" value="<?= h($value) ?>" class="acp-input"
100 placeholder="<?= h(t_default('acp.plgset.color_placeholder', 'blank = theme default')) ?>" maxlength="7" style="max-width:110px;">
101 </div>
102
103 <?php elseif ($field['type'] === 'checklist'):
104 $chosen = array_flip(array_filter(explode(',', $value)));
105 ?>
106 <?php foreach ($field['options'] as $optValue => $optLabel): ?>
107 <label class="acp-inline">
108 <input type="checkbox" name="<?= h($key) ?>[]" value="<?= h($optValue) ?>" <?= isset($chosen[$optValue]) ? 'checked' : '' ?>>
109 <?= h($optLabel) ?>
110 </label>
111 <?php endforeach; ?>
112
113 <?php else: ?>
114 <input type="text" id="<?= h($id) ?>" name="<?= h($key) ?>" value="<?= h($value) ?>" class="acp-input">
115 <?php endif; ?>
116
117 <?php if ($field['help'] !== ''): ?>
118 <p class="acp-hint"><?= h($field['help']) ?></p>
119 <?php endif; ?>
120 </div>
121 <?php endforeach; ?>
122
123 <?php if ($schema): ?>
124 <button type="submit" class="acp-btn acp-btn--green"><?= t_default('acp.plgset.save', 'Save') ?></button>
125 <?php endif; ?>
126 </form>
127
128<?php acp_card_close(); ?>
129