Skip to content

Commit abfcfa2

Browse files
committed
Allow to edit stream keys
1 parent 227ccd4 commit abfcfa2

File tree

6 files changed

+130
-140
lines changed

6 files changed

+130
-140
lines changed

src/Admin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use RobiNN\Pca\Dashboards\DashboardInterface;
1212

1313
class Admin {
14-
public const VERSION = '2.2.3';
14+
public const VERSION = '2.2.4';
1515

1616
/**
1717
* @var array<string, DashboardInterface>

src/Dashboards/Redis/RedisTrait.php

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -331,29 +331,21 @@ public function saveKey(): void {
331331
$key = Http::post('key', '');
332332
$value = Value::converter(Http::post('value', ''), Http::post('encoder', ''), 'save');
333333
$old_value = Http::post('old_value', '');
334-
$type = Http::post('redis_type', '');
334+
$type = Http::post('rtype', '');
335335
$old_key = Http::post('old_key', '');
336336

337337
if ($old_key !== '' && $old_key !== $key) { // @phpstan-ignore-line
338338
$this->redis->rename($old_key, $key);
339339
}
340340

341341
$this->store($type, $key, $value, $old_value, [
342-
'list_index' => $_POST['index'] ?? '',
343-
'zset_score' => Http::post('score', 0),
344-
'hash_key' => Http::post('hash_key', ''),
345-
'stream_id' => Http::post('stream_id', '*'),
346-
'stream_field' => Http::post('field', ''),
342+
'list_index' => $_POST['index'] ?? '',
343+
'zset_score' => Http::post('score', 0),
344+
'hash_key' => Http::post('hash_key', ''),
345+
'stream_id' => Http::post('stream_id', '*'),
346+
'ttl' => Http::post('expire', 0),
347347
]);
348348

349-
$expire = Http::post('expire', 0);
350-
351-
if ($expire === -1) {
352-
$this->redis->persist($key);
353-
} else {
354-
$this->redis->expire($key, $expire);
355-
}
356-
357349
Http::redirect([], ['view' => 'key', 'key' => $key]);
358350
}
359351

@@ -364,13 +356,14 @@ public function saveKey(): void {
364356
*/
365357
private function form(): string {
366358
$key = (string) Http::get('key', Http::post('key', ''));
367-
$type = Http::post('redis_type', 'string');
359+
$type = Http::post('rtype', 'string');
368360
$index = $_POST['index'] ?? '';
369361
$score = Http::post('score', 0);
370362
$hash_key = Http::post('hash_key', '');
371363
$expire = Http::post('expire', -1);
372364
$encoder = Http::get('encoder', 'none');
373365
$value = Http::post('value', '');
366+
$stream_id = Http::post('stream_id', '*');
374367

375368
if (isset($_POST['submit'])) {
376369
$this->saveKey();
@@ -395,16 +388,17 @@ private function form(): string {
395388
$value = Value::converter($value, $encoder, 'view');
396389

397390
return $this->template->render('dashboards/redis/form', [
398-
'key' => $key,
399-
'value' => $value,
400-
'types' => $this->getAllTypes(),
401-
'type' => $type,
402-
'index' => $index,
403-
'score' => $score,
404-
'hash_key' => $hash_key,
405-
'expire' => $expire,
406-
'encoders' => Config::getEncoders(),
407-
'encoder' => $encoder,
391+
'key' => $key,
392+
'value' => $value,
393+
'types' => $this->getAllTypes(),
394+
'type' => $type,
395+
'index' => $index,
396+
'score' => $score,
397+
'hash_key' => $hash_key,
398+
'expire' => $expire,
399+
'encoders' => Config::getEncoders(),
400+
'encoder' => $encoder,
401+
'stream_id' => $stream_id,
408402
]);
409403
}
410404

src/Dashboards/Redis/RedisTypes.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ trait RedisTypes {
2424
*/
2525
public function getAllTypes(): array {
2626
static $types = [];
27-
28-
$exclude = ['none', 'other', 'stream'];
27+
$exclude = ['none', 'other'];
2928

3029
if (!$this->redis->checkModule('ReJSON')) {
3130
$exclude[] = 'rejson';
@@ -51,7 +50,6 @@ private function typesTplOptions(): array {
5150
return [
5251
'extra' => [
5352
'hide_title' => ['set'],
54-
'hide_edit' => ['stream'],
5553
],
5654
'set' => ['param' => 'member', 'title' => ''],
5755
'list' => ['param' => 'index', 'title' => 'Index'],
@@ -101,7 +99,8 @@ private function getKeyValue(string $type, string $key): array {
10199
break;
102100
case 'stream':
103101
$ranges = $this->redis->xRange($key, '-', '+');
104-
$value = $ranges[Http::get('stream_id', '')];
102+
$value = $ranges[Http::get('stream_id', '')] ?? [];
103+
$value = json_encode($value, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
105104
break;
106105
case 'rejson':
107106
$value = $this->redis->jsonGet($key);
@@ -118,7 +117,7 @@ private function getKeyValue(string $type, string $key): array {
118117
*
119118
* Used in view page.
120119
*
121-
* @return array<int, mixed>|string
120+
* @return string|array<int|string, string>
122121
*
123122
* @throws Exception
124123
*/
@@ -177,10 +176,24 @@ public function store(string $type, string $key, string $value, string $old_valu
177176
$this->redis->zAdd($key, $options['zset_score'], $value);
178177
break;
179178
case 'hash':
179+
if ($this->redis->hExists($key, Http::get('hash_key', ''))) {
180+
$this->redis->hDel($key, Http::get('hash_key', ''));
181+
}
182+
180183
$this->redis->hSet($key, $options['hash_key'], $value);
181184
break;
182185
case 'stream':
183-
$this->redis->streamAdd($key, $options['stream_id'], $options['stream_fields'] ?? [$options['stream_field'] => $value]);
186+
if (Http::get('stream_id', '') !== '') {
187+
$this->redis->xDel($key, [Http::get('stream_id', '')]);
188+
}
189+
190+
$fields = [$value];
191+
192+
if (json_validate($value)) {
193+
$fields = json_decode($value, true, 512, JSON_THROW_ON_ERROR);
194+
}
195+
196+
$this->redis->streamAdd($key, $options['stream_id'], $fields);
184197
break;
185198
case 'rejson':
186199
$this->redis->jsonSet($key, $value);

templates/dashboards/redis/form.twig

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<input type="hidden" name="old_value" value="{{ value }}">
44

55
{{ include('components/select.twig', {
6-
id: 'redis_type',
6+
id: 'rtype',
77
label: 'Type',
88
options: types,
99
class: 'w-full',
@@ -32,7 +32,7 @@
3232
id: 'index',
3333
label: 'List Index',
3434
type: 'number',
35-
extra_attr: ' style="display: ' ~ (type == 'list' ? 'show' : 'none') ~ ';" id="redis_index"',
35+
extra_attr: ' style="display: ' ~ (type == 'list' ? 'block' : 'none') ~ ';" id="redis_index"',
3636
help: 'Empty to append, -1 to prepend.',
3737
value: index,
3838
}) }}
@@ -41,17 +41,25 @@
4141
id: 'score',
4242
label: 'Zset Score',
4343
type: 'number',
44-
extra_attr: ' style="display: ' ~ (type == 'zset' ? 'show' : 'none') ~ ';" id="redis_score"',
44+
extra_attr: ' style="display: ' ~ (type == 'zset' ? 'block' : 'none') ~ ';" id="redis_score"',
4545
value: score,
4646
}) }}
4747

4848
{{ include('components/input.twig', {
4949
id: 'hash_key',
5050
label: 'Hash Key',
51-
extra_attr: ' style="display: ' ~ (type == 'hash' ? 'show' : 'none') ~ ';" id="redis_hash_key"',
51+
extra_attr: ' style="display: ' ~ (type == 'hash' ? 'block' : 'none') ~ ';" id="redis_hash_key"',
5252
value: hash_key,
5353
}) }}
5454

55+
{{ include('components/input.twig', {
56+
id: 'stream_id',
57+
label: 'Stream Entry ID',
58+
extra_attr: ' style="display: ' ~ (type == 'stream' ? 'block' : 'none') ~ ';" id="redis_stream_id"',
59+
help: 'Use * to let Redis generate the ID.',
60+
value: stream_id,
61+
}) }}
62+
5563
{% if encoders %}
5664
{{ include('components/select.twig', {
5765
id: 'encoder',
@@ -78,11 +86,12 @@
7886
</form>
7987

8088
<script>
81-
document.getElementById('redis_type').addEventListener('change', e => {
89+
document.getElementById('rtype').addEventListener('change', e => {
8290
document.getElementById('redis_index').style.display = e.target.value === 'list' ? 'block' : 'none';
8391
document.getElementById('redis_score').style.display = e.target.value === 'zset' ? 'block' : 'none';
8492
document.getElementById('score').required = e.target.value === 'zset';
8593
document.getElementById('redis_hash_key').style.display = e.target.value === 'hash' ? 'block' : 'none';
8694
document.getElementById('hash_key').required = e.target.value === 'hash';
95+
document.getElementById('redis_stream_id').style.display = e.target.value === 'stream' ? 'block' : 'none';
8796
});
8897
</script>

templates/partials/view_key_array.twig

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
{% if type not in types.extra.hide_edit %}
2-
{{ include('components/button.twig', {
3-
text: 'Add another value',
4-
icon: 'plus',
5-
link: add_subkey_url,
6-
btn_green: true,
7-
class: 'mb-4',
8-
}) }}
9-
{% endif %}
1+
{{ include('components/button.twig', {
2+
text: 'Add another value',
3+
icon: 'plus',
4+
link: add_subkey_url,
5+
btn_green: true,
6+
class: 'mb-4',
7+
}) }}
108

119
{% for item in value %}
1210
<div class="mb-4 rounded-sm bg-white border border-gray-200 dark:bg-gray-800 dark:border-gray-700">
@@ -31,11 +29,9 @@
3129
</span>
3230

3331
<div>
34-
{% if type not in types.extra.hide_edit %}
35-
<a href="{{ edit_url }}&{{ types[type].param }}={{ item.key ~ item_encode_url }}" class="text-gray-500 hover:text-gray-700 font-semibold inline-flex items-center gap-1 mr-3 dark:text-gray-400 dark:hover:text-gray-300">
36-
{{ svg('edit', 16) }} Edit
37-
</a>
38-
{% endif %}
32+
<a href="{{ edit_url }}&{{ types[type].param }}={{ item.key ~ item_encode_url }}" class="text-gray-500 hover:text-gray-700 font-semibold inline-flex items-center gap-1 mr-3 dark:text-gray-400 dark:hover:text-gray-300">
33+
{{ svg('edit', 16) }} Edit
34+
</a>
3935
<a href="{{ deletesub_url }}&{{ types[type].param }}={{ item.key }}" class="text-red-500 hover:text-red-700 font-semibold inline-flex items-center gap-1 dark:text-red-400 dark:hover:text-red-300"
4036
onclick="return confirm('Are you sure you want to remove this item?');">
4137
{{ svg('trash', 16) }} Delete

0 commit comments

Comments
 (0)