PSR에 맞게 수정

This commit is contained in:
2018-04-06 19:03:35 +09:00
parent 37339b91b0
commit 2bce82c73e
18 changed files with 584 additions and 481 deletions
+1
View File
@@ -23,6 +23,7 @@ class RootDB{
* DB 객체 생성 * DB 객체 생성
* *
* @return \MeekroDB * @return \MeekroDB
* @suppress PhanTypeMismatchProperty
*/ */
public static function db(){ public static function db(){
if(self::$uDB === null){ if(self::$uDB === null){
+1
View File
@@ -21,6 +21,7 @@ class DB{
* DB 객체 생성 * DB 객체 생성
* *
* @return \MeekroDB * @return \MeekroDB
* @suppress PhanTypeMismatchProperty
*/ */
public static function db(){ public static function db(){
if(self::$uDB === null){ if(self::$uDB === null){
+2 -2
View File
@@ -92,7 +92,7 @@ function getSpecial($leader, $power, $intel) {
$type = array(20, 31); $type = array(20, 31);
$special = $type[array_rand($type)]; $special = $type[array_rand($type)];
// 귀모는 50% * 5% = 2.5% // 귀모는 50% * 5% = 2.5%
if($special == 31 && randBool(0.95)) { if($special == 31 && Util::randBool(0.95)) {
$special = 20; $special = 20;
} }
//무장 //무장
@@ -100,7 +100,7 @@ function getSpecial($leader, $power, $intel) {
$type = array(10, 11, 12, 31); $type = array(10, 11, 12, 31);
$special = $type[array_rand($type)]; $special = $type[array_rand($type)];
// 귀모는 그중에 25% * 10% = 2.5% // 귀모는 그중에 25% * 10% = 2.5%
if($special == 31 && randBool(0.9)) { if($special == 31 && Util::randBool(0.9)) {
$type = array(10, 11, 12); $type = array(10, 11, 12);
$special = $type[array_rand($type)]; $special = $type[array_rand($type)];
} }
+4 -5
View File
@@ -3,8 +3,8 @@ namespace sammo;
require(__dir__.'/vendor/autoload.php'); require(__dir__.'/vendor/autoload.php');
if(!class_exists('\\sammo\\RootDB')){ if (!class_exists('\\sammo\\RootDB')) {
header ('Location:install.php'); header('Location:install.php');
die(); die();
} }
@@ -13,9 +13,8 @@ $session = Session::getInstance();
use \kakao\KakaoKey as KakaoKey; use \kakao\KakaoKey as KakaoKey;
if ($session->isLoggedIn()) {
if($session->isLoggedIn()){ header('Location:i_entrance/entrance.php');
header ('Location:i_entrance/entrance.php');
die(); die();
} }
+173 -161
View File
@@ -2,11 +2,12 @@
namespace kakao; namespace kakao;
if (class_exists('\\kakao\\KakaoKey') === false) { if (class_exists('\\kakao\\KakaoKey') === false) {
class KakaoKey{ class KakaoKey
const REST_KEY = ''; {
const ADMIN_KEY = ''; const REST_KEY = '';
const REDIRECT_URI = ''; const ADMIN_KEY = '';
} const REDIRECT_URI = '';
}
} }
//https://devtalk.kakao.com/t/php-rest-api/14602/3 //https://devtalk.kakao.com/t/php-rest-api/14602/3
//header('Content-Type: application/json; charset=utf-8'); //header('Content-Type: application/json; charset=utf-8');
@@ -19,241 +20,252 @@ if (class_exists('\\kakao\\KakaoKey') === false) {
class User_Management_Path class User_Management_Path
{ {
public static $TOKEN = "/oauth/token"; public static $TOKEN = "/oauth/token";
public static $SIGNUP = "/v1/user/signup"; public static $SIGNUP = "/v1/user/signup";
public static $UNLINK = "/v1/user/unlink"; public static $UNLINK = "/v1/user/unlink";
public static $LOGOUT = "/v1/user/logout"; public static $LOGOUT = "/v1/user/logout";
public static $ME = "/v1/user/me"; public static $ME = "/v1/user/me";
public static $UPDATE_PROFILE = "/v1/user/update_profile"; public static $UPDATE_PROFILE = "/v1/user/update_profile";
public static $USER_IDS = "/v1/user/ids"; public static $USER_IDS = "/v1/user/ids";
} }
class Story_Path class Story_Path
{ {
public static $PROFILE = "/v1/api/story/profile"; public static $PROFILE = "/v1/api/story/profile";
public static $ISSTORYUSER = "/v1/api/story/isstoryuser"; public static $ISSTORYUSER = "/v1/api/story/isstoryuser";
public static $MYSTORIES = "/v1/api/story/mystories"; public static $MYSTORIES = "/v1/api/story/mystories";
public static $MYSTORY = "/v1/api/story/mystory"; public static $MYSTORY = "/v1/api/story/mystory";
public static $DELETE_MYSTORY = "/v1/api/story/delete/mystory"; public static $DELETE_MYSTORY = "/v1/api/story/delete/mystory";
public static $POST_NOTE = "/v1/api/story/post/note"; public static $POST_NOTE = "/v1/api/story/post/note";
public static $UPLOAD_MULTI = "/v1/api/story/upload/multi"; public static $UPLOAD_MULTI = "/v1/api/story/upload/multi";
public static $POST_PHOTO = "/v1/api/story/post/photo"; public static $POST_PHOTO = "/v1/api/story/post/photo";
public static $LINKINFO = "/v1/api/story/linkinfo"; public static $LINKINFO = "/v1/api/story/linkinfo";
public static $POST_LINK = "/v1/api/story/post/link"; public static $POST_LINK = "/v1/api/story/post/link";
} }
class Talk_Path class Talk_Path
{ {
public static $TALK_PROFILE= "/v1/api/talk/profile"; public static $TALK_PROFILE= "/v1/api/talk/profile";
public static $TALK_TO_ME = "/v2/api/talk/memo/send"; public static $TALK_TO_ME = "/v2/api/talk/memo/send";
public static $TALK_TO_ME_DEFAULT = "/v2/api/talk/memo/default/send"; public static $TALK_TO_ME_DEFAULT = "/v2/api/talk/memo/default/send";
} }
class Push_Notification_Path class Push_Notification_Path
{ {
public static $REGISTER = "/v1/push/register"; public static $REGISTER = "/v1/push/register";
public static $TOKENS = "/v1/push/tokens"; public static $TOKENS = "/v1/push/tokens";
public static $DEREGISTER = "/v1/push/deregister"; public static $DEREGISTER = "/v1/push/deregister";
public static $SEND = "/v1/push/send"; public static $SEND = "/v1/push/send";
} }
class Kakao_REST_API_Helper class Kakao_REST_API_Helper
{ {
public static $OAUTH_HOST = "https://kauth.kakao.com"; public static $OAUTH_HOST = "https://kauth.kakao.com";
public static $API_HOST = "https://kapi.kakao.com"; public static $API_HOST = "https://kapi.kakao.com";
private static $admin_apis; private static $admin_apis;
private $access_token; private $access_token;
private $admin_key; private $admin_key;
public function __construct($access_token = '') { public function __construct($access_token = '')
{
if ($access_token) {
$this->access_token = $access_token;
}
if ($access_token) { self::$admin_apis = array(
$this->access_token = $access_token;
}
self::$admin_apis = array(
User_Management_Path::$USER_IDS, User_Management_Path::$USER_IDS,
Push_Notification_Path::$REGISTER, Push_Notification_Path::$REGISTER,
Push_Notification_Path::$TOKENS, Push_Notification_Path::$TOKENS,
Push_Notification_Path::$DEREGISTER, Push_Notification_Path::$DEREGISTER,
Push_Notification_Path::$SEND Push_Notification_Path::$SEND
); );
}
public function request($api_path, $params = '', $http_method = 'GET')
{
if ($api_path != Story_Path::$UPLOAD_MULTI && is_array($params)) { // except for uploading
$params = http_build_query($params);
} }
$requestUrl = ($api_path == '/oauth/token' ? self::$OAUTH_HOST : self::$API_HOST) . $api_path; public function request($api_path, $params = '', $http_method = 'GET')
{
if ($api_path != Story_Path::$UPLOAD_MULTI && is_array($params)) { // except for uploading
$params = http_build_query($params);
}
if (($http_method == 'GET' || $http_method == 'DELETE') && !empty($params)) { $requestUrl = ($api_path == '/oauth/token' ? self::$OAUTH_HOST : self::$API_HOST) . $api_path;
$requestUrl .= '?'.$params;
}
$opts = array( if (($http_method == 'GET' || $http_method == 'DELETE') && !empty($params)) {
$requestUrl .= '?'.$params;
}
$opts = array(
CURLOPT_URL => $requestUrl, CURLOPT_URL => $requestUrl,
CURLOPT_RETURNTRANSFER => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLVERSION => 1, CURLOPT_SSLVERSION => 1,
); );
if ($api_path != '/oauth/token') if ($api_path != '/oauth/token') {
if (in_array($api_path, self::$admin_apis)) {
if (!$this->admin_key) {
throw new Exception('admin key should not be null or empty.');
}
$headers = array('Authorization: KakaoAK ' . $this->admin_key);
} else {
if (!$this->access_token) {
throw new Exception('access token should not be null or empty.');
}
$headers = array('Authorization: Bearer ' . $this->access_token);
}
$opts[CURLOPT_HEADER] = false;
$opts[CURLOPT_HTTPHEADER] = $headers;
}
if ($http_method == 'POST') {
$opts[CURLOPT_POST] = true;
if ($params) {
$opts[CURLOPT_POSTFIELDS] = $params;
}
} elseif ($http_method == 'DELETE') {
$opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
}
$curl_session = curl_init();
curl_setopt_array($curl_session, $opts);
$return_data = curl_exec($curl_session);
if (curl_errno($curl_session)) {
throw new Exception(curl_error($curl_session));
} else {
// 디버깅 시에 주석을 풀고 응답 내용 확인할 때
//print_r(curl_getinfo($curl_session));
curl_close($curl_session);
return json_decode($return_data, true);
}
}
public function set_access_token($access_token)
{ {
if (in_array($api_path, self::$admin_apis)) { $this->access_token = $access_token;
if (!$this->admin_key) {
throw new Exception('admin key should not be null or empty.');
}
$headers = array('Authorization: KakaoAK ' . $this->admin_key);
} else {
if (!$this->access_token) {
throw new Exception('access token should not be null or empty.');
}
$headers = array('Authorization: Bearer ' . $this->access_token);
}
$opts[CURLOPT_HEADER] = false;
$opts[CURLOPT_HTTPHEADER] = $headers;
} }
if ($http_method == 'POST') { public function set_admin_key($admin_key)
$opts[CURLOPT_POST] = true; {
if ($params) { $this->admin_key = $admin_key;
$opts[CURLOPT_POSTFIELDS] = $params;
}
} else if ($http_method == 'DELETE') {
$opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
} }
$curl_session = curl_init(); ///////////////////////////////////////////////////////////////
curl_setopt_array($curl_session, $opts); // User Management
$return_data = curl_exec($curl_session); ///////////////////////////////////////////////////////////////
if (curl_errno($curl_session)) { private function _create_or_refresh_access_token($params)
throw new Exception(curl_error($curl_session)); {
} else { return $this->request(User_Management_Path::$TOKEN, $params, 'POST');
// 디버깅 시에 주석을 풀고 응답 내용 확인할 때
//print_r(curl_getinfo($curl_session));
curl_close($curl_session);
return json_decode($return_data, true);
} }
}
public function set_access_token($access_token) { public function create_access_token($authorization_code)
$this->access_token = $access_token; {
} $this->AUTHORIZATION_CODE = $authorization_code;
$params = [
public function set_admin_key($admin_key) {
$this->admin_key = $admin_key;
}
///////////////////////////////////////////////////////////////
// User Management
///////////////////////////////////////////////////////////////
private function _create_or_refresh_access_token($params) {
return $this->request(User_Management_Path::$TOKEN, $params, 'POST');
}
public function create_access_token($authorization_code){
$this->AUTHORIZATION_CODE = $authorization_code;
$params = [
'grant_type'=>'authorization_code', 'grant_type'=>'authorization_code',
'client_id'=>$this->REST_KEY, 'client_id'=>$this->REST_KEY,
'redirect_uri'=>$this->REDIRECT_URI, 'redirect_uri'=>$this->REDIRECT_URI,
'code'=>$this->AUTHORIZATION_CODE 'code'=>$this->AUTHORIZATION_CODE
]; ];
$result = $this->_create_or_refresh_access_token($params); $result = $this->_create_or_refresh_access_token($params);
return $result; return $result;
} }
public function refresh_access_token($refresh_token){ public function refresh_access_token($refresh_token)
$params = [ {
$params = [
'grant_type'=>'refresh_token', 'grant_type'=>'refresh_token',
'client_id'=>$this->REST_KEY, 'client_id'=>$this->REST_KEY,
'redirect_uri'=>$this->REDIRECT_URI, 'redirect_uri'=>$this->REDIRECT_URI,
'code'=>$refresh_token 'code'=>$refresh_token
]; ];
$result = $this->_create_or_refresh_access_token($params); $result = $this->_create_or_refresh_access_token($params);
return $result; return $result;
} }
public function signup() { public function signup()
return $this->request(User_Management_Path::$SIGNUP); {
} return $this->request(User_Management_Path::$SIGNUP);
}
public function unlink() { public function unlink()
return $this->request(User_Management_Path::$UNLINK); {
} return $this->request(User_Management_Path::$UNLINK);
}
public function logout() { public function logout()
return $this->request(User_Management_Path::$UNLINK); {
} return $this->request(User_Management_Path::$UNLINK);
}
public function me() { public function me()
return $this->request(User_Management_Path::$ME); {
} return $this->request(User_Management_Path::$ME);
}
public function meWithEmail(){ public function meWithEmail()
$params = [ {
$params = [
'propertyKeys'=>'["id","kaacount_email","kaccount_email_verified"]' 'propertyKeys'=>'["id","kaacount_email","kaccount_email_verified"]'
]; ];
return $this->request(User_Management_Path::$ME); return $this->request(User_Management_Path::$ME);
} }
public function update_profile($params) { public function update_profile($params)
return $this->request(User_Management_Path::$UPDATE_PROFILE, $params, 'POST'); {
} return $this->request(User_Management_Path::$UPDATE_PROFILE, $params, 'POST');
}
public function user_ids() { public function user_ids()
return $this->request(User_Management_Path::$USER_IDS); {
} return $this->request(User_Management_Path::$USER_IDS);
}
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// Kakao Story // Kakao Story
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
public function isstoryuser() { public function isstoryuser()
return $this->request(Story_Path::$ISSTORYUSER); {
} return $this->request(Story_Path::$ISSTORYUSER);
}
public function story_profile() { public function story_profile()
return $this->request(Story_Path::$PROFILE); {
} return $this->request(Story_Path::$PROFILE);
}
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// Kakao Talk // Kakao Talk
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
public function talk_profile() { public function talk_profile()
return $this->request(Talk_Path::$TALK_PROFILE); {
} return $this->request(Talk_Path::$TALK_PROFILE);
}
public function talk_to_me_default($req){ public function talk_to_me_default($req)
{
$params = [ $params = [
'template_object' => json_encode($req) 'template_object' => json_encode($req)
]; ];
return $this->request(Talk_Path::$TALK_TO_ME_DEFAULT, $params, 'POST'); return $this->request(Talk_Path::$TALK_TO_ME_DEFAULT, $params, 'POST');
} }
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
// API Test // API Test
/////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////
private $REST_KEY = KakaoKey::REST_KEY; // 디벨로퍼스의 앱 설정에서 확인할 수 있습니다. private $REST_KEY = KakaoKey::REST_KEY; // 디벨로퍼스의 앱 설정에서 확인할 수 있습니다.
private $REDIRECT_URI = KakaoKey::REDIRECT_URI; // 설정에 등록한 사이트 도메인 + redirect uri private $REDIRECT_URI = KakaoKey::REDIRECT_URI; // 설정에 등록한 사이트 도메인 + redirect uri
private $AUTHORIZATION_CODE = ''; // 동의를 한 후 발급되는 code private $AUTHORIZATION_CODE = ''; // 동의를 한 후 발급되는 code
private $REFRESH_TOKEN = ''; private $REFRESH_TOKEN = '';
} }
+17 -13
View File
@@ -1,16 +1,18 @@
<?php <?php
namespace sammo; namespace sammo;
class AppConf{ class AppConf
{
private static $serverList = null; private static $serverList = null;
/** /**
* 서버 설정 반환 * 서버 설정 반환
* *
* @return \sammo\Setting[] * @return \sammo\Setting[]
*/ */
public static function getList(){ public static function getList()
if(self::$serverList === null){ {
if (self::$serverList === null) {
self::$serverList = [ self::$serverList = [
'che'=>new Setting(ROOT.'/che', '체', 'white'), 'che'=>new Setting(ROOT.'/che', '체', 'white'),
'kwe'=>new Setting(ROOT.'/kwe', '퀘', 'yellow'), 'kwe'=>new Setting(ROOT.'/kwe', '퀘', 'yellow'),
@@ -24,11 +26,12 @@ class AppConf{
/** /**
* DB 객체 생성 * DB 객체 생성
* *
* @return \MeekroDB * @return \MeekroDB
*/ */
public static function requireRootDB(){ public static function requireRootDB()
if(!class_exists('\\sammo\\RootDB')){ {
if (!class_exists('\\sammo\\RootDB')) {
trigger_error('RootDB.php가 설정되지 않았습니다.', E_USER_ERROR); trigger_error('RootDB.php가 설정되지 않았습니다.', E_USER_ERROR);
die(); die();
} }
@@ -37,14 +40,15 @@ class AppConf{
/** /**
* DB 객체 생성 * DB 객체 생성
* *
* @return \MeekroDB * @return \MeekroDB
*/ */
public static function requireDB(){ public static function requireDB()
if(!class_exists('\\sammo\\DB')){ {
if (!class_exists('\\sammo\\DB')) {
trigger_error('DB.php가 설정되지 않았습니다.', E_USER_ERROR); trigger_error('DB.php가 설정되지 않았습니다.', E_USER_ERROR);
die(); die();
} }
return DB::db(); return DB::db();
} }
} }
+3 -3
View File
@@ -1,6 +1,6 @@
<?php <?php
namespace sammo; namespace sammo;
class FileTail extends \PhpExtended\Tail\Tail{ class FileTail extends \PhpExtended\Tail\Tail
{
}; };
+11 -8
View File
@@ -1,15 +1,17 @@
<?php <?php
namespace sammo; namespace sammo;
class FileUtil{ class FileUtil
public static function delInDir(string $dir) { {
public static function delInDir(string $dir)
{
$handle = opendir($dir); $handle = opendir($dir);
if($handle !== false){ if ($handle !== false) {
while(false !== ($FolderOrFile = readdir($handle))) { while (false !== ($FolderOrFile = readdir($handle))) {
if ($FolderOrFile == "." || $FolderOrFile == "..") { if ($FolderOrFile == "." || $FolderOrFile == "..") {
continue; continue;
} }
if($FolderOrFile[0] == '.'){ if ($FolderOrFile[0] == '.') {
continue; continue;
} }
@@ -27,7 +29,8 @@ class FileUtil{
return true; return true;
} }
function delExpiredInDir($dir, $t) { public function delExpiredInDir($dir, $t)
{
$handle = opendir($dir); $handle = opendir($dir);
if ($handle !== false) { if ($handle !== false) {
while (false !== ($FolderOrFile = readdir($handle))) { while (false !== ($FolderOrFile = readdir($handle))) {
@@ -50,5 +53,5 @@ class FileUtil{
} }
return $success; return $success;
} }
} }
+14 -10
View File
@@ -1,34 +1,38 @@
<?php <?php
namespace sammo; namespace sammo;
class Json{ class Json
{
const PRETTY = 1; const PRETTY = 1;
const DELETE_NULL = 2; const DELETE_NULL = 2;
const NO_CACHE = 4; const NO_CACHE = 4;
public static function encode($value, $flag = 0){ public static function encode($value, $flag = 0)
{
$rawFlag = JSON_UNESCAPED_UNICODE; $rawFlag = JSON_UNESCAPED_UNICODE;
if($flag & static::PRETTY){ if ($flag & static::PRETTY) {
$rawFlag |= JSON_PRETTY_PRINT; $rawFlag |= JSON_PRETTY_PRINT;
} }
if($flag & static::DELETE_NULL){ if ($flag & static::DELETE_NULL) {
$value = Util::eraseNullValue($value); $value = Util::eraseNullValue($value);
} }
return json_encode($value, $rawFlag); return json_encode($value, $rawFlag);
} }
public static function decode($value){ public static function decode($value)
{
return json_decode($value, true); return json_decode($value, true);
} }
public static function die($value, $flag = self::NO_CACHE){ public static function die($value, $flag = self::NO_CACHE)
{
//NOTE: REST 형식에 맞게, ok(), fail()로 쪼개는게 낫지 않을까 생각해봄. //NOTE: REST 형식에 맞게, ok(), fail()로 쪼개는게 낫지 않을까 생각해봄.
if($flag & static::NO_CACHE){ if ($flag & static::NO_CACHE) {
WebUtil::setHeaderNoCache(); WebUtil::setHeaderNoCache();
} }
header('Content-Type: application/json'); header('Content-Type: application/json');
die(Json::encode($value, $flag)); die(Json::encode($value, $flag));
} }
} }
+41 -26
View File
@@ -1,27 +1,37 @@
<?php <?php
namespace sammo; namespace sammo;
class Lock { class Lock
{
private static $l = ROOT.'/d_log/lock.txt'; private static $l = ROOT.'/d_log/lock.txt';
public static function Busy() { public static function Busy()
{
$fp = fopen(Lock::$l, 'r'); $fp = fopen(Lock::$l, 'r');
$lock = fread($fp, 1); $lock = fread($fp, 1);
fclose($fp); fclose($fp);
if($lock == 1) return true; if ($lock == 1) {
else return false; return true;
} else {
return false;
}
} }
private static function LockFile() { private static function LockFile()
{
$fp = fopen(Lock::$l, 'r'); $fp = fopen(Lock::$l, 'r');
$lock = fread($fp, 1); $lock = fread($fp, 1);
fclose($fp); fclose($fp);
if($lock == 1) return false; if ($lock == 1) {
return false;
}
$fp = fopen(Lock::$l, 'w'); $fp = fopen(Lock::$l, 'w');
if(!flock($fp, LOCK_EX)) { return false; } if (!flock($fp, LOCK_EX)) {
return false;
}
fwrite($fp, '1'); fwrite($fp, '1');
fclose($fp); fclose($fp);
flock($fp, LOCK_UN); flock($fp, LOCK_UN);
@@ -29,15 +39,20 @@ class Lock {
return true; return true;
} }
private static function UnlockFile() { private static function UnlockFile()
{
$fp = fopen(Lock::$l, 'r'); $fp = fopen(Lock::$l, 'r');
$lock = fread($fp, 1); $lock = fread($fp, 1);
fclose($fp); fclose($fp);
if($lock == 0) return false; if ($lock == 0) {
return false;
}
$fp = fopen(Lock::$l, 'w'); $fp = fopen(Lock::$l, 'w');
if(!flock($fp, LOCK_EX)) { return false; } if (!flock($fp, LOCK_EX)) {
return false;
}
fwrite($fp, '0'); fwrite($fp, '0');
fclose($fp); fclose($fp);
flock($fp, LOCK_UN); flock($fp, LOCK_UN);
@@ -45,28 +60,28 @@ class Lock {
return true; return true;
} }
public static function Lock() { public static function Lock()
/* {
// 키 생성 /*
$key = fileinode(Lock::$l); // 키 생성
// 뮤텍스 획득 $key = fileinode(Lock::$l);
$mutex = sem_get($key); // 뮤 스 획득
// 락 획득 $mutex = sem_get($key);
sem_acquire($mutex); // 락 획득
*/ sem_acquire($mutex);
*/
// 파일에 잠금 걸기 // 파일에 잠금 걸기
return Lock::LockFile(); return Lock::LockFile();
} }
public static function Unlock() { public static function Unlock()
{
// 파일에 잠금 풀기 // 파일에 잠금 풀기
$res = Lock::UnlockFile(); $res = Lock::UnlockFile();
/* /*
// 락 해제 // 락 해제
sem_release($mutex); sem_release($mutex);
*/ */
return $res; return $res;
} }
} }
+86 -74
View File
@@ -3,20 +3,20 @@ namespace sammo;
/** /**
* Session Wrapper. 내부적으로 $_SESSION을 이용 * Session Wrapper. 내부적으로 $_SESSION을 이용
* *
* @property int $userID 유저코드 * @property int $userID 유저코드
* @property string $userName 유저명 * @property string $userName 유저명
* @property int $userGrade 유저등급 * @property int $userGrade 유저등급
* @property string $ip IP * @property string $ip IP
*/ */
class Session { class Session
{
const PROTECTED_NAMES = [ const PROTECTED_NAMES = [
'ip'=>true, 'ip'=>true,
'time'=>true, 'time'=>true,
'userID'=>true, 'userID'=>true,
'userName'=>true, 'userName'=>true,
'userGrade'=>true, 'userGrade'=>true,
'writeClosed'=>true, 'writeClosed'=>true,
'generalID'=>true, 'generalID'=>true,
'generalName'=>true 'generalName'=>true
@@ -31,15 +31,17 @@ class Session {
private $writeClosed = false; private $writeClosed = false;
private $sessionID = null; private $sessionID = null;
public static function getInstance(): Session{ public static function getInstance(): Session
{
static $inst = null; static $inst = null;
if($inst === null){ if ($inst === null) {
$inst = new Session(); $inst = new Session();
} }
return $inst; return $inst;
} }
public function restart(): Session{ public function restart(): Session
{
//NOTE: logout 프로세스는 아예 세션을 날려버리기도 하므로, 항상 안전하게 session_restart가 가능함을 보장하지 않음. //NOTE: logout 프로세스는 아예 세션을 날려버리기도 하므로, 항상 안전하게 session_restart가 가능함을 보장하지 않음.
ini_set('session.use_only_cookies', false); ini_set('session.use_only_cookies', false);
ini_set('session.use_cookies', false); ini_set('session.use_cookies', false);
@@ -50,8 +52,9 @@ class Session {
return $this; return $this;
} }
private static function die($result){ private static function die($result)
if(is_string($result)){ {
if (is_string($result)) {
header('Location:'.$result); header('Location:'.$result);
die(); die();
} }
@@ -61,90 +64,98 @@ class Session {
'reason'=>'로그인이 필요합니다.' 'reason'=>'로그인이 필요합니다.'
]; ];
if(is_array($result)){ if (is_array($result)) {
$jsonResult = array_merge($result, $jsonResult); $jsonResult = array_merge($result, $jsonResult);
} }
Json::die($jsonResult); Json::die($jsonResult);
} }
public static function requireLogin($result = '..'): Session{ public static function requireLogin($result = '..'): Session
{
$session = Session::getInstance(); $session = Session::getInstance();
if($session->isLoggedIn()){ if ($session->isLoggedIn()) {
return $session; return $session;
} }
static::die($result); static::die($result);
} }
public static function requireGameLogin($result = '..'): Session{ public static function requireGameLogin($result = '..'): Session
{
$session = Session::requireLogin($result)->loginGame(); $session = Session::requireLogin($result)->loginGame();
if($session->generalID){ if ($session->generalID) {
return $session; return $session;
} }
static::die($result); static::die($result);
} }
public function __construct() { public function __construct()
{
//session_cache_limiter('nocache, must_revalidate'); //session_cache_limiter('nocache, must_revalidate');
// 세션 변수의 등록 // 세션 변수의 등록
if (session_id() == ""){ if (session_id() == "") {
session_start(); session_start();
$this->sessionID = session_id(); $this->sessionID = session_id();
} }
//첫 등장 //첫 등장
if(!$this->get('ip')) { if (!$this->get('ip')) {
$this->set('ip', Util::get_client_ip(true)); $this->set('ip', Util::get_client_ip(true));
$this->set('time', time()); $this->set('time', time());
} }
} }
public function setReadOnly(): Session{ public function setReadOnly(): Session
if(!$this->writeClosed){ {
if (!$this->writeClosed) {
session_write_close(); session_write_close();
$this->writeClosed = true; $this->writeClosed = true;
} }
return $this; return $this;
} }
public function __set(string $name, $value){ public function __set(string $name, $value)
if(key_exists($name, $this->PROTECED_NAMES)){ {
if (key_exists($name, $this->PROTECED_NAMES)) {
trigger_error("{$name}은 외부에서 쓰기 금지된 Session 변수입니다.", E_USER_NOTICE); trigger_error("{$name}은 외부에서 쓰기 금지된 Session 변수입니다.", E_USER_NOTICE);
return; return;
} }
$this->set($name, $value); $this->set($name, $value);
} }
private function set(string $name, $value){ private function set(string $name, $value)
if($value === null){ {
if ($value === null) {
unset($_SESSION[$name]); unset($_SESSION[$name]);
} } else {
else{
$_SESSION[$name] = $value; $_SESSION[$name] = $value;
} }
} }
public function __get(string $name){ public function __get(string $name)
if($name == 'generalID'){ {
if ($name == 'generalID') {
return $this->get(UniqueConst::$serverID.static::GAME_KEY_GENERAL_ID); return $this->get(UniqueConst::$serverID.static::GAME_KEY_GENERAL_ID);
} }
if($name == 'generalName'){ if ($name == 'generalName') {
return $this->get(UniqueConst::$serverID.static::GAME_KEY_GENERAL_NAME); return $this->get(UniqueConst::$serverID.static::GAME_KEY_GENERAL_NAME);
} }
return $this->get($name); return $this->get($name);
} }
private function get(string $name){ private function get(string $name)
{
return Util::array_get($_SESSION[$name]); return Util::array_get($_SESSION[$name]);
} }
public function login(int $userID, string $userName, int $grade): Session { public function login(int $userID, string $userName, int $grade): Session
{
$this->set('userID', $userID); $this->set('userID', $userID);
$this->set('userName', $userName); $this->set('userName', $userName);
$this->set('ip', Util::get_client_ip(true)); $this->set('ip', Util::get_client_ip(true));
@@ -155,11 +166,12 @@ class Session {
} }
public function logout(): Session { public function logout(): Session
if($this->writeClosed){ {
if ($this->writeClosed) {
$this->restart(); $this->restart();
} }
if(class_exists('\\sammo\\UniqueConst')){ if (class_exists('\\sammo\\UniqueConst')) {
$this->logoutGame(); $this->logoutGame();
} }
@@ -170,17 +182,18 @@ class Session {
return $this; return $this;
} }
public function loginGame(&$result = null): Session{ public function loginGame(&$result = null): Session
{
$userID = $this->userID; $userID = $this->userID;
if(!$userID){ if (!$userID) {
if($result !== null){ if ($result !== null) {
$result = false; $result = false;
} }
return $this; return $this;
} }
if(!class_exists('\\sammo\\DB') || !class_exists('\\sammo\\UniqueConst')){ if (!class_exists('\\sammo\\DB') || !class_exists('\\sammo\\UniqueConst')) {
if($result !== null){ if ($result !== null) {
$result = false; $result = false;
} }
return $this; return $this;
@@ -194,29 +207,29 @@ class Session {
$deadTime = $this->get($serverID.static::GAME_KEY_EXPECTED_DEADTIME); $deadTime = $this->get($serverID.static::GAME_KEY_EXPECTED_DEADTIME);
$now = time(); $now = time();
if( if (
$generalID && $generalName && $loginDate && $deadTime $generalID && $generalName && $loginDate && $deadTime
&& $loginDate + 1800 > $now && $deadTime > $now && $loginDate + 1800 > $now && $deadTime > $now
){ ) {
//로그인 정보는 30분간 유지한다. //로그인 정보는 30분간 유지한다.
if($result !== null){ if ($result !== null) {
$result = true; $result = true;
} }
return $this; return $this;
} }
if($generalID || $generalName || $loginDate || $deadTime){ if ($generalID || $generalName || $loginDate || $deadTime) {
$this->logoutGame(); $this->logoutGame();
} }
$db = DB::db(); $db = DB::db();
$general = $db->queryFirstRow( $general = $db->queryFirstRow(
'SELECT `no`, `name`, `killturn`, `turntime` from general where `owner` = %i', 'SELECT `no`, `name`, `killturn`, `turntime` from general where `owner` = %i',
$userID $userID
); );
if(!$general){ if (!$general) {
if($result !== null){ if ($result !== null) {
$result = false; $result = false;
} }
return $this; return $this;
@@ -232,15 +245,14 @@ class Session {
$nextTurn = $nextTurn->getTimestamp(); $nextTurn = $nextTurn->getTimestamp();
$deadTime = $nextTurn + $general['killturn'] * $turnterm; $deadTime = $nextTurn + $general['killturn'] * $turnterm;
if($deadTime < $now && !$isUnited){ if ($deadTime < $now && !$isUnited) {
$locked = $db->queryFirstField('SELECT plock FROM plock LIMIT 1'); $locked = $db->queryFirstField('SELECT plock FROM plock LIMIT 1');
if(!$locked){ if (!$locked) {
if($result !== null){ if ($result !== null) {
$result = false; $result = false;
} }
return $this; return $this;
} }
} }
$db->update('general', [ $db->update('general', [
@@ -256,8 +268,9 @@ class Session {
return $this; return $this;
} }
public function logoutGame(): Session{ public function logoutGame(): Session
if($this->writeClosed){ {
if ($this->writeClosed) {
$this->restart(); $this->restart();
} }
$serverID = UniqueConst::$serverID; $serverID = UniqueConst::$serverID;
@@ -273,44 +286,43 @@ class Session {
* 로그인 유저의 전역 grade를 받아옴 * 로그인 유저의 전역 grade를 받아옴
* @return int|null * @return int|null
*/ */
public static function getUserGrade(bool $requireLogin = false, string $exitPath = '..'){ public static function getUserGrade(bool $requireLogin = false, string $exitPath = '..')
if($requireLogin){ {
if ($requireLogin) {
$obj = self::requireLogin($exitPath); $obj = self::requireLogin($exitPath);
} } else {
else{
$obj = self::getInstance(); $obj = self::getInstance();
} }
return $obj->userGrade; return $obj->userGrade;
} }
/** /**
* 로그인한 유저의 전역 id(숫자)를 받아옴 * 로그인한 유저의 전역 id(숫자)를 받아옴
* *
* @return int|null * @return int|null
*/ */
public static function getUserID(bool $requireLogin = false, string $exitPath = '..'){ public static function getUserID(bool $requireLogin = false, string $exitPath = '..')
if($requireLogin){ {
if ($requireLogin) {
$obj = self::requireLogin($exitPath); $obj = self::requireLogin($exitPath);
} } else {
else{
$obj = self::getInstance(); $obj = self::getInstance();
} }
return $obj->userID; return $obj->userID;
} }
public function isLoggedIn() { public function isLoggedIn()
if($this->userID){ {
if ($this->userID) {
return true; return true;
} } else {
else{
return false; return false;
} }
} }
public function __destruct() { public function __destruct()
{
} }
} }
+40 -31
View File
@@ -1,7 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
class Setting { class Setting
{
private $basepath; private $basepath;
private $settingFile; private $settingFile;
private $htaccessFile; private $htaccessFile;
@@ -14,7 +15,8 @@ class Setting {
private $color; private $color;
private $version = null; private $version = null;
public function __construct(string $basepath, string $korName, string $color, string $name=null) { public function __construct(string $basepath, string $korName, string $color, string $name=null)
{
$this->basepath = $basepath; $this->basepath = $basepath;
$this->settingFile = realpath($basepath.'/d_setting/DB.php'); $this->settingFile = realpath($basepath.'/d_setting/DB.php');
$this->htaccessFile = realpath($basepath.'/.htaccess'); $this->htaccessFile = realpath($basepath.'/.htaccess');
@@ -22,56 +24,63 @@ class Setting {
$this->korName = $korName; $this->korName = $korName;
$this->color = $color; $this->color = $color;
if($name){ if ($name) {
$this->shortName = $name; $this->shortName = $name;
} } else {
else{
$this->shortName = basename($this->basepath); $this->shortName = basename($this->basepath);
} }
if(file_exists($this->settingFile)) { if (file_exists($this->settingFile)) {
$this->exist = true; $this->exist = true;
if(!file_exists($this->htaccessFile)){ if (!file_exists($this->htaccessFile)) {
$this->running = true; $this->running = true;
} }
} }
} }
public function isRunning(){ public function isRunning()
{
return $this->running; return $this->running;
} }
public function isExists() { public function isExists()
{
return $this->exist; return $this->exist;
} }
public function getShortName(){ public function getShortName()
{
return $this->shortName; return $this->shortName;
} }
public function getColor(){ public function getColor()
{
return $this->color; return $this->color;
} }
public function getKorName(){ public function getKorName()
{
return $this->korName; return $this->korName;
} }
public function getBasePath(){ public function getBasePath()
{
return $this->basepath; return $this->basepath;
} }
public function getSettingFile() { public function getSettingFile()
{
return $this->settingFile; return $this->settingFile;
} }
public function getVersion(){ public function getVersion()
if($this->version !== null){ {
if ($this->version !== null) {
return $this->version; return $this->version;
} }
if(!file_exists($this->versionFile)){ if (!file_exists($this->versionFile)) {
$this->version = 'noVersionFile'; $this->version = 'noVersionFile';
return $this->version; return $this->version;
} }
@@ -79,7 +88,7 @@ class Setting {
$tail = new FileTail($this->versionFile); $tail = new FileTail($this->versionFile);
$version = 'noVersionJson'; $version = 'noVersionJson';
foreach ($tail->smart(5, 100, true) as $line) { foreach ($tail->smart(5, 100, true) as $line) {
if(Util::starts_with($line, '//{')){ if (Util::starts_with($line, '//{')) {
$version = Json::decode(substr($line, 2)); $version = Json::decode(substr($line, 2));
$version = Util::array_get($version['version'], 'noVersionValue'); $version = Util::array_get($version['version'], 'noVersionValue');
break; break;
@@ -87,40 +96,40 @@ class Setting {
} }
$this->version = $version; $this->version = $version;
return $version; return $version;
} }
public function closeServer(){ public function closeServer()
if(!file_exists($this->basepath) || !is_dir($this->basepath)){ {
if (!file_exists($this->basepath) || !is_dir($this->basepath)) {
return false; return false;
} }
$templates = new \League\Plates\Engine(__dir__.'/templates'); $templates = new \League\Plates\Engine(__dir__.'/templates');
//TODO: .htaccess가 서버 오픈에도 사용될 수 있으니 별도의 방법이 필요함 //TODO: .htaccess가 서버 오픈에도 사용될 수 있으니 별도의 방법이 필요함
$allow_ip = Util::get_client_ip(false); $allow_ip = Util::get_client_ip(false);
if(Util::starts_with($allow_ip, '192.168.') || if (Util::starts_with($allow_ip, '192.168.') ||
Util::starts_with($allow_ip, '10.')) Util::starts_with($allow_ip, '10.')) {
{
//172.16~172.31은 코딩하기 귀찮으니까 안할거다 //172.16~172.31은 코딩하기 귀찮으니까 안할거다
$allow_ip = Util::get_client_ip(true); $allow_ip = Util::get_client_ip(true);
} }
$xforward_allow_ip = WebUtil::escapeIPv4($allow_ip); $xforward_allow_ip = WebUtil::escapeIPv4($allow_ip);
$htaccess = $templates->render('block_htaccess', $htaccess = $templates->render(
['allow_ip' => $allow_ip, 'xforward_allow_ip' => $xforward_allow_ip]); 'block_htaccess',
['allow_ip' => $allow_ip, 'xforward_allow_ip' => $xforward_allow_ip]
);
file_put_contents($this->basepath.'/.htaccess', $htaccess); file_put_contents($this->basepath.'/.htaccess', $htaccess);
return true; return true;
} }
public function openServer(){ public function openServer()
if(!file_exists($this->basepath) || !is_dir($this->basepath)){ {
if (!file_exists($this->basepath) || !is_dir($this->basepath)) {
return false; return false;
} }
if(file_exists($this->basepath.'/.htaccess')){ if (file_exists($this->basepath.'/.htaccess')) {
@unlink($this->basepath.'/.htaccess'); @unlink($this->basepath.'/.htaccess');
} }
return true; return true;
} }
} }
+71 -54
View File
@@ -1,20 +1,22 @@
<?php <?php
namespace sammo; namespace sammo;
class StringUtil { class StringUtil
public static function GetStrLen($str) { {
public static function GetStrLen($str)
{
$count = strlen($str); $count = strlen($str);
$len = 0; $len = 0;
for($i=0; $i < $count; ) { for ($i=0; $i < $count;) {
$code = ord($str[$i]); $code = ord($str[$i]);
if($code >= 0xf0) { if ($code >= 0xf0) {
$len++; $len++;
$i += 4; $i += 4;
} elseif($code >= 0xe0) { } elseif ($code >= 0xe0) {
$len++; $len++;
$i += 3; $i += 3;
} elseif($code >= 0xc2) { } elseif ($code >= 0xc2) {
$len++; $len++;
$i += 2; $i += 2;
} else { } else {
@@ -25,29 +27,32 @@ class StringUtil {
return $len; return $len;
} }
public static function SubStr($str, $s, $l=1000) { public static function SubStr($str, $s, $l=1000)
{
$count = strlen($str); $count = strlen($str);
$startByte = 0; $isSet = 0; $startByte = 0;
$isSet = 0;
$endByte = $count; $endByte = $count;
$len = 0; $len = 0;
for($i=0; $i < $count; ) { for ($i=0; $i < $count;) {
$code = ord($str[$i]); $code = ord($str[$i]);
if($isSet == 0 && $len >= $s) { if ($isSet == 0 && $len >= $s) {
$startByte = $i; $isSet = 1; $startByte = $i;
$isSet = 1;
} }
if($isSet == 1 && $len-$s >= $l) { if ($isSet == 1 && $len-$s >= $l) {
$endByte = $i; $endByte = $i;
break; break;
} }
if($code >= 0xf0) { if ($code >= 0xf0) {
$len++; $len++;
$i += 4; $i += 4;
} elseif($code >= 0xe0) { } elseif ($code >= 0xe0) {
$len++; $len++;
$i += 3; $i += 3;
} elseif($code >= 0xc2) { } elseif ($code >= 0xc2) {
$len++; $len++;
$i += 2; $i += 2;
} else { } else {
@@ -59,39 +64,43 @@ class StringUtil {
return $str; return $str;
} }
public static function SubStrForWidth($str, $s, $w) { public static function SubStrForWidth($str, $s, $w)
{
$count = strlen($str); $count = strlen($str);
$startByte = 0; $isSet = 0; $startByte = 0;
$endByte = $count; $last = 0; $isSet = 0;
$endByte = $count;
$last = 0;
$len = 0; $len = 0;
$width = 0; $width = 0;
for($i=0; $i < $count; ) { for ($i=0; $i < $count;) {
$code = ord($str[$i]); $code = ord($str[$i]);
if($isSet == 0 && $len >= $s) { if ($isSet == 0 && $len >= $s) {
$startByte = $i; $isSet = 1; $startByte = $i;
$isSet = 1;
$width = 0; $width = 0;
} }
if($isSet == 1 && $width == $w) { if ($isSet == 1 && $width == $w) {
$endByte = $i; $endByte = $i;
break; break;
} }
if($isSet == 1 && $width > $w) { if ($isSet == 1 && $width > $w) {
$endByte = $i - $last; $endByte = $i - $last;
break; break;
} }
if($code >= 0xf0) { if ($code >= 0xf0) {
$len++; $len++;
$width += 2; $width += 2;
$last = 4; $last = 4;
$i += 4; $i += 4;
} elseif($code >= 0xe0) { } elseif ($code >= 0xe0) {
$len++; $len++;
$width += 2; $width += 2;
$last = 3; $last = 3;
$i += 3; $i += 3;
} elseif($code >= 0xc2) { } elseif ($code >= 0xc2) {
$len++; $len++;
$width += 2; $width += 2;
$last = 2; $last = 2;
@@ -107,37 +116,41 @@ class StringUtil {
return $str; return $str;
} }
public static function CutStrForWidth($str, $s, $w, $ch='..') { public static function CutStrForWidth($str, $s, $w, $ch='..')
{
$isCut = 0; $isCut = 0;
$count = strlen($str); $count = strlen($str);
$startByte = 0; $isSet = 0; $startByte = 0;
$endByte = $count; $last = 0; $isSet = 0;
$endByte = $count;
$last = 0;
$len = 0; $len = 0;
$width = 0; $width = 0;
for($i=0; $i < $count; ) { for ($i=0; $i < $count;) {
$code = ord($str[$i]); $code = ord($str[$i]);
if($isSet == 0 && $len >= $s) { if ($isSet == 0 && $len >= $s) {
$startByte = $i; $isSet = 1; $startByte = $i;
$isSet = 1;
$width = 0; $width = 0;
} }
if($isSet == 1 && $width >= $w) { if ($isSet == 1 && $width >= $w) {
$endByte = $i - $last; $endByte = $i - $last;
$isCut = 1; $isCut = 1;
break; break;
} }
if($code >= 0xf0) { if ($code >= 0xf0) {
$len++; $len++;
$width += 2; $width += 2;
$last = 4; $last = 4;
$i += 4; $i += 4;
} elseif($code >= 0xe0) { } elseif ($code >= 0xe0) {
$len++; $len++;
$width += 2; $width += 2;
$last = 3; $last = 3;
$i += 3; $i += 3;
} elseif($code >= 0xc2) { } elseif ($code >= 0xc2) {
$len++; $len++;
$width += 2; $width += 2;
$last = 2; $last = 2;
@@ -149,15 +162,16 @@ class StringUtil {
$i += 1; $i += 1;
} }
} }
if($isCut != 0) { if ($isCut != 0) {
$str = substr($str, $startByte, $endByte-$startByte) . $ch; $str = substr($str, $startByte, $endByte-$startByte) . $ch;
} }
return $str; return $str;
} }
//중간정렬 //중간정렬
public static function staticFill($str, $maxsize, $ch) { public static function staticFill($str, $maxsize, $ch)
if(!$str){ {
if (!$str) {
$str = ''; $str = '';
} }
$size = strlen($str); $size = strlen($str);
@@ -165,18 +179,19 @@ class StringUtil {
$count = ($maxsize - $size) / 2; $count = ($maxsize - $size) / 2;
$string = ''; $string = '';
for($i=0; $i < $count; $i++) { for ($i=0; $i < $count; $i++) {
$string = $string.$ch; $string = $string.$ch;
} }
$string = $string.$str; $string = $string.$str;
for($i=0; $i < $count; $i++) { for ($i=0; $i < $count; $i++) {
$string = $string.$ch; $string = $string.$ch;
} }
return $string; return $string;
} }
public static function Fill($str, $maxsize, $ch) { public static function Fill($str, $maxsize, $ch)
if(!$str){ {
if (!$str) {
$str = ''; $str = '';
} }
$size = strlen($str); $size = strlen($str);
@@ -184,26 +199,27 @@ class StringUtil {
$count = ($maxsize - $size) / 2; $count = ($maxsize - $size) / 2;
$string = ''; $string = '';
for($i=0; $i < $count; $i++) { for ($i=0; $i < $count; $i++) {
$string = $string.$ch; $string = $string.$ch;
} }
$string = $string.$str; $string = $string.$str;
for($i=0; $i < $count; $i++) { for ($i=0; $i < $count; $i++) {
$string = $string.$ch; $string = $string.$ch;
} }
return $string; return $string;
} }
//우측정렬 //우측정렬
public static function Fill2($str, $maxsize, $ch='0') { public static function Fill2($str, $maxsize, $ch='0')
if(!$str){ {
if (!$str) {
$str = ''; $str = '';
} }
$size = strlen($str); $size = strlen($str);
$count = ($maxsize - $size); $count = ($maxsize - $size);
$string = ''; $string = '';
for($i=0; $i < $count; $i++) { for ($i=0; $i < $count; $i++) {
$string = $string.$ch; $string = $string.$ch;
} }
$string = $string.$str; $string = $string.$str;
@@ -211,7 +227,8 @@ class StringUtil {
return $string; return $string;
} }
public static function EscapeTag($str) { public static function EscapeTag($str)
{
$str = htmlspecialchars($str); $str = htmlspecialchars($str);
$str = str_replace(["\r\n", "\r", "\n"], '<br>', $str); $str = str_replace(["\r\n", "\r", "\n"], '<br>', $str);
// return nl2br(htmlspecialchars($str)); // return nl2br(htmlspecialchars($str));
@@ -219,13 +236,13 @@ class StringUtil {
return $str; return $str;
} }
public static function removeSpecialCharacter($str) { public static function removeSpecialCharacter($str)
{
return str_replace([ return str_replace([
' ', '"', '\'', 'ⓝ', 'ⓜ', 'ⓖ', '\\', '/', '`', ' ', '"', '\'', 'ⓝ', 'ⓜ', 'ⓖ', '\\', '/', '`',
'-', '=', '[', ']', ';', ',', '.', '~', '!', '@', '-', '=', '[', ']', ';', ',', '.', '~', '!', '@',
'#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',
'|', '{', '}', ':', '', '<', '>', '?', ' ' '|', '{', '}', ':', '', '<', '>', '?', ' '
], '', $str); ], '', $str);
} }
} }
+24 -14
View File
@@ -1,46 +1,57 @@
<?php <?php
namespace sammo; namespace sammo;
class TimeUtil { class TimeUtil
public static function DateToday() { {
public static function DateToday()
{
return date('Y-m-d'); return date('Y-m-d');
} }
public static function DatetimeNow() { public static function DatetimeNow()
{
return date('Y-m-d H:i:s'); return date('Y-m-d H:i:s');
} }
public static function DatetimeFromNowDay($day) { public static function DatetimeFromNowDay($day)
{
return date('Y-m-d H:i:s', strtotime("{$day} days")); return date('Y-m-d H:i:s', strtotime("{$day} days"));
} }
public static function DatetimeFromNowHour($hour) { public static function DatetimeFromNowHour($hour)
{
return date('Y-m-d H:i:s', strtotime("{$hour} hours")); return date('Y-m-d H:i:s', strtotime("{$hour} hours"));
} }
public static function DatetimeFromNowMinute($minute) { public static function DatetimeFromNowMinute($minute)
{
return date('Y-m-d H:i:s', strtotime("{$minute} minutes")); return date('Y-m-d H:i:s', strtotime("{$minute} minutes"));
} }
public static function DatetimeFromNowSecond($second) { public static function DatetimeFromNowSecond($second)
{
return date('Y-m-d H:i:s', strtotime("{$second} seconds")); return date('Y-m-d H:i:s', strtotime("{$second} seconds"));
} }
public static function DatetimeFromMinute($date, $minute) { public static function DatetimeFromMinute($date, $minute)
{
return date('Y-m-d H:i:s', strtotime($date) + $minute*60); return date('Y-m-d H:i:s', strtotime($date) + $minute*60);
} }
public static function DatetimeFromSecond($date, $second) { public static function DatetimeFromSecond($date, $second)
{
return date('Y-m-d H:i:s', strtotime($date) + $second); return date('Y-m-d H:i:s', strtotime($date) + $second);
} }
public static function CutSecond($date) { public static function CutSecond($date)
{
$date[17] = '0'; $date[17] = '0';
$date[18] = '0'; $date[18] = '0';
return $date; return $date;
} }
public static function CutMinute($date) { public static function CutMinute($date)
{
$date[14] = '0'; $date[14] = '0';
$date[15] = '0'; $date[15] = '0';
$date[17] = '0'; $date[17] = '0';
@@ -48,9 +59,8 @@ class TimeUtil {
return $date; return $date;
} }
public static function HourMinuteSecond($second) { public static function HourMinuteSecond($second)
{
return date('H:i:s', strtotime('00:00:00') + $second); return date('H:i:s', strtotime('00:00:00') + $second);
} }
} }
+69 -60
View File
@@ -1,30 +1,33 @@
<?php <?php
namespace sammo; namespace sammo;
class Util extends \utilphp\util{ class Util extends \utilphp\util
public static function hashPassword($salt, $password){ {
public static function hashPassword($salt, $password)
{
return hash('sha512', $salt.$password.$salt); return hash('sha512', $salt.$password.$salt);
} }
/** /**
* 변환할 내용이 _tK_$key_ 형태로 작성된 단순한 템플릿 파일을 이용하여 결과물을 생성해주는 함수. * 변환할 내용이 _tK_$key_ 형태로 작성된 단순한 템플릿 파일을 이용하여 결과물을 생성해주는 함수.
*/ */
public static function generateFileUsingSimpleTemplate(string $srcFilePath, string $destFilePath, array $params, bool $canOverwrite=false){ public static function generateFileUsingSimpleTemplate(string $srcFilePath, string $destFilePath, array $params, bool $canOverwrite=false)
if($destFilePath === $srcFilePath){ {
if ($destFilePath === $srcFilePath) {
return 'invalid destFilePath'; return 'invalid destFilePath';
} }
if(!file_exists($srcFilePath)){ if (!file_exists($srcFilePath)) {
return 'srcFilePath is not exists'; return 'srcFilePath is not exists';
} }
if(file_exists($destFilePath) && !$canOverwrite){ if (file_exists($destFilePath) && !$canOverwrite) {
return 'destFilePath is already exists'; return 'destFilePath is already exists';
} }
if(!is_writable(dirname($destFilePath))){ if (!is_writable(dirname($destFilePath))) {
return 'destFilePath is not writable'; return 'destFilePath is not writable';
} }
$text = file_get_contents($srcFilePath); $text = file_get_contents($srcFilePath);
foreach($params as $key => $value){ foreach ($params as $key => $value) {
$text = str_replace("_tK_{$key}_", $value, $text); $text = str_replace("_tK_{$key}_", $value, $text);
} }
file_put_contents($destFilePath, $text); file_put_contents($destFilePath, $text);
@@ -39,28 +42,29 @@ class Util extends \utilphp\util{
* float -> int * float -> int
* numeric(int, float) 포함 -> int * numeric(int, float) 포함 -> int
* 기타 -> 예외처리 * 기타 -> 예외처리
* *
* @return int|null * @return int|null
*/ */
public static function toInt($val, $silent=false){ public static function toInt($val, $silent=false)
if(!isset($val)){ {
if (!isset($val)) {
return null; return null;
} }
if($val === null){ if ($val === null) {
return null; return null;
} }
if(is_int($val)){ if (is_int($val)) {
return $val; return $val;
} }
if(is_numeric($val)){ if (is_numeric($val)) {
return intval($val);// return intval($val);//
} }
if(strtolower($val) === 'null'){ if (strtolower($val) === 'null') {
return null; return null;
} }
if($silent){ if ($silent) {
if($val == null){ if ($val == null) {
return null; return null;
} }
return intval($val); return intval($val);
@@ -69,12 +73,12 @@ class Util extends \utilphp\util{
} }
/** /**
* Generate a random string, using a cryptographically secure * Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int) * pseudorandom number generator (random_int)
* *
* For PHP 7, random_int is a PHP core function * For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat * For PHP 5.x, depends on https://github.com/paragonie/random_compat
* *
* @param int $length How many characters do we want? * @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters * @param string $keyspace A string of all possible characters
* to select from * to select from
@@ -90,18 +94,20 @@ class Util extends \utilphp\util{
return $str; return $str;
} }
public static function mapWithDict($callback, $dict){ public static function mapWithDict($callback, $dict)
{
$result = []; $result = [];
foreach(array_keys($dict) as $key){ foreach (array_keys($dict) as $key) {
$result[$key] = ($callback)($dict[$key]); $result[$key] = ($callback)($dict[$key]);
} }
return $result; return $result;
} }
public static function convertArrayToDict($arr, $keyName){ public static function convertArrayToDict($arr, $keyName)
{
$result = []; $result = [];
foreach($arr as $obj){ foreach ($arr as $obj) {
$key = $obj[$keyName]; $key = $obj[$keyName];
$result[$key] = $obj; $result[$key] = $obj;
} }
@@ -109,66 +115,65 @@ class Util extends \utilphp\util{
return $result; return $result;
} }
public static function convertDictToArray($dict, $keys){ public static function convertDictToArray($dict, $keys)
{
$result = []; $result = [];
foreach($keys as $key){ foreach ($keys as $key) {
$result[] = Util::array_get($dict[$key], null); $result[] = Util::array_get($dict[$key], null);
} }
return $result; return $result;
} }
public static function isDict(&$array){ public static function isDict(&$array)
if(!is_array($array)){ {
if (!is_array($array)) {
//배열이 아니면 dictionary 조차 아님. //배열이 아니면 dictionary 조차 아님.
return false; return false;
} }
$idx = 0; $idx = 0;
$jmp = 0; $jmp = 0;
foreach ($array as $key=>&$value) { foreach ($array as $key=>&$value) {
if(is_string($key)){ if (is_string($key)) {
return true; return true;
} }
$jmp = $key - $idx - 1; $jmp = $key - $idx - 1;
$idx = $key; $idx = $key;
} }
if ($jmp * 5 >= count($array)){ if ($jmp * 5 >= count($array)) {
//빈칸이 많으면 dictionary인걸로. //빈칸이 많으면 dictionary인걸로.
return true; return true;
} } else {
else{
return false; return false;
} }
} }
public static function eraseNullValue($dict, $depth=512){ public static function eraseNullValue($dict, $depth=512)
{
//TODO:Test 추가 //TODO:Test 추가
if($dict === null){ if ($dict === null) {
return null; return null;
} }
if(is_array($dict) && empty($dict)){ if (is_array($dict) && empty($dict)) {
return null; return null;
} }
if($depth <= 0){ if ($depth <= 0) {
return $dict; return $dict;
} }
foreach ($dict as $key=>$value) { foreach ($dict as $key=>$value) {
if($value === null){ if ($value === null) {
unset($dict[$key]); unset($dict[$key]);
} } elseif (Util::isDict($value)) {
else if(Util::isDict($value)){
$newValue = Util::eraseNullValue($value, $depth - 1); $newValue = Util::eraseNullValue($value, $depth - 1);
if($newValue === null){ if ($newValue === null) {
unset($dict[$key]); unset($dict[$key]);
} } else {
else{
$dict[$key] = $newValue; $dict[$key] = $newValue;
} }
} }
} }
@@ -176,11 +181,12 @@ class Util extends \utilphp\util{
} }
/** /**
* 0.0~1.0 사이의 랜덤 float * 0.0~1.0 사이의 랜덤 float
* @return float * @return float
*/ */
public static function randF(){ public static function randF()
{
return mt_rand() / mt_getrandmax(); return mt_rand() / mt_getrandmax();
} }
@@ -188,7 +194,8 @@ class Util extends \utilphp\util{
* $prob의 확률로 true를 반환 * $prob의 확률로 true를 반환
* @return boolean * @return boolean
*/ */
public static function randBool($prob = 0.5){ public static function randBool($prob = 0.5)
{
return self::randF() < $prob; return self::randF() < $prob;
} }
@@ -196,11 +203,12 @@ class Util extends \utilphp\util{
/** /**
* $min과 $max 사이의 값으로 교정 * $min과 $max 사이의 값으로 교정
*/ */
public static function valueFit($value, $min, $max){ public static function valueFit($value, $min, $max)
if($value < $min){ {
if ($value < $min) {
return $min; return $min;
} }
if($value > $max){ if ($value > $max) {
return $max; return $max;
} }
return $value; return $value;
@@ -208,20 +216,21 @@ class Util extends \utilphp\util{
/** /**
* 각 값의 비중에 따라 랜덤한 값을 선택 * 각 값의 비중에 따라 랜덤한 값을 선택
* *
* @param array $items 각 수치의 비중 * @param array $items 각 수치의 비중
* *
* @return int|string 선택된 랜덤 값의 key값. 단순 배열인 경우에는 index * @return int|string 선택된 랜덤 값의 key값. 단순 배열인 경우에는 index
*/ */
public static function choiceRandomUsingWeight(array $items){ public static function choiceRandomUsingWeight(array $items)
{
$sum = 0; $sum = 0;
foreach($items as $value){ foreach ($items as $value) {
$sum += $value; $sum += $value;
} }
$rd = self::randF()*$sum; $rd = self::randF()*$sum;
foreach($items as $key=>$value){ foreach ($items as $key=>$value) {
if($rd <= $value){ if ($rd <= $value) {
return $key; return $key;
} }
$rd -= $value; $rd -= $value;
@@ -234,13 +243,13 @@ class Util extends \utilphp\util{
/** /**
* 배열의 아무거나 고름. Python의 random.choice() * 배열의 아무거나 고름. Python의 random.choice()
* *
* @param array $items 선택하고자 하는 배열 * @param array $items 선택하고자 하는 배열
* *
* @return object 선택된 value값. * @return object 선택된 value값.
*/ */
public static function choiceRandom(array $items){ public static function choiceRandom(array $items)
{
return $items[array_rand($items)]; return $items[array_rand($items)];
} }
};
};
+8 -4
View File
@@ -1,13 +1,17 @@
<?php <?php
namespace sammo; namespace sammo;
class Validator extends \Valitron\Validator{ class Validator extends \Valitron\Validator
{
protected static $_lang = 'ko'; protected static $_lang = 'ko';
public function errorStr(){ public function errorStr()
{
$errors = array_values((array)$this->errors()); $errors = array_values((array)$this->errors());
$errors = array_map(function($value){return join(', ', $value);}, $errors); $errors = array_map(function ($value) {
return join(', ', $value);
}, $errors);
$errors = join(', ', $errors); $errors = join(', ', $errors);
return $errors; return $errors;
} }
} }
+18 -15
View File
@@ -1,35 +1,38 @@
<?php <?php
namespace sammo; namespace sammo;
class WebUtil{ class WebUtil
{
private function __construct(){ private function __construct()
{
} }
public static function escapeIPv4($ip){ public static function escapeIPv4($ip)
{
return str_replace('.', '\\.', $ip); return str_replace('.', '\\.', $ip);
} }
public static function setHeaderNoCache(){ public static function setHeaderNoCache()
if(!headers_sent()) { {
if (!headers_sent()) {
header('Expires: Wed, 01 Jan 2014 00:00:00 GMT'); header('Expires: Wed, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate'); header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE); header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache'); header('Pragma: no-cache');
} }
} }
public static function parseJsonPost(){ public static function parseJsonPost()
{
// http://thisinterestsme.com/receiving-json-post-data-via-php/ // http://thisinterestsme.com/receiving-json-post-data-via-php/
// http://thisinterestsme.com/php-json-error-handling/ // http://thisinterestsme.com/php-json-error-handling/
if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){ if (strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0) {
throw new \Exception('Request method must be POST!'); throw new \Exception('Request method must be POST!');
} }
//Make sure that the content type of the POST request has been set to application/json //Make sure that the content type of the POST request has been set to application/json
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : ''; $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
if(strcasecmp($contentType, 'application/json') != 0){ if (strcasecmp($contentType, 'application/json') != 0) {
throw new \Exception('Content type must be: application/json'); throw new \Exception('Content type must be: application/json');
} }
@@ -43,16 +46,16 @@ class WebUtil{
$jsonError = json_last_error(); $jsonError = json_last_error();
//In some cases, this will happen. //In some cases, this will happen.
if(is_null($decoded) && $jsonError == JSON_ERROR_NONE){ if (is_null($decoded) && $jsonError == JSON_ERROR_NONE) {
throw new \Exception('Could not decode JSON!'); throw new \Exception('Could not decode JSON!');
} }
//If an error exists. //If an error exists.
if($jsonError != JSON_ERROR_NONE){ if ($jsonError != JSON_ERROR_NONE) {
$error = 'Could not decode JSON! '; $error = 'Could not decode JSON! ';
//Use a switch statement to figure out the exact error. //Use a switch statement to figure out the exact error.
switch($jsonError){ switch ($jsonError) {
case JSON_ERROR_DEPTH: case JSON_ERROR_DEPTH:
$error .= 'Maximum depth exceeded!'; $error .= 'Maximum depth exceeded!';
break; break;
@@ -77,4 +80,4 @@ class WebUtil{
return $decoded; return $decoded;
} }
} }
+1 -1
View File
@@ -3,7 +3,7 @@ Header set Cache-Control "max-age=60, must-revalidate"
</IfModule> </IfModule>
Deny from all Deny from all
<?php if(isset($allow_ip) && $allow_ip != ''): ?> <?php if (isset($allow_ip) && $allow_ip != ''): ?>
SetEnvIf X-Forwarded-For ^<?=str_replace('.', '\\.', $allow_ip)?> env_allow_1 SetEnvIf X-Forwarded-For ^<?=str_replace('.', '\\.', $allow_ip)?> env_allow_1
Allow from env=env_allow_1 Allow from env=env_allow_1
Allow from <?=$allow_ip?> Allow from <?=$allow_ip?>