copy sandbox to trunk

git-svn-id: http://xe-core.googlecode.com/svn/trunk@7203 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
haneul 2010-01-20 11:41:59 +00:00
commit 8cb57d0de9
233 changed files with 9683 additions and 8550 deletions

View file

@ -1,51 +1,18 @@
RewriteEngine On RewriteEngine On
# reserve XE Layout Template Source File (*.html) # reserve XE Layout Template Source File (*.html)
RewriteRule ^layouts/(.+)/(.+).html$ ./index.php [L] RewriteRule ^layouts/(.+)/(.+)\.html$ ./index.php [L]
# static files # static files
RewriteRule ^(.+)/files/member_extra_info/(.*) ./files/member_extra_info/$2 [L] RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.+)/files/attach/(.*) ./files/attach/$2 [L] RewriteRule ^(.+)/files/(member_extra_info|attach|cache|faceOff)/(.*) ./files/$2/$3 [L]
RewriteRule ^(.+)/files/cache/(.*) ./files/cache/$2 [L] RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.+)/files/faceOff/(.*) ./files/faceOff/$2 [L] RewriteRule ^([a-zA-Z0-9_]+)(/[a-zA-Z0-9_]+(/entry)?)?/(files|modules|common|widgets|widgetStyle|layouts|addons)/(.*) ./$4/$5 [L]
RewriteRule ^([a-zA-Z0-9_]+)/files/(.*) ./files/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/modules/(.*) ./modules/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/common/(.*) ./common/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/widgets/(.*) ./widgets/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/widgetstyle/(.*) ./widgetstyle/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/layouts/(.*) ./layouts/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/addons/(.*) ./addons/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/files/(.*) ./files/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/modules/(.*) ./modules/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/common/(.*) ./common/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/widgets/(.*) ./widgets/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/widgetstyle/(.*) ./widgetstyle/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/layouts/(.*) ./layouts/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/entry/addons/(.*) ./addons/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/files/(.*) ./files/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/modules/(.*) ./modules/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/common/(.*) ./common/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/widgets/(.*) ./widgets/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/widgetstyle/(.*) ./widgetstyle/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/layouts/(.*) ./layouts/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/addons/(.*) ./addons/$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/files/(.*) ./files/$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/modules/(.*) ./modules/$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/common/(.*) ./common/$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/widgets/(.*) ./widgets/$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/widgetstyle/(.*) ./widgetstyle/$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/layouts/(.*) ./layouts/$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/addons/(.*) ./addons/$3 [L]
# rss , blogAPI # rss , blogAPI
RewriteRule ^rss$ ./index.php?module=rss&act=rss [L] RewriteRule ^(rss|atom)$ ./index.php?module=rss&act=$1 [L]
RewriteRule ^atom$ ./index.php?module=rss&act=atom [L] RewriteRule ^([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?mid=$1&act=$2 [L]
RewriteRule ^([a-zA-Z0-9_]+)/rss$ ./index.php?mid=$1&act=rss [L] RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?vid=$1&mid=$2&act=$3 [L]
RewriteRule ^([a-zA-Z0-9_]+)/atom$ ./index.php?mid=$1&act=atom [L]
RewriteRule ^([a-zA-Z0-9_]+)/api$ ./index.php?mid=$1&act=api [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/rss$ ./index.php?vid=$1&mid=$2&act=rss [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/atom$ ./index.php?vid=$1&mid=$2&act=atom [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/api$ ./index.php?vid=$1&mid=$2&act=api [L]
# trackback # trackback
RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L] RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L]
@ -55,21 +22,22 @@ RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&documen
RewriteRule ^admin/?$ ./index.php?module=admin [L] RewriteRule ^admin/?$ ./index.php?module=admin [L]
# document permanent link # document permanent link
RewriteRule ^([[:digit:]]+)$ ./index.php?document_srl=$1 [L] RewriteRule ^([0-9]+)$ ./index.php?document_srl=$1 [L]
# vid + document permanent link
RewriteRule ^([a-zA-Z0-9_]+)/([[:digit:]]+)$ ./index.php?vid=$1&document_srl=$2 [L]
# mid link # mid link
RewriteRule ^([a-zA-Z0-9_]+)(/){0,1}$ ./index.php?mid=$1 [L] RewriteCond %{SCRIPT_FILENAME} !-d
# vid + mid link RewriteRule ^([a-zA-Z0-9_]+)/?$ ./index.php?mid=$1 [L]
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)(/){0,1}$ ./index.php?vid=$1&mid=$2 [L]
# mid + document link # mid + document link
RewriteRule ^([a-zA-Z0-9_]+)/([[:digit:]]+)$ ./index.php?mid=$1&document_srl=$2 [L] RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L]
# vid + mid link
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ ./index.php?vid=$1&mid=$2 [L]
# vid + mid + document link # vid + mid + document link
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([[:digit:]]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L] RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L]
# mid + entry title # mid + entry title
RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L] RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L]
# vid + mid + entry title # vid + mid + entry title
RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?vid=$1&mid=$2&entry=$3 [L] RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?vid=$1&mid=$2&entry=$3 [L]

858
LICENSE
View file

@ -1,469 +1,397 @@
이 문서는 자유 소프트웨어 재단(Free Software Foundation)의 GNU General Public License를 GNU LESSER GENERAL PUBLIC LICENSE
한국어로 번역한 것입니다. 이 문서는 GNU General Public License가 내포하고 있는 호혜적인 Version 2.1, February 1999
자유와 공유의 정신을 보다 많은 사람들에게 알리기 위한 희망에서 작성되었지만, 자유 소프트
웨어 재단의 공식 문서로 취급될 수는 없습니다. 이는 원래의 문서가 의도하고 있는 내용이 왜
곡되지 않고 법률적으로 유효하기 위해서 선행되어야 할 양국의 현행 법률과 언어의 적합성 여
부에 대한 전문가들의 검토 작업에 많은 비용이 필요하기 때문입니다. 또한 공식 번역문으로 인
정된 문서라 하더라도 다른 언어로의 번역에 따른 위험 부담은 여전히 남아 있게 됩니다. 따라서
자유 소프트웨어 재단은 오역이나 해석상의 난점으로 인해서 발생될 지도 모를 혼란과 분쟁의
가능성을 미연에 방지하고, 문서가 담고 있는 내용과 취지를 보다 많은 사람들에게 알리려는 상
반된 목적을, 한국어 번역문을 공식적으로 승인하지 않는 방법으로 양립시키고 있습니다.
자유 소프트웨어 재단은 어떠한 언어에 대한 번역문도 공식적으로 인정하지 않고 있으며, Copyright (C) 1991, 1999 Free Software Foundation, Inc.
그러한 계획 또한 갖고 있지 않습니다. 자유 소프트웨어 재단은 GNU General Public License를 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
실무에 적용할 경우, 오직 영문판에 의해서만 그 법률적 효력이 올바르게 발생될 수 있음을 권고하고
있습니다. 이 번역문은 법률적 검토와 문서간의 동일성 여부에 대한 검증을 거치지 않은 것이며,
이로 인해서 야기될 수 있을 지도 모를 법률적인 문제에 대해서 어떠한 형태의 보증도 제공하지
않습니다. GNU General Public License를 상업적인 목적으로 사용하려고 할 경우에는 변호사나
변리사에게 직접 자문을 구하기 바랍니다. 그러나 대부분의 일반 사용자들에게는 이 번역문이 전달하려고
하는 내용과 취지를 이해하는 것만으로도 충분할 것입니다.
본 문서는 한글 번역된 GPL과 원본 영문 GPL을 전부 포함하고 있습니다.
--------------------------------------------------------------------------------------------------------------------------
GNU 일반 공중 사용 허가서
(GNU GENERAL PUBLIC LICENSE)
제 2판, 1991년 6월
(Version 2, June 1991)
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
누구든지 본 사용 허가서를 있는 그대로 복제하고 배포할 수 있습니다.
그러나 본문에 대한 수정은 허용되지 않습니다.
전 문
소프트웨어에 적용되는 대부분의 사용 허가서(license)들은 소프트웨어에 대한 수정과 공유의 자유를 제한
하려는 것을 그 목적으로 합니다. 그러나 GNU 일반 공중 사용 허가서(이하, ``GPL''이라고 칭합니다.)는 자
유 소프트웨어에 대한 수정과 공유의 자유를 모든 사용자들에게 보장하기 위해서 성립된 것입니다. 자유 소
프트웨어 재단이 제공하는 대부분의 소프트웨어들은 GPL에 의해서 관리되고 있으며, 몇몇 소프트웨어에는
별도의 사용 허가서인 GNU 라이브러리 일반 공중 사용 허가서(GNU Library General Public License)를 대신
적용하기도 합니다. 자유 소프트웨어란, 이를 사용하려고 하는 모든 사람에 대해서 동일한 자유와 권리가
함께 양도되는 소프트웨어를 말하며 프로그램 저작자의 의지에 따라 어떠한 종류의 프로그램에도 GPL을 적
용할 수 있습니다. 따라서 여러분이 만든 프로그램에도 GPL을 적용할 수 있습니다.
자유 소프트웨어를 언급할 때 사용되는 ``자유''라는 단어는 무료(無料)를 의미하는 금전적인 측면의 자유
가 아니라 구속되지 않는다는 관점에서의 자유를 의미하며, GPL은 자유 소프트웨어를 이용한 복제와 개작,
배포와 수익 사업 등의 가능한 모든 형태의 자유를 실질적으로 보장하고 있습니다. 여기에는 원시 코드
(source code)의 전부 또는 일부를 원용해서 개선된 프로그램을 만들거나 새로운 프로그램을 창작할 수 있
는 자유가 포함되며, 자신에게 양도된 이러한 자유와 권리를 보다 명확하게 인식할 수 있도록 하기 위한 규
정도 포함되어 있습니다.
GPL은 GPL 안에 소프트웨어를 양도받을 사용자의 권리를 제한하는 조항과 단서를 별항으로 추가시키지 못하
게 함으로써 사용자들의 자유와 권리를 실제적으로 보장하고 있습니다. 자유 소프트웨어의 개작과 배포에
관계하고 있는 사람들은 이러한 무조건적인 권리 양도 규정을 준수해야만 합니다.
예를 들어 GPL 프로그램을 배포할 경우에는 프로그램의 유료 판매나 무료 배포에 관계없이 자신이 해당 프
로그램에 대해서 가질 수 있었던 모든 권리를, 프로그램을 받게될 사람에게 그대로 양도해 주어야 합니다.
이 경우, 프로그램의 원시 코드를 함께 제공하거나 원시 코드를 구할 수 있는 방법을 확실히 알려주어야 하
고 이러한 모든 사항들을 사용자들이 분명히 알 수 있도록 명시해야 합니다.
자유 소프트웨어 재단은 다음과 같은 두 가지 단계를 통해서 사용자들을 권리를 보호합니다. (1) 소프트웨
어에 저작권을 설정합니다. (2) 저작권의 양도에 관한 실정법에 의해서 유효한 법률적 효력을 갖는 GPL을
통해 소프트웨어를 복제하거나 개작 및 배포할 수 있는 권리를 사용자들에게 부여합니다.
자유 소프트웨어를 사용하는 사람들은 반복적인 재배포 과정을 통해 소프트웨어 자체에 수정과 변형이 일어
날 수도 있으며, 이는 최초의 저작자가 만든 소프트웨어가 갖고 있는 문제가 아닐 수 있다는 개연성을 인식
하고 있어야 합니다. 우리는 개작과 재배포 과정에서 다른 사람에 의해 발생된 문제로 인해 프로그램 원저
작자들의 신망이 훼손되는 것을 원하지 않습니다. GPL에 자유 소프트웨어에 대한 어떠한 형태의 보증도 규
정하지 않는 이유는 이러한 점들이 고려되었기 때문이며, 이는 프로그램 원저작자와 자유 소프트웨어 재단
의 자유로운 활동을 보장하는 현실적인 수단이기도 합니다.
특허 제도는 자유 소프트웨어의 발전을 위협하는 요소일 수밖에 없습니다. 자유 프로그램을 재배포하는 사
람들이 개별적으로 특허를 취득하게 되면, 결과적으로 그 프로그램이 독점 소프트웨어가 될 가능성이 있습
니다. 자유 소프트웨어 재단은 이러한 문제에 대처하기 위해서 어떠한 특허에 대해서도 그 사용 권리를 모
든 사람들(이하, ``공중(公衆)''이라고 칭합니다.)에게 자유롭게 허용하는 경우에 한해서만 자유 소프트웨
어와 함께 사용할 수 있다는 것을 명확히 밝히고 있습니다.
복제(copying)와 개작(modification) 및 배포(distribution)에 관련된 구체적인 조건과 규정은 다음과 같습
니다.
복제와 개작 및 배포에 관한 조건과 규정
제 0 조. 본 허가서는 GNU 일반 공중 사용 허가서의 규정에 따라 배포될 수 있다는 사항이 저작권자에 의해
서 명시된 모든 컴퓨터 프로그램 저작물에 대해서 동일하게 적용됩니다. 컴퓨터 프로그램 저작물(이하, ``
프로그램''이라고 칭합니다.)이란 특정한 결과를 얻기 위해서 컴퓨터 등의 정보 처리 능력을 가진 장치(이
하, ``컴퓨터''라고 칭합니다.) 내에서 직접 또는 간접으로 사용되는 일련의 지시 및 명령으로 표현된 창작
물을 의미하고, ``2차적 프로그램''이란 전술한 프로그램 자신 또는 저작권법의 규정에 따라 프로그램의 전
부 또는 상당 부분을 원용하거나 다른 언어로의 번역을 포함할 수 있는 개작 과정을 통해서 창작된 새로운
프로그램과 이와 관련된 저작물을 의미합니다. (이후로 다른 언어로의 번역은 별다른 제한없이 개작의 범위
에 포함되는 것으로 간주합니다.) ``피양도자''란 GPL의 규정에 따라 프로그램을 양도받은 사람을 의미하
고, ``원(原)프로그램''이란 프로그램을 개작하거나 2차적 프로그램을 만들기 위해서 사용된 최초의 프로그
램을 의미합니다.
본 허가서는 프로그램에 대한 복제와 개작 그리고 배포 행위에 대해서만 적용됩니다. 따라서 프로그램을 실
행시키는 행위에 대한 제한은 없습니다. 프로그램의 결과물(output)에는, 그것이 프로그램을 실행시켜서 생
성된 것인지 아닌지의 여부에 상관없이 결과물의 내용이 원프로그램으로부터 파생된 2차적 프로그램을 구성
했을 때에 한해서 본 허가서의 규정들이 적용됩니다. 2차적 프로그램의 구성 여부는 2차적 프로그램 안에서
의 원프로그램의 역할을 토대로 판단합니다.
제 1 조. 적절한 저작권 표시와 프로그램에 대한 보증이 제공되지 않는다는 사실을 각각의 복제물에 명시하
는 한, 피양도자는 프로그램의 원시 코드를 자신이 양도받은 상태 그대로 어떠한 매체를 통해서도 복제하고
배포할 수 있습니다. 복제와 배포가 이루어 질 때는 본 허가서와 프로그램에 대한 보증이 제공되지 않는다
는 사실에 대해서 언급되었던 모든 내용을 그대로 유지시켜야 하며, 영문판 GPL을 함께 제공해야 합니다.
배포자는 복제물을 물리적으로 인도하는데 소요된 비용을 청구할 수 있으며, 선택 사항으로 독자적인 유료
보증을 설정할 수 있습니다.
제 2 조. 피양도자는 자신이 양도받은 프로그램의 전부나 일부를 개작할 수 있으며, 이를 통해서 2차적 프
로그램을 창작할 수 있습니다. 개작된 프로그램이나 창작된 2차적 프로그램은 다음의 사항들을 모두 만족시
키는 조건에 한해서, 제1조의 규정에 따라 또다시 복제되고 배포될 수 있습니다.
제 1 항. 파일을 개작할 때는 파일을 개작한 사실과 그 날짜를 파일 안에 명시해야 합니다.
제 2 항. 배포하거나 공표하려는 저작물의 전부 또는 일부가 양도받은 프로그램으로부터 파생된 것이라면,
저작물 전체에 대한 사용 권리를 본 허가서의 규정에 따라 공중에게 무상으로 허용해야 합니다.
제 3 항. 개작된 프로그램의 일반적인 실행 형태가 대화형 구조로 명령어를 읽어 들이는 방식을 취하고 있
을 경우에는, 적절한 저작권 표시와 프로그램에 대한 보증이 제공되지 않는다는 사실, (별도의 보증을 설정
한 경우라면 해당 내용) 그리고 양도받은 프로그램을 본 규정에 따라 재배포할 수 있다는 사실과 GPL 사본
을 참고할 수 있는 방법이 함께 포함된 문구가 프로그램이 대화형 구조로 평이하게 실행된 직후에 화면 또
는 지면으로 출력되도록 작성되어야 합니다. (예외 규정: 양도받은 프로그램이 대화형 구조를 갖추고 있다
하더라도 통상적인 실행 환경에서 전술한 사항들이 출력되지 않는 형태였을 경우에는 이를 개작한 프로그램
또한 관련 사항들을 출력시키지 않아도 무방합니다.)
위의 조항들은 개작된 프로그램 전체에 적용됩니다. 만약, 개작된 프로그램에 포함된 특정 부분이 원프로그
램으로부터 파생된 것이 아닌 별도의 독립 저작물로 인정될 만한 상당한 이유가 있을 경우에는 해당 저작물
의 개별적인 배포에는 본 허가서의 규정들이 적용되지 않습니다. 그러나 이러한 저작물이 2차적 프로그램의
일부로서 함께 배포된다면 개별적인 저작권과 배포 기준에 상관없이 저작물 모두에 본 허가서가 적용되어야
하며, 전체 저작물에 대한 사용 권리는 공중에게 무상으로 양도됩니다.
이러한 규정은 개별적인 저작물에 대한 저작자의 권리를 침해하거나 인정하지 않으려는 것이 아니라, 원프
로그램으로부터 파생된 2차적 프로그램이나 수집 저작물의 배포를 일관적으로 규제할 수 있는 권리를 행사
하기 위한 것입니다.
원프로그램이나 원프로그램으로부터 파생된 2차적 프로그램을 이들로부터 파생되지 않은 다른 저작물과 함
께 단순히 저장하거나 배포할 목적으로 동일한 매체에 모아 놓은 집합물의 경우에는, 원프로그램으로부터
파생되지 않은 다른 저작물에는 본 허가서의 규정들이 적용되지 않습니다.
제 3 조. 피양도자는 다음 중 하나의 항목을 만족시키는 조건에 한해서 제1조와 제2조의 규정에 따라 프로
그램(또는 제2조에서 언급된 2차적 프로그램)을 목적 코드(object code)나 실행물(executable form)의 형태
로 복제하고 배포할 수 있습니다.
제 1 항. 목적 코드나 실행물에 상응하는 컴퓨터가 인식할 수 있는 완전한 원시 코드를 함께 제공해야 합니
다. 원시 코드는 제1조와 제2조의 규정에 따라 배포될 수 있어야 하며, 소프트웨어의 교환을 위해서 일반적
으로 사용되는 매체를 통해 제공되어야 합니다.
제 2 항. 배포에 필요한 최소한의 비용만을 받고 목적 코드나 실행물에 상응하는 완전한 원시 코드를 배포
하겠다는, 최소한 3년간 유효한 약정서를 함께 제공해야 합니다. 이 약정서는 약정서를 갖고 있는 어떠한
사람에 대해서도 유효해야 합니다. 원시 코드는 컴퓨터가 인식할 수 있는 형태여야 하고 제1조와 제2조의
규정에 따라 배포될 수 있어야 하며, 소프트웨어의 교환을 위해서 일반적으로 사용되는 매체를 통해 제공되
어야 합니다.
제 3 항. 목적 코드나 실행물에 상응하는 원시 코드를 배포하겠다는 약정에 대해서 자신이 양도받은 정보를
함께 제공해야 합니다. (제3항은 위의 제2항에 따라 원시 코드를 배포하겠다는 약정을 프로그램의 목적 코
드나 실행물과 함께 제공 받았고, 동시에 비상업적인 배포를 하고자 할 경우에 한해서만 허용됩니다.)
저작물에 대한 원시 코드란 해당 저작물을 개작하기에 적절한 형식을 의미합니다. 실행물에 대한 완전한 원
시 코드란 실행물에 포함된 모든 모듈들의 원시 코드와 이와 관련된 인터페이스 정의 파일 모두, 그리고 실
행물의 컴파일과 설치를 제어하는데 사용된 스크립트 전부를 의미합니다. 그러나 특별한 예외의 하나로서,
실행물이 실행될 운영체제의 주요 부분(컴파일러나 커널 등)과 함께 (원시 코드나 바이너리의 형태로) 일반
적으로 배포되는 구성 요소들은 이러한 구성 요소 자체가 실행물에 수반되지 않는 한 원시 코드의 배포 대
상에서 제외되어도 무방합니다.
목적 코드나 실행물을 지정한 장소로부터 복제해 갈 수 있게 하는 방식으로 배포할 경우, 동일한 장소로부
터 원시 코드를 복제할 수 있는 동등한 접근 방법을 제공한다면 이는 원시 코드를 목적 코드와 함께 복제되
도록 설정하지 않았다고 하더라도 원시 코드를 배포하는 것으로 간주됩니다.
제 4 조. 본 허가서에 의해 명시적으로 이루어 지지 않는 한 프로그램에 대한 복제와 개작 및 하위 허가권
설정과 배포가 성립될 수 없습니다. 이와 관련된 어떠한 행위도 무효이며 본 허가서가 보장한 권리는 자동
으로 소멸됩니다. 그러나 본 허가서의 규정에 따라 프로그램의 복제물이나 권리를 양도받았던 제3자는 본
허가서의 규정들을 준수하는 한, 배포자의 권리 소멸에 관계없이 사용상의 권리를 계속해서 유지할 수 있습
니다.
제 5 조. 본 허가서는 서명이나 날인이 수반되는 형식을 갖고 있지 않기 때문에 피양도자가 본 허가서의 내
용을 반드시 받아들여야 할 필요는 없습니다. 그러나 프로그램이나 프로그램에 기반한 2차적 프로그램에 대
한 개작 및 배포를 허용하는 것은 본 허가서에 의해서만 가능합니다. 만약 본 허가서에 동의하지 않을 경우
에는 이러한 행위들이 법률적으로 금지됩니다. 따라서 프로그램(또는 프로그램에 기반한 2차적 프로그램)을
개작하거나 배포하는 행위는 이에 따른 본 허가서의 내용에 동의한다는 것을 의미하며, 복제와 개작 및 배
포에 관한 본 허가서의 조건과 규정들을 모두 받아들이겠다는 의미로 간주됩니다.
제 6 조. 피양도자에 의해서 프로그램(또는 프로그램에 기반한 2차적 프로그램)이 반복적으로 재배포될 경
우, 각 단계에서의 피양도자는 본 허가서의 규정에 따른 프로그램의 복제와 개작 및 배포에 대한 권리를 최
초의 양도자로부터 양도받은 것으로 자동적으로 간주됩니다. 프로그램(또는 프로그램에 기반한 2차적 프로
그램)을 배포할 때는 피양도자의 권리의 행사를 제한할 수 있는 어떠한 사항도 추가할 수 없습니다. 그러나
피양도자에게, 재배포가 일어날 시점에서의 제3의 피양도자에게 본 허가서를 준수하도록 강제할 책임은 부
과되지 않습니다.
제 7 조. 법원의 판결이나 특허권 침해에 대한 주장 또는 특허 문제에 국한되지 않은 그밖의 이유들로 인해
서 본 허가서의 규정에 배치되는 사항이 발생한다 하더라도 그러한 사항이 선행하거나 본 허가서의 조건과
규정들이 면제되는 것은 아닙니다. 따라서 법원의 명령이나 합의 등에 의해서 본 허가서에 위배되는 사항들
이 발생한 상황이라도 양측 모두를 만족시킬 수 없다면 프로그램은 배포될 수 없습니다. 예를 들면, 특정한
특허 관련 허가가 프로그램의 복제물을 직접 또는 간접적인 방법으로 양도받은 임의의 제3자에게 해당 프로
그램을 무상으로 재배포할 수 있게 허용하지 않는다면, 그러한 허가와 본 사용 허가를 동시에 만족시키면서
프로그램을 배포할 수 있는 방법은 없습니다.
본 조항은 특정한 상황에서 본 조항의 일부가 유효하지 않거나 적용될 수 없을 경우에도 본 조항의 나머지
부분들을 적용하기 위한 의도로 만들어 졌습니다. 따라서 그 이외의 상황에서는 본 조항을 전체적으로 적용
하면 됩니다.
본 조항의 목적은 특허나 저작권 침해 등의 행위를 조장하거나 해당 권리를 인정하지 않으려는 것이 아니
라, GPL을 통해서 구현되어 있는 자유 소프트웨어의 배포 체계를 통합적으로 보호하기 위한 것입니다. 많은
사람들이 배포 체계에 대한 신뢰있는 지원을 계속해 줌으로써 소프트웨어의 다양한 분야에 많은 공헌을 해
주었습니다. 소프트웨어를 어떠한 배포 체계로 배포할 것인가를 결정하는 것은 전적으로 저작자와 기증자들
의 의지에 달려있는 것이지, 일반 사용자들이 강요할 수 있는 문제는 아닙니다.
본 조항은 본 허가서의 다른 조항들에서 무엇이 중요하게 고려되어야 하는 지를 명확하게 설명하기 위한 목
적으로 만들어진 것입니다.
제 8 조. 특허나 저작권이 설정된 인터페이스로 인해서 특정 국가에서 프로그램의 배포와 사용이 함께 또는
개별적으로 제한되어 있는 경우, 본 사용 허가서를 프로그램에 적용한 최초의 저작권자는 문제가 발생하지
않는 국가에 한해서 프로그램을 배포한다는 배포상의 지역적 제한 조건을 명시적으로 설정할 수 있으며, 이
러한 사항은 본 허가서의 일부로 간주됩니다.
제 9 조. 자유 소프트웨어 재단은 때때로 본 사용 허가서의 개정판이나 신판을 공표할 수 있습니다. 새롭게
공표될 판은 당면한 문제나 현안을 처리하기 위해서 세부적인 내용에 차이가 발생할 수 있지만, 그 근본 정
신에는 변함이 없을 것입니다.
각각의 판들은 판번호를 사용해서 구별됩니다. 특정한 판번호와 그 이후 판을 따른다는 사항이 명시된 프로
그램에는 해당 판이나 그 이후에 발행된 어떠한 판을 선택해서 적용해도 무방하고, 판번호를 명시하고 있지
않은 경우에는 자유 소프트웨어 재단이 공표한 어떠한 판번호의 판을 적용해도 무방합니다.
제 10 조. 프로그램의 일부를 본 허가서와 배포 기준이 다른 자유 프로그램과 함께 결합하고자 할 경우에는
해당 프로그램의 저작자로부터 서면 승인을 받아야 합니다. 자유 소프트웨어 재단이 저작권을 갖고 있는 소
프트웨어의 경우에는 자유 소프트웨어 재단의 승인을 얻어야 합니다. 우리는 이러한 요청을 수락하기 위해
서 때때로 예외 기준을 만들기도 합니다. 자유 소프트웨어 재단은 일반적으로 자유 소프트웨어의 2차적 저
작물들을 모두 자유로운 상태로 유지시키려는 목적과 소프트웨어의 공유와 재활용을 증진시키려는 두가지
목적을 기준으로 승인 여부를 결정할 것입니다.
보증의 결여 (제11조, 제12조)
제 11 조. 본 허가서를 따르는 프로그램은 무상으로 양도되기 때문에 관련 법률이 허용하는 한도 내에서 어
떠한 형태의 보증도 제공되지 않습니다. 프로그램의 저작권자와 배포자가 공동 또는 개별적으로 별도의 보
증을 서면으로 제공할 때를 제외하면, 특정한 목적에 대한 프로그램의 적합성이나 상업성 여부에 대한 보증
을 포함한 어떠한 형태의 보증도 명시적이나 묵시적으로 설정되지 않은 ``있는 그대로의'' 상태로 이 프로
그램을 배포합니다. 프로그램과 프로그램의 실행에 따라 발생할 수 있는 모든 위험은 피양도자에게 인수되
며 이에 따른 보수 및 복구를 위한 제반 경비 또한 피양도자가 모두 부담해야 합니다.
제 12 조. 저작권자나 배포자가 프로그램의 손상 가능성을 사전에 알고 있었다 하더라도 발생된 손실이 관
련 법규에 의해 보호되고 있거나 이에 대한 별도의 서면 보증이 설정된 경우가 아니라면, 저작권자나 프로
그램을 원래의 상태 또는 개작한 상태로 제공한 배포자는 프로그램의 사용이나 비작동으로 인해 발생된 손
실이나 프로그램 자체의 손실에 대해 책임지지 않습니다. 이러한 면책 조건은 사용자나 제3자가 프로그램을
조작함으로써 발생된 손실이나 다른 소프트웨어와 프로그램을 함께 동작시키는 것으로 인해서 발생된 데이
터의 상실 및 부정확한 산출 결과에만 국한되는 것이 아닙니다. 발생된 손실의 일반성이나 특수성 뿐 아니
라 원인의 우발성 및 필연성도 전혀 고려되지 않습니다.
----------------------------------------------------------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble Preamble
The licenses for most software are designed to take away your The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free Licenses are intended to guarantee your freedom to share and change
software--to make sure the software is free for all its users. This free software--to make sure the software is free for all its users.
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not This license, the Lesser General Public License, applies to some
price. Our General Public Licenses are designed to make sure that you specially designated software packages--typically libraries--of the
have the freedom to distribute copies of free software (and charge for Free Software Foundation and other authors who decide to use it. You
this service if you wish), that you receive source code or can get it can use it too, but we suggest you first think carefully about whether
if you want it, that you can change the software or use pieces of it this license or the ordinary General Public License is the better
in new free programs; and that you know you can do these things. strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights. distributors to deny you these rights or to ask you to surrender these
These restrictions translate to certain responsibilities for you if you rights. These restrictions translate to certain responsibilities for
distribute copies of the software, or if you modify it. you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of such a program, whether For example, if you distribute copies of the library, whether gratis
gratis or for a fee, you must give the recipients all the rights that or for a fee, you must give the recipients all the rights that we gave
you have. You must make sure that they, too, receive or can get the you. You must make sure that they, too, receive or can get the source
source code. And you must show them these terms so they know their code. If you link other code with the library, you must provide
rights. complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with two steps: (1) copyright the software, and We protect your rights with a two-step method: (1) we copyright the
(2) offer you this license which gives you legal permission to copy, library, and (2) we offer you this license, which gives you legal
distribute and/or modify the software. permission to copy, distribute and/or modify the library.
Also, for each author's protection and ours, we want to make certain To protect each distributor, we want to make it very clear that
that everyone understands that there is no warranty for this free there is no warranty for the free library. Also, if the library is
software. If the software is modified by someone else and passed on, we modified by someone else and passed on, the recipients should know
want its recipients to know that what they have is not the original, so that what they have is not the original version, so that the original
that any problems introduced by others will not reflect on the original author's reputation will not be affected by problems that might be
authors' reputations. introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Finally, any free program is threatened constantly by software Most GNU software, including some libraries, is covered by the
patents. We wish to avoid the danger that redistributors of a free ordinary GNU General Public License. This license, the GNU Lesser
program will individually obtain patent licenses, in effect making the General Public License, applies to certain designated libraries, and
program proprietary. To prevent this, we have made it clear that any is quite different from the ordinary General Public License. We use
patent must be licensed for everyone's free use or not licensed at all. this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and The precise terms and conditions for copying, distribution and
modification follow. modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
GNU GENERAL PUBLIC LICENSE former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains 0. This License Agreement applies to any software library or other
a notice placed by the copyright holder saying it may be distributed program which contains a notice placed by the copyright holder or
under the terms of this General Public License. The "Program", below, other authorized party saying it may be distributed under the terms of
refers to any such program or work, and a "work based on the Program" this Lesser General Public License (also called "this License").
means either the Program or any derivative work under copyright law: Each licensee is addressed as "you".
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program running a program using the Library is not restricted, and output from
is covered only if its contents constitute a work based on the such a program is covered only if its contents constitute a work based
Program (independent of having been made by running the Program). on the Library (independent of the use of the Library in a tool for
Whether that is true depends on what the Program does. writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Program's 1. You may copy and distribute verbatim copies of the Library's
source code as you receive it, in any medium, provided that you complete source code as you receive it, in any medium, provided that
conspicuously and appropriately publish on each copy an appropriate you conspicuously and appropriately publish on each copy an
copyright notice and disclaimer of warranty; keep intact all the appropriate copyright notice and disclaimer of warranty; keep intact
notices that refer to this License and to the absence of any warranty; all the notices that refer to this License and to the absence of any
and give any other recipients of the Program a copy of this License warranty; and distribute a copy of this License along with the
along with the Program. Library.
You may charge a fee for the physical act of transferring a copy, and You may charge a fee for the physical act of transferring a copy,
you may at your option offer warranty protection in exchange for a fee. and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and 2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1 distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions: above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change. stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in c) You must cause the whole of the work to be licensed at no
whole or in part contains or is derived from the Program or any charge to all third parties under the terms of this License.
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively d) If a facility in the modified Library refers to a function or a
when run, you must cause it, when started running for such table of data to be supplied by an application program that uses
interactive use in the most ordinary way, to print or display an the facility, other than as an argument passed when the facility
announcement including an appropriate copyright notice and a is invoked, then you must make a good faith effort to ensure that,
notice that there is no warranty (or else, saying that you provide in the event an application does not supply such function or
a warranty) and that users may redistribute the program under table, the facility still operates, and performs whatever part of
these conditions, and telling the user how to view a copy of this its purpose remains meaningful.
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on (For example, a function in a library to compute square roots has
the Program is not required to print an announcement.) a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program, identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it. entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or exercise the right to control the distribution of derivative or
collective works based on the Program. collective works based on the Library.
In addition, mere aggregation of another work not based on the Program In addition, mere aggregation of another work not based on the Library
with the Program (or with a work based on the Program) on a volume of with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under a storage or distribution medium does not bring the other work under
the scope of this License. the scope of this License.
3. You may copy and distribute the Program (or a work based on it, 3. You may opt to apply the terms of the ordinary GNU General Public
under Section 2) in object code or executable form under the terms of License instead of this License to a given copy of the Library. To do
Sections 1 and 2 above provided that you also do one of the following: this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
a) Accompany it with the complete corresponding machine-readable This option is useful when you wish to copy part of the code of
source code, which must be distributed under the terms of Sections the Library into a program that is not a library.
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three 4. You may copy and distribute the Library (or a portion or
years, to give any third party, for a charge no more than your derivative of it, under Section 2) in object code or executable form
cost of physically performing source distribution, a complete under the terms of Sections 1 and 2 above provided that you accompany
machine-readable copy of the corresponding source code, to be it with the complete corresponding machine-readable source code, which
distributed under the terms of Sections 1 and 2 above on a medium must be distributed under the terms of Sections 1 and 2 above on a
customarily used for software interchange; or, medium customarily used for software interchange.
c) Accompany it with the information you received as to the offer If distribution of object code is made by offering access to copy
to distribute corresponding source code. (This alternative is from a designated place, then offering equivalent access to copy the
allowed only for noncommercial distribution and only if you source code from the same place satisfies the requirement to
received the program in object code or executable form with such distribute the source code, even though third parties are not
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code. compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program 5. A program that contains no derivative of any portion of the
except as expressly provided under this License. Any attempt Library, but is designed to work with the Library by being compiled or
otherwise to copy, modify, sublicense or distribute the Program is linked with it, is called a "work that uses the Library". Such a
void, and will automatically terminate your rights under this License. work, in isolation, is not a derivative work of the Library, and
However, parties who have received copies, or rights, from you under therefore falls outside the scope of this License.
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the modifying or distributing the Library (or any work based on the
Program), you indicate your acceptance of this License to do so, and Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying all its terms and conditions for copying, distributing or modifying
the Program or works based on it. the Library or works based on it.
6. Each time you redistribute the Program (or any work based on the 10. Each time you redistribute the Library (or any work based on the
Program), the recipient automatically receives a license from the Library), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to original licensor to copy, distribute, link with or modify the Library
these terms and conditions. You may not impose any further subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein. restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to You are not responsible for enforcing compliance by third parties with
this License. this License.
7. If, as a consequence of a court judgment or allegation of patent 11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues), infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program. refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under If any portion of this section is held invalid or unenforceable under any
any particular circumstance, the balance of the section is intended to particular circumstance, the balance of the section is intended to apply,
apply and the section as a whole is intended to apply in other and the section as a whole is intended to apply in other circumstances.
circumstances.
It is not the purpose of this section to induce you to infringe any It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is integrity of the free software distribution system which is
implemented by public license practices. Many people have made implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that through that system in reliance on consistent application of that
@ -474,53 +402,103 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License. be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in 12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License original copyright holder who places the Library under this License may add
may add an explicit geographical distribution limitation excluding an explicit geographical distribution limitation excluding those countries,
those countries, so that distribution is permitted only in or among so that distribution is permitted only in or among countries not thus
countries not thus excluded. In such case, this License incorporates excluded. In such case, this License incorporates the limitation as if
the limitation as if written in the body of this License. written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions 13. The Free Software Foundation may publish revised and/or new
of the General Public License from time to time. Such new versions will versions of the Lesser General Public License from time to time.
be similar in spirit to the present version, but may differ in detail to Such new versions will be similar in spirit to the present version,
address new problems or concerns. but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Program Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and "any specifies a version number of this License which applies to it and
later version", you have the option of following the terms and conditions "any later version", you have the option of following the terms and
either of that version or of any later version published by the Free conditions either of that version or of any later version published by
Software Foundation. If the Program does not specify a version number of the Free Software Foundation. If the Library does not specify a
this License, you may choose any version ever published by the Free Software license version number, you may choose any version ever published by
Foundation. the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free 14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are different, write to the author programs whose distribution conditions are incompatible with these,
to ask for permission. For software which is copyrighted by the Free write to the author to ask for permission. For software which is
Software Foundation, write to the Free Software Foundation; we sometimes copyrighted by the Free Software Foundation, write to the Free
make exceptions for this. Our decision will be guided by the two goals Software Foundation; we sometimes make exceptions for this. Our
of preserving the free status of all derivatives of our free software and decision will be guided by the two goals of preserving the free status
of promoting the sharing and reuse of software generally. of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
REPAIR OR CORRECTION. THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

View file

@ -4,15 +4,15 @@
* @author taggon (gonom9@gmail.com) * @author taggon (gonom9@gmail.com)
*/ */
(function($){ (function($){
var protocol_re = '(https?|ftp|news|telnet|irc)://'; var protocol_re = '(https?|ftp|news|telnet|irc|mms)://';
var domain_re = '(?:[\\w\\-]+\\.)+(?:[a-z]+)'; var domain_re = '(?:[\\w\\-]+\\.)+(?:[a-z]+)';
var max_255_re = '(?:1[0-9]{2}|2[0-4][0-9]|25[0-5])'; var max_255_re = '(?:1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9]?[0-9])';
var ip_re = '(?:'+max_255_re+'\\.){3}'+max_255_re; var ip_re = '(?:'+max_255_re+'\\.){3}'+max_255_re;
var port_re = '(?::([0-9]+))?'; var port_re = '(?::([0-9]+))?';
var path_re = '((?:/[\\w!"$-/:-@]+)*)'; var path_re = '((?:/[\\w!"$-/:-@]+)*)';
var hash_re = '(?:#([\\w!-@]+))?'; var hash_re = '(?:#([\\w!-@]+))?';
var url_regex = new RegExp('('+protocol_re+'('+domain_re+'|'+ip_re+')'+port_re+path_re+hash_re+')', 'ig'); var url_regex = new RegExp('('+protocol_re+'('+domain_re+'|'+ip_re+'|localhost'+')'+port_re+path_re+hash_re+')', 'ig');
var AutoLink = xe.createPlugin("autolink", { var AutoLink = xe.createPlugin("autolink", {
targets : [], targets : [],
@ -65,7 +65,7 @@
if(content.length < 5) return; if(content.length < 5) return;
if(!/(http|https|ftp|news|telnet|irc):\/\//i.test(content)) return; if(!/(http|https|ftp|news|telnet|irc|mms):\/\//i.test(content)) return;
thisPlugin.targets.push(this); thisPlugin.targets.push(this);
} else { } else {

View file

@ -51,7 +51,7 @@ describe('AutoLink functionality', {
value_of( $('#test5').contents().length ).should_be(3); value_of( $('#test5').contents().length ).should_be(3);
}, },
"#test6 - complex example" : function() { "#test6 - complex example" : function() {
value_of( $('#test6 a').length ).should_be(4); value_of( $('#test6 a').length ).should_be(8);
value_of( $('#test6 a').eq(0).attr('href') ).should_be($('#test6 a').eq(0).text()); value_of( $('#test6 a').eq(0).attr('href') ).should_be($('#test6 a').eq(0).text());
value_of( $('#test6 a').eq(2).parent().is('b') ).should_be_true(); value_of( $('#test6 a').eq(2).parent().is('b') ).should_be_true();
value_of( $('#test6 > textarea > a').length ).should_be(0); value_of( $('#test6 > textarea > a').length ).should_be(0);
@ -85,7 +85,7 @@ describe('Autolink trigger', {
<div id="test4">http://www.abc.com/some_program?hello=world&encoded=%ED%C2%C1</div> <div id="test4">http://www.abc.com/some_program?hello=world&encoded=%ED%C2%C1</div>
<div id="test5">Before text. http://www.abc.com/some_program?hello=world&encoded=%ED%C2%C1 After Text</div> <div id="test5">Before text. http://www.abc.com/some_program?hello=world&encoded=%ED%C2%C1 After Text</div>
<div id="test6"> <div id="test6">
This is text. http://www.abc.com/some_program?hello=world&encoded=%ED%C2%C1 Text Text. <p>This is text. http://www.abc.com/some_program?hello=world&encoded=%ED%C2%C1 Text Text.
Another URL : http://www.decccccf12312.co.uk/path/to/program?mymy=lovelove. XE! Another URL : http://www.decccccf12312.co.uk/path/to/program?mymy=lovelove. XE!
<b>Bold text and http://mail.abc.com/path/to/one_cgi.cgi?hello=world#hash_text Bold text end</b> <b>Bold text and http://mail.abc.com/path/to/one_cgi.cgi?hello=world#hash_text Bold text end</b>
<textarea>this text should be ignored http://mygony.com ignored?</textarea> <textarea>this text should be ignored http://mygony.com ignored?</textarea>
@ -94,6 +94,10 @@ describe('Autolink trigger', {
<a href="http://mygony.com" target="_self">http://mygony.com</a> <a href="http://mygony.com" target="_self">http://mygony.com</a>
Sayonara~ Sayonara~
</div> </div>
IP Test http://119.205.243.46 and MMS Link mms://xpressengine.com/a.wmv
http://localhost/some/path/file.ext
Is it OK?</p>
<p>mms://xpressengine.com/a.wmv</p>
</div> </div>
<div id="test7">http://mygony.com</div> <div id="test7">http://mygony.com</div>
<div id="test8">Go to http://mygony.com</div> <div id="test8">Go to http://mygony.com</div>

View file

@ -168,6 +168,7 @@
} }
$content = sprintf( $content = sprintf(
'<?xml version="1.0" encoding="utf-8"?>'.
'<methodResponse>'. '<methodResponse>'.
'<params>'. '<params>'.
'<param>'. '<param>'.
@ -263,8 +264,7 @@
if(!$output->toBool()) { if(!$output->toBool()) {
$content = getXmlRpcFailure(1, $output->getMessage()); $content = getXmlRpcFailure(1, $output->getMessage());
} else { } else {
//$content = getXmlRpcResponse(Context::getRequestUri().$this->mid.'/'.$document_srl); $content = getXmlRpcResponse(strval($document_srl));
$content = getXmlRpcResponse($document_srl);
} }
FileHandler::removeDir($tmp_uploaded_path); FileHandler::removeDir($tmp_uploaded_path);
@ -362,7 +362,7 @@
if(!$output->toBool()) { if(!$output->toBool()) {
$content = getXmlRpcFailure(1, $output->getMessage()); $content = getXmlRpcFailure(1, $output->getMessage());
} else { } else {
$content = getXmlRpcResponse(getFullUrl('','document_srl',$document_srl)); $content = getXmlRpcResponse(true);
FileHandler::removeDir($tmp_uploaded_path); FileHandler::removeDir($tmp_uploaded_path);
} }

View file

@ -102,7 +102,7 @@
exit(); exit();
} }
Context::addJsFile('./addons/captcha/captcha.js',false); Context::addJsFile('./addons/captcha/captcha.min.js',false);
// 게시판/ 이슈트래커의 글쓰기/댓글쓰기 액션 호출시 세션 비교 // 게시판/ 이슈트래커의 글쓰기/댓글쓰기 액션 호출시 세션 비교
if(in_array(Context::get('act'), $target_acts)) { if(in_array(Context::get('act'), $target_acts)) {

8
addons/captcha/captcha.min.js vendored Normal file
View file

@ -0,0 +1,8 @@
/**
* procFilter 함수를 가로채서 captcha 이미지 폼을 출력
**/
var oldExecXml=null;var calledArgs=null;(function($){$(function(){var captchaXE=null;function xeCaptcha(){var body=$(document.body);var captchaIma;if(!captchaXE){captchaXE=$("<div>").attr("id","captcha_screen").css({position:"absolute",display:"none",backgroundColor:"#111",backgroundRepeat:"repeat",backgroundPosition:"0 0",zIndex:500});$('<div id="captchaBox" style="display:none;*zoom:1;overflow:hidden;height:200px;">'+'<img src="about:blank" id="captcha_image" />'+'<p style="color:#666;width:250px;padding:0;margin:10px 0 20px 0; " id="captchaAbout">&nbsp;</p>'+'<p style="color:#DDD;width:250px;font-size:15px;padding:0; margin:0 0 10px; font-weight:bold; text-align:center;" id="captchaText">&nbsp;</p>'+'</div>').appendTo(captchaXE);body.append(captchaXE);captchaXE.exec=function(module,act,params,callback_func,response_tags,callback_func_arg,fo_obj){var doCheck=false;if(typeof(captchaTargetAct)!='undefined'){for(var i in captchaTargetAct){if(captchaTargetAct[i]==act){doCheck=true;break;}}}
if(doCheck){calledArgs={'module':module,'act':act,'params':params,'callback_func':callback_func,'response_tags':response_tags,'callback_func_arg':callback_func_arg,'fo_obj':fo_obj};var params=new Array();params['captcha_action']='setCaptchaSession';params['mid']=current_mid;oldExecXml(module,act,params,captchaXE.show,new Array('error','message','about','keyword'));}else{oldExecXml(module,act,params,callback_func,response_tags,callback_func_arg,fo_obj);}
return true;};captchaXE.show=function(ret_obj){var clientWidth=$(window).width();var clientHeight=$(window).height();$(document).scrollTop(0);$(document).scrollLeft(0);$("#captcha_screen").css({display:"block",width:clientWidth+"px",height:clientHeight+"px",left:0,top:0});$("#captchaAbout").html(ret_obj['about']);$("#captchaText").html(ret_obj['keyword']);$("#captcha_image").css({width:"250px",height:"100px",margin:"0 0 10px 0",cursor:"pointer"}).attr("src",current_url.setQuery('captcha_action','captchaImage').setQuery('rnd',Math.round(Math.random()*6))).click(captchaXE.compare).focus(function(){this.blur();});$("#captchaBox").css({display:"block",border:"10px solid #222222",padding:"10px",position:"absolute",backgroundColor:"#2B2523",left:(clientWidth/2-125)+"px",top:(clientHeight/2-100)+"px"})};captchaXE.compare=function(e){var posX=parseInt($("#captchaBox").css("left").replace(/px$/,''),10);var posY=parseInt($("#captchaBox").css("top").replace(/px$/,''),10);var x=e.pageX-posX-20;var y=e.pageY-posY-20;var params=new Array();params['mx']=x;params['my']=y;params['captcha_action']='captchaCompare';params['mid']=current_mid;oldExecXml(calledArgs.module,calledArgs.act,params,function(){$("#captcha_screen").css({display:"none"});oldExecXml(calledArgs.module,calledArgs.act,calledArgs.params,calledArgs.callback_func,calledArgs.response_tags,calledArgs.callback_func_arg,calledArgs.fo_obj);});};}
return captchaXE;}
$(window).ready(function(){oldExecXml=exec_xml;exec_xml=xeCaptcha().exec;});});})(jQuery);

View file

@ -7,7 +7,7 @@
* @brief 카운터 애드온 * @brief 카운터 애드온
**/ **/
// called_position가 before_display_content 일 경우 실행 // called_position가 before_display_content 일 경우 실행
if(Context::isInstalled() && $called_position == 'before_module_init' && Context::get('module')!='admin') { if(Context::isInstalled() && $called_position == 'before_module_init' && Context::get('module')!='admin' && Context::getResponseMethod() == 'HTML') {
$oCounterController = &getController('counter'); $oCounterController = &getController('counter');
$oCounterController->procCounterExecute(); $oCounterController->procCounterExecute();
} }

View file

@ -0,0 +1,9 @@
/**
* @brief 화면내에서 상위 영역보다 이미지가 크면 리사이즈를 하고 클릭시 원본을 보여줄수 있도록 변경
**/
(function($){var xScreen=null;function getScreen(){var body=$(document.body);var controls,imgframe,closebtn,prevbtn,nextbtn;if(!xScreen){xScreen=$("<div>").attr("id","xe_gallery_screen").css({position:"absolute",display:"none",backgroundColor:"black",zIndex:500,opacity:0.5});controls=$("<div>").attr("id","xe_gallery_controls").css({position:"absolute",display:"none",overflow:"hidden",zIndex:510});closebtn=$("<img>").attr("id","xe_gallery_closebtn").attr("src",request_uri+"addons/resize_image/iconClose.png").css({top:"10px"}).click(function(){xScreen.xeHide()}).appendTo(controls);prevbtn=$("<img>").attr("id","xe_gallery_prevbtn").attr("src",request_uri+"addons/resize_image/iconLeft.png").css("left","10px").click(function(){xScreen.xePrev()}).appendTo(controls);nextbtn=$("<img>").attr("id","xe_gallery_nextbtn").attr("src",request_uri+"addons/resize_image/iconRight.png").css("right","10px").click(function(){xScreen.xeNext()}).appendTo(controls);controls.find("img").attr({width:60,height:60,className:"iePngFix"}).css({position:"absolute",width:"60px",height:"60px",zIndex:530,cursor:"pointer"});imgframe=$("<img>").attr("id","xe_gallery_holder").css("border","7px solid white").css("zIndex",520).appendTo(controls).draggable();body.append(xScreen).append(controls);xScreen.xeShow=function(){var clientWidth=$(window).width();var clientHeight=$(window).height();$("#xe_gallery_controls,#xe_gallery_screen").css({display:"block",width:clientWidth+"px",height:clientHeight+"px",left:$(document).scrollLeft(),top:$(document).scrollTop()});closebtn.css("left",Math.round((clientWidth-60)/2)+"px");$("#xe_gallery_prevbtn,#xe_gallery_nextbtn").css("top",Math.round((clientHeight-60)/2)+"px");this.xeMove(0);};xScreen.xeHide=function(event){xScreen.css("display","none");controls.css("display","none");};xScreen.xePrev=function(){this.xeMove(-1);};xScreen.xeNext=function(){this.xeMove(1);};xScreen.xeMove=function(val){var clientWidth=$(window).width();var clientHeight=$(window).height();this.index+=val;prevbtn.css("visibility",(this.index>0)?"visible":"hidden");nextbtn.css("visibility",(this.index<this.list.size()-1)?"visible":"hidden");var src=this.list.eq(this.index).attr("rawsrc");if(!src)src=this.list.eq(this.index).attr("src");imgframe.attr("src",src).css({left:Math.round(Math.max((clientWidth-imgframe.width()-14)/2,0))+"px",top:Math.round(Math.max((clientHeight-imgframe.height()-14)/2,0))+"px"});};$(document).scroll(xScreen.xeHide);$(document).keydown(xScreen.xeHide);$(window).resize(xScreen.xeHide);$(window).scroll(xScreen.xeHide);}else{controls=$("#xe_gallery_controls");imgframe=$("#xe_gallery_holder");closebtn=$("#xe_gallery_closebtn");prevbtn=$("#xe_gallery_prevbtn");nextbtn=$("#xe_gallery_nextbtn");}
return xScreen;}
function slideshow(event){var container=$(this).parents(".xe_content");var imglist=container.find("img[rel=xe_gallery]");var currentIdx=$.inArray($(this).get(0),imglist.get());var xScreen=getScreen();xScreen.list=imglist;xScreen.index=currentIdx;xScreen.xeShow();}
$(function(){var regx_skip=/(?:(modules|addons|classes|common|layouts|libs|widgets|widgetstyles)\/)/i;var regx_allow_i6pngfix=/(?:common\/tpl\/images\/blank\.gif$)/i;var dummy=$('<div style="height:1; overflow:hidden; opacity:0; display:block; clear:both;"></div>');function doResize(contentWidth,count){if(!count)count=0;if(count>=10)return;var $img=this;var beforSize={'width':$img.width(),'height':$img.height()};if(!beforSize.width||!beforSize.height){setTimeout(function(){doResize.call($img,contentWidth,++count)},200);return;}
if(beforSize.width<=contentWidth)return;var resize_ratio=contentWidth/beforSize.width;$img.removeAttr('width').removeAttr('height').css({'width':contentWidth,'height':parseInt(beforSize.height*resize_ratio,10)});}
$('div.xe_content').each(function(){dummy.appendTo(this);var contentWidth=dummy.width();dummy.remove();if(!contentWidth)return;$('img',this).each(function(){var $img=$(this);var imgSrc=$img.attr('src');if(regx_skip.test(imgSrc)&&!regx_allow_i6pngfix.test(imgSrc))return;$img.attr('rel','xe_gallery');doResize.call($img,contentWidth);});$('img[rel=xe_gallery]',this).live('mouseover',function(){var $img=$(this);if(!$img.parent('a').length&&!$img.attr('onclick')){$img.css('cursor','pointer').click(slideshow);}});});});})(jQuery);

View file

@ -9,6 +9,6 @@
if($called_position == 'after_module_proc' && Context::getResponseMethod()=="HTML") { if($called_position == 'after_module_proc' && Context::getResponseMethod()=="HTML") {
Context::loadJavascriptPlugin('ui'); Context::loadJavascriptPlugin('ui');
Context::addJsFile('./addons/resize_image/js/resize_image.js',false); Context::addJsFile('./addons/resize_image/js/resize_image.min.js',false);
} }
?> ?>

View file

@ -2,11 +2,10 @@
if(!defined("__ZBXE__")) exit(); if(!defined("__ZBXE__")) exit();
if(Context::get('module')=='admin') return; if(Context::get('module')=='admin') return;
require_once(_XE_PATH_.'addons/smartphone/classes/smartphone.class.php');
if($called_position == "before_module_init") if($called_position == "before_module_init")
{ {
require(_XE_PATH_.'addons/smartphone/classes/smartphone.class.php');
if(Context::get('full_browse')) if(Context::get('full_browse'))
{ {
setcookie("FullBrowse", 1); setcookie("FullBrowse", 1);

View file

@ -2,9 +2,9 @@
/** /**
* @class Context * @class Context
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief Request Argument/환경변수등의 모든 Context를 관리 * @brief Manages Context such as request arguments/environment variables
* Context 클래스는 Context::methodname() 처럼 쉽게 사용하기 위해 만들어진 객체를 받아서 * @remarks It has dual method structure, easy-to use methods which can be called as Context::methodname(),
* 호출하는 구조를 위해 이중 method 구조를 가지고 있다. * and methods called with static object.
**/ **/
define('FOLLOW_REQUEST_SSL',0); define('FOLLOW_REQUEST_SSL',0);
@ -13,44 +13,42 @@
class Context { class Context {
var $allow_rewrite = false; ///< @brief rewrite mod 사용에 대한 변수 var $allow_rewrite = false; ///< true: using rewrite mod, false: otherwise
var $request_method = 'GET'; ///< @brief GET/POST/XMLRPC 중 어떤 방식으로 요청이 왔는지에 대한 값이 세팅. GET/POST/XML 3가지가 있음 var $request_method = 'GET';///< request method(GET/POST/XMLRPC)
var $response_method = ''; ///< @brief HTML/XMLRPC 중 어떤 방식으로 결과를 출력할지 결정. (강제 지정전까지는 request_method를 따름) var $response_method = ''; ///< response method(HTML/XMLRPC). If it's not set, it follows request method.
var $context = NULL; ///< @brief request parameter 및 각종 환경 변수등을 정리하여 담을 변수 var $context = NULL; ///< conatins request parameters and environment variables
var $db_info = NULL; ///< @brief DB 정보 var $db_info = NULL; ///< DB info.
var $ftp_info = NULL; ///< @brief FTP 정보 var $ftp_info = NULL; ///< FTP info.
var $ssl_actions = array(); ///< @brief ssl로 전송해야 할 action등록 (common/js/xml_handler.js에서 ajax통신시 활용) var $ssl_actions = array(); ///< list of actions to be sent via ssl (it is used by javascript xml handler for ajax)
var $js_files = array(); ///< @brief display시에 사용하게 되는 js files의 목록 var $js_files = array(); ///< list of javascript files used for display
var $css_files = array(); ///< @brief display시에 사용하게 되는 css files의 목록 var $css_files = array(); ///< list of css files used for display
var $html_header = NULL; ///< @brief display시에 사용하게 되는 <head>..</head>내의 스크립트코드 var $html_header = NULL; ///< script codes in <head>..</head>
var $body_class = array(); ///< @brief display시에 사용하게 되는 <body> 안에 출력될 class var $body_class = array(); ///< classnames of <body>
var $body_header = NULL; ///< @brief display시에 사용하게 되는 <body> 바로 다음에 출력될 스크립트 코드 var $body_header = NULL; ///< codes after <body>
var $html_footer = NULL; ///< @brief display시에 사용하게 되는 </body> 바로 앞에 추가될 코드 var $html_footer = NULL; ///< codes before </body>
var $path = ''; ///< zbxe의 경로 var $path = ''; ///< path of Xpress Engine
// language information - it is changed by HTTP_USER_AGENT or user's cookie
var $lang_type = ''; ///< language type
var $lang = NULL; ///< contains language-specific data
var $loaded_lang_files = array(); ///< list of loaded languages (to avoid re-loading them)
var $site_title = ''; ///< site's browser title
var $get_vars = NULL; ///< variables from GET or form submit
var $is_uploaded = false; ///< true if attached file exists
/** /**
* @brief 언어 정보 * @brief return static context object (Singleton)
* 기본으로 ko. HTTP_USER_AGENT나 사용자의 직접 세팅(쿠키이용)등을 통해 변경됨 * @return object
**/ * @remarks it's to use Context without declaration of an object
var $lang_type = ''; ///< 언어 종류
var $lang = NULL; ///< 언어 데이터를 담고 있는 변수
var $loaded_lang_files = array(); ///< 로딩된 언어파일의 목록 (재로딩을 피하기 위함)
var $site_title = ''; ///< @brief 현 사이트의 browser title. Context::setBrowserTitle() 로 변경 가능
var $get_vars = NULL; ///< @brief form이나 get으로 요청이 들어온 변수만 별도로 관리
var $is_uploaded = false; ///< @brief 첨부파일이 업로드 된 요청이였는지에 대한 체크 플래그
/**
* @brief 유일한 Context 객체를 반환 (Singleton)
* Context는 어디서든 객체 선언없이 사용하기 위해서 static 하게 사용
**/ **/
function &getInstance() { function &getInstance() {
static $theInstance; static $theInstance;
@ -59,33 +57,30 @@
} }
/** /**
* @brief DB정보, Request Argument등을 세팅 * @brief initialization, it sets DB information, request arguments and so on.
* Context::init() 한번만 호출되어야 하며 init()시에 Request Argument, DB/언어/세션정보등의 모든 정보를 세팅한다 * @return none
* @remarks this function should be called only once
**/ **/
function init() { function init() {
// context 변수를 $GLOBALS의 변수로 지정 // set context variables in $GLOBALS (to use in display handler)
$this->context = &$GLOBALS['__Context__']; $this->context = &$GLOBALS['__Context__'];
$this->context->lang = &$GLOBALS['lang']; $this->context->lang = &$GLOBALS['lang'];
$this->context->_COOKIE = $_COOKIE; $this->context->_COOKIE = $_COOKIE;
// Request Method 설정
$this->_setRequestMethod(); $this->_setRequestMethod();
// Request Argument 설정
$this->_setXmlRpcArgument(); $this->_setXmlRpcArgument();
$this->_setJSONRequestArgument(); $this->_setJSONRequestArgument();
$this->_setRequestArgument(); $this->_setRequestArgument();
$this->_setUploadedArgument(); $this->_setUploadedArgument();
// 기본적인 DB정보 세팅
$this->_loadDBInfo(); $this->_loadDBInfo();
// 설치가 되어 있다면 가상 사이트 정보를 구함 // If XE is installed, get virtual site information
if(Context::isInstalled()) { if(Context::isInstalled()) {
// site_module_info를 구함
$oModuleModel = &getModel('module'); $oModuleModel = &getModel('module');
$site_module_info = $oModuleModel->getDefaultMid(); $site_module_info = $oModuleModel->getDefaultMid();
// site_module_info의 site_srl = 0 일 경우 db_config의 default_url과 비교 // if site_srl of site_module_info is 0 (default site), compare the domain to default_url of db_config
if($site_module_info->site_srl == 0 && $site_module_info->domain != $this->db_info->default_url) { if($site_module_info->site_srl == 0 && $site_module_info->domain != $this->db_info->default_url) {
$site_module_info->domain = $this->db_info->default_url; $site_module_info->domain = $this->db_info->default_url;
} }
@ -97,26 +92,26 @@
if(!$this->db_info->lang_type) $this->db_info->lang_type = 'en'; if(!$this->db_info->lang_type) $this->db_info->lang_type = 'en';
} }
// 언어 파일 불러오기 // Load Language File
$lang_supported = $this->loadLangSelected(); $lang_supported = $this->loadLangSelected();
// 사용자의 쿠키 설정된 언어 타입 추출 // Retrieve language type set in user's cookie
if($_COOKIE['lang_type']) $this->lang_type = $_COOKIE['lang_type']; if($_COOKIE['lang_type']) $this->lang_type = $_COOKIE['lang_type'];
// 사용자 설정 언어 타입이 없으면 기본 언어타입으로 지정 // If it's not exists, follow default language type set in db_info
if(!$this->lang_type) $this->lang_type = $this->db_info->lang_type; if(!$this->lang_type) $this->lang_type = $this->db_info->lang_type;
// 관리자 설정 언어값에 등록된 것이 아니라면 기본 언어로 변경 // if still lang_type has not been set or has not-supported type , set as English.
if(!$this->lang_type) $this->lang_type = "en"; if(!$this->lang_type) $this->lang_type = "en";
if(is_array($lang_supported)&&!isset($lang_supported[$this->lang_type])) $this->lang_type = 'en'; if(is_array($lang_supported)&&!isset($lang_supported[$this->lang_type])) $this->lang_type = 'en';
Context::set('lang_supported', $lang_supported); Context::set('lang_supported', $lang_supported);
$this->setLangType($this->lang_type); $this->setLangType($this->lang_type);
// module의 언어파일 강제 로드 (언어 type에 맞춰서) // load module module's language file according to language setting
$this->loadLang(_XE_PATH_.'modules/module/lang'); $this->loadLang(_XE_PATH_.'modules/module/lang');
// 세션 핸들러 지정 // set session handler
if($this->db_info->use_db_session != 'N') { if($this->db_info->use_db_session != 'N') {
$oSessionModel = &getModel('session'); $oSessionModel = &getModel('session');
$oSessionController = &getController('session'); $oSessionController = &getController('session');
@ -132,18 +127,16 @@
session_start(); session_start();
// 인증 관련 정보를 Context와 세션에 설정 // set authentication information in Context and session
if(Context::isInstalled()) { if(Context::isInstalled()) {
// 인증관련 데이터를 Context에 설정
$oMemberModel = &getModel('member'); $oMemberModel = &getModel('member');
$oMemberController = &getController('member'); $oMemberController = &getController('member');
// 인증이 되어 있을 경우 유효성 체크 // if signed in, validate it.
if($oMemberModel->isLogged()) { if($oMemberModel->isLogged()) {
$oMemberController->setSessionInfo(); $oMemberController->setSessionInfo();
}
// 인증이 되어 있지 않을 경우 자동 로그인 확인 elseif($_COOKIE['xeak']) { // check auto sign-in
} elseif($_COOKIE['xeak']) {
$oMemberController->doAutologin(); $oMemberController->doAutologin();
} }
@ -151,15 +144,15 @@
$this->_set('logged_info', $oMemberModel->getLoggedInfo() ); $this->_set('logged_info', $oMemberModel->getLoggedInfo() );
} }
// 기본 언어파일 로드 // load common language file
$this->lang = &$GLOBALS['lang']; $this->lang = &$GLOBALS['lang'];
$this->_loadLang(_XE_PATH_."common/lang/"); $this->_loadLang(_XE_PATH_."common/lang/");
// rewrite 모듈사용 상태 체크 // check if using rewrite module
if(file_exists(_XE_PATH_.'.htaccess')&&$this->db_info->use_rewrite == 'Y') $this->allow_rewrite = true; if(file_exists(_XE_PATH_.'.htaccess')&&$this->db_info->use_rewrite == 'Y') $this->allow_rewrite = true;
else $this->allow_rewrite = false; else $this->allow_rewrite = false;
// 기본 JS/CSS 등록 // add common JS/CSS files
$this->addJsFile("./common/js/jquery.js"); $this->addJsFile("./common/js/jquery.js");
$this->addJsFile("./common/js/x.js"); $this->addJsFile("./common/js/x.js");
$this->addJsFile("./common/js/common.js"); $this->addJsFile("./common/js/common.js");
@ -169,10 +162,10 @@
$this->addCSSFile("./common/css/default.css"); $this->addCSSFile("./common/css/default.css");
$this->addCSSFile("./common/css/button.css"); $this->addCSSFile("./common/css/button.css");
// 관리자 페이지일 경우 관리자 공용 CSS 추가 // for admin page, add admin css
if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0) $this->addCssFile("./modules/admin/tpl/css/admin.css", false); if(Context::get('module')=='admin' || strpos(Context::get('act'),'Admin')>0) $this->addCssFile("./modules/admin/tpl/css/admin.css", false);
// rewrite module때문에 javascript에서 location.href 문제 해결을 위해 직접 실제 경로 설정 // set locations for javascript use
if($_SERVER['REQUEST_METHOD'] == 'GET') { if($_SERVER['REQUEST_METHOD'] == 'GET') {
if($this->get_vars) { if($this->get_vars) {
foreach($this->get_vars as $key => $val) { foreach($this->get_vars as $key => $val) {
@ -196,7 +189,8 @@
} }
/** /**
* @brief DB및 기타 자원들의 close * @brief finalize using resources, such as DB connection
* @return none
**/ **/
function close() { function close() {
// Session Close // Session Close
@ -208,7 +202,8 @@
} }
/** /**
* @brief DB의 기타 정보 load * @brief load DB information
* @return none
**/ **/
function loadDBInfo() { function loadDBInfo() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -216,12 +211,12 @@
} }
/** /**
* @brief DB 정보를 설정하고 DB Type과 DB 정보를 return * @brief load DB information
* @return none
**/ **/
function _loadDBInfo() { function _loadDBInfo() {
if(!$this->isInstalled()) return; if(!$this->isInstalled()) return;
// db 정보 설정
$db_config_file = $this->getConfigFile(); $db_config_file = $this->getConfigFile();
if(file_exists($db_config_file)) @include($db_config_file); if(file_exists($db_config_file)) @include($db_config_file);
@ -248,7 +243,8 @@
} }
/** /**
* @brief DB의 db_type을 return * @brief get DB's db_type
* @return DB's db_type string
**/ **/
function getDBType() { function getDBType() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -256,14 +252,17 @@
} }
/** /**
* @brief DB의 db_type을 return * @brief get DB's db_type
* @return DB's db_type string
**/ **/
function _getDBType() { function _getDBType() {
return $this->db_info->db_type; return $this->db_info->db_type;
} }
/** /**
* @brief DB 정보가 담긴 object를 return * @brief set DB information
* @param[in] DB information object
* @return none
**/ **/
function setDBInfo($db_info) { function setDBInfo($db_info) {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -271,14 +270,17 @@
} }
/** /**
* @brief DB 정보가 담긴 object를 return * @brief set DB information
* @param[in] DB information object
* @return none
**/ **/
function _setDBInfo($db_info) { function _setDBInfo($db_info) {
$this->db_info = $db_info; $this->db_info = $db_info;
} }
/** /**
* @brief DB 정보가 담긴 object를 return * @brief get DB information
* @return DB information object
**/ **/
function getDBInfo() { function getDBInfo() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -286,14 +288,16 @@
} }
/** /**
* @brief DB 정보가 담긴 object를 return * @brief get DB information
* @return DB information object
**/ **/
function _getDBInfo() { function _getDBInfo() {
return $this->db_info; return $this->db_info;
} }
/** /**
* @brief 기본 URL을 return * @brief return default URL
* @return default URL string
**/ **/
function getDefaultUrl() { function getDefaultUrl() {
$db_info = Context::getDBInfo(); $db_info = Context::getDBInfo();
@ -301,7 +305,8 @@
} }
/** /**
* @brief 지원되는 언어 파일 찾기 * @brief find supported languages
* @return array of supported languages
**/ **/
function loadLangSupported() { function loadLangSupported() {
static $lang_supported = null; static $lang_supported = null;
@ -317,7 +322,8 @@
} }
/** /**
* @brief 설정한 언어 파일 찾기 * @brief find selected languages to serve in the site
* @return array of selected languages
**/ **/
function loadLangSelected() { function loadLangSelected() {
static $lang_selected = null; static $lang_selected = null;
@ -349,18 +355,20 @@
} }
/** /**
* @brief SSO URL이 설정되어 있고 아직 SSO URL검사를 하지 않았다면 return true * @brief Single Sign On (SSO)
* @return true if module handleing is necessary in the control path of current request
**/ **/
function checkSSO() { function checkSSO() {
// GET 접속이 아니거나 설치가 안되어 있으면 패스 // pass if it's not GET request or XE is not yet installed
if(isCrawler()) return true;
if(Context::getRequestMethod()!='GET' || !Context::isInstalled() || in_array(Context::get('act'),array('rss','atom'))) return true; if(Context::getRequestMethod()!='GET' || !Context::isInstalled() || in_array(Context::get('act'),array('rss','atom'))) return true;
// DB info에 설정된 Default URL이 없다면 무조건 무사통과 // pass if default URL is not set
$default_url = trim($this->db_info->default_url); $default_url = trim($this->db_info->default_url);
if(!$default_url) return true; if(!$default_url) return true;
if(substr($default_url,-1)!='/') $default_url .= '/'; if(substr($default_url,-1)!='/') $default_url .= '/';
// SSO 검증을 요청 받는 사이트 // for sites recieving SSO valdiation
if($default_url == Context::getRequestUri()) { if($default_url == Context::getRequestUri()) {
if(Context::get('default_url')) { if(Context::get('default_url')) {
$url = base64_decode(Context::get('default_url')); $url = base64_decode(Context::get('default_url'));
@ -370,9 +378,9 @@
header("location:".$redirect_url); header("location:".$redirect_url);
return false; return false;
} }
// SSO 검증을 요청하는 사이트 // for sites requesting SSO validation
} else { } else {
// SSO 결과를 받는 경우 session_name() 세팅 // result handling : set session_name()
if(Context::get('SSOID')) { if(Context::get('SSOID')) {
$session_name = Context::get('SSOID'); $session_name = Context::get('SSOID');
setcookie(session_name(), $session_name); setcookie(session_name(), $session_name);
@ -380,7 +388,7 @@
$url = preg_replace('/([\?\&])$/','',str_replace('SSOID='.$session_name,'',Context::getRequestUrl())); $url = preg_replace('/([\?\&])$/','',str_replace('SSOID='.$session_name,'',Context::getRequestUrl()));
header("location:".$url); header("location:".$url);
return false; return false;
// SSO 결과를 요청 // send SSO request
} else if($_COOKIE['sso']!=md5(Context::getRequestUri()) && !Context::get('SSOID')) { } else if($_COOKIE['sso']!=md5(Context::getRequestUri()) && !Context::get('SSOID')) {
setcookie('sso',md5(Context::getRequestUri()),0,'/'); setcookie('sso',md5(Context::getRequestUri()),0,'/');
$url = sprintf("%s?default_url=%s", $default_url, base64_encode(Context::getRequestUrl())); $url = sprintf("%s?default_url=%s", $default_url, base64_encode(Context::getRequestUrl()));
@ -393,7 +401,8 @@
} }
/** /**
* @biref FTP 정보가 등록되었는지 확인 * @biref check if FTP info is registered
* @return true: FTP information is registered, false: otherwise
**/ **/
function isFTPRegisted() { function isFTPRegisted() {
$ftp_config_file = Context::getFTPConfigFile(); $ftp_config_file = Context::getFTPConfigFile();
@ -402,7 +411,8 @@
} }
/** /**
* @brief FTP 정보가 담긴 object를 return * @brief get FTP information object
* @return FTP information object
**/ **/
function getFTPInfo() { function getFTPInfo() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -410,7 +420,8 @@
} }
/** /**
* @brief FTP 정보가 담긴 object를 return * @brief get FTP information object
* @return FTP information object
**/ **/
function _getFTPInfo() { function _getFTPInfo() {
if(!$this->isFTPRegisted()) return null; if(!$this->isFTPRegisted()) return null;
@ -421,7 +432,9 @@
} }
/** /**
* @brief 사이트 title adding * @brief add string to browser title
* @param[in] $site_title string to be added
* @return none
**/ **/
function addBrowserTitle($site_title) { function addBrowserTitle($site_title) {
if(!$site_title) return; if(!$site_title) return;
@ -430,7 +443,9 @@
} }
/** /**
* @brief 사이트 title adding * @brief add string to browser title
* @param[in] $site_title string to be added
* @return none
**/ **/
function _addBrowserTitle($site_title) { function _addBrowserTitle($site_title) {
if($this->site_title) $this->site_title .= ' - '.$site_title; if($this->site_title) $this->site_title .= ' - '.$site_title;
@ -438,7 +453,9 @@
} }
/** /**
* @brief 사이트 title setting * @brief set string to browser title
* @param[in] $site_title string to be set
* @return none
**/ **/
function setBrowserTitle($site_title) { function setBrowserTitle($site_title) {
if(!$site_title) return; if(!$site_title) return;
@ -447,14 +464,17 @@
} }
/** /**
* @brief 사이트 title setting * @brief set string to browser title
* @param[in] $site_title string to be set
* @return none
**/ **/
function _setBrowserTitle($site_title) { function _setBrowserTitle($site_title) {
$this->site_title = $site_title; $this->site_title = $site_title;
} }
/** /**
* @brief 사이트 title return * @brief get browser title
* @return browser title string (htmlspecialchars applied)
**/ **/
function getBrowserTitle() { function getBrowserTitle() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -462,7 +482,8 @@
} }
/** /**
* @brief 사이트 title return * @brief get browser title
* @return browser title string
**/ **/
function _getBrowserTitle() { function _getBrowserTitle() {
$oModuleController = &getController('module'); $oModuleController = &getController('module');
@ -471,7 +492,9 @@
} }
/** /**
* @brief 지정된 언어파일 로드 * @brief load language file according to language type
* @param[in] $path path of the language file
* @return none
**/ **/
function loadLang($path) { function loadLang($path) {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -479,9 +502,10 @@
} }
/** /**
* @brief 지정된 언어파일 로드 * @brief load language file according to language type
* * @param[in] $path path of the language file
* loaded_lang_files 변수를 이용하여 한번 로드된 파일을 다시 로드하지 않음 * @return none
* @remarks using $loaded_lang_files it does not load once-loaded files
**/ **/
function _loadLang($path) { function _loadLang($path) {
global $lang; global $lang;
@ -497,7 +521,8 @@
} }
/** /**
* @brief lang_type을 세팅 (기본 ko) * @brief set lang_type
* @return none
**/ **/
function setLangType($lang_type = 'ko') { function setLangType($lang_type = 'ko') {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -506,7 +531,8 @@
} }
/** /**
* @brief lang_type을 세팅 (기본 ko) * @brief set lang_type
* @return none
**/ **/
function _setLangType($lang_type = 'ko') { function _setLangType($lang_type = 'ko') {
$this->lang_type = $lang_type; $this->lang_type = $lang_type;
@ -514,7 +540,8 @@
} }
/** /**
* @brief lang_type을 return * @brief get lang_type
* @return lang_type string
**/ **/
function getLangType() { function getLangType() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -522,16 +549,17 @@
} }
/** /**
* @brief lang_type을 return * @brief get lang_type
* @return lang_type string
**/ **/
function _getLangType() { function _getLangType() {
return $this->lang_type; return $this->lang_type;
} }
/** /**
* @brief code에 해당하는 문자열을 return * @brief return string accoring to the inputed code
* * @param[in] $code language variable name
* 만약 code에 해당하는 문자열이 없다면 code를 그대로 리턴 * @return if string for the code exists returns it, otherwise returns original code
**/ **/
function getLang($code) { function getLang($code) {
if(!$code) return; if(!$code) return;
@ -540,14 +568,17 @@
} }
/** /**
* @brief 직접 lang 변수에 데이터를 추가 * @brief set data to lang variable
* @return none
**/ **/
function setLang($code, $val) { function setLang($code, $val) {
$GLOBALS['lang']->{$code} = $val; $GLOBALS['lang']->{$code} = $val;
} }
/** /**
* @brief object내의 variables의 문자열을 utf8로 변경 * @brief convert strings of variables in $source_object into UTF-8
* @param[in] $source_obj object conatins strings to convert
* @return converted object
**/ **/
function convertEncoding($source_obj) { function convertEncoding($source_obj) {
$charset_list = array( $charset_list = array(
@ -580,7 +611,9 @@
} }
/** /**
* @brief 특정 문자열만 utf-8 변경 * @brief convert strings into UTF-8
* @param[in] $str string to convert
* @return converted string
**/ **/
function convertEncodingStr($str) { function convertEncodingStr($str) {
$obj->str = $str; $obj->str = $str;
@ -589,30 +622,37 @@
} }
/** /**
* @brief response method강제로 지정 (기본으로는 request method를 이용함) * @brief force to set response method
* * @param[in] $method response method (HTML/XMLRPC/JSON)
* method의 종류에는 HTML/ TEXT/ XMLRPC/ JSON가 있음 * @return none
**/ **/
function setResponseMethod($method = "HTML") { function setResponseMethod($method = "HTML") {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
return $oContext->_setResponseMethod($method); return $oContext->_setResponseMethod($method);
} }
/**
* @brief force to set response method
* @param[in] $method response method (HTML/XMLRPC/JSON)
* @return none
**/
function _setResponseMethod($method = "HTML") { function _setResponseMethod($method = "HTML") {
$this->response_method = $method; $this->response_method = $method;
} }
/** /*
* @brief response method 값을 return * @brief get reponse method
* * @return response method string (if it's not set, returns request method)
* method의 종류에는 HTML/ TEXT/ XMLRPC가 있음 */
* 별도로 response method를 지정하지 않았다면 request method로 판단하여 결과 return
**/
function getResponseMethod() { function getResponseMethod() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
return $oContext->_getResponseMethod(); return $oContext->_getResponseMethod();
} }
/*
* @brief get reponse method
* @return response method string (if it's not set, returns request method)
*/
function _getResponseMethod() { function _getResponseMethod() {
if($this->response_method) return $this->response_method; if($this->response_method) return $this->response_method;
@ -623,7 +663,9 @@
} }
/** /**
* @brief request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC/JSON) * @brief determine request method (GET/POST/XMLRPC/JSON)
* @param[in] $type request method
* @return none
**/ **/
function setRequestMethod($type) { function setRequestMethod($type) {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -632,7 +674,9 @@
/** /**
* @brief request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC/JSON) * @brief deteremine request method (GET/POST/XMLRPC/JSON)
* @param[in] $type request method
* @return none
**/ **/
function _setRequestMethod($type = '') { function _setRequestMethod($type = '') {
if($type) return $this->request_method = $type; if($type) return $this->request_method = $type;
@ -644,7 +688,8 @@
} }
/** /**
* @brief GET/POST방식일 경우 처리 * @brief handle request areguments for GET/POST
* @return none
**/ **/
function _setRequestArgument() { function _setRequestArgument() {
if(!count($_REQUEST)) return; if(!count($_REQUEST)) return;
@ -660,11 +705,11 @@
} }
/** /**
* @brief JSON 방식일 경우 처리 * @brief handle request arguments for JSON
* @return none
**/ **/
function _setJSONRequestArgument() { function _setJSONRequestArgument() {
if($this->_getRequestMethod() != 'JSON') return; if($this->_getRequestMethod() != 'JSON') return;
// if(!$GLOBALS['HTTP_RAW_POST_DATA']) return;
$params = array(); $params = array();
parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$params); parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$params);
@ -676,7 +721,8 @@
} }
/** /**
* @brief XML RPC일때 * @brief handle request arguments for XML RPC
* @return none
**/ **/
function _setXmlRpcArgument() { function _setXmlRpcArgument() {
if($this->_getRequestMethod() != 'XMLRPC') return; if($this->_getRequestMethod() != 'XMLRPC') return;
@ -695,8 +741,12 @@
} }
/** /**
* @brief 변수명에 따라서 필터링 처리 * @brief Filter request variable
* _srl, page, cpage등의 변수는 integer로 형변환 * @param[in] $key variable key
* @param[in] $val variable value
* @param[in] $do_stripslashes whether to strip slashes
* @remarks cast variables, such as _srl, page, and cpage, into interger
* @return filtered value
**/ **/
function _filterRequestVar($key, $val, $do_stripslashes = 1) { function _filterRequestVar($key, $val, $do_stripslashes = 1) {
if( ($key == "page" || $key == "cpage" || substr($key,-3)=="srl")) return !preg_match('/^[0-9,]+$/',$val)?(int)$val:$val; if( ($key == "page" || $key == "cpage" || substr($key,-3)=="srl")) return !preg_match('/^[0-9,]+$/',$val)?(int)$val:$val;
@ -714,7 +764,8 @@
} }
/** /**
* @brief 업로드 되었을 경우 return true * @brief Check if there exists uploaded file
* @return true: exists, false: otherwise
**/ **/
function isUploaded() { function isUploaded() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -722,14 +773,16 @@
} }
/** /**
* @brief 업로드 되었을 경우 return true * @brief Check if there exists uploaded file
* @return true: exists, false: otherwise
**/ **/
function _isUploaded() { function _isUploaded() {
return $this->is_uploaded; return $this->is_uploaded;
} }
/** /**
* @brief 업로드된 파일이 있을 경우도 역시 context에 통합 처리 ( 정상적인 업로드인지 체크) * @brief handle uploaded file
* @return none
**/ **/
function _setUploadedArgument() { function _setUploadedArgument() {
if($this->_getRequestMethod() != 'POST') return; if($this->_getRequestMethod() != 'POST') return;
@ -745,7 +798,8 @@
} }
/** /**
* @brief Request Method값을 return (GET/POST/XMLRPC/JSON); * @brief return request method (GET/POST/XMLRPC/JSON);
* @return request method type
**/ **/
function getRequestMethod() { function getRequestMethod() {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -753,21 +807,23 @@
} }
/** /**
* @brief Request Method값을 return (GET/POST/XMLRPC/JSON); * @brief return request method (GET/POST/XMLRPC/JSON);
* @return request method type
**/ **/
function _getRequestMethod() { function _getRequestMethod() {
return $this->request_method; return $this->request_method;
} }
/** /**
* @brief 현재 요청된 full url을 return * @brief return request URL
* @return request URL
**/ **/
function getRequestUrl() { function getRequestUrl() {
static $url = null; static $url = null;
if(is_null($url)) { if(is_null($url)) {
$url = Context::getRequestUri(); $url = Context::getRequestUri();
if(count($_GET)) { if(count($_GET)) {
foreach($_GET as $key => $val) $vars[] = $key.'='.$val; foreach($_GET as $key => $val) $vars[] = $key.'='.urlencode(Context::convertEncodingStr($val));
$url .= '?'.implode('&',$vars); $url .= '?'.implode('&',$vars);
} }
} }
@ -775,7 +831,8 @@
} }
/** /**
* @brief 요청받은 url에 args_list를 적용하여 return * @brief make URL with args_list upon request URL
* @return result URL
**/ **/
function getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) { function getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) {
$oContext = &Context::getInstance(); $oContext = &Context::getInstance();
@ -783,28 +840,29 @@
} }
/** /**
* @brief 요청받은 url에 args_list를 적용하여 return * @brief make URL with args_list upon request URL
* @return result URL
**/ **/
function _getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) { function _getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) {
static $site_module_info = null; static $site_module_info = null;
static $current_info = null; static $current_info = null;
// 가상 사이트 정보를 구함 // retrieve virtual site information
if(is_null($site_module_info)) $site_module_info = Context::get('site_module_info'); if(is_null($site_module_info)) $site_module_info = Context::get('site_module_info');
// SiteID 요청시 전처리 ($domain이 vid 형식일 경우 $domain값을 없애고 vid로 처리하도록 함) // If $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid)
if($domain && isSiteID($domain)) { if($domain && isSiteID($domain)) {
$vid = $domain; $vid = $domain;
$domain = ''; $domain = '';
} }
// $domain, $vid값이 없을 경우(= 현재 사이트 정보를 이용함) // If $domain, $vid are not set, use current site information
if(!$domain && !$vid) { if(!$domain && !$vid) {
if($site_module_info->domain && isSiteID($site_module_info->domain)) $vid = $site_module_info->domain; if($site_module_info->domain && isSiteID($site_module_info->domain)) $vid = $site_module_info->domain;
else $domain = $site_module_info->domain; else $domain = $site_module_info->domain;
} }
// $domain값이 있을 경우 현재 요청된 도메인과 비교해서 동일할 경우 제거 그렇지 않으면 http 프로토콜을 제거하고 제일 뒤에 / 를 붙임 // if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain.
if($domain) { if($domain) {
$domain_info = parse_url($domain); $domain_info = parse_url($domain);
if(is_null($current_info)) $current_info = parse_url(($_SERVER['HTTPS']=='on'?'https':'http').'://'.$_SERVER['HTTP_HOST'].getScriptPath()); if(is_null($current_info)) $current_info = parse_url(($_SERVER['HTTPS']=='on'?'https':'http').'://'.$_SERVER['HTTP_HOST'].getScriptPath());
@ -816,38 +874,37 @@
} }
} }
// 변수 정리
$get_vars = null; $get_vars = null;
// GET 변수가 없거나 변수 초기화 지정이 되었을 경우 // If there is no GET variables or first argument is '' to reset variables
if(!$this->get_vars || $args_list[0]=='') { if(!$this->get_vars || $args_list[0]=='') {
// 요청받은 변수가 있고 첫번째 인자가 '' 라서 초기화를 해야 할 경우 요청받은 변수를 정리 // rearrange args_list
if(is_array($args_list) && $args_list[0]=='') array_shift($args_list); if(is_array($args_list) && $args_list[0]=='') array_shift($args_list);
// 초기화를 원하지 않을 경우 GET 변수를 배열로 처리
} else { } else {
// Otherwise, make GET variables into array
$get_vars = get_object_vars($this->get_vars); $get_vars = get_object_vars($this->get_vars);
} }
// 새로 꾸미기를 원하는 변수를 정리 // arrange args_list
for($i=0,$c=count($args_list);$i<$c;$i=$i+2) { for($i=0,$c=count($args_list);$i<$c;$i=$i+2) {
$key = $args_list[$i]; $key = $args_list[$i];
$val = trim($args_list[$i+1]); $val = trim($args_list[$i+1]);
// 값이 없으면 GET변수에서 해당 키를 제거 // If value is not set, remove the key
if(!isset($val) || strlen($val)<1) { if(!isset($val) || strlen($val)<1) {
unset($get_vars[$key]); unset($get_vars[$key]);
continue; continue;
} }
// 새로운 변수를 정리 // set new variables
$get_vars[$key] = $val; $get_vars[$key] = $val;
} }
// 변수중 vid, rnd값 제거 // remove vid, rnd
unset($get_vars['rnd']); unset($get_vars['rnd']);
if($vid) $get_vars['vid'] = $vid; if($vid) $get_vars['vid'] = $vid;
else unset($get_vars['vid']); else unset($get_vars['vid']);
// action명이 변경되었던 것에 대해 호환성을 유지하기 위한 강제 값 변경 // for compatibility to lower versions
switch($get_vars['act']) { switch($get_vars['act']) {
case 'dispMemberFriend' : $get_vars['act'] = 'dispCommunicationFriend'; break; case 'dispMemberFriend' : $get_vars['act'] = 'dispCommunicationFriend'; break;
case 'dispMemberMessages' : $get_vars['act'] = 'dispCommunicationMessages'; break; case 'dispMemberMessages' : $get_vars['act'] = 'dispCommunicationMessages'; break;
@ -855,10 +912,10 @@
case 'dispModuleAdminSelectList' : $get_vars['act'] = 'dispModuleSelectList'; break; case 'dispModuleAdminSelectList' : $get_vars['act'] = 'dispModuleSelectList'; break;
} }
// URL 구성 // organize URL
$query = null; $query = null;
if($var_count = count($get_vars)) { if($var_count = count($get_vars)) {
// rewrite mod 사용시 // If using rewrite mod
if($this->allow_rewrite) { if($this->allow_rewrite) {
$var_keys = array_keys($get_vars); $var_keys = array_keys($get_vars);
asort($var_keys); asort($var_keys);
@ -878,7 +935,6 @@
} }
} }
// rewrite mod 미사용 또는 query값이 생성되지 않았을 경우 get argument로 생성
if(!$query) { if(!$query) {
foreach($get_vars as $key => $val) { foreach($get_vars as $key => $val) {
if(is_array($val) && count($val)) { if(is_array($val) && count($val)) {
@ -891,23 +947,22 @@
} }
} }
// 항상 SSL을 이용하고 현재 SSL이 아닌 경우 https에 대한 prefix를 붙임 // If using SSL always
if(Context::get('_use_ssl')=='always') { if(Context::get('_use_ssl')=='always') {
$query = $this->getRequestUri(ENFORCE_SSL, $domain).$query; $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query;
// 상황에 따라 혹은 지정된 대상만 SSL 취급될 경우 // optional SSL use
} elseif(Context::get('_use_ssl')=='optional') { } elseif(Context::get('_use_ssl')=='optional') {
$ssl_mode = RELEASE_SSL; $ssl_mode = RELEASE_SSL;
if($get_vars['act'] && $this->_isExistsSSLAction($get_vars['act'])) $ssl_mode = ENFORCE_SSL; if($get_vars['act'] && $this->_isExistsSSLAction($get_vars['act'])) $ssl_mode = ENFORCE_SSL;
$query = $this->getRequestUri($ssl_mode, $domain).$query; $query = $this->getRequestUri($ssl_mode, $domain).$query;
// SSL 을 사용하지 않을 경우 // no SSL
} else { } else {
// SSL상태인데 대상이 SSL이 아닌 경우 // currently on SSL but target is not based on SSL
if($_SERVER['HTTPS']=='on' ) $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query; if($_SERVER['HTTPS']=='on' ) $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query;
// $domain 값이 있을 경우 // if $domain is set
else if($domain) $query = $this->getRequestUri(FOLLOW_REQUEST_SSL, $domain).$query; else if($domain) $query = $this->getRequestUri(FOLLOW_REQUEST_SSL, $domain).$query;
// $domain 값이 없을 경우
else $query = getScriptPath().$query; else $query = getScriptPath().$query;
} }
@ -1114,8 +1169,8 @@
* @brief js file을 추가 * @brief js file을 추가
**/ **/
function _addJsFile($file, $optimized, $targetie,$index) { function _addJsFile($file, $optimized, $targetie,$index) {
if(strpos($file,'://')===false && substr($file,0,1)!='/' && substr($file,0,1)!='.') $file = './'.$file; if(strpos($file,'://')===false && $file{0}!='/' && $file{0}!='.') $file = './'.$file;
$file = str_replace(array('/./','//'),'/',$file); $file = preg_replace('@/\./|(?<!:)\/\/@', '/', $file);
while(strpos($file,'/../')) $file = preg_replace('/\/([^\/]+)\/\.\.\//s','/',$file); while(strpos($file,'/../')) $file = preg_replace('/\/([^\/]+)\/\.\.\//s','/',$file);
if(in_array($file, $this->js_files)) return; if(in_array($file, $this->js_files)) return;

View file

@ -326,7 +326,6 @@
$output = $this->_executeSelectAct($output); $output = $this->_executeSelectAct($output);
break; break;
} }
if($this->isError()) $output = $this->getError(); if($this->isError()) $output = $this->getError();
else if(!is_a($output, 'Object') && !is_subclass_of($output, 'Object')) $output = new Object(); else if(!is_a($output, 'Object') && !is_subclass_of($output, 'Object')) $output = new Object();
$output->add('_query', $this->query); $output->add('_query', $this->query);
@ -360,7 +359,7 @@
break; break;
case 'number' : case 'number' :
case 'numbers' : case 'numbers' :
if(!preg_match('/^(-?)[0-9,]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key)); if(!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key));
break; break;
case 'alpha' : case 'alpha' :
if(!preg_match('/^[a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key} ? $lang->{$key} : $key)); if(!preg_match('/^[a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key} ? $lang->{$key} : $key));
@ -613,5 +612,10 @@
return $result; return $result;
} }
function dropTable($table_name){
if(!$table_name) return;
$query = sprintf("drop table %s%s", $this->prefix, $table_name);
$this->_query($query);
}
} }
?> ?>

View file

@ -422,18 +422,18 @@
$pipe = $v['pipe']; $pipe = $v['pipe'];
$value = $this->getConditionValue($name, $value, $operation, $type, $column_type); $value = $this->getConditionValue($name, $value, $operation, $type, $column_type);
if(!$value) { if (!$value) {
$value = $v['value']; $value = $v['value'];
if (strpos ($value, '(')) $valuetmp = $value; if (strpos ($value, '(')) $valuetmp = $value;
elseif (strpos ($value, ".") === false) $valuetmp = $value; elseif (strpos ($value, ".") === false) $valuetmp = $value;
else $valuetmp = '"'.str_replace('.', '"."', $value).'"'; else $valuetmp = '"'.str_replace('.', '"."', $value).'"';
} else $valuetmp = $value; } else $valuetmp = $value;
if (strpos ($name, '(')) $nametmp = $name; if (strpos ($name, '(') > 0) $nametmp = $name;
elseif (strpos ($name, ".") === false) $nametmp = '"'.$name.'"'; elseif (strpos ($name, ".") === false) $nametmp = '"'.$name.'"';
else $nametmp = '"'.str_replace('.', '"."', $name).'"'; else $nametmp = '"'.str_replace('.', '"."', $name).'"';
$str = $this->getConditionPart($nametmp, $valuetmp, $operation); $str = $this->getConditionPart($nametmp, $valuetmp, $operation);
if($sub_condition) $sub_condition .= ' '.$pipe.' '; if ($sub_condition) $sub_condition .= ' '.$pipe.' ';
$sub_condition .= $str; $sub_condition .= $str;
} }
if($sub_condition) { if($sub_condition) {
if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' ';
@ -482,30 +482,41 @@
} }
$query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list));
return $this->_query($query); $result = $this->_query($query);
if($result && !$this->transaction_started) @cubrid_commit($this->fd);
return $result;
} }
/** /**
* @brief updateAct 처리 * @brief updateAct 처리
**/ **/
function _executeUpdateAct($output) { function _executeUpdateAct($output) {
// 테이블 정리 // 테이블 정리
foreach($output->tables as $key => $val) { foreach($output->tables as $key => $val) {
$table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"';
} }
$check_click_count = true;
// 컬럼 정리 // 컬럼 정리
foreach($output->columns as $key => $val) { foreach($output->columns as $key => $val) {
if(!isset($val['value'])) continue; if(!isset($val['value'])) continue;
$name = $val['name']; $name = $val['name'];
$value = $val['value']; $value = $val['value'];
if(substr($value,-2)!='+1') $check_click_count = false;
for ($i = 0; $i < $key; $i++) { // 한문장에 같은 속성에 대한 중복 설정은 큐브리드에서는 허용치 않음 for ($i = 0; $i < $key; $i++) { // 한문장에 같은 속성에 대한 중복 설정은 큐브리드에서는 허용치 않음
if ($output->columns[$i]['name'] == $name) break; if ($output->columns[$i]['name'] == $name) break;
} }
if ($i < $key) continue; // 중복이 발견되면 이후의 설정은 무시 if ($i < $key) continue; // 중복이 발견되면 이후의 설정은 무시
if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value;
else { else {
if($output->column_type[$name]!='number') { if($output->column_type[$name]!='number') {
$check_column = false;
$clen=strlen($value); $clen=strlen($value);
if ($clen <= $this->cutlen) if ($clen <= $this->cutlen)
$value = "'".$this->addQuotes($value)."'"; $value = "'".$this->addQuotes($value)."'";
@ -531,10 +542,46 @@
// 조건절 정리 // 조건절 정리
$condition = $this->getCondition($output); $condition = $this->getCondition($output);
$query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); $check_click_count_condition = false;
if($check_click_count){
foreach($output->conditions as $val){
if($val['pipe']=='or'){
$check_click_count_condition = false;
break;
}
foreach($val['condition'] as $v){
if($v['operation']=='equal') $check_click_count_condition = true;
else{
if($v['operation']=='in' && !strpos($v['value'],',') ) $check_click_count_condition = true;
else $check_click_count_condition=false;
}
return $this->_query($query); if($v['pipe']=='or'){
} $check_click_count_condition= false;
break;
}
}
}
}
if($check_click_count
&& $check_click_count_condition
&& count($output->tables)==1
&& count($output->conditions)>0
&& count($output->groups)==0
&& count($output->order)==0){
foreach($output->columns as $k => $v) $incr_columns[]= 'incr("'.$v['name'].'")';
$query = sprintf('select %s from %s %s',join(',',$incr_columns), implode(',',$table_list), $condition);
}else{
$query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition);
}
$result = $this->_query($query);
if($result && !$this->transaction_started) @cubrid_commit($this->fd);
return $result;
}
/** /**
* @brief deleteAct 처리 * @brief deleteAct 처리
@ -549,8 +596,9 @@
$condition = $this->getCondition($output); $condition = $this->getCondition($output);
$query = sprintf("delete from %s %s", implode(',',$table_list), $condition); $query = sprintf("delete from %s %s", implode(',',$table_list), $condition);
$result = $this->_query($query);
return $this->_query($query); if($result && !$this->transaction_started) @cubrid_commit($this->fd);
return $result;
} }
/** /**
@ -572,8 +620,8 @@
foreach($left_tables as $key => $val) { foreach($left_tables as $key => $val) {
$condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type);
if($condition){ if($condition) {
$left_join[] = $val . ' "'.$this->prefix.$output->_tables[$key].'" "'.$key . '" on (' . $condition . ')'; $left_join[] = $val.' "'.$this->prefix.$output->_tables[$key].'" "'.$key.'" on ('.$condition.')';
} }
} }

View file

@ -2,11 +2,10 @@
/** /**
* @class DisplayHandler * @class DisplayHandler
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief 데이터 출력을 위한 class (XML/HTML 데이터를 구분하여 출력) * @brief DisplayHandler is responsible for displaying the execution result. \n
* * Depending on the request type, it can display either HTML or XML content.\n
* Response Method에 따라서 html or xml 출력방법을 결정한다 * Xml content is simple xml presentation of variables in oModule while html content
* xml : oModule의 variables를 simple xml 출력 * is the combination of the variables of oModue and template files/.
* html : oModule의 template/variables로 html을 만들고 contents_html로 처리
**/ **/
class DisplayHandler extends Handler { class DisplayHandler extends Handler {
@ -16,8 +15,11 @@
var $gz_enabled = false; ///< gzip 압축하여 컨텐츠 호출할 것인지에 대한 flag변수 var $gz_enabled = false; ///< gzip 압축하여 컨텐츠 호출할 것인지에 대한 flag변수
/** /**
* @brief 모듈객체를 받아서 content 출력 * @brief print either html or xml content given oModule object
**/ * @remark addon execution and the trigger execution are included within this method, which
* might create inflexibility for the fine grained caching
* @param[in] $oModule the module object
**/
function printContent(&$oModule) { function printContent(&$oModule) {
// gzip encoding 지원 여부 체크 // gzip encoding 지원 여부 체크
@ -97,7 +99,7 @@
$called_position = 'before_display_content'; $called_position = 'before_display_content';
$oAddonController = &getController('addon'); $oAddonController = &getController('addon');
$addon_file = $oAddonController->getCacheFilePath(); $addon_file = $oAddonController->getCacheFilePath();
if(file_exists($addon_file)) @include($addon_file); @include($addon_file);
// HTML 출력일 경우 최종적으로 common layout을 씌워서 출력 // HTML 출력일 경우 최종적으로 common layout을 씌워서 출력
if(Context::getResponseMethod()=="HTML") { if(Context::getResponseMethod()=="HTML") {
@ -159,23 +161,27 @@
} }
/** /**
* @brief <!--Meta:파일이름.(css|js)--> 변경 * @brief add given .css or .js file names in widget code to Context
**/ * @param[in] $oModule the module object
**/
function transMeta($matches) { function transMeta($matches) {
if(substr($matches[1],'-4')=='.css') Context::addCSSFile($matches[1]); if(substr($matches[1],'-4')=='.css') Context::addCSSFile($matches[1]);
elseif(substr($matches[1],'-3')=='.js') Context::addJSFile($matches[1]); elseif(substr($matches[1],'-3')=='.js') Context::addJSFile($matches[1]);
} }
/** /**
* @brief <body>내의 <style태그를 header로 이동 * @brief add html style code extracted from html body to Context, which will be
**/ * printed inside <header></header> later.
* @param[in] $oModule the module object
**/
function moveStyleToHeader($matches) { function moveStyleToHeader($matches) {
Context::addHtmlHeader($matches[0]); Context::addHtmlHeader($matches[0]);
} }
/** /**
* @brief RequestMethod가 JSON이면 JSON 데이터로 컨텐츠 생성 * @brief produce JSON compliant cotent given a module object.
**/ * @param[in] $oModule the module object
**/
function _toJSON(&$oModule) { function _toJSON(&$oModule) {
$variables = $oModule->getVariables(); $variables = $oModule->getVariables();
$variables['error'] = $oModule->getError(); $variables['error'] = $oModule->getError();
@ -185,8 +191,9 @@
} }
/** /**
* @brief RequestMethod가 virtualXML이면 성공, 실패, redirect에 대해 컨텐츠 생성 * @brief Produce virtualXML compliant content given a module object.\n
**/ * @param[in] $oModule the module object
**/
function _toVirtualXmlDoc(&$oModule) { function _toVirtualXmlDoc(&$oModule) {
$error = $oModule->getError(); $error = $oModule->getError();
$message = $oModule->getMessage(); $message = $oModule->getMessage();
@ -214,12 +221,13 @@
} }
/** /**
* @brief RequestMethod가 XML이면 XML 데이터로 컨텐츠 생성 * @brief Produce XML compliant content given a module object.\n
**/ * @param[in] $oModule the module object
**/
function _toXmlDoc(&$oModule) { function _toXmlDoc(&$oModule) {
$variables = $oModule->getVariables(); $variables = $oModule->getVariables();
$xmlDoc = "<response>\n"; $xmlDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<response>\n";
$xmlDoc .= sprintf("<error>%s</error>\n",$oModule->getError()); $xmlDoc .= sprintf("<error>%s</error>\n",$oModule->getError());
$xmlDoc .= sprintf("<message>%s</message>\n",str_replace(array('<','>','&'),array('&lt;','&gt;','&amp;'),$oModule->getMessage())); $xmlDoc .= sprintf("<message>%s</message>\n",str_replace(array('<','>','&'),array('&lt;','&gt;','&amp;'),$oModule->getMessage()));
@ -230,6 +238,10 @@
return $xmlDoc; return $xmlDoc;
} }
/**
* @brief produce XML code given variable object\n
* @param[in] $oModule the module object
**/
function _makeXmlDoc($obj) { function _makeXmlDoc($obj) {
if(!count($obj)) return; if(!count($obj)) return;
@ -247,8 +259,9 @@
} }
/** /**
* @brief RequestMethod가 XML이 아니면 html 컨텐츠 생성 * @brief Produce HTML compliant content given a module object.\n
**/ * @param[in] $oModule the module object
**/
function _toHTMLDoc(&$oModule) { function _toHTMLDoc(&$oModule) {
// template handler 객체 생성 // template handler 객체 생성
$oTemplate = &TemplateHandler::getInstance(); $oTemplate = &TemplateHandler::getInstance();
@ -260,11 +273,9 @@
} }
/** /**
* @brief 디버그 모드일 경우 디버깅 메시지 출력 * @brief Print debugging message to designated output source depending on the value set to __DEBUG_OUTPUT_. \n
* * This method only functions when __DEBUG__ variable is set to 1.
* __DEBUG__ 값이 1 이상이면 __DEBUG_OUTPUT__ 값에 따라 메시지 출력. * __DEBUG_OUTPUT__ == 0, messages are written in ./files/_debug_message.php
* __DEBUG__를 세팅하고, __DEBUG_OUTPUT__ == 0 이면
* tail -f ./files/_debug_message.php로 하여 console로 확인하면 편리함
**/ **/
function _debugOutput() { function _debugOutput() {
if(!__DEBUG__) return; if(!__DEBUG__) return;
@ -336,6 +347,10 @@
// 전체 실행 시간 출력, Request/Response info 출력 // 전체 실행 시간 출력, Request/Response info 출력
if(__DEBUG__ & 2) { if(__DEBUG__ & 2) {
if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) {
return;
}
// Request/Response 정보 작성 // Request/Response 정보 작성
$buff .= "\n- Request/ Response info\n"; $buff .= "\n- Request/ Response info\n";
$buff .= sprintf("\tRequest URI \t\t\t: %s:%s%s%s%s\n", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['PHP_SELF'], $_SERVER['QUERY_STRING']?'?':'', $_SERVER['QUERY_STRING']); $buff .= sprintf("\tRequest URI \t\t\t: %s:%s%s%s%s\n", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['PHP_SELF'], $_SERVER['QUERY_STRING']?'?':'', $_SERVER['QUERY_STRING']);
@ -363,6 +378,10 @@
// DB 로그 작성 // DB 로그 작성
if(__DEBUG__ & 4) { if(__DEBUG__ & 4) {
if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) {
return;
}
if($GLOBALS['__db_queries__']) { if($GLOBALS['__db_queries__']) {
$buff .= sprintf("\n- DB Queries : %d Queries. %0.5f sec\n", count($GLOBALS['__db_queries__']), $GLOBALS['__db_elapsed_time__']); $buff .= sprintf("\n- DB Queries : %d Queries. %0.5f sec\n", count($GLOBALS['__db_queries__']), $GLOBALS['__db_elapsed_time__']);
$num = 0; $num = 0;
@ -405,7 +424,7 @@
} }
/** /**
* @brief xml header 출력 (utf8 고정) * @brief print a HTTP HEADER for XML, which is encoded in UTF-8
**/ **/
function _printXMLHeader() { function _printXMLHeader() {
header("Content-Type: text/xml; charset=UTF-8"); header("Content-Type: text/xml; charset=UTF-8");
@ -416,8 +435,9 @@
header("Pragma: no-cache"); header("Pragma: no-cache");
} }
/** /**
* @brief html header 출력 (utf8 고정) * @brief print a HTTP HEADER for HTML, which is encoded in UTF-8
**/ **/
function _printHTMLHeader() { function _printHTMLHeader() {
header("Content-Type: text/html; charset=UTF-8"); header("Content-Type: text/html; charset=UTF-8");
@ -428,8 +448,9 @@
header("Pragma: no-cache"); header("Pragma: no-cache");
} }
/** /**
* @brief JSON header 출력 (utf8 고정) * @brief print a HTTP HEADER for JSON, which is encoded in UTF-8
**/ **/
function _printJSONHeader() { function _printJSONHeader() {
header("Content-Type: text/html; charset=UTF-8"); header("Content-Type: text/html; charset=UTF-8");

View file

@ -3,10 +3,9 @@
* @class HttpRequest * @class HttpRequest
* @author haneul (haneul@gmail.com) * @author haneul (haneul@gmail.com)
* @version 0.1 * @version 0.1
* @brief 다른 서버에 HTTP Request를 전송하고 result를 받아오는 클래스 * @brief a class that is designed to be used for sending out HTTP request to an external server and retrieving response
* @remarks Connection: keep-alive 지원하지 않음 * @remarks Connection: keep-alive is not supported
*/ */
class XEHttpRequest { class XEHttpRequest {
/// target host /// target host
@ -27,7 +26,9 @@
} }
/** /**
* @brief Add (key, value) pair to the HTTP request header * @brief mether to add key/value pair to the HTTP request header
* @param[in] key HTTP header element
* @param[in] value value string for HTTP header element
*/ */
function AddToHeader($key, $value) function AddToHeader($key, $value)
{ {
@ -36,7 +37,10 @@
/** /**
* @brief send HTTP message to the host * @brief send HTTP message to the host
* @return (result code, response body) * @param[in] target ip or url of the external server
* @param[in] method HTTP method such as GET and POST
* @param[in] timeout time out value for HTTP request expiration
* @return Returns an object containing HTTP Response body and HTTP response code
*/ */
function Send($target, $method="GET", $timeout = 3) function Send($target, $method="GET", $timeout = 3)
{ {

View file

@ -13,9 +13,30 @@
var $title = ''; var $title = '';
var $content = ''; var $content = '';
var $content_type = 'html'; var $content_type = 'html';
var $messageId = null;
var $replyTo = null;
var $bcc = null;
var $attachments = array();
var $cidAttachments = array();
var $mainMailPart = null;
var $body = '';
var $header = '';
var $eol = '';
var $references = '';
function Mail() { } function Mail() { }
function addAttachment($filename, $orgfilename)
{
$this->attachments[$orgfilename] = $filename;
}
function addCidAttachment($filename, $cid)
{
$this->cidAttachments[$cid] = $filename;
}
function setSender($name, $email) { function setSender($name, $email) {
$this->sender_name = $name; $this->sender_name = $name;
$this->sender_email = $email; $this->sender_email = $email;
@ -32,7 +53,7 @@
} }
function getReceiptor() { function getReceiptor() {
if($this->receiptor_name) return sprintf("%s <%s>", '=?utf-8?b?'.base64_encode($this->receiptor_name).'?=', $this->receiptor_email); if($this->receiptor_name && $this->receiptor_name != $this->receiptor_email) return sprintf("%s <%s>", '=?utf-8?b?'.base64_encode($this->receiptor_name).'?=', $this->receiptor_email);
return $this->receiptor_email; return $this->receiptor_email;
} }
@ -44,6 +65,24 @@
return '=?utf-8?b?'.base64_encode($this->title).'?='; return '=?utf-8?b?'.base64_encode($this->title).'?=';
} }
function setBCC($bcc)
{
$this->bcc = $bcc;
}
function setMessageID($messageId) {
$this->messageId = $messageId;
}
function setReferences($references) {
$this->references = $references;
}
function setReplyTo($replyTo)
{
$this->replyTo = $replyTo;
}
function setContent($content) { function setContent($content) {
$content = preg_replace_callback('/<img([^>]+)>/i',array($this,'replaceResourceRealPath'), $content); $content = preg_replace_callback('/<img([^>]+)>/i',array($this,'replaceResourceRealPath'), $content);
$this->content = $content; $this->content = $content;
@ -58,38 +97,103 @@
} }
function getHTMLContent() { function getHTMLContent() {
return chunk_split(base64_encode($this->content_type=='html'?nl2br($this->content):$this->content)); return chunk_split(base64_encode($this->content_type!='html'?nl2br($this->content):$this->content));
} }
function setContentType($mode = 'html') { function setContentType($mode = 'html') {
$this->content_type = $mode=='html'?'html':''; $this->content_type = $mode=='html'?'html':'';
} }
function procAttachments()
{
if(count($this->attachments) > 0)
{
$this->body = $this->header.$this->body;
$boundary = '----=='.uniqid(rand(),true);
$this->header = "Content-Type: multipart/mixed;".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol;
$this->body = "--".$boundary.$this->eol.$this->body.$this->eol.$this->eol;
$res = array();
$res[] = $this->body;
foreach($this->attachments as $filename => $attachment)
{
$type = $this->returnMIMEType($filename);
$file_str = FileHandler::readFile($attachment);
$chunks = chunk_split(base64_encode($file_str));
$tempBody = sprintf(
"--".$boundary.$this->eol.
"Content-Type: %s;".$this->eol.
"\tname=\"%s\"".$this->eol.
"Content-Transfer-Encoding: base64".$this->eol.
"Content-Description: %s".$this->eol.
"Content-Disposition: attachment;".$this->eol.
"\tfilename=\"%s\"".$this->eol.$this->eol.
"%s".$this->eol.$this->eol,
$type,
$filename,
$filename,
$filename,
$chunks);
$res[] = $tempBody;
}
$this->body = implode("", $res);
$this->body .= "--".$boundary."--";
}
}
function procCidAttachments()
{
if(count($this->cidAttachments) > 0)
{
$this->body = $this->header.$this->body;
$boundary = '----=='.uniqid(rand(),true);
$this->header = "Content-Type: multipart/relative;".$this->eol."\ttype=\"multipart/alternative\";".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol;
$this->body = "--".$boundary.$this->eol.$this->body.$this->eol.$this->eol;
$res = array();
$res[] = $this->body;
foreach($this->cidAttachments as $cid => $attachment)
{
$filename = basename($attachment);
$type = $this->returnMIMEType(FileHandler::getRealPath($attachment));
$file_str = FileHandler::readFile($attachment);
$chunks = chunk_split(base64_encode($file_str));
$tempBody = sprintf(
"--".$boundary.$this->eol.
"Content-Type: %s;".$this->eol.
"\tname=\"%s\"".$this->eol.
"Content-Transfer-Encoding: base64".$this->eol.
"Content-ID: <%s>".$this->eol.
"Content-Description: %s".$this->eol.
"Content-Location: %s".$this->eol.$this->eol.
"%s".$this->eol.$this->eol,
$type,
$filename,
$cid,
$filename,
$filename,
$chunks);
$res[] = $tempBody;
}
$this->body = implode("", $res);
$this->body .= "--".$boundary."--";
}
}
function send() { function send() {
$boundary = '----=='.uniqid(rand(),true); $boundary = '----=='.uniqid(rand(),true);
$eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n"; $this->eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n";
$headers = sprintf( $this->header = "Content-Type: multipart/alternative;".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol;
"From: %s".$eol. $this->body = sprintf(
"To: %s".$eol. "--%s".$this->eol.
"MIME-Version: 1.0".$eol. "Content-Type: text/plain; charset=utf-8; format=flowed".$this->eol.
"Content-Type: multipart/alternative;".$eol."\tboundary=\"%s\"".$eol.$eol. "Content-Transfer-Encoding: base64".$this->eol.
"", "Content-Disposition: inline".$this->eol.$this->eol.
$this->getSender(),
$this->getReceiptor(),
$boundary
);
$body = sprintf(
"--%s".$eol.
"Content-Type: text/plain; charset=utf-8; format=flowed".$eol.
"Content-Transfer-Encoding: base64".$eol.
"Content-Disposition: inline".$eol.$eol.
"%s". "%s".
"--%s".$eol. "--%s".$this->eol.
"Content-Type: text/html; charset=utf-8".$eol. "Content-Type: text/html; charset=utf-8".$this->eol.
"Content-Transfer-Encoding: base64".$eol. "Content-Transfer-Encoding: base64".$this->eol.
"Content-Disposition: inline".$eol.$eol. "Content-Disposition: inline".$this->eol.$this->eol.
"%s". "%s".
"--%s--". "--%s--".
"", "",
@ -100,7 +204,25 @@
$boundary $boundary
); );
return mail($this->receiptor_email, $this->getTitle(), $body, $headers); $this->procCidAttachments();
$this->procAttachments();
$headers = sprintf(
"From: %s".$this->eol.
"%s".
"%s".
"%s".
"%s".
"MIME-Version: 1.0".$this->eol."",
$this->getSender(),
$this->messageId?("Message-ID: <".$this->messageId.">".$this->eol):"",
$this->replyTo?("Reply-To: <".$this->replyTo.">".$this->eol):"",
$this->bcc?("Bcc: ".$this->bcc.$this->eol):"",
$this->references?("References: <".$this->references.">".$this->eol."In-Reply-To: <".$this->references.">".$this->eol):""
);
$headers .= $this->header;
return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers);
} }
function checkMailMX($email_address) { function checkMailMX($email_address) {
@ -117,5 +239,109 @@
if( preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address) ) return $email_address; if( preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address) ) return $email_address;
else return ''; else return '';
} }
function returnMIMEType($filename)
{
preg_match("|\.([a-z0-9]{2,4})$|i", $filename, $fileSuffix);
switch(strtolower($fileSuffix[1]))
{
case "js" :
return "application/x-javascript";
case "json" :
return "application/json";
case "jpg" :
case "jpeg" :
case "jpe" :
return "image/jpg";
case "png" :
case "gif" :
case "bmp" :
case "tiff" :
return "image/".strtolower($fileSuffix[1]);
case "css" :
return "text/css";
case "xml" :
return "application/xml";
case "doc" :
case "docx" :
return "application/msword";
case "xls" :
case "xlt" :
case "xlm" :
case "xld" :
case "xla" :
case "xlc" :
case "xlw" :
case "xll" :
return "application/vnd.ms-excel";
case "ppt" :
case "pps" :
return "application/vnd.ms-powerpoint";
case "rtf" :
return "application/rtf";
case "pdf" :
return "application/pdf";
case "html" :
case "htm" :
case "php" :
return "text/html";
case "txt" :
return "text/plain";
case "mpeg" :
case "mpg" :
case "mpe" :
return "video/mpeg";
case "mp3" :
return "audio/mpeg3";
case "wav" :
return "audio/wav";
case "aiff" :
case "aif" :
return "audio/aiff";
case "avi" :
return "video/msvideo";
case "wmv" :
return "video/x-ms-wmv";
case "mov" :
return "video/quicktime";
case "zip" :
return "application/zip";
case "tar" :
return "application/x-tar";
case "swf" :
return "application/x-shockwave-flash";
default :
if(function_exists("mime_content_type"))
{
$fileSuffix = mime_content_type($filename);
}
return "unknown/" . trim($fileSuffix[0], ".");
}
}
} }
?> ?>

View file

@ -62,7 +62,7 @@
$called_position = 'before_module_init'; $called_position = 'before_module_init';
$oAddonController = &getController('addon'); $oAddonController = &getController('addon');
$addon_file = $oAddonController->getCacheFilePath(); $addon_file = $oAddonController->getCacheFilePath();
if(file_exists($addon_file)) @include($addon_file); @include($addon_file);
} }
/** /**
@ -118,7 +118,7 @@
if(!$module_info && !$this->module && $site_module_info->module_site_srl) $module_info = $site_module_info; if(!$module_info && !$this->module && $site_module_info->module_site_srl) $module_info = $site_module_info;
// redirect, if site_srl of module_info is different from one of site's module_info // redirect, if site_srl of module_info is different from one of site's module_info
if($module_info && $module_info->site_srl != $site_module_info->site_srl) { if($module_info && $module_info->site_srl != $site_module_info->site_srl && !isCrawler()) {
// If the module is of virtual site // If the module is of virtual site
if($module_info->site_srl) { if($module_info->site_srl) {
$site_info = $oModuleModel->getSiteInfo($module_info->site_srl); $site_info = $oModuleModel->getSiteInfo($module_info->site_srl);

View file

@ -2,39 +2,41 @@
/** /**
* @class ModuleObject * @class ModuleObject
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief module의 상위 클래스 * @brief base class of ModuleHandler
**/ **/
class ModuleObject extends Object { class ModuleObject extends Object {
var $mid = NULL; ///< module로 생성한 instance(관리상)의 값 var $mid = NULL; ///< string to represent run-time instance of Module (XE Module)
var $module = NULL; ///< mid로 찾아서 생성한 모듈 class 이름 var $module = NULL; ///< Class name of Xe Module that is identified by mid
var $module_srl = NULL; ///< 모듈 객체의 고유값인 module_srl var $module_srl = NULL; ///< integer value to represent a run-time instance of Module (XE Module)
var $module_info = NULL; ///< 모듈의 설정 정보 var $module_info = NULL; ///< an object containing the module information
var $xml_info = NULL; ///< 모듈 자체 정보 var $xml_info = NULL; ///< an object containing the module description extracted from XML file
var $module_path = NULL; ///< 모듈 class file의 실행 위치 var $module_path = NULL; ///< a path to directory where module source code resides
var $act = NULL; ///< act 값 var $act = NULL; ///< a string value to contain the action name
var $template_path = NULL; ///< template 경로 var $template_path = NULL; ///< a path of directory where template files reside
var $template_file = NULL; ///< template 파일 var $template_file = NULL; ///< name of template file
var $layout_path = ''; ///< 레이아웃 경로 var $layout_path = ''; ///< a path of directory where layout files reside
var $layout_file = ''; ///< 레이아웃 파일 var $layout_file = ''; ///< name of layout file
var $edited_layout_file = ''; ///< 관리자 모드에서 수정된 레이아웃 파일 var $edited_layout_file = ''; ///< name of temporary layout files that is modified in an admin mode
var $stop_proc = false; ///< action 수행중 stop()를 호출하면 ModuleObject::proc()를 수행하지 않음 var $stop_proc = false; ///< a flag to indicating whether to stop the execution of code.
/** /**
* @brief 현재 모듈의 이름을 지정 * @brief setter to set the name of module
* @param name of module
**/ **/
function setModule($module) { function setModule($module) {
$this->module = $module; $this->module = $module;
} }
/** /**
* @brief 현재 모듈의 path를 지정 * @brief setter to set the name of module path
* @param the directory path to a module directory
**/ **/
function setModulePath($path) { function setModulePath($path) {
if(substr($path,-1)!='/') $path.='/'; if(substr($path,-1)!='/') $path.='/';
@ -42,17 +44,17 @@
} }
/** /**
* @brief redirect_url을 정함 * @brief setter to set an url for redirection
* * @param $url url for redirection
* redirect_url의 경우 ajax로 request를 받았을 경우에 사용하면 ... * @remark redirect_url is used only for ajax requests
**/ **/
function setRedirectUrl($url='./') { function setRedirectUrl($url='./') {
$this->add('redirect_url', $url); $this->add('redirect_url', $url);
} }
/** /**
* @brief 현재 페이지를 refresh시킴 * @brief sett to set the template path for refresh.html
* * @remark refresh.html is executed as a result of method execution
* 공통 tpl중 refresh.html을 실행할 .. * 공통 tpl중 refresh.html을 실행할 ..
**/ **/
function setRefreshPage() { function setRefreshPage() {
@ -62,15 +64,17 @@
/** /**
* @brief act값 지정 * @brief sett to set the action name
**/ **/
function setAct($act) { function setAct($act) {
$this->act = $act; $this->act = $act;
} }
/** /**
* @brief 모듈의 정보 세팅 * @brief sett to set module information
**/ * @param[in] $module_info object containing module information
* @param[in] $xml_info object containing module description
**/
function setModuleInfo($module_info, $xml_info) { function setModuleInfo($module_info, $xml_info) {
// 기본 변수 설정 // 기본 변수 설정
$this->mid = $module_info->mid; $this->mid = $module_info->mid;
@ -130,7 +134,8 @@
} }
/** /**
* @brief 메세지 출력 * @brief set the stop_proc and approprate message for msg_code
* @param $msg_code an error code
**/ **/
function stop($msg_code) { function stop($msg_code) {
// proc 수행을 중지 시키기 위한 플래그 세팅 // proc 수행을 중지 시키기 위한 플래그 세팅
@ -153,7 +158,7 @@
} }
/** /**
* @brief template 파일 지정 * @brief set the file name of the template file
**/ **/
function setTemplateFile($filename) { function setTemplateFile($filename) {
if(substr($filename,-5)!='.html') $filename .= '.html'; if(substr($filename,-5)!='.html') $filename .= '.html';
@ -161,14 +166,14 @@
} }
/** /**
* @brief template 파일 return * @brief retrieve the directory path of the template directory
**/ **/
function getTemplateFile() { function getTemplateFile() {
return $this->template_file; return $this->template_file;
} }
/** /**
* @brief template 경로 지정 * @brief set the directory path of the template directory
**/ **/
function setTemplatePath($path) { function setTemplatePath($path) {
if(substr($path,0,1)!='/' && substr($path,0,2)!='./') $path = './'.$path; if(substr($path,0,1)!='/' && substr($path,0,2)!='./') $path = './'.$path;
@ -177,14 +182,15 @@
} }
/** /**
* @brief template 경로 return
* @brief retrieve the directory path of the template directory
**/ **/
function getTemplatePath() { function getTemplatePath() {
return $this->template_path; return $this->template_path;
} }
/** /**
* @brief edited layout 파일 지정 * @brief set the file name of the temporarily modified by admin
**/ **/
function setEditedLayoutFile($filename) { function setEditedLayoutFile($filename) {
if(substr($filename,-5)!='.html') $filename .= '.html'; if(substr($filename,-5)!='.html') $filename .= '.html';
@ -192,14 +198,14 @@
} }
/** /**
* @brief layout 파일 return * @brief retreived the file name of edited_layout_file
**/ **/
function getEditedLayoutFile() { function getEditedLayoutFile() {
return $this->edited_layout_file; return $this->edited_layout_file;
} }
/** /**
* @brief layout 파일 지정 * @brief set the file name of the layout file
**/ **/
function setLayoutFile($filename) { function setLayoutFile($filename) {
if(substr($filename,-5)!='.html') $filename .= '.html'; if(substr($filename,-5)!='.html') $filename .= '.html';
@ -207,14 +213,14 @@
} }
/** /**
* @brief layout 파일 return * @brief get the file name of the layout file
**/ **/
function getLayoutFile() { function getLayoutFile() {
return $this->layout_file; return $this->layout_file;
} }
/** /**
* @brief layout 경로 지정 * @brief set the directory path of the layout directory
**/ **/
function setLayoutPath($path) { function setLayoutPath($path) {
if(substr($path,0,1)!='/' && substr($path,0,2)!='./') $path = './'.$path; if(substr($path,0,1)!='/' && substr($path,0,2)!='./') $path = './'.$path;
@ -223,16 +229,15 @@
} }
/** /**
* @brief layout 경로 return * @brief set the directory path of the layout directory
**/ **/
function getLayoutPath() { function getLayoutPath() {
return $this->layout_path; return $this->layout_path;
} }
/** /**
* @brief 모듈의 action에 해당하는 method를 실행 * @brief excute the member method specified by $act variable
* *
* $act값에 의해서 $action_list에 선언된 것들을 실행한다
**/ **/
function proc() { function proc() {
// stop_proc==true이면 그냥 패스 // stop_proc==true이면 그냥 패스
@ -242,7 +247,7 @@
$called_position = 'before_module_proc'; $called_position = 'before_module_proc';
$oAddonController = &getController('addon'); $oAddonController = &getController('addon');
$addon_file = $oAddonController->getCacheFilePath(); $addon_file = $oAddonController->getCacheFilePath();
if(file_exists($addon_file)) @include($addon_file); @include($addon_file);
if(isset($this->xml_info->action->{$this->act}) && method_exists($this, $this->act)) { if(isset($this->xml_info->action->{$this->act}) && method_exists($this, $this->act)) {
@ -306,6 +311,8 @@
if($oModule->getLayoutFile()) $this->setLayoutFile($oModule->getLayoutFile()); if($oModule->getLayoutFile()) $this->setLayoutFile($oModule->getLayoutFile());
$this->adds($oModule->getVariables()); $this->adds($oModule->getVariables());
$this->setMessage($oModule->getMessage());
$this->setError($oModule->getError());
// forward 모듈을 찾지 못했다면 원 모듈의 default index action을 실행 // forward 모듈을 찾지 못했다면 원 모듈의 default index action을 실행
} else if($this->xml_info->default_index_act && method_exists($this, $this->xml_info->default_index_act)) { } else if($this->xml_info->default_index_act && method_exists($this, $this->xml_info->default_index_act)) {
@ -323,7 +330,7 @@
$called_position = 'after_module_proc'; $called_position = 'after_module_proc';
$oAddonController = &getController('addon'); $oAddonController = &getController('addon');
$addon_file = $oAddonController->getCacheFilePath(); $addon_file = $oAddonController->getCacheFilePath();
if(file_exists($addon_file)) @include($addon_file); @include($addon_file);
if(is_a($output, 'Object') || is_subclass_of($output, 'Object')) { if(is_a($output, 'Object') || is_subclass_of($output, 'Object')) {
$this->setError($output->getError()); $this->setError($output->getError());

View file

@ -2,9 +2,9 @@
/** /**
* @class Object * @class Object
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief 모듈간의 데이터를 주고 받기 위한 클래스 * @brief Base class design to pass the Object instance between XE Modules
* *
* 모든 모듈은 Object를 상속하며 Object의 error, message, variables 이용하여 통신을 하게 된다 * @remark Every modules inherits from Object class. It includes error, message, and other variables for communicatin purpose
**/ **/
class Object { class Object {
@ -23,21 +23,25 @@
} }
/** /**
* @brief error 코드를 지정 * @brief Setter to set error code
* @param[in] $error error code
**/ **/
function setError($error = 0) { function setError($error = 0) {
$this->error = $error; $this->error = $error;
} }
/** /**
* @brief error 코드를 return * @brief Getter to retrieve error code
**/ **/
function getError() { function getError() {
return $this->error; return $this->error;
} }
/** /**
* @brief 에러 메세지 지정 * @brief Setter to set set the error message
* @param[in] $message a messge string
* @return return True
* @remark this method always returns True. We'd better remove it
**/ **/
function setMessage($message = 'success') { function setMessage($message = 'success') {
if(Context::getLang($message)) $message = Context::getLang($message); if(Context::getLang($message)) $message = Context::getLang($message);
@ -46,21 +50,24 @@
} }
/** /**
* @brief 에러 메세지 return * @brief getter to retrieve an error message
**/ **/
function getMessage() { function getMessage() {
return $this->message; return $this->message;
} }
/** /**
* @brief 추가 변수 * @brief setter to set a key/value pair as an additional variable
* @param[in] $key a variable name
* @param[in] $val a value for the variable
**/ **/
function add($key, $val) { function add($key, $val) {
$this->variables[$key] = $val; $this->variables[$key] = $val;
} }
/** /**
* @brief 추가된 변수의 key, value들을 추가 * @brief method to set multiple key/value pairs as an additional variables
* @param[in] $object either object or array containg key/value pairs to be added
**/ **/
function adds($object) { function adds($object) {
if(is_object($object)) { if(is_object($object)) {
@ -72,15 +79,17 @@
} }
/** /**
* @brief 추가된 변수의 key에 해당하는 값을 return * @brief method to retrieve a corresponding value to a given key
**/ **/
function get($key) { function get($key) {
return $this->variables[$key]; return $this->variables[$key];
} }
/** /**
* @brief 추가된 변수의 key들에 해당하는 값을 return * @brief method to retrieve an object containing a key/value paris
**/ * @return Returns an object containing key/value pairs
**/
function gets() { function gets() {
$num_args = func_num_args(); $num_args = func_num_args();
$args_list = func_get_args(); $args_list = func_get_args();
@ -92,26 +101,34 @@
} }
/** /**
* @brief 추가변수 전체 return * @brief method to retrieve an array of key/value pairs
* @return Return a list of key/value pairs
**/ **/
function getVariables() { function getVariables() {
return $this->variables; return $this->variables;
} }
/**
* @brief method to retrieve an object of key/value pairs
* @return Return an object of key/value pairs
**/
function getObjectVars() { function getObjectVars() {
foreach($this->variables as $key => $val) $output->{$key} = $val; foreach($this->variables as $key => $val) $output->{$key} = $val;
return $output; return $output;
} }
/** /**
* @brief error값이 0 아니면 오류 * @brief method to return either true or false depnding on the value in a 'error' variable
* @remark this method is misleading in that it returns true if error is 0, which should be true in
* boolean representation.
**/ **/
function toBool() { function toBool() {
return $this->error==0?true:false; return $this->error==0?true:false;
} }
/** /**
* @brief error값이 0 아니면 오류 (Object::toBool() aliasing) * @brief method to return either true or false depnding on the value in a 'error' variable
**/ **/
function toBoolean() { function toBoolean() {
return $this->toBool(); return $this->toBool();

View file

@ -2,11 +2,8 @@
/** /**
* @class Optimizer * @class Optimizer
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief JS/CSS파일등을 특정한 규칙에 맞게 하나의 파일로 만들어서 client에서 가져갈 있도록 성능향상을 지원하는 클래스 * @brief class designed to be used to merge mutiple JS/CSS files into one file to shorten time taken for transmission.
* *
* 일단 내부적인 코드가 아무리 튜닝이 되어도 모듈/애드온/위젯/에디터컴포넌트등 요소들의 JS/CSs파일들을 잘라서 호출하는 구조이기에
* 사용자의 브라우저에서는 최소 10이상의 파일을 별도로 서버에 요청을 하게 된다.
* 이를 방지하기 위해서 서버내의 로컬 파일일 경우 하나로 묶어서 클라이언트에서 가져갈 있도록 하여 효과를 증대시킴.
**/ **/
class Optimizer { class Optimizer {
@ -14,8 +11,8 @@
var $cache_path = "./files/cache/optimized/"; var $cache_path = "./files/cache/optimized/";
/** /**
* @brief optimizer에서 캐싱파일을 저장할 곳을 찾아서 없으면 만듬 * @brief Constructor which check if a directory, 'optimized' exists in designated path. If not create a new one
**/ **/
function Optimizer() { function Optimizer() {
if(!is_dir($this->cache_path)) { if(!is_dir($this->cache_path)) {
FileHandler::makeDir($this->cache_path); FileHandler::makeDir($this->cache_path);
@ -23,7 +20,8 @@
} }
/** /**
* @brief 파일 목록 배열에서 optimized 첨자를 제거한 return * @brief file that removes 'optimized' in a given array
* @param[in] $files an array to be modified
**/ **/
function _getOptimizedRemoved($files) { function _getOptimizedRemoved($files) {
foreach($files as $key => $val) unset($files[$key]['optimized']); foreach($files as $key => $val) unset($files[$key]['optimized']);
@ -31,7 +29,10 @@
} }
/** /**
* @brief optimize 대상 파일을 받아서 처리 optimize 파일이름을 return * @brief method that optimizes a given file and returns a resultant file
* @param[in] source_files an array of source files to be optimized
* @param[in] type a type of source file, either js or css.
* @return Returns a optimized file
**/ **/
function getOptimizedFiles($source_files, $type = "js") { function getOptimizedFiles($source_files, $type = "js") {
if(!is_array($source_files) || !count($source_files)) return; if(!is_array($source_files) || !count($source_files)) return;
@ -89,7 +90,8 @@
} }
/** /**
* @brief 파일 목록 배열에서 file을 제외한 나머지 첨자를 제거하여 return * @brief retrive a list of files from a given parameter
* @param[in] files a list containing files
**/ **/
function _getOnlyFileList($files) { function _getOnlyFileList($files) {
foreach($files as $key => $val) $files[$key] = $val['file']; foreach($files as $key => $val) $files[$key] = $val['file'];
@ -97,11 +99,11 @@
} }
/** /**
* @brief optimize는 대상 파일을 \n로 연결후 md5 hashing하여 파일이름의 중복을 피함 * @brief method to generate a unique key from list of files along with a last modified date
* 개별 파일과 optimizer 클래스 파일의 변경을 적용하기 위해 파일들과 Optimizer.class.php의 filemtime을 비교, 파일이름에 반영 * @param[in] files an array containing file names
**/ **/
function getOptimizedInfo($files) { function getOptimizedInfo($files) {
// 개별 요소들 또는 Optimizer.class.php파일이 갱신되었으면 새로 옵티마이징 // 개별 요소 파일이 갱신되었으면 새로 옵티마이징
$count = count($files); $count = count($files);
$last_modified = 0; $last_modified = 0;
for($i=0;$i<$count;$i++) { for($i=0;$i<$count;$i++) {
@ -115,7 +117,11 @@
} }
/** /**
* @brief 이미 저장된 캐시 파일과의 시간등을 검사하여 새로 캐싱해야 할지를 체크 * @brief method that check if a valid cache file exits for a given filename. If not create new one.
* @param[in] path directory path of the cache files
* @param[in] filename a filename for cache files
* @param[in] targets
* @param[in] type a type of cache file
**/ **/
function doOptimizedFile($path, $filename, $targets, $type) { function doOptimizedFile($path, $filename, $targets, $type) {
// 대상 파일이 있으면 그냥 패스~ // 대상 파일이 있으면 그냥 패스~
@ -129,14 +135,18 @@
} }
/** /**
* @brief css나 js파일을 묶어서 하나의 파일로 만들고 gzip 압축이나 헤더등을 통제하기 위해서 php파일을 별도로 만들어서 진행함 * @brief method produce a php code to merge css/js files, compress the resultant files and modified the HTML header accordingly.
* @param[in] path
* @param[in] filename a name of a resultant file
* @param[in] targets list of files to be used for the operation
* @param[in] type a type of file such as css or js
* @return NONE
**/ **/
function makeOptimizedFile($path, $filename, $targets, $type) { function makeOptimizedFile($path, $filename, $targets, $type) {
/** /**
* 실제 css나 js의 내용을 합친 것을 구함 * 실제 css나 js의 내용을 합친 것을 구함
**/ **/
// 대상 파일의 내용을 구해오고 css 파일일 경우 url()내의 경로를 변경 // 대상 파일의 내용을 구해오고 css 파일일 경우 url()내의 경로를 변경
$content_filename = substr($filename, 0, -4); $content_filename = substr($filename, 0, -4);
$file_object = FileHandler::openFile($path."/".$content_filename, "w"); $file_object = FileHandler::openFile($path."/".$content_filename, "w");
@ -144,7 +154,7 @@
foreach($targets as $file) { foreach($targets as $file) {
$str = FileHandler::readFile($file['file']); $str = FileHandler::readFile($file['file']);
$str = Context::convertEncodingStr($str); $str = trim(Context::convertEncodingStr($str));
// css 일경우 background:url() 변경 / media 적용 // css 일경우 background:url() 변경 / media 적용
if($type == 'css') { if($type == 'css') {
@ -215,7 +225,10 @@ if(!$cached) {
} }
/** /**
* @brief css의 경우 import/ background 등의 속성에서 사용되는 url내의 경로를 변경시켜줌 * @brief method that modify a path for import or background element in a given css file
* @param[in] file a file to be modified
* @param[in] str a buffer to store resultant content
* @return Returns resultant content
**/ **/
function replaceCssPath($file, $str) { function replaceCssPath($file, $str) {
// css 파일의 위치를 구함 // css 파일의 위치를 구함
@ -230,6 +243,12 @@ if(!$cached) {
return $str; return $str;
} }
/**
* @brief callback method that is responsible for replacing strings in css file with predefined ones.
* @param[in] matches a list of strings to be examined and modified if necessary
* @return Returns resultant content
**/
function _replaceCssPath($matches) { function _replaceCssPath($matches) {
static $abpath = null; static $abpath = null;
if(is_null($abpath)) { if(is_null($abpath)) {
@ -246,6 +265,5 @@ if(!$cached) {
return 'url("'.$target.'")'; return 'url("'.$target.'")';
} }
} }
?> ?>

View file

@ -32,11 +32,11 @@
} }
/** /**
* @brief compiles specified tpl file * @brief compiles specified tpl file and execution result in Context into resultant content
* @param[in] $tpl_path path of the directory containing target template file * @param[in] $tpl_path path of the directory containing target template file
* @param[in] $tpl_filename target template file's name * @param[in] $tpl_filename target template file's name
* @param[in] $tpl_file if specified use it as template file's full path * @param[in] $tpl_file if specified use it as template file's full path
* @return compiled result * @return Returns compiled result in case of success, NULL otherwise
*/ */
function compile($tpl_path, $tpl_filename, $tpl_file = '') { function compile($tpl_path, $tpl_filename, $tpl_file = '') {
// store the starting time for debug information // store the starting time for debug information
@ -73,7 +73,7 @@
* @brief compile specified file and immediately return * @brief compile specified file and immediately return
* @param[in] $tpl_path path of the directory containing target template file * @param[in] $tpl_path path of the directory containing target template file
* @param[in] $tpl_filename target template file's name * @param[in] $tpl_filename target template file's name
* @return * @return Returns compiled content in case of success or NULL in case of failure
**/ **/
function compileDirect($tpl_path, $tpl_filename) { function compileDirect($tpl_path, $tpl_filename) {
$this->tpl_path = $tpl_path; $this->tpl_path = $tpl_path;
@ -86,24 +86,25 @@
} }
/** /**
* @brief compile if necessary * @brief compile a template file only if a cached template file does not exist or it is outdated.
* @param[in] $tpl_path path of the directory containing target template file * @param[in] $tpl_path a file path of the target template file
* @param[in] $tpl_filename target template file's name * @param[in] $compiled_tpl_file a file path of cached template file
* @return if compiled file exists and it is newer than template file return nothing, otherwise compiled result * @return Returns compiled template file if cached one does not exists or it is outdated, NULL otherwise
**/ **/
function _compile($tpl_file, $compiled_tpl_file) { function _compile($tpl_file, $compiled_tpl_file) {
if(!file_exists($compiled_tpl_file)) return $this->_compileTplFile($tpl_file, $compiled_tpl_file); if(!file_exists($compiled_tpl_file)) return $this->_compileTplFile($tpl_file, $compiled_tpl_file);
$source_ftime = filemtime(FileHandler::getRealPath($tpl_file)); $source_ftime = filemtime(FileHandler::getRealPath($tpl_file));
$target_ftime = filemtime($compiled_tpl_file); $target_ftime = filemtime($compiled_tpl_file);
if($source_ftime>$target_ftime || $target_ftime < filemtime(_XE_PATH_.'classes/template/TemplateHandler.class.php') ) return $this->_compileTplFile($tpl_file, $compiled_tpl_file); if($source_ftime>$target_ftime) return $this->_compileTplFile($tpl_file, $compiled_tpl_file);
} }
/** /**
* @brief compile tpl_file file * @brief compile a template file specified in $tpl_file and
* @pre files specified by $tpl_file exists.
* @param[in] $tpl_file path of tpl file * @param[in] $tpl_file path of tpl file
* @param[in] $compiled_tpl_file if specified, write compiled result into the file * @param[in] $compiled_tpl_file if specified, write compiled result into the file
* @return compiled result * @return compiled result in case of success or NULL in case of error
**/ **/
function _compileTplFile($tpl_file, $compiled_tpl_file = '') { function _compileTplFile($tpl_file, $compiled_tpl_file = '') {
@ -141,16 +142,16 @@
// prevent from calling directly before writing into file // prevent from calling directly before writing into file
$buff = sprintf('%s%s%s','<?php if(!defined("__ZBXE__")) exit();?>',"\n",$buff); $buff = sprintf('%s%s%s','<?php if(!defined("__ZBXE__")) exit();?>',"\n",$buff);
// write compiled code into file // write compiled code into file only if $compiled_tpl_file is not NULL
if($compiled_tpl_file) FileHandler::writeFile($compiled_tpl_file, $buff); if($compiled_tpl_file) FileHandler::writeFile($compiled_tpl_file, $buff);
return $buff; return $buff;
} }
/** /**
* @brief replace $... variables in { } into Context::get(...) * @brief replace $... variables in { } with Context::get(...)
* @param[in] $matches match * @param[in] $matches match
* @return replaced result * @return replaced result in case of success or NULL in case of error
**/ **/
function _compileVarToContext($matches) { function _compileVarToContext($matches) {
$str = trim(substr($matches[0],1,strlen($matches[0])-2)); $str = trim(substr($matches[0],1,strlen($matches[0])-2));
@ -164,8 +165,10 @@
} }
} else { } else {
list($class, $method) = explode('::',$func); list($class, $method) = explode('::',$func);
// FIXME regardless of whether class/func name is case-sensitive, it is safe
// to assume names are case sensitive. We don't have compare twice.
if(!class_exists($class) || !in_array($method, get_class_methods($class))) { if(!class_exists($class) || !in_array($method, get_class_methods($class))) {
// within some environment, name of classes and methods may be case-sensitive // In some environment, the name of classes and methods may be case-sensitive
list($class, $method) = explode('::',strtolower($func)); list($class, $method) = explode('::',strtolower($func));
if(!class_exists($class) || !in_array($method, get_class_methods($class))) { if(!class_exists($class) || !in_array($method, get_class_methods($class))) {
return $matches[0]; return $matches[0];
@ -181,6 +184,7 @@
/** /**
* @brief change image path * @brief change image path
* @pre $matches is an array containg three elements
* @param[in] $matches match * @param[in] $matches match
* @return changed result * @return changed result
**/ **/
@ -215,7 +219,7 @@
} }
/** /**
* @brief changed content in <!--@, --> into php code * @brief replace code in <!--@, --> with php code
* @param[in] $matches match * @param[in] $matches match
* @return changed result * @return changed result
**/ **/
@ -275,7 +279,7 @@
} }
/** /**
* @brief replace <!--#include $path--> * @brief replace <!--#include $path--> with php code
* @param[in] $matches match * @param[in] $matches match
* @return replaced result * @return replaced result
**/ **/
@ -303,7 +307,7 @@
// step1: check files in the template directory // step1: check files in the template directory
$source_filename = sprintf("%s/%s", dirname($this->tpl_file), $arg); $source_filename = sprintf("%s/%s", dirname($this->tpl_file), $arg);
// step2: check path from root2단계로 root로부터 경로를 체크 // step2: check path from root
if(!file_exists($source_filename)) $source_filename = './'.$arg; if(!file_exists($source_filename)) $source_filename = './'.$arg;
if(!file_exists($source_filename)) return; if(!file_exists($source_filename)) return;
@ -332,9 +336,9 @@
} }
/** /**
* @brief modify to include js filter/ css/ js according to extension of <!--%filename--> * @brief replace xe specific code, "<!--%filename-->" with appropriate php code
* @param[in] $matches match * @param[in] $matches match
* @return modified result * @return Returns modified result or NULL in case of error
**/ **/
function _compileImportCode($matches) { function _compileImportCode($matches) {
// find xml file // find xml file
@ -448,7 +452,7 @@
if(substr($given_file,0,1)!='/') $source_filename = sprintf("%s%s",$base_path, $given_file); if(substr($given_file,0,1)!='/') $source_filename = sprintf("%s%s",$base_path, $given_file);
else $source_filename = $given_file; else $source_filename = $given_file;
// get path and file name // get path and file nam
$tmp_arr = explode("/",$source_filename); $tmp_arr = explode("/",$source_filename);
$filename = array_pop($tmp_arr); $filename = array_pop($tmp_arr);

View file

@ -2,7 +2,8 @@
/** /**
* @class WidgetHandler * @class WidgetHandler
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief 위젯의 실행을 담당 * @brief Handler class for widget execution
* @remark it is empty for now, it would be removed in the future
**/ **/
class WidgetHandler { class WidgetHandler {

View file

@ -2,12 +2,17 @@
/** /**
* @class GeneralXmlParser * @class GeneralXmlParser
* @author haneul (haneul0318@gmail.com) * @author haneul (haneul0318@gmail.com)
* @brief XE에서 쓰는 XmlParser보다 좀더 범용으로 있는 Parser * @brief Generic XML parser for XE
* @version 0.1 * @version 0.1
*/ */
class GeneralXmlParser { class GeneralXmlParser {
var $output = array(); var $output = array();
/**
* @brief parse a given input to product a object containing parse values.
* @param[in] $input data to be parsed
* @return Returns an object containing parsed values or NULL in case of failure
*/
function parse($input = '') { function parse($input = '') {
$oParser = xml_parser_create('UTF-8'); $oParser = xml_parser_create('UTF-8');
xml_set_object($oParser, $this); xml_set_object($oParser, $this);
@ -23,9 +28,12 @@
return $this->output; return $this->output;
} }
/** /**
* @brief 태그 오픈 * @brief start element handler
**/ * @param[in] $parse an instance of parser
* @param[in] $node_name a name of node
* @param[in] $attrs attributes to be set
*/
function _tagOpen($parser, $node_name, $attrs) { function _tagOpen($parser, $node_name, $attrs) {
$obj->node_name = strtolower($node_name); $obj->node_name = strtolower($node_name);
$obj->attrs = $attrs; $obj->attrs = $attrs;
@ -34,30 +42,40 @@
array_push($this->output, $obj); array_push($this->output, $obj);
} }
/**
* @brief character data handler
* variable in the last element of this->output
* @param[in] $parse an instance of parser
* @param[in] $body a data to be added
*/
function _tagBody($parser, $body) { function _tagBody($parser, $body) {
//if(!trim($body)) return; //if(!trim($body)) return;
$this->output[count($this->output)-1]->body .= $body; $this->output[count($this->output)-1]->body .= $body;
} }
/**
* @brief 태그 닫음 /**
**/ * @brief end element handler
* @param[in] $parse an instance of parser
* @param[in] $node_name name of xml node
*/
function _tagClosed($parser, $node_name) { function _tagClosed($parser, $node_name) {
$node_name = strtolower($node_name); $node_name = strtolower($node_name);
$cur_obj = array_pop($this->output); $cur_obj = array_pop($this->output);
$parent_obj = &$this->output[count($this->output)-1]; $parent_obj = &$this->output[count($this->output)-1];
if($parent_obj->childNodes[$node_name]) { if($parent_obj->childNodes[$node_name])
$tmp_obj = $parent_obj->childNodes[$node_name]; {
if(is_array($tmp_obj)) { $tmp_obj = $parent_obj->childNodes[$node_name];
array_push($parent_obj->childNodes[$node_name], $cur_obj); if(is_array($tmp_obj)) {
} else { array_push($parent_obj->childNodes[$node_name], $cur_obj);
$parent_obj->childNodes[$node_name] = array(); } else {
array_push($parent_obj->childNodes[$node_name], $tmp_obj); $parent_obj->childNodes[$node_name] = array();
array_push($parent_obj->childNodes[$node_name], $cur_obj); array_push($parent_obj->childNodes[$node_name], $tmp_obj);
} array_push($parent_obj->childNodes[$node_name], $cur_obj);
} else { }
$parent_obj->childNodes[$node_name] = $cur_obj; } else {
$parent_obj->childNodes[$node_name] = $cur_obj;
} }
} }

View file

@ -1,269 +1,297 @@
<?php <?php
/** /**
* @class XmlJsFilter * @class XmlJsFilter
* @author zero (zero@nzeo.com) * @author taggon (gonom9@gmail.com)
* @brief filter xml문서를 해석하여 js파일로 만듬 * @brief filter class traslate xml content into javascript code
* @version 0.1 * @version 0.2
*
* it convert xml code into js file and save the result as a cache file
* @code
* {
* <filter name="name of javascript funcion" act="action name" confirm_msg_code="message string to be prompted when submitting the form" >
* <form> <-- code to validate data in the form
* <node target="name" required="true" minlength="1" maxlength="5" filter="email,userid,alpha,number" equalto="target" />
* </form>
* <parameter> <-- 항목을 조합하여 key=val js array로 return, act는 필수
* <param name="key" target="target" />
* </parameter>
* <response callback_func="callback 받게 될 js function 이름 지정" > <-- 서버에 ajax로 전송하여 받을 결과값
* <tag name="error" /> <-- error이름의 결과값을 받겠다는
* </response>
* </filter>
* }
* *
* xml filter 파일은 js script로 컴파일 되어 캐싱됨 * @detail {
* * - syntax description of <form> node
* <filter name="js function 이름" act="서버에 요청할 action 이름" confirm_msg_code="submit시에 prompt로 물어볼 메세지의 코드" > * target = name of for element
* <form> <-- 항목의 체크 * required = flag indicating whether a field is mandatory or not
* <node target="name" required="true" minlength="1" maxlength="5" filter="email,userid,alpha,number" equalto="target" /> * minlength, maxlength = mininum, maxinum length of string allowed for the field
* </form> * filter = name of filter to be used for javascript validation. Following is the description of filter available
* <parameter> <-- 항목을 조합하여 key=val js array로 return, act는 필수 * 1) email : validate the confirmance of the value against an email format
* <param name="key" target="target" /> * 2) userid : validate the confirmance of the value against the format of user id. (combination of number[0-9],alphabet(lower case) and '_', underscore starting with an alphatic character)
* </parameter> * 3) alpha : check if the value is consists of alphabatic characters.
* <response callback_func="callback 받게 될 js function 이름 지정" > <-- 서버에 ajax로 전송하여 받을 결과값 * 4) number : check if the value is consists of numerical digits
* <tag name="error" /> <-- error이름의 결과값을 받겠다는 * 5) equalto = target : indicate that values in the form should be equal to those in target
* </response> *
* </filter> * - parameter - param
* * name = key : indicate that a new array, 'key' will be created and a value will be assigned to it
* - form - node * target = target_name : target form element의 값을 가져옴
* target = element의 이름 *
* required = true/ false 있어야 하는지에 대한 체크 * - response
* minlength, maxlength = 최소/최대 길이 * tag = key : name of variable that will contain the result of the execution
* filter = javascript로 체크하기 위한 체크 필터 * }
* email : email의 형식 ( aaa.aaa@aaa.com) **/
* userid : 영문+숫자+_, 글자는 영문, 소문자
* alpha : 영문값만 허용
* number : 숫자만 허용
* equalto = target , 현재 폼과 지정 target의 값이 동일해야
*
* - parameter - param
* name = key : key를 이름으로 가지고 value의 값을 가지는 array 생성
* target = target_name : target form element의 값을 가져옴
*
* - response
* tag = key : return받을 결과값의 변수명
**/
class XmlJsFilter extends XmlParser { class XmlJsFilter extends XmlParser {
var $compiled_path = './files/cache/js_filter_compiled/'; ///< 컴파일된 캐시 파일이 놓일 위치 var $version = '0.2.3';
var $xml_file = NULL; ///< 대상 xml 파일 var $compiled_path = './files/cache/js_filter_compiled/'; ///< 컴파일된 캐시 파일이 놓일 위치
var $js_file = NULL; ///< 컴파일된 js 파일 var $xml_file = NULL; ///< 대상 xml 파일
var $js_file = NULL; ///< 컴파일된 js 파일
/** /**
* @brief constructor * @brief constructor
**/
function XmlJsFilter($path, $xml_file) {
if(substr($path,-1)!=='/') $path .= '/';
$this->xml_file = sprintf("%s%s",$path, $xml_file);
$this->js_file = $this->_getCompiledFileName($this->xml_file);
}
/**
* @brief compile a xml_file only when a corresponding js file does not exists or is outdated
* @return Returns NULL regardless of the success of failure of the operation
**/ **/
function XmlJsFilter($path, $xml_file) { function compile() {
if(substr($path,-1)!=='/') $path .= '/'; if(!file_exists($this->xml_file)) return;
$this->xml_file = sprintf("%s%s",$path, $xml_file); if(!file_exists($this->js_file)) $this->_compile();
$this->js_file = $this->_getCompiledFileName($this->xml_file); else if(filemtime($this->xml_file)>filemtime($this->js_file)) $this->_compile();
} Context::addJsFile($this->js_file);
}
/** /**
* @brief xml파일과 compiled된js파일의 시간 비교 유무 비교등을 처리 * @brief compile a xml_file into js_file
**/ **/
function compile() { function _compile() {
if(!file_exists($this->xml_file)) return; global $lang;
if(!file_exists($this->js_file)) $this->_compile();
else if(filemtime($this->xml_file)>filemtime($this->js_file)) $this->_compile();
Context::addJsFile($this->js_file);
}
/** // xml 파일을 읽음
* @brief 실제 xml_file을 컴파일하여 js_file을 생성 $buff = FileHandler::readFile($this->xml_file);
**/
function _compile() {
global $lang;
// xml 파일을 읽음 // xml parsing
$buff = FileHandler::readFile($this->xml_file); $xml_obj = parent::parse($buff);
// xml parsing // XmlJsFilter는 filter_name, field, parameter 3개의 데이터를 핸들링
$xml_obj = parent::parse($buff); $filter_name = $xml_obj->filter->attrs->name;
$confirm_msg_code = $xml_obj->filter->attrs->confirm_msg_code;
$module = $xml_obj->filter->attrs->module;
$act = $xml_obj->filter->attrs->act;
$extend_filter = $xml_obj->filter->attrs->extend_filter;
// XmlJsFilter는 filter_name, field, parameter 3개의 데이터를 핸들링 $field_node = $xml_obj->filter->form->node;
$filter_name = $xml_obj->filter->attrs->name; if($field_node && !is_array($field_node)) $field_node = array($field_node);
$confirm_msg_code = $xml_obj->filter->attrs->confirm_msg_code;
$module = $xml_obj->filter->attrs->module;
$act = $xml_obj->filter->attrs->act;
$extend_filter = $xml_obj->filter->attrs->extend_filter;
$field_node = $xml_obj->filter->form->node; $parameter_param = $xml_obj->filter->parameter->param;
if($field_node && !is_array($field_node)) $field_node = array($field_node); if($parameter_param && !is_array($parameter_param)) $parameter_param = array($parameter_param);
$parameter_param = $xml_obj->filter->parameter->param; $response_tag = $xml_obj->filter->response->tag;
if($parameter_param && !is_array($parameter_param)) $parameter_param = array($parameter_param); if($response_tag && !is_array($response_tag)) $response_tag = array($response_tag);
$response_tag = $xml_obj->filter->response->tag; // extend_filter가 있을 경우 해당 method를 호출하여 결과를 받음
if($response_tag && !is_array($response_tag)) $response_tag = array($response_tag); if($extend_filter) {
// extend_filter가 있을 경우 해당 method를 호출하여 결과를 받음 // extend_filter가 있을 경우 캐시 사용을 못하도록 js 캐시 파일명을 변경
if($extend_filter) { $this->js_file .= '.nocache.js';
// extend_filter가 있을 경우 캐시 사용을 못하도록 js 캐시 파일명을 변경 // extend_filter는 module.method 로 지칭되어 이를 분리
$this->js_file .= '.nocache.js'; list($module_name, $method) = explode('.',$extend_filter);
// extend_filter는 module.method 로 지칭되어 이를 분리 // 모듈 이름과 method가 있을 경우 진행
list($module_name, $method) = explode('.',$extend_filter); if($module_name&&$method) {
// 해당 module의 model 객체를 받음
$oExtendFilter = &getModel($module_name);
// 모듈 이름과 method가 있을 경우 진행 // method가 존재하면 실행
if($module_name&&$method) { if(method_exists($oExtendFilter, $method)) {
// 해당 module의 model 객체를 받음 // 결과를 받음
$oExtendFilter = &getModel($module_name); $extend_filter_list = $oExtendFilter->{$method}(true);
$extend_filter_count = count($extend_filter_list);
// method가 존재하면 실행 // 결과에서 lang값을 이용 문서 변수에 적용
if(method_exists($oExtendFilter, $method)) { for($i=0; $i < $extend_filter_count; $i++) {
// 결과를 받음 $name = $extend_filter_list[$i]->name;
//$extend_filter_list = call_user_method($method, $oExtendFilter, true); $lang_value = $extend_filter_list[$i]->lang;
//$extend_filter_list = call_user_func(array($oExtendFilter, $method)); if($lang_value) $lang->{$name} = $lang_value;
$extend_filter_list = $oExtendFilter->{$method}(true); }
$extend_filter_count = count($extend_filter_list); }
// 결과에서 lang값을 이용 문서 변수에 적용 }
for($i=0;$i<$extend_filter_count;$i++) { }
$name = $extend_filter_list[$i]->name;
$lang_value = $extend_filter_list[$i]->lang;
if($lang_value) $lang->{$name} = $lang_value;
}
}
} $callback_func = $xml_obj->filter->response->attrs->callback_func;
} if(!$callback_func) $callback_func = "filterAlertMessage";
$callback_func = $xml_obj->filter->response->attrs->callback_func; // 언어 입력을 위한 사용되는 필드 조사
if(!$callback_func) $callback_func = "filterAlertMessage"; $target_list = array();
$target_type_list = array();
// 언어 입력을 위한 사용되는 필드 조사 // js function 을 만들기 시작
$target_list = array(); $js_doc = array();
$target_type_list = array(); $js_doc[] = "function {$filter_name}(fo_obj){";
$js_doc[] = "\tvar validator = xe.getApp('validator')[0];";
$js_doc[] = "\tif(!validator) return false;";
$js_doc[] = "\tif(!fo_obj.elements['_filter']) jQuery(fo_obj).prepend('<input type=\"hidden\" name=\"_filter\" value=\"\" />');";
$js_doc[] = "\tfo_obj.elements['_filter'].value = '{$filter_name}';";
// js function 을 만들기 시작 $jsdoc = array();
$js_doc = sprintf("function %s(fo_obj) {\n", $filter_name); $jsdoc[] = '(function($){';
$js_doc .= sprintf("\tvar oFilter = new XmlJsFilter(fo_obj, \"%s\", \"%s\", %s);\n", $module, $act, $callback_func); $jsdoc[] = "\tvar validator = xe.getApp('Validator')[0];";
$jsdoc[] = "\tif(!validator) return false;";
$jsdoc[] = "\tvalidator.cast('ADD_FILTER', ['{$filter_name}', {";
// field, 즉 체크항목의 script 생성 $fields = array();
$node_count = count($field_node);
if($node_count) {
foreach($field_node as $key =>$node) {
$attrs = $node->attrs;
$target = trim($attrs->target);
if(!$target) continue;
$required = $attrs->required=='true'?'true':'false';
$minlength = $attrs->minlength>0?$attrs->minlength:'0';
$maxlength = $attrs->maxlength>0?$attrs->maxlength:'0';
$equalto = trim($attrs->equalto);
$filter = $attrs->filter;
$js_doc .= sprintf( // field, 즉 체크항목의 script 생성
"\toFilter.addFieldItem(\"%s\",%s,%s,%s,\"%s\",\"%s\");\n", $node_count = count($field_node);
$target, $required, $minlength, $maxlength, $equalto, $filter if($node_count) {
); foreach($field_node as $key =>$node) {
$attrs = $node->attrs;
$target = trim($attrs->target);
if(!$target) continue;
$filter = $attrs->filter;
if(!in_array($target, $target_list)) $target_list[] = $target; $attrs->equalto = trim($attrs->equalto);
if(!$target_type_list[$target]) $target_type_list[$target] = $filter;
}
}
// extend_filter_item 체크 $field = array();
for($i=0;$i<$extend_filter_count;$i++) { if($attrs->required == 'true') $field[] = 'required:true';
$filter_item = $extend_filter_list[$i]; if($attrs->minlength > 0) $field[] = 'minlength:'.$attrs->minlength;
$target = trim($filter_item->name); if($attrs->maxlength > 0) $field[] = 'maxlength:'.$attrs->maxlength;
if(!$target) continue; if($attrs->equalto) $field[] = "equalto:'{$attrs->equalto}'";
$type = $filter_item->type; if($attrs->filter) $field[] = "rule:'{$attrs->filter}'";
$required = $filter_item->required?'true':'false'; $s_field = implode(',', $field);
$fields[] = "\t\t'{$target}': {{$s_field}}";
// extend filter item의 type으로 filter를 구함 if(!in_array($target, $target_list)) $target_list[] = $target;
switch($type) { if(!$target_type_list[$target]) $target_type_list[$target] = $filter;
case 'homepage' : }
$filter = 'homepage'; }
break;
case 'email_address' :
$filter = 'email';
break;
default :
$filter = '';
break;
}
$js_doc .= sprintf( // extend_filter_item 체크
"\toFilter.addFieldItem(\"%s\",%s,%s,%s,\"%s\",\"%s\");\n", for($i=0;$i<$extend_filter_count;$i++) {
$target, $required, 0, 0, '', $filter $filter_item = $extend_filter_list[$i];
); $target = trim($filter_item->name);
if(!$target) continue;
$type = $filter_item->type;
$required = $filter_item->required?'true':'false';
if(!in_array($target, $target_list)) $target_list[] = $target; // extend filter item의 type으로 filter를 구함
if(!$target_type_list[$target]) $target_type_list[$target] = $type; $types = array('homepage'=>'homepage', 'email_address'=>'email');
$filter = $types[$type]?$types[$type]:'';
} $field = array();
if($filter_item->required == 'true') $field[] = 'required:true';
if($filter) $field[] = "rule:'{$filter}'";
$s_field = implode(',', $field);
$fields[] = "\t\t'{$target}' : {{$s_field}}";
// 데이터를 만들기 위한 parameter script 생성 if(!in_array($target, $target_list)) $target_list[] = $target;
$parameter_count = count($parameter_param); if(!$target_type_list[$target]) $target_type_list[$target] = $type;
if($parameter_count) { }
// 기본 필터 내용의 parameter로 구성
foreach($parameter_param as $key =>$param) {
$attrs = $param->attrs;
$name = trim($attrs->name);
$target = trim($attrs->target);
if(!$name || !$target) continue;
$target = htmlentities($target,ENT_QUOTES);
$js_doc .= sprintf( $jsdoc[] = implode(",\n", $fields);
"\toFilter.addParameterItem(\"%s\",\"%s\");\n", $jsdoc[] = "\t}]);";
$name, $target
);
if(!in_array($name, $target_list)) $target_list[] = $name;
}
// extend_filter_item 체크 // javascript callback function
for($i=0;$i<$extend_filter_count;$i++) { $js_doc[] = "\tvalidator.cast('ADD_CALLBACK', ['{$filter_name}', function(form){";
$filter_item = $extend_filter_list[$i]; $js_doc[] = "\t\tvar params={}, responses=[], elms=form.elements, data=jQuery(form).serializeArray();";
$target = $name = trim($filter_item->name); $js_doc[] = "\t\tjQuery.each(data, function(i, field){";
if(!$name || !$target) continue; $js_doc[] = "\t\t\tvar val = jQuery.trim(field.value);";
$target = htmlentities($target,ENT_QUOTES); $js_doc[] = "\t\t\tif(!val) return true;";
$js_doc[] = "\t\t\tif(/\[\]$/.test(field.name)) field.name = field.name.replace(/\[\]$/, '');";
$js_doc[] = "\t\t\tif(params[field.name]) params[field.name] += '|@|'+val;";
$js_doc[] = "\t\t\telse params[field.name] = field.value;";
$js_doc[] = "\t\t});";
$js_doc .= sprintf( // 데이터를 만들기 위한 parameter script 생성
"\toFilter.addParameterItem(\"%s\",\"%s\");\n", $parameter_count = count($parameter_param);
$name, $target if($parameter_count) {
); // 기본 필터 내용의 parameter로 구성
if(!in_array($name, $target_list)) $target_list[] = $name; foreach($parameter_param as $key =>$param) {
} $attrs = $param->attrs;
} $name = trim($attrs->name);
$target = trim($attrs->target);
// response script 생성 if($name && $target && ($name != $target)) $js_doc[] = "\t\tparams['{$name}'] = params['{$target}']; delete params['{$target}'];";
$response_count = count($response_tag); if($name && !in_array($name, $target_list)) $target_list[] = $name;
for($i=0;$i<$response_count;$i++) { }
$attrs = $response_tag[$i]->attrs;
$name = $attrs->name;
$js_doc .= sprintf("\toFilter.addResponseItem(\"%s\");\n", $name);
}
if($confirm_msg_code) $js_doc .= sprintf("\treturn oFilter.proc(\"%s\");\n",str_replace('"','\"',$lang->{$confirm_msg_code})); // extend_filter_item 체크
else $js_doc .= sprintf("\treturn oFilter.proc();\n"); for($i=0;$i<$extend_filter_count;$i++) {
$js_doc .= "}\n"; $filter_item = $extend_filter_list[$i];
$target = $name = trim($filter_item->name);
if(!$name || !$target) continue;
// form 필드 lang 값을 기록 if(!in_array($name, $target_list)) $target_list[] = $name;
$target_count = count($target_list); }
for($i=0;$i<$target_count;$i++) { }
$target = $target_list[$i];
if(!$lang->{$target}) $lang->{$target} = $target;
$js_doc .= sprintf("alertMsg[\"%s\"] = \"%s\";\n", $target, str_replace("\"","\\\"",$lang->{$target}));
}
// target type을 기록 // response script 생성
$target_type_count = count($target_type_list); $response_count = count($response_tag);
if($target_type_count) { $responses = array();
foreach($target_type_list as $target => $type) { for($i=0;$i<$response_count;$i++) {
$js_doc .= sprintf("target_type_list[\"%s\"] = \"%s\";\n", $target, $type); $attrs = $response_tag[$i]->attrs;
} $name = $attrs->name;
} $responses[] = "'{$name}'";
}
$js_doc[] = "\t\tresponses = [".implode(',', $responses)."];";
// 에러 메세지를 기록 if ($confirm_msg_code) $js_doc[] = sprintf("\t\tif(!confirm('%s')) return false;", $lang->{$confirm_msg_code});
foreach($lang->filter as $key => $val) {
if(!$val) $val = $key;
$js_doc .= sprintf("alertMsg[\"%s\"] = \"%s\";\n", $key, str_replace("\"","\\\"",$val));
}
// js파일 생성 $js_doc[] = "\t\texec_xml('{$module}','{$act}', params, {$callback_func}, responses, params, form);";
FileHandler::writeFile($this->js_file, $js_doc); $js_doc[] = "\t}]);";
}
/** // form 필드 lang 값을 기록
* @brief $xml_file로 compiled_xml_file이름을 return $target_count = count($target_list);
**/ for($i=0;$i<$target_count;$i++) {
function _getCompiledFileName($xml_file) { $target = $target_list[$i];
return sprintf('%s%s.%s.compiled.js',$this->compiled_path, md5($xml_file),Context::getLangType()); if(!$lang->{$target}) $lang->{$target} = $target;
} $jsdoc[] = sprintf("\tvalidator.cast('ADD_MESSAGE', ['%s', '%s']);", $target, str_replace('\'', '\\\'', $lang->{$target}));
} }
// target type을 기록
/*
$target_type_count = count($target_type_list);
if($target_type_count) {
foreach($target_type_list as $target => $type) {
//$js_doc .= sprintf("target_type_list[\"%s\"] = \"%s\";\n", $target, $type);
}
}
*/
// 에러 메세지를 기록
foreach($lang->filter as $key => $val) {
if(!$val) $val = $key;
$jsdoc[] = sprintf("\tvalidator.cast('ADD_MESSAGE', ['%s', '%s']);", $key, $val);
//$jsdoc[] = sprintf("\tvalidator.cast('ADD_MESSAGE', ['%s', '%s']);", $key, str_replace('\'', '\\\'', $val));
}
$jsdoc[] = '})(jQuery);';
$js_doc[] = "\tvalidator.cast('VALIDATE', [fo_obj,'{$filter_name}']);";
$js_doc[] = "\treturn false;";
$js_doc[] = "};\n";
$js_doc = implode("\n", $js_doc);
$jsdoc = implode("\n", $jsdoc);
// js파일 생성
FileHandler::writeFile($this->js_file, $js_doc."\n".$jsdoc);
}
/**
* @brief return a file name of js file corresponding to the xml file
**/
function _getCompiledFileName($xml_file) {
return sprintf('%s%s.%s.compiled.js',$this->compiled_path, md5($this->version.$xml_file),Context::getLangType());
}
}
?> ?>

View file

@ -2,11 +2,14 @@
/** /**
* @class XmlParser * @class XmlParser
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief xmlrpc를 해석하여 object로 return 하는 simple xml parser * @brief class parsing a given xmlrpc request and creating a data object
* @version 0.1 * @version 0.1
* *
* xml 데이터의 attribute중에 xml:lang="ko,en,ch,jp,..." 있을 경우 지정된 lang 값에 해당하는 것만 남기는 트릭이 적용됨. * @remarks {
* 무슨 문제를 일으킬지는 현재 모르나 동작하고 있음 * This class may drops unsupported xml lanuage attributes when multiple language attributes are given.
* For example, if 'xml:lang='ko, en, ch, jp..' is given in a xml file, only ko will be left ignoring all other language
* attributes when kor is only supported language. It seems to work fine now but we did not scrutinze any potential side effects,
* }
**/ **/
class XmlParser { class XmlParser {
@ -19,7 +22,9 @@
var $lang = "en"; ///< 기본 언어타입 var $lang = "en"; ///< 기본 언어타입
/** /**
* @brief xml 파일을 로딩하여 parsing 처리 return * @brief load a xml file specified by a filename and parse it to return the resultant data object
* @param[in] $filename a file path of file
* @return Returns a data object containing data extracted from a xml file or NULL if a specified file does not exist
**/ **/
function loadXmlFile($filename) { function loadXmlFile($filename) {
if(!file_exists($filename)) return; if(!file_exists($filename)) return;
@ -30,7 +35,9 @@
} }
/** /**
* @brief xml 파싱 * @brief parse xml data to extract values from it and construct data object
* @param[in] a data buffer containing xml data
* @return Returns a resultant data object or NULL in case of error
**/ **/
function parse($input = '') { function parse($input = '') {
// 디버그를 위한 컴파일 시작 시간 저장 // 디버그를 위한 컴파일 시작 시간 저장
@ -39,6 +46,7 @@
$this->lang = Context::getLangType(); $this->lang = Context::getLangType();
$this->input = $input?$input:$GLOBALS['HTTP_RAW_POST_DATA']; $this->input = $input?$input:$GLOBALS['HTTP_RAW_POST_DATA'];
$this->input = str_replace(array('',''),array('',''),$this->input);
// 지원언어 종류를 뽑음 // 지원언어 종류를 뽑음
preg_match_all("/xml:lang=\"([^\"].+)\"/i", $this->input, $matches); preg_match_all("/xml:lang=\"([^\"].+)\"/i", $this->input, $matches);
@ -77,9 +85,13 @@
return $output; return $output;
} }
/**
* @brief 태그 오픈 /**
**/ * @brief start element handler.
* @param[in] $parse an instance of parser
* @param[in] $node_name a name of node
* @param[in] $attrs attributes to be set
*/
function _tagOpen($parser, $node_name, $attrs) { function _tagOpen($parser, $node_name, $attrs) {
$obj->node_name = strtolower($node_name); $obj->node_name = strtolower($node_name);
$obj->attrs = $this->_arrToObj($attrs); $obj->attrs = $this->_arrToObj($attrs);
@ -87,17 +99,24 @@
array_push($this->output, $obj); array_push($this->output, $obj);
} }
/**
* @brief body 내용 /**
**/ * @brief character data handler
* variable in the last element of this->output
* @param[in] $parse an instance of parser
* @param[in] $body a data to be added
* @remark the first parameter, $parser ought to be remove since it is not used.
*/
function _tagBody($parser, $body) { function _tagBody($parser, $body) {
//if(!trim($body)) return; //if(!trim($body)) return;
$this->output[count($this->output)-1]->body .= $body; $this->output[count($this->output)-1]->body .= $body;
} }
/** /**
* @brief 태그 닫음 * @brief end element handler
**/ * @param[in] $parse an instance of parser
* @param[in] $node_name name of xml node
*/
function _tagClosed($parser, $node_name) { function _tagClosed($parser, $node_name) {
$node_name = strtolower($node_name); $node_name = strtolower($node_name);
$cur_obj = array_pop($this->output); $cur_obj = array_pop($this->output);
@ -120,8 +139,9 @@
} }
/** /**
* @brief 파싱한 결과를 object vars에 담기 위한 method * @brief method to transfer values in an array to a data object
**/ * @param[in] $arr data array
**/
function _arrToObj($arr) { function _arrToObj($arr) {
if(!count($arr)) return; if(!count($arr)) return;
foreach($arr as $key => $val) { foreach($arr as $key => $val) {

View file

@ -2,16 +2,25 @@
/** /**
* @class XmlQueryParser * @class XmlQueryParser
* @author zero (zero@nzeo.com) * @author zero (zero@nzeo.com)
* @brief query xml을 파싱하여 캐싱을 결과를 return * @brief case to parse XE xml query
* @version 0.1 * @version 0.1
* *
* @todo subquery나 union등의 확장 쿼리에 대한 지원이 필요 * @todo need to support extend query such as subquery, union
**/ **/
class XmlQueryParser extends XmlParser { class XmlQueryParser extends XmlParser {
var $default_list = array();
var $notnull_list = array();
var $filter_list = array();
/** /**
* @brief 쿼리 파일을 찾아서 파싱하고 캐싱한다 * @brief parse a xml query file and save the result as a new file specified by cache_file
* @param[in] $query_id name of query
* @param[in] $xml_file file path of a xml query file to be loaded
* @param[in] $cache_file file path of a cache file to store resultant php code after parsing xml query
* @return Nothing is requred.
* @remarks {there should be a way to report an error}
**/ **/
function parse($query_id, $xml_file, $cache_file) { function parse($query_id, $xml_file, $cache_file) {
// query xml 파일을 찾아서 파싱, 결과가 없으면 return // query xml 파일을 찾아서 파싱, 결과가 없으면 return
@ -194,15 +203,15 @@
} }
// default check // default check
if(count($default_list)) { if(count($this->default_list)) {
foreach($default_list as $key => $val) { foreach($this->default_list as $key => $val) {
$pre_buff .= 'if(!isset($args->'.$key.')) $args->'.$key.' = '.$val.';'."\n"; $pre_buff .= 'if(!isset($args->'.$key.')) $args->'.$key.' = '.$val.';'."\n";
} }
} }
// not null check // not null check
if(count($notnull_list)) { if(count($this->notnull_list)) {
foreach($notnull_list as $key => $val) { foreach($this->notnull_list as $key => $val) {
$pre_buff .= 'if(!isset($args->'.$val.')) return new Object(-1, sprintf($lang->filter->isnull, $lang->'.$val.'?$lang->'.$val.':\''.$val.'\'));'."\n"; $pre_buff .= 'if(!isset($args->'.$val.')) return new Object(-1, sprintf($lang->filter->isnull, $lang->'.$val.'?$lang->'.$val.':\''.$val.'\'));'."\n";
} }
} }
@ -222,10 +231,9 @@
} }
// filter check // filter check
if(count($filter_list)) { if(count($this->filter_list)) {
foreach($filter_list as $key => $val) { foreach($this->filter_list as $key => $val) {
if(!$notnull_list[$key]) continue; $pre_buff .= sprintf('if(isset($args->%s)) { unset($_output); $_output = $this->checkFilter("%s",$args->%s,"%s"); if(!$_output->toBool()) return $_output; } %s',$val->var, $val->var,$val->var,$val->filter,"\n");
$pre_buff .= sprintf('unset($_output); $_output = $this->checkFilter("%s",$args->%s,"%s"); if(!$_output->toBool()) return $_output;%s',$val->var,$val->var,$val->filter,"\n");
} }
} }
@ -240,6 +248,12 @@
FileHandler::writeFile($cache_file, $buff); FileHandler::writeFile($cache_file, $buff);
} }
/**
* @brief transfer given column information to object->columns
* @param[in] column information
* @result Returns $object
*/
function _setColumn($columns){ function _setColumn($columns){
if(!$columns) { if(!$columns) {
$output->column[] = array("*" => "*"); $output->column[] = array("*" => "*");
@ -270,6 +284,11 @@
return $output; return $output;
} }
/**
* @brief transfer condition information to $object->conditions
* @param[in] SQL condition information
* @result Returns $output
*/
function _setConditions($conditions){ function _setConditions($conditions){
// 조건절 정리 // 조건절 정리
@ -308,6 +327,11 @@
return $output; return $output;
} }
/**
* @brief transfer condition information to $object->groups
* @param[in] SQL group information
* @result Returns $output
*/
function _setGroup($group_list){ function _setGroup($group_list){
// group 정리 // group 정리
@ -325,6 +349,11 @@
} }
/**
* @brief transfer pagnation information to $output
* @param[in] $xml_obj xml object containing Navigation information
* @result Returns $output
*/
function _setNavigation($xml_obj){ function _setNavigation($xml_obj){
$navigation = $xml_obj->query->navigation; $navigation = $xml_obj->query->navigation;
if($navigation) { if($navigation) {
@ -348,6 +377,12 @@
return $output; return $output;
} }
/**
* @brief retrieve column information from $output->colums to generate corresponding php code
* @param[in] $column
* @remarks the name of this method is misleading.
* @result Returns string buffer containing php code
*/
function _getColumn($columns){ function _getColumn($columns){
$buff = ''; $buff = '';
$str = ''; $str = '';
@ -392,6 +427,12 @@
return $buff; return $buff;
} }
/**
* @brief retrieve condition information from $output->condition to generate corresponding php code
* @param[in] $conditions array containing Query conditions
* @remarks the name of this method is misleading.
* @return Returns string buffer containing php code
*/
function _getConditions($conditions){ function _getConditions($conditions){
$buff = ''; $buff = '';
foreach($conditions as $key => $val) { foreach($conditions as $key => $val) {
@ -400,9 +441,9 @@
$v->default = $this->getDefault($v->column, $v->default); $v->default = $this->getDefault($v->column, $v->default);
if($v->var) { if($v->var) {
if(strpos($v->var,".")===false) { if(strpos($v->var,".")===false) {
if($v->default) $default_list[$v->var] = $v->default; if($v->default) $this->default_list[$v->var] = $v->default;
if($v->filter) $filter_list[] = $v; if($v->filter) $this->filter_list[] = $v;
if($v->notnull) $notnull_list[] = $v->var; if($v->notnull) $this->notnull_list[] = $v->var;
if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s?$args->%s:%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->var, $v->default, $v->pipe, $v->operation, "\n"); if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s?$args->%s:%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->var, $v->default, $v->pipe, $v->operation, "\n");
else $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n"); else $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n");
} else { } else {
@ -418,12 +459,16 @@
return $buff; return $buff;
} }
/** /**
* @brief column, condition등의 key에 default 값을 세팅 * @brief returns predefined default values correspoding to given parameters
**/ * @param[in] $name
* @param[in] $value
* @return Returns a default value for specified field
*/
function getDefault($name, $value) { function getDefault($name, $value) {
$db_info = Context::getDBInfo (); $db_info = Context::getDBInfo ();
if(!$value) return; if(!isset($value)) return;
$str_pos = strpos($value, '('); $str_pos = strpos($value, '(');
if($str_pos===false) return '"'.$value.'"'; if($str_pos===false) return '"'.$value.'"';

View file

@ -643,11 +643,16 @@ function doDocumentSave(obj) {
editorRelKeys[editor_sequence]['content'].value = content; editorRelKeys[editor_sequence]['content'].value = content;
} }
var oFilter = new XmlJsFilter(obj.form, "member", "procMemberSaveDocument", completeDocumentSave); var params={}, responses=['error','message','document_srl'], elms=obj.form.elements, data=jQuery(obj.form).serializeArray();;
oFilter.addResponseItem("error"); jQuery.each(data, function(i, field){
oFilter.addResponseItem("message"); var val = jQuery.trim(field.value);
oFilter.addResponseItem("document_srl"); if(!val) return true;
oFilter.proc(); if(/\[\]$/.test(field.name)) field.name = field.name.replace(/\[\]$/, '');
if(params[field.name]) params[field.name] += '|@|'+val;
else params[field.name] = field.value;
});
exec_xml('member','procMemberSaveDocument', params, completeDocumentSave, responses, params, obj.form);
editorRelKeys[editor_sequence]['content'].value = prev_content; editorRelKeys[editor_sequence]['content'].value = prev_content;
return false; return false;

View file

@ -1,6 +1,9 @@
/** /**
* @brief XE Application Framework * @file js_app.js
* @author zero (zero@nzeo.com)
* @brief XE JavaScript Application Framework (JAF)
* @namespace xe * @namespace xe
* @update 20091120
*/ */
(function($){ (function($){
@ -56,6 +59,7 @@ _xe_base = {
* @brief Get one application * @brief Get one application
*/ */
getApp : function(indexOrName) { getApp : function(indexOrName) {
indexOrName = (indexOrName||'').toLowerCase();
if (typeof _apps[indexOrName] != 'undefined') { if (typeof _apps[indexOrName] != 'undefined') {
return _apps[indexOrName]; return _apps[indexOrName];
} else { } else {
@ -96,13 +100,13 @@ _xe_base = {
/** /**
* @brief overrides broadcast method * @brief overrides broadcast method
*/ */
broadcast : function(oSender, msg, params) { broadcast : function(sender, msg, params) {
for(var i=0; i < _apps.length; i++) { for(var i=0; i < _apps.length; i++) {
_apps[i].cast(oSender, msg, params); _apps[i]._cast(sender, msg, params);
} }
// cast to child plugins // cast to child plugins
this.cast(oSender, msg, params); this._cast(sender, msg, params);
} }
} }
@ -110,7 +114,7 @@ _app_base = {
_plugins : [], _plugins : [],
_messages : [], _messages : [],
_fn_level : -1, _fn_level : [],
/** /**
* @brief register a plugin instance * @brief register a plugin instance
@ -134,16 +138,11 @@ _app_base = {
$.each(oPlugin, function(key, val){ $.each(oPlugin, function(key, val){
if (!$.isFunction(val)) return true; if (!$.isFunction(val)) return true;
if (!/^API_((BEFORE_|AFTER_)?[A-Z0-9_]+)$/.test(key)) return true; if (!/^API_((BEFORE_|AFTER_)?[A-Z0-9_]+)$/.test(key)) return true;
var fn = function(s,p){ return oPlugin[key](s,p) }; var fn = function(s,p){ return oPlugin[key](s,p) };
fn._fn = val; fn._fn = val;
if (RegExp.$2) { // is hooker? if (!$.isArray(msgs[RegExp.$1])) msgs[RegExp.$1] = [];
if (!$.isArray(msgs[RegExp.$1])) msgs[RegExp.$1] = []; msgs[RegExp.$1].push(fn);
msgs[RegExp.$1].push(fn);
} else { // register only one main function
msgs[RegExp.$1] = fn;
}
}); });
// set the application // set the application
@ -151,7 +150,7 @@ _app_base = {
// binding // binding
oPlugin.cast = function(msg, params) { oPlugin.cast = function(msg, params) {
oPlugin._cast(msg, params); return oPlugin._cast(msg, params);
}; };
oPlugin.broadcast = function(msg, params) { oPlugin.broadcast = function(msg, params) {
@ -200,55 +199,50 @@ _app_base = {
oPlugin.oApp = null; oPlugin.oApp = null;
}, },
cast : function(sender, msg, params) { cast : function(msg, params) {
var i, len; return this._cast(this, msg, params || []);
var aMsg = this._messages;
msg = msg.toUpperCase();
// increase function level
this._fn_level++;
// BEFORE hooker
if (typeof aMsg['BEFORE_'+msg] != 'undefined') {
var bContinue = this.cast(sender, 'BEFORE_'+msg, params);
if (!bContinue) {
this._fn_level--;
return;
}
}
// main api function
var vRet;
if ($.isFunction(aMsg[msg])) {
vRet = aMsg[msg](sender, params);
} else if ($.isArray(aMsg[msg])) {
vRet = [];
for(i=0; i < aMsg[msg].length; i++) {
vRet.push( aMsg[msg][i](sender, params) );
}
}
// AFTER hooker
if (typeof aMsg['AFTER_'+msg] != 'undefined') {
this.cast(sender, 'AFTER_'+msg, params);
}
// decrease function level
this._fn_level--;
if (this._fn_level < 0) { // top level function
return vRet;
} else {
if (typeof vRet == 'undefined') vRet = true;
return $.isArray(vRet)?$.inArray(false, vRet):!!vRet;
}
}, },
broadcast : function(sender, msg, params) { broadcast : function(sender, msg, params) {
if (this.parent && this.parent.broadcast) { if (this.parent && this.parent.broadcast) {
this.parent.broadcast(sender, msg, params); this.parent.broadcast(sender, msg, params);
} }
},
_cast : function(sender, msg, params) {
var i, len;
var aMsg = this._messages;
msg = msg.toUpperCase();
// BEFORE hooker
if (aMsg['BEFORE_'+msg] || this['API_BEFORE_'+msg]) {
var bContinue = this._cast(sender, 'BEFORE_'+msg, params);
if (!bContinue) return;
}
// main api function
var vRet = [], sFn = 'API_'+msg;
if ($.isFunction(this[sFn])) vRet.push( this[sFn](sender, params) );
if ($.isFunction(aMsg[msg])) vRet.push( aMsg[msg](sender, params) );
else if ($.isArray(aMsg[msg])) {
for(i=0; i < aMsg[msg].length; i++) {
vRet.push( aMsg[msg][i](sender, params) );
}
}
if (vRet.length < 2) vRet = vRet[0];
// AFTER hooker
if (aMsg['AFTER_'+msg] || this['API_AFTER_'+msg]) {
this._cast(sender, 'AFTER_'+msg, params);
}
if (!/^(?:AFTER_|BEFORE_)/.test(msg)) { // top level function
return vRet;
} else {
if (typeof vRet == 'undefined') vRet = true;
return $.isArray(vRet)?$.inArray(false, vRet):!!vRet;
}
} }
}; };
@ -257,8 +251,8 @@ _plugin_base = {
_binded_fn : [], _binded_fn : [],
_cast : function(msg, params) { _cast : function(msg, params) {
if (this.oApp && this.oApp.cast) { if (this.oApp && this.oApp._cast) {
this.oApp.cast(this, msg, params || []); return this.oApp._cast(this, msg, params || []);
} }
}, },
_broadcast : function(msg, params) { _broadcast : function(msg, params) {
@ -269,6 +263,8 @@ _plugin_base = {
/** /**
* Event handler prototype * Event handler prototype
*
* function (oSender, params)
*/ */
}; };
@ -287,6 +283,7 @@ function getTypeBase() {
} }
window.xe = $.extend(_app_base, _xe_base); window.xe = $.extend(_app_base, _xe_base);
window.xe.lang = {}; // language repository
// domready event // domready event
$(function(){ xe.broadcast(xe, 'ONREADY'); }); $(function(){ xe.broadcast(xe, 'ONREADY'); });

View file

@ -29,7 +29,7 @@ function exec_xml(module, act, params, callback_func, response_tags, callback_fu
function xml_response_filter(oXml, callback_func, response_tags, callback_func_arg, fo_obj) { function xml_response_filter(oXml, callback_func, response_tags, callback_func_arg, fo_obj) {
var text = oXml.getResponseText(); var text = oXml.getResponseText();
if(oXml.objXmlHttp.readyState!=4) return; if(oXml.objXmlHttp.readyState!=4) return;
if(text && !/^<response>/i.test(text)) { if(text && !/<\/response>$/i.test(text)) {
var waiting_obj = xGetElementById("waitingforserverresponse"); var waiting_obj = xGetElementById("waitingforserverresponse");
if(waiting_obj) waiting_obj.style.visibility = "hidden"; if(waiting_obj) waiting_obj.style.visibility = "hidden";
alert(text); alert(text);

View file

@ -1,330 +1,297 @@
/** /**
* @file common/js/xml_js_filter.js * @file common/js/xml_js_filter.js
* @author zero (zero@nzeo.com) * @author taggon (taggon@gmail.com)
* @brief xml filter에서 사용될 js * @brief xml filter (validator) plugin
* *
* zbxe 에서 form의 동작시 필수입력 여부등을 선처리하고 xml_handler.js의 exec_xml() 통해서 * A rule is a method validate one field.
* 특정 모듈과의 ajax 통신을 통해 process를 진행시킴 * A filter is made up of one or more rules.
**/ **/
(function($){
var alertMsg = new Array(); var messages = [];
var target_type_list = new Array(); var rules = [];
var notnull_list = new Array(); var filters = [];
var extra_vars = new Array(); var callbacks = [];
var extras = {};
var Validator = xe.createApp('Validator', {
init : function() {
// {{{ add filters
// email
var regEmail = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)*$/;
this.cast('ADD_RULE', ['email', regEmail]);
this.cast('ADD_RULE', ['email_address', regEmail]);
// userid
var regUserid = /^[a-z]+[\w-]*[a-z0-9]+$/i;
this.cast('ADD_RULE', ['userid', regUserid]);
this.cast('ADD_RULE', ['user_id', regUserid]);
// url
var regUrl = /^(https?|ftp|mms):\/\/[0-9a-z-]+(\.[_0-9a-z-\/\~]+)+(:[0-9]{2,4})*$/;
this.cast('ADD_RULE', ['url', regUrl]);
this.cast('ADD_RULE', ['homepage', regUrl]);
// korean
var regKor = /^[가-힣]*$/;
this.cast('ADD_RULE', ['korean', regKor]);
// korean_number
var regKorNum = /^[가-힣0-9]*$/;
this.cast('ADD_RULE', ['korean_number', regKorNum]);
// alpha
var regAlpha = /^[a-z]*$/i;
this.cast('ADD_RULE', ['alpha', regAlpha]);
// alpha_number
var regAlphaNum = /^[a-z][a-z0-9_]*$/i;
this.cast('ADD_RULE', ['alpha_number', regAlphaNum]);
// number
var regNum = /^[0-9]*$/;
this.cast('ADD_RULE', ['number', regNum]);
// }}} add filters
},
// run validator
run : function(oForm) {
var filter = '';
if (oForm._filter) filter = oForm._filter.value;
return this.cast('VALIDATE', [oForm, filter]);
},
API_ONREADY : function() {
var self = this;
// hook form submit event
$('form')
.each(function(){
if (this.onsubmit) {
this['xe:onsubmit'] = this.onsubmit;
this.onsubmit = null;
}
})
.submit(function(){
var legacyFn = this['xe:onsubmit'];
var hasLegacyFn = $.isFunction(legacyFn);
var bResult = hasLegacyFn?legacyFn.apply(this):self.run(this);
return bResult;
});
},
API_VALIDATE : function(sender, params) {
var self = this, result = true, form = params[0], filter=null, callback=null;
if (form.elements['_filter']) filter = form.elements['_filter'].value;
if (!filter) return true;
if ($.isFunction(callbacks[filter])) callback = callbacks[filter];
filter = $.extend({}, filters[filter.toLowerCase()] || {}, extras);
$.each(filter, function(name) {
var _el = form.elements[name];
if (!_el) return true;
var el = $(_el), val = $.trim(get_value(el));
var minlen = parseInt(this.minlen) || 0;
var maxlen = parseInt(this.maxlen) || 0;
var rule = (this.rule || '').split(',');
if (this.required && !val) return (result = (!!self.cast('ALERT', [form, name, 'isnull']) && false));
if (!this.required && !val) return (result = true);
if ((minlen && maxlen) && (val.length < minlen || val.length > maxlen)) return (result = (!!self.cast('ALERT', [form, name, 'outofrange', minlen, maxlen]) && false));
if (this.equalto) {
var eq_val = get_value($(form.elements[this.equalto]));
if (eq_val != val) return (result = (!!self.cast('ALERT', [form, name, 'equalto']) && false));
}
$.each(rule, function() {
var ret = self.cast('APPLY_RULE', [this, val]);
if (!ret) {
self.cast('ALERT', [form, name, 'invalid_'+this]);
return (result = false);
}
});
if (!result) return false;
});
if (!result) return false;
if ($.isFunction(callback)) return callback(form);
return true;
},
API_ADD_RULE : function(sender, params) {
var name = params[0].toLowerCase();
rules[name] = params[1];
},
API_DEL_RULE : function(sender, params) {
var name = params[0].toLowerCase();
delete rules[name];
},
API_GET_RULE : function(sender, params) {
var name = params[0].toLowerCase();
if (rules[name]) {
return rules[name];
} else {
return null;
}
},
API_ADD_FILTER : function(sender, params) {
var name = params[0].toLowerCase();
var filter = params[1];
filters[name] = filter;
},
API_DEL_FILTER : function(sender, params) {
var name = params[0].toLowerCase();
delete filters[name];
},
API_GET_FILTER : function(sender, params) {
var name = params[0].toLowerCase();
if (filters[name]) {
return filters[name];
} else {
return null;
}
},
API_ADD_EXTRA_FIELD : function(sender, params) {
var name = params[0].toLowerCase();
var prop = params[1];
extras[name] = prop;
},
API_GET_EXTRA_FIELD : function(sender, params) {
var name = params[0].toLowerCase();
return extras[name];
},
API_DEL_EXTRA_FIELD : function(sender, params) {
var name = params[0].toLowerCase();
delete extras[name];
},
API_APPLY_RULE : function(sender, params) {
var name = params[0].toLowerCase();
var value = params[1];
if (typeof(rules[name]) == 'undefined') return true; // no filter
if ($.isFunction(rules[name])) return rules[name](value);
if (rules[name] instanceof RegExp) return rules[name].test(value);
return true;
},
API_ALERT : function(sender, params) {
var form = params[0];
var field_name = params[1];
var msg_code = params[2];
var minlen = params[3];
var maxlen = params[4];
var field_msg = this.cast('GET_MESSAGE', [field_name]);
var msg = this.cast('GET_MESSAGE', [msg_code]);
if (msg != msg_code) msg = (msg.indexOf('%s')<0)?(field_msg+msg):(msg.replace('%s',field_msg));
if (typeof(minlen)!='undefined' && typeof(maxlen)!='undefined') msg += '('+minlen+'~'+maxlen+')';
this.cast('SHOW_ALERT', [msg]);
// set focus
$(form.elements[field_name]).focus();
},
API_SHOW_ALERT : function(sender, params) {
alert(params[0]);
},
API_ADD_MESSAGE : function(sender, params) {
var msg_code = params[0];
var msg_str = params[1];
messages[msg_code] = msg_str;
},
API_GET_MESSAGE : function(sender, params) {
var msg_code = params[0];
return messages[msg_code] || msg_code;
},
API_ADD_CALLBACK : function(sender, params) {
var name = params[0];
var func = params[1];
callbacks[name] = func;
},
API_REMOVE_CALLBACK : function(sender, params) {
var name = params[0];
delete callbacks[name];
}
});
var oValidator = new Validator;
// register validator
xe.registerApp(oValidator);
// 호환성을 위해 추가한 플러그인 - 에디터에서 컨텐트를 가져와서 설정한다.
var EditorStub = xe.createPlugin('editor_stub', {
API_BEFORE_VALIDATE : function(sender, params) {
var form = params[0];
var seq = form.getAttribute('editor_sequence');
if (seq) {
try {
editorRelKeys[seq].content.value = editorRelKeys[seq].func(seq) || '';
} catch(e) { }
}
}
});
oValidator.registerPlugin(new EditorStub);
// functions
function get_value(elem) {
var vals = [];
if (elem.is(':radio')){
return elem.filter(':checked').val();
} else if (elem.is(':checkbox')) {
elem.filter(':checked').each(function(){
vals.push(this.value);
});
return vals.join('|@|');
} else {
return elem.val();
}
}
})(jQuery);
/** /**
* @function filterAlertMessage * @function filterAlertMessage
* @brief ajax로 서버에 요청후 결과를 처리할 callback_function을 지정하지 않았을 호출되는 기본 함수 * @brief ajax로 서버에 요청후 결과를 처리할 callback_function을 지정하지 않았을 호출되는 기본 함수
**/ **/
function filterAlertMessage(ret_obj) { function filterAlertMessage(ret_obj) {
var error = ret_obj["error"]; var error = ret_obj["error"];
var message = ret_obj["message"]; var message = ret_obj["message"];
var act = ret_obj["act"]; var act = ret_obj["act"];
var redirect_url = ret_obj["redirect_url"]; var redirect_url = ret_obj["redirect_url"];
var url = location.href; var url = location.href;
if(typeof(message)!="undefined"&&message&&message!="success") alert(message); if(typeof(message)!="undefined"&&message&&message!="success") alert(message);
if(typeof(act)!="undefined" && act) url = current_url.setQuery("act", act); if(typeof(act)!="undefined" && act) url = current_url.setQuery("act", act);
else if(typeof(redirect_url)!="undefined" && redirect_url) url = redirect_url; else if(typeof(redirect_url)!="undefined" && redirect_url) url = redirect_url;
if(url == location.href) url = url.replace(/#(.*)$/,''); if(url == location.href) url = url.replace(/#(.*)$/,'');
location.href = url; location.href = url;
} }
/** /**
* @class XmlJsFilter * @brief Function to process filters
* @authro zero (zero@nzeo.com) * @deprecated
* @brief form elements, module/act, callback_user_func을 이용하여 서버에 ajax로 form 데이터를 넘기고 결과를 받아오는 js class */
**/ function procFilter(fo_obj, filter_func)
function XmlJsFilter(form_object, module, act, callback_user_func) { {
this.field = new Array(); filter_func(fo_obj);
this.parameter = new Array(); return false;
this.response = new Array();
this.fo_obj = form_object;
this.module = module;
this.act = act;
this.user_func = callback_user_func;
this.setFocus = XmlJsFilterSetFocus;
this.addFieldItem = XmlJsFilterAddFieldItem;
this.addParameterItem = XmlJsFilterAddParameterItem;
this.addResponseItem = XmlJsFilterAddResponseItem;
this.getValue = XmlJsFilterGetValue;
this.executeFilter = XmlJsFilterExecuteFilter;
this.checkFieldItem = XmlJsFilterCheckFieldItem;
this.getParameterParam = XmlJsFilterGetParameterParam;
this.alertMsg = XmlJsFilterAlertMsg;
this.proc = XmlJsFilterProc;
}
function XmlJsFilterSetFocus(target_name) {
var obj = this.fo_obj[target_name];
if(typeof(obj)=='undefined' || !obj) return;
var length = obj.length;
try {
if(typeof(length)!='undefined') {
obj[0].focus();
} else {
obj.focus();
}
} catch(e) {
}
}
function XmlJsFilterAddFieldItem(target, required, minlength, maxlength, equalto, filter) {
var obj = new Array(target, required, minlength, maxlength, equalto, filter);
this.field[this.field.length] = obj;
}
function XmlJsFilterAddParameterItem(param, target) {
var obj = new Array(param, target);
this.parameter[this.parameter.length] = obj;
}
function XmlJsFilterAddResponseItem(name) {
this.response[this.response.length] = name;
}
function XmlJsFilterGetValue(target_name) {
var obj = this.fo_obj[target_name];
if(typeof(obj)=='undefined' || !obj) return '';
var value = '';
var length = obj.length;
var type = obj.type;
if((typeof(type)=='undefined'||!type) && typeof(length)!='undefined' && typeof(obj[0])!='undefined' && length>0) type = obj[0].type;
else length = 0;
switch(type) {
case 'checkbox' :
if(length>0) {
var value_list = new Array();
for(var i=0;i<length;i++) {
if(obj[i].checked) value_list[value_list.length] = obj[i].value;
}
value = value_list.join('|@|');
} else {
if(obj.checked) value = obj.value;
else value = '';
}
break;
case 'radio' :
if(length>0) {
for(var i=0;i<length;i++) {
if(obj[i].checked) value = obj[i].value;
}
} else {
if(obj.checked) value = obj.value;
else value = '';
}
break;
case 'select' :
case 'select-one' :
if(obj.selectedIndex>=0) value = obj.options[obj.selectedIndex].value;
break;
default :
if(length>0 && target_type_list[target_name]) {
switch(target_type_list[target_name]) {
case 'kr_zip' :
var val1 = obj[0].value;
var val2 = obj[1].value;
if(val1&&val2) {
value = val1+'|@|'+val2;
}
break;
case 'tel' :
var val1 = obj[0].value;
var val2 = obj[1].value;
var val3 = obj[2].value;
if(val1&&val2&&val3) {
value = val1+'|@|'+val2+'|@|'+val3;
}
break;
}
} else {
value = obj.value;
}
break;
}
if(typeof(value)=='undefined'||!value) return '';
return value.trim();
}
function XmlJsFilterExecuteFilter(filter, value) {
switch(filter) {
case "email" :
case "email_address" :
var regx = /^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$/;
return regx.test(value);
break;
case "userid" :
case "user_id" :
var regx = /^[a-zA-Z]+([_0-9a-zA-Z]+)*$/;
return regx.test(value);
break;
case "homepage" :
var regx = /^(http|https|ftp|mms):\/\/[0-9a-z-]+(\.[_0-9a-z-\/\~]+)+(:[0-9]{2,4})*$/;
return regx.test(value);
break;
case "korean" :
var regx = /^[가-힣]*$/;
return regx.test(value);
break;
case "korean_number" :
var regx = /^[가-힣0-9]*$/;
return regx.test(value);
break;
case "alpha" :
var regx = /^[a-zA-Z]*$/;
return regx.test(value);
break;
case "alpha_number" :
var regx = /^[a-zA-Z][a-zA-Z0-9\_]*$/;
return regx.test(value);
break;
case "number" :
return !isNaN(value);
break;
}
return null;
}
function XmlJsFilterAlertMsg(target, msg_code, minlength, maxlength) {
var target_msg = "";
if(alertMsg[target]!='undefined') target_msg = alertMsg[target];
else target_msg = target;
var msg = "";
if(typeof(alertMsg[msg_code])!='undefined') {
if(alertMsg[msg_code].indexOf('%s')>=0) msg = alertMsg[msg_code].replace('%s',target_msg);
else msg = target_msg+alertMsg[msg_code];
} else {
msg = msg_code;
}
if(typeof(minlength)!='undefined' && typeof(maxlength)!='undefined') msg += "("+minlength+"~"+maxlength+")";
alert(msg);
this.setFocus(target);
return false;
}
function XmlJsFilterCheckFieldItem() {
for(var i=0; i<extra_vars.length;i++) {
var name = extra_vars[i];
this.addFieldItem(name, false, 0, 0, "", "");
}
for(var i=0; i<this.field.length;i++) {
var item = this.field[i];
var target = item[0];
var required = item[1];
var minlength = item[2];
var maxlength = item[3];
var equalto = item[4];
var filter = item[5].split(",");
if(typeof(this.fo_obj[target])=='undefined') continue;
for(var j=0; j<notnull_list.length; j++) {
if(notnull_list[j]==target) required = true;
}
var value = this.getValue(target);
if(!required && !value) continue;
if(required && !value && this.fo_obj[target]) return this.alertMsg(target,'isnull');
if(minlength>0 && maxlength>0 && (value.length < minlength || value.length > maxlength)) return this.alertMsg(target, 'outofrange', minlength, maxlength);
if(equalto) {
var equalto_value = this.getValue(equalto);
if(equalto_value != value) return this.alertMsg(target, 'equalto');
}
if(filter.length && filter[0]) {
for(var j=0;j<filter.length;j++) {
var filter_item = filter[j];
if(!this.executeFilter(filter_item, value)) return this.alertMsg(target, "invalid_"+filter_item);
}
}
}
return true;
}
function XmlJsFilterGetParameterParam() {
if(!this.fo_obj) return new Array();
var prev_name = '';
if(this.parameter.length<1) {
for(var i=0;i<this.fo_obj.length;i++) {
var name = this.fo_obj[i].name;
if(typeof(name)=='undefined'||!name||name==prev_name) continue;
this.addParameterItem(name, name);
prev_name = name;
}
}
var params = new Array();
for(var i=0; i<this.parameter.length;i++) {
var item = this.parameter[i];
var param = item[0];
var target = item[1];
var value = this.getValue(target);
params[param] = value;
}
return params;
}
function XmlJsFilterProc(confirm_msg) {
var result = this.checkFieldItem();
if(!result) return false;
if(typeof(confirm_msg)=='undefined') confirm_msg = '';
var params = this.getParameterParam();
var response = this.response;
if(confirm_msg && !confirm(confirm_msg)) return false;
if(!this.act) {
this.user_func(this.fo_obj, params);
return true;
}
exec_xml(this.module, this.act, params, this.user_func, response, params, this.fo_obj);
return false;
}
// form proc
function procFilter(fo_obj, filter_func) {
// form문 안에 위지윅 에디터가 세팅되어 있을 경우 에디터의 값과 지정된 content field를 sync
var editor_sequence = fo_obj.getAttribute('editor_sequence');
if(typeof(editor_sequence)!='undefined' && editor_sequence && typeof(editorRelKeys)!='undefined') {
if(jQuery.isFunction(editorRelKeys[editor_sequence]['pasteHTML'])){
var content = editorGetContent(editor_sequence);
editorRelKeys[editor_sequence]['content'].value = content;
}else{
var content = editorGetContent(editor_sequence);
var dummy = xCreateElement("div");
xInnerHtml(dummy, content);
// IE에서 컨텐츠 전체를 P태그로 감싸는 경우가 있어서 이 의미없는 P태그를 제거
if(dummy.firstChild && dummy.firstChild.nodeName == 'P' && dummy.firstChild == dummy.lastChild) {
var content = xInnerHtml(dummy.firstChild);
xInnerHtml(dummy,content);
}
}
var regxPath = new RegExp('(src|href)=("|\'){1}'+request_uri.replace(/\//g,'\\/')+'([^"\']+)("|\'){1}','g');
content = content.replace(regxPath, '$1="./$3"');
editorRelKeys[editor_sequence]['content'].value = content;
}
filter_func(fo_obj);
return false;
} }

View file

@ -151,8 +151,8 @@
$lang->regdate = 'Registered Date'; $lang->regdate = 'Registered Date';
$lang->last_update = 'Last Update'; $lang->last_update = 'Last Update';
$lang->last_post = 'Last Post'; $lang->last_post = 'Last Post';
$lang->signup_date = 'Join Date'; $lang->signup_date = 'Sign up Date';
$lang->last_login = 'Last Login'; $lang->last_login = 'Last Sign in';
$lang->first_page = 'First Page'; $lang->first_page = 'First Page';
$lang->last_page = 'Last Page'; $lang->last_page = 'Last Page';
$lang->search_target = 'Target for Search'; $lang->search_target = 'Target for Search';
@ -277,10 +277,12 @@
$lang->eid = 'Name of extra variable'; $lang->eid = 'Name of extra variable';
// ftp-related // ftp-related
$lang->ftp_form_title = 'Input FTP account information'; $lang->ftp_form_title = 'FTP Account Information';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->cmd_check_ftp_connect = 'Check connection via FTP'; $lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'Check FTP Connection';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP account information can be used in following cases. <br /> FTP account information can be used in following cases. <br />
1. If safe_mode setting of PHP is on, XE will be installed using FTP. <br /> 1. If safe_mode setting of PHP is on, XE will be installed using FTP. <br />
@ -296,9 +298,9 @@
$lang->msg_ftp_chmod_fail = "Chmod failed. Please check the permission and configuration of FTP server."; $lang->msg_ftp_chmod_fail = "Chmod failed. Please check the permission and configuration of FTP server.";
$lang->msg_ftp_connect_success = "Connection and authentication to the FTP server succeeded."; $lang->msg_ftp_connect_success = "Connection and authentication to the FTP server succeeded.";
$lang->ftp_path_title = 'FTP 경로 정보 입력'; $lang->ftp_path_title = 'FTP Path Information';
$lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; $lang->msg_ftp_installed_realpath = 'Absolute Path of XE';
$lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; $lang->msg_ftp_installed_ftp_realpath = 'Absolute FTP Path of XE';
// Alert messages for Javascript using by XML filter // Alert messages for Javascript using by XML filter
@ -313,4 +315,6 @@
$lang->filter->invalid_alpha = "The format of %s is invalid. Please input alphabets only"; $lang->filter->invalid_alpha = "The format of %s is invalid. Please input alphabets only";
$lang->filter->invalid_alpha_number = "The format of %s is invalid. Please input alphabets or numbers"; $lang->filter->invalid_alpha_number = "The format of %s is invalid. Please input alphabets or numbers";
$lang->filter->invalid_number = "The format of %s is invalid. Please input numbers only"; $lang->filter->invalid_number = "The format of %s is invalid. Please input numbers only";
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -285,7 +285,9 @@
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'Datos de conexión para FTP'; $lang->ftp_form_title = 'Datos de conexión para FTP';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'conexión de FTP confirmada'; $lang->cmd_check_ftp_connect = 'conexión de FTP confirmada';
$lang->about_ftp_info = " $lang->about_ftp_info = "
Los datos de conexión para FTP pueden ser utilizados en los siguientes casos.<br/> Los datos de conexión para FTP pueden ser utilizados en los siguientes casos.<br/>
@ -320,4 +322,6 @@
$lang->filter->invalid_alpha = 'Sólo puede introducir los alfabetos en el %s'; $lang->filter->invalid_alpha = 'Sólo puede introducir los alfabetos en el %s';
$lang->filter->invalid_alpha_number = 'Sólo puede introducir los alfanuméricos en el %s es inválido'; $lang->filter->invalid_alpha_number = 'Sólo puede introducir los alfanuméricos en el %s es inválido';
$lang->filter->invalid_number = 'Sólo puede introducir los dígitos numéricos en el %s'; $lang->filter->invalid_number = 'Sólo puede introducir los dígitos numéricos en el %s';
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -279,7 +279,9 @@
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'FTP 정보 입력'; $lang->ftp_form_title = 'FTP 정보 입력';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'FTP 접속 확인'; $lang->cmd_check_ftp_connect = 'FTP 접속 확인';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP 정보는 다음의 경우에 이용될 있습니다.<br/> FTP 정보는 다음의 경우에 이용될 있습니다.<br/>
@ -306,11 +308,11 @@
$lang->filter->outofrange = 'Aligner la longueur du texte de %s'; $lang->filter->outofrange = 'Aligner la longueur du texte de %s';
$lang->filter->equalto = "La valeur de %s est invalide."; $lang->filter->equalto = "La valeur de %s est invalide.";
$lang->filter->invalid_email = "Le format de %s est invalide. ex) zbxe@zeroboard.com"; $lang->filter->invalid_email = "Le format de %s est invalide. ex) zbxe@zeroboard.com";
$lang->filter->invalid_user_id = $lang->filter->invalid_userid = "La format de %s n\'est pas convenable.\\nToutes les lettres devraient se composer des alphabets, des chiffres ou du soulignage(_) Et la première lettre doit être un de l'alphabet."; $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "La format de %s n\'est pas convenable.\\nToutes les lettres devraient se composer des alphabets, des chiffres ou du soulignage(_) Et la première lettre doit être un de l\'alphabet.";
$lang->filter->invalid_homepage = "La format de %s n\'est pas convenable. ex) http://www.zeroboard.com"; $lang->filter->invalid_homepage = "La format de %s n\'est pas convenable. ex) http://www.zeroboard.com";
$lang->filter->invalid_korean = "La format de %s n\'est pas convenable. Entrez seulement en coréen, S.V.P."; $lang->filter->invalid_korean = "La format de %s n\'est pas convenable. Entrez seulement en coréen, S.V.P.";
$lang->filter->invalid_korean_number = "La format de %s n\'est pas convenable. Entrez seulement des lettres d'alphabet coréen ou des chiffres, S.V.P."; $lang->filter->invalid_korean_number = "La format de %s n\'est pas convenable. Entrez seulement des lettres d\'alphabet coréen ou des chiffres, S.V.P.";
$lang->filter->invalid_alpha = "La format de %s n\'est pas convenable. Entrez seulement en alphabet, S.V.P."; $lang->filter->invalid_alpha = "La format de %s n\'est pas convenable. Entrez seulement en alphabet, S.V.P.";
$lang->filter->invalid_alpha_number = "La format de %s n\'est pas convenable. Entrez seulement des lettres d'alphabet ou des chiffres."; $lang->filter->invalid_alpha_number = "La format de %s n\'est pas convenable. Entrez seulement des lettres d\'alphabet ou des chiffres.";
$lang->filter->invalid_number = "La format de %s n\'est pas convenable. Entrez seulement des chiffres."; $lang->filter->invalid_number = "La format de %s n\'est pas convenable. Entrez seulement des chiffres.";
?> ?>

View file

@ -279,7 +279,9 @@
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'FTP 정보 입력'; $lang->ftp_form_title = 'FTP 정보 입력';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'FTP 접속 확인'; $lang->cmd_check_ftp_connect = 'FTP 접속 확인';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP 정보는 다음의 경우에 이용될 있습니다.<br/> FTP 정보는 다음의 경우에 이용될 있습니다.<br/>
@ -313,4 +315,6 @@
$lang->filter->invalid_alpha = "Das Format von% s ist ungültig. Bitte geben Sie nur Alphabete"; $lang->filter->invalid_alpha = "Das Format von% s ist ungültig. Bitte geben Sie nur Alphabete";
$lang->filter->invalid_alpha_number = "Das Format von% s ist ungültig. Bitte geben Sie Ihre Alphabete oder Zahlen"; $lang->filter->invalid_alpha_number = "Das Format von% s ist ungültig. Bitte geben Sie Ihre Alphabete oder Zahlen";
$lang->filter->invalid_number = "Das Format von% s ist ungültig. Bitte geben Sie nur Zahlen"; $lang->filter->invalid_number = "Das Format von% s ist ungültig. Bitte geben Sie nur Zahlen";
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -281,7 +281,9 @@
// ftp関連 // ftp関連
$lang->ftp_form_title = 'サーバーのFTP情報の入力'; $lang->ftp_form_title = 'サーバーのFTP情報の入力';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTPポート番号port'; $lang->ftp_port = 'FTPポート番号port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'FTP接続をテストする'; $lang->cmd_check_ftp_connect = 'FTP接続をテストする';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP情報は次の場合、利用されます。<br /> FTP情報は次の場合、利用されます。<br />
@ -315,4 +317,6 @@
$lang->filter->invalid_alpha = '%sの形式が正しくありません。半角英文字のみ入力して下さい。'; $lang->filter->invalid_alpha = '%sの形式が正しくありません。半角英文字のみ入力して下さい。';
$lang->filter->invalid_alpha_number = '%sの形式が正しくありません。半角英数で入力して下さい。'; $lang->filter->invalid_alpha_number = '%sの形式が正しくありません。半角英数で入力して下さい。';
$lang->filter->invalid_number = '%sの形式が正しくありません。半角数字で入力して下さい。'; $lang->filter->invalid_number = '%sの形式が正しくありません。半角数字で入力して下さい。';
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -281,7 +281,9 @@
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'FTP 계정 정보 입력'; $lang->ftp_form_title = 'FTP 계정 정보 입력';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP 서버 주소';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP Password는 저장되지 않습니다.';
$lang->cmd_check_ftp_connect = 'FTP 접속 확인'; $lang->cmd_check_ftp_connect = 'FTP 접속 확인';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP 정보는 다음 경우에 이용될 있습니다.<br /> FTP 정보는 다음 경우에 이용될 있습니다.<br />
@ -300,7 +302,7 @@
$lang->ftp_path_title = 'FTP 경로 정보 입력'; $lang->ftp_path_title = 'FTP 경로 정보 입력';
$lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로';
$lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 경로 설정';
// xml filter에서 사용되는 javascript용 alert msg // xml filter에서 사용되는 javascript용 alert msg
$lang->filter->isnull = '%s을 입력해주세요.'; $lang->filter->isnull = '%s을 입력해주세요.';
@ -314,4 +316,6 @@
$lang->filter->invalid_alpha = '%s의 형식이 잘못되었습니다. 영문으로만 입력하셔야 합니다.'; $lang->filter->invalid_alpha = '%s의 형식이 잘못되었습니다. 영문으로만 입력하셔야 합니다.';
$lang->filter->invalid_alpha_number = '%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력하셔야 합니다.'; $lang->filter->invalid_alpha_number = '%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력하셔야 합니다.';
$lang->filter->invalid_number = '%s의 형식이 잘못되었습니다. 숫자로만 입력하셔야 합니다.'; $lang->filter->invalid_number = '%s의 형식이 잘못되었습니다. 숫자로만 입력하셔야 합니다.';
$lang->security_warning_embed = "보안 문제로 관리자 아이디로는 embed를 볼 수 없습니다. 확인하시려면 다른 아이디로 접속하세요";
?> ?>

View file

@ -279,9 +279,11 @@
$lang->eid = 'eгeдлийн нэр'; $lang->eid = 'eгeдлийн нэр';
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'FTP мэдээлэл оруулах'; $lang->ftp_form_title = 'FTP мэдээлэл оруулах';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'FTP холболт шалгах'; $lang->cmd_check_ftp_connect = 'FTP холболт шалгах';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP мэдээлэл нь дараах тохиолдолд хэрэглэгдэх боломжтой.<br /> FTP мэдээлэл нь дараах тохиолдолд хэрэглэгдэх боломжтой.<br />
@ -303,11 +305,13 @@
$lang->filter->outofrange = '%s-ийн үсгийн тоог тааруулна уу.'; $lang->filter->outofrange = '%s-ийн үсгийн тоог тааруулна уу.';
$lang->filter->equalto = '%s-ыг буруу оруулсан байна.'; $lang->filter->equalto = '%s-ыг буруу оруулсан байна.';
$lang->filter->invalid_email = '%s-ын хэлбэрийг буруу оруулсан байна. (Жнь: zbxe@zeroboard.com)'; $lang->filter->invalid_email = '%s-ын хэлбэрийг буруу оруулсан байна. (Жнь: zbxe@zeroboard.com)';
$lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%s-ын хэлбэр буруу байна. .\\n Латин vсэг, тоо болон '_'-р оруулж болох бeгeeд эхлэл нь vсэг байх шаардлагатай. "; $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%s-ын хэлбэр буруу байна. .\\n Латин vсэг, тоо болон \'_\'-р оруулж болох бeгeeд эхлэл нь vсэг байх шаардлагатай. ";
$lang->filter->invalid_homepage = '%s-ын хэлбэр буруу байна.. (Жнь: http://www.zeroboard.com)'; $lang->filter->invalid_homepage = '%s-ын хэлбэр буруу байна.. (Жнь: http://www.zeroboard.com)';
$lang->filter->invalid_korean = '%s-ын хэлбэр буруу байна. Солонгосоор оруулах ёстой'; $lang->filter->invalid_korean = '%s-ын хэлбэр буруу байна. Солонгосоор оруулах ёстой';
$lang->filter->invalid_korean_number = '%s-ын хэлбэр буруу байна. Солонгос үсэг болон тоогоор оруулах хэрэгтэй.'; $lang->filter->invalid_korean_number = '%s-ын хэлбэр буруу байна. Солонгос үсэг болон тоогоор оруулах хэрэгтэй.';
$lang->filter->invalid_alpha = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсгээр оруулах ёстой'; $lang->filter->invalid_alpha = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсгээр оруулах ёстой';
$lang->filter->invalid_alpha_number = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсэг болон тоогоор л оруулах ёстой.'; $lang->filter->invalid_alpha_number = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсэг болон тоогоор л оруулах ёстой.';
$lang->filter->invalid_number = '%s-ын хэлбэр буруу байна. Зөвхөн тоогоор оруулах ёстой.'; $lang->filter->invalid_number = '%s-ын хэлбэр буруу байна. Зөвхөн тоогоор оруулах ёстой.';
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -274,7 +274,9 @@
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'FTP 정보 입력'; $lang->ftp_form_title = 'FTP 정보 입력';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'FTP 접속 확인'; $lang->cmd_check_ftp_connect = 'FTP 접속 확인';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP 정보는 다음의 경우에 이용될 있습니다.<br/> FTP 정보는 다음의 경우에 이용될 있습니다.<br/>
@ -313,4 +315,6 @@
$lang->filter->invalid_alpha = "Формат %s неверен. Пожалуйста, вводите только алфавитные символы"; $lang->filter->invalid_alpha = "Формат %s неверен. Пожалуйста, вводите только алфавитные символы";
$lang->filter->invalid_alpha_number = "Формат %s неверен. Пожалуйста, вводите алфавитные символы или цифры"; $lang->filter->invalid_alpha_number = "Формат %s неверен. Пожалуйста, вводите алфавитные символы или цифры";
$lang->filter->invalid_number = "Формат %s неверен. Пожалуйста, вводите только цифры"; $lang->filter->invalid_number = "Формат %s неверен. Пожалуйста, вводите только цифры";
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -270,7 +270,9 @@
// ftp 관련 // ftp 관련
$lang->ftp_form_title = 'Thông tin FTP'; $lang->ftp_form_title = 'Thông tin FTP';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'Cổng kết nối:'; $lang->ftp_port = 'Cổng kết nối:';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = 'Kiểm tra kết nối bằng FTP'; $lang->cmd_check_ftp_connect = 'Kiểm tra kết nối bằng FTP';
$lang->about_ftp_info = " $lang->about_ftp_info = "
Thông tin tài khoản FTP thể được sử dụng trong các trường hợp sau: <br /> Thông tin tài khoản FTP thể được sử dụng trong các trường hợp sau: <br />
@ -303,4 +305,6 @@
$lang->filter->invalid_alpha = "Định dạng của %s không hợp lệ. Chỉ sử dụng các kí tự từ a-z"; $lang->filter->invalid_alpha = "Định dạng của %s không hợp lệ. Chỉ sử dụng các kí tự từ a-z";
$lang->filter->invalid_alpha_number = "Định dạng của %s không hợp lệ. Chỉ sử dụng các kí tự từ a-z và các chữ số"; $lang->filter->invalid_alpha_number = "Định dạng của %s không hợp lệ. Chỉ sử dụng các kí tự từ a-z và các chữ số";
$lang->filter->invalid_number = "Định dạng của %s không hợp lệ. Chỉ sử dụng các chữ số"; $lang->filter->invalid_number = "Định dạng của %s không hợp lệ. Chỉ sử dụng các chữ số";
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -281,7 +281,9 @@
// ftp 相关 // ftp 相关
$lang->ftp_form_title = '设置FTP信息'; $lang->ftp_form_title = '设置FTP信息';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_host = 'FTP hostname';
$lang->ftp_port = 'FTP port'; $lang->ftp_port = 'FTP port';
$lang->about_ftp_password = 'FTP password will not be stored';
$lang->cmd_check_ftp_connect = '测试FTP连接'; $lang->cmd_check_ftp_connect = '测试FTP连接';
$lang->about_ftp_info = " $lang->about_ftp_info = "
相关FTP信息应用于如下几种状况:<br/> 相关FTP信息应用于如下几种状况:<br/>
@ -314,4 +316,6 @@
$lang->filter->invalid_alpha = '%s只能输入英文字母'; $lang->filter->invalid_alpha = '%s只能输入英文字母';
$lang->filter->invalid_alpha_number = '%s只能输入英文或数字'; $lang->filter->invalid_alpha_number = '%s只能输入英文或数字';
$lang->filter->invalid_number = '%s只能输入数字'; $lang->filter->invalid_number = '%s只能输入数字';
$lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.<BR /> To view them, please use another non-administrator ID.";
?> ?>

View file

@ -65,8 +65,8 @@
$lang->cmd_publish = "發表"; $lang->cmd_publish = "發表";
$lang->cmd_layout_setup = '版面設置'; $lang->cmd_layout_setup = '版面設置';
$lang->cmd_layout_edit = '版面編輯'; $lang->cmd_layout_edit = '版面編輯';
$lang->cmd_search_by_ipaddress = '以IP位址搜尋'; $lang->cmd_search_by_ipaddress = '以 IP 位址搜尋';
$lang->cmd_add_ip_to_spamfilter = '封鎖此IP位址'; $lang->cmd_add_ip_to_spamfilter = '封鎖此 IP 位址';
$lang->enable = '可用'; $lang->enable = '可用';
$lang->disable = '禁用'; $lang->disable = '禁用';
@ -221,13 +221,13 @@
$lang->msg_error_occured = '發生錯誤'; $lang->msg_error_occured = '發生錯誤';
$lang->msg_not_founded = '找不到相關內容'; $lang->msg_not_founded = '找不到相關內容';
$lang->msg_no_result = '搜尋不到結果'; $lang->msg_no_result = '搜尋不到結果';
$lang->msg_fail_to_request_open = 'Fail to open your request'; $lang->msg_fail_to_request_open = '連結失敗';
$lang->msg_invalid_format = '格式錯誤'; $lang->msg_invalid_format = '格式錯誤';
$lang->msg_not_permitted_act = '沒有權限執行'; $lang->msg_not_permitted_act = '沒有權限執行';
$lang->msg_module_is_not_exists = "요청하신 모듈을 찾을 수 없습니다.\n사이트 관리자에게 모듈 점검 요청 바랍니다"; $lang->msg_module_is_not_exists = "找不到模組。\n請聯絡管理員";
$lang->msg_module_is_not_standalone = '您請求的模組不能單獨執行'; $lang->msg_module_is_not_standalone = '您請求的模組不能單獨執行';
$lang->msg_default_url_is_not_defined = '기본 URL이 정해지지 않아서 동작을 중지합니다'; $lang->msg_default_url_is_not_defined = '尚未設定預設網址';
$lang->success_registed = '成功送出!'; $lang->success_registed = '成功送出!';
$lang->success_declared = '檢舉成功!'; $lang->success_declared = '檢舉成功!';
@ -261,15 +261,15 @@
$lang->column_type = '格式'; $lang->column_type = '格式';
$lang->column_type_list['text'] = '文字輸入(text)'; $lang->column_type_list['text'] = '文字輸入(text)';
$lang->column_type_list['homepage'] = '網址格式'; $lang->column_type_list['homepage'] = '網址格式';
$lang->column_type_list['email_address'] = '郵件格式 (email)'; $lang->column_type_list['email_address'] = '郵件格式(email)';
$lang->column_type_list['tel'] = '電話號碼格式 (phone)'; $lang->column_type_list['tel'] = '電話號碼格式(phone)';
$lang->column_type_list['textarea'] = '文字區域 (textarea)'; $lang->column_type_list['textarea'] = '文字區域(textarea)';
$lang->column_type_list['checkbox'] = '核取方塊 (checkbox)'; $lang->column_type_list['checkbox'] = '核取方塊(checkbox)';
$lang->column_type_list['select'] = '下拉式選單 (select)'; $lang->column_type_list['select'] = '下拉式選單(select)';
$lang->column_type_list['radio'] = '選項按紐 (radio)'; $lang->column_type_list['radio'] = '選項按紐(radio)';
$lang->column_type_list['kr_zip'] = '韓國郵編(zip)'; $lang->column_type_list['kr_zip'] = '韓國郵編(zip)';
$lang->column_type_list['date'] = '日期 (年月日)'; $lang->column_type_list['date'] = '日期(年月日)';
//$lang->column_type_list['jp_zip'] = '日本郵編 (zip)'; //$lang->column_type_list['jp_zip'] = '日本郵編(zip)';
$lang->column_name = '項目名稱'; $lang->column_name = '項目名稱';
$lang->column_title = '項目標題'; $lang->column_title = '項目標題';
$lang->default_value = '預設值'; $lang->default_value = '預設值';
@ -278,28 +278,30 @@
$lang->eid = '延伸變數名稱'; $lang->eid = '延伸變數名稱';
// 關於FTP // 關於FTP
$lang->ftp_form_title = '輸入FTP資訊'; $lang->ftp_form_title = '輸入 FTP 資訊';
$lang->ftp = 'FTP'; $lang->ftp = 'FTP';
$lang->ftp_port = 'FTP埠口'; $lang->ftp_host = 'FTP 主機名稱';
$lang->cmd_check_ftp_connect = '檢查FTP連線'; $lang->ftp_port = 'FTP 埠口';
$lang->about_ftp_password = 'FTP 密碼將不會被儲存';
$lang->cmd_check_ftp_connect = '檢查 FTP 連線';
$lang->about_ftp_info = " $lang->about_ftp_info = "
FTP資訊可應用至以下情形<br/> FTP資訊可應用至以下情形<br/>
1. 當PHP的安全模式(safe_mode)開啟時,可使程式正常運作。<br/> 1. 當PHP的安全模式(safe_mode)開啟時,可使程式正常運作。<br/>
2. 可用於自動更新。<br/> 2. 可用於自動更新。<br/>
此FTP資訊會儲存在檔案『files/config/ftp.config.php』裡面。<br/> 此FTP資訊會儲存在檔案『files/config/ftp.config.php』裡面。<br/>
安裝程式後,可以在管理頁面中針對FTP資訊進行修改或刪除。<br /> 安裝程式後,可以在管理頁面中針對 FTP 資訊進行修改或刪除。<br />
"; ";
$lang->msg_safe_mode_ftp_needed = '當PHP的安全模式(safe_mode)開啟時,請輸入相關FTP資訊否則無法正常安裝或使用程式。'; $lang->msg_safe_mode_ftp_needed = '當PHP的安全模式(safe_mode)開啟時,請輸入相關 FTP 資訊,否則無法正常安裝或使用程式。';
$lang->msg_ftp_not_connected = '本地(localhost)FTP連線錯誤。請檢查FTP埠口並確認是否支援FTP功能。'; $lang->msg_ftp_not_connected = '本地(localhost) FTP 連線錯誤。請檢查 FTP 埠口並確認是否支援 FTP 功能。';
$lang->msg_ftp_invalid_auth_info = 'FTP登入失敗。請確認輸入的FTP資訊。'; $lang->msg_ftp_invalid_auth_info = 'FTP登入失敗。請確認輸入的 FTP 資訊。';
$lang->msg_ftp_mkdir_fail = '新增資料夾失敗。請確認FTP主機設置。'; $lang->msg_ftp_mkdir_fail = '新增資料夾失敗。請確認 FTP 主機設置。';
$lang->msg_ftp_chmod_fail = '修改資料夾權限失敗。請確認FTP主機設置。'; $lang->msg_ftp_chmod_fail = '修改資料夾權限失敗。請確認 FTP 主機設置。';
$lang->msg_ftp_connect_success = 'FTP連線成功。'; $lang->msg_ftp_connect_success = 'FTP連線成功。';
$lang->ftp_path_title = '請輸入FTP路經'; $lang->ftp_path_title = '請輸入FTP路經';
$lang->msg_ftp_installed_realpath = '安裝XE時的絕對路經'; $lang->msg_ftp_installed_realpath = 'XE絕對路經';
$lang->msg_ftp_installed_ftp_realpath = '請輸入安裝XE的FTP絕對路經'; $lang->msg_ftp_installed_ftp_realpath = 'XE的FTP絕對路經';
// 在xml filter中所使用的JavaScript警告訊息 // 在xml filter中所使用的JavaScript警告訊息
@ -314,4 +316,6 @@
$lang->filter->invalid_alpha = '%s只能輸入英文字母'; $lang->filter->invalid_alpha = '%s只能輸入英文字母';
$lang->filter->invalid_alpha_number = '%s只能輸入英文或數字'; $lang->filter->invalid_alpha_number = '%s只能輸入英文或數字';
$lang->filter->invalid_number = '%s只能輸入數字'; $lang->filter->invalid_number = '%s只能輸入數字';
$lang->security_warning_embed = "由於安全的關係,管理員無法檢視嵌入的物件。<BR /> 請使用其他非管理員帳號檢視。";
?> ?>

View file

@ -19,17 +19,6 @@
<!--@end--> <!--@end-->
<meta http-equiv="imagetoolbar" content="no" /> <meta http-equiv="imagetoolbar" content="no" />
<title>{Context::getBrowserTitle()}</title> <title>{Context::getBrowserTitle()}</title>
{@ $js_files = Context::getJsFile() }
<!--@foreach($js_files as $key => $js_file)-->
<!--@if($js_file['targetie'])-->
<!--[if {$js_file['targetie']}]>
<!--@end-->
<script type="text/javascript" src="{$js_file['file']}"></script>
<!--@if($js_file['targetie'])-->
<![endif]-->
<!--@end-->
<!--@end-->
{@ $css_files = Context::getCssFile() } {@ $css_files = Context::getCssFile() }
<!--@foreach($css_files as $key => $css_file)--> <!--@foreach($css_files as $key => $css_file)-->
<!--@if($css_file['targetie'])--> <!--@if($css_file['targetie'])-->
@ -40,6 +29,16 @@
<![endif]--> <![endif]-->
<!--@end--> <!--@end-->
<!--@end--> <!--@end-->
{@ $js_files = Context::getJsFile() }
<!--@foreach($js_files as $key => $js_file)-->
<!--@if($js_file['targetie'])-->
<!--[if {$js_file['targetie']}]>
<!--@end-->
<script type="text/javascript" src="{$js_file['file']}"></script>
<!--@if($js_file['targetie'])-->
<![endif]-->
<!--@end-->
<!--@end-->
<!--@if($rss_url)--> <!--@if($rss_url)-->
<link rel="alternate" type="application/rss+xml" title="RSS" href="{$rss_url}" /> <link rel="alternate" type="application/rss+xml" title="RSS" href="{$rss_url}" />
<link rel="alternate" type="application/atom+xml" title="Atom" href="{$atom_url}" /> <link rel="alternate" type="application/atom+xml" title="Atom" href="{$atom_url}" />

View file

@ -13,7 +13,7 @@
* @brief XE의 전체 버전 표기 * @brief XE의 전체 버전 표기
* 파일의 수정이 없더라도 공식 릴리즈시에 수정되어 함께 배포되어야 * 파일의 수정이 없더라도 공식 릴리즈시에 수정되어 함께 배포되어야
**/ **/
define('__ZBXE_VERSION__', '1.3.1'); define('__ZBXE_VERSION__', '1.4.0');
/** /**
* @brief zbXE가 설치된 장소의 base path를 구함 * @brief zbXE가 설치된 장소의 base path를 구함
@ -46,7 +46,7 @@
* 2 : 소요시간, Request/Response info 출력 * 2 : 소요시간, Request/Response info 출력
* 4 : DB 쿼리 내역 출력 * 4 : DB 쿼리 내역 출력
**/ **/
if(!defined('__DEBUG__')) define('__DEBUG__', 1); if(!defined('__DEBUG__')) define('__DEBUG__', 0);
/** /**
* @brief 디버그 메세지의 출력 장소 * @brief 디버그 메세지의 출력 장소

View file

@ -520,6 +520,9 @@
$firephp->fb($debug_output, $label); $firephp->fb($debug_output, $label);
} else { } else {
if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) {
return;
}
$debug_file = _XE_PATH_.'files/_debug_message.php'; $debug_file = _XE_PATH_.'files/_debug_message.php';
if(function_exists("memory_get_usage")) if(function_exists("memory_get_usage"))
{ {
@ -835,4 +838,26 @@
} }
} }
function isCrawler($agent = null) {
if(!$agent) $agent = $_SERVER['HTTP_USER_AGENT'];
$check_agent = array('bot', 'spider', 'google', 'yahoo', 'daum', 'teoma', 'fish', 'hanrss');
$check_ip = array(
'211.245.21.11*' /* mixsh */
);
foreach($check_agent as $str) {
if(stristr($agent, $str) != FALSE) return true;
}
$check_ip = '/^('.implode($check_ip, '|').')/';
$check_ip = str_replace('.', '\.', $check_ip);
$check_ip = str_replace('*', '.+', $check_ip);
$check_ip = str_replace('?', '.?', $check_ip);
if(preg_match($check_ip, $_SERVER['REMOTE_ADDR'], $matches)) return true;
return false;
}
?> ?>

View file

@ -14,17 +14,19 @@
* - 공식홈페이지 : http://www.xpressengine.com * - 공식홈페이지 : http://www.xpressengine.com
* - SVN Repository : http://svn.xpressengine.net/xe * - SVN Repository : http://svn.xpressengine.net/xe
* \n * \n
* "XpressEngine (XE)" 자유 소프트웨어입니다. \n * "XpressEngine (XE)" is free software; you can redistribute it and/or \n
* 소프트웨어의 피양도자는 자유 소프트웨어 재단이 공표한 GNU 일반 공중 사용 허가서 2 또는 \n * modify it under the terms of the GNU Lesser General Public \n
* 이후 판을 임의로 선택해서, 규정에 따라 프로그램을 개작하거나 재배포할 있습니다. \n * License as published by the Free Software Foundation; either \n
* version 2.1 of the License, or (at your option) any later version. \n
* \n * \n
* 프로그램은 유용하게 사용될 있으리라는 희망에서 배포되고 있지만, 특정한 목적에 맞는 적합성 \n * This library is distributed in the hope that it will be useful,
* 여부나 판매용으로 사용할 있으리라는 묵시적인 보증을 포함한 어떠한 형태의 보증도 제공하지 않습니다. \n * but WITHOUT ANY WARRANTY; without even the implied warranty of
* 보다 자세한 사항에 대해서는 GNU 일반 공중 사용 허가서를 참고하시기 바랍니다. \n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* \n * \n
* GNU 일반 공중 사용 허가서는 프로그램과 함께 제공됩니다. 만약, 문서가 누락되어 있다면 자유 소프트웨어\n * You should have received a copy of the GNU Lesser General Public
* 재단으로 문의하시기 바랍니다. \n * License along with this library; if not, write to the Free Software
* (자유 소프트웨어 재단: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* *
**/ **/

View file

@ -76,7 +76,7 @@
<name xml:lang="es">zero</name> <name xml:lang="es">zero</name>
<name xml:lang="zh-CN">zero</name> <name xml:lang="zh-CN">zero</name>
<name xml:lang="zh-TW">zero</name> <name xml:lang="zh-TW">zero</name>
<name xml:lang="vi">zero</name> <name xml:lang="vi">zero</name>
</author> </author>
<extra_vars> <extra_vars>
@ -151,7 +151,7 @@
<description xml:lang="ge">Bitte geben Sie ein Logo das Bild wird auf dem oberen Layout. (Transparent Bild mit einer Höhe von 23px wird empfohlen).</description> <description xml:lang="ge">Bitte geben Sie ein Logo das Bild wird auf dem oberen Layout. (Transparent Bild mit einer Höhe von 23px wird empfohlen).</description>
<description xml:lang="ru">Введите логотип изображение, которое будет отображаться в верхней части формы. (Прозрачный изображение с высотой 23px рекомендуется.)</description> <description xml:lang="ru">Введите логотип изображение, которое будет отображаться в верхней части формы. (Прозрачный изображение с высотой 23px рекомендуется.)</description>
<description xml:lang="es">Ingresar una imagen para logotipo. ( Se recomienda una imagen de fondo transparente con una altura de 23px.</description> <description xml:lang="es">Ingresar una imagen para logotipo. ( Se recomienda una imagen de fondo transparente con una altura de 23px.</description>
<description xml:lang="vi">Hãy chọn Logo hiển thị phía trên cùng của giao diện. (Đề nghị: Hình ảnh có nền trong suốt và kích thước 23px.)</description> <description xml:lang="vi">Hãy chọn Logo hiển thị phía trên cùng của giao diện. (Đề nghị: Hình ảnh có nền trong suốt và kích thước 23px.)</description>
</var> </var>
<var name="index_url" type="text"> <var name="index_url" type="text">
<title xml:lang="ko">홈 페이지 URL</title> <title xml:lang="ko">홈 페이지 URL</title>

View file

@ -55,8 +55,10 @@
// 모듈 카테고리 목록을 구함 // 모듈 카테고리 목록을 구함
$module_categories = $oModuleModel->getModuleCategories(); $module_categories = $oModuleModel->getModuleCategories();
foreach($mid_list as $module_srl => $module) { if($mid_list) {
$module_categories[$module->module_category_srl]->list[$module_srl] = $module; foreach($mid_list as $module_srl => $module) {
$module_categories[$module->module_category_srl]->list[$module_srl] = $module;
}
} }
} else { } else {
$module_categories[0]->list = $mid_list; $module_categories[0]->list = $mid_list;

View file

@ -22,11 +22,14 @@
$site_srl = $site_module_info->site_srl; $site_srl = $site_module_info->site_srl;
$addon_path = _XE_PATH_.'files/cache/addons/'; $addon_path = _XE_PATH_.'files/cache/addons/';
if(!is_dir($addon_path)) FileHandler::makeDir($addon_path);
if($site_srl) $addon_file = $addon_path.$site_srl.'.acivated_addons.cache.php'; if($site_srl) $addon_file = $addon_path.$site_srl.'.acivated_addons.cache.php';
else $addon_file = $addon_path.'acivated_addons.cache.php'; else $addon_file = $addon_path.'acivated_addons.cache.php';
if($this->addon_file_called) return $addon_file;
$this->addon_file_called = true;
if(!is_dir($addon_path)) FileHandler::makeDir($addon_path);
if(!file_exists($addon_file)) $this->makeCacheFile($site_srl); if(!file_exists($addon_file)) $this->makeCacheFile($site_srl);
return $addon_file; return $addon_file;
} }

View file

@ -66,6 +66,7 @@
<table cellspacing="0" class="rowTable"> <table cellspacing="0" class="rowTable">
<!--@end--> <!--@end-->
<!--@if($mid_list)-->
<tr> <tr>
<th scope="row"><div> <th scope="row"><div>
{$lang->module} {$lang->module}
@ -94,6 +95,7 @@
<!--@end--> <!--@end-->
</td> </td>
</tr> </tr>
<!--@endif-->
</table> </table>
</div> </div>

View file

@ -47,6 +47,8 @@
function procAdminLogout() { function procAdminLogout() {
$oMemberController = &getController('member'); $oMemberController = &getController('member');
$oMemberController->procMemberLogout(); $oMemberController->procMemberLogout();
header('Location: '.getUrl('module','admin','act',''));
} }
} }
?> ?>

View file

@ -6,8 +6,12 @@
function getSFTPList() function getSFTPList()
{ {
$ftp_info = Context::getFTPInfo(); $ftp_info = Context::getRequestVars();
$connection = ssh2_connect('localhost', $ftp_info->ftp_port); if(!$ftp_info->ftp_host)
{
$ftp_info->ftp_host = "127.0.0.1";
}
$connection = ssh2_connect($ftp_info->ftp_host, $ftp_info->ftp_port);
if(!ssh2_auth_password($connection, $ftp_info->ftp_user, $ftp_info->ftp_password)) if(!ssh2_auth_password($connection, $ftp_info->ftp_user, $ftp_info->ftp_password))
{ {
return new Object(-1,'msg_ftp_invalid_auth_info'); return new Object(-1,'msg_ftp_invalid_auth_info');
@ -36,8 +40,16 @@
{ {
set_time_limit(5); set_time_limit(5);
require_once(_XE_PATH_.'libs/ftp.class.php'); require_once(_XE_PATH_.'libs/ftp.class.php');
$ftp_info = Context::getFTPInfo(); $ftp_info = Context::getRequestVars();
$this->pwd = Context::get('pwd'); if(!$ftp_info->ftp_user || !$ftp_info->ftp_password)
{
return new Object(-1, 'msg_ftp_invalid_auth_info');
}
$this->pwd = $ftp_info->ftp_root_path;
if(!$ftp_info->ftp_host)
{
$ftp_info->ftp_host = "127.0.0.1";
}
if($ftp_info->sftp == 'Y') if($ftp_info->sftp == 'Y')
{ {
@ -45,22 +57,17 @@
} }
$oFtp = new ftp(); $oFtp = new ftp();
if($oFtp->ftp_connect('localhost', $ftp_info->ftp_port)){ if($oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)){
if($oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) { if($oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) {
$_list = $oFtp->ftp_rawlist($this->pwd); $_list = $oFtp->ftp_rawlist($this->pwd);
$oFtp->ftp_quit(); $oFtp->ftp_quit();
} }
else
{
return new Object(-1,'msg_ftp_invalid_auth_info');
}
} }
$list = array(); $list = array();
if(count($_list) == 0 || !$_list[0]) {
$oFtp = new ftp();
if($oFtp->ftp_connect($_SERVER['SERVER_NAME'], $ftp_info->ftp_port)){
if($oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) {
$_list = $oFtp->ftp_rawlist($this->pwd);
$oFtp->ftp_quit();
}
}
}
if($_list){ if($_list){
foreach($_list as $k => $v){ foreach($_list as $k => $v){

View file

@ -71,6 +71,7 @@
Context::set('time_zone', $GLOBALS['_time_zone']); Context::set('time_zone', $GLOBALS['_time_zone']);
Context::set('use_rewrite', $db_info->use_rewrite=='Y'?'Y':'N'); Context::set('use_rewrite', $db_info->use_rewrite=='Y'?'Y':'N');
Context::set('use_optimizer', $db_info->use_optimizer!='N'?'Y':'N'); Context::set('use_optimizer', $db_info->use_optimizer!='N'?'Y':'N');
Context::set('use_spaceremover', $db_info->use_spaceremover?$db_info->use_spaceremover:'Y');
Context::set('qmail_compatibility', $db_info->qmail_compatibility=='Y'?'Y':'N'); Context::set('qmail_compatibility', $db_info->qmail_compatibility=='Y'?'Y':'N');
Context::set('use_db_session', $db_info->use_db_session=='N'?'N':'Y'); Context::set('use_db_session', $db_info->use_db_session=='N'?'N':'Y');
Context::set('use_ssl', $db_info->use_ssl?$db_info->use_ssl:"none"); Context::set('use_ssl', $db_info->use_ssl?$db_info->use_ssl:"none");
@ -275,17 +276,6 @@
$output = executeQuery('module.getSiteInfo', $site_args); $output = executeQuery('module.getSiteInfo', $site_args);
Context::set('start_module', $output->data); Context::set('start_module', $output->data);
$pwd = Context::get('pwd');
if(!$pwd) {
if($ftp_info->sftp == 'Y')
{
$pwd = _XE_PATH_;
}
else
{
$pwd = '/';
}
}
Context::set('pwd',$pwd); Context::set('pwd',$pwd);
Context::set('layout','none'); Context::set('layout','none');
$this->setTemplateFile('config'); $this->setTemplateFile('config');

View file

@ -13,7 +13,7 @@
<description xml:lang="vi">Module này hiển thị những đặc tính của những Module, và cho phép bạn sử dụng một chút quyền của Administrator bở việc áp dụng giao diện cho Administrator.</description> <description xml:lang="vi">Module này hiển thị những đặc tính của những Module, và cho phép bạn sử dụng một chút quyền của Administrator bở việc áp dụng giao diện cho Administrator.</description>
<description xml:lang="es">Este módulo muestra una lista de características de cada módulo, en donde puede activar la función de la administracion aplicando el diseño del administrador.</description> <description xml:lang="es">Este módulo muestra una lista de características de cada módulo, en donde puede activar la función de la administracion aplicando el diseño del administrador.</description>
<description xml:lang="zh-CN">列出各模块的功能并使用管理员布局,可以让其使用管理功能的模块。</description> <description xml:lang="zh-CN">列出各模块的功能并使用管理员布局,可以让其使用管理功能的模块。</description>
<description xml:lang="jp">各モジュールを機能別に並べ、かつ管理者用のレイアウトを適用させて、管理機能が使用出来るようにします。</description> <description xml:lang="jp">各モジュールの機能を表示し、かつ管理者用のレイアウトを適用させて、管理機能が使用出来るようにします。</description>
<description xml:lang="ru">Этот модуль показывает список возможностей каждого модуля, и позволяет Вам использовать несколько менеджеров, применяя лейаут для администратора.</description> <description xml:lang="ru">Этот модуль показывает список возможностей каждого модуля, и позволяет Вам использовать несколько менеджеров, применяя лейаут для администратора.</description>
<description xml:lang="zh-TW">列出各模組的功能並使用管理員版面,可讓其使用管理功能的模組。</description> <description xml:lang="zh-TW">列出各模組的功能並使用管理員版面,可讓其使用管理功能的模組。</description>
<version>0.1</version> <version>0.1</version>

View file

@ -7,18 +7,18 @@
$lang->admin_info = 'Administrator Info'; $lang->admin_info = 'Administrator Info';
$lang->admin_index = 'Index Admin Page'; $lang->admin_index = 'Index Admin Page';
$lang->control_panel = 'Control panel'; $lang->control_panel = 'Dashboard';
$lang->start_module = 'Start Module'; $lang->start_module = 'Default Module';
$lang->about_start_module = 'You can specify start module by default.'; $lang->about_start_module = 'You can specify default module of the site.';
$lang->module_category_title = array( $lang->module_category_title = array(
'service' => 'Service Setting', 'service' => 'Services',
'member' => 'Member Setting', 'member' => 'Members',
'content' => 'Content Setting', 'content' => 'Contents',
'statistics' => 'Statistics', 'statistics' => 'Statistics',
'construction' => 'Construction', 'construction' => 'Construction',
'utility' => 'Utility Setting', 'utility' => 'Utilities',
'interlock' => 'Interlock Setting', 'interlock' => 'Embedded',
'accessory' => 'Accessories', 'accessory' => 'Accessories',
'migration' => 'Data Migration', 'migration' => 'Data Migration',
'system' => 'System Setting', 'system' => 'System Setting',
@ -34,7 +34,7 @@
$lang->current_version = "Current Version"; $lang->current_version = "Current Version";
$lang->current_path = "Installed Path"; $lang->current_path = "Installed Path";
$lang->released_version = "Latest Version"; $lang->released_version = "Latest Version";
$lang->about_download_link = "New version of Zerboard XE is now available.\nClick the download link to get the latest version."; $lang->about_download_link = "New version of Zerboard XE is now available!\nPlease click the download link to get the latest version.";
$lang->item_module = "Module List"; $lang->item_module = "Module List";
$lang->item_addon = "Addon List"; $lang->item_addon = "Addon List";
@ -50,13 +50,13 @@
$lang->cmd_shortcut_management = "Edit Menu"; $lang->cmd_shortcut_management = "Edit Menu";
$lang->msg_is_not_administrator = 'Administrator only'; $lang->msg_is_not_administrator = 'Administrator Only';
$lang->msg_manage_module_cannot_delete = 'Shortcuts of module, addon, layout, widget cannot be removed'; $lang->msg_manage_module_cannot_delete = 'Shortcuts of module, addon, layout, widget cannot be removed';
$lang->msg_default_act_is_null = 'Shortcut could not be registered because default admin Action is not set'; $lang->msg_default_act_is_null = 'Shortcut could not be registered because default admin Action is not set';
$lang->welcome_to_xe = 'Welcome to the admin page of XE'; $lang->welcome_to_xe = 'Welcome to the admin page of XE';
$lang->about_admin_page = "Admin page is still being developing,\nWe will add essential contents by accepting many good suggestions during Closebeta."; $lang->about_admin_page = "Admin page is still under development,\nWe will add essential contents by accepting many good suggestions during Closebeta.";
$lang->about_lang_env = "To apply selected language as default language, click the [Save] button."; $lang->about_lang_env = "To apply selected language as default language, click on the Save button.";
$lang->xe_license = 'XE complies with the GPL'; $lang->xe_license = 'XE complies with the GPL';
$lang->about_shortcut = 'You may remove shortcuts of modules which are registered on frequently using module list'; $lang->about_shortcut = 'You may remove shortcuts of modules which are registered on frequently using module list';
@ -65,18 +65,20 @@
$lang->today = "Today"; $lang->today = "Today";
$lang->cmd_lang_select = "Language"; $lang->cmd_lang_select = "Language";
$lang->about_cmd_lang_select = "Selected languages only will be serviced"; $lang->about_cmd_lang_select = "Only selected languages will be served.";
$lang->about_recompile_cache = "You can arrange useless or invalid cache files"; $lang->about_recompile_cache = "You can delete useless or invalid cache files.";
$lang->use_ssl = "Use SSL"; $lang->use_ssl = "Use SSL";
$lang->ssl_options = array( $lang->ssl_options = array(
'none' => "Not use", 'none' => "Never",
'optional' => "optional", 'optional' => "Optional",
'always' => "always" 'always' => "Always"
); );
$lang->about_use_ssl = "If you choose 'optional', SSL will be used for actions such as sign up / changing information. And for 'always', your site will be served only via https."; $lang->about_use_ssl = "In case of 'Optional', SSL will be used for actions such as signing up / changing information. And for 'Always', your site will be served only via https.";
$lang->server_ports = "Server port"; $lang->server_ports = "Server Port";
$lang->about_server_ports = "If your web-server uses other than 80 for HTTP, 443 for HTTPS, you should specify server ports"; $lang->about_server_ports = "If your web server does not use 80 for HTTP or 443 for HTTPS port, you should specify server ports";
$lang->use_db_session = 'Use Session DB'; $lang->use_db_session = 'Use Session DB';
$lang->about_db_session = 'It will use php session with DB when authenticating.<br/>Websites with infrequent usage of web server may expect faster response when this function is disabled.<br/>However session DB will make it unable to get current users, so you cannot use related functions.'; $lang->about_db_session = 'It will use php session with DB when authenticating.<br/>Websites with infrequent usage of web server may expect faster response when this function is disabled.<br/>However session DB will make it unable to get current users, so you cannot use related functions.';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -81,4 +81,6 @@
$lang->use_db_session = '인증 세션 DB 사용'; $lang->use_db_session = '인증 세션 DB 사용';
$lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.'; $lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -80,4 +80,6 @@
$lang->use_db_session = '인증 세션 DB 사용'; $lang->use_db_session = '인증 세션 DB 사용';
$lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.'; $lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -79,4 +79,6 @@
$lang->use_db_session = 'DBで認証セッション管理'; $lang->use_db_session = 'DBで認証セッション管理';
$lang->about_db_session = '認証の時に使われるPHPセッションをDBで使う機能です。<br />ウェブサーバーの負荷が低いサイトではこの機能をオフにすることでむしろサイトのレスポンスが向上されることもあります。<br />また、この機能をオンにすると、「現在ログイン中の会員」の機能が不可になります。'; $lang->about_db_session = '認証の時に使われるPHPセッションをDBで使う機能です。<br />ウェブサーバーの負荷が低いサイトではこの機能をオフにすることでむしろサイトのレスポンスが向上されることもあります。<br />また、この機能をオンにすると、「現在ログイン中の会員」の機能が不可になります。';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -79,4 +79,6 @@
$lang->use_db_session = '인증 세션 DB 사용'; $lang->use_db_session = '인증 세션 DB 사용';
$lang->about_db_session = '인증 시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용률이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다.<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.'; $lang->about_db_session = '인증 시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용률이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다.<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.';
$lang->sftp = 'SFTP 사용'; $lang->sftp = 'SFTP 사용';
$lang->ftp_get_list = '목록 가져오기';
$lang->ftp_remove_info = 'FTP 정보 삭제';
?> ?>

View file

@ -80,4 +80,6 @@
$lang->use_db_session = '인증 세션 DB 사용'; $lang->use_db_session = '인증 세션 DB 사용';
$lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.'; $lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -81,4 +81,6 @@
$lang->use_db_session = 'Xác nhận Database'; $lang->use_db_session = 'Xác nhận Database';
$lang->about_db_session = 'PHP sẽ xác nhận với Database. Có thể cải thiện được tốc độ của Website.'; $lang->about_db_session = 'PHP sẽ xác nhận với Database. Có thể cải thiện được tốc độ của Website.';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -79,4 +79,6 @@
$lang->use_db_session = 'DB储存认证会话'; $lang->use_db_session = 'DB储存认证会话';
$lang->about_db_session = '用DB储存认证时的PHP会话。<br/>服务器使用率较少的网站建议不要勾选此项(可提高网站访问速度)。<br/>只是无法统计在线会员。'; $lang->about_db_session = '用DB储存认证时的PHP会话。<br/>服务器使用率较少的网站建议不要勾选此项(可提高网站访问速度)。<br/>只是无法统计在线会员。';
$lang->sftp = "Use SFTP"; $lang->sftp = "Use SFTP";
$lang->ftp_get_list = "Get List";
$lang->ftp_remove_info = 'Remove FTP Info.';
?> ?>

View file

@ -8,8 +8,8 @@
$lang->admin_info = '管理員資訊'; $lang->admin_info = '管理員資訊';
$lang->admin_index = '管理頁面'; $lang->admin_index = '管理頁面';
$lang->control_panel = '控制介面'; $lang->control_panel = '控制介面';
$lang->start_module = '啟用模組'; $lang->start_module = '預設首頁';
$lang->about_start_module = '可將所選擇的模組作為預設首頁。'; $lang->about_start_module = '可將所選擇的模組作為預設首頁。';
$lang->module_category_title = array( $lang->module_category_title = array(
'service' => '服務設定', 'service' => '服務設定',
@ -56,7 +56,6 @@
$lang->msg_default_act_is_null = '沒有指定預設管理員的動作,是無法新增到快捷選單的。'; $lang->msg_default_act_is_null = '沒有指定預設管理員的動作,是無法新增到快捷選單的。';
$lang->welcome_to_xe = 'XE管理頁面'; $lang->welcome_to_xe = 'XE管理頁面';
$lang->about_admin_page = "後台管理頁面未完成";
$lang->about_lang_env = "可以設置顯示語言給首次訪問的使用者。修改語言環境後,請按[儲存]按鈕進行儲存。"; $lang->about_lang_env = "可以設置顯示語言給首次訪問的使用者。修改語言環境後,請按[儲存]按鈕進行儲存。";
$lang->xe_license = 'XE遵循GPL協議'; $lang->xe_license = 'XE遵循GPL協議';
@ -78,6 +77,8 @@
$lang->server_ports = "主機埠口"; $lang->server_ports = "主機埠口";
$lang->about_server_ports = "HTTP預設埠口是『80』、HTTPS是『443』如果想使用其他的埠口的話請自行設定。"; $lang->about_server_ports = "HTTP預設埠口是『80』、HTTPS是『443』如果想使用其他的埠口的話請自行設定。";
$lang->use_db_session = 'DB session認證'; $lang->use_db_session = 'DB session認證';
$lang->about_db_session = '인증시 사용되는 PHP 세션을 DB로 사용하는 기능입니다.<br/>웹서버의 사용율이 낮은 사이트에서는 비활성화시 사이트 응답 속도가 향상될 수 있습니다<br/>단 현재 접속자를 구할 수 없어 관련된 기능을 사용할 수 없게 됩니다.'; $lang->about_db_session = '使用 PHP session 進行 DB 認證。<br/>關閉此功能對於負荷較低的網站可提高效率。<br/>使用此功能會無法統計線上人數。';
$lang->sftp = "使用 SFTP"; $lang->sftp = "使用 SFTP";
$lang->ftp_get_list = "取得列表";
$lang->ftp_remove_info = '移除 FTP 資料';
?> ?>

View file

@ -4,7 +4,7 @@
<div class="header"> <div class="header">
<h1 class="xeAdmin"><a href="{getUrl('','module','admin')}">XpressEngine</a></h1> <h1 class="xeAdmin"><a href="{getUrl('','module','admin')}">XpressEngine</a></h1>
<ul class="gnb"> <ul class="gnb">
<li><a href="#" onclick="doAdminLogout(); return false;">Logout</a></li> <li><a href="{getUrl('module','admin','act','procAdminLogout')}">Sign out</a></li>
<!--@if($logged_info->is_admin=='Y')--><li><a href="{getUrl('','module','admin','act','dispAdminConfig')}">Settings</a></li><!--@end--> <!--@if($logged_info->is_admin=='Y')--><li><a href="{getUrl('','module','admin','act','dispAdminConfig')}">Settings</a></li><!--@end-->
<li><a href="#" onclick="toggleAdminLang();return false;">Language</a> <li><a href="#" onclick="toggleAdminLang();return false;">Language</a>
<ul id="adminLang"> <ul id="adminLang">

View file

@ -15,12 +15,7 @@
sObj.value = module_srl; sObj.value = module_srl;
obj.value = decodeURIComponent(browser_title.replace(/\+/g," "))+' ('+mid+')'; obj.value = decodeURIComponent(browser_title.replace(/\+/g," "))+' ('+mid+')';
} }
<!--@if($ftp_info && $ftp_info->ftp_password && $ftp_info->ftp_user)--> var xe_root = "{_XE_PATH_}";
var pwd = '{$pwd}';
params = new Array();
params['pwd'] = pwd;
exec_xml('admin','getAdminFTPList', params, completeGetFtpInfo, new Array('list','error','message'));
<!--@end-->
</script> </script>
<div class="content"> <div class="content">
@ -127,71 +122,55 @@
</table> </table>
</form> </form>
<h4 class="xeAdmin" id="ftpSetup">{$lang->ftp_form_title}</h4> <h4 class="xeAdmin" id="ftpSetup">{$lang->ftp_form_title}</h4>
<p class="summary">{$lang->about_ftp_info}</p> <p class="summary">{$lang->about_ftp_info}</p>
<form action="./" method="post" onsubmit="return procFilter(this, install_ftp_info);" id="ftp_form"> <form action="./" method="post" onsubmit="return procFilter(this, install_ftp_info);" id="ftp_form">
{@ $nCols = 3; }
<table cellspacing="0" class="rowTable"> <table cellspacing="0" class="rowTable">
<tr>
<th><div><label for="textfield21">{$lang->user_id}</label></div></th>
<th><div><label for="textfield22">{$lang->password}</label></div></th>
<th><div><label for="textfield24">{$lang->ftp_port}</label></div></th>
<!--@if($sftp_support)-->
{@ $nCols += 1; }
<th><div><label for="checkbox25">{$lang->sftp}</label></div></th>
<!--@end-->
</tr>
<tr>
<td><input type="text" id="textfield21" name="ftp_user" value="{$ftp_info->ftp_user}" class="inputTypeText" /></td>
<td><input id="textfield22" type="password" name="ftp_password" value="{$ftp_info->ftp_password}" class="inputTypeText" /></td>
<td><input id="textfield24" type="text" name="ftp_port" value="{$ftp_info->ftp_port}" class="inputTypeText" /></td>
<!--@if($sftp_support)-->
<td><input type="checkbox" id="checkbox25" name="sftp" value="Y" <!--@if($ftp_info->sftp=="Y")-->checked="checked"<!--@end--> /></td>
<!--@end-->
</tr>
<tr>
<th colspan="{$nCols}" class="button">
<span class="button blue"><input type="button" value="{$lang->cmd_check_ftp_connect}" onclick="doCheckFTPInfo(); return false;"/></span>
<span class="button black strong"><input type="submit" value="{$lang->cmd_registration}" /></span>
</th>
</tr>
</table>
</form>
<!--@if($ftp_info && $ftp_info->ftp_password && $ftp_info->ftp_user)-->
<h4 class="xeAdmin" id="ftpSetup">{$lang->ftp_path_title}</h4>
<form action="./" method="get" onsubmit="return procFilter(this, install_ftp_path)">
<input type="hidden" name="ftp_user" value="{$ftp_info->ftp_user}" />
<input type="hidden" name="ftp_password" value="{$ftp_info->ftp_password}" />
<input type="hidden" name="ftp_port" value="{$ftp_info->ftp_port}" />
<input type="hidden" name="sftp" value="{$ftp_info->sftp}" />
<table cellspacing="0" class="rowTable">
<tr> <tr>
<th scope="col"><div>{$lang->msg_ftp_installed_realpath}</div></th> <th scope="col"><div><label for="textfield21">{$lang->user_id}</label></div></th>
<td>{_XE_PATH_} <td><input type="text" id="textfield21" name="ftp_user" value="{$ftp_info->ftp_user}" class="inputTypeText" />
</td>
</tr> </tr>
<tr> <tr>
<th scope="col" rowspan="2"><div>{$lang->msg_ftp_installed_ftp_realpath}</div></th> <th scope="col"><div><label for="textfield22">{$lang->password} ({$lang->about_ftp_password})</label></div></th>
<td><input id="textfield22" type="password" name="ftp_password" value="" class="inputTypeText" /></td>
</tr>
<tr>
<th scope="col"><div><label for="textfield23">{$lang->ftp_host} (default: 127.0.0.1)</label></div></th>
<td><input id="textfield23" type="text" name="ftp_host" value="{$ftp_info->ftp_host}" class="inputTypeText" /></td>
</tr>
<tr>
<th scope="col"><div><label for="textfield24">{$lang->ftp_port} (default: 21) </label></div></th>
<td><input id="textfield24" type="text" name="ftp_port" value="{$ftp_info->ftp_port}" class="inputTypeText" /></td>
</tr>
<!--@if($sftp_support)-->
<tr>
<th scope="col"><div><label for="checkbox25">{$lang->sftp}</label></div></th>
<td><input type="checkbox" id="checkbox25" name="sftp" value="Y" <!--@if($ftp_info->sftp=="Y")-->checked="checked"<!--@end--> /></td>
</tr>
<!--@end-->
<tr>
<th scope="col" rowspan="2"><div>{$lang->msg_ftp_installed_ftp_realpath}<br /><br/>{$lang->msg_ftp_installed_realpath}:<br/> {_XE_PATH_}</div></th>
<td> <td>
<input type="text" name="ftp_root_path" value="<!--@if($pwd)-->{$pwd}<!--@else-->{$ftp_info->ftp_root_path}<!--@end-->" class="inputTypeText w400" /> <input type="text" name="ftp_root_path" value="{$ftp_info->ftp_root_path}" class="inputTypeText w400" />
</td> </td>
</tr> </tr>
<tr id="ftplist"> <tr id="ftplist">
<td> <td>
<div class="serverresponse"> <div>
Waiting to load information <span class="button blue strong"><input type="button" onclick="getFTPList(); return false;" value="{$lang->ftp_get_list}"></span>
</div> </div>
</td> </td>
</tr> </tr>
<tr class="row2"> <tr>
<th colspan="2" class="button"> <th colspan="2" class="button">
<span class="button blue strong"><input type="button" onclick="removeFTPInfo(); return false;" value="{$lang->ftp_remove_info}"></span>
<span class="button black strong"><input type="submit" value="{$lang->cmd_registration}" /></span> <span class="button black strong"><input type="submit" value="{$lang->cmd_registration}" /></span>
</th> </th>
</tr> </tr>
</table> </table>
</form> </form>
<!--@end-->
</div> </div>
<hr /> <hr />
@ -206,7 +185,14 @@
<!--@foreach($langs as $key => $val)--> <!--@foreach($langs as $key => $val)-->
<tr> <tr>
<td> <td>
<input id="lang_{$key}" type="checkbox" name="selected_lang" value="{$key}" <!--@if(isset($lang_selected[$key]))-->checked="checked"<!--@end--> <!--@if($key==$selected_lang)-->disabled="disabled"<!--@end--> /> <label for="lang_{$key}">{$val}</label> <!--@if($key==$selected_lang)-->
<input type="hidden" name="selected_lang[]" value="{$key}" />
<input type="checkbox" checked="checked" disabled="disabled" />
<label>{$val}</label>
<!--@else-->
<input id="lang_{$key}" type="checkbox" name="selected_lang[]" value="{$key}" <!--@if(isset($lang_selected[$key]))-->checked="checked"<!--@end--> />
<label for="lang_{$key}">{$val}</label>
<!--@end-->
</td> </td>
</tr> </tr>
<!--@endforeach--> <!--@endforeach-->

View file

@ -1,8 +1,8 @@
<filter name="install_ftp_info" module="install" act="procInstallAdminSaveFTPInfo" > <filter name="install_ftp_info" module="install" act="procInstallAdminSaveFTPInfo" >
<form> <form>
<node target="ftp_user" required="true" /> <node target="ftp_user" required="true" />
<node target="ftp_password" required="true" />
<node target="ftp_port" required="true" /> <node target="ftp_port" required="true" />
<node target="ftp_root_path" required="true" />
<node target="sftp" /> <node target="sftp" />
</form> </form>
<response callback_func="completeMessage"> <response callback_func="completeMessage">

View file

@ -1,4 +1,4 @@
<filter name="install_ftp_path" module="install" act="procInstallAdminSaveFTPInfo" confirm_msg_code="confirm_submit"> <filter name="install_ftp_path" module="install" act="procInstallAdminSaveFTPPath" confirm_msg_code="confirm_submit">
<form> <form>
<node target="ftp_root_path" required="true" /> <node target="ftp_root_path" required="true" />
</form> </form>

View file

@ -11,32 +11,22 @@ function doRecompileCacheFile() {
// 모듈 목록 오픈 // 모듈 목록 오픈
function toggleModuleMenu(category) { function toggleModuleMenu(category) {
var obj = xGetElementById('module_'+category); jQuery('#module_'+category).toggleClass('open');
if(obj.className == 'open') obj.className = '';
else obj.className = 'open';
} }
// 메인 모듈/ 애드온 토글 // 메인 모듈/ 애드온 토글
function toggleModuleAddon(target) { function toggleModuleAddon(target) {
if(target == 'module') { var b = (target == 'module');
xGetElementById('moduleOn').className = 'on';
xGetElementById('xeModules').style.display = 'block'; jQuery('#moduleOn').attr('class', b?'on':'');
xGetElementById('addonOn').className = ''; jQuery('#addonOn').attr('class', b?'':'on');
xGetElementById('xeAddons').style.display = 'none'; jQuery('#xeModules')[b?'show':'hide']();
} else { jQuery('#xeAddons')[b?'hide':'show']();
xGetElementById('addonOn').className = 'on';
xGetElementById('xeAddons').style.display = 'block';
xGetElementById('moduleOn').className = '';
xGetElementById('xeModules').style.display = 'none';
}
} }
// toggle language list // toggle language list
function toggleAdminLang() { function toggleAdminLang() {
var obj = xGetElementById("adminLang"); jQuery('#adminLang').toggleClass('open');
if(!obj) return;
if(obj.style.display == 'block') obj.style.display = 'none';
else obj.style.display = 'block';
} }
// string to regex(초성검색용) // string to regex(초성검색용)
@ -152,8 +142,3 @@ jQuery(function($){
}); });
}); });
// logout
function doAdminLogout() {
exec_xml('admin','procAdminLogout',new Array(), function() { location.reload(); });
}

View file

@ -1,24 +1,66 @@
function getFTPList(pwd)
{
var form = jQuery("#ftp_form").get(0);
if(typeof(pwd) != 'undefined')
{
form.ftp_root_path.value = pwd;
}
else
{
if(!form.ftp_root_path.value)
{
if(typeof(form.sftp) != 'undefined' && form.sftp.checked) {
form.ftp_root_path.value = xe_root;
}
else
{
form.ftp_root_path.value = "/";
}
}
}
var params={}, data=jQuery("#ftp_form").serializeArray();
jQuery.each(data, function(i, field){ params[field.name] = field.value });
exec_xml('admin', 'getAdminFTPList', params, completeGetFtpInfo, ['list', 'error', 'message'], params, form);
}
function removeFTPInfo()
{
var params = {};
exec_xml('install', 'procInstallAdminRemoveFTPInfo', params, filterAlertMessage, ['error', 'message'], params);
}
function completeGetFtpInfo(ret_obj) function completeGetFtpInfo(ret_obj)
{ {
if(ret_obj['error'] != 0)
{
alert(ret_obj['error']);
alert(ret_obj['message']);
return;
}
var e = jQuery("#ftplist").empty(); var e = jQuery("#ftplist").empty();
var list = ""; var list = "";
if(!jQuery.isArray(ret_obj['list']['item']))
{
ret_obj['list']['item'] = [ret_obj['list']['item']];
}
pwd = jQuery("#ftp_form").get(0).ftp_root_path.value;
if(pwd != "/")
{
arr = pwd.split("/");
arr.pop();
arr.pop();
arr.push("");
target = arr.join("/");
list = list + "<li><a href='#ftpSetup' onclick=\"getFTPList('"+target+"')\">../</a></li>";
}
for(var i=0;i<ret_obj['list']['item'].length;i++) for(var i=0;i<ret_obj['list']['item'].length;i++)
{ {
var v = ret_obj['list']['item'][i]; var v = ret_obj['list']['item'][i];
if(v == "../") if(v == "../")
{ {
if(pwd == "/") continue;
{
continue;
}
arr = pwd.split("/");
arr.pop();
arr.pop();
arr.push("");
target = arr.join("/");
list = list + "<li><a href='"+current_url.setQuery('pwd',target)+"#ftpSetup'>"+v+"</a></li>";
} }
else if( v == "./") else if( v == "./")
{ {
@ -26,10 +68,10 @@ function completeGetFtpInfo(ret_obj)
} }
else else
{ {
list = list + "<li><a href='"+current_url.setQuery('pwd',pwd+v)+"#ftpSetup'>"+v+"</a></li>"; list = list + "<li><a href='#ftpSetup' onclick=\"getFTPList('"+pwd+v+"')\">"+v+"</a></li>";
} }
} }
list = "<td><ul>"+list+"</ul></td>"; list = "<td><ul>"+list+"</ul></td>";
e.append(jQuery(list)); e.append(jQuery(list));
} }

View file

@ -5,195 +5,7 @@
* @brief autoinstall 모듈의 admin controller class * @brief autoinstall 모듈의 admin controller class
**/ **/
class ModuleInstaller { require_once(_XE_PATH_.'modules/autoinstall/autoinstall.lib.php');
var $package = null;
var $base_url = 'http://download.xpressengine.com/';
var $temp_dir = './files/cache/autoinstall/';
var $target_path;
var $download_file;
var $url;
var $download_path;
function _download()
{
if($this->package->path == ".")
{
$this->download_file = $this->temp_dir."xe.tar";
$this->target_path = "";
$this->download_path = $this->temp_dir;
}
else
{
$subpath = substr($this->package->path,2);
$this->download_file = $this->temp_dir.$subpath.".tar";
$subpatharr = explode("/", $subpath);
array_pop($subpatharr);
$this->download_path = $this->temp_dir.implode("/", $subpatharr);
$this->target_path = implode("/", $subpatharr);
}
$postdata = array();
$postdata["path"] = $this->package->path;
$postdata["module"] = "resourceapi";
$postdata["act"] = "procResourceapiDownload";
$buff = FileHandler::getRemoteResource($this->base_url, null, 3, "POST", "application/x-www-form-urlencoded; charset=utf-8", array(), array(), $postdata);
FileHandler::writeFile($this->download_file, $buff);
}
function installModule()
{
$path_array = explode("/", $this->package->path);
$target_name = array_pop($path_array);
$type = substr(array_pop($path_array), 0, -1);
if($type == "module")
{
$oModuleModel = &getModel('module');
$oInstallController = &getController('install');
$module_path = ModuleHandler::getModulePath($target_name);
if($oModuleModel->checkNeedInstall($target_name))
{
$oInstallController->installModule($target_name, $module_path);
}
if($oModuleModel->checkNeedUpdate($target_name))
{
$oModule = &getModule($target_name, 'class');
if(method_exists($oModule, 'moduleUpdate'))
{
$oModule->moduleUpdate();
}
}
}
}
function install()
{
$this->_download();
$file_list = $this->_unPack();
$this->_copyDir($file_list);
$this->installModule();
FileHandler::removeDir($this->temp_dir);
return;
}
function _unPack(){
require_once(_XE_PATH_.'libs/tar.class.php');
$oTar = new tar();
$oTar->openTAR($this->download_file);
$_files = $oTar->files;
$file_list = array();
foreach($_files as $key => $info) {
FileHandler::writeFile($this->download_path."/".$info['name'], $info['file']);
$file_list[] = $info['name'];
}
return $file_list;
}
}
class SFTPModuleInstaller extends ModuleInstaller {
function SFTPModuleInstaller(&$package)
{
$this->package =& $package;
}
function _copyDir(&$file_list){
$ftp_info = Context::getFTPInfo();
if(!$ftp_info->ftp_user || !$ftp_info->ftp_password || !$ftp_info->sftp || $ftp_info->sftp != 'Y') return new Object(-1,'msg_ftp_invalid_auth_info');
$connection = ssh2_connect('localhost', $ftp_info->ftp_port);
if(!ssh2_auth_password($connection, $ftp_info->ftp_user, $ftp_info->ftp_password))
{
return new Object(-1,'msg_ftp_invalid_auth_info');
}
$sftp = ssh2_sftp($connection);
$target_dir = $ftp_info->ftp_root_path.$this->target_path;
foreach($file_list as $k => $file){
$org_file = $file;
if($this->package->path == ".")
{
$file = substr($file,3);
}
$path = FileHandler::getRealPath("./".$this->target_path."/".$file);
$pathname = dirname($target_dir."/".$file);
if(!file_exists(FileHandler::getRealPath($real_path)))
{
ssh2_sftp_mkdir($sftp, $pathname, 0755, true);
}
ssh2_scp_send($connection, FileHandler::getRealPath($this->download_path."/".$org_file), $target_dir."/".$file);
}
}
}
class FTPModuleInstaller extends ModuleInstaller {
function FTPModuleInstaller(&$package)
{
$this->package =& $package;
}
function _copyDir(&$file_list){
$ftp_info = Context::getFTPInfo();
if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_ftp_invalid_auth_info');
require_once(_XE_PATH_.'libs/ftp.class.php');
$oFtp = new ftp();
if(!$oFtp->ftp_connect('localhost', $ftp_info->ftp_port)) return new Object(-1,'msg_ftp_not_connected');
if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) {
$oFtp->ftp_quit();
return new Object(-1,'msg_ftp_invalid_auth_info');
}
$_list = $oFtp->ftp_rawlist($ftp_info->ftp_root_path);
if(count($_list) == 0 || !$_list[0]) {
$oFtp->ftp_quit();
$oFtp = new ftp();
if(!$oFtp->ftp_connect($_SERVER['SERVER_NAME'], $ftp_info->ftp_port)) return new Object(-1,'msg_ftp_not_connected');
if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) {
$oFtp->ftp_quit();
return new Object(-1,'msg_ftp_invalid_auth_info');
}
}
$target_dir = $ftp_info->ftp_root_path.$this->target_path;
foreach($file_list as $k => $file){
$org_file = $file;
if($this->package->path == ".")
{
$file = substr($file,3);
}
$path = FileHandler::getRealPath("./".$this->target_path."/".$file);
$path_list = explode('/', dirname($this->target_path."/".$file));
$real_path = "./";
$ftp_path = $ftp_info->ftp_root_path;
for($i=0;$i<count($path_list);$i++)
{
if($path_list=="") continue;
$real_path .= $path_list[$i]."/";
$ftp_path .= $path_list[$i]."/";
if(!file_exists(FileHandler::getRealPath($real_path)))
{
$oFtp->ftp_mkdir($ftp_path);
$oFtp->ftp_site("CHMOD 755 ".$path);
}
}
$oFtp->ftp_put($target_dir .'/'. $file, FileHandler::getRealPath($this->download_path."/".$org_file));
}
$oFtp->ftp_quit();
return new Object();
}
}
class autoinstallAdminController extends autoinstall { class autoinstallAdminController extends autoinstall {
@ -303,18 +115,31 @@
$oModel =& getModel('autoinstall'); $oModel =& getModel('autoinstall');
$packages = explode(',', $package_srls); $packages = explode(',', $package_srls);
$ftp_info = Context::getFTPInfo(); $ftp_info = Context::getFTPInfo();
if(!$_SESSION['ftp_password'])
{
$ftp_password = Context::get('ftp_password');
if($ftp_password) $_SESSION['ftp_password'] = $ftp_password;
}
else
{
$ftp_password = $_SESSION['ftp_password'];
}
foreach($packages as $package_srl) foreach($packages as $package_srl)
{ {
$package = $oModel->getPackage($package_srl); $package = $oModel->getPackage($package_srl);
if($ftp_info->sftp && $ftp_info->sftp == 'Y') if($ftp_info->sftp && $ftp_info->sftp == 'Y')
{ {
$oModuleInstaller = new SFTPModuleInstaller($package); $oModuleInstaller = new SFTPModuleInstaller($package);
$oModuleInstaller->setPassword($ftp_password);
} }
else else
{ {
$oModuleInstaller = new FTPModuleInstaller($package); $oModuleInstaller = new FTPModuleInstaller($package);
$oModuleInstaller->setPassword($ftp_password);
} }
$oModuleInstaller->install(); $output = $oModuleInstaller->install();
if(!$output->toBool()) return $output;
} }
$this->setMessage('success_installed'); $this->setMessage('success_installed');
} }

View file

@ -8,12 +8,21 @@
class autoinstallAdminView extends autoinstall { class autoinstallAdminView extends autoinstall {
var $categories;
function init() { function init() {
$template_path = sprintf("%stpl/",$this->module_path); $template_path = sprintf("%stpl/",$this->module_path);
Context::set('original_site', $this->original_site); Context::set('original_site', $this->original_site);
Context::set('uri', $this->uri); Context::set('uri', $this->uri);
$this->setTemplatePath($template_path); $this->setTemplatePath($template_path);
$ftp_info = Context::getFTPInfo();
if(!$ftp_info->ftp_root_path) Context::set('show_ftp_note', true);
$this->dispCategory();
$oModel = &getModel('autoinstall');
Context::set('tCount', $oModel->getPackageCount(null));
Context::set('iCount', $oModel->getInstalledPackageCount());
} }
function rearrange(&$item, &$targets) function rearrange(&$item, &$targets)
@ -26,7 +35,7 @@
return $ret; return $ret;
} }
function rearranges($items) function rearranges($items, $packages = null)
{ {
if(!is_array($items)) $items = array($items); if(!is_array($items)) $items = array($items);
$item_list = array(); $item_list = array();
@ -37,7 +46,8 @@
$targetpackages[$item->package_srl->body] = 0; $targetpackages[$item->package_srl->body] = 0;
} }
$oModel = &getModel('autoinstall'); $oModel = &getModel('autoinstall');
$packages = $oModel->getInstalledPackages(array_keys($targetpackages)); if($package == null)
$packages = $oModel->getInstalledPackages(array_keys($targetpackages));
foreach($items as $item) foreach($items as $item)
{ {
@ -53,11 +63,39 @@
return $item_list; return $item_list;
} }
function dispAutoinstallAdminInstalledPackages()
{
$page = Context::get('page');
if(!$page) $page = 1;
Context::set('page', $page);
$oModel = &getModel('autoinstall');
$output = $oModel->getInstalledPackageList($page);
$package_list = $output->data;
$params["act"] = "getResourceapiPackages";
$params["package_srls"] = implode(",", array_keys($package_list));
$body = XmlGenerater::generate($params);
$buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml");
$xml_lUpdate = new XmlParser();
$xmlDoc = $xml_lUpdate->parse($buff);
if($xmlDoc && $xmlDoc->response->packagelist->item)
{
$item_list = $this->rearranges($xmlDoc->response->packagelist->item, $package_list);
$res = array();
foreach($package_list as $package_srl => $package)
{
$res[] = $item_list[$package_srl];
}
Context::set('item_list', $res);
}
Context::set('page_navigation', $output->page_navigation);
$this->setTemplateFile('index');
}
function dispAutoinstallAdminInstall() { function dispAutoinstallAdminInstall() {
$package_srl = Context::get('package_srl'); $package_srl = Context::get('package_srl');
if(!$package_srl) return $this->dispAutoinstallAdminIndex(); if(!$package_srl) return $this->dispAutoinstallAdminIndex();
$ftp_info = Context::getFTPInfo();
if(!$ftp_info->ftp_root_path) Context::set('show_ftp_note', true);
$params["act"] = "getResourceapiInstallInfo"; $params["act"] = "getResourceapiInstallInfo";
$params["package_srl"] = $package_srl; $params["package_srl"] = $package_srl;
@ -119,6 +157,10 @@
Context::set("package", $package); Context::set("package", $package);
} }
if(!$_SESSION['ftp_password'])
{
Context::set('need_password', true);
}
$this->setTemplateFile('install'); $this->setTemplateFile('install');
} }
@ -140,7 +182,7 @@
$oModel = &getModel('autoinstall'); $oModel = &getModel('autoinstall');
$item = $oModel->getLatestPackage(); $item = $oModel->getLatestPackage();
if(!$item || $item->updatedate < $updateDate ) if(!$item || $item->updatedate < $updateDate || count($this->categories) < 1)
{ {
Context::set('need_update', true); Context::set('need_update', true);
return; return;
@ -185,10 +227,13 @@
Context::set('page_navigation', $page_navigation); Context::set('page_navigation', $page_navigation);
} }
}
function dispCategory()
{
$oModel = &getModel('autoinstall'); $oModel = &getModel('autoinstall');
$categories = &$oModel->getCategoryList(); $this->categories = &$oModel->getCategoryList();
Context::set('categories', $categories); Context::set('categories', $this->categories);
Context::set('tCount', $oModel->getPackageCount(null));
} }
} }
?> ?>

View file

@ -45,6 +45,16 @@
* @brief 설치가 이상이 없는지 체크하는 method * @brief 설치가 이상이 없는지 체크하는 method
**/ **/
function checkUpdate() { function checkUpdate() {
$oDB =& DB::getInstance();
if($oDB->isTableExists("autoinstall_installed_packages"))
{
return true;
}
if($oDB->isTableExists("autoinstall_remote_categories"))
{
return true;
}
return false; return false;
} }
@ -52,6 +62,15 @@
* @brief 업데이트 실행 * @brief 업데이트 실행
**/ **/
function moduleUpdate() { function moduleUpdate() {
$oDB =& DB::getInstance();
if($oDB->isTableExists("autoinstall_installed_packages"))
{
$oDB->dropTable("autoinstall_installed_packages");
}
if($oDB->isTableExists("autoinstall_remote_categories"))
{
$oDB->dropTable("autoinstall_remote_categories");
}
return new Object(0, 'success_updated'); return new Object(0, 'success_updated');
} }

View file

@ -0,0 +1,215 @@
<?php
class ModuleInstaller {
var $package = null;
var $base_url = 'http://download.xpressengine.com/';
var $temp_dir = './files/cache/autoinstall/';
var $target_path;
var $download_file;
var $url;
var $download_path;
var $ftp_password;
function setPassword($ftp_password)
{
$this->ftp_password = $ftp_password;
}
function _download()
{
if($this->package->path == ".")
{
$this->download_file = $this->temp_dir."xe.tar";
$this->target_path = "";
$this->download_path = $this->temp_dir;
}
else
{
$subpath = substr($this->package->path,2);
$this->download_file = $this->temp_dir.$subpath.".tar";
$subpatharr = explode("/", $subpath);
array_pop($subpatharr);
$this->download_path = $this->temp_dir.implode("/", $subpatharr);
$this->target_path = implode("/", $subpatharr);
}
$postdata = array();
$postdata["path"] = $this->package->path;
$postdata["module"] = "resourceapi";
$postdata["act"] = "procResourceapiDownload";
$buff = FileHandler::getRemoteResource($this->base_url, null, 3, "POST", "application/x-www-form-urlencoded; charset=utf-8", array(), array(), $postdata);
FileHandler::writeFile($this->download_file, $buff);
}
function installModule()
{
$path_array = explode("/", $this->package->path);
$target_name = array_pop($path_array);
$type = substr(array_pop($path_array), 0, -1);
if($type == "module")
{
$oModuleModel = &getModel('module');
$oInstallController = &getController('install');
$module_path = ModuleHandler::getModulePath($target_name);
if($oModuleModel->checkNeedInstall($target_name))
{
$oInstallController->installModule($target_name, $module_path);
}
if($oModuleModel->checkNeedUpdate($target_name))
{
$oModule = &getModule($target_name, 'class');
if(method_exists($oModule, 'moduleUpdate'))
{
$oModule->moduleUpdate();
}
}
}
}
function install()
{
$this->_download();
$file_list = $this->_unPack();
$output = $this->_copyDir($file_list);
if(!$output->toBool())
{
FileHandler::removeDir($this->temp_dir);
return $output;
}
$this->installModule();
FileHandler::removeDir($this->temp_dir);
return new Object();
}
function _unPack(){
require_once(_XE_PATH_.'libs/tar.class.php');
$oTar = new tar();
$oTar->openTAR($this->download_file);
$_files = $oTar->files;
$file_list = array();
foreach($_files as $key => $info) {
FileHandler::writeFile($this->download_path."/".$info['name'], $info['file']);
$file_list[] = $info['name'];
}
return $file_list;
}
}
class SFTPModuleInstaller extends ModuleInstaller {
function SFTPModuleInstaller(&$package)
{
$this->package =& $package;
}
function _copyDir(&$file_list){
if(!$this->ftp_password) return new Object(-1,'msg_ftp_password_input');
$ftp_info = Context::getFTPInfo();
if(!$ftp_info->ftp_user || !$ftp_info->sftp || $ftp_info->sftp != 'Y') return new Object(-1,'msg_ftp_invalid_auth_info');
if($ftp_info->ftp_host)
{
$ftp_host = $ftp_info->ftp_host;
}
else
{
$ftp_host = "127.0.0.1";
}
$connection = ssh2_connect($ftp_host, $ftp_info->ftp_port);
if(!ssh2_auth_password($connection, $ftp_info->ftp_user, $this->ftp_password))
{
return new Object(-1,'msg_ftp_invalid_auth_info');
}
$sftp = ssh2_sftp($connection);
$target_dir = $ftp_info->ftp_root_path.$this->target_path;
foreach($file_list as $k => $file){
$org_file = $file;
if($this->package->path == ".")
{
$file = substr($file,3);
}
$path = FileHandler::getRealPath("./".$this->target_path."/".$file);
$pathname = dirname($target_dir."/".$file);
if(!file_exists(FileHandler::getRealPath($real_path)))
{
ssh2_sftp_mkdir($sftp, $pathname, 0755, true);
}
ssh2_scp_send($connection, FileHandler::getRealPath($this->download_path."/".$org_file), $target_dir."/".$file);
}
return new Object();
}
}
class FTPModuleInstaller extends ModuleInstaller {
function FTPModuleInstaller(&$package)
{
$this->package =& $package;
}
function _copyDir(&$file_list){
$ftp_info = Context::getFTPInfo();
if(!$this->ftp_password) return new Object(-1,'msg_ftp_password_input');
require_once(_XE_PATH_.'libs/ftp.class.php');
if($ftp_info->ftp_host)
{
$ftp_host = $ftp_info->ftp_host;
}
else
{
$ftp_host = "127.0.0.1";
}
$oFtp = new ftp();
if(!$oFtp->ftp_connect($ftp_host, $ftp_info->ftp_port)) return new Object(-1,'msg_ftp_not_connected');
if(!$oFtp->ftp_login($ftp_info->ftp_user, $this->ftp_password)) {
$oFtp->ftp_quit();
return new Object(-1,'msg_ftp_invalid_auth_info');
}
$_list = $oFtp->ftp_rawlist($ftp_info->ftp_root_path);
$target_dir = $ftp_info->ftp_root_path.$this->target_path;
foreach($file_list as $k => $file){
$org_file = $file;
if($this->package->path == ".")
{
$file = substr($file,3);
}
$path = FileHandler::getRealPath("./".$this->target_path."/".$file);
$path_list = explode('/', dirname($this->target_path."/".$file));
$real_path = "./";
$ftp_path = $ftp_info->ftp_root_path;
for($i=0;$i<count($path_list);$i++)
{
if($path_list=="") continue;
$real_path .= $path_list[$i]."/";
$ftp_path .= $path_list[$i]."/";
if(!file_exists(FileHandler::getRealPath($real_path)))
{
$oFtp->ftp_mkdir($ftp_path);
$oFtp->ftp_site("CHMOD 755 ".$path);
}
}
$oFtp->ftp_put($target_dir .'/'. $file, FileHandler::getRealPath($this->download_path."/".$org_file));
}
$oFtp->ftp_quit();
return new Object();
}
}
?>

View file

@ -78,6 +78,13 @@
return $output->data->count; return $output->data->count;
} }
function getInstalledPackageCount()
{
$output = executeQuery("autoinstall.getInstalledPackageCount", $args);
if(!$output->data) return 0;
return $output->data->count;
}
function setDepth(&$item, $depth, &$list, &$resultList) function setDepth(&$item, $depth, &$list, &$resultList)
{ {
$resultList[$item->category_srl] =& $item; $resultList[$item->category_srl] =& $item;
@ -113,5 +120,18 @@
return $result; return $result;
} }
function getInstalledPackageList($page)
{
$args->page = $page;
$output = executeQueryArray("autoinstall.getInstalledPackageList", $args);
$res = array();
foreach($output->data as $val)
{
$res[$val->package_srl] = $val;
}
$output->data = $res;
return $output;
}
} }
?> ?>

View file

@ -1,15 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module version="0.2"> <module version="0.2">
<title xml:lang="ko">쉬운 설치</title> <title xml:lang="ko">쉬운 설치</title>
<title xml:lang="en">Easy-Installation</title> <title xml:lang="en">One Click Installer</title>
<title xml:lang="vi">Cài đặt tự động</title> <title xml:lang="vi">Cài đặt tự động</title>
<title xml:lang="zh-TW">自動安裝</title> <title xml:lang="zh-TW">自動安裝</title>
<title xml:lang="zh-CN">在线安装</title> <title xml:lang="zh-CN">在线安装</title>
<title xml:lang="jp">イージーインストール</title>
<description xml:lang="ko">관리자 모드에서 클릭으로 모듈/스킨/레이아웃/위젯/위젯스타일 등을 설치하는 모듈입니다.</description> <description xml:lang="ko">관리자 모드에서 클릭으로 모듈/스킨/레이아웃/위젯/위젯스타일 등을 설치하는 모듈입니다.</description>
<description xml:lang="en">With this module, you can install and upgrade your programs including modules, skins, layouts, etc., from www.xpressengine.com by one-click.</description> <description xml:lang="en">With this module, you can install and upgrade your programs including modules, skins, layouts, etc., from www.xpressengine.com by one-click.</description>
<description xml:lang="vi">Với Module này, bạn có thể cập nhật và cài đặt các phiên bản một cách tự động. Bao gồm Module, Layout, Widget, Addon, ... từ trang chủ XE bằng một bấm chuột.</description> <description xml:lang="vi">Với Module này, bạn có thể cập nhật và cài đặt các phiên bản một cách tự động. Bao gồm Module, Layout, Widget, Addon, ... từ trang chủ XE bằng một bấm chuột.</description>
<description xml:lang="zh-TW">With this module, you can install and upgrade your programs including modules, skins, layouts, etc., from www.xpressengine.com by one-click.</description> <description xml:lang="zh-TW">With this module, you can install and upgrade your programs including modules, skins, layouts, etc., from www.xpressengine.com by one-click.</description>
<description xml:lang="zh-CN">很方便的在管理页面一键安装XE相关模块(模块/皮肤/布局/控件/控件样式等)。</description> <description xml:lang="zh-CN">很方便的在管理页面一键安装XE相关模块(模块/皮肤/布局/控件/控件样式等)。</description>
<description xml:lang="jp">管理者モードにてクリックだけで、モジュール/スキン/レイアウト/ウィジェット/ウィジェットスタイルのインストールを可能にするモジュールです。</description>
<version>0.1</version> <version>0.1</version>
<date>2009-11-11</date> <date>2009-11-11</date>
<category>system</category> <category>system</category>
@ -19,6 +21,7 @@
<name xml:lang="vi">haneul</name> <name xml:lang="vi">haneul</name>
<name xml:lang="zh-TW">haneul</name> <name xml:lang="zh-TW">haneul</name>
<name xml:lang="zh-CN">haneul</name> <name xml:lang="zh-CN">haneul</name>
<name xml:lang="jp">haneul</name>
</author> </author>
<author email_address="sol@ngleader.com" link="http://ngleader.com"> <author email_address="sol@ngleader.com" link="http://ngleader.com">
<name xml:lang="ko">sol</name> <name xml:lang="ko">sol</name>
@ -26,5 +29,6 @@
<name xml:lang="vi">sol</name> <name xml:lang="vi">sol</name>
<name xml:lang="zh-TW">sol</name> <name xml:lang="zh-TW">sol</name>
<name xml:lang="zh-CN">sol</name> <name xml:lang="zh-CN">sol</name>
<name xml:lang="jp">sol</name>
</author> </author>
</module> </module>

View file

@ -2,6 +2,7 @@
<module> <module>
<actions> <actions>
<action name="dispAutoinstallAdminInstall" type="view" standalone="true" /> <action name="dispAutoinstallAdminInstall" type="view" standalone="true" />
<action name="dispAutoinstallAdminInstalledPackages" type="view" standalone="true" />
<action name="dispAutoinstallAdminIndex" type="view" standalone="true" admin_index="true" /> <action name="dispAutoinstallAdminIndex" type="view" standalone="true" admin_index="true" />
<action name="procAutoinstallAdminUpdateinfo" type="controller" standalone="true" /> <action name="procAutoinstallAdminUpdateinfo" type="controller" standalone="true" />
<action name="procAutoinstallAdminPackageinstall" type="controller" standalone="true" /> <action name="procAutoinstallAdminPackageinstall" type="controller" standalone="true" />

View file

@ -1,31 +1,33 @@
<?php <?php
/** /**
* @file ko.lang.php * @file en.lang.php
* @author sol (sol@ngleader.com) * @author haneul (haneul0318@gmail.com)
* @brief Autoinstall(autoinstall) 모듈의 기본 언어팩 * @brief Autoinstall(autoinstall) language pack (English)
**/ **/
$lang->autoinstall = 'Easy-install'; $lang->autoinstall = 'EasyInstall';
$lang->about_autoinstall = 'It helps you install/upgrade progams(skins) of XE.'; $lang->about_autoinstall = 'EasyInstall module will help you install/upgrade programs(skins) for XE.';
$lang->package_update = 'Recent Update'; $lang->package_update = 'Recent Update';
$lang->package_downloaded_count = 'Download Count'; $lang->package_downloaded_count = 'Download Count';
$lang->need_update = "You need to update package list."; $lang->need_update = "Please update package list first.";
$lang->order_newest = "Newest"; $lang->order_newest = "Newest";
$lang->order_popular = "Popular"; $lang->order_popular = "Popular";
$lang->order_download = "Download"; $lang->order_download = "Download";
$lang->success_installed = "Installations succeeded."; $lang->success_installed = "Successfully Installed";
$lang->view_all_package = "View All"; $lang->view_all_package = "View All";
$lang->description_ftp_note = "If FTP configuration is not set, installation would not work. Please configure FTP information"; $lang->description_ftp_note = "If FTP configuration is not set, installation would not work. Please configure FTP information";
$lang->description_update = "If you recently upgrade or install programs without easy installation module, please press update button to keep information of the programs updated."; $lang->description_update = "If you have upgraded or installed programs without EasyInstall module, please press update button to renew new information.";
$lang->install = "Install"; $lang->install = "Install";
$lang->update = "Update"; $lang->update = "Update";
$lang->current_version = "Installed version"; $lang->current_version = "Version";
$lang->depending_programs = "This program depends on "; $lang->depending_programs = "This program is depending on ";
$lang->require_update = "Update is required."; $lang->require_update = "Update is required.";
$lang->require_installation = "Installation is required."; $lang->require_installation = "Installation is required.";
$lang->description_install = "Installation process also install/update programs which this program depends on"; $lang->description_install = "EasyInstall will also install/update all other programs which this program is depending on";
$lang->description_download = "When FTP is disabled, you should download it and extract it into target path. (if target path is ./modules/board, extract it at ./modules)"; $lang->description_download = "If FTP is unavailable, you should manually download it and extract it into target path. (if target path is ./modules/board, extract it at ./modules)";
$lang->path = "Path"; $lang->path = "Path";
$lang->cmd_download = "Download"; $lang->cmd_download = "Download";
$lang->view_installed_packages = "Installed Packages";
$lang->msg_ftp_password_input = "Please input FTP password.";
?> ?>

View file

@ -0,0 +1,33 @@
<?php
/**
* @file modules/autoinstall/lang/jp.lang.php
* @author sol (sol@ngleader.com) 翻訳:ミニミ
* @brief Autoinstall(autoinstall) 日本語基本言語パッケージ
**/
$lang->autoinstall = 'イージーインストール';
$lang->about_autoinstall = 'XpressEngineの様々なプログラムを管理者画面上で簡単にインストール・アップグレードするモジュールです。';
$lang->package_update = '最新アップデート';
$lang->package_downloaded_count = '全体ダウンロード';
$lang->need_update = "アップデートが必要です。";
$lang->order_newest = "新規登録";
$lang->order_popular = "人気";
$lang->order_download = "ダウンロード";
$lang->success_installed = "インストールが成功しました。";
$lang->view_all_package = "全てをみる";
$lang->description_ftp_note = "FTP設定が完了されないと、イージーインストールが動作しません。 FTP設定を確認して下さい。";
$lang->description_update = "新しくインストールしたモジュールバージョン情報などは「アップデート」を押すと反映されます。";
$lang->install = "インストール";
$lang->update = "アップデート";
$lang->current_version = "現インストールバージョン";
$lang->depending_programs = "依存プログラム";
$lang->require_update = "アップデートが必要です。";
$lang->require_installation = "インストールが必要です。";
$lang->description_install = "インストールに進みますと、本プログラムが依存している全てのプログラムをアップデート/インストールします。";
$lang->description_download = "FTPの利用が出来ない場合は、直接ダウンロードし、サーバー上の該当パスにてインストールして下さい。 (一つ上階層にて解凍します。 ./modules/board の場合 ./modulesにて tarを解凍して下さい。)";
$lang->path = "インストールパス";
$lang->cmd_download = "ダウンロード";
$lang->view_installed_packages = "Installed Packages";
$lang->msg_ftp_password_input = "Please input FTP password.";
?>

View file

@ -28,4 +28,6 @@
$lang->description_download = "FTP를 이용할 수 없는 경우, 직접 다운로드 하여 해당 path에 설치하셔야 합니다. (한칸 상위에서 압축을 푸시면 됩니다. ./modules/board의 경우 ./modules에서 tar를 푸세요)"; $lang->description_download = "FTP를 이용할 수 없는 경우, 직접 다운로드 하여 해당 path에 설치하셔야 합니다. (한칸 상위에서 압축을 푸시면 됩니다. ./modules/board의 경우 ./modules에서 tar를 푸세요)";
$lang->path = "설치경로"; $lang->path = "설치경로";
$lang->cmd_download = "다운로드"; $lang->cmd_download = "다운로드";
$lang->view_installed_packages = "설치된 패키지";
$lang->msg_ftp_password_input = "FTP 비밀번호를 입력해주세요";
?> ?>

View file

@ -28,4 +28,6 @@
$lang->description_download = "Khi FTP không được mở, bạn nên tải về và giả nén, sau đó Upload theo đường dẫn. (Nếu đường dẫn là ./modules/board, thì giải nén vào ./modules)"; $lang->description_download = "Khi FTP không được mở, bạn nên tải về và giả nén, sau đó Upload theo đường dẫn. (Nếu đường dẫn là ./modules/board, thì giải nén vào ./modules)";
$lang->path = "Đường dẫn"; $lang->path = "Đường dẫn";
$lang->cmd_download = "Download"; $lang->cmd_download = "Download";
$lang->view_installed_packages = "Installed Packages";
$lang->msg_ftp_password_input = "Please input FTP password.";
?> ?>

View file

@ -28,4 +28,6 @@
$lang->description_download = "When FTP is disabled, you should download it and extract it into target path. (if target path is ./modules/board, extract it at ./modules)"; $lang->description_download = "When FTP is disabled, you should download it and extract it into target path. (if target path is ./modules/board, extract it at ./modules)";
$lang->path = "Path"; $lang->path = "Path";
$lang->cmd_download = "Download"; $lang->cmd_download = "Download";
$lang->view_installed_packages = "Installed Packages";
$lang->msg_ftp_password_input = "Please input FTP password.";
?> ?>

View file

@ -20,12 +20,14 @@
$lang->description_update = "如果您最近不是用自動安裝模組更新或安裝,請點擊更新按鈕更新。"; $lang->description_update = "如果您最近不是用自動安裝模組更新或安裝,請點擊更新按鈕更新。";
$lang->install = "安裝"; $lang->install = "安裝";
$lang->update = "更新"; $lang->update = "更新";
$lang->depending_programs = "This program depends on "; $lang->current_version = "版本";
$lang->depending_programs = "此程式需要安裝";
$lang->require_update = "需要更新"; $lang->require_update = "需要更新";
$lang->require_installation = "需要安裝"; $lang->require_installation = "需要安裝";
$lang->description_install = "Installation process also install/update programs which this program depends on"; $lang->description_install = "One Click Installer will also install/update all other programs which this program is depending on";
$lang->current_version = "安裝版本"; $lang->description_download = "如果FTP無法使用的話必須要手動下載並解壓縮到目標路徑。(假設目標路徑為 ./modules/board的話將檔案解壓縮到 ./modules就可以了)";
$lang->description_download = "When FTP is disabled, you should download it and extract it into target path. (if target path is ./modules/board, extract it at ./modules)";
$lang->path = "路徑"; $lang->path = "路徑";
$lang->cmd_download = "Download"; $lang->cmd_download = "下載";
$lang->view_installed_packages = "已安裝套裝軟體";
$lang->msg_ftp_password_input = "Please input FTP password.";
?> ?>

View file

@ -1,6 +1,6 @@
<query id="deleteCategory" action="delete"> <query id="deleteCategory" action="delete">
<tables> <tables>
<table name="autoinstall_remote_categories" /> <table name="ai_remote_categories" />
</tables> </tables>
<conditions> <conditions>
</conditions> </conditions>

View file

@ -1,6 +1,6 @@
<query id="deleteInstalledPackage" action="delete"> <query id="deleteInstalledPackage" action="delete">
<tables> <tables>
<table name="autoinstall_installed_packages" /> <table name="ai_installed_packages" />
</tables> </tables>
<conditions> <conditions>
<condition operation="equal" column="package_srl" var="package_srl" filter="number" /> <condition operation="equal" column="package_srl" var="package_srl" filter="number" />

View file

@ -1,6 +1,6 @@
<query id="getCategories" action="select"> <query id="getCategories" action="select">
<tables> <tables>
<table name="autoinstall_remote_categories" /> <table name="ai_remote_categories" />
</tables> </tables>
<columns> <columns>
<column name="*" /> <column name="*" />

View file

@ -1,6 +1,6 @@
<query id="getCategory" action="select"> <query id="getCategory" action="select">
<tables> <tables>
<table name="autoinstall_remote_categories" /> <table name="ai_remote_categories" />
</tables> </tables>
<columns> <columns>
<column name="*" /> <column name="*" />

View file

@ -1,6 +1,6 @@
<query id="getInstalledPackage" action="select"> <query id="getInstalledPackage" action="select">
<tables> <tables>
<table name="autoinstall_installed_packages" /> <table name="ai_installed_packages" />
</tables> </tables>
<columns> <columns>
<column name="*" /> <column name="*" />

View file

@ -0,0 +1,8 @@
<query id="getInstalledPackageCount" action="select">
<tables>
<table name="ai_installed_packages" />
</tables>
<columns>
<column name="count(*)" alias="count" />
</columns>
</query>

View file

@ -0,0 +1,14 @@
<query id="getInstalledPackageList" action="select">
<tables>
<table name="ai_installed_packages" />
</tables>
<columns>
<column name="*" />
</columns>
<navigation>
<index var="sort_index" default="need_update" order="desc" />
<list_count var="list_count" default="10" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
</query>

View file

@ -1,6 +1,6 @@
<query id="getInstalledPackages" action="select"> <query id="getInstalledPackages" action="select">
<tables> <tables>
<table name="autoinstall_installed_packages" /> <table name="ai_installed_packages" />
</tables> </tables>
<columns> <columns>
<column name="*" /> <column name="*" />

View file

@ -1,6 +1,6 @@
<query id="insertCategory" action="insert"> <query id="insertCategory" action="insert">
<tables> <tables>
<table name="autoinstall_remote_categories" /> <table name="ai_remote_categories" />
</tables> </tables>
<columns> <columns>
<column name="category_srl" var="category_srl" filter="number" notnull="notnull" /> <column name="category_srl" var="category_srl" filter="number" notnull="notnull" />

View file

@ -1,6 +1,6 @@
<query id="insertInstalledPackage" action="insert"> <query id="insertInstalledPackage" action="insert">
<tables> <tables>
<table name="autoinstall_installed_packages" /> <table name="ai_installed_packages" />
</tables> </tables>
<columns> <columns>
<column name="package_srl" var="package_srl" filter="number" notnull="notnull" /> <column name="package_srl" var="package_srl" filter="number" notnull="notnull" />

View file

@ -1,6 +1,6 @@
<query id="updateCategory" action="update"> <query id="updateCategory" action="update">
<tables> <tables>
<table name="autoinstall_remote_categories" /> <table name="ai_remote_categories" />
</tables> </tables>
<columns> <columns>
<column name="parent_srl" var="parent_srl" filter="number" notnull="notnull" /> <column name="parent_srl" var="parent_srl" filter="number" notnull="notnull" />

View file

@ -1,6 +1,6 @@
<query id="updateInstalledPackage" action="update"> <query id="updateInstalledPackage" action="update">
<tables> <tables>
<table name="autoinstall_installed_packages" /> <table name="ai_installed_packages" />
</tables> </tables>
<columns> <columns>
<column name="version" var="version" notnull="notnull" /> <column name="version" var="version" notnull="notnull" />

View file

@ -1,4 +1,4 @@
<table name="autoinstall_installed_packages"> <table name="ai_installed_packages">
<column name="package_srl" type="number" size="11" notnull="notnull" default="0" index="idx_package_srl" /> <column name="package_srl" type="number" size="11" notnull="notnull" default="0" index="idx_package_srl" />
<column name="version" type="varchar" size="255" /> <column name="version" type="varchar" size="255" />
<column name="current_version" type="varchar" size="255" /> <column name="current_version" type="varchar" size="255" />

View file

@ -1,4 +1,4 @@
<table name="autoinstall_remote_categories"> <table name="ai_remote_categories">
<column name="category_srl" type="number" size="11" default="0" notnull="notnull" primary_key="primary_key" /> <column name="category_srl" type="number" size="11" default="0" notnull="notnull" primary_key="primary_key" />
<column name="parent_srl" type="number" size="11" default="0" notnull="notnull" index="idx_parent_srl" /> <column name="parent_srl" type="number" size="11" default="0" notnull="notnull" index="idx_parent_srl" />
<column name="title" type="varchar" size="250" notnull="notnull" /> <column name="title" type="varchar" size="250" notnull="notnull" />

View file

@ -6,7 +6,9 @@
.aside { width:180px; float:left; margin-right:30px; padding-bottom:30px; } .aside { width:180px; float:left; margin-right:30px; padding-bottom:30px; }
.aside .categoryBox { background-color:#F8F8F8; padding:10px; width:160px; overflow:hidden; } .aside .categoryBox { background-color:#F8F8F8; padding:10px; width:160px; overflow:hidden; }
.aside .categoryBox h3 { padding:0 0 10px 0; margin:0 0 10px 0; white-space:nowrap; overflow:hidden; color:#48494E; font-size:11px; font-weight:normal; background:transparent url(../img/hrE1.gif) repeat-x scroll left bottom;} .aside .categoryBox h3 { padding:0 0 10px 0; margin:0 0 10px 0; white-space:nowrap; overflow:hidden; color:#48494E; font-size:11px; font-weight:normal;}
.aside .categoryBox .bottomLine {background:transparent url(../img/hrE1.gif) repeat-x scroll left bottom;}
.aside .categoryBox .topLine {background:transparent url(../img/hrE1.gif) repeat-x scroll left top;}
.aside .categoryBox h3 a { color:#48494E; font-size:12px; font-weight:bold; text-decoration:none; } .aside .categoryBox h3 a { color:#48494E; font-size:12px; font-weight:bold; text-decoration:none; }
.aside .categoryBox ul.category { margin:10px 0 0 0; padding:0; list-style:none; } .aside .categoryBox ul.category { margin:10px 0 0 0; padding:0; list-style:none; }
.aside .categoryBox ul.category li { margin:0 0 10px 10px; } .aside .categoryBox ul.category li { margin:0 0 10px 10px; }
@ -19,7 +21,7 @@
.aside .categoryBox ul.resourceManage li a { text-decoration:none; color:#747474; } .aside .categoryBox ul.resourceManage li a { text-decoration:none; color:#747474; }
.aside .categoryBox ul.resourceManage li a.selected { font-weight:bold; } .aside .categoryBox ul.resourceManage li a.selected { font-weight:bold; }
.aside .searchBox { padding:10px 0; text-align:center; background:transparent url(../img/hrE1.gif) repeat-x scroll left top;} .aside .searchBox { padding:10px 0; text-align:center; }
.aside .searchBox input.input { border:1px solid #ddd; width:120px; height:16px;} .aside .searchBox input.input { border:1px solid #ddd; width:120px; height:16px;}
.aside .searchBox input.submit { vertical-align:middle; } .aside .searchBox input.submit { vertical-align:middle; }

View file

@ -12,13 +12,19 @@
</dd> </dd>
</dl> </dl>
<!--@end--> <!--@end-->
<!--@if(!$package->installed || $package->need_update)-->
<!--@if($show_ftp_note)--> <!--@if($show_ftp_note)-->
<p class="warning">{$lang->description_download}. (<a href="{getUrl('','module','admin','act','dispAdminConfig')}#ftpSetup">FTP Setup</a>) </p> <p class="warning">{$lang->description_download}. (<a href="{getUrl('','module','admin','act','dispAdminConfig')}#ftpSetup">FTP Setup</a>) </p>
<p>{$lang->path} : {$package->path}</p> <p>{$lang->path} : {$package->path}</p>
<p><a href="http://download.xpressengine.com/?module=resourceapi&act=procResourceapiDownload&package_srl={$package->package_srl}" class="button large green strong"><span>{$lang->cmd_download}</span></a></p> <p><a href="http://download.xpressengine.com/?module=resourceapi&act=procResourceapiDownload&package_srl={$package->package_srl}" class="button large green strong"><span>{$lang->cmd_download}</span></a></p>
<!--@else--> <!--@else-->
<p>{$lang->description_install}. </p> <p>{$lang->description_install}. </p>
<p><!--@if(!$package->installed || $package->need_update)--><a href="#" onclick="doInstallPackage('{$package->package_srl}')" class="button large green strong"><span>{$lang->install}</span></a><!--@end--></p> <!--@if($need_password)-->
<p><label for="ftp_password">FTP {$lang->password} ({$lang->about_ftp_password}):</label><input type="password" name="ftp_password" id="ftp_password" class="inputTypeText" /></p>
<!--@end-->
<p><a href="#" onclick="doInstallPackage('{$package->package_srl}')" class="button large green strong"><span>{$package->installed?$lang->update:$lang->install}</span></a></p>
<!--@end-->
<!--@end--> <!--@end-->
</div> </div>

View file

@ -11,6 +11,12 @@ function doUpdate() {
function doInstallPackage(package_srl) { function doInstallPackage(package_srl) {
var params = new Array(); var params = new Array();
params['package_srl'] = package_srl; params['package_srl'] = package_srl;
var e = jQuery("#ftp_password").get(0)
if(typeof(e) != "undefined")
{
params['ftp_password'] = e.value;
}
exec_xml('autoinstall', 'procAutoinstallAdminPackageinstall', params, completeInstall); exec_xml('autoinstall', 'procAutoinstallAdminPackageinstall', params, completeInstall);
} }
@ -20,6 +26,7 @@ function completeUpdateNoMsg(ret_obj) {
function completeInstall(ret_obj) { function completeInstall(ret_obj) {
alert(ret_obj['message']); alert(ret_obj['message']);
if(ret_obj['error'] != 0) return;
var params = new Array(); var params = new Array();
exec_xml('autoinstall', 'procAutoinstallAdminUpdateinfo', params, completeUpdateNoMsg); exec_xml('autoinstall', 'procAutoinstallAdminUpdateinfo', params, completeUpdateNoMsg);
} }

View file

@ -1,6 +1,6 @@
<div class="aside"> <div class="aside">
<div class="categoryBox"> <div class="categoryBox">
<h3><a href="{getUrl('category_srl','')}">{$lang->view_all_package}</a> <span>({$tCount})</span></h3> <h3 class="bottomLine"><a href="{getUrl('act','dispAutoinstallAdminIndex','category_srl','')}">{$lang->view_all_package}</a> <span>({$tCount})</span></h3>
{@ $_pDepth = 0;} {@ $_pDepth = 0;}
<ul class="category"> <ul class="category">
@ -14,9 +14,9 @@
<!--@end--> <!--@end-->
<li> <li>
<!--@if(count($val->children))--> <!--@if(count($val->children))-->
<a href="{getUrl('category_srl',$val->category_srl,'childrenList',$val->childrenList)}"<!--@if($val->category_srl == $category_srl)--> class="selected"<!--@end-->>{$val->title}</a> <a href="{getUrl('act','dispAutoinstallAdminIndex','category_srl',$val->category_srl,'childrenList',$val->childrenList)}"<!--@if($val->category_srl == $category_srl)--> class="selected"<!--@end-->>{$val->title}</a>
<!--@else--> <!--@else-->
<a href="{getUrl('category_srl',$val->category_srl,'childrenList','')}"<!--@if($val->category_srl == $category_srl)--> class="selected"<!--@end-->>{$val->title}</a> <a href="{getUrl('act','dispAutoinstallAdminIndex','category_srl',$val->category_srl,'childrenList','')}"<!--@if($val->category_srl == $category_srl)--> class="selected"<!--@end-->>{$val->title}</a>
<!--@end--> <!--@end-->
<!--@if($val->nPackages)--> <!--@if($val->nPackages)-->
<span>({$val->nPackages})</span> <span>({$val->nPackages})</span>
@ -33,7 +33,7 @@
<!--@end--> <!--@end-->
</li> </li>
</ul> </ul>
<div class="searchBox"> <div class="searchBox bottomLine">
<form action="{getUrl()}" method="get"> <form action="{getUrl()}" method="get">
<input type="hidden" name="category_srl" value="{$category_srl}" /> <input type="hidden" name="category_srl" value="{$category_srl}" />
<input type="hidden" name="module" value="admin" /> <input type="hidden" name="module" value="admin" />
@ -42,6 +42,9 @@
<input type="image" src="./img/btn_search.gif" class="submit" /> <input type="image" src="./img/btn_search.gif" class="submit" />
</form> </form>
</div> </div>
<br />
<h3><a href="{getUrl('','module','admin','act','dispAutoinstallAdminInstalledPackages')}">{$lang->view_installed_packages}</a> <span>({$iCount})</span></h3>
</div> </div>
</div> </div>

Some files were not shown because too many files have changed in this diff Show more