<?php
/*=======================================================================
 *
 * inc_APP.inc.php
 *
 * Autor: Marc Vollmann
 *
 =======================================================================*/
 

// Get licence Data by licence key
// $licId : Licence id to be requested
function getLicenceData($searchValue, $searchField = "lic_key", $returnSingleField = "") {
	global $dbname, $dblogin, $dbpassword;
	if ($returnSingleField == "") : $retObject = array(); else : $retObject = ""; endif;
	if ($searchField == "") : $searchField = "lic_key"; endif;
	if ($searchField != "" && $searchValue != "") :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     $sqlStmt = "SELECT lic.lic_id, lic.lic_key, lic.mo_id, lic.usr_id FROM meta_object.licence AS lic WHERE lic." . $searchField . " = '" . $searchValue . "'";
     $result = $db_conn->query($sqlStmt);
     // One row has to match only !!!!
     while ($row = $result->fetch_assoc()):
        if ($returnSingleField != "") :
           $retObject = $row[$returnSingleField];
        else :
           $retObject = array($row["appusr_code"], $row["lic_key"], $row["mo_id"], $row["usr_id"]);
        endif;
     endwhile;
     $result->free();     
  endif;
  return $retObject;
}

// Get licence ID by licence key
function getLicenceIDByKey($licKey) {
  return getLicenceData($licKey, "lic_key", "lic_id");
}

// Get licence ID by licence key
function getLicenceKeyByID($licId) {
  return getLicenceData($licId, "lic_id", "lic_key");
}

// Get all children licences of the requestet licence (next sublevel)
// $licId : Licence id to be requested
function getLicenceChildren($licId, $withIdentity = "") {
	global $dbname, $dblogin, $dbpassword;
  $retArray = array();
  if ($licId != "" && is_numeric($licId)) :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     if ($withIdentity == "1") :
        $tmpLicKey = getFieldValueFromId("meta_object.licence", "lic_id", $licId, "lic_key",$db_conn);
        $retArray[$licId] = $tmpLicKey;
     endif;
     $sqlStmt = "SELECT lic.lic_id, lic.lic_key FROM meta_object.licence AS lic WHERE lic.lic_pre_id = '" . $licId . "' ";
     $result = $db_conn->query($sqlStmt);
     if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
     while ($row = $result->fetch_assoc()):
       $retArray[$row["lic_id"]] = $row["lic_key"];
     endwhile;
     $result->free();
  endif;
  return $retArray;
}

// Checks two licences being child from the other
// $licId      : licence id (parent)
// $licIdChild : licence id (child)
function isLicChild($licId, $licIdChild, $checkForIdentity = "") {
	global $dbname, $dblogin, $dbpassword;
  $retBool = false;
  if ($licId != "" && is_numeric($licId) && $licIdChild != "" && is_numeric($licIdChild)) :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     if ($checkForIdentity == "1") :
        if ($licId == $licIdChild) :
           $retBool = true;
        endif;
     endif;
     if (!$retBool) :
        $tmpLicChildPath = getFieldValueFromId("meta_object.licence", "lic_id", $licIdChild, "lic_path",$db_conn);
        if (!(strpos($tmpLicChildPath, "//" . $licId . "//") === FALSE)) :
           $retBool = true;
        endif;
     endif;
  endif;
  return $retBool;
}

// Get the id of the root licence of the requested licence
// $licId : Licence id to be requested
// $level : Level of the tree (default = "0" returns the ROOT id !!!)
function getLicPathId($licId, $level = "0") {
  global $db, $PHP_SELF;
  $retVal = "0";
  if ($licId != "" && is_numeric($licId)) :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     // Get path field of the requested licence
     $tmpLicPath = getFieldValueFromId("meta_object.licence", "lic_id", $licId, "lic_path",$db_conn);
     if ($tmpLicPath != "") :
        // Remove path delimiter at the beginning and at the end
        $tmpLicPath = substr($tmpLicPath, 2, -2);
        // Split path to array of ids
        $tmpPathArray = spliti("//", $tmpLicPath);
        // Get the first element being the root licence id
        $retVal = $tmpPathArray[$level];
     else :
        // The root of the requested licence is the licence itself
        $retVal = $licId;
     endif;
  endif;
  return $retVal;
}

// Gets all licences of a specified (root) licence (top down recursion)
// $licId : Licence id
function getTreeLicenceData($licId) {
  global $licIdTreeArray;

  // Get licence children
  $tmpArray = getLicenceChildren($licId);
  $keys = array_keys($tmpArray);
  $keysLen = count($keys);

  if ($keysLen > 0) :
     // Iterate current children
     for ($i = 0; $i < $keysLen; $i++) :
         $tmpLicId = $keys[$i];

         // Get data of the current licence
         $licIdTreeArray[$tmpLicId] = $tmpArray[$tmpLicId];

         // Recursion ...	       		
         getTreeLicenceData($tmpLicId);
     endfor;
  endif;  
}

// Returns the statement to get all licences of the whole subtree of a specified licence
function getStmtAllLicencesByLicId ($licId, $whereClause = "") {
  $retStmt = "";
  if ($licId != "" && is_numeric($licId)) :
   if ($whereClause != "") : $whereClause = " AND " . $whereClause; endif;
   $retStmt = "SELECT lic.lic_id, lic.lic_key, lic.lic_name, lic.lic_path, lic.usr_id"
              . " FROM meta_object.licence AS lic"
		          . " WHERE (lic.lic_id = '" . $licId . "' OR lic.lic_path LIKE '%//" . $licId . "//%') " . $whereClause
		          . " ORDER BY lic.lic_key";
  endif;
  return $retStmt;
}


// Gets all data for a apecified licence key
function getLicenceDataSrv ($licKey) {
	global $db, $PHP_SELF;
	global $dbname, $dblogin, $dbpassword;
	global $licIdTreeArray;

  $retArray = array();
  if ($licKey == "") : 
     $retArray = array("201","<err_no>201</err_no>\n","<err_desc>" . getLngt("Lizenznummer nicht spezifiziert.") . "</err_desc>\n");
  else :
     $licId = getLicenceIDByKey($licKey);
     
     if ($licId == "" || !is_numeric($licId)) : 
        $retArray = array("203","<err_no>203</err_no>\n","<err_desc>" . getLngt("Lizenznummer existiert nicht.") . "</err_desc>\n");
     else :
        // Get all (sub-)licences of a specified licence
        $licIdTreeArray = array();    // Global
        $whereClauseLicIDs = "";

        // [Version 1.: Recursion by parent ID]
        // getTreeLicenceData($licId);   // Result in array $licIdTreeArray
        // $keys = array_keys($licIdTreeArray);
        // $whereClauseLicIDs = $licId;
        // if (count($keys) > 0) :
        //    $whereClauseLicIDs .= "," . implode(",", $keys);
        // endif;

        // [Version 2.: One statement according to the existing path]
        $sqlStmt = getStmtAllLicencesByLicId($licId);
        $result = $db->query($sqlStmt);
        if (DB::isError($result)) die ("$PHP_SELF: " . $result->getMessage());
        while ($row = $result->fetch_assoc()):
              $licIdTreeArray[$row["lic_id"]] = $row["lic_key"];
        endwhile;
        $result->free();
        $keys = array_keys($licIdTreeArray);
        if (count($keys) > 0) :
           $whereClauseLicIDs .= implode(",", $keys);
        endif;

        // Get all application data and user data according to the specified licence key including all sub-licences
        $sqlquery = "SELECT app.app_id, app.app_name, app.app_auth_req, app.app_url_app, app.app_url_tpl, licapp.licapp_auth_req, licapp.licapp_url"
                  . "  FROM meta_object.licenceapplication AS licapp, meta_object.application AS app"
                  . "  WHERE licapp.lic_id IN (" . $whereClauseLicIDs . ") AND licapp.app_id = app.app_id";
        $result = $db->query($sqlquery);

        if (DB::isError($result)):  
          $retArray = array("202","<err_no>202</err_no>\n","<err_desc>" . getLngt("Datenbankfehler") . "</err_desc>\n");
        else:
          while ($row = $result->fetch_assoc()):
                $authReq = $row["licapp_auth_req"];
                if ($row["app_auth_req"] == "1") : $authReq = "1"; endif;
                $retArray[] = array($row["app_id"], $row["app_name"], $authReq, $row["app_url_app"], $row["app_url_tpl"], $row["licapp_url"]);
          endwhile;
          $result->free();
          
          // Get the IP of the current client calling the page
          $currentClientIP = trim($_SERVER['REMOTE_ADDR']);
        
          // writeToLogDB("52",$hq_id,"",$usr_id,"","","","ACCOUNT=" . $usrName . "|MESS=Login ok|IP=" . $currentClientIP);
        endif;
     endif;
  endif;
  return $retArray;
}

// Activate APP regarding to the registration key compared with stored value in the db for the current user and APP
function appRegister ($appKey, $appId) {
	global $dbname, $dblogin, $dbpassword;
  $retArray = array("001","<err_no>001</err_no>\n","<err_desc>" . getLngt("Registrierung fehlgeschlagen!") . "</err_desc>\n");  // Init only
  if ($appKey != "" && $appId != "") :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     $tmpSqlQuery = "SELECT mo_id, usr_id FROM meta_object.applicationuser WHERE app_id = '" . $appId . "' AND appusr_code = '" . $appKey . "' AND appusr_activated = '0'";
     $result = $db_conn->query($tmpSqlQuery);
     while ($row = $result->fetch_assoc()):
           $retArray = array("0", $row["usr_id"], $row["mo_id"]);
           // Set activation flag
           $tmpSqlQuery = "UPDATE meta_object.applicationuser SET appusr_activated = '1' WHERE app_id = '" . $appId . "' AND appusr_code = '" . $appKey . "'";
           $res = $db_conn->query($tmpSqlQuery);
           if (DB::isError($res)) : die ("$PHP_SELF: " . $res->getMessage()); endif;
     endwhile;
     $result->free();
  endif;
  return $retArray;
}

// Check access rights for login process
function accessRightsUser ($moId, $usrId, $appKey, $appId) {
	global $dbname, $dblogin, $dbpassword;
  $hasAccess = false;
  if ($moId != "" && $usrId != "" && $appKey != "" && $appId != "") :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     $tmpSqlQuery = "SELECT appusr_code FROM meta_object.applicationuser WHERE app_id = '" . $appId . "' AND mo_id = '" . $moId . "' AND usr_id = '" . $usrId . "' AND appusr_code = '" . $appKey . "' AND appusr_activated = '1'";
     $result = $db_conn->query($tmpSqlQuery);
     while ($row = $result->fetch_assoc()):
        if ($row["appusr_code"] == $appKey) :
           $hasAccess = true;  // Authentication ok
        endif;
     endwhile;
     $result->free();
  endif;
  return $hasAccess;
}

// Same as "accessRightsUser()" matched by licence key
function licenceAccessRightsUser ($licKey, $appKey, $appId) {
	$hasAccess = false;
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $hasAccess = accessRightsUser ($moId, $usrId, $appKey, $appId);
  endif;
  return $hasAccess;
}

// Check login data
function login ($moId, $usrId, $appKey, $appId) {
	global $db, $PHP_SELF;
	global $dbname, $dblogin, $dbpassword;

  $retArray = array();
  if ($moId == "" || $usrId == "" || $appKey == "" || $appId == "") :
     $retArray = array("201","<err_no>201</err_no>\n","<err_desc>" . getLngt("Benutzername oder Passwort nicht spezifiziert.") . "</err_desc>\n");
  else :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     $tmpSqlQuery = "SELECT mo_hash FROM meta_object.metaobject WHERE mo_obj_type = 'usr' AND mo_id_ref_db = '" . $moId . "' AND mo_obj_id = '" . $usrId . "'";
     $result = $db_conn->query($tmpSqlQuery);
     while ($row = $result->fetch_assoc()):
        $sessionHash = $row["mo_hash"];
     endwhile;
     $result->free();

     // Get the IP of the current client calling the page
     $currentClientIP = trim($_SERVER['REMOTE_ADDR']);  

     if ($sessionHash != "") :
        // Check APP registration being correct
        if (accessRightsUser($moId, $usrId, $appKey, $appId)) :

           // Get operational IP and port from $moId
           $tmpSqlQuery = "SELECT mo_value FROM meta_object.metaobject WHERE mo_id = '" . $moId . "' AND mo_obj_type = 'db'";
           $result = $db_conn->query($tmpSqlQuery);
           $moValue = "";
           while ($row = $result->fetch_assoc()):
              $moValue = $row["mo_value"];
           endwhile;
           $result->free();

           if ($moValue != "") :
              // Set operational database and get user data
              $db_op_conn = getDbConnectionSpecial($moValue, $dbname, $dblogin, $dbpassword);
              $tmpSqlQuery = "SELECT usr.usr_type, usr.usr_name, usr.usr_firstname, usr.hq_id, hq.hq_mnemonic, hq.hq_name FROM phoenix.user AS usr, phoenix.headquarters AS hq WHERE usr.hq_id = hq.hq_id AND usr.usr_id = '" . $usrId . "'";
              $result = $db_op_conn->query($tmpSqlQuery);
              $usrRealName = getFieldValueFromId("user", "usr_id", $usrId, "usr_name");
              $usrRealFirstname = getFieldValueFromId("user", "usr_id", $usrId, "usr_firstname");
              $hqName = "";
              $hqMnemonic = "";
              while ($row = $result->fetch_assoc()):
                    $usrRealName = $row["usr_name"];
                    $usrRealFirstname = $row["usr_firstname"];
                    $hqId = $row["hq_id"];
                    $hqMnemonic = $row["hq_mnemonic"];
                    $hqName = $row["hq_name"];
                    $usrRealType = $row["usr_type"];
              endwhile;
              $result->free();

              $retArray = array("0", $usrId, $hqId, $moId, $sessionHash, $usrRealName, $usrRealFirstname, $hqName, $hqMnemonic, $usrRealType);
              writeToLogDB("52",$hq_id,"",$usrId,"","","","DB=" . $moValue . "|ACCOUNT=" . $usrName . "|MESS=Login ok|IP=" . $currentClientIP);

           else:
              $retArray = array("206","<err_no>206</err_no>\n","<err_desc>" . getLngt("Operative Datenbank nicht gefunden.") . "</err_desc>\n");
              writeToLogDB("52",$hq_id,"",$usrId,"","","","DB=" . $moValue . "|ACCESS=No connect|IP=" . $currentClientIP);
           endif;
        else : 
           $retArray = array("205","<err_no>205</err_no>\n","<err_desc>" . getLngt("Berechtigungen fehlen.") . "</err_desc>\n");
           writeToLogDB("52",$hq_id,"",$usrId,"","","","ACCOUNT=" . $usrName . "|ACCESS=No rights|IP=" . $currentClientIP);
        endif;
     else :
        $retArray = array("204","<err_no>204</err_no>\n","<err_desc>" . getLngt("Keine Session-ID für den Benutzer verfügbar.") . "</err_desc>\n");
        writeToLogDB("52",$hq_id,"",$usrId,"","","","ACCOUNT=" . $usrName . "|MESS=Login failed|IP=" . $currentClientIP);
     endif;
  endif;
  return $retArray;
}

// Same as "login()" matched by licence key
function licenceLogin ($licKey, $appKey, $appId) {
	$retArray = array();
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retArray = login($moId, $usrId, $appKey, $appId);
  endif;
  return $retArray;
}

function checkAccess ($sessionHash, $moId, $usrId) {
	global $db, $PHP_SELF;
	global $dbname, $dblogin, $dbpassword;
	$retBool = false;
  if ($sessionHash != "" && $moId != "" && $usrId != "") :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     $tmpSqlQuery = "SELECT mo_obj_id FROM meta_object.metaobject WHERE mo_id_ref_db = '" . $moId . "' AND mo_obj_type = 'usr' AND mo_hash = '" . $sessionHash . "'";
     $result = $db_conn->query($tmpSqlQuery);
     while ($row = $result->fetch_assoc()):
           if ($usrId == $row["mo_obj_id"]) :
              $retBool = true;
           endif;
     endwhile;
     $result->free();
  endif;
  return $retBool;
}

// Same as "checkAccess()" matched by licence key
function licenceCheckAccess ($licKey, $sessionHash) {
	$retArray = array();
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retArray = checkAccess ($sessionHash, $moId, $usrId);
  endif;
  return $retArray;
}

// Gets the operational database via connection data of metaobject
function getOperationalDatabase ($moId) {
	global $db, $PHP_SELF;
	global $dbname, $dblogin, $dbpassword;
	$retVal = "";
	if ($moId != "" && is_numeric($moId)) :
     $constExtDbInst = getExternalMetaDbInst();
     if ($constExtDbInst != "") :
        $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
        $tmpSqlQuery = "SELECT mo_value FROM meta_object.metaobject WHERE mo_id = '" . $moId . "' AND mo_obj_type = 'db'";
        $result = $db_conn->query($tmpSqlQuery);
        while ($row = $result->fetch_assoc()):
              $retVal = $row["mo_value"];
        endwhile;
        $result->free();
     endif;
  endif;
  return $retVal;
}

// Same as "getOperationalDatabase()" matched by licence key
function licenceGetOperationalDatabase ($licKey) {
	$retVal = "";
	$moId = getLicenceData($licKey, "lic_key", "mo_id");
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retVal = getOperationalDatabase($moId);
  endif;
  return $retVal;
}

// Gets the current register code for a specified APP, DB and user
function getRegisterCode ($appId, $moId, $usrId) {
	global $dbname, $dblogin, $dbpassword;
  $retArray = array("301","<err_no>301</err_no>\n","<err_desc>" . getLngt("Zugriff fehlgeschlagen!") . "</err_desc>\n");  // Init only
  if ($appId != "" && $moId != "" && $usrId != "") :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     $tmpSqlQuery = "SELECT appusr_code, appusr_activated FROM meta_object.applicationuser WHERE app_id = '" . $appId . "' AND mo_id = '" . $moId . "' AND usr_id = '" . $usrId . "'";
     $result = $db_conn->query($tmpSqlQuery);
     $registerCodeDoesExist = false;
     while ($row = $result->fetch_assoc()):
           $retArray = array("0", $row["appusr_code"], $row["appusr_activated"]);
           $registerCodeDoesExist = true;
     endwhile;
     $result->free();
     if (!$registerCodeDoesExist) :
        $retArray = array("302","<err_no>302</err_no>\n","<err_desc>" . getLngt("Derzeit existiert kein Registrierungsschlüssel für den Mitarbeiter!") . "</err_desc>\n");
     endif;
  endif;
  return $retArray;
}

// Same as "getRegisterCode()" matched by licence key
function licenceGetRegisterCode ($licKey, $appId) {
	$retArray = array();
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retArray = getRegisterCode($appId, $moId, $usrId);
  endif;
  return $retArray;
}

// Sets the current register code for a specified APP, DB and user
function setRegisterCode ($appId, $moId, $usrId, $appKey, $adId = "0") {
	global $dbname, $dblogin, $dbpassword;
  $retArray = array("301","<err_no>301</err_no>\n","<err_desc>" . getLngt("Zugriff fehlgeschlagen!") . "</err_desc>\n");
  if ($appId != "" && $moId != "" && $usrId != "" && $appKey != "") :
     // Get database instance connection data of metaobject
     $constExtDbInst = getExternalMetaDbInst();
     $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
     // Check for code being unique
     $tmpSqlQuery = "SELECT usr_id FROM meta_object.applicationuser WHERE appusr_code = '" . $appKey . "'";
     $result = $db_conn->query($tmpSqlQuery);
     $codeDoesExist = false;
     while ($row = $result->fetch_assoc()):
           $codeDoesExist = true;
     endwhile;
     $result->free();
     if ($codeDoesExist) :
        $retArray = array("310","<err_no>310</err_no>\n","<err_desc>" . getLngt("Der Registrierungscode ist ungültig! Bitte verwenden Sie einen anderen!") . "</err_desc>\n");
     else :
        $tmpSqlQuery = "SELECT appusr_code, appusr_activated FROM meta_object.applicationuser WHERE app_id = '" . $appId . "' AND mo_id = '" . $moId . "' AND usr_id = '" . $usrId . "'";
        $result = $db_conn->query($tmpSqlQuery);
        $rowDoesExist = false;
        while ($row = $result->fetch_assoc()):
              $rowDoesExist = true;
        endwhile;
        $result->free();
        if ($rowDoesExist) :
           $tmpSqlQuery = "UPDATE meta_object.applicationuser SET appusr_code = '" . $appKey . "', appusr_activated = '0' WHERE app_id = '" . $appId . "' AND mo_id = '" . $moId . "' AND usr_id = '" . $usrId . "'";
           $retArray = array("0","<err_no>0</err_no>\n","<err_desc>" . getLngt("Der Schlüssel wurde aktualisiert!") . "</err_desc>\n");
        else:
           $currentTime = getDateTime("0");
           $tmpSqlQuery = "INSERT INTO meta_object.applicationuser (app_id, mo_id, usr_id, ad_id, appusr_code, appusr_activated, appusr_createtime) VALUES ('" . $appId . "', '" . $moId . "', '" . $usrId . "', '" . $adId . "', '" . $appKey . "', '0', '" . $currentTime . "')";
           $retArray = array("0","<err_no>0</err_no>\n","<err_desc>" . getLngt("Benutzereintrag und Schlüssel wurden angelegt!") . "</err_desc>\n");
        endif;
        $res = $db_conn->query($tmpSqlQuery);
        if (DB::isError($res)) : die ("$PHP_SELF: " . $res->getMessage()); endif;
     endif;
  endif;
  return $retArray;
}

// Same as "setRegisterCode()" matched by licence key
function licenceSetRegisterCode ($licKey, $appId, $appKey, $adId = "0") {
	$retArray = array();
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retArray = setRegisterCode($appId, $moId, $usrId, $appKey, $adId);
  endif;
  return $retArray;
}

// Get state of the app user account ("0" = test, "1" = productive)
function getUserStatus ($appId, $moId, $usrId, $appKey = "") {
	global $dbname, $dblogin, $dbpassword;
  $retArray = array("211","<err_no>211</err_no>\n","<err_desc>" . getLngt("Der Status konnte nicht abgefragt werden!") . "</err_desc>\n");
  if ($appId != "" && $moId != "" && $usrId != "") :
     $hasAccess = accessRightsUser($moId, $usrId, $appKey, $appId);
     if ($hasAccess) :
        // Get database instance connection data of metaobject
        $constExtDbInst = getExternalMetaDbInst();
        $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
        $appusrStatus = getFieldValueFromClause("meta_object.applicationuser","appusr_status","app_id = '" . $appId . "' AND mo_id = '" . $moId . "' AND usr_id = '" . $usrId . "'", $db_conn);
        if ($appusrStatus != "") :
           $retArray = array("0", $appusrStatus, $appId, $moId, $usrId);
        else :
           $retArray = array("213","<err_no>213</err_no>\n","<err_desc>" . getLngt("Der Eintrag wurde nicht gefunden!") . "</err_desc>\n");
        endif;
     else :
        $retArray = array("212","<err_no>212</err_no>\n","<err_desc>" . getLngt("Der Status durfte nicht gesetzt werden!") . "</err_desc>\n");
     endif;
  endif;
  return $retArray;
}

// Same as "getUserStatus()" matched by licence key
function licenceGetUserStatus ($licKey, $appId, $appKey) {
	$retArray = array();
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retArray = getUserStatus($appId, $moId, $usrId, $appKey);
  endif;
  return $retArray;
}

// Set state of the app user account ("0" = test, "1" = productive)
function setUserStatus ($appId, $moId, $usrId, $appusrStatus = "", $appKey = "") {
	global $dbname, $dblogin, $dbpassword;
  $retArray = array("201","<err_no>201</err_no>\n","<err_desc>" . getLngt("Der Status wurde nicht gesetzt!") . "</err_desc>\n");
  if ($appId != "" && $moId != "" && $usrId != "" && $appusrStatus != "" && is_numeric($appusrStatus)) :
     $hasAccess = accessRightsUser($moId, $usrId, $appKey, $appId);
     if ($hasAccess) :
        // Get database instance connection data of metaobject
        $constExtDbInst = getExternalMetaDbInst();
        $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
        $res = updateStmt("meta_object.applicationuser", "usr_id", $usrId, array("appusr_status", $appusrStatus), "app_id = '" . $appId . "' AND mo_id = '" . $moId . "'", $db_conn);
        if ($db_conn->affected_rows > 0) :
           $retArray = array("0", $appusrStatus, $appId, $moId, $usrId);
        else :
           $retArray = array("203","<err_no>203</err_no>\n","<err_desc>" . getLngt("Der zu aktualisierende Eintrag wurde nicht gefunden!") . "</err_desc>\n");
        endif;
     else :
        $retArray = array("202","<err_no>202</err_no>\n","<err_desc>" . getLngt("Der Status durfte nicht gesetzt werden!") . "</err_desc>\n");
     endif;
  endif;
  return $retArray;
}

// Same as "setUserStatus()" matched by licence key
function licenceSetUserStatus ($licKey, $appId, $appusrStatus = "", $appKey = "") {
	$retArray = array();
	$licDataArray = getLicenceData($licKey, "lic_key");
	$moId = $licDataArray[2];
	$usrId = $licDataArray[3];
  if ($moId != "" && is_numeric($moId) && $usrId != "" && is_numeric($usrId)) :
     $retArray = setUserStatus($appId, $moId, $usrId, $appusrStatus, $appKey);
  endif;
  return $retArray;
}

// Inserts a new user account
function insertUser ($appId, $moId, $userEmail, $userMobile, $appusrStatus = "0", $userAccount = "", $userPassword = "", $userPassword2 = "", $userName = "", $userFirstname = "", $adStreet = "", $adHsno = "", $adZipcode = "", $adCity = "", $adCountry = "DE", $cmpComp = "", $cmpComp2 = "", $hqName = "", $hqMnemonic = "") {
	global $db, $PHP_SELF;
	global $dbname, $dblogin, $dbpassword;

  $retArray = array("101","<err_no>101</err_no>\n","<err_desc>" . getLngt("Registrierung fehlgeschlagen!") . "</err_desc>\n");  // Init only

  // Check global switch for web registration to be enabled
  $userRegistrationEnabled = getParameterValue("0", "GLOBAL_USER_REGISTRATION_ENABLED", "0", "0");
  if ($userRegistrationEnabled == "1") :

     $retArray = array();
     if ($appId != "" && $moId != "" && $userEmail != "" && $userMobile != "") :

        // Get the IP of the current client calling the page
        $currentClientIP = trim($_SERVER['REMOTE_ADDR']);  

        // Get operational IP and port from $moId
        $constExtDbInst = getExternalMetaDbInst();
        $db_conn = getDbConnectionSpecial($constExtDbInst, $dbname, $dblogin, $dbpassword);
        $tmpSqlQuery = "SELECT mo_value FROM meta_object.metaobject WHERE mo_id = '" . $moId . "' AND mo_obj_type = 'db'";
        $result = $db_conn->query($tmpSqlQuery);
        $moValue = "";
        while ($row = $result->fetch_assoc()):
           $moValue = $row["mo_value"];
        endwhile;
        $result->free();
        // Check $appId
        $tmpSqlQuery = "SELECT app_name, app_auth_req FROM meta_object.application WHERE app_id = '" . $appId . "'";
        $result = $db_conn->query($tmpSqlQuery);
        $appName = "";
        $appAuthReq = "";
        while ($row = $result->fetch_assoc()):
           $appName = $row["app_name"];
           $appAuthReq = $row["app_auth_req"];
        endwhile;
        $result->free();

        if ($moValue != "" && $appName != "" && $appAuthReq == "1") :
           // Try to insert user in operational database
           // $db_op_conn = getDbConnectionSpecial($moValue, $dbname, $dblogin, $dbpassword);

           $userEmail = trim($userEmail);
           $userAccount = trim($userAccount);
           $userPassword = trim($userPassword);
           $userPassword2 = trim($userPassword2);
           $userName = trim($userName);
           $userFirstname = trim($userFirstname);

           // ACCOUNT equals EMAIL every time
           $userAccountEqualsEmailDisabled = getParameterValue("0", "GLOBAL_USER_ACCOUNT_EQUALS_EMAIL_DISABLED", "0", "0");           
           if ($userAccountEqualsEmailDisabled != "1") :
              if ($userAccount == "") :
                 $userAccount = $userEmail;
              endif;
              if ($userEmail == "") :
                 $userEmail = $userAccount;
              endif;
           endif;

           // Generate unique user account
           $userDoesExist = false;
           do {
           	  $tmpUserAccount = $userAccount;
           	  $tmpUsrId = "0";
           	  if ($tmpUserAccount != "") :
           	     $tmpUsrId = getFieldValueFromId("user", "usr_account", $tmpUserAccount, "usr_id");
           	     if ($tmpUsrId != "") :
           	        if ($userAccountEqualsEmailDisabled != "1") :
           	           $tmpUsrId = "0";
           	           $userDoesExist = true;
           	           break;
           	        else :
           	           $tmpUserAccount .= rand(10000, 99999);
           	        endif;
           	     endif;
           	  else :
           	     $tmpUserAccount = rand(0, getrandmax());
           	  endif;
           	  $tmpUsrId = getFieldValueFromId("user", "usr_account", $tmpUserAccount, "usr_id");
           } while ($tmpUsrId != "");
           $userAccount = $tmpUserAccount;

           if (!$userDoesExist) :

              // Generate user password
              $userPassword = trim($userPassword);
              $checkPasswordStrengthOK = false;
              /*
              if ($userPassword == "") : 
                 $userPassword = rand(10000, getrandmax());
                 $userPassword2 = $userPassword;
              endif;
              */
              // Check password strength
              if ($userPassword != "" && checkPasswordValidation($userPassword,$userPassword2)) :
                 $checkPasswordStrengthOK = true;
              endif;

              if ($checkPasswordStrengthOK) :

                 if ($userAccountEqualsEmailDisabled == "1" || checkEmailFormat($userAccount)) :

                    if (checkEmailFormat($userEmail)) :

// Handle headquarters !!!!!!!!!!!!!!!!!!!!!!!
$x_hq_id = "1";
$x_usr_type = 1000 + $appId;

                       $tmpHash = makeMD5Hash(rand(10000, 99999), getDateTime(6), rand(10000, 99999));
                       if ($tmpHash != "") :

                          TA("B");
                          $dbErr = false;

                          // Insert new user requested
                          insertStmt("user", array("hq_id", $x_hq_id, "usr_type", $x_usr_type, "usr_name", $userName, "usr_firstname", $userFirstname, "usr_email", $userEmail, "usr_phone", $userMobile, "usr_account", $userAccount, "usr_password", $userPassword));
                          $usr_id_last = getLastInsertId();
                          if ($usr_id_last == "" || !is_numeric($usr_id_last) || $usr_id_last <= 0) : $dbErr = true; endif;

                          if (!$dbErr) :
                             // Set crypted Password
                             $currentTime = getDateTime("0");
                             $sqlStmtPwd = "UPDATE user SET usr_password = PASSWORD('" . $userPassword . "'), usr_password_modify = '" . $currentTime . "' WHERE usr_id = '" . $usr_id_last . "'";
                             $res = $db->query($sqlStmtPwd);
                             if (DB::isError($res)) : die ("$PHP_SELF: " . $res->getMessage()); endif;

                             // Insert user into "metaobjects"
                             $tmpSqlQuery = "INSERT meta_object.metaobject (mo_id_ref_db,mo_obj_type,mo_obj_id,mo_hash) VALUES ('" . $moId . "','usr','" . $usr_id_last . "','" . $tmpHash . "') ";
                             $result = $db_conn->query($tmpSqlQuery);
                             if (DB::isError($result)) {$dbErr = true;};
                             $usr_mo_id_last = getLastInsertID($db_conn);
                             if ($usr_mo_id_last == "" || !is_numeric($usr_mo_id_last) || $usr_mo_id_last <= 0) : $dbErr = true; endif;

                             if (!$dbErr) :
                                $addressUsed = false;
                                $adIdNew = "0";
                                if ($adStreet != "" || $adZipcode != "" || $adCity != "") :
                                   $addressUsed = true;
                                   $adArray = insertAddress($adStreet, $adZipcode, $adCity, "", $adCountry, true);
                                   $adIdNew = $adArray[0];
                                endif;
                                if (!$addressUsed || ($adIdNew != "" && is_numeric($adIdNew))) : 
                                   // Insert user into "applicationuser" and generate initial app key
                                   $appusrCode = md5(strval(rand(1000,9999)) . strval($usr_id_last) . strval(rand(1000,9999)));
                                   $retArray = setRegisterCode($appId, $moId, $usr_id_last, $appusrCode, $adIdNew);
                                   if ($retArray[0] == "0") :
                                      $retArray = setUserStatus($appId, $moId, $usrId, $appusrStatus, $appusrCode);
                                      if ($retArray[0] != "0") :
                                         $dbErr = true;
                                      endif;
                                   else :
                                      $dbErr = true;
                                   endif;
                                else :
                                   $dbErr = true;
                                   $retArray = array("108","<err_no>108</err_no>\n","<err_desc>" . getLngt("Die Adresse konnte nicht angelegt werden.") . "</err_desc>\n");
                                endif;
                             endif;
                          endif;

                          if ($dbErr) :
                             TA("R");
                             TA("E");
                          else :
                             TA("C");
                             TA("E");
                             $retArray = array("0", $usr_id_last, $usr_mo_id_last, $appusrCode, $appusrStatus);
                          endif;

                       else :
                          $retArray = array("107","<err_no>107</err_no>\n","<err_desc>" . getLngt("Broker-Eintrag fehlgeschlagen.") . "</err_desc>\n");
                       endif;
                    else :
                       $retArray = array("106","<err_no>106</err_no>\n","<err_desc>" . getLngt("Die Email-Adresse scheint nicht in Ordnung.") . "</err_desc>\n");
                    endif;
                 else :
                    $retArray = array("105","<err_no>105</err_no>\n","<err_desc>" . getLngt("Der Account ist leider nicht in Ordnung.") . "</err_desc>\n");
                 endif;
              else :
                 $retArray = array("104","<err_no>104</err_no>\n","<err_desc>" . getLngt("Das Passwort ist leider ungeeignet.") . "</err_desc>\n");
              endif;
           else :
              $retArray = array("103","<err_no>103</err_no>\n","<err_desc>" . getLngt("Der Account existiert leider schon.") . "</err_desc>\n");
           endif;
        else:
           $retArray = array("102","<err_no>102</err_no>\n","<err_desc>" . getLngt("Operative Datenbank nicht gefunden.") . "</err_desc>\n");
        endif;
     endif;
  endif;
  return $retArray;
}
?>
