개발로그... 굳이굳이 KG 프레임워크 이런걸 만들게 된 것은... 정보
개발로그... 굳이굳이 KG 프레임워크 이런걸 만들게 된 것은...
본문
처음 시작은 플러그인 만들어서 배포하다보니 파일들은 plugin 폴더에 넣고 이를 실행시키기위해 extend 폴더에 파일을 하나 더 넣어줘야하는게 귀찮아서 였습니다.
이게 진짜 그 시작의 이유입니다.
플러인을 자동으로 로드해주는 것이 유일한 목적으로 시작된 것입니다.
거기에 몇 가지를 더하기 시작했습니다.
https://kg-framework.github.io/kg/inspector.html
$is_admin === 'super', $bo_table, $member['mb_id'], !!$wr_id 이런 전역변수를 이용한 현재 요청에 대해 권한이나 요청된 것을 파악하기 위해 들이는 노력이 너무 커져서 이를 규격화된 인터페이스를 제공하기 위해 만들었습니다.
- kg()->inspect()->admin(): bool
- kg()->inspect()->articleId(): ?int
- kg()->inspect()->memberId(): ?int
- kg()->inspect()->index(): bool
- kg()->inspect()->board(): bool
- kg()->inspect()->mobile(): bool
이런식으로 대체로 boolean 타입으로 요청된 페이지나 접속자를 간단하게 확인하는 용도이죠. 앞에 'kg()->inspect()' 이런게 붙어서 길어져 좀 거추장 스럽긴한데 충돌하는 것보다는 낫겠죠.
애초의 목적이었던 플러그인을 자동로드해주는 나름 이 프레임워크에서 가장 먼저 만들어진 거의 핵심 기능이나 다름 없습니다.
Inspector 는 전역 변수에 의존하도록 했습니다. 아무래도 그누보드의 기존 환경에 맞춰야 했고, Inspector 목적 자체가 전역변수를 다루는데 규격화된 인터페이스 제공이 목적이었으므로 회원이나 글의 정보를 가져오는 것 모두 전역변수에 의존하고 있어서 기존의 코드에서 Inspector 로 쉽게 대체될 수 있도록 했습니다.
요 며칠 코드를 보다보니 버그를 발견했지만요 ^^;
✅ Hook
https://kg-framework.github.io/kg/hook.html
그 다음으로 만들어진게 Hook 기능입니다. 이건 따로 hook 기능을 별도로 구현한게 아니고 그누보드의 Hook 기능을 그대로 이용합니다.
그누보드는 PHP 5.2를 지원해야하기 때문에 Closure를 사용할 수 없죠.
Hook에 Closure를 리스너로 등록할 수 있도록 개선 #244 PR을 통해 PHP 5.3 이상에서는 Closure를 사용할 수 있도록 개선했지만, 그누보드 5.5.8.3.2 버전부터 가능해진 것이라서 클로져 사용을 원활하게 하기위해서 만들어진 기능입니다. 저 PR은 이 Hook 인터페이스를 만들면서 만들어진 부산물 입니다.
kg()->hook()->onEvent(), kg()->hook()->onReplace() 를 이용해 사용할 수 있고, onReplaceOnce() 이처럼 1회만 동작하는 것도 추가해두긴 했는데 사용률은 떨어질 것 같아서 제거할까 생각중입니다.
암튼 그누보드 Hook에 클로져를 활용할 수 없어서 만들어 추가한 기능입니다.
부산물로 add_replace()에서 $args 값을 1로 변경 #250 이것도 있네요. Replace Hook은 값을 반환해야해서 항상 최소 1개의 파라미터를 받아야하는데 기본 값이 0이라서 항상 1을 붙이는게 너무나도 귀찮아서 1로 바꿨습니다. 이것도 그누보드 5.5.8.3.2 버전에 적용되었습니다.
✅ Domain
https://kg-framework.github.io/kg/domain/about.html
아마도 이게 그 다음 순서였을 겁니다. Inspector 와 함께 사용되기도 합니다. 전역변수에 있는 회원, 글, 게시판 등의 정보에 접근하기위한 Inspector 의 확장된 부분이라고 보면 될 것 같네요.
글, 회원 등의 정보를 확인할 때 일관성을 제공하고 단순화하기 위해서 만들어졌죠.
$article = kg()->inspect()->getArticle();
이렇게 가져와서 $article->title(), $article->summary(), $article->thumbnail(size: 'm', options: ['ratio': '16/10']) 이런 인터페이스를 활용할 수 있습니다. 아직 제가 만들었으면서도 활용을 제대로 못해서 완성도가 좀 떨어집니다.
그래서 이런 정보를 활용하는 위젯 기능에 박차를 가하고 있고 이 기능을 활용해 게시판 스킨을 실제로 만들어보면서 게시판, 글, 댓글, 회원, 설정 이런 인터페이스 전반을 다듬어가게 될 것 같습니다.(누가 이쁜 디자인 좀...)
✅ 디버깅
https://kg-framework.github.io/kg/debug.html
이건 사실 위 어디 중간에 껴있는 것이기도하고 제가 이 프레임워크를 개발하기 전에 첫번째 플러그인을 만들어 배포했었던 DebugBar 플러그인의 확장... 이라기엔 뭐하지만 암튼 DebugBar 를 사용하기 조금 더 수월하게 하는 목적으로 만들어졌습니다.
사실 만들어졌다기보다는 DebugBar 플러그인이 설치나 활성화되지 않았을 때 디버그 함수를 사용할 수 없는 문제 때문에 일부 기능을 DebugBar에서 프레임워크로 올려 가져온 것입니다. DebugBar는 자체 기능 외에도 symfony/var-dumper 패키지가 제공하는 dd(), dump() 함수를 사용할 수 있는데, debugbar 플러그인이 비활성화되면 dd(), dump() 함수를 사용한 코드에서 당연히 오류가 발생하기 때문에 프레임워크로 가져왔습니다. 사실 저 함수 2개 가져온게 다 입니다.
그래도 이 변경으로 인해 어디서든 자유롭게 디버깅용 함수를 사용할 수 있게 됐습니다. 물론, 프레임워크가 로드된 후에만 가능하겠지만 더이상 앞으로 끌어올리기는 불가능 하니까요.
✅ sql()
https://kg-framework.github.io/kg/database/sql.html
Prepared Statement 를 지원하는 DB 인터페이스입니다.
PDO나 쿼리빌더 등의 욕심은 났지만... 진짜 굴뚝 같았지만 최소한의 기능만을 제공하면서 그누보드의 DB 커넥션을 그대로 활용하는 좀 더 안전한 방법을 제공하는 기능으로 만들어졌습니다.
PDO 처럼 따로 커넥션을 가지지 않으면서 Prepared Statement 를 좀 더 간편하게 사용할 수 있도록 만들었습니다. PHP 기본 인터페이스는 $stmt->bind('sssiiisss', ...) 이런식으로 타입을 s, i, d, b 이렇게 직접 지정해줘야했기에 사용하기 불편한 부분을 좀 도와주는 역할이죠. 이게 가장 핵심이라고 말할 수 있는 간단한 기능에 불과합니다.
쿼리빌더가 너무 욕심났지만 꾹 참고 있습니다. PDO 인터페이스도 만들어두긴 했는데, 그누보드가 PDO를 지원하지 않는한 이 프레임워크에서도 PDO로 대체하지는 않을 생각입니다. DB 커넥션이 두개가 될테니까요.
✅ 라우터
https://kg-framework.github.io/kg/router.html
그 다음이 이 라우터 인것 같네요.
애초에 그누보드 자체에 라우터를 붙이려는 목적은 전혀 없었습니다. 현재 그누보드가 라우터를 제공하기에 너무 어려운 환경이기 때문에 사실상 불가능 합니다. 많은 역경을 헤쳐나가야만 붙이기 적절할텐데 현재로서는 어렵다고 봐야죠.
그래서 이 라우터는 프레임워크의 설치 폴더인 'kg' 폴더 아래에서만 동작합니다. 그렇다고 완전히 분리된 것은 아니고 그누보드의 라이프 사이클 앞부분의 초기화 과정까지는 그대로 적용됩니다. 완전히 분리되면 사실상 다른 프로그램이 되어가는 것이라서 일부러 분리할 필요도 없고요.
아직 실험적인 기능이라서 문서도 제공하지 않고 있습니다. 슬림프레임워크를 가져다 쓰고 있는데 DI 도 가능하고 미들웨어 사용 등 너무 좋은데 덩치가 너무 크지 않을까 라는 생각도 있습니다. 근데 보면 필요한 규격이긴해서 슬림 프레임워크를 계속 사용할지 제거하고 단순한 라이브러리로 대체할지 고민중입니다.
DebugBar 플러그인 등의 일부에서 라우터를 사용하고는 있습니다만, 좀 더 봐야할 것같네요. 테마 등 레이아웃을 입힐 때 문제도 있고해서 아직은 사용이 어려운 상태인 기능입니다.
https://kg-framework.github.io/kg/uuid-and-ulid.html
UUID는 뭐 따로 설명할 것도 없고, ULID는 DB에 넣을 Primary Key로 사용하기위해 채용했습니다. 시간에 따른 순서를 보장하기 때문에 PKey로 사용하기 적당해서 단순히 순차적으로 증가하는 auto_increment를 대체하기 좋네요.
이건 에디터 첨부 이미지 관리 플러그인에 사용되고 있습니다. 이 플러그인 자체는 그냥 자동 증가값을 사용해도 전혀 문제가 없지만 생각하고 있는 기능이 있어서 순차적인 자동증가 값 대신 ULID를 사용하도록 했습니다.
✅ 관리 메뉴
https://kg-framework.github.io/kg/admin-menu.html
전통적으로(?) 관리페이지에 관리자 메뉴를 추가하기위해서 admin.100.php 이런 파일을 수정하거나 그누보드에 포함되지 않은 여분으로 사용할 수 있는 admin.800.php 이런 파일을 생성해서 메뉴를 추가하던게 보편적인데 최근에 플러그인 만드시는 분들은 Hook을 사용해서 메뉴를 아주 쉽게 추가하고 계시죠.
이 Hook을 이용하는 방식에 인터페이스를 지원하는 기능합니다. URL 로 메뉴를 추가하거나 그누보드가 관리페이지 추가를 쉽게 도와주는 /adm/view.php 파일을 활용하는데 도움을 주는 유틸리티입니다. 이런 Hook을 사용하려면 관련된 Hook을 3개를 사용해야 하는데 kg()->adminMenu()->addView() 함수 하나로 해결할 수 있게 해줍니다. (문서는 쓰다만 흔적이 있네요;;)
물론 그누보드의 기존 메뉴에 끼워넣기도 되고요. 새로운 메뉴 그룹을 생성할 수도 있습니다(이것도 문서에 안 적어놨네요 ㅎㅎ).
✅ 위젯
https://kg-framework.github.io/kg/widget/about-widget.html
사실 앞의 것들은 제가 플러그인을 개발하면서 불편했던 부분의 단순화 시키고 규격화를 위한 인터페이스 제공을 위해 만들어진 것들이고, 이 프레임워크를 만드려는 목적에는 전혀 없었던 기능이 위젯입니다.
여러 플러그인을 만들다보니 반복되는 UI나 설정 UI의 간소화를 위해서 컴포넌트화하는 것에서부터 시작됐습니다. 지금은 kg()->widget() 이지만, 시작은 kg()->ui() 였습니다. HTML과 css, js 코드 덩어리를 출력해주는 간단한 기능이었는데 어쩌다 위젯이 된건지도 저도 잘... 암튼.
현재는 그누보드가 제공하는 latest, outlogin 등과 같은 위젯으로서 개발하고 있습니다. 테스트 삼아 latest, outlogin에 해당하는 위젯과 그누보드에서 활용 가능한 데이터 중에 댓글, faq 를 뿌려주는 위젯도 만들어 봤고요. 뭐 딱히 더 할만한건 나중에 생각하면 될 것같습니다.
보다 핵심은 위젯 설정 기능을 제공하는데 집중하고 있습니다. 지금도 대략적으로 구성은 되어있는데 띄엄띄엄 만들다보니 엉망진창인 상태라서 지난 일주일간 조금씩 고쳐와서 좀 정리된 것같습니다. 좀 더 다듬어야겠지만요.
아무튼 기본적인 기능은 이제 좀 정리가 되어가는 것같습니다. 이제는 위젯 설정 UI를 제공하기위한 준비를 하고 있습니다. 이를 위해서 xe/라이믹스도 좀 살펴보고, 나리야, 이윰 빌더도 UI를 살펴봤습니다. 맘 같아서는 vue를 활용하고 싶지만 그누보드에 좀 더 잘 어울릴거라 생각하는 AlpineJS를 사용하기로 했습니다.
알파인을 꼭 활용하지 않더라도 설정 UI를 만드는데 문제가 없게 할 생각이고 그냥 바닐라나 jQuery를 이용하든 상관이 없도록 알아서 만들수 있도록할 생각입니다. 그래서 알파인을 채택했고, 구성은 자유지만 알파인에 맞추면 제공하는 기능을 활용하여 좀 더 간편할 수도 있는(?) 활용이 가능하도록 도와주는 수준으로 알파인을 적용할 계획입니다.
위젯 기능은 좀 더 시간이 지나야 공개할 수 있을 것 같네요. 문서는 일부 작성되어 있는데 많이 바뀌고 있고, 개발하면서 문서도 함께 수정해나가고 있습니다. 물론 아직 제 로컬에서만 수정된 상태이고요.
✅ 마치며...
단순히 extend 폴더에 파일 하나 복사하라고 안내하는게 귀찮아서 시작된 프로젝트입니다.
시간 날 때 띄엄띄엄 만드는 거라서 개발 속도도 느리고 설계도 없이 필요한 것을 바로 구현해왔기 때문에 뒤죽박죽입니다. 좀 정리가 많이 필요하고 무엇보다도 테스트 코드가 전혀 없습니다!! ㅎㅎ
테스트 기반을 안 만들어놔서 F5와 dd(), dump(), ddd() 이런 함수를 이용한 단순한 디버깅 환경에만 의존한 개발이기 때문에 불안 요소가 많지만 사실 이렇게 키워올 생각이 없었는데 이리 된 것이기 때문에... 흠
앞으로 위젯이 가장 큰 작업이 될 것같고 이를 위해 설정 UI와 이 설정 값을 저장하고 다루는 인터페이스를 개발하는 것에서 이 프레임워크의 기능은 갖춰질 것같네요. 더이상 뭔가를 더 추가할건 아직 생각하고 있지않습니다.
이제는 기능들을 마무리하고 완성도를 높여가는 것이 목표입니다. 도중에 좀 갈아엎는 코드도 있을 것같지만 범위는 크지 않을 것같고요. 완성도를 높이기 위해서는 역시 개밥먹기겠죠. 지금까지 공개한 플러그인들도 있지만 이 플러그인들도 완성도를 높이고, 위젯도 만들고, 테마와 게시판 스킨 등을 만들어내면서 진행할 생각입니다. 디자인이 구려서 테마나 스킨은 아마 공개하지 못할 수도 있는데, 가능한 공개해서 피드백을 받는게 좋긴한데... 아.. 디자인 젬병이라서...
적다보니 글이 엄청 길어졌네요. 아무튼 1.0.0으로 정식버전으로 이 프레임워크를 공개하는 날이 오면 좋겠네요.
아래는 이 프레임워크와 플러그인들을 개발하면서 발견한 이슈와 개선 사항입니다.
- debugbar 쿼리 오류 표시 추가 및 G5_COLLECT_QUERY 설정 추가 #212
- 디버그바 플러그인에서 DB 쿼리 목록을 수집하기 위한 변경
- 회원 sideview 메뉴에 Replace Hook 추가 #218
- 아직 공개하지 못한 플러그인에서 메뉴를 추가하기 위한 변경
- goto_url 함수에 Event Hook 추가 #219
- html_process->run()에 Replace Hook 추가 #220
- 디버그바 플러그인에서 데이터 수집을 최대한 뒤로 미루기위해 추가한 Hook
- rewrite 룰 제안에 Hook 추가 #223
- 이건 라우터를 위해 추가했는데 아직 라우터 상태가 안 좋아서 활용을 못하고 있는...
- 관리페이지 폰트 개선 #233
- 관리페이지 들락거리면서 맥에서 폰트가 너무 구리게 나와서 폰트 수정했는데... 안 받아주셔서 닫아버린 이슈. 그냥 프레임워크에서 css를 일부 덮어버리는 걸로 적용함
- HTMLPurifier 설정을 변경할 수 있는 html_purifier_config 이벤트 Hook 추가 #238
- CK 에디터를 만들어서 붙이다가 제거되는 일부 태그 때문에 HTMLPurifier 설정을 변경할 수 있는 Hook 추가. 정작 본인은 CK에디터 배포를 못하고 있으나, 이 Hook을 사용한 플러그인을 공개해주셨네요. https://sir.kr/g5_plugin/11459
- 관리자 페이지 및 일부 데이터 업데이트 시 Event hook 추가 #243
- 에디터 이미지 관리 플러그인을 위해서 각종 관리자 설정이나 일부 기능에서 데이터 업데이트 시 Hook 추가
- Hook에 Closure를 리스너로 등록할 수 있도록 개선 #244
- 이건 앞에 Hook 기능에서도 이야기했던 Closure 사용 문제를 개선한 PR
- CHEditor에서 이미지 업로드시 get_editor_upload_url Hook에 파일의 정보 추가 #246
- 에디터 이미지 관리 플러그인을 만들다가 스마트에디터와는 다르게 hook에 전달하는 정보가 누락된 것을 발견해 고친? 개선한? PR
- add_replace()에서 $args 값을 1로 변경 #250
- 이것도 앞에서 말했든 숫자 1 타이핑 하는게 귀찮아서...
- get_microtime 함수 개선 #252
- 이건 그냥 꼴보기 싫어서. (?)
- adm/view.php 파일에서 $sub_menu 등 변수 위치를 변경 #259
- 역시 위에 관리 메뉴 인터페이스를 만들면서 변수 2개의 위치가 아쉬워서 개선한 코드
- QA에서 질문글 삭제 시 답변글의 첨부파일 및 썸네일을 삭제하지 못하는 문제 수정 #266
- 에디터 이미지 관리 플러그인을 만들다가 QA 기능에서 답변에 첨부된 파일을 삭제하지 못하는 버그를 발견해 수정한 것
- 1:1문의 답변 시 qawrite_update Hook에서 답변 글의 ID를 전달하도록 개선 #268
- 이것 역시 에디터 이미지 관리 플러그인을 만들다가 발견한 DB를 다시 뒤적거려야하는 불편이 있어서 개선한 PR
- 영카트 상품 복사 후 shop_admin_itemcopy Event Hook 추가 #270
- 이것도 역시 에디터 이미지....
여기까지는 PR이고.. 아래는 이슈로 작성한 보고나 제안
- 새로운 인증 수단을 위한 패스워드 확인 없는 로그인 처리 지원 #205
- 원하는 방향과 조금 달랐지만, 어쨌든 패스키 지원 기능을 붙일 수 있게 된 변경 사항
- html_process가 초기화 되기전에 js/css 파일을 로드 할수 없습니다 #20
- 플러그인을 만들다가 css/js 파일 로드가 안돼서 발견한 버그
- html_process 에서 css 파일을 로드하지 못하는 문제가 있어요 #207
- 테마를 만들다가 발견한 버그
- https://sir.kr/g5_tip/20791 이런 사례의 문제
- Object cache의 데이터를 삭제하지 못하는 버그 #225
- 플러그인에서 캐시를 활용해보려다가 발견한 버그. 버그는 고쳐졌지만 정작 오브젝트 캐시는 활용하지 않기로 했다...
- 설치시 자동생성되는 게시판 글읽기 포인트로 인한 문제 #231
- 플러그인과 그누보드 PR 보낼때 테스트를 위한 사이트에서 비회원으로 테스트하는데 기본 포인트 설정 때문에 글을 못보는 불편으로 제보
- 게시판 RSS 포맷이 RSS 2.0 스펙에 맞지 않습니다 #234
- 아직 공개하지 못한 SEO 플러그인을 만들면서 RSS로 구글 등록 시 발견한 버그
- CHEditor에서 이미지 업로드시 서버 내 경로가 노출되는 문제 #248
- 이것도 에디터 이미지 플러그인을 만들면서 발견한 문제. 사실상 보안취약점
- 6월 25일 제보한 영카트 보안취약점 #249
- 이것도 에디터 이미지 플러그인을 만들다가 발견한 보안취약점
- 세션 고정 취약점 #257
- 이건 패스키 플러그인(구 자료는 자료실에서 내림. 신규 버전은 아직 다듬는 중)을 개발하면서 발견한 세션고정 취약점
- 관리페이지 메뉴 접근 권한이 부여된 경우 관리페이지의 index 페이지의 정보가 노출되는 문제 #258
- 플러그인과 https://kg-framework.github.io/kg/admin-menu.html 이 관리메뉴 기능을 만들다가 메뉴 권한이 주어졌을때 권한 밖의 데이터가 일부 노출되는 보안취약점
- wr_num 필드 값이 동시성 문제로 겹치는 경우 답변글에 대한 권한이 잘못 주어지는 등의 문제 #265
- 프레임워크와 더미 데이터 생성 플러그인을 만들다가 발견한 문제
- 고쳐졌으나 권한이 잘못 부여될 수 있는 버그난 아직 해결되지 않아 이슈를 못 닫고 있음
- 더미 데이터 게시물 제3자 제공에 대한 동의 누락항목에 대한 조치 안내
- 코드 상 이슈는 아니고 sir.kr 사이트의 개인정보 유출 문제
- 더미 데이터 생성 플러그인을 만들다가 발견한 문제
- 사실 만들어진 기능에서 활용한 데이터는 완전히 다른데, sir이 공개한 플러그인이 사용하는 글 가져오기 API를 사용해보려다가 발견한 개인정보 유출 문제
- 동의한 것과 다르게 회원아아디, 이메일주소, 홈페이지 주소, IP가 제공되고 있었다
- 본인인증 처리 후 저장되는 개인정보 최소화 #272
- 역시 프레임워크를 만들다가 데이터를 다루는 중에 이상한 부분에서 발견한 문제
- 과도한 개인정보가 저장되어 개선이 필요할 것같은데 아직 처리되지 않은 이슈
- 이 문제는 sir.kr의 개인정보처리방침에서도 누락되어 개정되게 만든 이슈다 https://sir.kr/co_notice/1398
- 비밀글이 게시판 목록에서 내용, 썸네일이 노출되는 문제 #287
- 프레임워크 개선과 우젯을 개발하다가 발견한 문제
- 비밀글이 내용 일부와 첨부한 이미지의 썸네일 등이 노출될 수 있는 문제
- latest에서는 가려져 나오는데 게시판 기본 스킨 중 gallery 스킨에서 노출 되는 문제
여기까지가 프레임워크와 플러그인을 개발하면서 발견한 문제나 개선사항들입니다. 이 외에도 조금 더 있는데 나머지는 그냥 둘러보다가 발견한 문제라서 프레임워크 개발하면서 나온 부산물 겪인 이슈들만 나열했습니다.
이정도 부산물이면 지금 당장 때려쳐도 성공적인 프로젝트 아니겠습니까........
후, 언제 완성해서 배포할 수 있으려나요.
5
관련링크
댓글 7개

위젯은 간단한 코드 스니펫 같은 기능이었는데 어쩌다 이리 키워버렸는지 모르겠네요;;
애초에 계획한 기능은 겸사겸사 위젯으로 퉁쳐서 사용하여 했는데 스펙이 너무 커져서 다시 따로 만들어야겠네요.
이왕 만든 거 잘 다듬어서 성공적으로 배포를 완료하면 좋겠네요.

회원 사이드뷰를 첨가하는 hook 이나
익명함수 내지는 네임스페이스를 hook 에서 쓸 수 있는 건 지한님의 적극성 때문에 저도 날로먹은 꼴이라 김사히 생각하고 있습니다.




https://sir.kr/manual/g5/288
저걸로 충분하지 않으면 이것도 참고해보세요.
https://g5guide.github.io/developers/hook.html
