summaryrefslogblamecommitdiffstats
path: root/modules-available/locations/inc/location.inc.php
blob: 1a01ff242221099a7c3a6328806c61585894fdb6 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                                                                                








                                                                              


































































































































                                                                                                                            
<?php

class Location
{

	private static $flatLocationCache = false;
	private static $assocLocationCache = false;
	
	public static function queryLocations()
	{
		$res = Database::simpleQuery("SELECT locationid, parentlocationid, locationname FROM location");
		$rows = array();
		while ($row = $res->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;
	}

}