The challenge:
Take Adam Walker’s Carrajina dictionary (http://carrajina.conlang.org/dicthome.html) and stick it in a database so that Adam can add an entry whenever he wants without re-writing an html page and possibly messing up his html. One stricture is that Adam does not want to learn too much new stuff – no SQL, no PHP, just HTML. And if he can enter SAMPA and have it turn into IPA, that’s a plus!
Step 1 (data prep) is here, Step 2 (create database and load data) is here, and Step 3 (generating listings) is here. Part 4 on adding new entries is here. This is part 5.
Updating an entry uses the same form as adding an entry, but with the values pre-filled. Here is a screenshot of the form with an entry to edit. 
And here is the code to generate this form. First some code in the html head:
switch ($lang) {
case 'eng':
if ((isset($id)) && (is_numeric($id))) {
$_SESSION['id'] = $id;
$data = new EnglishEntry($mysqli, $id);
$task = 'edit';
$_SESSION['task'] = $task;
$dbc = new EnglishController();
}
break;
case 'car':
if ((isset($id)) && (is_numeric($id))) {
$_SESSION['id'] = $id;
$data = new CarrajinaEntry($mysqli, $id);
$task = 'edit';
$_SESSION['task'] = $task;
$dbc = new CarrajinaController();
}
break;
}
?>
Now for code in the body:
<!-- the big form -->
<form method="post" action="edit.php">
<?php
$term = null;
$pron = null;
$defs = null;
if (isset($data)) {
$term = $data->getTerm();
$pron = $data->getPron();
$delforms[] = $dbc->formDelete($id, 'delentry',
"Delete Full Entry "$term"");
$defs = $data->getDefs();
}
?>
<!-- term and pronounciation -->
<p>
Word <input type="text" id="term" name="term"
value="<?php echo $term; ?>" />
Sampa or IPA <input
type="text" id="pron" name="pron" value="<?php echo $pron; ?>"
class="ipa" />
<span class="replace">click for ipa</span>
</p>
Easy enough. The $delforms array is used to hold delete links for each item that can be independently deleted.
<!-- definitions -->
<?php
$i = 1;
if (isset($defs)) {
foreach ($defs as $defno => $defentry) {
$delforms[] = $dbc->formDelete($defentry[0],
'deldef', "Delete Def #$defno");
?>
<p>
Def # <input type="text" class="num"
name="<?php echo "def[$defno][defno]"; ?>"
value="<?php echo $defno; ?>" />
POS <input type="text"
class="dp" name="<?php echo "def[$defno][pos]"; ?>"
value="<?php echo $defentry[1]; ?>" />
Definition Text
<textarea rows='3' cols='48' name="<?php echo
"def[$defno][deftext]"; ?>"><?php echo $defentry[2]; ?></textarea>
<input type="hidden" name="<?php echo "def[$defno][defid]"; ?>"
value="<?php echo $defentry[0]; ?>" />
</p>
<?php
$i = $defno + 1;
}
}
?>
<!-- add a definition -->
<div class="animate">
<p class="toggleable">New Definition +</p>
<div class="newitem">
<p>Def # <input type="text" class="num"
name="<?php echo "def[$i][defno]"; ?>" /> POS
<input type="text" class="dp" name="<?php echo "def[$i][pos]"; ?>" />
Definition Text <textarea rows='3' cols='48'
name="<?php echo "def[$i][deftext]"; ?>"></textarea>
</p>
</div>
</div>
This code prints definition form fields for each definition plus form fields for adding a new definition. The following adds the other form fields for English or for Carrajina entries.
<!-- extras -->
<!-- English first -->
<?php
if ($lang == 'eng') {
//subentries
$j = 1;
if (isset($data)) {
$subids = $data->getSubIDs();
$count = count($subids);
if ($count != 0) {
foreach ($subids as $subid) {
$sub = new EnglishEntry($mysqli, $subid);
$sterm = $sub->getTerm();
$spron = $sub->getPron();
$delforms[] = $dbc->formDelete($subid, 'delsub',
"Delete Subentry "$sterm"");
?>
<p>
Subentry <input type="text"
name="<?php echo "subentry[$j][sterm]"; ?>"
value="<?php echo $sterm; ?>" /> Sampa or IPA
<input type="text" name="<?php echo "subentry[$j][spron]"; ?>"
value="<?php echo $spron; ?>" class="ipa" />
<span class="replace">click for ipa</span>
<input type="hidden" name="<?php echo "subentry[$j][subid]"; ?>"
value="<?php echo $subid; ?>" />
</p>
<?php
//subentry defs
$defs = $sub->getDefs();
$k = 1;
if (!empty($defs)) {
foreach ($defs as $defno => $defentry) {
$delforms[] = $dbc->formDelete($defentry[0],
'deldef', "Delete Subentry "$sterm" Def #$defno");
?>
<p>
Def # <input type="text" class="num" value="<?php echo $defno; ?>"
name="<?php echo "subentry[$j][sdef][$defno][defno]"; ?>" />
POS <input type="text" class="dp"
value="<?php echo $defentry[1]; ?>"
name="<?php echo "subentry[$j][sdef][$defno][pos]"; ?>" />
Definition Text <textarea rows='3' cols='48'
name="<?php echo "subentry[$j][sdef][$defno][deftext]"; ?>"><?php
echo $defentry[2]; ?></textarea>
<input type="hidden" value="<?php echo $defentry[0]; ?>"
name="<?php echo "subentry[$j][sdef][$defno][defid]"; ?>" />
</p>
<?php
$k = $defno + 1;
}//end foreach ($defs as $defno => $defentry)
}//end if (!empty($defs))
?>
<div class="animate">
<p class="toggleable">New Subentry Definition +</p>
<div class="newitem">
<p>
Def # <input type="text" class="num"
name="<?php echo "subentry[$j][sdef][$k][defno]"; ?>" />
POS <input type="text" class="dp"
name="<?php echo "subentry[$j][sdef][$k][pos]"; ?>" />
Definition Text <textarea rows='3' cols='48'
name="<?php echo "subentry[$j][sdef][$k][deftext]"; ?>"></textarea>
<input type="hidden"
name="<?php echo "subentry[$j][sdef][$k][defid]"; ?>" />
</p>
</div>
</div>
<?php
$j++;
}//end foreach ($subids as $subid)
}//end if ($count != 0)
}//end if (isset($data))
?>
<!-- new subentry -->
<div class="animate">
<p class="toggleable">New Subentry +</p>
<div class="newitem">
<p>
Subentry <input type="text"
name="<?php echo "subentry[$j][sterm]"; ?>" />
Sampa or IPA
<input type="text" name="<?php echo "subentry[$j][spron]"; ?>"
class="ipa" />
<span class="replace">click for ipa</span>
</p>
<p>
Def # <input type="text" class="num"
name="<?php echo "subentry[$j][sdef][1][defno]"; ?>" />
POS <input type="text" class="dp"
name="<?php echo "subentry[$j][sdef][1][pos]"; ?>" />
Definition Text <textarea rows='3' cols='48'
name="<?php echo "subentry[$j][sdef][1][deftext]"; ?>"></textarea>
</p>
</div>
</div>
<!-- Carrajina extras -->
<?php
} else if ($lang == 'car') {
$etym = null;
if (isset($data)) {
$etym = $data->getEtymology();
}//end if (isset($data))
?>
<!-- etymology -->
<p>Etymology
<textarea rows='3' cols='48' name="etymology"><?php
echo $etym; ?></textarea>
</p>
<!-- Idioms -->
<p class="help">Idioms should be entered in lower case.</p>
<?php
$idioms = null;
$p = 1;
if (isset($data)) {
$idioms = $data->getIdioms();
if (!empty($idioms)) {
foreach ($idioms as $idiomentry) {
$delforms[] = $dbc->formDelete($idiomentry[2],
'delidiom',"Delete Idiom "$idiomentry[0]"");
?>
<p>
Idiom <input type="text" name="<?php echo "idioms[$p][idiom]"; ?>"
value="<?php echo $idiomentry[0]; ?>" />
Definition <textarea rows='3' cols='48'
name="<?php echo "idioms[$p][idiomdef]"; ?>"><?php
echo $idiomentry[1]; ?></textarea>
<input type="hidden" name="<?php echo "idioms[$p][idiomid]"; ?>"
value="<?php echo $idiomentry[2]; ?>" />
</p>
<?php
$p++;
}//end foreach ($idioms as $idiomentry)
}//end if (!empty($idioms))
}//end if (isset($data))
?>
<!-- New idioms -->
<div class="animate">
<p class="toggleable">New Idiom +</p>
<div class="newitem">
<p>Idiom
<input type="hidden" name="<?php echo "idioms[$p][idiomid]"; ?>" />
<input type="text" name="<?php echo "idioms[$p][idiom]"; ?>" />
Definition
<textarea rows='3' cols='48' name="<?php
echo "idioms[$p][idiomdef]"; ?>"></textarea>
</p>
</div>
</div>
<!-- Note -->
<?php
$note = null;
if (isset($data)) {
$note = $data->getNote();
if ($note[0] > 0) {
$delforms[] = $dbc->formDelete($note[0], 'delnote',
"Delete Note for "$term"");
}
}
?>
<p>
Note
<input type="hidden" name="note[noteid]"
value="<?php echo "$note[0]"; ?>" />
<textarea rows='3' cols='48' name="note[note]"><?php
echo "$note[1]"; ?></textarea>
</p>
<?php
}//end if lang
?>
<!-- Submit! -->
<p><input type="hidden" name="task" value="<?php echo $task; ?>" />
<input type="hidden" name="lang" value="<?php echo $lang; ?>" />
<!-- this will be blank for new entries -->
<input type="hidden" name="entryID"
value="<?php if (isset($id)) {echo $id;} ?>" />
<input type="submit" value="Submit!" /></p>
</form>
<!-- Now for those nasty deletes -->
<div>
<?php
if (isset($delforms)) {
echo "<h2>Deletes</h2>";
foreach ($delforms as $form) {
echo $form;
}
}
?>
</div>
That’s the form. One thing that might bite: Make sure there is no space or other characters between empty <textarea></textarea> code. If there is, the space will show up as a value when processing the data.
The code for processing updates is very similar to the code for processing adds.
public function updateEntry($mysqli, $entry) {
$id = $this->sanitize($entry['entryID']);
$term = $this->process($entry['term']);
$pron = $this->process($entry['pron']);
$etym = $this->process($entry['etymology']);
$csort = $this->getSort($term);
$query = "UPDATE carrajina_entry SET carrajina_sort=?,
carrajina_term=?, carrajina_pronounciation=?,
etymology=? WHERE carrajina_entryID =?";
$stmt = $mysqli->stmt_init();
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param("ssssi", $csort, $term, $pron, $etym, $id);
$stmt->execute();
$stmt->close();
}
//update defs and add new defs for entry, if
foreach ($entry['def'] as $def) {
if (!empty($def['defid'])) {
$this->updateCardefs($mysqli, $def);
} else {
$this->addDefs($mysqli, $def, $id);
}
}
//update idioms, if and add new, if
if (isset($entry['idioms'])) {
foreach ($entry['idioms'] as $idiom) {
if (!empty($idiom['idiomid'])) {
$this->updateIdioms($mysqli, $idiom);
} else {
$this->addIdioms($mysqli, $idiom, $id);
}
}
}
//update note, if
if (!empty($entry['note']['noteid'])) {
$noteid = $this->process($entry['note']['noteid']);
$note = $this->process($entry['note']['note']);
$query = "UPDATE carrajina_note SET note=? WHERE noteID =?";
$stmt = $mysqli->stmt_init();
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_param("si", $note, $noteid);
$stmt->execute();
$stmt->close();
}
} else if (!empty($entry['note']['note'])) {
$this->addNote($mysqli, $entry['note'], $id);
} else {
//nada
}
return $id;
}
And that is pretty much it. I enjoyed doing this and I think Adam enjoyed having it done.












