<?php
###############################################################################
# dbinit.php
# Watch My Domains SED v3
# (c) Softnik Technologies. All rights reserved.
###############################################################################

if(defined("USE_AUTH_DB"))
	require_once("domainauth.php");
else
	require_once("domainpdo.php");

###############################################################################

function init_db($init_tables=false)
{
	if(defined("USE_AUTH_DB"))
		return init_auth_db($init_tables);
	
	if(wmDomainDatabase::$glb_domain_database === false)
	{
		global $db_config_dbtype, $db_table_prefix, $db_default_mysql_engine;
		global $db_config_host, $db_config_database, $db_config_username, $db_config_password;
		
		wmDomainDatabase::$glb_domain_database = new wmDomainDatabase($db_config_dbtype, $db_table_prefix);
		$dbh = false;
		if(strtolower($db_config_dbtype) == "mysql")
			$dbh = wmDomainDatabase::$glb_domain_database->openMySQL($db_config_host, $db_config_database, $db_config_username, $db_config_password);
		else
			wmDomainDatabase::$glb_domain_database->setError("Database type '$db_config_dbtype' is currently not supported.");
		if($dbh !== false)
		{
			if($init_tables)
			{
				wmDomainDatabase::$glb_domain_database->initTables($db_default_mysql_engine);
				include(get_php_folder_path()."config/defaults.tlds.php");
				wmDomainAuthDB::$glb_domain_database->SetPreference("root_url", get_root_url());
				if(isset($_SERVER['SERVER_ADDR']))
					wmDomainAuthDB::$glb_domain_database->SetPreference("server_ip_address", $_SERVER['SERVER_ADDR']);
			}
			return wmDomainDatabase::$glb_domain_database;
		}
		else
		{
			wmDomainDatabase::$last_init_error = wmDomainDatabase::$glb_domain_database->getLastError();
			wmDomainDatabase::$glb_domain_database = null;
			wmDomainDatabase::$glb_domain_database = false;
			return false;
		}
	}
	else
		return wmDomainDatabase::$glb_domain_database;
}

###############################################################################

function init_auth_db($init_tables=false)
{
	if(wmDomainAuthDB::$glb_domain_database === false)
	{
		global $db_config_dbtype, $db_table_prefix, $db_default_mysql_engine;
		global $db_config_host, $db_config_database, $db_config_username, $db_config_password;
		
		wmDomainAuthDB::$glb_domain_database = new wmDomainAuthDB($db_config_dbtype, $db_table_prefix);
		$dbh = false;
		if(strtolower($db_config_dbtype) == "mysql")
			$dbh = wmDomainAuthDB::$glb_domain_database->openMySQL($db_config_host, $db_config_database, $db_config_username, $db_config_password);
		else
			wmDomainAuthDB::$glb_domain_database->setError("Database type '$db_config_dbtype' is currently not supported.");
		if($dbh !== false)
		{
			if($init_tables)
			{
				wmDomainAuthDB::$glb_domain_database->initTables($db_default_mysql_engine);
				include(get_php_folder_path()."config/defaults.tlds.php");
				wmDomainAuthDB::$glb_domain_database->SetPreference("root_url", get_root_url());
				if(isset($_SERVER['SERVER_ADDR']))
					wmDomainAuthDB::$glb_domain_database->SetPreference("server_ip_address", $_SERVER['SERVER_ADDR']);
				
				// Legacy Problem, change the description field for Audit table to Text.
				$ftype = wmDomainAuthDB::$glb_domain_database->getFieldType(wmDomainAuthDB::$glb_domain_database->getAuditLogTableName(), "description");
				if(stristr($ftype, "varchar") !== false)
				{
					try 
					{
						$table = wmDomainAuthDB::$glb_domain_database->getAuditLogTableName();
						$sql = "ALTER TABLE `$table` MODIFY COLUMN `description` TEXT DEFAULT NULL";
						$q = wmDomainAuthDB::$glb_domain_database->db_connect_handle->prepare($sql);
						$q->execute();
					} 
					catch (PDOException $e) 
					{
						wmDomainAuthDB::$glb_domain_database->setError($e->getMessage());
					}
				}
			}
			return wmDomainAuthDB::$glb_domain_database;
		}
		else
		{
			wmDomainAuthDB::$last_init_error = wmDomainAuthDB::$glb_domain_database->getLastError();
			wmDomainAuthDB::$glb_domain_database = null;
			wmDomainAuthDB::$glb_domain_database = false;
			return false;
		}
	}
	else
		return wmDomainAuthDB::$glb_domain_database;
}

###############################################################################

function get_stranslation_array_for_whois_server($server)
{
    $xlat = array();
    $pdo = init_db();
    if($pdo !== false)
    {
        $rawdata = $pdo->getSingleEntry($pdo->getWhoisserverTableName(), "server", $server, "xlate");
        if($rawdata !== false && $rawdata != "")
        {
            if($rawdata != "")
            {
                $entries = explode("\n", $rawdata);
                foreach($entries as $k => $v)
                {
                    $kvpair = explode("=>", $v);
                    if(count($kvpair) == 2)
                    {
                        $kv = trim($kvpair[0], " \t\n\r\0\x0B'");
                        $vv = trim($kvpair[1], " \t\n\r\0\x0B'");
                        if($kv != "" && $vv != "")
                            $xlat[$kv] = $vv;
                    }
                }
            }
        }
    }
    return count($xlat) > 0 ? $xlat : false;
}

###############################################################################

function update_domain_table($data, $domain)
{
	// Feb 2018 .. temporary hack... to be redone.
	if(isset($data['address']))
	{
		if(strlen($data['address']) > 254)
			$data['address'] = substr($data['address'], 0, 254);
	}
	// Feb 2018 .. temporary hack... to be redone.
    $pdo = init_db();
    if($pdo !== false)
        return $pdo->setDomainDataFromArray($domain, $data);
    else
        return false;
}

###############################################################################

function get_dateformat_from_whoisserver($server)
{
    $format = "";
    $pdo = init_db();
    if($pdo !== false)
        $format = $pdo->getSingleEntry($pdo->getWhoisserverTableName(), "server", $server, "dateformat");
    return $format;
}

###############################################################################

function set_querystring_for_whoisserver($server, $qstring)
{
    $pdo = init_db();
    if($pdo !== false)
	{
		$tablename = $pdo->getWhoisserverTableName();
		$count = $pdo->getCount($tablename, "server='$server'");
		if($count !== false && $count == 0)
			return $pdo->insertIntoTable($tablename, array('query'=>$qstring, 'server'=>$server)); 
		else
			return $pdo->updateTable($tablename, "query=? where server=?", array($qstring, $server)); 
	}
	return false;
}

###############################################################################

function get_searchtoken_from_whoisserver($server)
{
    $token = "";
    $pdo = init_db();
    if($pdo !== false)
        $token = $pdo->getSingleEntry($pdo->getWhoisserverTableName(), "server", $server, "searchtoken");
    return $token;
}

###############################################################################

function set_searchtoken_for_whoisserver($server, $token)
{
    $pdo = init_db();
    if($pdo !== false)
	{
		$tablename = $pdo->getWhoisserverTableName();
		$count = $pdo->getCount($tablename, "server='$server'");
		if($count !== false && $count == 0)
			return $pdo->insertIntoTable($tablename, array('searchtoken'=>$token, 'server'=>$server)); 
		else
			return $pdo->updateTable($tablename, "searchtoken=? where server=?", array($token, $server)); 
	}
	return false;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

function get_whoisdata_for_domain($domain)
{
	$whoisdata = array();
	$pdo = init_db();
    if($pdo !== false)
	{
		$rows = $pdo->getTableData($pdo->getDomainTableName(), "registrar_whois,registry_whois,ip_whois", "where domain=?", array($domain));
		if($rows !== false)
		{
			foreach($rows as $row)
			{
				foreach($row as $key=>$value)
					$whoisdata[$key] = str_replace("<br>", "\n", $value);
			}
		}
	}
	return $whoisdata;
}

###############################################################################

function reset_domain_table($domain)
{
    $pdo = init_db();
    if($pdo !== false)
        return $pdo->resetDomainData($domain, get_db_resettable_domain_whois_columns());
    else
        return false;
}

###############################################################################

function get_whois_server_for_tld($tld)
{
	$pdo = init_db();
    if($pdo !== false)
	{
		$tld = filter_var($tld, FILTER_SANITIZE_STRING);
		$clause = "WHERE tld='$tld'";
        $tinfo = $pdo->getTLDsInfo($clause);
		if($tinfo !== false && is_array($tinfo))
		{
			if(isset($tinfo[0]['server']))
				return $tinfo[0]['server'];
		}
		return "";
	}
	else
		return false;
}

###############################################################################

function set_whois_server_for_tld($tld, $wserver)
{
	$pdo = init_db();
    if($pdo !== false)
        return $pdo->setWhoisServerForTLD($tld, $wserver);
	else
		return false;
}

###############################################################################

function update_subdomain_table($darray, $host, $domain, $manualedit=0)
{
	$pdo = init_db();
    if($pdo !== false)
	{
		$did = $pdo->getSingleEntry($pdo->getDomainTableName(), "domain", $domain, "sid"); 
		if($did !== false)
		{
			$setinfo = "";
			$updateArray = array();
			foreach($darray as $key=>$uvalue) 
			{
				$value = trim($uvalue);
				$value = trim($value,chr(0xC2).chr(0xA0)); 
				
				if($key == 'id' || $key == 'domain' || $key == 'subdomain' || $key == 'hid' || $key == 'sid')
					continue;
				else if($key == 'ttl')
				{
					$setinfo .= "$key = ?, ";
					$updateArray[] = $value == "" ? NULL : intval($value); 
				}
				else
				{
					$setinfo .= "$key = ?, ";
					$updateArray[] = $value;
				}
			}
			$setinfo = trim($setinfo, ", ");
			$timenow = date("Y-m-d H:i:s");
			if($manualedit)
				$setinfo .= ",edited=1,manual_edited_at='$timenow'";
			if(isset($darray['id']))
				$where = "where hid = " . intval($darray['id']) . " AND sid = " . $did;
			else 
				$where = "where subdomain = '" . $host . "' AND sid = " . $did;
			$setinfo .= " $where";
			if(count($updateArray) || $manualedit)
				return $pdo->updateTable($pdo->getSubdomainTableName(), $setinfo, $updateArray);
		}
	}
	return false;
}

###############################################################################

function getCustomQueryData()
{
	$cqdata = array();
	if(isset($_REQUEST['qs']))
	{
		$qs =  strtolower(trim($_REQUEST['qs']));
		if($qs != "")
		{
			if(stristr($qs, '%') === false)
				$qs = "%$qs%";
		}
		if($qs != "")
			$cqdata['qs'] = strip_tags($qs);
	}
	if(isset($_REQUEST['qcids']))
	{
		$qcids = explode(",", trim($_REQUEST['qcids']));
		if(count($qcids) > 0)
			$cqdata['qcids'] = strip_tags($qcids);
	}
	if(isset($_REQUEST['q']))
		$cqdata['q'] = strip_tags(trim($_REQUEST['q']));
	return $cqdata;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

function AddSubDomainForDomain($domain, $subdomain, $cid, &$udomains, &$hid)
{
	$pdo = init_db();
    if($pdo !== false)
	{
		$allowed_category_ids = getValidCategoryIDs();
		$domain = trim($domain);
		$sid = $pdo->getSingleEntry($pdo->getDomainTableName(), "domain", $domain, "sid");
		
		// If not admin, check if the domain belongs to users' categories.
		// Otherwise don't add.
		if(count($allowed_category_ids) && $sid > 0)
		{
			$catids = implode(",", $allowed_category_ids);
			$count = $pdo->getCount($pdo->getCategoryIDToDomainIDTableName(), "CategoryID IN ($catids) AND sid=? LIMIT 1", array($sid));
			if($count === false || $count == 0)
				return false;
		}
		
		# Don't allow addition of new domains if the user has access to only select categories.
		if(count($allowed_category_ids) && $sid <= 0)
			return false;
		
		if($sid > 0)
			$pdo->addSubdomain($sid, $subdomain);
		else
		{
			$pdo->addDomain($domain, $cid, $sid);
			if($sid > 0)
			{
				$pdo->logAuditEntry(AUDIT_ADD_DOMAINS, "Added domain '$domain'");
				$pdo->doDefaultDomainLookups($sid);
				$pdo->addSubdomain($sid, $subdomain);
			}
		}
		if($sid > 0)
		{
			if(in_array($sid, $udomains) === false)
				$udomains[] = $sid;
			$hids = $pdo->getTableData($pdo->getSubdomainTableName(), "hid", "where sid=? AND subdomain=?", array($sid, $subdomain));
			if($hids !== false && count($hids) > 0)
			{
				$hid = $hids[0];
				return true;
			}
		}
	}
	return false;
}

###############################################################################

function addSubomainsForDomains($domaindata, $cid, $sids)
{
	$pdo = init_db();
    if($pdo !== false)
	{
		$records = 0;
		$split_tokens = "\n\r";
		$domain_names = array();
		$udomains = array();
		$dentry = strtok($domaindata, $split_tokens);
		$tlds = $pdo->getTableData($pdo->getSecondLevelTLDTableName(), "tld", "order by id");
		if(!count($tlds))
			$tlds = $pdo->updateSecondLevelTLDs();
		if($tlds === false)
			$tlds = array();
		while ($dentry !== false) 
		{
			$dearray = explode(",", $dentry);
			if(count($dearray) == 2)
			{
				$subdomain = $dearray[0];
				$domain = $dearray[1];
				if(substr_count($domain, ".") > 0)
				{
					$hid = 0;
					if(AddSubDomainForDomain($domain, $subdomain, $cid, $udomains, $hid))
						$records++;
				}
			}
			else if(count($dearray) == 1)
			{
				$hostname = $dearray[0];
				$domain = ""; $subdomain = "";
				if(findDomainAndSubdomain($hostname, $domain, $subdomain, $tlds))
				{
					if($domain == "" && $subdomain != "")
					{
						$subdomain = trim($hostname);
						$sidarray = explode(",", $sids);
						foreach($sidarray as $sid)
						{
							if($pdo->addSubdomain($sid, $subdomain) == true)
								$records++;
						}
					}
					else if($domain != "" && $subdomain != "")
					{
						$hid = 0;
						if(AddSubDomainForDomain($domain, $subdomain, $cid, $udomains, $hid))
							$records++;
					}
				}
			}
			$dentry = strtok($split_tokens);
		}
		foreach($udomains as $sid)
			$pdo->addToLookupQueue($sid, LOOKUP_SUB_DOMAINS, 0);
		return $records;
	}
	return false;
}

###############################################################################

function findDomainAndSubDomain($hostname, &$domain, &$subdomain, $tlds=array())
{
	$domain = "";
	$subdomain = "";
	
	$dotcount = substr_count($hostname, ".");
	if($dotcount == 0)
	{
		$subdomain = trim($hostname);
		return true;
	}
	else if($dotcount == 1)
	{
		$domain = trim($hostname);
		return true;
	}
	else if($dotcount == 2)
	{
		$pos = mb_strpos($hostname, ".");
		if($pos !== false)
		{
			$subdomain = mb_substr($hostname, 0, $pos);
			$domain = mb_substr($hostname, $pos+1);
			return true;
		}
	}
	else if($dotcount > 2)
	{
		$pos = mb_strrpos($hostname, ".");
		$thistld = mb_substr($hostname, $pos+1);

		// Look for known second level domains.
		if(count($tlds))
		{
			$seclevel_tld_list = $tlds;
			//We assume that the TLDs are grouped together
			$startat = array_search($thistld, $seclevel_tld_list);
			if($startat === false)
				$startat = -1;
			$the_tlds = array();
			for($i = $startat+1; $i < count($seclevel_tld_list); $i++)
			{
				$tld = $seclevel_tld_list[$i];
				$tld = trim($tld, ".");
				if(!string_ends_with($tld, $thistld))
					break;
				$the_tlds[] = $tld;
			}
		}
		else
			$the_tlds = array("co.uk", "ac.uk", "gov.uk", "ltd.uk", 
				"org.uk", "nic.uk", "plc.uk", "net.uk", "nhs.uk", "co.in", "gov.in", "nic.in",
				"com.au", "gov.au", "edu.au");
		
		foreach($the_tlds as $tld)
		{
			if(splitHostNameForTLD($hostname, $tld, $domain, $subdomain))
				return true;
			if(!mb_check_encoding($tld, 'ASCII'))
			{
				$idntld = idn_convert($tld);
				if(splitHostNameForTLD($hostname, $idntld, $domain, $subdomain))
					return true;
			}
		}
		
		// Can't find any known second level domains. Just pull out
		// the last dotted pair as the domain name and rest as subdomain.
		$pos = mb_strrpos($hostname, ".");
		if($pos !== false)
		{
			$tld = mb_substr($hostname, $pos);
			$firstpart = mb_substr($hostname, 0, $pos);
			$pos = mb_strrpos($firstpart, ".");
			if($pos !== false)
			{
				$domain = mb_substr($firstpart, $pos+1) . $tld;
				$subdomain = mb_substr($firstpart, 0, $pos);
				return true;
			}
		}
	}
	return false;
}

###############################################################################

function splitHostNameForTLD($hostname, $tld, &$domain, &$subdomain)
{
	$tld = "." . $tld;
	if(mb_strlen($hostname) > mb_strlen($tld))
	{
		$pos = mb_strrpos($hostname, $tld);
		if($pos !== false)
		{
			$firstpart = mb_substr($hostname, 0, $pos);
			$lastpart = mb_substr($hostname, $pos);
			if($lastpart == $tld)
			{
				$pos = mb_strrpos($firstpart, ".");
				if($pos !== false)
				{
					$domain = mb_substr($firstpart, $pos+1) . $tld;
					$subdomain = mb_substr($firstpart, 0, $pos);
					return true;
				}
			}
		}						
	}
	return false;
}

###############################################################################
?>
