$label, 'javascriptCode' => $javascriptCode)); } // modify the viewer-preset-URLs.php file to add preset URLs for the viewer's form include 'viewer-preset-URLs.php'; $pgnOnly = get_param("pgnOnly", "po", ""); $generateParameter = get_param("generateParameter", "gp", ""); if (($pgnOnly == "true") || ($pgnOnly == "t")) { if (!get_pgn()) { header("HTTP/1.1 204 No Content"); } header("content-type: application/x-chess-pgn"); header("content-disposition: inline; filename=games.pgn"); if ($http_response_header_last_modified) { header($http_response_header_last_modified); } if ($pgnText) { print $pgnText; } } elseif (($generateParameter == "true") || ($generateParameter == "t")) { header("content-type: text/html; charset=utf-8"); $pgnUrl = get_param("pgnData", "pd", ""); if ($pgnUrl == "") { $pgnUrl = get_param("pgnUrl", "pu", ""); } $pgnLink = $_SERVER['SCRIPT_NAME'] . urlencode("?po=t&pd=" . $pgnUrl); print("
" . $pgnLink . "
"); } else { header("content-type: text/html; charset=utf-8"); if (!($goToView = get_pgn())) { $pgnText = preg_match("/^error:/", $pgnStatus) ? '[Event ""] [Site ""] [Date ""] [Round ""] [White ""] [Black ""] [Result ""] { error loading PGN data, click square A8 for more details }' : $startPosition; } print_header(); print_form(); check_tmpDir(); print_menu("board"); print_chessboard_one(); print_menu("moves"); print_chessboard_two(); print_footer(); print_menu("bottom"); print_html_close(); } function get_param($param, $shortParam, $default) { if (isset($_REQUEST[$param])) { return $_REQUEST[$param]; } if (isset($_REQUEST[$shortParam])) { return $_REQUEST[$shortParam]; } return $default; } function http_parse_headers($headerFields) { global $http_response_header_status, $http_response_header_last_modified; $retVal = array(); foreach ($headerFields as $field) { if (preg_match('/([^:]+): (.+)/m', $field, $match)) { $match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1]))); if (isset($retVal[$match[1]])) { $retVal[$match[1]] = array($retVal[$match[1]], $match[2]); } else { $retVal[$match[1]] = trim($match[2]); } } else if (preg_match('/^\S+\s+\d+\s/m', $field)) { $retVal["status"] = $field; } } if (isset($retVal["status"])) { $http_response_header_status = $retVal["status"]; } if (isset($retVal["Last-Modified"])) { $http_response_header_last_modified = "Last-Modified: " . $retVal["Last-Modified"]; } return $retVal; } function http_response_header_isInvalid() { global $http_response_header_status; return $http_response_header_status ? preg_match("/^\S+\s+[45]\d\d\s/", $http_response_header_status) : FALSE; } function get_pgn() { global $pgnText, $pgnTextbox, $pgnUrl, $pgnFileName, $pgnFileSize, $pgnStatus, $tmpDir, $debugHelpText, $pgnDebugInfo; global $fileUploadLimitIniText, $fileUploadLimitText, $fileUploadLimitBytes, $startPosition, $goToView, $zipSupported; global $http_response_header_status, $http_response_header_last_modified; $pgnDebugInfo = $pgnDebugInfo . get_param("debug", "d", ""); $pgnText = get_param("pgnText", "pt", ""); $pgnUrl = get_param("pgnData", "pd", ""); if ($pgnUrl == "") { $pgnUrl = get_param("pgnUrl", "pu", ""); } if ($pgnText) { $pgnStatus = "info: games from textbox input"; $pgnTextbox = $pgnText = str_replace("\\\"", "\"", $pgnText); $pgnText = preg_replace("/\[/", "\n\n[", $pgnText); $pgnText = preg_replace("/\]/", "]\n\n", $pgnText); $pgnText = preg_replace("/([012\*])(\s*)(\[)/", "$1\n\n$3", $pgnText); $pgnText = preg_replace("/\]\s*\[/", "]\n[", $pgnText); $pgnText = preg_replace("/^\s*\[/", "[", $pgnText); $pgnText = preg_replace("/\n[\s*\n]+/", "\n\n", $pgnText); $pgnTextbox = $pgnText; return TRUE; } else if ($pgnUrl) { $pgnStatus = "info: games from $pgnUrl"; $isPgn = preg_match("/\.(pgn|txt)$/i", preg_replace("/[?#].*$/", "", $pgnUrl)); $isZip = preg_match("/\.zip$/i", preg_replace("/[?#].*$/", "", $pgnUrl)); if ($isZip) { if (!$zipSupported) { $pgnStatus = "error: zipfile support unavailable, unable to open $pgnUrl"; return FALSE; } else { $tempZipName = tempnam($tmpDir, "pgn4webViewer_"); // $pgnUrlOpts tries forcing following location redirects // depending on server configuration, the script might still fail if the ZIP URL is redirected $pgnUrlOpts = array("http" => array("follow_location" => TRUE, "max_redirects" => 20)); $pgnUrlHandle = @fopen($pgnUrl, "rb", false, stream_context_create($pgnUrlOpts)); if (!$pgnUrlHandle) { $pgnStatus = "error: failed to get $pgnUrl: file not found or server error"; return FALSE; } else { $tempZipHandle = fopen($tempZipName, "wb"); $copiedBytes = stream_copy_to_stream($pgnUrlHandle, $tempZipHandle, $fileUploadLimitBytes + 1, 0); fclose($pgnUrlHandle); fclose($tempZipHandle); if (isset($http_response_header)) { http_parse_headers($http_response_header); } if ((($copiedBytes > 0) && ($copiedBytes <= $fileUploadLimitBytes)) && (!http_response_header_isInvalid())) { $pgnSource = $tempZipName; } else { $pgnStatus = "error: failed to get $pgnUrl: " . (http_response_header_isInvalid() ? "server error: $http_response_header_status" : "file not found, file size exceeds $fileUploadLimitText form limit, $fileUploadLimitIniText server limit or server error"); if (($tempZipName) && (file_exists($tempZipName))) { unlink($tempZipName); } return FALSE; } } } } else { $pgnSource = $pgnUrl; } } elseif (count($_FILES) == 0) { $pgnStatus = "info: no games supplied"; return FALSE; } elseif ($_FILES['pgnFile']['error'] === UPLOAD_ERR_OK) { $pgnFileName = $_FILES['pgnFile']['name']; $pgnStatus = "info: games from file $pgnFileName"; $pgnFileSize = $_FILES['pgnFile']['size']; if ($pgnFileSize == 0) { $pgnStatus = "info: failed uploading games: file not found, file empty or upload error"; return FALSE; } elseif ($pgnFileSize > $fileUploadLimitBytes) { $pgnStatus = "error: failed uploading games: file size exceeds $fileUploadLimitText limit"; return FALSE; } else { $isPgn = preg_match("/\.(pgn|txt)$/i",$pgnFileName); $isZip = preg_match("/\.zip$/i",$pgnFileName); $pgnSource = $_FILES['pgnFile']['tmp_name']; } } else { $pgnStatus = "error: failed uploading games: "; switch ($_FILES['pgnFile']['error']) { case UPLOAD_ERR_INI_SIZE: case UPLOAD_ERR_FORM_SIZE: $pgnStatus = $pgnStatus . "file size exceeds $fileUploadLimitText form limit or $fileUploadLimitIniText server limit"; break; case UPLOAD_ERR_PARTIAL: case UPLOAD_ERR_NO_FILE: $pgnStatus = $pgnStatus . "file missing or truncated"; break; case UPLOAD_ERR_NO_TMP_DIR: case UPLOAD_ERR_CANT_WRITE: case UPLOAD_ERR_EXTENSION: $pgnStatus = $pgnStatus . "server error"; break; default: $pgnStatus = $pgnStatus . "unknown upload error"; break; } return FALSE; } if ($isZip) { if ($zipSupported) { if ($pgnUrl) { $zipFileString = $pgnUrl; } else { $zipFileString = "zip file"; } $pgnZip = zip_open($pgnSource); if (is_resource($pgnZip)) { while (is_resource($zipEntry = zip_read($pgnZip))) { if (zip_entry_open($pgnZip, $zipEntry)) { if (preg_match("/\.pgn$/i",zip_entry_name($zipEntry))) { $pgnText = $pgnText . zip_entry_read($zipEntry, zip_entry_filesize($zipEntry)) . "\n\n\n"; } zip_entry_close($zipEntry); } else { $pgnStatus = "error: failed reading $zipFileString content"; zip_close($pgnZip); if ((isset($tempZipName)) && ($tempZipName) && (file_exists($tempZipName))) { unlink($tempZipName); } return FALSE; } } zip_close($pgnZip); if ((isset($tempZipName)) && ($tempZipName) && (file_exists($tempZipName))) { unlink($tempZipName); } if (!$pgnText) { $pgnStatus = "error: games not found in $zipFileString"; return FALSE; } } else { if ((isset($tempZipName)) && ($tempZipName) && (file_exists($tempZipName))) { unlink($tempZipName); } $pgnStatus = "error: failed opening $zipFileString"; return FALSE; } } else { $pgnStatus = "error: ZIP support unavailable from this server, only PGN files are supported"; return FALSE; } } elseif ($isPgn) { if ($pgnUrl) { $pgnFileString = $pgnUrl; } else { $pgnFileString = "pgn file"; } $pgnText = @file_get_contents($pgnSource, NULL, NULL, 0, $fileUploadLimitBytes + 1); if (isset($http_response_header)) { http_parse_headers($http_response_header); } if ((!$pgnText) || (($pgnUrl) && (http_response_header_isInvalid()))) { $pgnStatus = "error: failed reading $pgnFileString: " . (http_response_header_isInvalid() ? "server error: $http_response_header_status" : "file not found or server error"); return FALSE; } if ((strlen($pgnText) == 0) || (strlen($pgnText) > $fileUploadLimitBytes)) { $pgnStatus = "error: failed reading $pgnFileString: file size exceeds $fileUploadLimitText form limit, $fileUploadLimitIniText server limit or server error"; return FALSE; } } elseif ($pgnSource) { if ($zipSupported) { $pgnStatus = "error: only PGN and ZIP (zipped pgn) files are supported"; } else { $pgnStatus = "error: only PGN files are supported, ZIP support unavailable from this server"; } return FALSE; } $pgnText = str_replace(array("&", "<", ">"), array("&", "<", ">"), $pgnText); return TRUE; } function check_tmpDir() { global $pgnText, $pgnTextbox, $pgnUrl, $pgnFileName, $pgnFileSize, $pgnStatus, $tmpDir, $debugHelpText, $pgnDebugInfo; global $fileUploadLimitIniText, $fileUploadLimitText, $fileUploadLimitBytes, $startPosition, $goToView, $zipSupported; $unexpectedFiles = ""; $tmpDirHandle = opendir($tmpDir); while($entryName = readdir($tmpDirHandle)) { if (($entryName !== ".") && ($entryName !== "..") && ($entryName !== "index.html")) { if ((time() - filemtime($tmpDir . "/" . $entryName)) > 3600) { $unexpectedFiles = $unexpectedFiles . " " . $entryName; } } } closedir($tmpDirHandle); if ($unexpectedFiles) { $pgnDebugInfo = $pgnDebugInfo . "\\n" . "clean temporary directory " . $tmpDir . ":" . $unexpectedFiles; } } function print_menu($item) { print << 
    bottom     moves     board     top
END; } function print_header() { global $headlessPage; if (($headlessPage == "true") || ($headlessPage == "t")) { $headClass = " display:none;"; } else { $headClass = ""; } print << pgn4web games viewer

pgn4web games viewer

 
END; } function print_form() { global $pgnText, $pgnTextbox, $pgnUrl, $pgnFileName, $pgnFileSize, $pgnStatus, $tmpDir, $debugHelpText, $pgnDebugInfo; global $fileUploadLimitIniText, $fileUploadLimitText, $fileUploadLimitBytes, $startPosition, $goToView, $zipSupported; global $headlessPage, $hideFormCss, $presetURLsArray; $thisScript = $_SERVER['SCRIPT_NAME']; if (($headlessPage == "true") || ($headlessPage == "t")) { $thisScript .= "?hp=t"; } print << "use strict"; function setPgnUrl(newPgnUrl) { if (!newPgnUrl) { newPgnUrl = ""; } document.getElementById("urlFormText").value = newPgnUrl; return false; } function checkPgnUrl() { var theObj = document.getElementById("urlFormText"); if (!theObj) { return false; } if (!checkPgnExtension(theObj.value)) { return false; } else { return (theObj.value !== ""); } } function checkPgnFile() { var theObj = document.getElementById("uploadFormFile"); if (!theObj) { return false; } if (!checkPgnExtension(theObj.value)) { return false; } else { return (theObj.value !== ""); } } END; if ($zipSupported) { print << END; if ($presetURLsArray) { print(' ' . "\n"); } print <<
' . "\n" . ' ' . "\n" . '
END; } function print_chessboard_one() { global $pgnText, $pgnTextbox, $pgnUrl, $pgnFileName, $pgnFileSize, $pgnStatus, $tmpDir, $debugHelpText, $pgnDebugInfo; global $fileUploadLimitIniText, $fileUploadLimitText, $fileUploadLimitBytes, $startPosition, $goToView, $zipSupported; global $hideFormCss; print << @import url("fonts/pgn4web-font-LiberationSans.css"); @import url("fonts/pgn4web-font-ChessSansUsual.css"); .gameBoard, .boardTable { width: 392px !important; height: 392px !important; } .boardTable { border-style: solid; border-color: #663300; border-width: 4px; box-shadow: 0px 0px 20px #663300; } .pieceImage { width: 36px; height: 36px; } .whiteSquare, .blackSquare, .highlightWhiteSquare, .highlightBlackSquare { width: 44px; height: 44px; border-style: solid; border-width: 2px; } .whiteSquare, .highlightWhiteSquare { border-color: #FFCC99; background: #FFCC99; } .blackSquare, .highlightBlackSquare { border-color: #CC9966; background: #CC9966; } .highlightWhiteSquare, .highlightBlackSquare { border-color: #663300; } .selectControl { /* a "width" attribute here must use the !important flag to override default settings */ width: 100% !important; margin-top: 1em; } .optionSelectControl { } .gameButtons { width: 392px; } .buttonControlPlay, .buttonControlStop, .buttonControl { /* a "width" attribute here must use the !important flag to override default settings */ width: 75.2px !important; font-family: 'pgn4web ChessSansUsual', 'pgn4web Liberation Sans', sans-serif; font-size: 1em; color: #B0B0B0; -webkit-appearance: none; border: none; background: transparent; margin-top: 25px; margin-bottom: 10px; } .buttonControlSpace { /* a "width" attribute here must use the !important flag to override default settings */ width: 4px !important; } .searchPgnButton { /* a "width" attribute here must use the !important flag to override default settings */ width: 10% !important; } .searchPgnExpression { /* a "width" attribute here must use the !important flag to override default settings */ width: 90% !important; } .move, .variation, .comment { line-height: 1.4em; font-weight: normal; } .move, .variation, .commentMove { font-family: 'pgn4web ChessSansUsual', 'pgn4web Liberation Sans', sans-serif; } a.move, a.variation, .commentMove { white-space: nowrap; } .move, .variation { text-decoration: none; } .move { color: black; } .moveText { clear: both; text-align: justify; } .comment, .variation { color: #808080; } a.variation { color: #808080; } .moveOn, .variationOn { background-color: #FFCC99; } .selectSearchContainer { text-align: center; } .emMeasure { height: 1em; /* required */ padding-top: 1em; } .mainContainer { padding-top: 0.5em; padding-bottom: 1em; } .columnsContainer { float: left; width: 100%; } .boardColumn { float: left; width: 60%; } .headerColumn { margin-left: 60%; } .headerItem { width: 100%; height: 1.4em; white-space: nowrap; overflow: hidden; } .innerHeaderItem, .innerHeaderItemNoMargin { color: black; text-decoration: none; } .innerHeaderItem { margin-right: 1.25em; } .innerHeaderItemNoMargin { margin-right: 0px; } .headerSpacer { height: 0.66em; } .gameAnnotationContainer { height: 6em; width: 100%; } .toggleComments, .toggleAnalysis { white-space: nowrap; text-align: right; } .toggleCommentsLink, .toggleAnalysisLink, .backButton { display: inline-block; width: 1em; padding-left: 1em; text-decoration: none; text-align: right; color: #B0B0B0; } .gameAnnotationMessage { display: inline-block; white-space: nowrap; color: #B0B0B0; margin-top: 25px; margin-bottom: 10px; } .lastMoveAndVariations { float: left; } .lastMove { } .lastVariations { padding-left: 1em; } .nextMoveAndVariations { float: right; } .nextMove { } .nextVariations { padding-right: 1em; } .backButton { } .lastMoveAndComment { clear: both; line-height: 1.4em; display: none; } .lastComment { clear: both; resize: vertical; overflow-y: auto; height: 4.2em; min-height: 1.4em; max-height: 21em; padding-right: 1em; margin-bottom: 1em; text-align: justify; } .analysisEval { display: inline-block; min-width: 3em; } .analysisMove { } .tablebase { display: none; } .analysisPv { margin-left: 0.5em; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  <
 
END; } function print_chessboard_two() { global $pgnText, $pgnTextbox, $pgnUrl, $pgnFileName, $pgnFileSize, $pgnStatus, $tmpDir, $debugHelpText, $pgnDebugInfo; global $fileUploadLimitIniText, $fileUploadLimitText, $fileUploadLimitBytes, $startPosition, $goToView, $zipSupported; print <<
END; } function print_footer() { global $pgnText, $pgnTextbox, $pgnUrl, $pgnFileName, $pgnFileSize, $pgnStatus, $tmpDir, $debugHelpText, $pgnDebugInfo; global $fileUploadLimitIniText, $fileUploadLimitText, $fileUploadLimitBytes, $startPosition, $goToView, $zipSupported; if ($goToView) { $hashStatement = " goToHash('board');"; } else { $hashStatement = ""; } if (($pgnDebugInfo) != "") { $pgnDebugMessage = "warning: system: " . $pgnDebugInfo; } else {$pgnDebugMessage = ""; } print << "use strict"; function pgn4web_onload(e) { setPgnUrl("$pgnUrl"); checkPgnFormTextSize(); start_pgn4web(); if ("$pgnDebugMessage".length > 0) { myAlert("$pgnDebugMessage", false, true); } $hashStatement } END; } function print_html_close() { print << END; } ?>