145 lines
5.8 KiB
PHP
Executable File
145 lines
5.8 KiB
PHP
Executable File
<?php
|
|
// Patcher v2 · étend anchors pour saas-chat + claude-pattern-api
|
|
// Doctrine 141+142 application finale
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
function patch_chatbot_v2(string $file, string $chat_id, array $extra_msg_captures = []): array {
|
|
if (!file_exists($file)) return ['ok'=>false, 'err'=>'not found'];
|
|
|
|
$content = file_get_contents($file);
|
|
|
|
// Skip if already patched
|
|
if (strpos($content, 'DOCTRINE-141-SHUTDOWN') !== false || strpos($content, 'DOCTRINE-141-INLINE') !== false) {
|
|
return ['ok'=>false, 'err'=>'already patched'];
|
|
}
|
|
|
|
// Check chattr
|
|
$attr = shell_exec("lsattr $file 2>&1");
|
|
if (strpos($attr, 'i') !== false && strpos($attr, '----i') !== false) {
|
|
shell_exec("sudo chattr -i $file 2>/dev/null");
|
|
}
|
|
|
|
// Backup
|
|
$backup = '/var/www/html/vault-gold/opus/' . basename($file) . '.doctrine141-' . date('Ymd-His') . '.bak';
|
|
@mkdir(dirname($backup), 0755, true);
|
|
copy($file, $backup);
|
|
|
|
// === Bloc à injecter (même que v1) ===
|
|
$inject = "\n// === DOCTRINE-141-SHUTDOWN · memory bridge ===
|
|
if (@file_exists(__DIR__.'/wevia-memory-bridge.php')) { @require_once __DIR__.'/wevia-memory-bridge.php'; }
|
|
\$__chat_id = '" . $chat_id . "';
|
|
\$__user_id = \$_COOKIE['weval_chat_session'] ?? \$_SERVER['HTTP_X_USER_ID'] ?? ('anon-'.substr(md5((\$_SERVER['REMOTE_ADDR']??'').(\$_SERVER['HTTP_USER_AGENT']??'')),0,12));
|
|
\$__msg_for_mem = '';
|
|
register_shutdown_function(function() use (&\$__msg_for_mem, \$__chat_id, \$__user_id) {
|
|
if (!function_exists('wevia_mem_save')) return;
|
|
\$out = ob_get_contents();
|
|
if (!\$out) return;
|
|
\$d = @json_decode(\$out, true);
|
|
\$resp = is_array(\$d) ? (\$d['response'] ?? \$d['answer'] ?? \$d['content'] ?? '') : \$out;
|
|
if (\$resp && \$__msg_for_mem) {
|
|
@wevia_mem_save(\$__chat_id, \$__user_id, \$__msg_for_mem, is_string(\$resp)?\$resp:json_encode(\$resp), 'internal');
|
|
}
|
|
});
|
|
ob_start();
|
|
// === /DOCTRINE-141-SHUTDOWN ===
|
|
\n";
|
|
|
|
// === Anchors étendus (v2) ===
|
|
$anchors = [
|
|
// v1 anchors (doubles quotes)
|
|
'$input = json_decode(file_get_contents("php://input"), true) ?: [];',
|
|
'$input = @json_decode(file_get_contents("php://input"), true) ?: [];',
|
|
'$raw = @file_get_contents("php://input");',
|
|
// v2 NEW anchors (simples quotes)
|
|
"\$input=json_decode(file_get_contents('php://input'),true);",
|
|
"\$input = json_decode(file_get_contents('php://input'), true) ?: [];",
|
|
"\$input = json_decode(file_get_contents('php://input'), true);",
|
|
"\$input = @json_decode(file_get_contents('php://input'), true) ?: [];",
|
|
];
|
|
|
|
$injected = false;
|
|
foreach ($anchors as $anchor) {
|
|
$pos = strpos($content, $anchor);
|
|
if ($pos !== false) {
|
|
$end = strpos($content, "\n", $pos) + 1;
|
|
$before = substr($content, 0, $end);
|
|
$after = substr($content, $end);
|
|
$content = $before . $inject . $after;
|
|
$injected = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$injected) {
|
|
shell_exec("sudo chattr +i $file 2>/dev/null");
|
|
return ['ok'=>false, 'err'=>'no anchor found'];
|
|
}
|
|
|
|
// Msg captures (v1 + v2 extended)
|
|
$msg_captures = array_merge([
|
|
['old' => '$msg = $input["message"] ?? $_GET["message"] ?? "";',
|
|
'new' => '$msg = $input["message"] ?? $_GET["message"] ?? ""; $__msg_for_mem = $msg;'],
|
|
['old' => '$msg = trim($in["message"] ?? "");',
|
|
'new' => '$msg = trim($in["message"] ?? ""); $__msg_for_mem = $msg;'],
|
|
// v2: saas-chat style (simples quotes)
|
|
['old' => "\$msg=\$input['message']??\$_POST['message']??'';",
|
|
'new' => "\$msg=\$input['message']??\$_POST['message']??''; \$__msg_for_mem = \$msg;"],
|
|
// v2: claude-pattern style
|
|
['old' => "\$message = trim(\$input['message'] ?? '');",
|
|
'new' => "\$message = trim(\$input['message'] ?? ''); \$__msg_for_mem = \$message;"],
|
|
], $extra_msg_captures);
|
|
|
|
$capture_ok = false;
|
|
foreach ($msg_captures as $cap) {
|
|
if (strpos($content, $cap['old']) !== false) {
|
|
$content = str_replace($cap['old'], $cap['new'], $content);
|
|
$capture_ok = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Lint
|
|
$tmp = tempnam('/tmp', 'cbv2-');
|
|
file_put_contents($tmp, $content);
|
|
$lint = shell_exec("php -l $tmp 2>&1");
|
|
if (strpos($lint, 'No syntax errors') === false) {
|
|
unlink($tmp);
|
|
shell_exec("sudo chattr +i $file 2>/dev/null");
|
|
return ['ok'=>false, 'err'=>'lint fail', 'lint'=>$lint];
|
|
}
|
|
|
|
// Write
|
|
file_put_contents($file, $content);
|
|
shell_exec("sudo chown www-data:www-data $file");
|
|
shell_exec("sudo chattr +i $file 2>/dev/null");
|
|
unlink($tmp);
|
|
|
|
return ['ok'=>true, 'backup'=>$backup, 'chat_id'=>$chat_id, 'capture_applied'=>$capture_ok];
|
|
}
|
|
|
|
$results = [
|
|
'saas-chat' => patch_chatbot_v2('/var/www/html/api/saas-chat.php', 'saas-chat'),
|
|
'claude-pattern-api' => patch_chatbot_v2('/var/www/html/api/claude-pattern-api.php', 'claude-pattern-api'),
|
|
];
|
|
|
|
@opcache_reset();
|
|
|
|
// Tests sanity
|
|
foreach (['saas-chat', 'claude-pattern-api'] as $name) {
|
|
if ($results[$name]['ok'] ?? false) {
|
|
$sess = 'opus-ph6-' . $name;
|
|
$test = shell_exec("curl -sk -m 8 'http://localhost/api/$name.php' -H 'Content-Type: application/json' -H 'X-User-Id: $sess' -d '{\"message\":\"hello test phase 6\"}' 2>&1 | head -c 200");
|
|
$results[$name]['test'] = trim($test);
|
|
sleep(1);
|
|
// Check Redis
|
|
if (file_exists('/var/www/html/api/wevia-memory-bridge.php')) {
|
|
require_once '/var/www/html/api/wevia-memory-bridge.php';
|
|
$hist = wevia_mem_load($name, $sess, 5);
|
|
$results[$name]['redis_msgs'] = count($hist);
|
|
}
|
|
}
|
|
}
|
|
|
|
echo json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|