- Removed visible debug information section - Debug data collection remains in code for future troubleshooting - Clean user interface now shows only results 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
651 lines
No EOL
25 KiB
PHP
651 lines
No EOL
25 KiB
PHP
<?php
|
|
// Include configuration
|
|
require_once 'config.php';
|
|
|
|
// Set error reporting for development
|
|
error_reporting(E_ALL);
|
|
ini_set('display_errors', 1);
|
|
|
|
// Function to extract Box file ID from URL
|
|
function extractBoxFileId($url) {
|
|
if (preg_match('/\/file\/(\d+)/', $url, $matches)) {
|
|
return $matches[1];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Process form submission
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$boxUrl = $_POST['box_url'] ?? '';
|
|
$username = $_POST['username'] ?? 'unknown';
|
|
$webhookUrl = $config['webhook_url']; // Always use the webhook URL from config
|
|
$fileId = extractBoxFileId($boxUrl);
|
|
$result = null;
|
|
$error = null;
|
|
$debugInfo = []; // Debug information
|
|
|
|
if ($fileId) {
|
|
// Prepare data for webhook
|
|
$data = [
|
|
'url' => $boxUrl,
|
|
'file_id' => $fileId,
|
|
'username' => $username,
|
|
'timestamp' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
$debugInfo['sent_data'] = $data;
|
|
|
|
// Initialize cURL session
|
|
$ch = curl_init($webhookUrl);
|
|
|
|
// Set cURL options
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
'Content-Type: application/json'
|
|
]);
|
|
|
|
// Execute cURL request
|
|
$response = curl_exec($ch);
|
|
$debugInfo['raw_response'] = $response;
|
|
|
|
// Check for errors
|
|
if (curl_errno($ch)) {
|
|
$error = 'cURL Error: ' . curl_error($ch);
|
|
$debugInfo['curl_error'] = curl_error($ch);
|
|
} else {
|
|
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
$debugInfo['http_code'] = $httpCode;
|
|
|
|
if ($httpCode >= 200 && $httpCode < 300) {
|
|
// Strip markdown code fences if present
|
|
$cleanedResponse = preg_replace('/^```json\s*/s', '', $response);
|
|
$cleanedResponse = preg_replace('/\s*```$/s', '', $cleanedResponse);
|
|
$debugInfo['cleaned_response'] = $cleanedResponse;
|
|
|
|
$result = json_decode($cleanedResponse, true);
|
|
$debugInfo['decoded_result'] = $result;
|
|
$debugInfo['json_decode_error'] = json_last_error_msg();
|
|
} else {
|
|
$error = "HTTP Error: $httpCode - $response";
|
|
}
|
|
}
|
|
|
|
// Close cURL session
|
|
curl_close($ch);
|
|
} else {
|
|
$error = "Could not extract file ID from the provided Box URL.";
|
|
}
|
|
}
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>HP STUDIO COPY PROOFING TOOL</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
|
|
<!-- auth 1 of 4 -->
|
|
<script src="https://alcdn.msauth.net/browser/2.15.0/js/msal-browser.min.js" crossorigin="anonymous"></script>
|
|
<style>
|
|
#protected-content {
|
|
display: none;
|
|
}
|
|
</style>
|
|
<!-- end auth block -->
|
|
|
|
<style>
|
|
body {
|
|
font-family: 'Montserrat', sans-serif;
|
|
max-width: 800px;
|
|
margin: 0 auto;
|
|
padding: 20px;
|
|
color: #333;
|
|
}
|
|
.container {
|
|
background-color: #f5f5f5;
|
|
padding: 25px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);
|
|
}
|
|
.form-group {
|
|
margin-bottom: 20px;
|
|
}
|
|
label {
|
|
display: block;
|
|
margin-bottom: 8px;
|
|
font-weight: 600;
|
|
color: #444;
|
|
}
|
|
input[type="text"], input[type="url"] {
|
|
width: 100%;
|
|
padding: 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 6px;
|
|
box-sizing: border-box;
|
|
font-family: 'Montserrat', sans-serif;
|
|
}
|
|
button {
|
|
background-color: #4CAF50;
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border: none;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
font-family: 'Montserrat', sans-serif;
|
|
font-weight: 500;
|
|
transition: background-color 0.2s;
|
|
position: relative;
|
|
}
|
|
button:hover {
|
|
background-color: #45a049;
|
|
}
|
|
button:disabled {
|
|
background-color: #cccccc;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Loader styles */
|
|
#loader {
|
|
display: none;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(255, 255, 255, 0.7);
|
|
z-index: 9999;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.spinner {
|
|
width: 40px;
|
|
height: 40px;
|
|
border: 4px solid #f3f3f3;
|
|
border-top: 4px solid #4CAF50;
|
|
border-radius: 50%;
|
|
animation: spin 1s linear infinite;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
.result {
|
|
margin-top: 30px;
|
|
border-top: 1px solid #ddd;
|
|
padding-top: 25px;
|
|
}
|
|
.error {
|
|
color: #d9534f;
|
|
font-weight: bold;
|
|
padding: 10px;
|
|
background-color: #ffeaea;
|
|
border-radius: 4px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
/* Styled results */
|
|
.report-section {
|
|
margin-bottom: 25px;
|
|
background: white;
|
|
padding: 15px 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 1px 5px rgba(0,0,0,0.05);
|
|
}
|
|
.report-title {
|
|
font-weight: 600;
|
|
margin-bottom: 15px;
|
|
font-size: 18px;
|
|
color: #333;
|
|
border-bottom: 2px solid #f0f0f0;
|
|
padding-bottom: 8px;
|
|
}
|
|
.issue-card {
|
|
background: #f9f9f9;
|
|
padding: 12px 15px;
|
|
margin-bottom: 10px;
|
|
border-radius: 6px;
|
|
border-left: 4px solid #4CAF50;
|
|
}
|
|
.issue-card.error {
|
|
border-left-color: #d9534f;
|
|
background-color: #fff;
|
|
}
|
|
.issue-card.warning {
|
|
border-left-color: #f0ad4e;
|
|
}
|
|
.issue-detail {
|
|
margin-bottom: 5px;
|
|
font-size: 14px;
|
|
}
|
|
.issue-section {
|
|
font-weight: 600;
|
|
color: #666;
|
|
}
|
|
.issue-error {
|
|
color: #d9534f;
|
|
font-weight: 500;
|
|
}
|
|
.issue-suggestion {
|
|
color: #5cb85c;
|
|
font-weight: 500;
|
|
}
|
|
.language-status {
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
background: #e6f7e6;
|
|
display: inline-block;
|
|
margin-right: 8px;
|
|
font-size: 14px;
|
|
}
|
|
.summary-box {
|
|
background-color: #f0f8ff;
|
|
border-radius: 6px;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
/* Debug JSON collapse section */
|
|
.debug-section {
|
|
margin-top: 25px;
|
|
border-top: 1px dashed #ccc;
|
|
padding-top: 15px;
|
|
}
|
|
.collapsible {
|
|
background-color: #eee;
|
|
color: #444;
|
|
cursor: pointer;
|
|
padding: 12px;
|
|
width: 100%;
|
|
border: none;
|
|
text-align: left;
|
|
outline: none;
|
|
font-size: 15px;
|
|
font-family: 'Montserrat', sans-serif;
|
|
border-radius: 4px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
.collapsible:after {
|
|
content: '+';
|
|
font-size: 20px;
|
|
font-weight: bold;
|
|
}
|
|
.active:after {
|
|
content: '-';
|
|
}
|
|
.content {
|
|
max-height: 0;
|
|
overflow: hidden;
|
|
transition: max-height 0.2s ease-out;
|
|
background-color: #f8f8f8;
|
|
border-radius: 0 0 4px 4px;
|
|
}
|
|
pre {
|
|
background-color: #f8f8f8;
|
|
padding: 15px;
|
|
border-radius: 4px;
|
|
overflow-x: auto;
|
|
margin: 0;
|
|
font-family: monospace;
|
|
font-size: 13px;
|
|
color: #333;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Fullscreen loading overlay -->
|
|
<div id="loader">
|
|
<div class="spinner"></div>
|
|
</div>
|
|
|
|
<div class="container">
|
|
<!-- auth 2 of 4 -->
|
|
<div style="text-align: left;">
|
|
<button id="logout-button" onclick="signOut()" style="display:none;">Log Out</button>
|
|
<button id="login-button" onclick="signIn()" style="display:none;">Log In</button>
|
|
</div>
|
|
<!-- end auth block -->
|
|
|
|
<h1>HP STUDIO COPY PROOFING TOOL</h1>
|
|
|
|
<div id="protected-content">
|
|
<form method="post" id="boxUrlForm">
|
|
<div class="form-group">
|
|
<label for="box_url">Box File URL:</label>
|
|
<input type="url" id="box_url" name="box_url" placeholder="https://oliver-na.app.box.com/file/1697251331911"
|
|
value="<?php echo htmlspecialchars($boxUrl ?? ''); ?>" required>
|
|
<small style="display: block; margin-top: 5px; color: #666;">Only image files supported (gif, jpeg, jpg, png, webp)</small>
|
|
</div>
|
|
|
|
<button type="submit" id="processButton">Process File</button>
|
|
</form>
|
|
</div> <!-- end protected-content -->
|
|
|
|
<?php if (isset($result) || isset($error)): ?>
|
|
<div class="result">
|
|
<h2>Result</h2>
|
|
|
|
<?php if (isset($error)): ?>
|
|
<div class="error">
|
|
<?php echo htmlspecialchars($error); ?>
|
|
</div>
|
|
<?php else: ?>
|
|
<div>
|
|
<h3>Extracted Information:</h3>
|
|
<p><strong>Box URL:</strong> <?php echo htmlspecialchars($boxUrl); ?></p>
|
|
<p><strong>File ID:</strong> <?php echo htmlspecialchars($fileId); ?></p>
|
|
|
|
<h3>Document Analysis Results:</h3>
|
|
|
|
<?php if (isset($result['document_analysis'])): ?>
|
|
<?php $analysis = $result['document_analysis']; ?>
|
|
|
|
<!-- Summary Information -->
|
|
<div class="report-section">
|
|
<div class="report-title">Document Summary</div>
|
|
<div class="summary-box">
|
|
<div>
|
|
<strong>Language:</strong>
|
|
<?php
|
|
$languageInfo = !empty($analysis['language_detected']) ? $analysis['language_detected'][0] : null;
|
|
if ($languageInfo):
|
|
?>
|
|
<span class="language-status">
|
|
<?php echo htmlspecialchars($languageInfo['language']); ?>
|
|
(<?php echo htmlspecialchars($languageInfo['type']); ?>)
|
|
</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<div>
|
|
<strong>Issues Found:</strong>
|
|
<?php
|
|
$grammarCount = !empty($analysis['grammar_issues']) ? count($analysis['grammar_issues']) : 0;
|
|
|
|
// Only count spelling errors with status "incorrect"
|
|
$spellingCount = 0;
|
|
if (!empty($analysis['spelling_errors'])) {
|
|
foreach ($analysis['spelling_errors'] as $error) {
|
|
if ($error['status'] === 'incorrect') {
|
|
$spellingCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo $grammarCount + $spellingCount;
|
|
?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Language Detection -->
|
|
<?php if (!empty($analysis['language_detected'])): ?>
|
|
<div class="report-section">
|
|
<div class="report-title">Language Detection</div>
|
|
<?php foreach ($analysis['language_detected'] as $language): ?>
|
|
<div class="issue-card">
|
|
<div class="issue-detail">
|
|
<span class="language-status">
|
|
<?php echo htmlspecialchars($language['language']); ?>
|
|
(<?php echo htmlspecialchars($language['type']); ?>)
|
|
</span>
|
|
<span class="language-status" style="background-color: <?php echo $language['spelling_status'] === 'correct' ? '#e6f7e6' : '#ffeaea'; ?>">
|
|
Spelling: <?php echo ucfirst(htmlspecialchars($language['spelling_status'])); ?>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Grammar Issues -->
|
|
<?php if (!empty($analysis['grammar_issues'])): ?>
|
|
<div class="report-section">
|
|
<div class="report-title">Grammar Issues</div>
|
|
<?php foreach ($analysis['grammar_issues'] as $issue): ?>
|
|
<div class="issue-card error">
|
|
<div class="issue-detail">
|
|
<span class="issue-section"><?php echo htmlspecialchars($issue['section']); ?>:</span>
|
|
</div>
|
|
<div class="issue-detail">
|
|
<span class="issue-error"><?php echo htmlspecialchars($issue['error']); ?></span>
|
|
</div>
|
|
<div class="issue-detail">
|
|
<span class="issue-suggestion"><?php echo htmlspecialchars($issue['suggestion']); ?></span>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Spelling Errors -->
|
|
<?php
|
|
$hasIncorrectSpelling = false;
|
|
if (!empty($analysis['spelling_errors'])):
|
|
foreach ($analysis['spelling_errors'] as $error):
|
|
if ($error['status'] === 'incorrect'):
|
|
$hasIncorrectSpelling = true;
|
|
break;
|
|
endif;
|
|
endforeach;
|
|
|
|
if ($hasIncorrectSpelling):
|
|
?>
|
|
<div class="report-section">
|
|
<div class="report-title">Spelling Errors</div>
|
|
<?php foreach ($analysis['spelling_errors'] as $error): ?>
|
|
<?php if ($error['status'] === 'incorrect'): ?>
|
|
<div class="issue-card error">
|
|
<div class="issue-detail">
|
|
<strong>Word:</strong> <?php echo htmlspecialchars($error['word']); ?>
|
|
</div>
|
|
<div class="issue-detail">
|
|
<strong>Context:</strong> <?php echo htmlspecialchars($error['context']); ?>
|
|
</div>
|
|
<div class="issue-detail">
|
|
<strong>Correction:</strong> <span class="issue-suggestion"><?php echo htmlspecialchars($error['correct_spelling']); ?></span>
|
|
</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
|
|
<!-- Text Evaluation -->
|
|
<?php if (!empty($analysis['text_evaluation'])): ?>
|
|
<div class="report-section">
|
|
<div class="report-title">Text Evaluation</div>
|
|
<?php
|
|
// First show texts that need correction
|
|
$needsCorrection = false;
|
|
foreach ($analysis['text_evaluation'] as $text):
|
|
if ($text['status'] === 'needs_correction'):
|
|
$needsCorrection = true;
|
|
?>
|
|
<div class="issue-card error">
|
|
<div class="issue-detail">
|
|
<span class="issue-error">Needs Correction:</span>
|
|
</div>
|
|
<div class="issue-detail">
|
|
"<?php echo htmlspecialchars($text['text']); ?>"
|
|
</div>
|
|
</div>
|
|
<?php
|
|
endif;
|
|
endforeach;
|
|
|
|
// Then show the good texts
|
|
$goodTexts = false;
|
|
echo '<div class="report-title" style="margin-top: 15px; font-size: 16px;">Approved Text</div>';
|
|
foreach ($analysis['text_evaluation'] as $text):
|
|
if ($text['status'] === 'good'):
|
|
$goodTexts = true;
|
|
?>
|
|
<div class="issue-card" style="border-left-color: #28a745;">
|
|
<div class="issue-detail">
|
|
"<?php echo htmlspecialchars($text['text']); ?>"
|
|
</div>
|
|
</div>
|
|
<?php
|
|
endif;
|
|
endforeach;
|
|
|
|
if (!$needsCorrection && !$goodTexts):
|
|
?>
|
|
<div class="issue-card">
|
|
<div class="issue-detail">No text evaluations available.</div>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php else: ?>
|
|
<div class="report-section">
|
|
<div class="report-title">Response Data</div>
|
|
<pre><?php echo htmlspecialchars(json_encode($result, JSON_PRETTY_PRINT)); ?></pre>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<!-- Debug JSON section -->
|
|
<div class="debug-section">
|
|
<button type="button" class="collapsible">View Raw JSON Response (Debug)</button>
|
|
<div class="content">
|
|
<pre><?php echo htmlspecialchars(json_encode($result, JSON_PRETTY_PRINT)); ?></pre>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Collapsible functionality
|
|
var coll = document.getElementsByClassName("collapsible");
|
|
for (var i = 0; i < coll.length; i++) {
|
|
coll[i].addEventListener("click", function() {
|
|
this.classList.toggle("active");
|
|
var content = this.nextElementSibling;
|
|
if (content.style.maxHeight) {
|
|
content.style.maxHeight = null;
|
|
} else {
|
|
content.style.maxHeight = content.scrollHeight + "px";
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<script>
|
|
// Form submission and loading screen handler
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var form = document.getElementById('boxUrlForm');
|
|
var loader = document.getElementById('loader');
|
|
var processButton = document.getElementById('processButton');
|
|
|
|
form.addEventListener('submit', function(e) {
|
|
// Get username from session storage
|
|
var username = sessionStorage.getItem('username');
|
|
|
|
// Create or update hidden input for username
|
|
var usernameInput = document.getElementById('username_field');
|
|
if (!usernameInput) {
|
|
usernameInput = document.createElement('input');
|
|
usernameInput.type = 'hidden';
|
|
usernameInput.id = 'username_field';
|
|
usernameInput.name = 'username';
|
|
form.appendChild(usernameInput);
|
|
}
|
|
usernameInput.value = username || 'unknown';
|
|
|
|
// Show loading screen
|
|
loader.style.display = 'flex';
|
|
// Disable button
|
|
processButton.disabled = true;
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<!-- auth 4 of 4 NOTE: ensure values for clientID, authority (URL with tenant ID) and redirectUri are correct below -->
|
|
<script>
|
|
const msalConfig = {
|
|
auth: {
|
|
clientId: "9079054c-9620-4757-a256-23413042f1ef",
|
|
authority: "https://login.microsoftonline.com/e519c2e6-bc6d-4fdf-8d9c-923c2f002385",
|
|
redirectUri: "https://ai-sandbox.oliver.solutions/format"
|
|
},
|
|
cache: {
|
|
cacheLocation: "sessionStorage",
|
|
storeAuthStateInCookie: true,
|
|
}
|
|
};
|
|
|
|
const loginRequest = {
|
|
scopes: ["user.read"]
|
|
};
|
|
|
|
const myMSALObj = new msal.PublicClientApplication(msalConfig);
|
|
let thisUser = null;
|
|
|
|
// Check if user is already logged in when page loads
|
|
window.addEventListener('load', function() {
|
|
const accessToken = sessionStorage.getItem('accessToken');
|
|
if (accessToken) {
|
|
// User is already logged in, just show protected content
|
|
showProtectedContent();
|
|
} else {
|
|
// User is not logged in, initiate sign in
|
|
signIn();
|
|
}
|
|
});
|
|
|
|
function signIn() {
|
|
myMSALObj.loginPopup(loginRequest)
|
|
.then(loginResponse => {
|
|
console.log("User logged in:", loginResponse.account.username);
|
|
thisUser = loginResponse.account.username;
|
|
sessionStorage.setItem('accessToken', loginResponse.accessToken);
|
|
sessionStorage.setItem('username', thisUser);
|
|
showProtectedContent();
|
|
}).catch(error => {
|
|
console.error("Error during login:", error);
|
|
});
|
|
}
|
|
|
|
function signOut() {
|
|
// Clear the session storage
|
|
sessionStorage.removeItem('accessToken');
|
|
sessionStorage.removeItem('username');
|
|
console.log("User logged out.");
|
|
document.getElementById('protected-content').style.display = 'none';
|
|
document.getElementById('logout-button').style.display = 'none';
|
|
document.getElementById('login-button').style.display = 'flex';
|
|
}
|
|
|
|
function showProtectedContent() {
|
|
// Verify that the access token exists before showing protected content
|
|
const accessToken = sessionStorage.getItem('accessToken');
|
|
if (accessToken) {
|
|
document.getElementById('protected-content').style.display = 'block';
|
|
document.getElementById('logout-button').style.display = 'flex';
|
|
document.getElementById('login-button').style.display = 'none';
|
|
thisUser = sessionStorage.getItem('username');
|
|
}
|
|
}
|
|
</script>
|
|
<!-- end auth block -->
|
|
|
|
</body>
|
|
</html>
|