From 317db874e7964231ac33b5646cc33b1b400a4f29 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 19 Feb 2016 15:01:56 +0100 Subject: [locations] New module for managing locations --- inc/database.inc.php | 2 +- inc/defaultdata.inc.php | 24 +++++++- inc/location.inc.php | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 inc/location.inc.php (limited to 'inc') diff --git a/inc/database.inc.php b/inc/database.inc.php index 978f0bfd..735b2181 100644 --- a/inc/database.inc.php +++ b/inc/database.inc.php @@ -20,7 +20,7 @@ class Database */ public static function getExpectedSchemaVersion() { - return 11; + return 12; } public static function needSchemaUpdate() diff --git a/inc/defaultdata.inc.php b/inc/defaultdata.inc.php index 82ed1165..9bd31628 100644 --- a/inc/defaultdata.inc.php +++ b/inc/defaultdata.inc.php @@ -21,11 +21,12 @@ class DefaultData { $cats = array( 1 => 30, // Inactivity/Shutdown - 2 => 20, // Internet access + 2 => 50, // Internet access 3 => 100, // Timesync 4 => 10, // System config //5 => 15, // Public Shared folder 6 => 20000, // Unassigned/no category + 7 => 20, ); foreach ($cats as $cat => $sort) { Database::exec("INSERT IGNORE INTO cat_setting (catid, sortval) VALUES (:catid, :sortval)", array( @@ -169,6 +170,27 @@ class DefaultData 'permissions' => '2', 'validator' => '' ), + array( + 'setting' => 'SLX_VMCHOOSER_TAB', + 'catid' => '7', + 'defaultvalue' => 'AUTO', + 'permissions' => '2', + 'validator' => 'list:0|1|2|AUTO' + ), + array( + 'setting' => 'SLX_VMCHOOSER_TEMPLATES', + 'catid' => '7', + 'defaultvalue' => 'IGNORE', + 'permissions' => '2', + 'validator' => 'list:IGNORE|BUMP' + ), + array( + 'setting' => 'SLX_VMCHOOSER_FORLOCATION', + 'catid' => '7', + 'defaultvalue' => 'BUMP', + 'permissions' => '2', + 'validator' => 'list:IGNORE|BUMP|EXCLUSIVE' + ), ); foreach ($data as $entry) { Database::exec("INSERT IGNORE INTO setting (setting, catid, defaultvalue, permissions, validator)" diff --git a/inc/location.inc.php b/inc/location.inc.php new file mode 100644 index 00000000..39ecdf67 --- /dev/null +++ b/inc/location.inc.php @@ -0,0 +1,148 @@ +fetch(PDO::FETCH_ASSOC)) { + $rows[] = $row; + } + return $rows; + } + + public static function getLocationsAssoc() + { + if (self::$assocLocationCache === false) { + $rows = self::queryLocations(); + $rows = self::buildTree($rows); + self::$assocLocationCache = self::flattenTreeAssoc($rows); + } + return self::$assocLocationCache; + } + + private static function flattenTreeAssoc($tree, $depth = 0) + { + $output = array(); + foreach ($tree as $node) { + $output[(int)$node['locationid']] = array( + 'parentlocationid' => (int)$node['parentlocationid'], + 'locationname' => $node['locationname'], + 'depth' => $depth + ); + if (!empty($node['children'])) { + $output += self::flattenTreeAssoc($node['children'], $depth + 1); + } + } + return $output; + } + + public static function getLocations($default = 0, $excludeId = 0, $addNoParent = false) + { + if (self::$flatLocationCache === false) { + $rows = self::queryLocations(); + $rows = self::buildTree($rows); + $rows = self::flattenTree($rows); + self::$flatLocationCache = $rows; + } else { + $rows = self::$flatLocationCache; + } + $del = false; + unset($row); + foreach ($rows as $key => &$row) { + if ($del === false && $row['locationid'] == $excludeId) { + $del = $row['depth']; + } elseif ($del !== false && $row['depth'] <= $del) { + $del = false; + } + if ($del !== false) { + unset($rows[$key]); + continue; + } + if ($row['locationid'] == $default) { + $row['selected'] = true; + } + } + if ($addNoParent) { + array_unshift($rows, array( + 'locationid' => 0, + 'locationname' => '-----', + 'selected' => $default == 0 + )); + } + return array_values($rows); + } + + public static function buildTree($elements, $parentId = 0) + { + $branch = array(); + $sort = array(); + foreach ($elements as $element) { + if ($element['locationid'] == 0 || $element['locationid'] == $parentId) + continue; + if ($element['parentlocationid'] == $parentId) { + $children = self::buildTree($elements, $element['locationid']); + if (!empty($children)) { + $element['children'] = $children; + } + $branch[] = $element; + $sort[] = $element['locationname']; + } + } + array_multisort($sort, SORT_ASC, $branch); + return $branch; + } + + private static function flattenTree($tree, $depth = 0) + { + $output = array(); + foreach ($tree as $node) { + $output[] = array( + 'locationid' => $node['locationid'], + 'locationname' => $node['locationname'], + 'locationpad' => str_repeat('--', $depth), + 'locationspan1' => $depth + 1, + 'locationspan2' => 10 - $depth, + 'depth' => $depth + ); + if (!empty($node['children'])) { + $output = array_merge($output, self::flattenTree($node['children'], $depth + 1)); + } + } + return $output; + } + + public static function extractIds($tree) + { + $ids = array(); + foreach ($tree as $node) { + $ids[] = $node['locationid']; + if (!empty($node['children'])) { + $ids = array_merge($ids, self::extractIds($node['children'])); + } + } + return $ids; + } + + public static function getFromIp($ip) + { + $locationId = false; + $long = sprintf('%u', ip2long($ip)); + $net = Database::simpleQuery('SELECT locationid FROM subnet' + . ' WHERE :ip BETWEEN startaddr AND endaddr', array('ip' => $long)); + while ($row = $net->fetch(PDO::FETCH_ASSOC)) { + $locations = self::getLocationsAssoc(); + $id = (int)$row['locationid']; + if (!isset($locations[$id])) continue; + if ($locationId !== false && $locations[$id]['depth'] <= $locations[$locationId]['depth']) continue; + $locationId = $id; + } + return $locationId; + } + +} -- cgit v1.2.3-55-g7522