I made a dropdown menu that is populated from the joomla database. The menu contains names of peaks from a specific user. This part works smoothly. When the user selects the peak name from the dropdown menu and click the delete button, query should only delete the row with the id of the specific user ($link_id) and the name of the selected top ($vrh_name2).
In my case, query deletes all rows of this user regardless of the name of the selected top
Where did I make a mistake?
<!DOCTYPE html>
<html>
<body>
<?php
echo '<div class="sender">';
$link_id = JRequest::getInt('link_id');
echo '<h4>Form for delete peak</h4>';
// Creating Dropdown menu from database
$db = JFactory::getDbo();
$query2 = $db->getQuery(true);
$query2->select('peak_name');
$query2->from($db->qn('#__climbing'));
$query2->where($db->quoteName('#__climbing.link_id')." = ".$db->quote($link_id));
$query2->order('peak_id ASC');
$db->setQuery($query2);
$peaks_list2 = $db->loadColumn();
$peaks_select2 = '<select name2="name2" id2="peaks">';
$peaks_select2 .= '<option value="">-- Select peak for delete --</option>';
foreach($peaks_list2 as $p2){
$peaks_select2 .= '<option value="' . $p2 . '">' . $p2 . '</option>';
}
$peaks_select2 .= '</select>';
?>
<form name="lista2" method="post" action="">
<?php echo $peaks_select2; ?>
<input type="submit" name="submit2" value="Delete" />
</form>
<?php
if(isset($_POST['submit2']))
{
$vrh_name2 = $_POST['name2'];
// Delete peak query
$db = JFactory::getDbo();
$q_4 = $db->getQuery(true);
$q_4->delete($db->quoteName('#__climbing'));
$q_4->where($db->quoteName('#__climbing.link_id')." = ".$db->quote($link_id))." AND ".($db->quoteName('#__climbing.peak_name')." = ".$db->quote($vrh_name2));
$db->setQuery($q_4);
$db->execute();
}
echo '</div>';
?>
</body>
</html>
Let's not forget some of the past advice that I have offered.
Most noticeable in this question, $peaks_select2 = '<select name2=
will not work. The name
attribute must be unadulterated.
By performing the potential delete action first, you can allow your users to make delete after delete and always see the most up-to-date data in the select.
I don't like that you are using peak_name
as your identifier. Your table has a peak_id
, these are expected to be auto-incremented and unique in most cases and they are how professionals associate related data. (You should alter your design to adopt this practice.)
When an option's value
attribute value is the same as the option's text value, there is no need to declare the name
attribute. Because I am suggesting the use of the ids, I am declaring the name
attribute.
Untested snippet:
<!DOCTYPE html>
<html>
<body>
<?php
// get the $_POST['submit'] value; if missing, set as empty string (WORD is a Joomla-specific filter that strips unwanted characters for security reasons)
$action = JFactory::getApplication()->input->post->get('submit', '', 'WORD')
// get the $_POST['peak_id'] value; if missing set as 0 (INT strips any character that is not a digit)
$peak_id = JFactory::getApplication()->input->post->get('peak_id', 0, 'INT');
// try to get the $_POST['link_id'] value; if it is missing, try from $_GET['link_id']
$hiker_id = JFactory::getApplication()->input->post->get('link_id', 0, 'INT');
if (!$hiker_id)
{
// there was no submission (this is the first load of the page)
$hiker_id = JFactory::getApplication()->input->get->get('link_id', 0, 'INT');
}
echo "<div>Link Id: $hiker_id</div>";
$db = JFactory::getDbo();
if ($action === 'Delete' && $peak) // if action is Delete and $peak is not empty or 0
{
$delete_query = $db->getQuery(true)
->delete("#__climbing")
->where([
"link_id = " . (int) $hiker_id,
"peak_id = " . (int) $peak_id
]);
$db->setQuery($delete_query);
$db->execute();
if ($db->getAffectedRows()) // check for successful deletion (if at least one row was deleted)
{
echo "<div>Successfully deleted row for hiker#: $hiker_id, peak#: $peak_id</div>";
}
else
{
echo "<div>Failed to delete row for hiker#: $hiker_id, peak#: $peak_id</div>";
}
}
// now query the table for the fresh data after the (potential) delete was performed
$peaks_query = $db->getQuery(true)
->select("peak_id, peak_name")
->from("#__climbing")
->where("link_id = " . (int) $link_id)
->order("peak_id");
$db->setQuery($peaks_query);
$peaks_select = '<select name="peak_id">';
$peaks_select .= '<option value="0">-- Select peak to delete --</option>';
if (!$results = $db->loadAssocList()) // there were no rows in the result set
{
// no peaks found for $link_id
}
else
{
foreach ($results as $row)
{
$peaks_select .= "<option value=\"{$row['peak_id']}\">{$row['peak_name']}</option>"; // create option with name as text and id as the value
}
}
$peaks_select .= '</select>';
// print the simple form...
?>
<div class="sender">
<h4>Peak Delete Form</h4>
<form method="post" action="">
<?=$peaks_select?>
<input type="hidden" name="link_id" value="<?=$hiker_id?>">
<input type="submit" name="submit" value="Delete" />
</form>
</div>
</body>
</html>