CommonTrait.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. <?php
  2. namespace App\Http\Traits;
  3. use Illuminate\Support\Facades\Auth;
  4. use Illuminate\Support\Facades\Hash;
  5. use Illuminate\Support\Str;
  6. use Illuminate\Http\Request;
  7. use DOMDocument;
  8. trait CommonTrait
  9. {
  10. /*
  11. * 비밀번호 확인 여부
  12. */
  13. public function isCertified(Request $request)
  14. {
  15. if (!$request->session()->exists('is-certified')) {
  16. return redirect()->route('account.certify')->with([
  17. 'url' => urlencode($request->fullUrl())
  18. ])->send();
  19. }
  20. }
  21. /*
  22. * 비밀번호가 일치하는지 여부
  23. */
  24. public function passwordAuthed(string|null $plainPassword): bool
  25. {
  26. if($plainPassword) {
  27. $hashPassword = Auth::user()->getAuthPassword();
  28. if(Hash::check($plainPassword, $hashPassword)) {
  29. return true;
  30. }
  31. }
  32. return false;
  33. }
  34. /*
  35. * 비밀번호 생성
  36. */
  37. public function passwordMake(string $plainPassword): string
  38. {
  39. return Hash::make($plainPassword);
  40. }
  41. /*
  42. * SNS 시간 표시
  43. */
  44. public function dateFormat($datetime, $format = null): string
  45. {
  46. $diff = time() - strtotime($datetime);
  47. $s = 60; // 1분 = 60초
  48. $h = $s * 60; // 1시간 = 60분
  49. $d = $h * 24; // 1일 = 24시간
  50. $y = $d * 10; // 1년 = 1일 * 10일
  51. if ($diff < $s) {
  52. $ret = $diff . '초전';
  53. } elseif ($h > $diff && $diff >= $s) {
  54. $ret = round($diff / $s) . '분전';
  55. } elseif ($d > $diff && $diff >= $h) {
  56. $ret = round($diff / $h) . '시간전';
  57. } elseif ($y > $diff && $diff >= $d) {
  58. $ret = round($diff / $d) . '일전';
  59. } else {
  60. if($format) {
  61. $ret = now()->setTimeFromTimeString($datetime)->format($format);
  62. }else{
  63. $ret = date('Y.m.d H:i:s', strtotime($datetime));
  64. }
  65. }
  66. return $ret;
  67. }
  68. /*
  69. * Editor 동영상 개수 조회
  70. */
  71. public function getVideoRows(string $html): int
  72. {
  73. $dom = new DOMDocument('1.0', 'UTF-8');
  74. libxml_use_internal_errors(true);
  75. $dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>' . $html);
  76. libxml_clear_errors();
  77. return ($dom->getElementsByTagName('iframe')->length + $dom->getElementsByTagName( "video" )->length);
  78. }
  79. /*
  80. * Editor 이미지 개수 조회
  81. */
  82. public function getImageRows(string $html): int
  83. {
  84. $dom = new DOMDocument('1.0', 'UTF-8');
  85. libxml_use_internal_errors(true);
  86. $dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>' . $html);
  87. libxml_clear_errors();
  88. return $dom->getElementsByTagName('img')->length;
  89. }
  90. /*
  91. * 글자 자르기
  92. */
  93. public function strCut(string $str, int $limit, string $end = '...'): string
  94. {
  95. return ($limit > 0 ? \Illuminate\Support\Str::limit($str, $limit, $end) : $str);
  96. }
  97. /*
  98. * IP 를 정한 형식에 따라 보여주기
  99. */
  100. public function ipAddrMasking(string $ip, string $type = '0001'): string
  101. {
  102. $len = strlen($type);
  103. if ($len !== 4) {
  104. return $ip;
  105. }
  106. if (empty($ip)) {
  107. return $ip;
  108. }
  109. $regex = ($type[0] === '1') ? '\\1' : '&#9825;';
  110. $regex .= '.';
  111. $regex .= ($type[1] === '1') ? '\\2' : '&#9825;';
  112. $regex .= '.';
  113. $regex .= ($type[2] === '1') ? '\\3' : '&#9825;';
  114. $regex .= '.';
  115. $regex .= ($type[3] === '1') ? '\\4' : '&#9825;';
  116. return preg_replace("/([0-9]+).([0-9]+).([0-9]+).([0-9]+)/", $regex, $ip);
  117. }
  118. /*
  119. * 자동 URL 링크 생성
  120. */
  121. public function urlAutoLink(string $str = "", bool $popup = false): string
  122. {
  123. $target = ($popup ? 'target="_blank"' : '');
  124. $str = str_replace(["<", ">", "&amp;", "&quot;", " ", "&#039;"], ["\t_lt_\t", "\t_gt_\t", "&", "\"", "\t_nbsp_\t", "'"], $str);
  125. $str = preg_replace("/([^(href=\"?'?)|(src=\"?'?)]|\(|^)((http|https|ftp|telnet|news|mms):\/\/[a-zA-Z0-9\.-]+\.[가-힣\xA1-\xFEa-zA-Z0-9\.:&#=_\?\/~\+%@;\-\|\,\(\)]+)/i", "\\1<a href=\"\\2\" {$target}>\\2</A>", $str);
  126. $str = preg_replace("/(^|[\"'\s(])(www\.[^\"'\s()]+)/i", "\\1<a href=\"http://\\2\" {$target}>\\2</A>", $str);
  127. $str = preg_replace("/[0-9a-z_-]+@[a-z0-9._-]{4,}/i", "<a href=\"mailto:\\0\">\\0</a>", $str);
  128. return str_replace(["\t_nbsp_\t", "\t_lt_\t", "\t_gt_\t", "'"], [" ", "<", ">", "&#039;"], $str);
  129. }
  130. /*
  131. * Image, iframe, video Thumbnail 저장
  132. */
  133. public function getThumbnail(string $html, ?string $defaultImgSrc = null): ?string
  134. {
  135. preg_match_all("/<img[^>]*src=[\"']?([^>\"']+)[\"']?[^>]*>/i", $html, $matches);
  136. if(array_key_exists(1, $matches)) {
  137. return current($matches[1]);
  138. }
  139. $iframeVideoSrc = $this->getYoutubeKey(getIframeTag($html, true)); // iframe src 추출
  140. if($iframeVideoSrc) {
  141. return sprintf("https://img.youtube.com/vi/%s/mqdefault.jpg", $iframeVideoSrc);
  142. }
  143. return (file_exists($defaultImgSrc) ? url($defaultImgSrc) : null);
  144. }
  145. /**
  146. * Youtube 썸네일 경로 조회
  147. */
  148. public function getYoutubeThumbURL(?string $str, int $type): string
  149. {
  150. $result = "";
  151. $youTubeId = $this->getYoutubeKey($str);
  152. if ($youTubeId) {
  153. switch ($type) {
  154. default :
  155. case 1 : // default
  156. $size = 'default';
  157. break;
  158. case 2 : // High Quality Thumbnail
  159. $size = 'hqdefault';
  160. break;
  161. case 3 : // Medium Quality
  162. $size = 'mqdefault';
  163. break;
  164. case 4 : // Standard Definition
  165. $size = 'sddefault';
  166. break;
  167. case 5 : // Maximum Resolution
  168. $size = 'maxresdefault';
  169. break;
  170. }
  171. $result = sprintf("//img.youtube.com/vi/%s/%s.jpg", $youTubeId, $size);
  172. }
  173. return $result;
  174. }
  175. /**
  176. * Youtube 퍼가기 URL 조회
  177. */
  178. public function getYoutubeEmbedUrl(?string $str): string
  179. {
  180. $result = "";
  181. $youTubeId = $this->getYoutubeKey($str);
  182. if ($youTubeId) {
  183. $result = sprintf("//www.youtube.com/embed/%s", $youTubeId);
  184. }
  185. return $result;
  186. }
  187. /*
  188. * Youtube Video ID 조회
  189. */
  190. public function getYoutubeKey(?string $src)
  191. {
  192. preg_match('#(?<=(?:v|i)=)[a-zA-Z0-9-]+(?=&)|(?<=(?:v|i)\/)[^&\n]+|(?<=embed\/)[^"&\n]+|(?<=‌​(?:v|i)=)[^&\n]+|(?<=youtu.be\/)[^&\n]+#', $src, $matches);
  193. return array_pop($matches);
  194. }
  195. /*
  196. * 이모티콘 삭제
  197. */
  198. public function removeEmoji(string $t): string
  199. {
  200. return iconv('ISO-8859-15', 'UTF-8', preg_replace('/\s+/', ' ', iconv('UTF-8', 'ISO-8859-15//IGNORE', $t)));
  201. }
  202. /*
  203. * 숫자만 조회
  204. */
  205. public function getOnlyNumber(string $str): array|null
  206. {
  207. return preg_replace('/[^0-9]/', '', $str);
  208. }
  209. /*
  210. * 금액을 한글로 변환
  211. */
  212. public function numberToHangul($number): string
  213. {
  214. $num = ['', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
  215. $unit4 = ['', '만', '억', '조', '경'];
  216. $unit1 = ['', '십', '백', '천'];
  217. $res = [];
  218. $number = str_replace(',', '', $number);
  219. $split4 = str_split(strrev(strval($number)), 4);
  220. for ($i = 0; $i < count($split4); $i++) {
  221. $temp = [];
  222. $split1 = str_split(strval($split4[$i]), 1);
  223. for ($j = 0; $j < count($split1); $j++) {
  224. $u = intval($split1[$j]);
  225. if ($u > 0) {
  226. $temp[] = $num[$u] . $unit1[$j];
  227. }
  228. }
  229. if (count($temp) > 0) {
  230. $res[] = implode('', array_reverse($temp)) . $unit4[$i];
  231. }
  232. }
  233. return implode('', array_reverse($res));
  234. }
  235. /*
  236. * Unique 반환
  237. */
  238. public function makeUniqueKey(int $length): int
  239. {
  240. return Str::random($length);
  241. }
  242. /**
  243. * 회원 프로필 이미지 조회
  244. */
  245. public function profileThumbSrc(?string $imgPath): string
  246. {
  247. return ($imgPath) ? asset($imgPath) : asset(NO_IMAGE_THUMB_SRC);
  248. }
  249. /*
  250. * 배열에 작은 따옴표를 추가한다. WHERE IN 사용시 편함
  251. */
  252. public function setArraySingQuote(array $arr)
  253. {
  254. return implode(', ', array_map(function ($val) {return sprintf("'%s'", $val);}, $arr));
  255. }
  256. /**
  257. * 에디터 내용안에서 이미지 주소를 찾아내 삭제한다.
  258. */
  259. public function deleteImageFromContent(?string $content): string
  260. {
  261. $dom = new DOMDocument('1.0', 'UTF-8');
  262. libxml_use_internal_errors(true);
  263. $dom->loadHTML('<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>' . $content);
  264. libxml_clear_errors();
  265. foreach ($dom->getElementsByTagName('img') as $img) {
  266. $filePath = public_path($img->attributes->getNamedItem("src")?->value);
  267. if (file_exists($filePath)) {
  268. unlink($filePath);
  269. }
  270. $img->parentNode->removeChild($img);
  271. }
  272. unset($content);
  273. return $dom->saveHTML();
  274. }
  275. /**
  276. * OpenSSL 암호화
  277. */
  278. public function sslEncrypt(string $s): string
  279. {
  280. return base64_encode(openssl_encrypt($s, "AES-128-CBC", openssl_digest(ENCRYPT_KEY, 'MD5', true), OPENSSL_ENCODING_DER, substr(md5(ENCRYPT_IV), 0, 16)));
  281. }
  282. /**
  283. * OpenSSL 복호화
  284. */
  285. public function sslDecrypt(string $s): string
  286. {
  287. return openssl_decrypt(base64_decode($s), "AES-128-CBC", openssl_digest(ENCRYPT_KEY, 'MD5', true), OPENSSL_ENCODING_DER, substr(md5(ENCRYPT_IV), 0, 16));
  288. }
  289. }