string edit_load (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string bible = request->query ["bible"]; int book = convert_to_int (request->query ["book"]); int chapter = convert_to_int (request->query ["chapter"]); // Store a copy of the USFM loaded in the editor for later reference. storeLoadedUsfm (webserver_request, bible, book, chapter, "edit"); string stylesheet = request->database_config_user()->getStylesheet (); string usfm = request->database_bibles()->getChapter (bible, book, chapter); Editor_Usfm2Html editor_usfm2html; editor_usfm2html.load (usfm); editor_usfm2html.stylesheet (stylesheet); editor_usfm2html.run (); string html = editor_usfm2html.get (); // To make editing empty verses easier, convert spaces to non-breaking spaces, so they appear in the editor. if (usfm_contains_empty_verses (usfm)) { string search = "<span> </span>"; string replace = "<span>" + unicode_non_breaking_space_entity () + "</span>"; html = filter_string_str_replace (search, replace, html); } string user = request->session_logic ()->currentUser (); bool write = access_bible_book_write (webserver_request, user, bible, book); return Checksum_Logic::send (html, write); }
string editverse_load (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string bible = request->query ["bible"]; int book = convert_to_int (request->query ["book"]); int chapter = convert_to_int (request->query ["chapter"]); int verse = convert_to_int (request->query ["verse"]); string usfm = request->database_bibles()->getChapter (bible, book, chapter); usfm = usfm_get_verse_text (usfm, verse); usfm = filter_string_str_replace ("\n", "<br>", usfm); string chapter_verse_text; string needle = "\\c"; if (verse) needle = "\\v"; size_t pos = usfm.find (needle); if (pos != string::npos) { if (pos < 2) { usfm.erase (0, pos + 2); usfm = filter_string_trim (usfm); chapter_verse_text = usfm_peek_verse_number (usfm); usfm.erase (0, chapter_verse_text.length ()); usfm = filter_string_trim (usfm); } } usfm.insert (0, "<span contenteditable=\"true\">"); usfm.append ("</span>"); if (!chapter_verse_text.empty ()) { string spacer; if (verse) spacer = " "; usfm.insert (0, "<span " + filter_css_grey_background () + ">" + needle + " " + chapter_verse_text + spacer + "</span>"); } string user = request->session_logic ()->currentUser (); bool write = access_bible_book_write (webserver_request, user, bible, book); return Checksum_Logic::send (usfm, write); }
string editusfm_save (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string bible = request->post["bible"]; int book = convert_to_int (request->post["book"]); int chapter = convert_to_int (request->post["chapter"]); string usfm = request->post["usfm"]; string checksum = request->post["checksum"]; if (request->post.count ("bible") && request->post.count ("book") && request->post.count ("chapter") && request->post.count ("usfm")) { if (Checksum_Logic::get (usfm) == checksum) { usfm = filter_url_tag_to_plus (usfm); usfm = filter_string_trim (usfm); if (usfm != "") { if (unicode_string_is_valid (usfm)) { string stylesheet = request->database_config_user()->getStylesheet(); vector <BookChapterData> book_chapter_text = usfm_import (usfm, stylesheet); for (BookChapterData & data : book_chapter_text) { int book_number = data.book; int chapter_number = data.chapter; string chapter_data_to_save = data.data; if (((book_number == book) || (book_number == 0)) && (chapter_number == chapter)) { string ancestor_usfm = getLoadedUsfm (webserver_request, bible, book, chapter, "editusfm"); // Collect some data about the changes for this user. string username = request->session_logic()->currentUser (); int oldID = request->database_bibles()->getChapterId (bible, book, chapter); string oldText = ancestor_usfm; string newText = chapter_data_to_save; // Merge if the ancestor is there and differs from what's in the database. if (!ancestor_usfm.empty ()) { string server_usfm = request->database_bibles ()->getChapter (bible, book, chapter); if (server_usfm != ancestor_usfm) { // Prioritize the USFM to save. chapter_data_to_save = filter_merge_run (ancestor_usfm, server_usfm, chapter_data_to_save); Database_Logs::log (translate ("Merging and saving chapter.")); } } // Check on write access. if (access_bible_book_write (request, "", bible, book)) { // Safely store the chapter. string message = usfm_safely_store_chapter (request, bible, book, chapter, chapter_data_to_save); if (message.empty()) { #ifndef CLIENT_PREPARED // Server configuration: Store details for the user's changes. int newID = request->database_bibles()->getChapterId (bible, book, chapter); Database_Modifications database_modifications; database_modifications.recordUserSave (username, bible, book, chapter, oldID, oldText, newID, newText); Database_Git::store_chapter (username, bible, book, chapter, oldText, newText); #endif // Store a copy of the USFM loaded in the editor for later reference. storeLoadedUsfm (webserver_request, bible, book, chapter, "editusfm"); return locale_logic_text_saved (); } return message; } else { return translate("No write access"); } } else { Database_Logs::log ("The following data could not be saved and was discarded: " + chapter_data_to_save); return translate("Passage mismatch"); } } } else { Database_Logs::log ("The text was not valid Unicode UTF-8. The chapter could not saved and has been reverted to the last good version."); return translate("Needs Unicode"); } } else { Database_Logs::log ("There was no text. Nothing was saved. The original text of the chapter was reloaded."); return translate("Nothing to save"); } } else { request->response_code = 409; return translate("Checksum error"); } } else { return translate("Nothing to save"); } return translate ("Confusing data"); }
string search_replacepre2 (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string siteUrl = Database_Config_General::getSiteURL (); // Get search variables from the query. string searchfor = request->query ["q"]; string replacewith = request->query ["r"]; bool casesensitive = (request->query ["c"] == "true"); string id = request->query ["id"]; bool searchplain = (request->query ["p"] == "true"); // Get the Bible and passage for this identifier. Passage details = Passage::from_text (id); string bible = details.bible; int book = details.book; int chapter = details.chapter; string verse = details.verse; // Get the plain text or the USFM. string text; if (searchplain) { text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse)); } else { text = search_logic_get_bible_verse_usfm (bible, book, chapter, convert_to_int (verse)); } // Clickable passage. string link = filter_passage_link_for_opening_editor_at (book, chapter, verse); string oldtext = filter_string_markup_words ({searchfor}, text); string newtext (text); if (casesensitive) { newtext = filter_string_str_replace (searchfor, replacewith, newtext); } else { vector <string> needles = filter_string_search_needles (searchfor, text); for (auto & needle : needles) { newtext = filter_string_str_replace (needle, replacewith, newtext); } } if (replacewith != "") newtext = filter_string_markup_words ({replacewith}, newtext); // The id sent to the browser contains bible identifier, book, chapter, and verse. int bibleID = request->database_bibles()->getID (bible); vector <string> bits = {convert_to_string (bibleID), convert_to_string (book), convert_to_string (chapter), verse}; string s_id = filter_string_implode (bits, "_"); // Check whether the user has write access to the book. string user = request->session_logic ()->currentUser (); bool write = access_bible_book_write (webserver_request, user, bible, book); // Create output. string output; output.append ("<div id=\"" + s_id + "\">\n"); output.append ("<p>"); if (write) output.append ("<a href=\"replace\"> ✔ </a> <a href=\"delete\"> ✗ </a> "); output.append (link); output.append ("</p>\n"); output.append ("<p>" + oldtext + "</p>\n"); output.append ("<p>"); if (write) output.append (newtext); else output.append (locale_logic_text_no_privileges_modify_book ()); output.append ("</p>\n"); output.append ("</div>\n"); // Output to browser. return output; }
string bible_book (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; Assets_Header header = Assets_Header (translate("Book"), webserver_request); header.addBreadCrumb (menu_logic_settings_menu (), menu_logic_settings_text ()); header.addBreadCrumb (bible_manage_url (), menu_logic_bible_manage_text ()); page = header.run (); Assets_View view; string success_message; string error_message; // The name of the Bible. string bible = access_bible_clamp (request, request->query["bible"]); view.set_variable ("bible", filter_string_sanitize_html (bible)); // The book. int book = convert_to_int (request->query ["book"]); view.set_variable ("book", convert_to_string (book)); string book_name = Database_Books::getEnglishFromId (book); view.set_variable ("book_name", filter_string_sanitize_html (book_name)); // Whether the user has write access to this Bible book. bool write_access = access_bible_book_write (request, "", bible, book); if (write_access) view.enable_zone ("write_access"); // Delete chapter. string deletechapter = request->query ["deletechapter"]; if (deletechapter != "") { string confirm = request->query ["confirm"]; if (confirm == "") { Dialog_Yes dialog_yes = Dialog_Yes ("book", translate("Would you like to delete this chapter?")); dialog_yes.add_query ("bible", bible); dialog_yes.add_query ("book", convert_to_string (book)); dialog_yes.add_query ("deletechapter", deletechapter); page += dialog_yes.run (); return page; } if (confirm == "yes") { if (write_access) Bible_Logic::deleteChapter (bible, book, convert_to_int (deletechapter)); } } // Add chapter. if (request->query.count ("createchapter")) { Dialog_Entry dialog_entry = Dialog_Entry ("book", translate("Please enter the number for the new chapter"), "", "createchapter", ""); dialog_entry.add_query ("bible", bible); dialog_entry.add_query ("book", convert_to_string (book)); page += dialog_entry.run (); return page; } if (request->post.count ("createchapter")) { int createchapter = convert_to_int (request->post ["entry"]); vector <int> chapters = request->database_bibles ()->getChapters (bible, book); // Only create the chapters if it does not yet exist. if (find (chapters.begin(), chapters.end(), createchapter) == chapters.end()) { vector <string> feedback; bool result = true; if (write_access) result = book_create (bible, book, createchapter, feedback); string message = filter_string_implode (feedback, " "); if (result) success_message = message; else error_message = message; } else { error_message = translate ("This chapter already exists"); } } // Available chapters. vector <int> chapters = request->database_bibles ()->getChapters (bible, book); string chapterblock; for (auto & chapter : chapters) { chapterblock.append ("<a href=\"chapter?bible="); chapterblock.append (bible); chapterblock.append ("&book="); chapterblock.append (convert_to_string (book)); chapterblock.append ("&chapter="); chapterblock.append (convert_to_string (chapter)); chapterblock.append ("\">"); chapterblock.append (convert_to_string (chapter)); chapterblock.append ("</a>\n"); } view.set_variable ("chapterblock", chapterblock); view.set_variable ("success_message", success_message); view.set_variable ("error_message", error_message); if (!client_logic_client_enabled ()) view.enable_zone ("server"); page += view.render ("bible", "book"); page += Assets_Page::footer (); return page; }