So how does the user input get saved dynamically to the database? It already happens in a similar way with post tags. Users enter them on the fly and they’re processed and the user interface is updated without needing a postback or page refresh.
The hard part was figuring how to tap into the existing AJAX / PHP functions from my child theme. After some deep, deep digging, I found the interactions in the WordPress core.
The key: hook into your php function with ‘wp_ajax_’ appended to the javascript function’s name
add_action('wp_ajax_process_bible_verses', 'bible_verses_ADD_callback'); function bible_verses_ADD_callback() { $verses = $_POST['verses']; $service = new IDWebService($verses); $verses = $service->verses; $xml = $service->xml; $id_firstBook = $service->id_firstBook; $id_firstChapter = $service->id_firstChapter; $id_firstVerse = $service->id_firstVerse; $id_secondBook = $service->id_secondBook; $id_secondChapter = $service->id_secondChapter; $id_secondVerse = $service->id_secondVerse; $id_sanitizedVerses = $service->sanitizedVerses; $exceptionBool = $service->exceptionBool; $exceptionMessage = $service->exceptionMessage; $verseformat = $service->GetVerseFormat($verses); $service->__destruct(); // Did this to solve memory leak; http://paul-m-jones.com/archives/262 unset($service); // however, leak probably came about from iterating through objects and not ints $post_id = intval( $_POST['post_id'] ); try { if ($exceptionBool == true) { //_log('exception prior to checking ...'.$exceptionMessage); die('<Error msg="'.$exceptionMessage.'" />'); } else { switch ($verseformat) { case "B": $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "B C": $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $bibleIDs[] = $id_firstChapter; $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "B C:V": $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $bibleIDs[] = $id_firstChapter; $bibleIDs[] = $id_firstVerse; $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "B C-C": $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $bibleIDs[] = $id_firstChapter; $bibleIDs[] = $id_secondChapter; // NOTE: Need to improve the logic to make this "B C-C" rather than "B C,C" $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "B C:V-V": // check to make sure second verse > first verse if ($id_firstVerse >= $id_secondVerse) { die('<Error msg="Choose a starting verse before the ending verse">'); } // _log('id_firstverse = '.$id_firstVerse); // _log('id_secondverse = '.$id_secondVerse); $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $bibleIDs[] = $id_firstChapter; for ($i = $id_firstVerse*1; $i < $id_secondVerse*1+1; $i++) { $bibleIDs[] = $i; } $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "B C:V,V": $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $bibleIDs[] = $id_firstChapter; $bibleIDs[] = $id_firstVerse; $bibleIDs[] = $id_secondVerse; $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "B C:V - C:V": case "B C:V - B C:V": // check to make sure second verse > first verse if ((int)$id_firstVerse >= (int)$id_secondVerse) { die('<Error msg="Choose a starting verse before the ending verse">'); } $bibleIDs = array(); $bibleIDs[] = $id_firstBook; $bibleIDs[] = $id_firstChapter; for ($i = $id_firstVerse*1; $i < $id_secondVerse*1+1; $i++) { $bibleIDs[] = $i; } $newCollectionID = bible_verses_addCollection($id_sanitizedVerses, $bibleIDs, $post_id); die('<collection id="'.$newCollectionID.'" name="'.$id_sanitizedVerses.'" />'); break; case "Error: Unknown Format (Book should be followed by Chapter number)": case "Error: Unknown Format (Are you missing a chapter?)": case "Error: Unknown Format (Are you trying to reference more than one verse? We suggest Book Chapter:Verse - Verse format)": echo '<Error '; echo 'msg="'.$verseformat.'" />'; break; default: echo ','; echo '<Error msg="Error: unknown Format" />'; } } // IMPORTANT: don't forget to "exit" exit; } catch (Exception $e) { die('<Error msg="'.$e.'" />'); exit; } }
Once the interaction’s happening correctly, the database insert statements look like normal SQL statements in the PHP:
function bible_verses_addCollection($collectionName, $arrayIds, $post_id) { global $wpdb; // Add collection to table $rowstatus = $wpdb->insert( $wpdb->prefix . "bible_terms_taxonomy", array( 'taxonomy' => $collectionName, 'term_id' => $post_id) ); $collectionID = $wpdb->insert_id; if ($rowstatus == 1) { foreach($arrayIds as $elemID) { $relationshipRowStatus = $wpdb->insert( $wpdb->prefix . "bible_terms_relationships", array('object_id' => $collectionID, 'term_id' => $elemID)); if ($relationshipRowStatus == 0) { $rowstatus = 0; } } return $collectionID; } else { return -1; } }
I ended up creating similar AJAX methods for the delete and GET / SELECT so that the Javascript methods had easy PHP functions to call.
So this is added to the function.php of a child theme? I’m recently learning to program by necessity. Looks like exactly what I’m trying to do, have sermons posted and referenced by verse.
Function.php is the place, Phil. Good luck – and let me know if you need help getting it working.