<?php
/*--------------------------------------------------------- 
 * File:utility.php
 * Author:Tomix,邱洪榮
 * Description: 
 * Created:2009
 * -------------------------------------------------------
 * Modified history:2023/08/22
 * Copyright © 2023 蘋果世界股份有限公司 版權所有
 * -------------------------------------------------------
 */
class utility {
	// 應用程序根目錄(返回值末尾沒有加"/")
	public static function getAppRoot(): string {
		require_once dirname(__FILE__) . "/../configuration/configFactory.php";
		$config = configFactory::createConfiguration();
		$root = $config->getConfigValue("appsettings", "appRoot");
		$appRoot = "";

		if (!isset($root) || $root == "") {
			$appRoot = "https://" . $_SERVER["HTTP_HOST"];
		} else if (strpos($root, "https://") === 0) {
			$appRoot = $root;
		} else {
			if (strpos($root, "/") === false || strpos($root, "/") !== 0) $root = "/" . $root;
			$appRoot = "https://" . $_SERVER["HTTP_HOST"] . $root;
		}

		if (strrpos($appRoot, "/") === strlen($appRoot) - 1) $appRoot = substr($appRoot, 0, strlen($appRoot) - 1);

		return $appRoot;
	}

	public static function getCurrentUrl(): string {
		$url = self::getAppRoot() . $_SERVER["SCRIPT_NAME"];
		$param = [];

		foreach ($_GET as $key => $value) {
			$param[] = $key . "=" . urldecode($value);
		}

		if (count($param) > 0) $url .= "?" . implode("&", $param);

		return $url;
	}

	// 去掉路径名的前后反斜杆
	static public function removeDirSlash($dir): string {
		if (strpos($dir, "/") === 0 && strlen($dir) > 1) $dir = substr($dir, 1);
		if (strrpos($dir, "/") === strlen($dir) - 1 && strlen($dir) > 1) $dir = substr($dir, 0, strlen($dir) - 1);
		
		return $dir;
	}
	
	// 產生隨機字符串
	// 參數說明:$length,返回字符串長度;$mode返回模式(0:数字与字母组合;1:纯数字;2纯字母)
	static public function getRandomString($length, $mode = 0): string {
		$chars = array_merge(
			range('A', 'Z'),
			range('a', 'z'),
			range('0', '9')
		);

		if ($mode == 1) {
			$chars = range('0', '9');
		} elseif ($mode == 2) {
			$chars = array_merge(range('A', 'Z'), range('a', 'z'));
		}

		$max = count($chars);
		$returnValue = "";

		while (strlen($returnValue) < $length) {
			$randIndex = rand(0, $max - 1);
			$returnValue .= $chars[$randIndex];
		}

		return $returnValue;
	}

	// 取得上級數據(包括自身)
	static public function getAncestors($source, $idField, $pidField, $fieldValue): array {
		$returnValue = [];
		$current = [];

		foreach ($source as $row) {
			if ($row[$idField] == $fieldValue) {
				$current = $row;
				$returnValue[] = $current;
				break;
			}
		}

		while ($current[$pidField] > 0) {
			$current = self::_getAncestors($source, $idField, $current[$pidField]);
			$returnValue[] = $current;
		}

		return array_reverse($returnValue);
	}

	// 私有方法:
	// 根據ID取得數據
	static private function _getAncestors($source, $idField, $fieldValue) {
		foreach ($source as $row) {
			if ($row[$idField] == $fieldValue) return $row;
		}
	}

	// 公開方法:取得下級數據(包括自身)
	// 參數說明:$source,二維陣列類型源數據;$idField,id字段;$pidField,上級ID字段;$fieldValue,當前id字段值
	static public function getOffSprings($source, $idField, $pidField, $fieldValue): array {
		$tmpValue = self::_getOffSprings($source, $idField, $pidField, $fieldValue);

		// 添加自身
		foreach ($source as $arr) {
			if ($arr[$idField] == $fieldValue) $tmpValue[] = $arr;
		}

		// 使用主鍵值索引
		$returnValue = [];
		foreach ($tmpValue as $arr) {
			if (!isset($returnValue[$arr[$idField]])) $returnValue[$arr[$idField]] = $arr;
		}

		return $returnValue;
	}
	
	// 私有方法:取得下級數據(不包括自身)
	// 參數說明:$source,二維陣列類型源數據;$idField,id字段;$pidField,上級ID字段;$fieldValue,當前id字段值
	static private function _getOffSprings($source, $idField, $pidField, $fieldValue): array {
		$returnValue = [];
		$newSource = [];

		foreach ($source as $arr) {
			if ($arr[$pidField] == $fieldValue) {
				$returnValue[] = $arr;
			} else {
				$newSource[] = $arr;
			}
		}

		$rootArray = $returnValue;

		foreach ($rootArray as $arr) {
			$temp = self::getOffSprings($newSource, $idField, $pidField, $arr[$idField]);
			$returnValue = array_merge($returnValue, $temp);
		}

		return $returnValue;
	}

	static public function substr_utf8($str, $start, $length) {
		$len = mb_strlen($str, 'utf-8');
		$r = [];
		$n = 0;
		$m = 0;
		
		for ($i = 0; $i < $len; $i++) {
			$char = mb_substr($str, $i, 1, 'utf-8');
			$byteLength = mb_strlen($char, 'utf-8');
			$n += $byteLength;
			
			if ($n <= $start) continue;
			
			$r[] = $char;
			$m++;
			
			if ($m >= $length) break;
		}
		
		return implode($r);
	}
	
	// 按比例縮放圖片大小
	// 如果$width=-1,$height>0時,按$height參數進行縮放(不限寬的圖片);反之按$width參數進行縮放(不限高的圖片);$width>0,$height>0時,按比例縮放(限寬,限高圖片)
	static public function resizeImage($oldWidth, $oldHeight, $width = -1, $height = -1) {
		$arr = [];
		
		if (!is_numeric($oldWidth) || !is_numeric($oldHeight) || $oldWidth == 0 || $oldHeight == 0 || $width == 0 || $height == 0) {
			$arr["width"] = $width;
			$arr["height"] = $height;
			return $arr;
		}

		if ($width < 0 && $height < 0) {
			$arr["height"] = $oldWidth;
			$arr["width"] = $oldHeight;
			return $arr;
		} elseif ($oldWidth / $oldHeight > $width / $height || $height < 0) {
			$arr["width"] = $width;
			$arr["height"] = ($oldHeight / $oldWidth) * $width;
			return $arr;
		} elseif ($oldHeight / $oldWidth > $height / $width || $width < 0) {
			$arr["height"] = $height;
			$arr["width"] = ($oldWidth / $oldHeight) * $height;
			return $arr;
		} else {
			$arr["width"] = $width;
			$arr["height"] = $height;
			return $arr;
		}
	}

	// 寫入日誌文件
	static public function writeLog($message, $logPrefix = "sys", $logType = "sys log") {
		$msg = "\r\n=============================================================================\r\n";
		$msg .= "Time: " . date("Y-m-d H:i:s") . "\r\n";
		$msg .= "Type: " . $logType . "\r\n";
		$msg .= "Message:\r\n";
		$msg .= $message;

		$path = dirname(__FILE__) . "/../../logs/";
		if (!is_dir($path)) @mkdir($path, 0777);
		
		$fn = $path . $logPrefix . "_" . date("Ymd") . ".log";
		
		if ($fp = fopen($fn, "ab")) {
			fwrite($fp, $msg);
			fclose($fp);
			return true;
		} else {
			return false;
		}
	}
}
?>