<?php
/**
* 汎用的な関数を集めたクラス
*
* PHP version 5
*
* @package    core
* @author     stk2k <stk2k@sazysoft.com>
* @copyright  2008 stk2k, sazysoft
*/

class System
{
	/**
	 *	タイプ名
	 */
	public static function getTypeName( $v ){
		return gettype( $v );
	}

	/*
	 *    現在時間を取得
	 */
	public static function now(){ 
		list($msec,$sec) = explode(' ',microtime()); 
		return ( (float)$msec + (float)$sec );
	}

	/**
	 *	２つの日付の差分を日単位で求める
	 */
	public static function dateDiff( $date1, $date2 = NULL ){
		if ( $date2 == NULL ){
			// 今日の日付
			$date2 = date("Y/m/d");
		}
		$result = strtotime($date2) - strtotime($date1);
		$result = intval( $result / (24 * 60 * 60));
		return $result;
	}

	/**
	 *	２つの日付を比較
	 */
	public static function compareDate( $date1, $date2 = NULL ){
		if ( $date2 == NULL ){
			// 今日の日付
			$date2 = date("Y/m/d");
		}
		$result = strtotime($date1) - strtotime($date2);
		return $result;
	}

	/*
	 *    配列を文字列にする
	 *
	 */
	public static function arrayToString( $ary, $line_end = NULL, $indent = NULL, EncodingConverter $conv = NULL )
	{
		if ( $ary === NULL ){
			return '';
		}
		if ( $line_end === NULL ){
			$line_end = '<BR>';
		}
		if ( $indent === NULL ){
			$indent = '--';
		}
		if ( $conv ){
			return self::_arrayToString( $ary, $line_end, $indent, 0, $conv );
		}
		else{
			return self::_arrayToString( $ary, $line_end, $indent, 0 );
		}
	}

	private static function _arrayToString( $ary, $line_end, $indent, $level, EncodingConverter $conv = NULL )
	{
		$type = is_object($ary) ? get_class($ary) : gettype($ary);

		$buffer = '';
		foreach( $ary as $key => $val ){
			if ( is_array($val) ){
				// 再起呼び出し
				$buffer .= str_repeat( $indent, $level );
				$buffer .= "[$key]=$val" . $line_end;
	 			$buffer .= self::_arrayToString( $val, $line_end, $indent, $level+1, $conv );
			}
			else if ( is_object($val) ){
				if ( $val instanceof Iterator ){
					// 再起呼び出し
					$buffer .= str_repeat( $indent, $level );
					$buffer .= "[$key]=" . get_class($val) . $line_end;
		 			$buffer .= self::_arrayToString( $val, $line_end, $indent, $level+1, $conv );
				}
				else if ( method_exists($val,"__toString") ){
					// __toString()メソッドが定義されている場合は__ToString()メソッドに表示を任せる
					$str_val = $val->__toString();
					if ( $conv ){
						$str_val = $conv->convertEncoding($str_val);
					}
					$buffer .= str_repeat( $indent, $level );
					$buffer .= "[$key]=$str_val" . $line_end;
				}
				else{
					// 定義されていない場合はクラス名だけを表示
					$val = '(class)' . get_class($val);
					$buffer .= str_repeat( $indent, $level );
					$buffer .= "[$key]=$val" . $line_end;
				}
			}
			else{
				// オブジェクト型、配列型以外はそのまま追加
				if ( $conv ){
					$val = $conv->convertEncoding($val);
				}
				$buffer .= str_repeat( $indent, $level );
				$buffer .= "[$key]=$val" . $line_end;
			}
		}
		return $buffer;
	}

	/*
	 *    変数をダンプする
	 */
	public static function dumpVar( $var, $title = NULL, $line_end = "<BR>", $indent = "&nbsp;", $to_encoding = NULL, $from_encoding = NULL )
	{
		if ( is_array($var) ){
			// 配列の場合
			self::dumpArray( $var, $title, $line_end, $indent, $to_encoding, $from_encoding );
			return;
		}
		else if ( is_object($var) ){
			// オブジェクトの場合
			if ( !method_exists($var,"__toString") ){
				// __toStringを定義していない場合はエラーとなるので、クラス名だけを表示
				$var = get_class($var);
			}
		}

		// その他の型の場合はString変換可能とみなす
		print "$line_end-----------[ $title array dump start ]-----------$line_end";
		print $var;
		print "$line_end-----------[ $title array dump end ]-----------$line_end";
	}

	/*
	 *    配列をダンプ
	 *
	 */
	public static function dumpArray( $ary, $title = NULL, $line_end = NULL, $indent = NULL, EncodingConverter $conv = NULL )
	{
		if ( $line_end == NULL ){
			$line_end = '<BR>';
		}
		if ( $indent == NULL ){
			$indent = '--';
		}
		if ( $conv ){
			$str = self::arrayToString( $ary, $line_end, $indent, $conv );
		}
		else{
			$str = self::arrayToString( $ary, $line_end, $indent );
		}
		if ( $title )	print "$line_end------------[ $title START ]------------$line_end";
		print $str;
		if ( $title )	print "$line_end------------[ $title END ]------------$line_end";
	}

	/*
	 *    配列からデータを検索する
	 */
	public static function getArrayData( $key, $array )
	{
		if ( isset($array[$key]) ){
			return $array[$key];
		}
		return null;
	}

	/*
	 *    配列からキーに部分一致するデータ配列を返す
	 */
	public static function makeSubArray( $part, $ary )
	{
		// キー一覧を取得
		$keys = array_keys( $ary );
		// 返却用の配列
		$ret = array();
		// キーごとに確認
		foreach( $keys as $key ){
			// 前方一致するか
			$pos = strpos($key,$part);
			if ( is_int($pos) && $pos >= 0 ){
				// 値を取得
				$val = $ary[ $key ];
				// 一致する部分を除いて新しいキーを作成
				$new_key = substr( $key, $pos + strlen($part) );
				// 配列に保存
				$ret[ $new_key ] = $val;
			}
		}

		return $ret;
	}

	/** 
	 *	文字列のエンコーディング判定
	 */
	public static function detectEncoding( $str, $detect_order = "EUC-JP, SJIS, JIS, UTF-8" ){

		return mb_detect_encoding( $str, $detect_order, TRUE );

	}

	/**
	 *	エンコード変換
	 */
	public static function encode( $str, $to_encoding = NULL, $from_encoding = NULL )
	{
		if ( is_string($str) && $to_encoding ){
			// エンコードあり
			return mb_convert_encoding($str,$to_encoding, $from_encoding);
		}
		// エンコード無し
		return $str;
	}

	/**
	 *	配列エンコード変換
	 */
	public static function encodeAssoc( $ary, $to_encoding = NULL, $from_encoding = NULL )
	{
		$new_array = array();
		foreach( $ary as $key => $value ){
			$new_array[ $key ] = self::encode( $value, $to_encoding, $from_encoding );
		}
		return $new_array;
	}

	/**
	 *	配列エンコード変換
	 */
	public static function encodeArray( $ary, $to_encoding = NULL, $from_encoding = NULL )
	{
		$new_array = array();
		foreach( $ary as $item ){
			$new_array[] = self::encode( $item, $to_encoding, $from_encoding );
		}
		return $new_array;
	}
}

?>
