fetch(PDO::FETCH_ASSOC)) { $rows[] = $row; } return $rows; } public static function getName($locationId) { self::getLocationsAssoc(); $locationId = (int)$locationId; if (!isset(self::$assocLocationCache[$locationId])) return false; return self::$assocLocationCache[$locationId]['locationname']; } 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; } }