Repository navigation
Expand file tree
/
Copy patheditor.php
More file actions
75 lines (63 loc) · 1.95 KB
/
Copy patheditor.php
File metadata and controls
75 lines (63 loc) · 1.95 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
<?php declare(strict_types=1);
/**
* The core of a configuration editor: list the options of a file as the fields of a form, apply what the user
* changed, and save a file whose diff is exactly those changes.
*
* Usage: php examples/config-editor/editor.php
*/
use Nette\Neon\Neon;
use Nette\Neon\Nodes\ArrayNode;
use Nette\Neon\Nodes\DocumentNode;
require __DIR__ . '/../bootstrap.php';
$file = sample('
# Application settings
# (edited by hand and by the admin panel)
mail:
host: smtp.example.com # outgoing server
port: 587
secure: yes
cache:
enabled: true
ttl: 3600 # seconds
paths: [temp/cache]
');
$doc = Neon::parse($file);
// 1. the fields of the form: every scalar with its path, its type and its comment
function fields(DocumentNode $document): array
{
$res = [];
$walk = function (mixed $node, array $path) use (&$walk, &$res) {
if (!$node instanceof ArrayNode) {
return;
}
foreach ($node->items as $i => $item) {
$itemPath = [...$path, $item->getKeyValue() ?? $i];
if ($item->value instanceof ArrayNode) {
$walk($item->value, $itemPath);
} else {
$comment = implode(' ', array_map(fn($c) => $c->getCommentText(), $item->getTrailingComments()));
$res[] = ['path' => $itemPath, 'value' => $item->getValue(), 'comment' => $comment];
}
}
};
$walk($document->value, []);
return $res;
}
foreach (fields($doc) as $field) {
echo rtrim(sprintf('%-14s %-8s %-18s %s', implode('.', $field['path']), get_debug_type($field['value']), var_export($field['value'], true), $field['comment'])), "\n";
}
// 2. what the user submitted: all fields, most of them unchanged
$submitted = [
'mail.host' => 'smtp.example.com',
'mail.port' => 465,
'mail.secure' => true,
'cache.enabled' => false,
'cache.ttl' => 3600,
'cache.paths.0' => 'temp/cache',
];
foreach ($submitted as $key => $value) {
$doc->setValue(explode('.', $key), $value);
}
// 3. save: only what changed is in the diff
echo "\n";
printDiff($file, $doc->print());