getAccessLevel($lid); } if ($accessLevel == $ACL_ACCESS_ADMIN_HIGH) { if (ContentHandler::writeNewFile($loggedInUser,$lid,$title,$content) && ContentHandler::addHistory(Language::lookupName($lid) . "/" . $title, $loggedInUser->getUID(), $lid, $content,ContentHandler::$QUEUE_ENTRY_NEW, $loggedInUser)) { $retVal = ContentHandler::$CONTENT_POSTED; } else $retVal = ContentHandler::$CONTENT_FAILURE; } else { if (ContentHandler::addQueue($lid, $title, $content, ContentHandler::$QUEUE_ENTRY_NEW, $loggedInUser, $ip)) $retVal = ContentHandler::$CONTENT_QUEUED; else $retVal = ContentHandler::$CONTENT_FAILURE; } return $retVal; } public static function submitEdit($loggedInUser, $ip, $file, $content) { require_once("languages.php"); global $ACL_ACCESS_NOBODY; global $ACL_ACCESS_NOBODY_VERIFIED; global $ACL_ACCESS_ADMIN_LOW; global $ACL_ACCESS_ADMIN_HIGH; $retVal = -1; if (substr($content, strlen($content) - 1, 1) != "\n") $content .= "\n"; $diff = ContentHandler::makeDiff($file, $content); if ($diff == null) return ContentHandler::$CONTENT_NO_CHANGE; $langName = substr($file, 0, strpos($file, "/")); $lid = Language::lookupLID($langName); $accessLevel = $ACL_ACCESS_NOBODY; if (isset($loggedInUser) && ($loggedInUser != null)) { $accessLevel = $loggedInUser->getAccessLevel($lid); } echo "Access level: $accessLevel
langid: $lid
"; if (($accessLevel == $ACL_ACCESS_ADMIN_LOW) || ($accessLevel == $ACL_ACCESS_ADMIN_HIGH)) { if (ContentHandler::applyDiff($file, $diff)) { if (ContentHandler::addHistory($file, $loggedInUser->getUID(), $lid, $diff, ContentHandler::$QUEUE_ENTRY_EDIT, $loggedInUser)) { $retVal = ContentHandler::$CONTENT_POSTED; } else { $retVal = ContentHandler::$CONTENT_FAILURE; } } else $retVal = ContentHandler::$CONTENT_FAILURE; } else { if (ContentHandler::addQueue($lid, $file, $diff, ContentHandler::$QUEUE_ENTRY_EDIT, $loggedInUser, $ip)) $retVal = ContentHandler::$CONTENT_QUEUED; else $retVal = ContentHandler::$CONTENT_FAILURE; } return $retVal; } public static function approveQueueEntry($pid, $loggedInUser){ global $CMS_CONTENT_PATH; settype($pid, "integer"); $retVal = ContentHandler::$CONTENT_FAILURE; $db = getDBConnection(); $result = mysql_query("SELECT UID,LID,path,type,data FROM PendingQueue WHERE PID=" . $pid, $db); if (!$result) die("Error while approving queue entry!"); $row = mysql_fetch_row($result); $uid = $row[ 0 ]; $lid = $row[ 1 ]; $path = $row[ 2 ]; $type = $row[ 3 ]; $data = addslashes($row[ 4 ]); settype($uid, "integer"); settype($lid, "integer"); settype($type, "integer"); $accessLevel = $loggedInUser->getAccessLevel($lid); if ($type == 0) { if ($accessLevel != ACLs::$ACL_ACCESS_ADMIN_HIGH) die("Error: You have insufficient privileges to approve new submissions!"); if (ContentHandler::writeNewFile($loggedInUser, $lid, $path, $data) && ContentHandler::addHistory($path,$uid,$lid,$data,$type,$loggedInUser) && ContentHandler::delQueue($pid)) { $retVal = ContentHandler::$CONTENT_POSTED; } else $retVal = ContentHandler::$CONTENT_FAILURE; } else if ($type == 1) { if ($accessLevel < ACLs::$ACL_ACCESS_ADMIN_LOW) die("Error: You have insufficient privileges to approve new submissions!"); $db = getDBConnection(); $result = mysql_query("SELECT path,data FROM PendingQueue WHERE PID=" . $pid, $db); if (!$result) die("Error while retrieving from pending queue!: " . $pid); $row = mysql_fetch_row($result); $path = $row[ 0 ]; $diff = $row[ 1 ]; mysql_close($db); if (ContentHandler::applyDiff($path, $diff) && ContentHandler::addHistory($path, $loggedInUser->getUID(), $lid, $diff, ContentHandler::$QUEUE_ENTRY_EDIT, $loggedInUser) && ContentHandler::delQueue($pid)) { $retVal = ContentHandler::$CONTENT_POSTED; } else $retVal = ContentHandler::$CONTENT_FAILURE; } else die("Internal error!"); return $retVal; } public static function rejectQueueEntry($pid) { if (ContentHandler::delQueue($pid)) return ContentHandler::$CONTENT_SUCCESS; else return ContentHandler::$CONTENT_FAILURE; } private static function getUnusedPID($db) { $needToClose = false; if ($db == null) { $db = getDBConnection(); $needToClose = true; } $result = mysql_query("SELECT MAX(PID) FROM PendingQueue", $db); if (!$result) { die('Error getting unused PID: ' . mysql_error()); } $retVal = mysql_result($result, 0); settype($retVal, "integer"); $retVal++; mysql_free_result($result); if ($needToClose) mysql_close($db); return $retVal; } private static function getUnusedHID($db) { $needToClose = false; if ($db == null) { $db = getDBConnection(); $needToClose = true; } $result = mysql_query("SELECT MAX(HID) FROM History", $db); if (!$result) { die('Error getting unused HID: ' . mysql_error()); } $retVal = mysql_result($result, 0); settype($retVal, "integer"); $retVal++; mysql_free_result($result); if ($needToClose) mysql_close($db); return $retVal; } private static function writeNewFile($loggedInUser, $lid, $title, $data) { global $CMS_CONTENT_FS_PATH; global $FILE_MODE; global $CONTENT_HEADER; global $CONTENT_FOOTER; $title = normalizeString($title); $langName = normalizeString(Language::lookupName($lid)); $relativePath = $langName . '/' . $title . '.html'; $filename = $CMS_CONTENT_FS_PATH . $relativePath; if (!($hFile = fopen($filename, "w+"))) die("Error while creating new file " . $filename); $footer = str_replace("%EDIT_URL%", $relativePath, $CONTENT_FOOTER); if (fwrite($hFile, $CONTENT_HEADER . $data . "\n" . $footer) === FALSE) die("Error while writing to file " . $filename); fclose($hFile); $oldumask = umask(0000); if (!chmod($filename, $FILE_MODE)) die("Error while chmod'ing file " . $filename); umask($oldumask); return true; } private static function makeDiff($originalFileName, $newContent) { global $CMS_CONTENT_FS_PATH; global $DIFF_PATH; $retVal = null; $tempFileOld = ContentHandler::extractContent($originalFileName); $tempFileNew = ContentHandler::tempFile($newContent); $command = $DIFF_PATH . ' -u ' . $tempFileOld. ' ' . $tempFileNew; $diff = array(); $diffRetVal = null; echo "Executing: " . $command . "
"; exec($command, $diff, $diffRetVal); if ($diffRetVal == 1) { $retVal = ''; for($i = 0; $i < count($diff); $i++) { $retVal .= ($diff[ $i ] . "\n"); } } if (unlink($tempFileOld) === false) die("Error while deleting temporary file: " . $tempFileOld); if (unlink($tempFileNew) === false) die("Error while deleting temporary file: " . $tempFileNew); echo 'Diff:
' . $retVal . '
'; return $retVal; } private static function tempFile($data) { global $TEMP_DIR; $oldumask = umask(0077); $randString = mt_rand(); settype($randString, "string"); $filename = $TEMP_DIR . "litcms" . $randString; if (!($hFile = fopen($filename, "w+"))) die("Error while creating temporary file!"); fwrite($hFile, $data); fclose($hFile); umask($oldumask); return $filename; } private static function applyDiff($originalFileName, $diff) { global $PATCH_PATH; global $CMS_CONTENT_FS_PATH; global $CONTENT_HEADER; global $CONTENT_FOOTER; // TODO: make backup of file before overwriting! $contentTempFile = ContentHandler::extractContent($originalFileName); $diffTempFile = ContentHandler::tempFile($diff); $command = $PATCH_PATH . ' -p0 ' . $contentTempFile . ' < ' . $diffTempFile; $patchResult = array(); $patchRetVal = -1; exec($command, $patchResult, $patchRetVal); if (unlink($diffTempFile) === false) my_log("Error while deleting temporary file: " . $diffTempFile); if ($patchRetVal == 0) { $hFile = null; if (!($hFile = fopen($contentTempFile, "r"))) die("Error while reading temporary content file: " . $contentTempFile); $newContent = fread($hFile, filesize($contentTempFile)); fclose($hFile); if (unlink($contentTempFile) === false) my_log("Error while deleting temporary file: " . $contentTempFile); if (!($hFile = fopen($CMS_CONTENT_FS_PATH . $originalFileName, "w+"))) { my_log("Error while applying the following diff file to $originalFileName:\n\n$diff\n\n"); } else { $newContent = $CONTENT_HEADER . $newContent . str_replace("%EDIT_URL%", $originalFileName, $CONTENT_FOOTER); fwrite($hFile, $newContent); fclose($hFile); $retVal = true; } } else { my_log("Error while applying the following diff file to $originalFileName:\n\n$diff\n\n"); if (unlink($contentTempFile) === false) my_log("Error while deleting temporary file: " . $contentTempFile); $retVal = false; } return $retVal; } private static function extractContent($file) { global $CMS_CONTENT_FS_PATH; $hFile = fopen($CMS_CONTENT_FS_PATH . $file, "r"); $content = fread($hFile, filesize($CMS_CONTENT_FS_PATH . $file)); fclose($hFile); $beginPos = strpos($content, ""); $endPos = strpos($content, ""); if (($beginPos === false) || ($endPos === false)) { die("Cannot read file " . $file); } else $beginPos += 19; $contentLen = $endPos - $beginPos; $content = substr($content, $beginPos, $contentLen); $tempFileName = ContentHandler::tempFile($content); return $tempFileName; } private static function addHistory($path, $uid, $lid, $data, $type, $loggedInUser) { $retVal = false; $db = getDBConnection(); $unusedHID = ContentHandler::getUnusedHID($db); $approvedbyUID = $loggedInUser->getUID(); $query = "INSERT INTO History VALUES($unusedHID,'$path',NOW(),$uid,$lid,'$data',$type,$approvedbyUID)"; $result = mysql_query($query, $db); if ($result) $retVal = true; else my_log("Error while executing: " . $query); mysql_close($db); return $retVal; } private static function addQueue($lid, $title, $content, $type, $loggedInUser, $ip) { $retVal = false; $db = getDBConnection(); $uid = -1; if ($loggedInUser != null) $uid = $loggedInUser->getUID(); $path = Language::lookupName($lid) . '/' . $title . '.html'; $query = "INSERT INTO PendingQueue VALUES(" . ContentHandler::getUnusedPID($db) . "," . $uid . "," . $lid . ",NOW(),'" . $ip . "','" . $path . "',$type,'" . $content . "')"; $result = mysql_query($query, $db); if ($result) $retVal = true; else my_log("Error while executing: " . $query); mysql_close($db); return $retVal; } private static function delQueue($pid) { settype($pid, "integer"); $retVal = false; $db = getDBConnection(); $result = mysql_query("DELETE FROM PendingQueue WHERE PID=" . $pid, $db); if (!$result || (mysql_affected_rows($db) != 1)) { $retVal = false; my_log("Error while deleting from pending queue!: " . $pid); } else $retVal = true; mysql_close($db); return $retVal; } } ?>