<?php
/*****************************************************************************
IP Reg, a PHP/MySQL IPAM tool
Copyright (C) 2007-2009 Wietse Warendorff (up to v0.5)
Copyright (C) 2011-2023 Thomas Hooge
SPDX-License-Identifier: GPL-3.0-or-later
*****************************************************************************/
include("includes.php");
if (isset($_REQUEST['id'])) {
$id = (int) $_REQUEST['id'] or $id = 0;
}
// look for parents
// function to look for parents and create a new array for every child
function location($parents, $parent = 0) {
// loop array to check
foreach($parents[$parent] as $child) {
if(isset($parents[$child])) {
// element has children
$children[$child] = location($parents, $child);
} else {
// no children, set NULL
$children[$child] = NULL;
}
}
// and again...
return $children;
}
// recursive children check to template
function checkchildren($locations, $level) {
global $location_options;
global $location_names;
global $location_parent;
foreach ($locations as $parent=>$child) {
$row = str_repeat("- ", $level) . $location_names[$parent];
$location_options[$parent] = $row;
if (isset($child)) {
checkchildren($child, $level+1);
}
}
}
// ========== ADDITIONAL ACTION DEFINITIONS ===================================
define ('ACT_SUBNET_EDIT', 100);
define ('ACT_SUBNET_ADD', 101);
define ('ACT_SUBNET_DEL', 102);
// ========== ACTIONS START ===================================================
switch ($submit = form_get_action()) {
case NULL: break;
case 'add': $action = ACT_ADD; break;
case 'view': $action = ACT_VIEW; break;
case 'edit': $action = ACT_EDIT; break;
case 'del': $action = ACT_DELETE; break;
case 'link': $action = ACT_SUBNET_EDIT; break;
case 'exec-link':
if ($_POST['action'] == 'locationsubnetadd') {
$action = ACT_SUBNET_ADD;
} elseif ($_POST['action'] == 'locationsubnetdel') {
$action = ACT_SUBNET_DEL;
} else {
$g_warning->Add('invalid action!'. $_POST['action']);
}
break;
case 'insert':
$name = sanitize($_POST['location_name']);
$parent = sanitize($_POST['location_parent']);
$info = sanitize($_POST['location_info']);
$sql = "INSERT INTO location (
location_name, location_parent, location_info
)
VALUE (?, ?, ?)";
$sth = $dbh->prepare($sql);
$sth->execute([$name, $parent, $info]);
$id = $dbh->lastInsertId();
$action = ACT_VIEW;
break;
case 'update':
$location_name = sanitize($_POST['location_name']);
$location_info = sanitize($_POST['location_info']);
$parentlocation_id = sanitize($_POST['parentlocation_id']);
$sql = "UPDATE location SET
location_name=?, location_parent=?, location_info=?
WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$location_name, $parentlocation_id, $location_info, $id]);
$action = ACT_VIEW;
break;
case 'subnetlink':
$subnet_id = sanitize($_POST['subnet_id']);
$sql = "INSERT INTO subnetlocation (location_id, subnet_id) VALUE (?, ?)";
$sth = $dbh->prepare($sql);
$sth->execute([$id, $subnet_id]);
$action = ACT_VIEW;
break;
case 'subnetunlink':
$subnet_id = sanitize($_POST['subnet_id']);
$sth = $dbh->prepare("DELETE FROM subnetlocation WHERE location_id=? AND subnet_id=?");
$sth->execute([$id, $subnet_id]);
$g_message->Add('Link removed');
$action = ACT_VIEW;
break;
case 'delete':
$sth = $dbh->prepare("DELETE FROM subnetlocation WHERE location_id=?");
$sth->execute([$id]);
$n = $sth->rowCount();
if ($n > 0) {
$g_message->Add("$n Subnetzzuordnungen wurden entfernt.");
}
$sth = $dbh->prepare("DELETE FROM location WHERE location_id=?");
$g_message->Add("Standort wurde gelöscht.");
$sth->execute([$id]);
$action = ACT_DEFAULT;
break;
default:
$g_error->Add(submit_error($submit));
$valid = FALSE;
}
// ========== ACTIONS END =====================================================
include("header.php");
if ($action == ACT_DEFAULT):
// ========== VARIANT: default behavior =======================================
$sql = "SELECT location_id AS id, location_name AS value, location_parent AS parent_id
FROM location
ORDER BY location_parent, location_sort, location_name";
$sth = $dbh->query($sql);
$locations = $sth->fetchAll();
$smarty->assign('location_count', count($locations));
// function for recursion
function build_tree($parent_id, $level) {
global $locations;
$children = array();
foreach ($locations as $key => $location) {
if ($location['parent_id'] == $parent_id) {
unset($location['parent_id']);
$location['children'] = build_tree($location['id'], $level+1);
$location['level'] = $level;
$location['href'] = 'location.php?f=view& id=' . $location['id'];
$children[] = $location;
}
}
return $children;
}
$tree = build_tree(0, 0);
$smarty->assign("locations", $tree);
$smarty->display("location.tpl");
elseif ($action == ACT_ADD):
// ========== VARIANT: add record =============================================
$sql = "SELECT location_id AS id, location_name AS name,
location_parent AS parent, location_sort AS sort
FROM location
ORDER BY location_parent, location_sort, location_name";
$sth = $dbh->query($sql);
$locations = $sth->fetchAll();
if (count($locations) > 0) {
foreach ($locations AS $location) {
$location_names[$location['id']] = $location['name'];
$parents[$location['parent']][] = $location['id'];
}
}
$tree = location($parents);
// create tree option list
$location_options = array(0 => '-');
checkchildren($tree, 0);
$smarty->assign("location_options", $location_options);
$location_parent = sanitize($_GET['parent']);
$smarty->assign("location_parent", $location_parent);
$smarty->display("locationadd.tpl");
elseif ($action == ACT_VIEW):
// ========== VARIANT: view single record =====================================
// base location
$sql = "SELECT location_id AS id, location_name AS name,
location_parent AS parent_id, location_info AS info,
CONCAT('location.php?f=view& id=', location_id) AS url
FROM location
WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$location = $sth->fetch(PDO::FETCH_OBJ);
$smarty->assign("location", $location);
// crumbs
$crumbs[] = $location;
$sql = "SELECT location_id AS id, location_name AS name,
location_parent AS parent_id,
CONCAT('location.php?f=view& id=', location_id) AS url
FROM location
WHERE location_id=?";
$sth = $dbh->prepare($sql);
while ($crumbs[0]->parent_id != 0) {
$sth->execute([$crumbs[0]->parent_id]);
$result = $sth->fetch(PDO::FETCH_OBJ);
array_unshift($crumbs, $result);
}
$smarty->assign("crumbs", $crumbs);
// sublocations
$sql = "SELECT location_id AS sublocation_id, location_name AS sublocation_name,
LEFT(location_info, 40) AS info_short,
CHAR_LENGTH(location_info) AS info_length
FROM location
WHERE location_parent=?
ORDER BY location_name";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$smarty->assign("sublocations", $sth->fetchAll());
// subnets
$sql = "SELECT s.subnet_id, s.subnet_address, s.subnet_mask
FROM subnet AS s LEFT JOIN subnetlocation AS l USING (subnet_id)
WHERE l.location_id=?
ORDER BY INET_ATON(s.subnet_address)";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$smarty->assign("subnets", $sth->fetchAll());
$smarty->display("locationview.tpl");
elseif ($action == ACT_EDIT):
// ========== VARIANT: edit single record =====================================
// TODO implement sorting with location_sort
// location
$sql = "SELECT location_id AS id, location_name AS name, location_parent AS parent,
location_info AS info, location_sort AS sort
FROM location
WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$location = $sth->fetch(PDO::FETCH_OBJ);
$location_parent = $location->parent;
$smarty->assign("location", $location);
// parent location
$sql = "SELECT location_id, location_name, location_parent
FROM location
WHERE location_id != ?
ORDER BY location_name";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$locations = $sth->fetchAll();
$location_counter = count($locations);
$smarty->assign("location_counter", $location_counter);
// any locations?
if ($location_counter>0) {
foreach($locations AS $location) {
$location_names[$location['location_id']] = $location['location_name'];
$parents[$location['location_parent']][] = $location['location_id'];
}
}
$tree = location($parents);
$location_options = array(0 => '-');
checkchildren($tree, 0);
$smarty->assign("location_options", $location_options);
$smarty->assign("location_parent", $location_parent);
$smarty->display("locationedit.tpl");
elseif ($action == ACT_SUBNET_EDIT):
// ========== VARIANT: location to subnet =====================================
$sql = "SELECT location_id AS id, location_name AS name
FROM location
WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$smarty->assign("location", $sth->fetch(PDO::FETCH_OBJ));
$smarty->display("locationsubnetedit.tpl");
elseif ($action == ACT_SUBNET_ADD):
// ========== VARIANT: add location to subnet =================================
$sql = "SELECT location_id AS id, location_name AS name
FROM location
WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$smarty->assign("location", $sth->fetch(PDO::FETCH_OBJ));
// TODO Filter für bereits zugeordnete Subnetze
$smarty->assign("subnet_options", db_get_options_subnet());
$smarty->display("locationsubnetadd.tpl");
elseif ($action == ACT_SUBNET_DEL):
// ========== VARIANT: del location to subnet =================================
// location
$sql = "SELECT location_id AS id, location_name AS name
FROM location
WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$smarty->assign("location", $sth->fetch(PDO::FETCH_OBJ));
// subnet
$sql = "SELECT s.subnet_id, CONCAT_WS('/', s.subnet_address, s.subnet_mask)
FROM subnetlocation AS l LEFT JOIN subnet AS s USING (subnet_id)
WHERE l.location_id=?
ORDER BY INET_ATON(s.subnet_address)";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$options = array();
foreach ($sth->fetchAll(PDO::FETCH_NUM) as $rec) {
$options[$rec[0]] = $rec[1];
}
$smarty->assign("subnet_options", $options);
$smarty->display("locationsubnetdel.tpl");
elseif ($action == ACT_DELETE):
// ========== VARIANT: delete record ==========================================
$sql = "SELECT location_id AS id, location_name AS name FROM location WHERE location_id=?";
$sth = $dbh->prepare($sql);
$sth->execute([$id]);
$smarty->assign("location", $sth->fetch(PDO::FETCH_OBJ));
$smarty->display("locationdel.tpl");
else:
// ========== ERROR UNKNOWN VARIANT ===========================================
echo "< p > Unknown function call: Please report to system development!< / p > \n";
endif; // $action == ...
// ========== END OF VARIANTS =================================================
$smarty->display('footer.tpl');