XE 패치가 나와서 버전업을 할 때마다 조마조마 하는 마음이 드는 것은 예나 지금이나 별반 다를 바가 없습니다.
근래에 들어서는 안정화가 상당히 이루어져서 자주 볼 수는 없지만, 1.4버전까지만 해도 버전업을 할 때마다 공포의 백지화면을 심심치 않게 볼 수 있었습니다.
패치를 적용한 뒤, 메인페이지에서 F5키를 눌렀을 때 아무 것도 뜨지 않은 새하얀 화면을 마주하게 되면 그야말로 머리 속도 같이 새하얘지곤 했었습니다..
1.5버전에 진입한 뒤로 백지화면을 본 적이 없기 때문에 이제 관리자 화면에서 [코어 업데이트] 버튼을 누르는 데 부담이 많이 사라졌지만, 그래도 혹여 써드파티 플러그인에서 오류가 나지는 않을까 하는 걱정은 여전히 존재합니다.
이번에 1.7.4.1 버전으로 업데이트 하면서 별다른 문제는 발견하지 못했는데, 그간 조용하던 SocialXE가 다시 한 번 문제를 일으켰습니다.
SocialXE (v1.10.11) 관련 위젯 등이 붙어있는 페이지에 접속하면 다음 스샷에서와 같이 별로 달갑지 않은 환영문구(?)가 저를 맞이했습니다.
이 문제를 처음 발견하고 원인을 파악하고자 여러 가지 시도를 해 보았습니다. 소셜 로그인/로그아웃, 댓글달고 지우기 등등.. 하지만, 오류 메시지가 항상 나타나는 것이 아니라 미지의 조건(?)에 의해 간헐적으로 나타나곤 했습니다. (생활에서 맞닥들이는 여러 가지 오류중에 가장 해결하기 골치아픈 오류입니다.)
간헐적으로 발생하는 특성 때문에 원인을 파악하는 데 다소 시간이 걸릴 것으로 생각하고, 미뤄미뤄 오다가 마침 한가해진 오늘 원인을 찾아내고 해결할 수 있었습니다.
문제의 원인
저는 XE 패치가 발행될때마다 패치로그를 꼬박꼬박 챙겨 보지는 않습니다.
이번에도 역시 XE를 업데이트 하면서 패치로그는 확인 하지 않았는데, 이번 문제를 해결하고 보니 이번 패치에서 Action Request 관련 Naming Rule Check 부분이 강화됬다는 것을 알 수 있었습니다.
XE 모듈을 작성할 때 가장 주의깊게 작성해야 하는 파일이 하나 있는데, 바로 conf 디렉토리에 있는 module.xml 파일입니다. 여기서는 Request Action들의 이름과 특성을 정의하는데, 여기서 실수로 오타를 내면 조만간 다소 골치아픈 상황과 마주하게 됩니다.
이번 문제는 오타에 의한 것은 아니었지만, Naming Rule Exception으로 인한 Request거부가 원인이었습니다.
이번 문제의 핵에는 socialxe의 module.xml파일이 위치하고 있습니다.
<?xml version="1.0" encoding="utf-8"?> <module> <grants /> <permissions> <permission action="dispSocialxeTextyleTool" target="manager" /> </permissions> <actions> <action name="dispSocialxeAdminConfig" type="view" standalone="true" menu_name="socialxe" /> <action name="dispSocialxeAdminBitly" type="view" admin_index="true" standalone="true" menu_name="socialxe" menu_index="true" /> <action name="procSocialxeAdminInsertConfig" type="controller" standalone="true" /> <action name="procSocialxeAdminInsertModuleConfig" type="controller" standalone="true" /> <action name="procSocialxeAdminDeleteChecked" type="controller" standalone="true" /> <action name="procCompileInput" type="controller" standalone="true" /> <action name="procCompileList" type="controller" standalone="true" /> <action name="procCompileSubList" type="controller" standalone="true" /> <action name="procSocialxeInsertComment" type="controller" standalone="true" /> <action name="procSocialxeDeleteComment" type="controller" standalone="true" /> <action name="procSocialxeChangeMaster" type="controller" standalone="true" /> <action name="procSocialxeSetAutoLoginKey" type="controller" standalone="true" /> <action name="procSocialxeLoginInsert" type="controller" standalone="true" /> <action name="procSocialxeUnlinkSocialInfo" type="controller" standalone="true" /> <action name="procSocialxeSetSend" type="controller" standalone="true" /> <action name="procSocialxeChangeMasterProvider" type="controller" standalone="true" /> <action name="procCompileInfo" type="controller" standalone="true" /> <action name="procResetSocialInfo" type="controller" standalone="true" /> <action name="dispSocialxeLogin" type="view" standalone="true" /> <action name="dispSocialxeCallback" type="view" standalone="true" /> <action name="dispSocialxeLogout" type="view" standalone="true" /> <action name="dispSocialxeTextyleTool" type="view" /> <action name="dispSocialxeLoginForm" type="view" standalone="true" /> <action name="dispSocialxeLoginAdditional" type="view" standalone="true" /> <action name="dispSocialxeSocialInfo" type="view" standalone="true" /> </actions> <menus> <menu name="socialxe" type="all"> <title xml:lang="ko">SocialXE</title> </menu> </menus> </module>
강조 표시된 줄들을 보면 공통점이 있습니다. 다른 Action Name들과 비교해보면, proc 뒤에 모두 Socialxe가 빠져 있음을 알 수 있습니다.
본래 XE에서 모듈 Action이름을 정할 때는 정해진 규칙에 따라야 하며, 그 형식은 다음과 같습니다.
[Type][ModuleName][ActionName]
Type은 Action의 종류를 나타내며, 대표적인 키워드는 다음과 같습니다.
- proc : Controller와 관련된 Action인 경우
- disp : View를 표시하는 Actin인 경우
- trigger : Trigger인 경우
ModuleName은 모듈명을 나타내며, 모듈명 중간에 대문자가 들어가 있어라도 반드시 첫 글자만 대문자로 써야 합니다.
ActionName은 첫 글자만 대문자면 제한없이 쓸 수 있습니다.
예를 들어, 모듈명이 MyModule이고 Type이 Controller이면 Action Name은 다음과 같은 형태가 됩니다.
: procMymoduleSomeActionName
1.7.4 이전 버전에서는 이와 관련된 검사를 정확히 하지 않았는데, 이번 패치에서 엄격한 검사를 적용하면서 문제가 발생한 것으로 보입니다.
해결 방법
문제 해결 방법은 의외로 간단합니다.
- SocialXE 관련 플러그인에서 위에서 언급한 잘못 표기된 5개의 Action Name을 올바르게 수정해주면 됩니다.
즉, 모든 소스코드에서
- procCompileInput -> procSocialxeCompileInput
- procCompileList -> procSocialxeCompileList
- procCompileSubList -> procSocialxeCompileSubList
- procCompileInfo -> procSocialxeCompileInfo
- procResetSocialInfo-> procSocialxeResetSocialInfo
이렇게 바꿔 주면 간단히[!] 해결될 문제입니다.
우선 module.xml 파일을 다음과 같이 수정합니다.
(proc 뒤에 Socialxe를 써 넣습니다.)
<?xml version="1.0" encoding="utf-8"?> <module> <grants /> <permissions> <permission action="dispSocialxeTextyleTool" target="manager" /> </permissions> <actions> <action name="dispSocialxeAdminConfig" type="view" standalone="true" menu_name="socialxe" /> <action name="dispSocialxeAdminBitly" type="view" admin_index="true" standalone="true" menu_name="socialxe" menu_index="true" /> <action name="procSocialxeAdminInsertConfig" type="controller" standalone="true" /> <action name="procSocialxeAdminInsertModuleConfig" type="controller" standalone="true" /> <action name="procSocialxeAdminDeleteChecked" type="controller" standalone="true" /> <action name="procSocialxeCompileInput" type="controller" standalone="true" /> <action name="procSocialxeCompileList" type="controller" standalone="true" /> <action name="procSocialxeCompileSubList" type="controller" standalone="true" /> <action name="procSocialxeInsertComment" type="controller" standalone="true" /> <action name="procSocialxeDeleteComment" type="controller" standalone="true" /> <action name="procSocialxeChangeMaster" type="controller" standalone="true" /> <action name="procSocialxeSetAutoLoginKey" type="controller" standalone="true" /> <action name="procSocialxeLoginInsert" type="controller" standalone="true" /> <action name="procSocialxeUnlinkSocialInfo" type="controller" standalone="true" /> <action name="procSocialxeSetSend" type="controller" standalone="true" /> <action name="procSocialxeChangeMasterProvider" type="controller" standalone="true" /> <action name="procSocialxeCompileInfo" type="controller" standalone="true" /> <action name="procSocialxeResetSocialInfo" type="controller" standalone="true" /> <action name="dispSocialxeLogin" type="view" standalone="true" /> <action name="dispSocialxeCallback" type="view" standalone="true" /> <action name="dispSocialxeLogout" type="view" standalone="true" /> <action name="dispSocialxeTextyleTool" type="view" /> <action name="dispSocialxeLoginForm" type="view" standalone="true" /> <action name="dispSocialxeLoginAdditional" type="view" standalone="true" /> <action name="dispSocialxeSocialInfo" type="view" standalone="true" /> </actions> <menus> <menu name="socialxe" type="all"> <title xml:lang="ko">SocialXE</title> </menu> </menus> </module>
그 다음은 나머지 파일에서도 똑같이 수정해 주면 됩니다.
여러 파일에서 텍스트를 검색하는 데는 grep 명령어를 사용하면 편리합니다. XE 루트 디렉토리로 이동해서 다음 명령어를 치면 XE 디렉토리 내 모든 파일에서 'procCompileInput' 이라는 텍스트가 포함된 위치를 알려줍니다.
$ grep -ir 'procCompileInput' .
ack-grep라는 패키지를 사용하면 조금 더 비쥬얼하게(?) 검색 결과를 볼 수 있습니다.
(리눅스 기본 패키지에 포함되어 있지 않으므로 사용하기 전에 설치해야 합니다.)
$ ack-grep -ir 'procCompileInput' .
검색하는 수고를 덜어드리기 위해 각 5개의 키워드가 위치하는 곳을 제가 대신 찾아드렸습니다.
※ SocialXE 패키지를 중간중간 수정했기 때문에 줄 번호가 완전히 일치하지 않을 수도 있습니다. 표시된 줄에 키워드가 없으면 그 근처를 찾아보세요. ^-^
+. 검색 결과에서 ./files/cache/... 에 존재하는 파일은 자동으로 생성되므로 수정하지 않아도 됩니다.
procCompileInput
- ./widgets/socialxe_comment/skins/sketchbook5/js/socialxe.js : 24
- ./widgets/socialxe_comment/skins/default/js/socialxe.js : 24
- ./modules/socialxe/conf/module.xml : 15
- ./modules/socialxe/socialxe.controller.php : 235
procCompileList
- ./widgets/socialxe_comment/skins/sketchbook5/js/socialxe.js : 56, 76, 102, 115
- ./widgets/socialxe_comment/skins/default/js/socialxe.js : 56, 76, 101, 114
- ./modules/socialxe/conf/module.xml : 16
- ./modules/socialxe/socialxe.controller.php : 271
procCompileSubList
- ./widgets/socialxe_comment/skins/sketchbook5/js/socialxe.js : 150, 190
- ./widgets/socialxe_comment/skins/default/js/socialxe.js : 147, 187
- ./modules/socialxe/conf/module.xml : 17
- ./modules/socialxe/socialxe.controller.php : 291
procCompileInfo
- ./widgets/socialxe_info/skins/default/js/socialxe.js : 21
- ./modules/socialxe/conf/module.xml : 26
- ./modules/socialxe/socialxe.controller.php : 253
procResetSocialInfo
- ./widgets/socialxe_info/skins/default/js/socialxe.js : 40
- ./modules/socialxe/conf/module.xml : 27
- ./modules/socialxe/socialxe.controller.php : 648