$database_modifications = Database_Modifications::getInstance(); $session_logic = Session_Logic::getInstance(); $bible = $_POST['bible']; $book = $_POST['book']; $chapter = $_POST['chapter']; $verse = $_POST['verse']; $usfm = $_POST['usfm']; $checksum = $_POST['checksum']; // Check on information about where to save the verse. $save = isset($bible) && isset($book) && isset($chapter) && isset($verse) && isset($usfm); if (!$save) { echo Locale_Translate::_("Don't know where to save"); die; } // Checksum. if (Checksum_Logic::get($usfm) != $checksum) { http_response_code(409); echo Locale_Translate::_("Checksum error"); die; } // Check there's anything to save at all. $usfm = trim($usfm); if ($usfm == "") { echo Locale_Translate::_("Nothing to save"); die; } // Check on valid UTF-8. if (!Validate_Utf8::valid($usfm)) { echo Locale_Translate::_("Cannot save: Needs Unicode"); die; }
<?php /* Copyright (©) 2003-2014 Teus Benschop. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ require_once "../bootstrap/bootstrap.php"; page_access_level(Filter_Roles::TRANSLATOR_LEVEL); $bible = $_GET['bible']; $book = $_GET['book']; $chapter = $_GET['chapter']; $database_bibles = Database_Bibles::getInstance(); $usfm = $database_bibles->getChapter($bible, $book, $chapter); echo Checksum_Logic::send($usfm);
$database_logs->log("Failure sending Bibles", Filter_Roles::TRANSLATOR_LEVEL); // Restore the Bible action for this chapter. $database_bibleactions->delete($bible, $book, $chapter); $database_bibleactions->record($bible, $book, $chapter, $oldusfm); } else { if ($response != "") { // The first line of the response can contain a message as a string. // This is what the server says to the client in case of an error. // Normally the first line of the response contains a numerical value. // This value is the checksum of the data that the server returns in the subsequent lines. // This data would be the updated USFM for the chapter. $response = explode("\n", $response); $checksum_message = array_shift($response); if (is_numeric($checksum_message)) { $response = implode("\n", $response); if (Checksum_Logic::get($response) == $checksum_message) { Bible_Logic::storeChapter($bible, $book, $chapter, $response); } else { // Checksum error. // The chapter will not be stored on the client. // That is fine for just now, because the pending sync action will do it. $database_logs->log("Checksum error while receiving chapter from server", Filter_Roles::TRANSLATOR_LEVEL); } } else { $database_logs->log("The server says: {$checksum_message}", Filter_Roles::TRANSLATOR_LEVEL); } } else { // If the server sends no response, // then the server decided that there is no need to send the updated chapter back to the client, // as it considers the client as already up to date. }
} else { if ($action == "book") { // The server responds with the checksum of the whole book. $server_checksum = Checksum_Logic::getBook($bible, $book); echo $server_checksum; } else { if ($action == "chapters") { // The server responds with the list of books in the Bible book. $server_chapters = $database_bibles->getChapters($bible, $book); $server_chapters = implode("\n", $server_chapters); $checksum = Checksum_Logic::get($server_chapters); echo "{$checksum}\n{$server_chapters}"; } else { if ($action == "chapter") { // The server responds with the checksum of the whole chapter. $server_checksum = Checksum_Logic::getChapter($bible, $book, $chapter); echo $server_checksum; } else { if ($action == "get") { // The server responds with the USFM of the chapter, prefixed by a checksum. $usfm = $database_bibles->getChapter($bible, $book, $chapter); $checksum = Checksum_Logic::get($usfm); echo "{$checksum}\n{$usfm}"; } } } } } } } }
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ require_once "../bootstrap/bootstrap.php"; page_access_level(Filter_Roles::TRANSLATOR_LEVEL); $database_config_user = Database_Config_User::getInstance(); $database_logs = Database_Logs::getInstance(); $database_bibles = Database_Bibles::getInstance(); $database_modifications = Database_Modifications::getInstance(); $session_logic = Session_Logic::getInstance(); $bible = $_POST['bible']; $book = $_POST['book']; $chapter = $_POST['chapter']; $html = $_POST['html']; $checksum = $_POST['checksum']; if (isset($bible) && isset($book) && isset($chapter) && isset($html) && isset($checksum)) { if (Checksum_Logic::get($html) == $checksum) { $html = trim($html); if ($html != "") { if (Validate_Utf8::valid($html)) { $stylesheet = $database_config_user->getStylesheet(); $editor_export = Editor_Export::getInstance(); $editor_export->load($html); $editor_export->stylesheet($stylesheet); $editor_export->run(); $usfm = $editor_export->get(); $book_chapter_text = Filter_Usfm::import($usfm, $stylesheet); foreach ($book_chapter_text as $data) { $book_number = $data[0]; $chapter_number = $data[1]; $chapter_data_to_save = $data[2]; if (($book_number == $book || $book_number == 0) && $chapter_number == $chapter) {
if ($mergedusfm == $serverusfm) { // When the merged USFM is the same as what's already on the server, then it means there was a merge conflict. // Email the user with the details, so the user can resolve the conflicts. $subject = "Problem sending chapter to server"; $body = "<p>While sending {$bible} {$bookname} {$chapter} to the server, the server didn't manage to merge it.</p>"; $body .= "<p>Please re-enter your changes as you see fit.</p>"; $body .= "<p>Here is the chapter you sent to the server:</p>"; $body .= "<pre>{$newusfm}</pre>"; $database_mail->send($username, $subject, $body); } else { // Update the server with the new chapter data. Bible_Logic::storeChapter($bible, $book, $chapter, $mergedusfm); } } } // If text was saved, record it as a change entered by the user. $new_id = $database_bibles->getChapterId($bible, $book, $chapter); if ($new_id != $old_id) { $database_modifications = Database_Modifications::getInstance(); $database_modifications->recordUserSave($username, $bible, $book, $chapter, $old_id, $old_text, $new_id, $new_text); } // Send the updated chapter back to the client. // Do this only in case the updated chapter USFM is different from the new USFM the client sent. // This means that in most cases, nothing will be sent back. // That saves bandwidth. // And it allows the user on the client to keep editing without the returned chapter to overwrite the changes the user made. $serverusfm = $database_bibles->getChapter($bible, $book, $chapter); if ($serverusfm != $newusfm) { $checksum = Checksum_Logic::get($serverusfm); echo "{$checksum}\n{$serverusfm}"; }
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ require_once "../bootstrap/bootstrap.php"; page_access_level(Filter_Roles::TRANSLATOR_LEVEL); $bible = $_GET['bible']; $book = $_GET['book']; $chapter = $_GET['chapter']; $database_bibles = Database_Bibles::getInstance(); $database_config_user = Database_Config_User::getInstance(); $stylesheet = $database_config_user->getStylesheet(); $usfm = $database_bibles->getChapter($bible, $book, $chapter); $editor_import = Editor_Import::getInstance(); $editor_import->load($usfm); $editor_import->stylesheet($stylesheet); $editor_import->run(); $html = $editor_import->get(); echo Checksum_Logic::send($html);
if ($client_checksum == $server_checksum) { continue; } // Different checksums: Get the USFM for the chapter as it is on the server. $database_logs->log(Locale_Translate::_("Getting chapter:") . " {$bible} {$book_name} {$chapter}", Filter_Roles::TRANSLATOR_LEVEL); $post = array("b" => $bible, "bk" => $book, "c" => $chapter, "a" => "get"); $server_usfm = Sync_Logic::post($post, $url); if ($server_usfm === false) { $database_logs->log(Locale_Translate::_("Failure getting chapter:") . " {$bible} {$book_name} {$chapter}", Filter_Roles::TRANSLATOR_LEVEL); continue; } // Verify the checksum of the chapter on the server, to be sure there's no corruption during transmission. $server_usfm = explode("\n", $server_usfm); $checksum = array_shift($server_usfm); $server_usfm = implode("\n", $server_usfm); if (!Checksum_Logic::get($server_usfm) == $checksum) { $database_logs->log(Locale_Translate::_("Checksum error while receiving chapter from server:") . " {$bible} {$book_name} {$chapter}", Filter_Roles::TRANSLATOR_LEVEL); continue; } // Check whether the user on the client has made changes in this chapter since the edits were sent to the server. // If there are none, then the client stores the chapter as it gets it from the server, and is done. $old_usfm = $database_bibleactions->getUsfm($bible, $book, $chapter); if ($old_usfm == "") { $database_bibles->storeChapter($bible, $book, $chapter, $server_usfm); continue; } // At this stage we're in a situation that there are changes on the client, and changes on the server. // Merge them. // It uses a 3-way merge, taking the chapter from the bible actions as the basis, and the other two (client and server) to merge together. // Store the merged data on the client. // It stores through the Bible Logic so the changes are staged to be sent.
public function testGetBibles2() { $checksum = Checksum_Logic::getBibles(array("phpunit3", "phpunit4")); $this->assertEquals("020eb29b524d7ba672d9d48bc72db455", $checksum); }