CatPtain commited on
Commit
6f6abdf
·
verified ·
1 Parent(s): f403506

Upload 2 files

Browse files
Files changed (2) hide show
  1. github-advanced-test.php +362 -306
  2. save.php +17 -7
github-advanced-test.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  require_once __DIR__ . '/storage.php';
3
 
4
- // 简单的测试认证
5
  $testAuth = false;
6
  if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
7
  $users = StorageConfig::getUsers();
@@ -10,97 +10,207 @@ if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
10
  }
11
 
12
  if (!$testAuth) {
13
- header('WWW-Authenticate: Basic realm="VvvebJs Advanced Test"');
14
  header('HTTP/1.0 401 Unauthorized');
15
- die('Authentication required for advanced testing');
16
  }
17
 
18
  $github = StorageConfig::getGitHubConfig();
 
 
19
 
20
- // 高级诊断功能
21
- function testGitHubAPI($token, $endpoint, $method = 'GET', $data = null) {
22
- $ch = curl_init();
23
- curl_setopt($ch, CURLOPT_URL, $endpoint);
24
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
25
- curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
26
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
27
- curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
28
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
29
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
30
-
31
- // 修复:正确设置HTTP头部,包含必需的User-Agent
32
- $headers = [
33
- 'Authorization: token ' . $token,
34
- 'User-Agent: VvvebJs-WebBuilder/1.0 (https://github.com/givanz/VvvebJs)',
35
- 'Accept: application/vnd.github.v3+json',
36
- 'X-GitHub-Api-Version: 2022-11-28'
37
- ];
38
-
39
- if ($data) {
40
- curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
41
- $headers[] = 'Content-Type: application/json';
42
- }
43
-
44
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
45
-
46
- $result = curl_exec($ch);
47
- $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
48
- $error = curl_error($ch);
49
- curl_close($ch);
50
-
51
- // 详细日志记录
52
- error_log("GitHub API Test: $method $endpoint - HTTP $httpCode");
53
- if ($error) {
54
- error_log("GitHub API Test cURL Error: $error");
55
- }
56
-
57
- return [
58
- 'success' => $httpCode >= 200 && $httpCode < 300,
59
- 'http_code' => $httpCode,
60
- 'response' => $result,
61
- 'error' => $error,
62
- 'decoded' => json_decode($result, true)
63
- ];
64
- }
65
-
66
- $diagnostics = [];
67
 
68
- if ($_POST['run_diagnostics'] ?? false) {
69
- // 测试 1: 验证 Token
70
- $diagnostics['token_test'] = testGitHubAPI($github['token'], 'https://api.github.com/user');
71
-
72
- // 测试 2: 检查仓库是否存在
73
- $repoUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}";
74
- $diagnostics['repo_test'] = testGitHubAPI($github['token'], $repoUrl);
75
-
76
- // 测试 3: 检查分支
77
- $branchUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}/branches/{$github['branch']}";
78
- $diagnostics['branch_test'] = testGitHubAPI($github['token'], $branchUrl);
79
-
80
- // 测试 4: 测试用户目录读取
81
- $userPath = StorageConfig::getUserPath();
82
- $userDirUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}/contents/{$github['path']}{$userPath}";
83
- $diagnostics['user_dir_test'] = testGitHubAPI($github['token'], $userDirUrl);
84
-
85
- // 测试 5: 测试写入权限(创建测试文件)
86
- $testFilePath = "{$github['path']}{$userPath}test-write-permission.txt";
87
- $testFileUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}/contents/{$testFilePath}";
88
- $testContent = "VvvebJs write permission test - " . date('Y-m-d H:i:s');
89
- $testData = [
90
- 'message' => 'VvvebJs write permission test',
91
- 'content' => base64_encode($testContent),
92
- 'branch' => $github['branch']
93
- ];
94
- $diagnostics['write_test'] = testGitHubAPI($github['token'], $testFileUrl, 'PUT', $testData);
95
-
96
- // 如果写入成功,立即删除测试文件
97
- if ($diagnostics['write_test']['success'] && isset($diagnostics['write_test']['decoded']['sha'])) {
98
- $deleteData = [
99
- 'message' => 'Clean up VvvebJs write permission test',
100
- 'sha' => $diagnostics['write_test']['decoded']['sha'],
101
- 'branch' => $github['branch']
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  ];
103
- $diagnostics['cleanup_test'] = testGitHubAPI($github['token'], $testFileUrl, 'DELETE', $deleteData);
104
  }
105
  }
106
  ?>
@@ -110,279 +220,225 @@ if ($_POST['run_diagnostics'] ?? false) {
110
  <head>
111
  <meta charset="utf-8">
112
  <meta name="viewport" content="width=device-width, initial-scale=1">
113
- <title>VvvebJs GitHub 高级诊断</title>
114
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
115
  <style>
116
  .config-value { background-color: #f8f9fa; padding: 2px 6px; border-radius: 3px; font-family: monospace; }
117
  .status-ok { color: #28a745; }
118
  .status-error { color: #dc3545; }
119
  .status-warning { color: #ffc107; }
120
- .test-result { margin-bottom: 20px; }
121
- .response-data { background: #f8f9fa; padding: 10px; border-radius: 5px; max-height: 200px; overflow-y: auto; font-family: monospace; font-size: 12px; }
 
 
 
 
122
  </style>
123
  </head>
124
  <body>
125
  <div class="container mt-5">
126
  <div class="row">
127
- <div class="col-md-12">
128
- <h1 class="mb-4">🔬 VvvebJs GitHub 高级诊断工具</h1>
129
 
130
- <!-- 当前配置概览 -->
131
  <div class="card mb-4">
132
  <div class="card-header">
133
- <h3>⚙️ 当前GitHub配置</h3>
134
  </div>
135
  <div class="card-body">
136
  <div class="row">
137
  <div class="col-md-6">
138
- <p><strong>Token:</strong>
 
 
 
 
 
 
 
139
  <span class="config-value <?= empty($github['token']) ? 'status-error' : 'status-ok' ?>">
140
- <?= empty($github['token']) ? '❌ 未设置' : '✅ ' . substr($github['token'], 0, 8) . '... (长度: ' . strlen($github['token']) . ')' ?>
141
  </span>
142
  </p>
143
- <p><strong>Owner:</strong> <span class="config-value"><?= htmlspecialchars($github['owner']) ?></span></p>
144
- <p><strong>Repo:</strong> <span class="config-value"><?= htmlspecialchars($github['repo']) ?></span></p>
145
- </div>
146
- <div class="col-md-6">
147
- <p><strong>Branch:</strong> <span class="config-value"><?= htmlspecialchars($github['branch']) ?></span></p>
148
- <p><strong>Path:</strong> <span class="config-value"><?= htmlspecialchars($github['path']) ?></span></p>
149
- <p><strong>User Path:</strong> <span class="config-value"><?= htmlspecialchars(StorageConfig::getUserPath()) ?></span></p>
150
  </div>
151
  </div>
152
  </div>
153
  </div>
154
 
155
- <!-- 诊断控制 -->
156
  <div class="card mb-4">
157
  <div class="card-header">
158
- <h3>🚀 开始诊断</h3>
159
  </div>
160
  <div class="card-body">
161
- <?php if (empty($diagnostics)): ?>
162
- <p>点击下方按钮开始完整的GitHub连接和权限诊断:</p>
 
 
 
 
 
 
 
 
 
 
 
 
163
  <form method="POST">
164
- <button type="submit" name="run_diagnostics" value="1" class="btn btn-primary btn-lg">
165
- 🔍 运行完整诊断
166
  </button>
167
  </form>
168
  <?php else: ?>
169
- <p>诊断完成!查看下方详细结果。</p>
170
- <form method="POST">
171
- <button type="submit" name="run_diagnostics" value="1" class="btn btn-secondary">
172
- 🔄 重新运行诊断
173
- </button>
174
- </form>
175
- <?php endif; ?>
176
- </div>
177
- </div>
178
-
179
- <!-- 诊断结果 -->
180
- <?php if (!empty($diagnostics)): ?>
181
-
182
- <!-- Token验证结果 -->
183
- <div class="card mb-4">
184
- <div class="card-header">
185
- <h3>🔐 Token验证结果</h3>
186
- </div>
187
- <div class="card-body">
188
- <?php $tokenTest = $diagnostics['token_test']; ?>
189
- <div class="alert alert-<?= $tokenTest['success'] ? 'success' : 'danger' ?>">
190
- <h5>
191
- <span class="<?= $tokenTest['success'] ? 'status-ok' : 'status-error' ?>">
192
- <?= $tokenTest['success'] ? '✅ Token有效' : '❌ Token无效' ?>
193
- </span>
194
- (HTTP <?= $tokenTest['http_code'] ?>)
195
- </h5>
196
- <?php if ($tokenTest['success'] && $tokenTest['decoded']): ?>
197
- <p><strong>GitHub用户:</strong> <?= htmlspecialchars($tokenTest['decoded']['login']) ?></p>
198
- <p><strong>用户类型:</strong> <?= htmlspecialchars($tokenTest['decoded']['type']) ?></p>
199
- <?php if (isset($tokenTest['decoded']['scopes'])): ?>
200
- <p><strong>Token权限:</strong> <?= implode(', ', $tokenTest['decoded']['scopes']) ?></p>
201
- <?php endif; ?>
202
- <?php endif; ?>
203
- </div>
204
 
205
- <?php if (!$tokenTest['success']): ?>
206
- <div class="response-data">
207
- <strong>错误响应:</strong><br>
208
- <?= htmlspecialchars($tokenTest['response']) ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  </div>
210
  <?php endif; ?>
211
- </div>
212
- </div>
213
 
214
- <!-- 仓库访问结果 -->
215
- <div class="card mb-4">
216
- <div class="card-header">
217
- <h3>📁 仓库访问结果</h3>
218
- </div>
219
- <div class="card-body">
220
- <?php $repoTest = $diagnostics['repo_test']; ?>
221
- <div class="alert alert-<?= $repoTest['success'] ? 'success' : 'danger' ?>">
222
- <h5>
223
- <span class="<?= $repoTest['success'] ? 'status-ok' : 'status-error' ?>">
224
- <?= $repoTest['success'] ? '✅ 仓库可访问' : '❌ 仓库不可访问' ?>
225
- </span>
226
- (HTTP <?= $repoTest['http_code'] ?>)
227
- </h5>
228
- <?php if ($repoTest['success'] && $repoTest['decoded']): ?>
229
- <p><strong>仓库全名:</strong> <?= htmlspecialchars($repoTest['decoded']['full_name']) ?></p>
230
- <p><strong>默认分支:</strong> <?= htmlspecialchars($repoTest['decoded']['default_branch']) ?></p>
231
- <p><strong>仓库权限:</strong>
232
- 读取: <?= $repoTest['decoded']['permissions']['pull'] ? '✅' : '❌' ?>,
233
- 写入: <?= $repoTest['decoded']['permissions']['push'] ? '✅' : '❌' ?>,
234
- 管理: <?= $repoTest['decoded']['permissions']['admin'] ? '✅' : '❌' ?>
235
- </p>
236
  <?php endif; ?>
237
- </div>
238
-
239
- <?php if (!$repoTest['success']): ?>
240
- <div class="response-data">
241
- <strong>错误响应:</strong><br>
242
- <?= htmlspecialchars($repoTest['response']) ?>
243
- </div>
244
- <?php endif; ?>
245
- </div>
246
- </div>
247
 
248
- <!-- 分支检查结果 -->
249
- <div class="card mb-4">
250
- <div class="card-header">
251
- <h3>🌿 分支检查结果</h3>
252
- </div>
253
- <div class="card-body">
254
- <?php $branchTest = $diagnostics['branch_test']; ?>
255
- <div class="alert alert-<?= $branchTest['success'] ? 'success' : 'danger' ?>">
256
- <h5>
257
- <span class="<?= $branchTest['success'] ? 'status-ok' : 'status-error' ?>">
258
- <?= $branchTest['success'] ? '✅ 分支存在' : '❌ 分支不存在' ?>
259
- </span>
260
- (HTTP <?= $branchTest['http_code'] ?>)
261
- </h5>
262
- <?php if ($branchTest['success'] && $branchTest['decoded']): ?>
263
- <p><strong>分支名:</strong> <?= htmlspecialchars($branchTest['decoded']['name']) ?></p>
264
- <p><strong>最后提交:</strong> <?= htmlspecialchars($branchTest['decoded']['commit']['sha']) ?></p>
265
  <?php endif; ?>
266
- </div>
267
-
268
- <?php if (!$branchTest['success']): ?>
269
- <div class="response-data">
270
- <strong>错误响应:</strong><br>
271
- <?= htmlspecialchars($branchTest['response']) ?>
272
- </div>
273
- <?php endif; ?>
274
- </div>
275
- </div>
276
 
277
- <!-- 用户目录检查 -->
278
- <div class="card mb-4">
279
- <div class="card-header">
280
- <h3>👤 用户目录检查结果</h3>
281
- </div>
282
- <div class="card-body">
283
- <?php $userDirTest = $diagnostics['user_dir_test']; ?>
284
- <div class="alert alert-<?= $userDirTest['success'] ? 'success' : 'warning' ?>">
285
- <h5>
286
- <span class="<?= $userDirTest['success'] ? 'status-ok' : 'status-warning' ?>">
287
- <?= $userDirTest['success'] ? '✅ 用户目录存在' : '⚠️ 用户目录不存在' ?>
288
- </span>
289
- (HTTP <?= $userDirTest['http_code'] ?>)
290
- </h5>
291
- <?php if ($userDirTest['success'] && $userDirTest['decoded']): ?>
292
- <p><strong>目录文件数:</strong> <?= count($userDirTest['decoded']) ?></p>
293
- <?php elseif ($userDirTest['http_code'] == 404): ?>
294
- <p>用户目录尚不存在,将在首次保存文件时自动创建。</p>
 
295
  <?php endif; ?>
296
- </div>
297
-
298
- <?php if ($userDirTest['http_code'] != 404 && !$userDirTest['success']): ?>
299
- <div class="response-data">
300
- <strong>错误响应:</strong><br>
301
- <?= htmlspecialchars($userDirTest['response']) ?>
302
- </div>
303
- <?php endif; ?>
304
- </div>
305
- </div>
306
 
307
- <!-- 写入权限测试结果 -->
308
- <div class="card mb-4">
309
- <div class="card-header">
310
- <h3>✍️ 写入权限测试结果</h3>
311
- </div>
312
- <div class="card-body">
313
- <?php $writeTest = $diagnostics['write_test']; ?>
314
- <div class="alert alert-<?= $writeTest['success'] ? 'success' : 'danger' ?>">
315
- <h5>
316
- <span class="<?= $writeTest['success'] ? 'status-ok' : 'status-error' ?>">
317
- <?= $writeTest['success'] ? '✅ 写入权限正常' : '❌ 写入权限失败' ?>
318
- </span>
319
- (HTTP <?= $writeTest['http_code'] ?>)
320
- </h5>
321
- <?php if ($writeTest['success']): ?>
322
- <p>成功创建测试文件,GitHub写入权限正常。</p>
323
- <?php if (isset($diagnostics['cleanup_test'])): ?>
324
- <p><strong>清理:</strong>
325
- <span class="<?= $diagnostics['cleanup_test']['success'] ? 'status-ok' : 'status-warning' ?>">
326
- <?= $diagnostics['cleanup_test']['success'] ? '✅ 测试文件已删除' : '⚠️ 测试文件删除失败' ?>
327
- </span>
328
- </p>
329
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
330
  <?php endif; ?>
331
  </div>
332
-
333
- <?php if (!$writeTest['success']): ?>
334
- <div class="response-data">
335
- <strong>错误响应:</strong><br>
336
- <?= htmlspecialchars($writeTest['response']) ?>
337
- </div>
338
- <?php endif; ?>
339
- </div>
340
- </div>
341
 
342
- <!-- 诊断总结 -->
343
- <div class="card mb-4">
344
- <div class="card-header">
345
- <h3>📊 诊断总结</h3>
346
- </div>
347
- <div class="card-body">
348
- <?php
349
- $allPassed = $diagnostics['token_test']['success'] &&
350
- $diagnostics['repo_test']['success'] &&
351
- $diagnostics['branch_test']['success'] &&
352
- $diagnostics['write_test']['success'];
353
- ?>
354
-
355
- <?php if ($allPassed): ?>
356
- <div class="alert alert-success">
357
- <h4>🎉 所有测试通过!</h4>
358
- <p>你的GitHub配置完全正常,VvvebJs应该能够正常保存文件到GitHub仓库。</p>
359
- <p><strong>建议:</strong> 如果仍然遇到保存问题,请检查网络连接或尝试重启Hugging Face Space。</p>
360
- </div>
361
- <?php else: ?>
362
- <div class="alert alert-danger">
363
- <h4>❌ 发现问题</h4>
364
- <p>部分测试失败,请根据上述详细结果修复相关问题:</p>
365
- <ul>
366
- <?php if (!$diagnostics['token_test']['success']): ?>
367
- <li>Token验证失败 - 检查Token是否正确且有效</li>
368
- <?php endif; ?>
369
- <?php if (!$diagnostics['repo_test']['success']): ?>
370
- <li>仓库访问失败 - 检查仓库名称和权限</li>
371
- <?php endif; ?>
372
- <?php if (!$diagnostics['branch_test']['success']): ?>
373
- <li>分支不存在 - 检查分支名称是否正确</li>
374
- <?php endif; ?>
375
- <?php if (!$diagnostics['write_test']['success']): ?>
376
- <li>写入权限不足 - 检查Token是否有repo权限</li>
377
- <?php endif; ?>
378
- </ul>
379
  </div>
380
  <?php endif; ?>
381
  </div>
382
  </div>
383
 
384
- <?php endif; ?>
385
-
386
  <!-- 操作按钮 -->
387
  <div class="card">
388
  <div class="card-body text-center">
@@ -391,7 +447,7 @@ if ($_POST['run_diagnostics'] ?? false) {
391
  <a href="github-save-debug.php" class="btn btn-warning w-100">保存调试</a>
392
  </div>
393
  <div class="col-md-3">
394
- <a href="hf-space-check.php" class="btn btn-info w-100">HF Space 检查</a>
395
  </div>
396
  <div class="col-md-3">
397
  <a href="config-check.php" class="btn btn-secondary w-100">配置检查</a>
 
1
  <?php
2
  require_once __DIR__ . '/storage.php';
3
 
4
+ // 简单认证
5
  $testAuth = false;
6
  if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
7
  $users = StorageConfig::getUsers();
 
10
  }
11
 
12
  if (!$testAuth) {
13
+ header('WWW-Authenticate: Basic realm="VvvebJs GitHub Advanced Test"');
14
  header('HTTP/1.0 401 Unauthorized');
15
+ die('Authentication required for GitHub advanced test');
16
  }
17
 
18
  $github = StorageConfig::getGitHubConfig();
19
+ $currentUser = StorageConfig::getCurrentUser();
20
+ $userPath = StorageConfig::getUserPath();
21
 
22
+ // 执行完整的GitHub测试
23
+ $testResults = [];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ if ($_POST['run_full_test'] ?? false) {
26
+ try {
27
+ error_log("GitHub Advanced Test: Starting comprehensive test suite");
28
+
29
+ // 测试1: GitHub API连接
30
+ $apiUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}";
31
+ $headers = [
32
+ 'Authorization: token ' . $github['token'],
33
+ 'User-Agent: VvvebJs-Advanced-Test',
34
+ 'Accept: application/vnd.github.v3+json'
35
+ ];
36
+
37
+ $context = stream_context_create([
38
+ 'http' => [
39
+ 'method' => 'GET',
40
+ 'header' => implode("\r\n", $headers)
41
+ ]
42
+ ]);
43
+
44
+ $response = @file_get_contents($apiUrl, false, $context);
45
+ $repoInfo = $response ? json_decode($response, true) : null;
46
+
47
+ $testResults['api_connection'] = [
48
+ 'success' => $repoInfo !== null,
49
+ 'response' => $repoInfo ? 'Repository found' : 'Failed to connect',
50
+ 'repo_name' => $repoInfo['name'] ?? 'N/A',
51
+ 'default_branch' => $repoInfo['default_branch'] ?? 'N/A'
52
+ ];
53
+
54
+ // 测试2: 分支检查
55
+ if ($testResults['api_connection']['success']) {
56
+ $branchUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}/branches/{$github['branch']}";
57
+ $branchContext = stream_context_create([
58
+ 'http' => [
59
+ 'method' => 'GET',
60
+ 'header' => implode("\r\n", $headers)
61
+ ]
62
+ ]);
63
+
64
+ $branchResponse = @file_get_contents($branchUrl, false, $branchContext);
65
+ $branchInfo = $branchResponse ? json_decode($branchResponse, true) : null;
66
+
67
+ $testResults['branch_check'] = [
68
+ 'success' => $branchInfo !== null,
69
+ 'branch_name' => $github['branch'],
70
+ 'exists' => $branchInfo !== null,
71
+ 'commit_sha' => $branchInfo['commit']['sha'] ?? 'N/A'
72
+ ];
73
+ }
74
+
75
+ // 测试3: 目录结构检查
76
+ $testResults['directory_structure'] = [];
77
+ $directories = [
78
+ 'pages' => "pages",
79
+ 'users' => "pages/users",
80
+ 'user_dir' => "pages/{$userPath}"
81
+ ];
82
+
83
+ foreach ($directories as $key => $path) {
84
+ $dirUrl = "https://api.github.com/repos/{$github['owner']}/{$github['repo']}/contents/{$path}";
85
+ $dirContext = stream_context_create([
86
+ 'http' => [
87
+ 'method' => 'GET',
88
+ 'header' => implode("\r\n", $headers)
89
+ ]
90
+ ]);
91
+
92
+ $dirResponse = @file_get_contents($dirUrl, false, $dirContext);
93
+ $testResults['directory_structure'][$key] = [
94
+ 'path' => $path,
95
+ 'exists' => $dirResponse !== false,
96
+ 'response' => $dirResponse ? 'Found' : 'Not found'
97
+ ];
98
+ }
99
+
100
+ // 测试4: 文件保存测试
101
+ $storageManager = new StorageManager();
102
+ $testHtml = '<!DOCTYPE html>
103
+ <html lang="en">
104
+ <head>
105
+ <meta charset="UTF-8">
106
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
107
+ <title>GitHub Advanced Test</title>
108
+ <style>
109
+ body { font-family: Arial, sans-serif; margin: 40px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; }
110
+ .container { max-width: 800px; margin: 0 auto; background: rgba(255,255,255,0.1); padding: 30px; border-radius: 15px; backdrop-filter: blur(10px); }
111
+ h1 { text-align: center; margin-bottom: 30px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); }
112
+ .test-info { background: rgba(255,255,255,0.2); padding: 20px; border-radius: 10px; margin: 20px 0; }
113
+ .success { color: #4CAF50; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.5); }
114
+ </style>
115
+ </head>
116
+ <body>
117
+ <div class="container">
118
+ <h1>🚀 GitHub Advanced Test Success!</h1>
119
+
120
+ <div class="test-info">
121
+ <h2>Test Results</h2>
122
+ <p><span class="success">✅ GitHub API Connection: SUCCESS</span></p>
123
+ <p><span class="success">✅ Branch Verification: SUCCESS</span></p>
124
+ <p><span class="success">✅ Directory Structure: SUCCESS</span></p>
125
+ <p><span class="success">✅ File Save Operation: SUCCESS</span></p>
126
+ </div>
127
+
128
+ <div class="test-info">
129
+ <h2>Test Details</h2>
130
+ <p><strong>Test Time:</strong> ' . date('Y-m-d H:i:s') . ' UTC</p>
131
+ <p><strong>User:</strong> ' . htmlspecialchars($currentUser) . '</p>
132
+ <p><strong>Repository:</strong> ' . htmlspecialchars($github['owner']) . '/' . htmlspecialchars($github['repo']) . '</p>
133
+ <p><strong>Branch:</strong> ' . htmlspecialchars($github['branch']) . '</p>
134
+ <p><strong>User Path:</strong> ' . htmlspecialchars($userPath) . '</p>
135
+ </div>
136
+
137
+ <div class="test-info">
138
+ <h2>🎉 All Systems Operational</h2>
139
+ <p>Your VvvebJs installation is properly configured and can successfully save files to GitHub. You can now use all editor features with confidence!</p>
140
+ </div>
141
+ </div>
142
+ </body>
143
+ </html>';
144
+
145
+ $testFilename = 'github-advanced-test-' . time() . '.html';
146
+ $saveResult = $storageManager->saveFile($testFilename, $testHtml);
147
+
148
+ $testResults['file_save'] = [
149
+ 'success' => $saveResult,
150
+ 'filename' => $testFilename,
151
+ 'content_length' => strlen($testHtml),
152
+ 'message' => $saveResult ? 'File saved successfully to GitHub' : 'Failed to save file'
153
+ ];
154
+
155
+ // 测试5: 文件检索测试
156
+ if ($saveResult) {
157
+ $retrievedContent = $storageManager->getFile($testFilename);
158
+ $testResults['file_retrieve'] = [
159
+ 'success' => $retrievedContent !== false,
160
+ 'content_matches' => $retrievedContent === $testHtml,
161
+ 'retrieved_length' => $retrievedContent ? strlen($retrievedContent) : 0
162
+ ];
163
+ }
164
+
165
+ // 测试6: 文件列表测试
166
+ $fileList = $storageManager->listFiles();
167
+ $testResults['file_list'] = [
168
+ 'success' => is_array($fileList),
169
+ 'file_count' => is_array($fileList) ? count($fileList) : 0,
170
+ 'contains_test_file' => false
171
+ ];
172
+
173
+ if (is_array($fileList)) {
174
+ foreach ($fileList as $file) {
175
+ if ($file['name'] === $testFilename) {
176
+ $testResults['file_list']['contains_test_file'] = true;
177
+ break;
178
+ }
179
+ }
180
+ }
181
+
182
+ // 计算总体成功率
183
+ $totalTests = 0;
184
+ $passedTests = 0;
185
+
186
+ foreach ($testResults as $test) {
187
+ if (isset($test['success'])) {
188
+ $totalTests++;
189
+ if ($test['success']) $passedTests++;
190
+ } elseif (is_array($test)) {
191
+ foreach ($test as $subtest) {
192
+ if (isset($subtest['success']) || isset($subtest['exists'])) {
193
+ $totalTests++;
194
+ if ($subtest['success'] ?? $subtest['exists'] ?? false) $passedTests++;
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ $testResults['summary'] = [
201
+ 'total_tests' => $totalTests,
202
+ 'passed_tests' => $passedTests,
203
+ 'success_rate' => $totalTests > 0 ? round(($passedTests / $totalTests) * 100, 1) : 0,
204
+ 'overall_success' => $passedTests === $totalTests
205
+ ];
206
+
207
+ } catch (Exception $e) {
208
+ error_log("GitHub Advanced Test Error: " . $e->getMessage());
209
+ $testResults['error'] = [
210
+ 'message' => $e->getMessage(),
211
+ 'file' => $e->getFile(),
212
+ 'line' => $e->getLine()
213
  ];
 
214
  }
215
  }
216
  ?>
 
220
  <head>
221
  <meta charset="utf-8">
222
  <meta name="viewport" content="width=device-width, initial-scale=1">
223
+ <title>VvvebJs GitHub 高级测试</title>
224
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
225
  <style>
226
  .config-value { background-color: #f8f9fa; padding: 2px 6px; border-radius: 3px; font-family: monospace; }
227
  .status-ok { color: #28a745; }
228
  .status-error { color: #dc3545; }
229
  .status-warning { color: #ffc107; }
230
+ .test-result { margin-bottom: 15px; padding: 15px; border-radius: 8px; }
231
+ .test-success { background-color: #d4edda; border: 1px solid #c3e6cb; }
232
+ .test-failure { background-color: #f8d7da; border: 1px solid #f5c6cb; }
233
+ .progress-ring { width: 120px; height: 120px; }
234
+ .progress-ring__circle { stroke: #ddd; fill: transparent; stroke-width: 4; }
235
+ .progress-ring__progress { stroke: #4caf50; fill: transparent; stroke-width: 4; stroke-linecap: round; transform: rotate(-90deg); transform-origin: 50% 50%; }
236
  </style>
237
  </head>
238
  <body>
239
  <div class="container mt-5">
240
  <div class="row">
241
+ <div class="col-md-10 mx-auto">
242
+ <h1 class="mb-4">🚀 VvvebJs GitHub 高级测试套件</h1>
243
 
244
+ <!-- 当前配置 -->
245
  <div class="card mb-4">
246
  <div class="card-header">
247
+ <h3>📋 测试配置</h3>
248
  </div>
249
  <div class="card-body">
250
  <div class="row">
251
  <div class="col-md-6">
252
+ <p><strong>GitHub仓库:</strong> <span class="config-value"><?= htmlspecialchars($github['owner']) ?>/<?= htmlspecialchars($github['repo']) ?></span></p>
253
+ <p><strong>分支:</strong> <span class="config-value"><?= htmlspecialchars($github['branch']) ?></span></p>
254
+ <p><strong>基础路径:</strong> <span class="config-value"><?= htmlspecialchars($github['path']) ?></span></p>
255
+ </div>
256
+ <div class="col-md-6">
257
+ <p><strong>当前用户:</strong> <span class="config-value"><?= htmlspecialchars($currentUser) ?></span></p>
258
+ <p><strong>用户路径:</strong> <span class="config-value"><?= htmlspecialchars($userPath) ?></span></p>
259
+ <p><strong>Token状态:</strong>
260
  <span class="config-value <?= empty($github['token']) ? 'status-error' : 'status-ok' ?>">
261
+ <?= empty($github['token']) ? '❌ 未设置' : '✅ 已配置' ?>
262
  </span>
263
  </p>
 
 
 
 
 
 
 
264
  </div>
265
  </div>
266
  </div>
267
  </div>
268
 
269
+ <!-- 测试控制 -->
270
  <div class="card mb-4">
271
  <div class="card-header">
272
+ <h3>🧪 运行完整测试</h3>
273
  </div>
274
  <div class="card-body">
275
+ <?php if (empty($testResults)): ?>
276
+ <div class="alert alert-info">
277
+ <h5>📋 测试项目清单</h5>
278
+ <ul>
279
+ <li><strong>GitHub API连接测试</strong> - 验证能否连接到GitHub API</li>
280
+ <li><strong>仓库访问测试</strong> - 确认仓库存在且可访问</li>
281
+ <li><strong>分支验证测试</strong> - 检查目标分支是否存在</li>
282
+ <li><strong>目录结构测试</strong> - 验证必要的目录结构</li>
283
+ <li><strong>文件保存测试</strong> - 测试实际的文件保存功能</li>
284
+ <li><strong>文件检索测试</strong> - 验证保存的文件能否正确读取</li>
285
+ <li><strong>文件列表测试</strong> - 测试文件列表功能</li>
286
+ </ul>
287
+ </div>
288
+
289
  <form method="POST">
290
+ <button type="submit" name="run_full_test" value="1" class="btn btn-primary btn-lg">
291
+ 🚀 运行完整测试套件
292
  </button>
293
  </form>
294
  <?php else: ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
295
 
296
+ <!-- 测试结果总览 -->
297
+ <?php if (isset($testResults['summary'])): ?>
298
+ <div class="row mb-4">
299
+ <div class="col-md-6">
300
+ <div class="card <?= $testResults['summary']['overall_success'] ? 'border-success' : 'border-danger' ?>">
301
+ <div class="card-body text-center">
302
+ <h5>🎯 测试总览</h5>
303
+ <div class="display-4 <?= $testResults['summary']['overall_success'] ? 'text-success' : 'text-danger' ?>">
304
+ <?= $testResults['summary']['success_rate'] ?>%
305
+ </div>
306
+ <p class="mb-0">
307
+ <?= $testResults['summary']['passed_tests'] ?>/<?= $testResults['summary']['total_tests'] ?> 测试通过
308
+ </p>
309
+ </div>
310
+ </div>
311
+ </div>
312
+ <div class="col-md-6">
313
+ <div class="card">
314
+ <div class="card-body">
315
+ <h5>📊 整体状态</h5>
316
+ <?php if ($testResults['summary']['overall_success']): ?>
317
+ <div class="alert alert-success mb-0">
318
+ <strong>🎉 全部测试通过!</strong><br>
319
+ 你的VvvebJs配置完全正常,可以正常使用所有功能。
320
+ </div>
321
+ <?php else: ?>
322
+ <div class="alert alert-warning mb-0">
323
+ <strong>⚠️ 部分测试失败</strong><br>
324
+ 请检查下方的详细测试结果,修复相关问题。
325
+ </div>
326
+ <?php endif; ?>
327
+ </div>
328
+ </div>
329
+ </div>
330
  </div>
331
  <?php endif; ?>
 
 
332
 
333
+ <!-- 详细测试结果 -->
334
+ <div class="row">
335
+ <!-- API连接测试 -->
336
+ <?php if (isset($testResults['api_connection'])): ?>
337
+ <div class="col-md-6 mb-3">
338
+ <div class="test-result <?= $testResults['api_connection']['success'] ? 'test-success' : 'test-failure' ?>">
339
+ <h6>
340
+ <span class="<?= $testResults['api_connection']['success'] ? 'status-ok' : 'status-error' ?>">
341
+ <?= $testResults['api_connection']['success'] ? '✅' : '❌' ?>
342
+ </span>
343
+ GitHub API连接
344
+ </h6>
345
+ <p><strong>状态:</strong> <?= htmlspecialchars($testResults['api_connection']['response']) ?></p>
346
+ <p><strong>仓库:</strong> <?= htmlspecialchars($testResults['api_connection']['repo_name']) ?></p>
347
+ <p><strong>默认分支:</strong> <?= htmlspecialchars($testResults['api_connection']['default_branch']) ?></p>
348
+ </div>
349
+ </div>
 
 
 
 
 
350
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
351
 
352
+ <!-- 分支检查 -->
353
+ <?php if (isset($testResults['branch_check'])): ?>
354
+ <div class="col-md-6 mb-3">
355
+ <div class="test-result <?= $testResults['branch_check']['success'] ? 'test-success' : 'test-failure' ?>">
356
+ <h6>
357
+ <span class="<?= $testResults['branch_check']['success'] ? 'status-ok' : 'status-error' ?>">
358
+ <?= $testResults['branch_check']['success'] ? '✅' : '❌' ?>
359
+ </span>
360
+ 分支验证
361
+ </h6>
362
+ <p><strong>目标分支:</strong> <?= htmlspecialchars($testResults['branch_check']['branch_name']) ?></p>
363
+ <p><strong>存在状态:</strong> <?= $testResults['branch_check']['exists'] ? '✅ 存在' : '❌ 不存在' ?></p>
364
+ <p><strong>最新提交:</strong> <?= htmlspecialchars(substr($testResults['branch_check']['commit_sha'], 0, 8)) ?>...</p>
365
+ </div>
366
+ </div>
 
 
367
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
368
 
369
+ <!-- 目录结 -->
370
+ <?php if (isset($testResults['directory_structure'])): ?>
371
+ <div class="col-md-12 mb-3">
372
+ <div class="test-result test-success">
373
+ <h6>📁 目录结构检查</h6>
374
+ <div class="row">
375
+ <?php foreach ($testResults['directory_structure'] as $key => $dir): ?>
376
+ <div class="col-md-4">
377
+ <p>
378
+ <span class="<?= $dir['exists'] ? 'status-ok' : 'status-warning' ?>">
379
+ <?= $dir['exists'] ? '✅' : '⚠️' ?>
380
+ </span>
381
+ <code><?= htmlspecialchars($dir['path']) ?></code>
382
+ </p>
383
+ </div>
384
+ <?php endforeach; ?>
385
+ </div>
386
+ </div>
387
+ </div>
388
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
389
 
390
+ <!-- 文件操作测试 -->
391
+ <?php if (isset($testResults['file_save'])): ?>
392
+ <div class="col-md-6 mb-3">
393
+ <div class="test-result <?= $testResults['file_save']['success'] ? 'test-success' : 'test-failure' ?>">
394
+ <h6>
395
+ <span class="<?= $testResults['file_save']['success'] ? 'status-ok' : 'status-error' ?>">
396
+ <?= $testResults['file_save']['success'] ? '✅' : '❌' ?>
397
+ </span>
398
+ 文件保存测试
399
+ </h6>
400
+ <p><strong>文件名:</strong> <?= htmlspecialchars($testResults['file_save']['filename']) ?></p>
401
+ <p><strong>内容长度:</strong> <?= $testResults['file_save']['content_length'] ?> 字节</p>
402
+ <p><strong>结果:</strong> <?= htmlspecialchars($testResults['file_save']['message']) ?></p>
403
+
404
+ <?php if ($testResults['file_save']['success']): ?>
405
+ <a href="https://github.com/<?= htmlspecialchars($github['owner']) ?>/<?= htmlspecialchars($github['repo']) ?>/blob/<?= htmlspecialchars($github['branch']) ?>/pages/<?= htmlspecialchars($userPath) ?><?= htmlspecialchars($testResults['file_save']['filename']) ?>"
406
+ target="_blank" class="btn btn-sm btn-outline-primary">
407
+ 在GitHub上查看
408
+ </a>
409
+ <?php endif; ?>
410
+ </div>
411
+ </div>
412
  <?php endif; ?>
413
+
414
+ <?php if (isset($testResults['file_retrieve'])): ?>
415
+ <div class="col-md-6 mb-3">
416
+ <div class="test-result <?= $testResults['file_retrieve']['success'] && $testResults['file_retrieve']['content_matches'] ? 'test-success' : 'test-failure' ?>">
417
+ <h6>
418
+ <span class="<?= $testResults['file_retrieve']['success'] && $testResults['file_retrieve']['content_matches'] ? 'status-ok' : 'status-error' ?>">
419
+ <?= $testResults['file_retrieve']['success'] && $testResults['file_retrieve']['content_matches'] ? '✅' : '❌' ?>
420
+ </span>
421
+ 文件检索测试
422
+ </h6>
423
+ <p><strong>读取状态:</strong> <?= $testResults['file_retrieve']['success'] ? '✅ 成功' : '❌ 失败' ?></p>
424
+ <p><strong>内容匹配:</strong> <?= $testResults['file_retrieve']['content_matches'] ? '✅ 一致' : '❌ 不一致' ?></p>
425
+ <p><strong>读取长度:</strong> <?= $testResults['file_retrieve']['retrieved_length'] ?> 字节</p>
426
+ </div>
427
+ </div>
428
  <?php endif; ?>
429
  </div>
 
 
 
 
 
 
 
 
 
430
 
431
+ <div class="mt-3">
432
+ <form method="POST" class="d-inline">
433
+ <button type="submit" name="run_full_test" value="1" class="btn btn-secondary">
434
+ 🔄 重新运行测试
435
+ </button>
436
+ </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  </div>
438
  <?php endif; ?>
439
  </div>
440
  </div>
441
 
 
 
442
  <!-- 操作按钮 -->
443
  <div class="card">
444
  <div class="card-body text-center">
 
447
  <a href="github-save-debug.php" class="btn btn-warning w-100">保存调试</a>
448
  </div>
449
  <div class="col-md-3">
450
+ <a href="directory-creation-test.php" class="btn btn-info w-100">目录创建测试</a>
451
  </div>
452
  <div class="col-md-3">
453
  <a href="config-check.php" class="btn btn-secondary w-100">配置检查</a>
save.php CHANGED
@@ -173,7 +173,7 @@ if (isset($_POST['file'])) {
173
  $file = sanitizeFileName($_POST['file']);
174
  }
175
 
176
- if ($action) {
177
  //file manager actions, delete and rename
178
  switch ($action) {
179
  case 'listFiles':
@@ -359,14 +359,12 @@ if ($action) {
359
  showError('Invalid url!');
360
  }
361
  break;
362
- default:
363
- error_log("VvvebJs Invalid Action: '$action'");
364
- header('Content-Type: application/json');
365
- http_response_code(400);
366
- echo json_encode(['success' => false, 'message' => "Invalid action '$action'"]);
367
- exit;
368
  }
369
  } else {
 
 
 
 
370
  //save page
371
  if ($html) {
372
  if ($file) {
@@ -468,9 +466,21 @@ if ($action) {
468
  showError("Error saving file '$file'\nExternal: $externalError\nLocal: File write failed\nPossible causes are missing write permission or incorrect file path!");
469
  }
470
  } else {
 
 
 
 
 
 
471
  showError('Filename is empty!');
472
  }
473
  } else {
 
 
 
 
 
 
474
  showError('Html content is empty!');
475
  }
476
  }
 
173
  $file = sanitizeFileName($_POST['file']);
174
  }
175
 
176
+ if ($action && $action !== '') {
177
  //file manager actions, delete and rename
178
  switch ($action) {
179
  case 'listFiles':
 
359
  showError('Invalid url!');
360
  }
361
  break;
 
 
 
 
 
 
362
  }
363
  } else {
364
+ // No action specified - this should be a save request
365
+ error_log("VvvebJs: No action specified, treating as save request");
366
+ error_log("VvvebJs Save Request Debug - POST data keys: " . implode(', ', array_keys($_POST)));
367
+
368
  //save page
369
  if ($html) {
370
  if ($file) {
 
466
  showError("Error saving file '$file'\nExternal: $externalError\nLocal: File write failed\nPossible causes are missing write permission or incorrect file path!");
467
  }
468
  } else {
469
+ // For AJAX requests, return JSON error
470
+ if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
471
+ header('Content-Type: application/json');
472
+ echo json_encode(['success' => false, 'message' => 'Filename is empty!']);
473
+ exit;
474
+ }
475
  showError('Filename is empty!');
476
  }
477
  } else {
478
+ // For AJAX requests, return JSON error
479
+ if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
480
+ header('Content-Type: application/json');
481
+ echo json_encode(['success' => false, 'message' => 'Html content is empty!']);
482
+ exit;
483
+ }
484
  showError('Html content is empty!');
485
  }
486
  }