";
echo "";
$fp = fopen("diagrams/graphmodel.xml", "r");
fpassthru($fp);
fclose($fp);
echo "";
echo "";
if (is_file($delta))
{
$fp = fopen($delta, "r+");
fpassthru($fp);
fclose($fp);
}
echo "";
echo "";
// Deletes existing buffer
if (is_file($filename))
{
unlink($filename);
}
touch($filename);
chmod($filename, 0777);
}
else
{
// Gets the XML parameter from the POST request and converts all linefeeds
// into a HTML entity. This is required for correct handling of the XML on
// the client side.
if (isset($_POST["xml"]))
{
$xml = str_replace("\n", "
", stripslashes($_POST["xml"]));
// TODO: Take only the edits from the XML
$edits = "";
$doc = mxUtils::parseXml($xml);
$child = $doc->documentElement;
if ($child->nodeName == "message")
{
$child = $child->firstChild;
while ($child != null)
{
if ($child->nodeName == "delta")
{
$edit = $child->firstChild;
while ($edit != null)
{
if ($edit->nodeName == "edit")
{
$edits .= $doc->saveXML($edit);
}
$edit = $edit->nextSibling;
}
}
$child = $child->nextSibling;
}
}
// Appends the change to all connected sessions except the incoming
// session and the global delta file
if (strlen($edits) > 0)
{
mxLog::debug("received changes from ".session_id().
": ".strlen($edits)." bytes");
// Makes sure the global delta file exists so that the change is
// appended below
if (!is_file($delta))
{
touch($delta);
chmod($delta, 0777);
}
// Clears out the delta file if this change contains a mxRootChange
// in which case the previous changes will no longer be visible and
// just waste bandwidth.
if (strpos($edits, "mxRootChange") > 0)
{
$fp = fopen($delta, "r+");
fpassthru($fp);
ftruncate($fp, 0);
fflush($fp);
fclose($fp);
}
// Dispatches the XML to all sessions except the incoming session
// TODO: Remove dead sessions
$fp = opendir($document);
while($filename = readdir($fp))
{
if ($filename!= "." &&
$filename != ".." &&
!is_dir("$document/$filename") &&
$filename != session_id())
{
mxLog::debug("dispatch changes to $filename");
$tmp = fopen("$document/$filename", "a");
fwrite($tmp, $edits);
fflush($tmp);
fclose($tmp);
}
}
flush();
}
}
else
{
// Makes sure to cancel existing pending requests before they consume the
// change data after a refresh, where the request must be served instead.
$requestid = md5(uniqid(rand(), true));
$_SESSION['requestid'] = $requestid;
session_commit();
mxLog::debug("request $requestid enters");
if (!is_file($filename))
{
touch($filename);
chmod($filename, 0777);
}
else
{
// Keeps the request for 10 secs and asks for changes each second
$timeout = 10;
$count = 0;
while (is_file($filename) &&
filesize($filename) == 0 &&
$count < $timeout &&
$_SESSION['requestid'] == $requestid)
{
sleep(1);
clearstatcache();
$count++;
// Sync the session state
session_start();
session_commit();
}
// Sync the session state
session_start();
session_commit();
if ($_SESSION['requestid'] != $requestid)
{
mxLog::debug("request $requestid has died");
}
else if (filesize($filename) > 0)
{
mxLog::debug("request $requestid leaves: ".filesize($filename)." bytes");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/xhtml+xml");
// Sends the changes to the client
echo "";
echo "";
$fp = fopen($filename, "r+");
fpassthru($fp);
ftruncate($fp, 0);
fflush($fp);
fclose($fp);
echo "";
echo "";
}
else
{
touch($filename);
}
}
}
}
mxLog::leave();
mxLog::close();
?>