1: | <?php declare(strict_types=1); |
2: | |
3: | use Opcenter\Admin\Bootstrapper\Config; |
4: | use Opcenter\Admin\Settings\Setting; |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | class Scope_Module extends Module_Skeleton |
18: | { |
19: | const SCOPE_CACHE_KEY = 'admin.syscfg'; |
20: | protected $exportedFunctions = [ |
21: | '*' => PRIVILEGE_ADMIN |
22: | ]; |
23: | |
24: | public function __construct() |
25: | { |
26: | parent::__construct(); |
27: | if (!AUTH_ADMIN_API) { |
28: | $this->exportedFunctions = ['*' => PRIVILEGE_NONE]; |
29: | } |
30: | } |
31: | |
32: | |
33: | |
34: | |
35: | |
36: | |
37: | |
38: | |
39: | public function set(string $name, ...$val): bool |
40: | { |
41: | if (DEMO_ADMIN_LOCK && posix_getuid()) { |
42: | return error("Scopes may not be set in demo mode"); |
43: | } |
44: | |
45: | if (!IS_CLI && posix_getuid()) { |
46: | if ($name === 'cp.restart') { |
47: | |
48: | |
49: | |
50: | |
51: | DataStream::get($this->getAuthContext())-> |
52: | setOption(\apnscpObject::NO_WAIT)->query('scope_set', $name, ...$val); |
53: | return success('Panel restarting now. Service will be briefly interrupted.'); |
54: | } |
55: | return $this->query('scope_set', $name, ...$val); |
56: | } |
57: | $c = Setting::className($name); |
58: | if (!$c) { |
59: | return $this->suggest($name); |
60: | } |
61: | if (!\array_key_exists(0, $val)) { |
62: | return error("`scope_set %s' requires one or more values. See `scope_info %s' for more information", |
63: | $name, |
64: | $name |
65: | ); |
66: | } |
67: | |
68: | return (new $c)->set(...$val); |
69: | } |
70: | |
71: | |
72: | |
73: | |
74: | |
75: | |
76: | |
77: | |
78: | |
79: | public function l(string $filter = ''): array |
80: | { |
81: | return $this->list($filter); |
82: | } |
83: | |
84: | |
85: | |
86: | |
87: | |
88: | |
89: | |
90: | public function list(string $filter = ''): array |
91: | { |
92: | $cache = Cache_Global::spawn(); |
93: | $filter = str_replace(':', '.', $filter); |
94: | |
95: | if (is_debug() || false === ($c = $cache->get(self::SCOPE_CACHE_KEY))) { |
96: | $c = Opcenter\Admin\Settings\Setting::list(); |
97: | asort($c); |
98: | $c = array_values($c); |
99: | $cache->set(self::SCOPE_CACHE_KEY, $c); |
100: | } |
101: | |
102: | return !$filter ? $c : array_values(array_filter($c, static function ($scope) use ($filter) { |
103: | return fnmatch($filter, $scope); |
104: | })); |
105: | } |
106: | |
107: | |
108: | |
109: | |
110: | |
111: | |
112: | |
113: | |
114: | public function i(string $name): ?array |
115: | { |
116: | return $this->info($name); |
117: | } |
118: | |
119: | |
120: | |
121: | |
122: | |
123: | |
124: | |
125: | public function info(string $name): ?array |
126: | { |
127: | if (!IS_CLI && posix_getuid()) { |
128: | return $this->query('scope_info', $name); |
129: | } |
130: | $c = Setting::className($name); |
131: | if (!$c) { |
132: | return null; |
133: | } |
134: | $class = new $c; |
135: | |
136: | return [ |
137: | 'info' => $class->getHelp(), |
138: | 'value' => $class->get(), |
139: | 'settings' => $class->getValues(), |
140: | 'default' => $class->getDefault() |
141: | ]; |
142: | } |
143: | |
144: | |
145: | |
146: | |
147: | |
148: | |
149: | |
150: | |
151: | public function get(string $name, ...$val) |
152: | { |
153: | if (!IS_CLI && posix_getuid()) { |
154: | return $this->query('scope_get', $name, ...$val); |
155: | } |
156: | $c = Setting::className($name); |
157: | if (!$c) { |
158: | return $this->suggest($name); |
159: | } |
160: | |
161: | return (new $c)->get(...$val); |
162: | } |
163: | |
164: | |
165: | |
166: | |
167: | |
168: | |
169: | |
170: | |
171: | public function diff(?string $role = null, string $pattern = "*"): array |
172: | { |
173: | $cfg = new Config(); |
174: | |
175: | $userConfiguration = $cfg->toArray(); |
176: | |
177: | if ($role && !$cfg->exists($role)) { |
178: | error("Role %s does not exist", $role); |
179: | return []; |
180: | } |
181: | |
182: | $defaults = $role ? $cfg->loadRole($role) : $userConfiguration; |
183: | |
184: | $filtered = !$pattern ? $defaults : array_filter($defaults, static function ($var) use ($pattern) { |
185: | return fnmatch($pattern, $var); |
186: | }, ARRAY_FILTER_USE_KEY); |
187: | |
188: | return array_intersect_key($userConfiguration, $filtered); |
189: | } |
190: | |
191: | private function suggest(string $name): bool |
192: | { |
193: | $max = [99999, $name]; |
194: | foreach ($this->list() as $scope) { |
195: | $score = levenshtein($name, $scope, 1, 2, 1); |
196: | if ($score < $max[0]) { |
197: | $max = [$score, $scope]; |
198: | } |
199: | } |
200: | |
201: | return error("Scope `%(target)s' does not exist. Did you mean `%(suggest)s'?", [ |
202: | 'target' => $name, |
203: | 'suggest' => $max[1] |
204: | ]); |
205: | } |
206: | |
207: | public function _housekeeping() |
208: | { |
209: | Cache_Global::spawn()->delete(self::SCOPE_CACHE_KEY); |
210: | } |
211: | } |
212: | |