string editone_preview (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; bool touch = request->session_logic ()->touchEnabled (); string page; Assets_Header header = Assets_Header (translate("Preview"), request); header.setNavigator (); header.setEditorStylesheet (); if (touch) header.jQueryTouchOn (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); header.refresh (5, "index"); page = header.run (); Assets_View view; // Get active Bible, and check read access to it. // If needed, change Bible to one it has read access to. string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); string cls = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", cls); view.set_variable ("custom_css", Filter_Css::getCss (cls, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); int book = Ipc_Focus::getBook (webserver_request); int chapter = Ipc_Focus::getChapter (webserver_request); //int verse = Ipc_Focus::getVerse (webserver_request); 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 (); view.set_variable ("html", html); page += view.render ("editone", "preview"); page += Assets_Page::footer (); return page; }
string notes_actions (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Notes database_notes (webserver_request); Notes_Logic notes_logic = Notes_Logic (webserver_request); string page; Assets_Header header = Assets_Header (translate("Note actions"), request); header.setNavigator (); page += header.run (); Assets_View view; string success, error; string user = request->session_logic()->currentUser (); int level = request->session_logic()->currentLevel (); int id; if (request->query.count ("id")) id = convert_to_int (request->query ["id"]); else id = convert_to_int (request->post ["id"]); if (request->query.count ("unsubscribe")) { notes_logic.unsubscribe (id); } if (request->query.count ("subscribe")) { notes_logic.subscribe (id); } if (request->query.count ("unassign")) { string unassign = request->query["unassign"]; notes_logic.unassignUser (id, unassign); } if (request->query.count ("done")) { notes_logic.unassignUser (id, user); } if (request->query.count ("markdel")) { notes_logic.markForDeletion (id); success = translate("The note will be deleted after a week.") + " " + translate ("Adding a comment to the note cancels the deletion."); } if (request->query.count ("unmarkdel")) { notes_logic.unmarkForDeletion (id); } if (request->query.count ("delete")) { notes_logic.erase (id); redirect_browser (request, notes_index_url ()); return ""; } if (request->query.count ("publicnote")) { bool state = database_notes.getPublic (id); database_notes.setPublic (id, !state); } view.set_variable ("id", convert_to_string (id)); string summary = database_notes.getSummary (id); view.set_variable ("summary", summary); bool subscribed = database_notes.isSubscribed (id, user); if (subscribed) view.enable_zone ("subscribed"); else view.enable_zone ("subscribe"); vector <string> assignees = database_notes.getAssignees (id); string assigneeblock; for (auto & assignee : assignees) { assigneeblock.append (assignee); if (level >= Filter_Roles::manager ()) { assigneeblock.append ("<a href=\"?id=" + convert_to_string (id) + "&unassign=" + assignee + "\"> [" + translate("unassign") + "]</a>"); assigneeblock.append (" | "); } } view.set_variable ("assigneeblock", assigneeblock); if (level >= Filter_Roles::manager ()) view.enable_zone ("assign"); bool assigned = database_notes.isAssigned (id, user); if (assigned) view.enable_zone ("assigned"); string status = database_notes.getStatus (id); view.set_variable ("status", status); if (Filter_Roles::translator ()) view.enable_zone ("editstatus"); else view.enable_zone ("viewstatus"); string verses = filter_passage_display_inline (database_notes.getPassages (id)); view.set_variable ("verses", verses); string severity = database_notes.getSeverity (id); view.set_variable ("severity", severity); string bible = database_notes.getBible (id); view.set_variable ("bible", bible); if (bible.empty ()) view.enable_zone ("nobible"); if (level >= Filter_Roles::manager ()) view.enable_zone ("rawedit"); if (level >= Filter_Roles::manager ()) view.enable_zone ("marknote"); bool marked = database_notes.isMarkedForDeletion (id); if (marked) view.enable_zone ("marked"); else view.enable_zone ("mark"); #ifndef HAVE_CLIENT view.enable_zone ("cloud"); string on_off = styles_logic_off_on_inherit_toggle_text (database_notes.getPublic (id)); view.set_variable ("publicnote", on_off); #endif // Roles of translator or higher can edit the public visibility of a note. if (level >= Filter_Roles::translator ()) view.enable_zone ("translator"); view.set_variable ("success", success); view.set_variable ("error", error); page += view.render ("notes", "actions"); page += Assets_Page::footer (); return page; }
string public_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; // If the person providing public feedback is not logged in, foward to the page for entering details. if (!request->session_logic ()->loggedIn ()) { redirect_browser (request, public_login_url ()); return ""; } // Take the Bible for this user, and ensure that it is one of the Bibles that have public feedback enabled. string bible = request->database_config_user()->getBible (); vector <string> public_bibles = public_logic_bibles (webserver_request); if (!in_array (bible, public_bibles)) { bible.clear (); if (!public_bibles.empty ()) { bible = public_bibles [0]; } request->database_config_user()->setBible (bible); } // Switch Bible before displaying the passage navigator because the navigator contains the active Bible. if (request->query.count ("bible")) { bible = request->query ["bible"]; if (bible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to display"), "", ""); for (auto & bible : public_bibles) { dialog_list.add_row (bible, "bible", bible); } Assets_Header header = Assets_Header ("", request); string page = header.run (); page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (bible); } } string page; Assets_Header header = Assets_Header (translate ("Public feedback"), request); header.setNavigator (); header.setStylesheet (); page = header.run (); Assets_View view; string stylesheet = Database_Config_Bible::getExportStylesheet (bible); bible = request->database_config_user()->getBible (); view.set_variable ("bible", bible); // If there's more than one Bible with public feedback enabled, the public can select a Bible. if (public_bibles.size () > 1) { view.enable_zone ("bibles"); } string clss = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", clss); view.set_variable ("custom_css", Filter_Css::getCss (clss, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); Styles_Css styles_css = Styles_Css (&request, stylesheet); styles_css.exports (); styles_css.generate (); string css = styles_css.css (); view.set_variable ("exports_css", css); page += view.render ("public", "index"); page += Assets_Page::footer (); return page; }
string editverse_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; bool touch = request->session_logic ()->touchEnabled (); if (request->query.count ("switchbook") && request->query.count ("switchchapter")) { int switchbook = convert_to_int (request->query ["switchbook"]); int switchchapter = convert_to_int (request->query ["switchchapter"]); Ipc_Focus::set (request, switchbook, switchchapter, 1); Navigation_Passage::recordHistory (request, switchbook, switchchapter, 1); } string page; Assets_Header header = Assets_Header (translate("Edit USFM"), request); header.setNavigator (); if (touch) header.jQueryTouchOn (); header.notifItOn (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); page = header.run (); Assets_View view; if (request->query.count ("changebible")) { string changebible = request->query ["changebible"]; if (changebible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to open in the editor"), "", ""); vector <string> bibles = access_bible_bibles (request); for (auto bible : bibles) { dialog_list.add_row (bible, "changebible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (changebible); } } // Get active Bible, and check read access to it. // If needed, change Bible to one it has read access to. string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); if (request->query.count ("bible")) bible = access_bible_clamp (request, request->query ["bible"]); view.set_variable ("bible", bible); // Store the active Bible in the page's javascript. view.set_variable ("navigationCode", Navigation_Passage::code (bible)); string chapterLoaded = locale_logic_text_loaded (); string chapterSaving = locale_logic_text_saving (); string chapterSaved = locale_logic_text_saved (); string chapterRetrying = locale_logic_text_retrying (); string script = "var verseEditorVerseLoaded = '" + chapterLoaded + "';\n" "var verseEditorVerseSaving = '" + chapterSaving + "';\n" "var verseEditorVerseSaved = '" + chapterSaved + "';\n" "var verseEditorChapterRetrying = '" + chapterRetrying + "';\n" "var verseEditorWriteAccess = true;" "var unsentBibleDataTimeoutWarning = '" + bible_logic_unsent_unreceived_data_warning (false) + "';\n"; config_logic_swipe_enabled (webserver_request, script); view.set_variable ("script", script); string cls = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", cls); view.set_variable ("custom_css", Filter_Css::getCss (cls, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); // Whether to enable fast Bible editor switching. if (request->database_config_user ()->getFastEditorSwitchingAvailable ()) { view.enable_zone ("fastswitcheditor"); } page += view.render ("editverse", "index"); page += Assets_Page::footer (); return page; }
string edit_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; bool touch = request->session_logic ()->touchEnabled (); if (request->query.count ("switchbook") && request->query.count ("switchchapter")) { int switchbook = convert_to_int (request->query ["switchbook"]); int switchchapter = convert_to_int (request->query ["switchchapter"]); int switchverse = 1; if (request->query.count ("switchverse")) switchverse = convert_to_int (request->query ["switchverse"]); Ipc_Focus::set (request, switchbook, switchchapter, switchverse); Navigation_Passage::recordHistory (request, switchbook, switchchapter, switchverse); } string page; Assets_Header header = Assets_Header (translate("Edit"), request); header.setNavigator (); header.setEditorStylesheet (); if (touch) header.jQueryTouchOn (); header.notifItOn (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); page = header.run (); if (request->query.count ("changebible")) { string changebible = request->query ["changebible"]; if (changebible == "") { Dialog_List dialog_list = Dialog_List ("index", translate("Select which Bible to open in the editor"), "", ""); vector <string> bibles = access_bible_bibles (request); for (auto & bible : bibles) { dialog_list.add_row (bible, "changebible", bible); } page += dialog_list.run(); return page; } else { request->database_config_user()->setBible (changebible); // Going to another Bible, ensure that the focused book exists there. int book = Ipc_Focus::getBook (request); vector <int> books = request->database_bibles()->getBooks (changebible); if (find (books.begin(), books.end(), book) == books.end()) { if (!books.empty ()) book = books [0]; else book = 0; Ipc_Focus::set (request, book, 1, 1); } } } Assets_View view; // Active Bible, and check access. string bible = access_bible_clamp (request, request->database_config_user()->getBible ()); if (request->query.count ("bible")) bible = access_bible_clamp (request, request->query ["bible"]); view.set_variable ("bible", bible); // Store the active Bible in the page's javascript. view.set_variable ("navigationCode", Navigation_Passage::code (bible)); int verticalCaretPosition = request->database_config_user ()->getVerticalCaretPosition (); string script = "var editorChapterLoaded = '" + locale_logic_text_loaded () + "';\n" "var editorChapterSaving = '" + locale_logic_text_saving () + "';\n" "var editorChapterSaved = '" + locale_logic_text_saved () + "';\n" "var editorChapterRetrying = '" + locale_logic_text_retrying () + "';\n" "var editorChapterReformat = '" + locale_logic_text_reformat () + "';\n" "var editorWriteAccess = true;\n" "var verticalCaretPosition = " + convert_to_string (verticalCaretPosition) + ";\n" "var unsentBibleDataTimeoutWarning = '" + bible_logic_unsent_unreceived_data_warning (false) + "';\n"; config_logic_swipe_enabled (webserver_request, script); view.set_variable ("script", script); string clss = Filter_Css::getClass (bible); string font = Fonts_Logic::getTextFont (bible); int direction = Database_Config_Bible::getTextDirection (bible); int lineheight = Database_Config_Bible::getLineHeight (bible); int letterspacing = Database_Config_Bible::getLetterSpacing (bible); view.set_variable ("custom_class", clss); view.set_variable ("custom_css", Filter_Css::getCss (clss, Fonts_Logic::getFontPath (font), direction, lineheight, letterspacing)); // In basic mode the editor has no controls and fewer indicators. // In basic mode, the user can just edit text, and cannot style it. bool basic_mode = config_logic_basic_mode (webserver_request); if (!basic_mode) view.enable_zone ("advancedmode"); // Whether to enable fast Bible editor switching. if (!basic_mode && request->database_config_user ()->getFastEditorSwitchingAvailable ()) { view.enable_zone ("fastswitcheditor"); } // Whether to enable the styles button. if (request->database_config_user ()->getEnableStylesButtonVisualEditors ()) { view.enable_zone ("stylesbutton"); } page += view.render ("edit", "index"); page += Assets_Page::footer (); return page; }
string workbench_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; vector <string> desktops = workbench_get_names (request); // Set the requested desktop as the active one. if (request->query.count ("bench")) { unsigned int bench = convert_to_int (request->query ["bench"]); if (bench < desktops.size ()) { string workbench = desktops [bench]; request->database_config_user()->setActiveWorkbench (workbench); } } // Check that the active desktop exists, else set the first available desktop as the active one. { string desktop = request->database_config_user ()->getActiveWorkbench (); if (!in_array (desktop, desktops)) { if (!desktops.empty ()) { request->database_config_user ()->setActiveWorkbench (desktops [0]); } } } // Create default set of desktops if there are none. bool create = desktops.empty (); if (!create) { create = (desktops [0] == workbench_get_default_name ()); } if (create) { workbench_create_defaults (webserver_request); } // In case the desktop is opened from a consultation note email, // read the note, and set the active passage to the passage the note refers to. int noteid = convert_to_int (request->query ["note"]); if (noteid) { Database_Notes database_notes (webserver_request); vector <Passage> passages = database_notes.getPassages (noteid); if (!passages.empty ()) { Ipc_Focus::set (webserver_request, passages[0].book, passages[0].chapter, convert_to_int (passages[0].verse)); Navigation_Passage::recordHistory (webserver_request, passages[0].book, passages[0].chapter, convert_to_int (passages[0].verse)); } } string page; Assets_Header header = Assets_Header (translate("Desktop"), request); header.setNavigator (); header.setFadingMenu (menu_logic_desktop_category (webserver_request)); page = header.run (); Assets_View view; map <int, string> urls = workbench_get_urls (request, true); map <int, string> widths = workbench_get_widths (request); for (unsigned int key = 0; key < 15; key++) { string url = urls [key]; string width = widths [key]; int row = round (key / 5) + 1; int column = key % 5 + 1; string variable = "url" + convert_to_string (row) + convert_to_string (column); view.set_variable (variable, url); variable = "width" + convert_to_string (row) + convert_to_string (column); view.set_variable (variable, width); if (convert_to_int (width) > 0) view.enable_zone (variable); } map <int, string> heights = workbench_get_heights (request); for (unsigned int key = 0; key < 3; key++) { string height = heights [key]; int row = key + 1; string variable = "height" + convert_to_string (row); view.set_variable (variable, height); if (convert_to_int (height) > 0) view.enable_zone (variable); } string workbenchwidth = workbench_get_entire_width (request); if (!workbenchwidth.empty ()) { workbenchwidth.insert (0, "width: "); workbenchwidth.append (";"); } view.set_variable ("workbenchwidth", workbenchwidth); // The rendered template disables framekillers through the "sandbox" attribute on the iframe elements. page += view.render ("workbench", "index"); page += Assets_Page::footer (); return page; }
string search_search2 (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Volatile database_volatile = Database_Volatile (); string siteUrl = config_logic_site_url (); string bible = request->database_config_user()->getBible (); if (request->query.count ("bible")) bible = request->query ["bible"]; bool hit_is_set = request->query.count ("h"); bool query_is_set = request->query.count ("q"); int identifier = convert_to_int (request->query ["i"]); string query = request->query ["q"]; string hit = request->query ["h"]; // Get one search hit. if (hit_is_set) { // Retrieve the search parameters from the volatile database. string query = database_volatile.getValue (identifier, "query"); //bool casesensitive = convert_to_bool (database_volatile.getValue (identifier, "casesensitive")); bool plaintext = convert_to_bool (database_volatile.getValue (identifier, "plaintext")); // Get the Bible and passage for this identifier. Passage details = Passage::from_text (hit); string bible = details.bible; int book = details.book; int chapter = details.chapter; string verse = details.verse; // Get the plain text or USFM. string text; if (plaintext) { 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)); } // Format it. string link = filter_passage_link_for_opening_editor_at (book, chapter, verse); text = filter_string_markup_words ({query}, text); string output = "<div>" + link + " " + text + "</div>"; // Output to browser. return output; } // Perform the initial search. if (query_is_set) { // Get extra search parameters and store them all in the volatile database. bool casesensitive = (request->query ["c"] == "true"); bool plaintext = (request->query ["p"] == "true"); bool currentbook = (request->query ["b"] == "true"); string sharing = request->query ["s"]; database_volatile.setValue (identifier, "query", query); database_volatile.setValue (identifier, "casesensitive", convert_to_string (casesensitive)); database_volatile.setValue (identifier, "plaintext", convert_to_string (plaintext)); // Deal with case sensitivity. // Deal with whether to search the plain text, or the raw USFM. // Fetch the initial set of hits. vector <Passage> passages; if (plaintext) { if (casesensitive) { passages = search_logic_search_bible_text_case_sensitive (bible, query); } else { passages = search_logic_search_bible_text (bible, query); } } else { if (casesensitive) { passages = search_logic_search_bible_usfm_case_sensitive (bible, query); } else { passages = search_logic_search_bible_usfm (bible, query); } } // Deal with possible searching in the current book only. if (currentbook) { int book = Ipc_Focus::getBook (request); vector <Passage> bookpassages; for (auto & passage : passages) { if (book == passage.book) { bookpassages.push_back (passage); } } passages = bookpassages; } // Deal with how to share the results. vector <string> hits; for (auto & passage : passages) { hits.push_back (passage.to_text ()); } if (sharing != "load") { vector <string> loaded_hits = filter_string_explode (database_volatile.getValue (identifier, "hits"), '\n'); if (sharing == "add") { hits.insert (hits.end(), loaded_hits.begin(), loaded_hits.end()); } if (sharing == "remove") { hits = filter_string_array_diff (loaded_hits, hits); } if (sharing == "intersect") { hits = array_intersect (loaded_hits, hits); } hits = array_unique (hits); } // Generate one string from the hits. string output = filter_string_implode (hits, "\n"); // Store search hits in the volatile database. database_volatile.setValue (identifier, "hits", output); // Output results. return output; } // Build the advanced search page. string page; Assets_Header header = Assets_Header (translate("Search"), request); header.setNavigator (); header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ()); page = header.run (); Assets_View view; view.set_variable ("bible", bible); string script = "var searchBible = \"" + bible + "\";"; view.set_variable ("script", script); page += view.render ("search", "search2"); page += Assets_Page::footer (); return page; }
string search_strong (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Kjv database_kjv = Database_Kjv (); string bible = request->database_config_user()->getBible (); if (request->query.count ("b")) { bible = request->query ["b"]; } if (request->query.count ("load")) { int book = Ipc_Focus::getBook (request); int chapter = Ipc_Focus::getChapter (request); int verse = Ipc_Focus::getVerse (request); // Get Strong's numbers, plus English snippets. string html = "<table>\n"; vector <Database_Kjv_Item> details = database_kjv.getVerse (book, chapter, verse); for (auto & detail : details) { string strong = detail.strong; string english = detail.english; html += "<tr><td><a href=\"" + strong + "\">" + strong + "</a></td><td>" + english + "</td></tr>\n"; } html += "</table>\n"; return html; } if (request->query.count ("strong")) { string strong = request->query ["strong"]; strong = filter_string_trim (strong); vector <int> passages; vector <Passage> details = database_kjv.searchStrong (strong); for (auto & passage : details) { int i_passage = filter_passage_to_integer (passage); passages.push_back (i_passage); } passages = array_unique (passages); sort (passages.begin(), passages.end()); string output; for (auto & passage : passages) { if (!output.empty()) output.append ("\n"); output.append (convert_to_string (passage)); } return output; } if (request->query.count ("id")) { int id = convert_to_int (request->query ["id"]); // Get the and passage for this identifier. Passage passage = filter_integer_to_passage (id); int book = passage.book; int chapter = passage.chapter; string verse = passage.verse; // Get the plain text. string text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse)); // Format it. string link = filter_passage_link_for_opening_editor_at (book, chapter, verse); string output = "<div>" + link + " " + text + "</div>"; // Output to browser. return output; } string page; Assets_Header header = Assets_Header (translate("Search"), request); header.setNavigator (); header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ()); page = header.run (); Assets_View view; view.set_variable ("bible", bible); string script = "var searchBible = \"" + bible + "\";"; view.set_variable ("script", script); page += view.render ("search", "strong"); page += Assets_Page::footer (); return page; }
string bible_import (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; string page; Assets_Header header = Assets_Header (translate("Import"), webserver_request); header.setNavigator (); 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)); int book = Ipc_Focus::getBook (webserver_request); int chapter = Ipc_Focus::getChapter (webserver_request); // Whether the user has write access to this Bible. bool write_access = access_bible_write (request, bible); if (write_access) view.enable_zone ("write_access"); // USFM data submission. if (request->post.count ("submit")) { // Submission may take long if there's a lot of data or the network is slow. string data = request->post ["data"]; data = filter_url_tag_to_plus (data); data = filter_string_trim (data); if (data != "") { if (unicode_string_is_valid (data)) { string datafile = filter_url_tempfile (); filter_url_file_put_contents (datafile, data); success_message = translate("Import has started. See Journal for progress."); tasks_logic_queue (IMPORTBIBLE, { datafile, bible, convert_to_string (book), convert_to_string (chapter) }); } else { error_message = translate("Please supply valid Unicode UTF-8 text."); } } else { success_message = translate("Nothing was imported."); } // User imported something into this Bible: Set it as the default Bible. request->database_config_user()->setBible (bible); } // File upload. if (request->post.count ("upload")) { string datafile = filter_url_tempfile () + request->post ["filename"]; string data = request->post ["data"]; if (!data.empty ()) { filter_url_file_put_contents (datafile, data); success_message = translate("Import has started. See Journal for progress."); tasks_logic_queue (IMPORTBIBLE, { datafile, bible, convert_to_string (book), convert_to_string (chapter) }); } else { error_message = translate ("Nothing was uploaded"); } // User imported something into this Bible: Set it as the default Bible. request->database_config_user()->setBible (bible); } #ifdef HAVE_UPLOAD view.enable_zone ("enable_upload"); #else view.enable_zone ("disable_upload"); #endif view.set_variable ("success_message", success_message); view.set_variable ("error_message", error_message); page += view.render ("bible", "import"); page += Assets_Page::footer (); return page; }
string notes_index (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Notes database_notes (webserver_request); string page; Assets_Header header = Assets_Header (translate("Consultation Notes"), request); header.setNavigator (); header.addBreadCrumb (menu_logic_translate_menu (), menu_logic_translate_text ()); page = header.run(); Assets_View view; string error; string success; // Presets for notes selectors. // This is for the daily statistics and the workspace. if (request->query.count ("presetselection")) { request->database_config_user()->setConsultationNotesPassageSelector (3); request->database_config_user()->setConsultationNotesEditSelector (0); request->database_config_user()->setConsultationNotesNonEditSelector (0); request->database_config_user()->setConsultationNotesStatusSelector (""); request->database_config_user()->setConsultationNotesBibleSelector (""); request->database_config_user()->setConsultationNotesAssignmentSelector (""); request->database_config_user()->setConsultationNotesSubscriptionSelector (0); request->database_config_user()->setConsultationNotesSeveritySelector (-1); request->database_config_user()->setConsultationNotesTextSelector (0); string preset_selector = request->query ["presetselection"]; if (preset_selector == "assigned") { request->database_config_user()->setConsultationNotesAssignmentSelector (request->session_logic()->currentUser ()); } if (preset_selector == "subscribed") { request->database_config_user()->setConsultationNotesSubscriptionSelector (1); } if (preset_selector == "subscribeddayidle") { request->database_config_user()->setConsultationNotesSubscriptionSelector (1); request->database_config_user()->setConsultationNotesNonEditSelector (1); } if (preset_selector == "subscribedweekidle") { request->database_config_user()->setConsultationNotesSubscriptionSelector (1); request->database_config_user()->setConsultationNotesNonEditSelector (3); } if (preset_selector == "forverse") { request->database_config_user()->setConsultationNotesPassageSelector (0); } } int level = request->session_logic ()->currentLevel (); // Manager roles and higher can do mass updates on the notes. if (level >= Filter_Roles::manager ()) { // No mass updates in basic mode. if (!config_logic_basic_mode (webserver_request)) { view.enable_zone ("update"); } } // Whether the user can create a new note. if (access_logic_privilege_create_comment_notes (webserver_request)) { view.enable_zone ("create"); } page += view.render ("notes", "index"); page += Assets_Page::footer (); return page; }
string search_similar (void * webserver_request) { Webserver_Request * request = (Webserver_Request *) webserver_request; Database_Volatile database_volatile = Database_Volatile (); int myIdentifier = filter_string_user_identifier (request); string bible = request->database_config_user()->getBible (); if (request->query.count ("b")) { bible = request->query ["b"]; } if (request->query.count ("load")) { int book = Ipc_Focus::getBook (request); int chapter = Ipc_Focus::getChapter (request); int verse = Ipc_Focus::getVerse (request); // Text of the focused verse in the active Bible. // Remove all punctuation from it. string versetext = search_logic_get_bible_verse_text (bible, book, chapter, verse); vector <string> punctuation = filter_string_explode (Database_Config_Bible::getSentenceStructureEndPunctuation (bible), ' '); for (auto & sign : punctuation) { versetext = filter_string_str_replace (sign, "", versetext); } punctuation = filter_string_explode (Database_Config_Bible::getSentenceStructureMiddlePunctuation (bible), ' '); for (auto & sign : punctuation) { versetext = filter_string_str_replace (sign, "", versetext); } versetext = filter_string_trim (versetext); database_volatile.setValue (myIdentifier, "searchsimilar", versetext); return versetext; } if (request->query.count ("words")) { string words = request->query ["words"]; words = filter_string_trim (words); database_volatile.setValue (myIdentifier, "searchsimilar", words); vector <string> vwords = filter_string_explode (words, ' '); // Include items if there are no more search hits than 30% of the total number of verses in the Bible. size_t maxcount = round (0.3 * search_logic_get_verse_count (bible)); // Store how often a verse occurs in an array. // The keys are the identifiers of the search results. // The values are how often the identifiers occur in the entire focused verse. map <int, int> identifiers; for (auto & word : vwords) { // Find out how often this word occurs in the Bible. Skip if too often. vector <Passage> passages = search_logic_search_bible_text (bible, word); if (passages.size () > maxcount) continue; // Store the identifiers and their count. for (auto & passage : passages) { int id = filter_passage_to_integer (passage); if (identifiers.count (id)) identifiers [id]++; else identifiers [id] = 1; } } // Sort on occurrence from high to low. // Skip identifiers that only occur once. vector <int> ids; vector <int> counts; for (auto & element : identifiers) { int id = element.first; int count = element.second; if (count <= 1) continue; ids.push_back (id); counts.push_back (count); } quick_sort (counts, ids, 0, counts.size()); reverse (ids.begin(), ids.end()); // Output the passage identifiers to the browser. string output; for (auto & id : ids) { if (!output.empty ()) output.append ("\n"); output.append (convert_to_string (id)); } return output; } if (request->query.count ("id")) { int id = convert_to_int (request->query ["id"]); // Get the Bible and passage for this identifier. Passage passage = filter_integer_to_passage (id); string bible = request->database_config_user()->getBible (); // string bible = passage.bible; int book = passage.book; int chapter = passage.chapter; string verse = passage.verse; // Get the plain text. string text = search_logic_get_bible_verse_text (bible, book, chapter, convert_to_int (verse)); // Get search words. vector <string> words = filter_string_explode (database_volatile.getValue (myIdentifier, "searchsimilar"), ' '); // Format it. string link = filter_passage_link_for_opening_editor_at (book, chapter, verse); text = filter_string_markup_words (words, text); string output = "<div>" + link + " " + text + "</div>"; // Output to browser. return output; } string page; Assets_Header header = Assets_Header (translate("Search"), request); header.setNavigator (); header.addBreadCrumb (menu_logic_search_menu (), menu_logic_search_text ()); page = header.run (); Assets_View view; view.set_variable ("bible", bible); string script = "var searchBible = \"" + bible + "\";"; view.set_variable ("script", script); page += view.render ("search", "similar"); page += Assets_Page::footer (); return page; }