From 8f385a592b3db251eba82483686d8c5b0d3cb9a7 Mon Sep 17 00:00:00 2001 From: ChanMyeong Date: Mon, 6 Sep 2010 06:35:20 +0000 Subject: [PATCH] Author name update. NHN developers@xpressengine.com http://xpressengine.com/ git-svn-id: http://xe-core.googlecode.com/svn/sandbox@7676 201d5d3c-b55e-5fd7-737f-ddc643e51545 --- addons/autolink/autolink.addon.php | 24 +- addons/autolink/autolink.js | 158 +- addons/autolink/conf/info.xml | 106 +- addons/blogapi/blogapi.addon.php | 936 ++--- addons/blogapi/blogapi.func.php | 138 +- addons/blogapi/conf/info.xml | 160 +- addons/captcha/captcha.addon.php | 524 +-- addons/captcha/conf/info.xml | 444 +- addons/counter/conf/info.xml | 124 +- addons/counter/counter.addon.php | 28 +- addons/member_communication/conf/info.xml | 116 +- addons/member_communication/lang/ru.lang.php | 2 +- addons/member_communication/lang/vi.lang.php | 2 +- .../member_communication.addon.php | 170 +- addons/member_extra_info/conf/info.xml | 106 +- .../member_extra_info.addon.php | 46 +- addons/mobile/classes/hdml.class.php | 206 +- addons/mobile/classes/mhtml.class.php | 164 +- addons/mobile/classes/mobile.class.php | 2 +- addons/mobile/classes/wml.class.php | 212 +- addons/mobile/conf/info.xml | 16 +- addons/mobile/lang/en.lang.php | 30 +- addons/mobile/lang/jp.lang.php | 34 +- addons/mobile/lang/ko.lang.php | 34 +- addons/mobile/lang/ru.lang.php | 34 +- addons/mobile/lang/vi.lang.php | 36 +- addons/mobile/lang/zh-CN.lang.php | 22 +- addons/mobile/lang/zh-TW.lang.php | 30 +- addons/mobile/mobile.addon.php | 122 +- addons/openid_delegation_id/conf/info.xml | 250 +- .../openid_delegation_id.addon.php | 58 +- addons/point_level_icon/conf/info.xml | 124 +- .../point_level_icon.addon.php | 38 +- addons/resize_image/conf/info.xml | 106 +- addons/resize_image/resize_image.addon.php | 26 +- classes/cache/CacheApc.class.php | 144 +- classes/cache/CacheHandler.class.php | 190 +- classes/cache/CacheMemcache.class.php | 182 +- classes/context/Context.class.php | 3114 +++++++------- classes/db/DB.class.php | 1256 +++--- classes/db/DBCubrid.class.php | 1950 ++++----- classes/db/DBMssql.class.php | 1748 ++++---- classes/db/DBMysql.class.php | 1374 +++--- classes/db/DBMysql_innodb.class.php | 1394 +++---- classes/db/DBMysqli.class.php | 1350 +++--- classes/db/DBSqlite2.class.php | 1456 +++---- classes/db/DBSqlite3_pdo.class.php | 1564 +++---- classes/display/DisplayHandler.class.php | 556 +-- classes/editor/EditorHandler.class.php | 54 +- classes/extravar/Extravar.class.php | 600 +-- classes/file/FileHandler.class.php | 1316 +++--- classes/file/FileObject.class.php | 256 +- classes/handler/Handler.class.php | 22 +- classes/httprequest/XEHttpRequest.class.php | 170 +- classes/mail/Mail.class.php | 706 ++-- classes/module/ModuleHandler.class.php | 1114 ++--- classes/object/Object.class.php | 274 +- classes/optimizer/Optimizer.class.php | 218 +- classes/page/PageHandler.class.php | 114 +- classes/template/TemplateHandler.class.php | 1070 ++--- classes/widget/WidgetHandler.class.php | 28 +- classes/xml/GeneralXmlParser.class.php | 166 +- classes/xml/XmlJsFilter.class.php | 596 +-- classes/xml/XmlParser.class.php | 308 +- classes/xml/XmlQueryParser.class.php | 1040 ++--- common/css/button.css | 2 +- common/js/common.js | 224 +- common/js/js_app.js | 32 +- common/js/plugins/ui.calendar/ui.calendar.js | 734 ++-- .../plugins/ui.colorpicker/xe_colorpicker.js | 732 ++-- .../plugins/watchinput/jquery.watchinput.js | 122 +- common/js/src/common.js | 1962 ++++----- common/js/src/js_app.js | 558 +-- common/js/src/xml_handler.js | 818 ++-- common/js/src/xml_js_filter.js | 602 +-- common/js/unittest/unittest_common.html | 148 +- common/js/xml_js_filter.js | 22 +- common/lang/en.lang.php | 6 +- common/lang/es.lang.php | 6 +- common/lang/fr.lang.php | 640 +-- common/lang/ge.lang.php | 644 +-- common/lang/jp.lang.php | 648 +-- common/lang/ko.lang.php | 2 +- common/lang/mn.lang.php | 638 +-- common/lang/ru.lang.php | 646 +-- common/lang/vi.lang.php | 2 +- common/lang/zh-CN.lang.php | 6 +- common/lang/zh-TW.lang.php | 6 +- common/script.php | 556 +-- config/config.inc.php | 2 +- config/func.inc.php | 1852 ++++----- index.php | 122 +- layouts/xe_official/conf/info.xml | 58 +- layouts/xe_official/css/black.css | 5 +- layouts/xe_official/css/default.css | 5 +- layouts/xe_official/css/white.css | 179 +- m.layouts/default/conf/info.xml | 24 +- m.layouts/simpleGray/conf/info.xml | 10 +- modules/addon/addon.admin.controller.php | 204 +- modules/addon/addon.admin.model.php | 626 +-- modules/addon/addon.admin.view.php | 196 +- modules/addon/addon.class.php | 142 +- modules/addon/addon.controller.php | 2 +- modules/addon/conf/info.xml | 72 +- modules/addon/lang/en.lang.php | 34 +- modules/addon/lang/es.lang.php | 2 +- modules/addon/lang/fr.lang.php | 2 +- modules/addon/lang/jp.lang.php | 34 +- modules/addon/lang/ko.lang.php | 34 +- modules/addon/lang/ru.lang.php | 34 +- modules/addon/lang/vi.lang.php | 38 +- modules/addon/lang/zh-CN.lang.php | 2 +- modules/addon/lang/zh-TW.lang.php | 2 +- modules/admin/lang/es.lang.php | 2 +- modules/admin/lang/vi.lang.php | 2 +- modules/admin/tpl/css/admin.css | 3 +- modules/admin/tpl/css/font.css | 2 +- modules/admin/tpl/css/layout.css | 3 +- modules/admin/tpl/css/pagination.css | 2 +- .../autoinstall.admin.controller.php | 486 +-- .../autoinstall/autoinstall.admin.view.php | 638 +-- modules/autoinstall/autoinstall.class.php | 174 +- modules/autoinstall/autoinstall.model.php | 370 +- modules/autoinstall/autoinstall.view.php | 52 +- modules/autoinstall/conf/info.xml | 60 +- modules/autoinstall/lang/en.lang.php | 2 +- modules/autoinstall/lang/jp.lang.php | 2 +- modules/autoinstall/lang/ko.lang.php | 2 +- modules/autoinstall/lang/ru.lang.php | 2 +- modules/autoinstall/lang/vi.lang.php | 2 +- modules/autoinstall/lang/zh-CN.lang.php | 2 +- modules/autoinstall/lang/zh-TW.lang.php | 2 +- modules/autoinstall/tpl/css/autoinstall.css | 2 +- modules/comment/comment.admin.controller.php | 144 +- modules/comment/comment.admin.view.php | 166 +- modules/comment/comment.class.php | 210 +- modules/comment/comment.controller.php | 1238 +++--- modules/comment/comment.item.php | 2 +- modules/comment/comment.model.php | 842 ++-- modules/comment/comment.view.php | 96 +- modules/comment/conf/info.xml | 66 +- modules/comment/lang/en.lang.php | 62 +- modules/comment/lang/es.lang.php | 2 +- modules/comment/lang/fr.lang.php | 64 +- modules/comment/lang/jp.lang.php | 64 +- modules/comment/lang/ko.lang.php | 64 +- modules/comment/lang/ru.lang.php | 64 +- modules/comment/lang/vi.lang.php | 66 +- modules/comment/lang/zh-CN.lang.php | 2 +- modules/comment/lang/zh-TW.lang.php | 2 +- .../communication.admin.controller.php | 2 +- .../communication.admin.model.php | 80 +- .../communication.admin.view.php | 80 +- modules/communication/communication.class.php | 84 +- .../communication.controller.php | 836 ++-- modules/communication/communication.model.php | 378 +- modules/communication/communication.view.php | 456 +- modules/communication/conf/info.xml | 60 +- modules/communication/lang/en.lang.php | 96 +- modules/communication/lang/es.lang.php | 98 +- modules/communication/lang/fr.lang.php | 96 +- modules/communication/lang/jp.lang.php | 96 +- modules/communication/lang/ko.lang.php | 96 +- modules/communication/lang/ru.lang.php | 98 +- modules/communication/lang/vi.lang.php | 100 +- modules/communication/lang/zh-CN.lang.php | 98 +- modules/communication/lang/zh-TW.lang.php | 2 +- modules/communication/skins/default/skin.xml | 230 +- modules/counter/conf/info.xml | 66 +- modules/counter/counter.admin.view.php | 100 +- modules/counter/counter.class.php | 138 +- modules/counter/counter.controller.php | 290 +- modules/counter/counter.model.php | 402 +- modules/counter/lang/en.lang.php | 50 +- modules/counter/lang/es.lang.php | 2 +- modules/counter/lang/fr.lang.php | 50 +- modules/counter/lang/jp.lang.php | 50 +- modules/counter/lang/ko.lang.php | 50 +- modules/counter/lang/ru.lang.php | 50 +- modules/counter/lang/vi.lang.php | 54 +- modules/counter/lang/zh-CN.lang.php | 2 +- modules/counter/lang/zh-TW.lang.php | 2 +- modules/document/conf/info.xml | 66 +- .../document/document.admin.controller.php | 1094 ++--- modules/document/document.admin.model.php | 174 +- modules/document/document.admin.view.php | 318 +- modules/document/document.class.php | 508 +-- modules/document/document.controller.php | 3300 +++++++-------- modules/document/document.item.php | 2 +- modules/document/document.model.php | 2058 ++++----- modules/document/document.view.php | 242 +- modules/document/lang/en.lang.php | 194 +- modules/document/lang/es.lang.php | 2 +- modules/document/lang/fr.lang.php | 162 +- modules/document/lang/jp.lang.php | 198 +- modules/document/lang/ko.lang.php | 200 +- modules/document/lang/ru.lang.php | 206 +- modules/document/lang/vi.lang.php | 202 +- modules/document/lang/zh-CN.lang.php | 200 +- modules/document/lang/zh-TW.lang.php | 2 +- modules/document/tpl/js/document_category.js | 2 +- .../components/emoticon/emoticon.class.php | 214 +- modules/editor/components/emoticon/info.xml | 64 +- .../image_gallery/image_gallery.class.php | 162 +- .../editor/components/image_gallery/info.xml | 64 +- .../components/image_gallery/lang/en.lang.php | 2 +- .../components/image_gallery/lang/es.lang.php | 2 +- .../components/image_gallery/lang/jp.lang.php | 54 +- .../components/image_gallery/lang/ko.lang.php | 54 +- .../components/image_gallery/lang/ru.lang.php | 2 +- .../components/image_gallery/lang/vi.lang.php | 2 +- .../image_gallery/lang/zh-CN.lang.php | 2 +- .../image_gallery/lang/zh-TW.lang.php | 2 +- .../image_gallery/tpl/list_gallery.js | 164 +- .../image_gallery/tpl/slide_gallery.js | 392 +- .../image_link/image_link.class.php | 216 +- modules/editor/components/image_link/info.xml | 64 +- .../components/image_link/lang/en.lang.php | 2 +- .../components/image_link/lang/es.lang.php | 2 +- .../components/image_link/lang/jp.lang.php | 46 +- .../components/image_link/lang/ko.lang.php | 46 +- .../components/image_link/lang/ru.lang.php | 2 +- .../components/image_link/lang/vi.lang.php | 2 +- .../components/image_link/lang/zh-CN.lang.php | 2 +- .../components/image_link/lang/zh-TW.lang.php | 2 +- .../components/multimedia_link/info.xml | 64 +- .../multimedia_link/lang/en.lang.php | 2 +- .../multimedia_link/lang/es.lang.php | 2 +- .../multimedia_link/lang/jp.lang.php | 36 +- .../multimedia_link/lang/ko.lang.php | 36 +- .../multimedia_link/lang/ru.lang.php | 2 +- .../multimedia_link/lang/vi.lang.php | 2 +- .../multimedia_link/lang/zh-CN.lang.php | 2 +- .../multimedia_link/lang/zh-TW.lang.php | 2 +- .../multimedia_link/multimedia_link.class.php | 142 +- modules/editor/components/poll_maker/info.xml | 64 +- .../components/poll_maker/lang/en.lang.php | 2 +- .../components/poll_maker/lang/es.lang.php | 2 +- .../components/poll_maker/lang/jp.lang.php | 36 +- .../components/poll_maker/lang/ko.lang.php | 36 +- .../components/poll_maker/lang/ru.lang.php | 2 +- .../components/poll_maker/lang/vi.lang.php | 2 +- .../components/poll_maker/lang/zh-CN.lang.php | 2 +- .../components/poll_maker/lang/zh-TW.lang.php | 2 +- .../poll_maker/poll_maker.class.php | 120 +- modules/editor/conf/info.xml | 66 +- modules/editor/editor.admin.controller.php | 332 +- modules/editor/editor.admin.view.php | 160 +- modules/editor/editor.api.php | 2 +- modules/editor/editor.class.php | 272 +- modules/editor/editor.controller.php | 2 +- modules/editor/editor.model.php | 2 +- modules/editor/editor.view.php | 276 +- modules/editor/lang/en.lang.php | 2 +- modules/editor/lang/es.lang.php | 2 +- modules/editor/lang/fr.lang.php | 2 +- modules/editor/lang/jp.lang.php | 2 +- modules/editor/lang/ko.lang.php | 2 +- modules/editor/lang/ru.lang.php | 2 +- modules/editor/lang/vi.lang.php | 2 +- modules/editor/lang/zh-CN.lang.php | 2 +- modules/editor/lang/zh-TW.lang.php | 2 +- .../skins/xpresseditor/js/Xpress_Editor.js | 13 +- modules/editor/skins/xpresseditor/skin.xml | 30 +- modules/editor/styles/default/editor.css | 46 +- modules/editor/styles/default/skin.xml | 86 +- modules/editor/styles/default/style.css | 3 +- modules/editor/styles/xeStyle/editor.css | 2 +- modules/editor/styles/xeStyle/skin.xml | 82 +- modules/editor/styles/xeStyle/style.css | 3 +- modules/editor/styles/xeStyleBlack/editor.css | 66 +- modules/editor/styles/xeStyleBlack/skin.xml | 12 +- modules/editor/tpl/js/editor.js | 2 +- modules/editor/tpl/js/editor_admin.js | 86 +- modules/editor/tpl/js/uploader.js | 872 ++-- modules/file/conf/info.xml | 66 +- modules/file/file.admin.controller.php | 254 +- modules/file/file.admin.model.php | 192 +- modules/file/file.admin.view.php | 374 +- modules/file/file.class.php | 298 +- modules/file/file.controller.php | 1206 +++--- modules/file/file.model.php | 426 +- modules/file/file.view.php | 106 +- modules/file/lang/en.lang.php | 4 +- modules/file/lang/es.lang.php | 4 +- modules/file/lang/fr.lang.php | 4 +- modules/file/lang/jp.lang.php | 4 +- modules/file/lang/ko.lang.php | 114 +- modules/file/lang/ru.lang.php | 2 +- modules/file/lang/vi.lang.php | 4 +- modules/file/lang/zh-CN.lang.php | 4 +- modules/file/lang/zh-TW.lang.php | 4 +- modules/importer/conf/info.xml | 66 +- modules/importer/extract.class.php | 416 +- .../importer/importer.admin.controller.php | 1930 ++++----- modules/importer/importer.admin.view.php | 116 +- modules/importer/importer.class.php | 74 +- modules/importer/lang/es.lang.php | 4 +- modules/importer/lang/fr.lang.php | 124 +- modules/importer/lang/jp.lang.php | 122 +- modules/importer/lang/ko.lang.php | 122 +- modules/importer/lang/ru.lang.php | 124 +- modules/importer/lang/vi.lang.php | 128 +- modules/importer/lang/zh-CN.lang.php | 4 +- modules/importer/lang/zh-TW.lang.php | 4 +- modules/importer/tpl/js/importer_admin.js | 340 +- modules/importer/ttimport.class.php | 1276 +++--- modules/install/conf/info.xml | 66 +- modules/install/install.admin.controller.php | 310 +- modules/install/install.class.php | 74 +- modules/install/install.controller.php | 720 ++-- modules/install/install.view.php | 182 +- modules/install/lang/en.lang.php | 1106 ++--- modules/install/lang/es.lang.php | 2 +- modules/install/lang/fr.lang.php | 1112 ++--- modules/install/lang/jp.lang.php | 1106 ++--- modules/install/lang/ko.lang.php | 1110 ++--- modules/install/lang/ru.lang.php | 1110 ++--- modules/install/lang/vi.lang.php | 1114 ++--- modules/install/lang/zh-CN.lang.php | 488 +-- modules/install/lang/zh-TW.lang.php | 2 +- modules/install/tpl/css/install.css | 110 +- modules/integration_search/conf/info.xml | 114 +- .../integration_search.admin.controller.php | 230 +- .../integration_search.admin.view.php | 168 +- .../integration_search.class.php | 82 +- .../integration_search.model.php | 372 +- .../integration_search.view.php | 206 +- modules/integration_search/lang/en.lang.php | 2 +- modules/integration_search/lang/es.lang.php | 2 +- modules/integration_search/lang/fr.lang.php | 2 +- modules/integration_search/lang/jp.lang.php | 86 +- modules/integration_search/lang/ko.lang.php | 86 +- modules/integration_search/lang/ru.lang.php | 2 +- modules/integration_search/lang/vi.lang.php | 2 +- .../integration_search/lang/zh-CN.lang.php | 86 +- .../integration_search/lang/zh-TW.lang.php | 2 +- .../integration_search/skins/default/skin.xml | 108 +- .../tpl/js/integration_search_admin.js | 10 +- modules/krzip/conf/info.xml | 114 +- modules/krzip/krzip.admin.controller.php | 66 +- modules/krzip/krzip.admin.view.php | 64 +- modules/krzip/krzip.class.php | 82 +- modules/krzip/krzip.model.php | 112 +- modules/krzip/lang/en.lang.php | 44 +- modules/krzip/lang/es.lang.php | 2 +- modules/krzip/lang/fr.lang.php | 44 +- modules/krzip/lang/jp.lang.php | 44 +- modules/krzip/lang/ko.lang.php | 44 +- modules/krzip/lang/ru.lang.php | 44 +- modules/krzip/lang/vi.lang.php | 48 +- modules/krzip/lang/zh-CN.lang.php | 44 +- modules/krzip/lang/zh-TW.lang.php | 2 +- modules/layout/conf/info.xml | 66 +- modules/layout/faceoff/conf/info.xml | 255 +- modules/layout/faceoff/css/layout.css | 2 +- modules/layout/lang/en.lang.php | 236 +- modules/layout/lang/es.lang.php | 2 +- modules/layout/lang/fr.lang.php | 232 +- modules/layout/lang/jp.lang.php | 234 +- modules/layout/lang/ko.lang.php | 238 +- modules/layout/lang/ru.lang.php | 234 +- modules/layout/lang/vi.lang.php | 238 +- modules/layout/lang/zh-CN.lang.php | 2 +- modules/layout/lang/zh-TW.lang.php | 2 +- modules/layout/layout.admin.controller.php | 1048 ++--- modules/layout/layout.admin.view.php | 592 +-- modules/layout/layout.class.php | 186 +- modules/layout/layout.model.php | 1236 +++--- modules/layout/layout.view.php | 68 +- modules/layout/tpl/css/widget.css | 2 +- modules/layout/tpl/js/ui.hotkey.js | 235 +- modules/layout/tpl/js/ui.toolbar.js | 275 +- modules/member/conf/info.xml | 66 +- modules/member/lang/en.lang.php | 2 +- modules/member/lang/es.lang.php | 2 +- modules/member/lang/fr.lang.php | 2 +- modules/member/lang/jp.lang.php | 2 +- modules/member/lang/ko.lang.php | 2 +- modules/member/lang/ru.lang.php | 2 +- modules/member/lang/vi.lang.php | 2 +- modules/member/lang/zh-CN.lang.php | 2 +- modules/member/lang/zh-TW.lang.php | 2 +- modules/member/member.admin.controller.php | 2 +- modules/member/member.admin.model.php | 272 +- modules/member/member.admin.view.php | 482 +-- modules/member/member.api.php | 2 +- modules/member/member.class.php | 400 +- modules/member/member.controller.php | 3702 ++++++++--------- modules/member/member.model.php | 1432 +++---- modules/member/member.view.php | 680 +-- modules/member/skins/default/skin.xml | 146 +- modules/member/tpl/js/signup_check.js | 104 +- modules/menu/conf/info.xml | 66 +- modules/menu/lang/en.lang.php | 106 +- modules/menu/lang/es.lang.php | 2 +- modules/menu/lang/fr.lang.php | 106 +- modules/menu/lang/jp.lang.php | 106 +- modules/menu/lang/ko.lang.php | 106 +- modules/menu/lang/ru.lang.php | 106 +- modules/menu/lang/vi.lang.php | 110 +- modules/menu/lang/zh-CN.lang.php | 2 +- modules/menu/lang/zh-TW.lang.php | 2 +- modules/menu/menu.admin.controller.php | 1308 +++--- modules/menu/menu.admin.model.php | 308 +- modules/menu/menu.admin.view.php | 210 +- modules/menu/menu.class.php | 134 +- modules/message/lang/es.lang.php | 2 +- modules/message/lang/vi.lang.php | 2 +- modules/message/m.skins/default/message.css | 39 +- .../m.skins/default/system_message.html | 1 - modules/module/conf/info.xml | 66 +- modules/module/lang/en.lang.php | 198 +- modules/module/lang/es.lang.php | 2 +- modules/module/lang/fr.lang.php | 196 +- modules/module/lang/jp.lang.php | 196 +- modules/module/lang/ko.lang.php | 196 +- modules/module/lang/ru.lang.php | 198 +- modules/module/lang/vi.lang.php | 202 +- modules/module/lang/zh-CN.lang.php | 2 +- modules/module/lang/zh-TW.lang.php | 2 +- modules/module/module.admin.controller.php | 970 ++--- modules/module/module.admin.model.php | 378 +- modules/module/module.admin.view.php | 448 +- modules/module/module.class.php | 734 ++-- modules/module/module.controller.php | 1412 +++---- modules/module/module.model.php | 2564 ++++++------ modules/module/module.view.php | 322 +- modules/module/tpl/js/module_admin.js | 380 +- modules/opage/conf/info.xml | 68 +- modules/opage/lang/en.lang.php | 36 +- modules/opage/lang/es.lang.php | 34 +- modules/opage/lang/fr.lang.php | 34 +- modules/opage/lang/jp.lang.php | 34 +- modules/opage/lang/ko.lang.php | 36 +- modules/opage/lang/ru.lang.php | 34 +- modules/opage/lang/vi.lang.php | 38 +- modules/opage/lang/zh-CN.lang.php | 36 +- modules/opage/lang/zh-TW.lang.php | 2 +- modules/opage/opage.admin.controller.php | 168 +- modules/opage/opage.admin.view.php | 2 +- modules/opage/opage.class.php | 90 +- modules/opage/opage.controller.php | 210 +- modules/opage/opage.model.php | 66 +- modules/opage/opage.view.php | 328 +- modules/opage/tpl/js/opage_admin.js | 124 +- modules/page/conf/info.xml | 66 +- modules/page/lang/en.lang.php | 28 +- modules/page/lang/es.lang.php | 2 +- modules/page/lang/fr.lang.php | 28 +- modules/page/lang/jp.lang.php | 28 +- modules/page/lang/ko.lang.php | 28 +- modules/page/lang/ru.lang.php | 28 +- modules/page/lang/vi.lang.php | 32 +- modules/page/lang/zh-CN.lang.php | 28 +- modules/page/lang/zh-TW.lang.php | 2 +- modules/page/page.admin.controller.php | 438 +- modules/page/page.admin.view.php | 502 +-- modules/page/page.api.php | 2 +- modules/page/page.class.php | 84 +- modules/page/page.view.php | 108 +- modules/page/page.wap.php | 52 +- modules/page/tpl/js/page_admin.js | 220 +- modules/point/conf/info.xml | 130 +- modules/point/lang/en.lang.php | 2 +- modules/point/lang/es.lang.php | 2 +- modules/point/lang/fr.lang.php | 2 +- modules/point/lang/jp.lang.php | 136 +- modules/point/lang/ko.lang.php | 136 +- modules/point/lang/ru.lang.php | 2 +- modules/point/lang/vi.lang.php | 2 +- modules/point/lang/zh-CN.lang.php | 2 +- modules/point/lang/zh-TW.lang.php | 2 +- modules/point/point.admin.controller.php | 622 +-- modules/point/point.admin.view.php | 202 +- modules/point/point.class.php | 394 +- modules/point/point.controller.php | 1322 +++--- modules/point/point.model.php | 244 +- modules/point/point.view.php | 124 +- modules/point/tpl/js/point_admin.js | 140 +- modules/poll/conf/info.xml | 66 +- modules/poll/lang/en.lang.php | 76 +- modules/poll/lang/es.lang.php | 2 +- modules/poll/lang/fr.lang.php | 76 +- modules/poll/lang/jp.lang.php | 76 +- modules/poll/lang/ko.lang.php | 76 +- modules/poll/lang/ru.lang.php | 76 +- modules/poll/lang/vi.lang.php | 80 +- modules/poll/lang/zh-CN.lang.php | 76 +- modules/poll/lang/zh-TW.lang.php | 2 +- modules/poll/poll.admin.controller.php | 222 +- modules/poll/poll.admin.model.php | 100 +- modules/poll/poll.admin.view.php | 254 +- modules/poll/poll.class.php | 166 +- modules/poll/poll.controller.php | 632 +-- modules/poll/poll.model.php | 284 +- modules/poll/skins/default/skin.xml | 74 +- modules/poll/skins/simple/skin.xml | 68 +- modules/poll/tpl/js/poll_admin.js | 112 +- modules/rss/conf/info.xml | 66 +- modules/rss/lang/en.lang.php | 2 +- modules/rss/lang/es.lang.php | 2 +- modules/rss/lang/fr.lang.php | 50 +- modules/rss/lang/jp.lang.php | 72 +- modules/rss/lang/ko.lang.php | 72 +- modules/rss/lang/ru.lang.php | 72 +- modules/rss/lang/vi.lang.php | 2 +- modules/rss/lang/zh-CN.lang.php | 72 +- modules/rss/lang/zh-TW.lang.php | 2 +- modules/rss/rss.admin.controller.php | 328 +- modules/rss/rss.class.php | 160 +- modules/rss/rss.controller.php | 116 +- modules/rss/rss.model.php | 88 +- modules/rss/rss.view.php | 2 +- modules/session/conf/info.xml | 88 +- modules/session/lang/en.lang.php | 26 +- modules/session/lang/fr.lang.php | 26 +- modules/session/lang/jp.lang.php | 26 +- modules/session/lang/ko.lang.php | 26 +- modules/session/lang/vi.lang.php | 30 +- modules/session/lang/zh-CN.lang.php | 26 +- modules/session/lang/zh-TW.lang.php | 2 +- modules/session/session.admin.controller.php | 52 +- modules/session/session.admin.view.php | 52 +- modules/session/session.class.php | 166 +- modules/session/session.controller.php | 140 +- modules/session/session.model.php | 186 +- modules/spamfilter/conf/info.xml | 66 +- modules/spamfilter/lang/en.lang.php | 66 +- modules/spamfilter/lang/es.lang.php | 2 +- modules/spamfilter/lang/fr.lang.php | 66 +- modules/spamfilter/lang/jp.lang.php | 66 +- modules/spamfilter/lang/ko.lang.php | 66 +- modules/spamfilter/lang/ru.lang.php | 66 +- modules/spamfilter/lang/vi.lang.php | 70 +- modules/spamfilter/lang/zh-CN.lang.php | 66 +- modules/spamfilter/lang/zh-TW.lang.php | 2 +- .../spamfilter.admin.controller.php | 198 +- modules/spamfilter/spamfilter.admin.view.php | 118 +- modules/spamfilter/spamfilter.class.php | 214 +- modules/spamfilter/spamfilter.controller.php | 346 +- modules/spamfilter/spamfilter.model.php | 308 +- modules/syndication/conf/info.xml | 30 +- .../syndication.admin.controller.php | 266 +- .../syndication/syndication.admin.view.php | 100 +- modules/syndication/syndication.class.php | 148 +- .../syndication/syndication.controller.php | 254 +- modules/syndication/syndication.model.php | 726 ++-- modules/tag/conf/info.xml | 66 +- modules/tag/tag.admin.controller.php | 34 +- modules/tag/tag.class.php | 192 +- modules/tag/tag.controller.php | 184 +- modules/tag/tag.model.php | 174 +- modules/trackback/conf/info.xml | 66 +- modules/trackback/lang/en.lang.php | 56 +- modules/trackback/lang/es.lang.php | 2 +- modules/trackback/lang/fr.lang.php | 56 +- modules/trackback/lang/jp.lang.php | 56 +- modules/trackback/lang/ko.lang.php | 56 +- modules/trackback/lang/ru.lang.php | 48 +- modules/trackback/lang/vi.lang.php | 62 +- modules/trackback/lang/zh-CN.lang.php | 56 +- modules/trackback/lang/zh-TW.lang.php | 2 +- .../trackback/trackback.admin.controller.php | 196 +- modules/trackback/trackback.admin.model.php | 136 +- modules/trackback/trackback.admin.view.php | 100 +- modules/trackback/trackback.class.php | 174 +- modules/trackback/trackback.controller.php | 658 +-- modules/trackback/trackback.model.php | 302 +- modules/trackback/trackback.view.php | 140 +- modules/widget/conf/info.xml | 66 +- modules/widget/lang/en.lang.php | 136 +- modules/widget/lang/es.lang.php | 2 +- modules/widget/lang/fr.lang.php | 136 +- modules/widget/lang/jp.lang.php | 136 +- modules/widget/lang/ko.lang.php | 136 +- modules/widget/lang/ru.lang.php | 92 +- modules/widget/lang/vi.lang.php | 140 +- modules/widget/lang/zh-CN.lang.php | 2 +- modules/widget/lang/zh-TW.lang.php | 2 +- modules/widget/tpl/js/widget.js | 2706 ++++++------ modules/widget/tpl/js/widget_admin.js | 940 ++--- modules/widget/widget.admin.view.php | 112 +- modules/widget/widget.class.php | 128 +- modules/widget/widget.controller.php | 1432 +++---- modules/widget/widget.model.php | 806 ++-- modules/widget/widget.view.php | 306 +- widgets/content/conf/info.xml | 18 +- widgets/content/content.class.php | 1620 ++++---- widgets/content/skins/default/skin.xml | 36 +- widgets/counter_status/conf/info.xml | 120 +- .../counter_status/counter_status.class.php | 80 +- widgets/counter_status/skins/default/skin.xml | 108 +- widgets/language_select/conf/info.xml | 66 +- .../language_select/language_select.class.php | 54 +- .../language_select/skins/default/skin.xml | 108 +- widgets/login_info/conf/info.xml | 66 +- widgets/login_info/login_info.class.php | 92 +- widgets/login_info/skins/xe_official/skin.xml | 156 +- widgets/mcontent/conf/info.xml | 18 +- widgets/mcontent/mcontent.class.php | 2 +- widgets/mcontent/skins/default/skin.xml | 6 +- widgetstyles/simple/skin.xml | 14 +- 603 files changed, 67379 insertions(+), 67522 deletions(-) diff --git a/addons/autolink/autolink.addon.php b/addons/autolink/autolink.addon.php index df1eff0f9..a99116cf9 100644 --- a/addons/autolink/autolink.addon.php +++ b/addons/autolink/autolink.addon.php @@ -1,12 +1,12 @@ - + diff --git a/addons/autolink/autolink.js b/addons/autolink/autolink.js index a6744c2bf..5b03d4bd7 100644 --- a/addons/autolink/autolink.js +++ b/addons/autolink/autolink.js @@ -1,80 +1,80 @@ -/** - * @file autolink.js - * @brief javascript code for autolink addon - * @author taggon (gonom9@gmail.com) - */ -(function($){ - var protocol_re = '(https?|ftp|news|telnet|irc|mms)://'; - var domain_re = '(?:[\\w\\-]+\\.)+(?:[a-z]+)'; - 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 port_re = '(?::([0-9]+))?'; - var user_re = '(?:/~[\\w-]+)?'; - var path_re = '((?:/[\\w!"$-/:-@]+)*)'; - var hash_re = '(?:#([\\w!-@]+))?'; - - var url_regex = new RegExp('('+protocol_re+'('+domain_re+'|'+ip_re+'|localhost'+')'+port_re+user_re+path_re+hash_re+')', 'ig'); - - var AutoLink = xe.createPlugin("autolink", { - targets : [], - init : function() { - this.targets = []; - }, - API_ONREADY : function() { - var thisPlugin = this; - - // extract target text nodes - this.extractTargets($('.xe_content')); - - $(this.targets).each(function(){ - thisPlugin.cast('AUTOLINK', [this]); - }); - }, - API_AUTOLINK : function(oSender, params) { - var textNode = params[0]; - if(!$(textNode).parent().length || $(textNode).parent().get(0).nodeName.toLowerCase() == 'a') return; - var content = textNode.nodeValue; - var dummy = $(''); - - content = content.replace(//g, '>'); - content = content.replace(url_regex, '$1'); - - $(textNode).before(dummy); - $(textNode).replaceWith(content); - params[0] = dummy.next('a'); - dummy.remove(); - }, - extractTargets : function(obj) { - var thisPlugin = this; - var wrap = $('.xe_content', obj); - if(wrap.length) { - this.extractTargets(wrap); - return; - } - - $(obj) - .contents() - .each(function(){ - var node_name = this.nodeName.toLowerCase(); - if($.inArray(node_name, ['a', 'pre', 'xml', 'textarea', 'input', 'select', 'option', 'code', 'script', 'style', 'iframe', 'button', 'img', 'embed', 'object', 'ins']) != -1) return; - - // FIX ME : When this meanless code wasn't executed, url_regex do not run correctly. why? - url_regex.exec(''); - - if(this.nodeType == 3) { // text node - var content = this.nodeValue; - - if(content.length < 5) return; - - if(!/(http|https|ftp|news|telnet|irc|mms):\/\//i.test(content)) return; - - thisPlugin.targets.push(this); - } else { - thisPlugin.extractTargets(this); - } - }); - } - }); - - xe.registerPlugin(new AutoLink()); +/** + * @file autolink.js + * @brief javascript code for autolink addon + * @author NHN (developers@xpressengine.com) + */ +(function($){ + var protocol_re = '(https?|ftp|news|telnet|irc|mms)://'; + var domain_re = '(?:[\\w\\-]+\\.)+(?:[a-z]+)'; + 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 port_re = '(?::([0-9]+))?'; + var user_re = '(?:/~[\\w-]+)?'; + var path_re = '((?:/[\\w!"$-/:-@]+)*)'; + var hash_re = '(?:#([\\w!-@]+))?'; + + var url_regex = new RegExp('('+protocol_re+'('+domain_re+'|'+ip_re+'|localhost'+')'+port_re+user_re+path_re+hash_re+')', 'ig'); + + var AutoLink = xe.createPlugin("autolink", { + targets : [], + init : function() { + this.targets = []; + }, + API_ONREADY : function() { + var thisPlugin = this; + + // extract target text nodes + this.extractTargets($('.xe_content')); + + $(this.targets).each(function(){ + thisPlugin.cast('AUTOLINK', [this]); + }); + }, + API_AUTOLINK : function(oSender, params) { + var textNode = params[0]; + if(!$(textNode).parent().length || $(textNode).parent().get(0).nodeName.toLowerCase() == 'a') return; + var content = textNode.nodeValue; + var dummy = $(''); + + content = content.replace(//g, '>'); + content = content.replace(url_regex, '$1'); + + $(textNode).before(dummy); + $(textNode).replaceWith(content); + params[0] = dummy.next('a'); + dummy.remove(); + }, + extractTargets : function(obj) { + var thisPlugin = this; + var wrap = $('.xe_content', obj); + if(wrap.length) { + this.extractTargets(wrap); + return; + } + + $(obj) + .contents() + .each(function(){ + var node_name = this.nodeName.toLowerCase(); + if($.inArray(node_name, ['a', 'pre', 'xml', 'textarea', 'input', 'select', 'option', 'code', 'script', 'style', 'iframe', 'button', 'img', 'embed', 'object', 'ins']) != -1) return; + + // FIX ME : When this meanless code wasn't executed, url_regex do not run correctly. why? + url_regex.exec(''); + + if(this.nodeType == 3) { // text node + var content = this.nodeValue; + + if(content.length < 5) return; + + if(!/(http|https|ftp|news|telnet|irc|mms):\/\//i.test(content)) return; + + thisPlugin.targets.push(this); + } else { + thisPlugin.extractTargets(this); + } + }); + } + }); + + xe.registerPlugin(new AutoLink()); })(jQuery); \ No newline at end of file diff --git a/addons/autolink/conf/info.xml b/addons/autolink/conf/info.xml index 069e76043..017183672 100644 --- a/addons/autolink/conf/info.xml +++ b/addons/autolink/conf/info.xml @@ -1,53 +1,53 @@ - - - 자동 링크 애드온 - 自動リンクアドオン - Auto Link - Auto Link - 自动链接插件 - auto vínculo addon - авто ссылка аддон - Auto-Link Addon - 自動連結 - - 글과 댓글의 내용 중 URL 문자열에 링크를 걸어주는 애드온입니다. - - - 書き込み本文とコメントに登録された内容の中、httpで始まる一般文字列に自動にリンクを貼り付け、そのリンクにマウスオーバすると、別ウィンドウ、または同一ウィンドウに開くメニュが現れるアドオンです。 - - - This addon makes a link to a string that starts with http. - - - Addon này sẽ tự động tạo ra một đường Link khi gặp chuỗi kí tự 'http' có trong bài viết. - - - 主题及评论中以http开始的字符串,自动转换为链接。并且鼠标移到链接上方时,将出现可选(新窗/本页面)提示框。 - - - Los comentarios que comienzan con http naeyongjung tema común de la cadena para vincular automáticamente a colgar el puntero del ratón sobre cada uno de los vínculos y saechang Ciudad y aparecen en el menú de add-on de decoración. - - - Комментарии, которые начинаются с http naeyongjung темой общей строки автоматически ссылку повесить мышь над каждой ссылке и saechang Сити и появляться на меню добавить-на украшения. - - - Kommentare beginnen mit http naeyongjung Thema der gemeinsamen String automatisch Link zu hängen Sie mit der Maus über die einzelnen Links und saechang Stadt und auf dem Menü des Add-On Dekoration. - - - 是種可將主題和評論內容中的URL網址字串自動轉換成連結的附加元件。 - - 0.1 - 2008-04-22 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 자동 링크 애드온 + 自動リンクアドオン + Auto Link + Auto Link + 自动链接插件 + auto vínculo addon + авто ссылка аддон + Auto-Link Addon + 自動連結 + + 글과 댓글의 내용 중 URL 문자열에 링크를 걸어주는 애드온입니다. + + + 書き込み本文とコメントに登録された内容の中、httpで始まる一般文字列に自動にリンクを貼り付け、そのリンクにマウスオーバすると、別ウィンドウ、または同一ウィンドウに開くメニュが現れるアドオンです。 + + + This addon makes a link to a string that starts with http. + + + Addon này sẽ tự động tạo ra một đường Link khi gặp chuỗi kí tự 'http' có trong bài viết. + + + 主题及评论中以http开始的字符串,自动转换为链接。并且鼠标移到链接上方时,将出现可选(新窗/本页面)提示框。 + + + Los comentarios que comienzan con http naeyongjung tema común de la cadena para vincular automáticamente a colgar el puntero del ratón sobre cada uno de los vínculos y saechang Ciudad y aparecen en el menú de add-on de decoración. + + + Комментарии, которые начинаются с http naeyongjung темой общей строки автоматически ссылку повесить мышь над каждой ссылке и saechang Сити и появляться на меню добавить-на украшения. + + + Kommentare beginnen mit http naeyongjung Thema der gemeinsamen String automatisch Link zu hängen Sie mit der Maus über die einzelnen Links und saechang Stadt und auf dem Menü des Add-On Dekoration. + + + 是種可將主題和評論內容中的URL網址字串自動轉換成連結的附加元件。 + + 0.1 + 2008-04-22 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/blogapi/blogapi.addon.php b/addons/blogapi/blogapi.addon.php index 11c4fc7b2..7b294e8e3 100644 --- a/addons/blogapi/blogapi.addon.php +++ b/addons/blogapi/blogapi.addon.php @@ -1,468 +1,468 @@ -domain, '', 'mid',$site_module_info->mid, 'act','api'); - - // 헤더에 rsd태그 삽입 - Context::addHtmlHeader(" ".''); - } - - // act가 api가 아니면 그냥 리턴~ - if($_REQUEST['act']!='api') return; - - // 관련 func 파일 읽음 - require_once('./addons/blogapi/blogapi.func.php'); - - // xmlprc 파싱 - // 요청된 xmlrpc를 파싱 - $oXmlParser = new XmlParser(); - $xmlDoc = $oXmlParser->parse(); - - $method_name = $xmlDoc->methodcall->methodname->body; - $params = $xmlDoc->methodcall->params->param; - if($params && !is_array($params)) $params = array($params); - - // 일부 methodname에 대한 호환 - if(in_array($method_name, array('metaWeblog.deletePost', 'metaWeblog.getUsersBlogs', 'metaWeblog.getUserInfo'))) { - $method_name = str_replace('metaWeblog.', 'blogger.', $method_name); - } - - // blogger.deletePost일 경우 첫번째 인자 값 삭제 - if($method_name == 'blogger.deletePost') array_shift($params); - - // user_id, password를 구해서 로그인 시도 - $user_id = trim($params[1]->value->string->body); - $password = trim($params[2]->value->string->body); - - // 모듈 실행전이라면 인증을 처리한다. - if($called_position == 'before_module_init') { - - // member controller을 이용해서 로그인 시도 - if($user_id && $password) { - $oMemberController = &getController('member'); - $output = $oMemberController->doLogin($user_id, $password); - // 로그인 실패시 에러 메시지 출력 - if(!$output->toBool()) { - $content = getXmlRpcFailure(1, $output->getMessage()); - printContent($content); - } - } else { - $content = getXmlRpcFailure(1, 'not logged'); - printContent($content); - } - } - - // 모듈에서 무언가 작업을 하기 전에 blogapi tool의 요청에 대한 처리를 하고 강제 종료한다. - if($called_position == 'before_module_proc') { - - // 글쓰기 권한 체크 (권한명의 경우 약속이 필요할듯..) - if(!$this->grant->write_document) { - printContent( getXmlRpcFailure(1, 'no permission') ); - } - - // 카테고리의 정보를 구해옴 - $oDocumentModel = &getModel('document'); - $category_list = $oDocumentModel->getCategoryList($this->module_srl); - - // 임시 파일 저장 장소 지정 - $tmp_uploaded_path = sprintf('./files/cache/blogapi/%s/%s/', $this->mid, $user_id); - $uploaded_target_path = sprintf('/files/cache/blogapi/%s/%s/', $this->mid, $user_id); - - switch($method_name) { - // 블로그 정보 - case 'blogger.getUsersBlogs' : - $obj->url = getFullSiteUrl(''); - $obj->blogid = $this->mid; - $obj->blogName = $this->module_info->browser_title; - $blog_list = array($obj); - - $content = getXmlRpcResponse($blog_list); - printContent($content); - break; - - // 카테고리 목록 return - case 'metaWeblog.getCategories' : - $category_obj_list = array(); - if($category_list) { - foreach($category_list as $category_srl => $category_info) { - unset($obj); - $obj->description = $category_info->title; - //$obj->htmlUrl = Context::getRequestUri().$this->mid.'/1'; - //$obj->rssUrl= Context::getRequestUri().'rss/'.$this->mid.'/1'; - $obj->title = $category_info->title; - $obj->categoryid = $category_srl; - $category_obj_list[] = $obj; - } - } - - $content = getXmlRpcResponse($category_obj_list); - printContent($content); - break; - - // 파일 업로드 - case 'metaWeblog.newMediaObject' : - // 파일 업로드 권한 체크 - $oFileModel = &getModel('file'); - $file_module_config = $oFileModel->getFileModuleConfig($this->module_srl); - if(is_array($file_module_config->download_grant) && count($file_module_config->download_grant)>0) { - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y') { - $is_permitted = false; - for($i=0;$idownload_grant);$i++) { - $group_srl = $file_module_config->download_grant[$i]; - if($logged_info->group_list[$group_srl]) { - $is_permitted = true; - break; - } - } - if(!$is_permitted) printContent( getXmlRpcFailure(1, 'no permission') ); - } - } - - $fileinfo = $params[3]->value->struct->member; - foreach($fileinfo as $key => $val) { - $nodename = $val->name->body; - if($nodename == 'bits') $filedata = base64_decode($val->value->base64->body); - elseif($nodename == 'name') $filename = $val->value->string->body; - } - - $tmp_arr = explode('/',$filename); - $filename = array_pop($tmp_arr); - - if(!is_dir($tmp_uploaded_path)) FileHandler::makeDir($tmp_uploaded_path); - - $target_filename = sprintf('%s%s', $tmp_uploaded_path, $filename); - FileHandler::writeFile($target_filename, $filedata); - $obj->url = Context::getRequestUri().$target_filename; - - $content = getXmlRpcResponse($obj); - printContent($content); - break; - - // 글 가져오기 - case 'metaWeblog.getPost' : - $document_srl = $params[0]->value->string->body; - if(!$document_srl) { - printContent( getXmlRpcFailure(1, 'no permission') ); - } else { - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); - if(!$oDocument->isExists() || !$oDocument->isGranted()) { - printContent( getXmlRpcFailure(1, 'no permission') ); - } else { - // 카테고리를 사용하는지 확인후 사용시 카테고리 목록을 구해와서 Context에 세팅 - $category = ""; - if($oDocument->get('category_srl')) { - $oDocumentModel = &getModel('document'); - $category_list = $oDocumentModel->getCategoryList($oDocument->get('module_srl')); - if($category_list[$oDocument->get('category_srl')]) { - $category = $category_list[$oDocument->get('category_srl')]->title; - } - } - - $content = sprintf( - ''. - ''. - ''. - ''. - ''. - ''. - 'categories'. - 'dateCreated%s'. - 'description'. - 'link%s'. - 'postid%s'. - 'title'. - 'publish1'. - ''. - ''. - ''. - ''. - '', - $category, - date("Ymd", $oDocument->getRegdateTime()).'T'.date("H:i:s", $oDocument->getRegdateTime()), - $oDocument->getContent(false, false, true,false), - getFullUrl('','document_srl', $oDocument->document_srl), - $oDocument->document_srl, - $oDocument->getTitleText() - ); - printContent($content); - } - } - break; - - // 글작성 - case 'metaWeblog.newPost' : - unset($obj); - $info = $params[3]; - // 글, 제목, 카테고리 정보 구함 - for($i=0;$ivalue->struct->member);$i++) { - $val = $info->value->struct->member[$i]; - switch($val->name->body) { - case 'title' : - $obj->title = $val->value->string->body; - break; - case 'description' : - $obj->content = $val->value->string->body; - break; - case 'categories' : - $categories = $val->value->array->data->value; - if(!is_array($categories)) $categories = array($categories); - $category = $categories[0]->string->body; - if($category && $category_list) { - foreach($category_list as $category_srl => $category_info) { - if($category_info->title == $category) $obj->category_srl = $category_srl; - } - } - break; - case 'tagwords' : - $tags = $val->value->array->data->value; - if(!is_array($tags)) $tags = array($tags); - for($j=0;$jstring->body; - } - if(count($tag_list)) $obj->tags = implode(',',$tag_list); - break; - } - - } - - // 문서 번호 설정 - $document_srl = getNextSequence(); - $obj->document_srl = $document_srl; - $obj->module_srl = $this->module_srl; - - // 첨부파일 정리 - if(is_dir($tmp_uploaded_path)) { - $file_list = FileHandler::readDir($tmp_uploaded_path); - $file_count = count($file_list); - if($file_count) { - $oFileController = &getController('file'); - for($i=0;$i<$file_count;$i++) { - $file_info['tmp_name'] = sprintf('%s%s', $tmp_uploaded_path, $file_list[$i]); - $file_info['name'] = $file_list[$i]; - $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true); - } - $obj->uploaded_count = $file_count; - } - } - - $obj->content = str_replace($uploaded_target_path,sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl,3), $filename), $obj->content); - - $oDocumentController = &getController('document'); - $obj->allow_comment = 'Y'; - $obj->allow_trackback = 'Y'; - $output = $oDocumentController->insertDocument($obj); - - if(!$output->toBool()) { - $content = getXmlRpcFailure(1, $output->getMessage()); - } else { - $content = getXmlRpcResponse(strval($document_srl)); - } - FileHandler::removeDir($tmp_uploaded_path); - - printContent($content); - break; - - // 글 수정 - case 'metaWeblog.editPost' : - $tmp_val = $params[0]->value->string->body; - if(!$tmp_val) $tmp_val = $params[0]->value->i4->body; - if(!$tmp_val) { - $content = getXmlRpcFailure(1, 'no permission'); - break; - } - $tmp_arr = explode('/', $tmp_val); - $document_srl = array_pop($tmp_arr); - if(!$document_srl) { - $content = getXmlRpcFailure(1, 'no permission'); - break; - } - - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); - - // 글 수정 권한 체크 - if(!$oDocument->isGranted()) { - $content = getXmlRpcFailure(1, 'no permission'); - break; - } - - $obj = $oDocument->getObjectVars(); - - $info = $params[3]; - - // 글, 제목, 카테고리 정보 구함 - for($i=0;$ivalue->struct->member);$i++) { - $val = $info->value->struct->member[$i]; - switch($val->name->body) { - case 'title' : - $obj->title = $val->value->string->body; - break; - case 'description' : - $obj->content = $val->value->string->body; - break; - case 'categories' : - $categories = $val->value->array->data->value; - if(!is_array($categories)) $categories = array($categories); - $category = $categories[0]->string->body; - if($category && $category_list) { - foreach($category_list as $category_srl => $category_info) { - if($category_info->title == $category) $obj->category_srl = $category_srl; - } - } - break; - case 'tagwords' : - $tags = $val->value->array->data->value; - if(!is_array($tags)) $tags = array($tags); - for($j=0;$jstring->body; - } - if(count($tag_list)) $obj->tags = implode(',',$tag_list); - break; - } - - } - - // 문서 번호 설정 - $obj->document_srl = $document_srl; - $obj->module_srl = $this->module_srl; - - // 첨부파일 정리 - if(is_dir($tmp_uploaded_path)) { - $file_list = FileHandler::readDir($tmp_uploaded_path); - $file_count = count($file_list); - if($file_count) { - $oFileController = &getController('file'); - for($i=0;$i<$file_count;$i++) { - $file_info['tmp_name'] = sprintf('%s%s', $tmp_uploaded_path, $file_list[$i]); - $file_info['name'] = $file_list[$i]; - - $moved_filename = sprintf('./files/attach/images/%s/%s/%s', $this->module_srl, $document_srl, $file_info['name']); - if(file_exists($moved_filename)) continue; - - $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true); - } - $obj->uploaded_count += $file_count; - } - } - - $obj->content = str_replace($uploaded_target_path,sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl,3), $filename), $obj->content); - - $oDocumentController = &getController('document'); - $output = $oDocumentController->updateDocument($oDocument,$obj); - - if(!$output->toBool()) { - $content = getXmlRpcFailure(1, $output->getMessage()); - } else { - $content = getXmlRpcResponse(true); - FileHandler::removeDir($tmp_uploaded_path); - } - - printContent($content); - break; - - // 글삭제 - case 'blogger.deletePost' : - $tmp_val = $params[0]->value->string->body; - $tmp_arr = explode('/', $tmp_val); - $document_srl = array_pop($tmp_arr); - - // 글 받아오기 - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); - - // 글 존재 - if(!$oDocument->isExists()) { - $content = getXmlRpcFailure(1, 'not exists'); - - // 글 삭제 권한 체크 - } elseif(!$oDocument->isGranted()) { - $content = getXmlRpcFailure(1, 'no permission'); - break; - - // 삭제 - } else { - $oDocumentController = &getController('document'); - $output = $oDocumentController->deleteDocument($document_srl); - if(!$output->toBool()) $content = getXmlRpcFailure(1, $output->getMessage()); - else $content = getXmlRpcResponse(true); - } - - printContent($content); - break; - - // 최신글 받기 - case 'metaWeblog.getRecentPosts' : - // 목록을 구하기 위한 옵션 - $args->module_srl = $this->module_srl; ///< 현재 모듈의 module_srl - $args->page = 1; - $args->list_count = 20; - $args->sort_index = 'list_order'; ///< 소팅 값 - $logged_info = Context::get('logged_info'); - $args->search_target = 'member_srl'; - $args->search_keyword = $logged_info->member_srl; - $output = $oDocumentModel->getDocumentList($args); - if(!$output->toBool() || !$output->data) { - $content = getXmlRpcFailure(1, 'post not founded'); - printContent($content); - } else { - $oEditorController = &getController('editor'); - - $posts = array(); - foreach($output->data as $key => $oDocument) { - $post = null; - $post->categories = array(); - $post->dateCreated = date("Ymd", $oDocument->getRegdateTime()).'T'.date("H:i:s", $oDocument->getRegdateTime()); - $post->description = htmlspecialchars($oEditorController->transComponent($oDocument->getContent(false,false,true,false))); - $post->link = $post->permaLink = getFullUrl('','document_srl',$oDocument->document_srl); - $post->postid = $oDocument->document_srl; - $post->title = htmlspecialchars($oDocument->get('title')); - $post->publish = 1; - $post->userid = $oDocument->get('user_id'); - $post->mt_allow_pings = 0; - $post->mt_allow_comments = $oDocument->allowComment()=='Y'?1:0; - $posts[] = $post; - } - $content = getXmlRpcResponse($posts); - printContent($content); - } - break; - - // 아무런 요청이 없을 경우 RSD 출력 - default : - - $homepagelink = getUrl('','mid',$this->mid); - $site_module_info = Context::get('site_module_info'); - $api_url = getFullSiteUrl($site_module_info->domain, '', 'mid',$site_module_info->mid, 'act','api'); - $content = << - - - XpressEngine - http://www.xpressengine.com/ - {$homepagelink} - - - - - -RSDContent; - printContent($content); - break; - } - } -?> +domain, '', 'mid',$site_module_info->mid, 'act','api'); + + // 헤더에 rsd태그 삽입 + Context::addHtmlHeader(" ".''); + } + + // act가 api가 아니면 그냥 리턴~ + if($_REQUEST['act']!='api') return; + + // 관련 func 파일 읽음 + require_once('./addons/blogapi/blogapi.func.php'); + + // xmlprc 파싱 + // 요청된 xmlrpc를 파싱 + $oXmlParser = new XmlParser(); + $xmlDoc = $oXmlParser->parse(); + + $method_name = $xmlDoc->methodcall->methodname->body; + $params = $xmlDoc->methodcall->params->param; + if($params && !is_array($params)) $params = array($params); + + // 일부 methodname에 대한 호환 + if(in_array($method_name, array('metaWeblog.deletePost', 'metaWeblog.getUsersBlogs', 'metaWeblog.getUserInfo'))) { + $method_name = str_replace('metaWeblog.', 'blogger.', $method_name); + } + + // blogger.deletePost일 경우 첫번째 인자 값 삭제 + if($method_name == 'blogger.deletePost') array_shift($params); + + // user_id, password를 구해서 로그인 시도 + $user_id = trim($params[1]->value->string->body); + $password = trim($params[2]->value->string->body); + + // 모듈 실행전이라면 인증을 처리한다. + if($called_position == 'before_module_init') { + + // member controller을 이용해서 로그인 시도 + if($user_id && $password) { + $oMemberController = &getController('member'); + $output = $oMemberController->doLogin($user_id, $password); + // 로그인 실패시 에러 메시지 출력 + if(!$output->toBool()) { + $content = getXmlRpcFailure(1, $output->getMessage()); + printContent($content); + } + } else { + $content = getXmlRpcFailure(1, 'not logged'); + printContent($content); + } + } + + // 모듈에서 무언가 작업을 하기 전에 blogapi tool의 요청에 대한 처리를 하고 강제 종료한다. + if($called_position == 'before_module_proc') { + + // 글쓰기 권한 체크 (권한명의 경우 약속이 필요할듯..) + if(!$this->grant->write_document) { + printContent( getXmlRpcFailure(1, 'no permission') ); + } + + // 카테고리의 정보를 구해옴 + $oDocumentModel = &getModel('document'); + $category_list = $oDocumentModel->getCategoryList($this->module_srl); + + // 임시 파일 저장 장소 지정 + $tmp_uploaded_path = sprintf('./files/cache/blogapi/%s/%s/', $this->mid, $user_id); + $uploaded_target_path = sprintf('/files/cache/blogapi/%s/%s/', $this->mid, $user_id); + + switch($method_name) { + // 블로그 정보 + case 'blogger.getUsersBlogs' : + $obj->url = getFullSiteUrl(''); + $obj->blogid = $this->mid; + $obj->blogName = $this->module_info->browser_title; + $blog_list = array($obj); + + $content = getXmlRpcResponse($blog_list); + printContent($content); + break; + + // 카테고리 목록 return + case 'metaWeblog.getCategories' : + $category_obj_list = array(); + if($category_list) { + foreach($category_list as $category_srl => $category_info) { + unset($obj); + $obj->description = $category_info->title; + //$obj->htmlUrl = Context::getRequestUri().$this->mid.'/1'; + //$obj->rssUrl= Context::getRequestUri().'rss/'.$this->mid.'/1'; + $obj->title = $category_info->title; + $obj->categoryid = $category_srl; + $category_obj_list[] = $obj; + } + } + + $content = getXmlRpcResponse($category_obj_list); + printContent($content); + break; + + // 파일 업로드 + case 'metaWeblog.newMediaObject' : + // 파일 업로드 권한 체크 + $oFileModel = &getModel('file'); + $file_module_config = $oFileModel->getFileModuleConfig($this->module_srl); + if(is_array($file_module_config->download_grant) && count($file_module_config->download_grant)>0) { + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y') { + $is_permitted = false; + for($i=0;$idownload_grant);$i++) { + $group_srl = $file_module_config->download_grant[$i]; + if($logged_info->group_list[$group_srl]) { + $is_permitted = true; + break; + } + } + if(!$is_permitted) printContent( getXmlRpcFailure(1, 'no permission') ); + } + } + + $fileinfo = $params[3]->value->struct->member; + foreach($fileinfo as $key => $val) { + $nodename = $val->name->body; + if($nodename == 'bits') $filedata = base64_decode($val->value->base64->body); + elseif($nodename == 'name') $filename = $val->value->string->body; + } + + $tmp_arr = explode('/',$filename); + $filename = array_pop($tmp_arr); + + if(!is_dir($tmp_uploaded_path)) FileHandler::makeDir($tmp_uploaded_path); + + $target_filename = sprintf('%s%s', $tmp_uploaded_path, $filename); + FileHandler::writeFile($target_filename, $filedata); + $obj->url = Context::getRequestUri().$target_filename; + + $content = getXmlRpcResponse($obj); + printContent($content); + break; + + // 글 가져오기 + case 'metaWeblog.getPost' : + $document_srl = $params[0]->value->string->body; + if(!$document_srl) { + printContent( getXmlRpcFailure(1, 'no permission') ); + } else { + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + if(!$oDocument->isExists() || !$oDocument->isGranted()) { + printContent( getXmlRpcFailure(1, 'no permission') ); + } else { + // 카테고리를 사용하는지 확인후 사용시 카테고리 목록을 구해와서 Context에 세팅 + $category = ""; + if($oDocument->get('category_srl')) { + $oDocumentModel = &getModel('document'); + $category_list = $oDocumentModel->getCategoryList($oDocument->get('module_srl')); + if($category_list[$oDocument->get('category_srl')]) { + $category = $category_list[$oDocument->get('category_srl')]->title; + } + } + + $content = sprintf( + ''. + ''. + ''. + ''. + ''. + ''. + 'categories'. + 'dateCreated%s'. + 'description'. + 'link%s'. + 'postid%s'. + 'title'. + 'publish1'. + ''. + ''. + ''. + ''. + '', + $category, + date("Ymd", $oDocument->getRegdateTime()).'T'.date("H:i:s", $oDocument->getRegdateTime()), + $oDocument->getContent(false, false, true,false), + getFullUrl('','document_srl', $oDocument->document_srl), + $oDocument->document_srl, + $oDocument->getTitleText() + ); + printContent($content); + } + } + break; + + // 글작성 + case 'metaWeblog.newPost' : + unset($obj); + $info = $params[3]; + // 글, 제목, 카테고리 정보 구함 + for($i=0;$ivalue->struct->member);$i++) { + $val = $info->value->struct->member[$i]; + switch($val->name->body) { + case 'title' : + $obj->title = $val->value->string->body; + break; + case 'description' : + $obj->content = $val->value->string->body; + break; + case 'categories' : + $categories = $val->value->array->data->value; + if(!is_array($categories)) $categories = array($categories); + $category = $categories[0]->string->body; + if($category && $category_list) { + foreach($category_list as $category_srl => $category_info) { + if($category_info->title == $category) $obj->category_srl = $category_srl; + } + } + break; + case 'tagwords' : + $tags = $val->value->array->data->value; + if(!is_array($tags)) $tags = array($tags); + for($j=0;$jstring->body; + } + if(count($tag_list)) $obj->tags = implode(',',$tag_list); + break; + } + + } + + // 문서 번호 설정 + $document_srl = getNextSequence(); + $obj->document_srl = $document_srl; + $obj->module_srl = $this->module_srl; + + // 첨부파일 정리 + if(is_dir($tmp_uploaded_path)) { + $file_list = FileHandler::readDir($tmp_uploaded_path); + $file_count = count($file_list); + if($file_count) { + $oFileController = &getController('file'); + for($i=0;$i<$file_count;$i++) { + $file_info['tmp_name'] = sprintf('%s%s', $tmp_uploaded_path, $file_list[$i]); + $file_info['name'] = $file_list[$i]; + $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true); + } + $obj->uploaded_count = $file_count; + } + } + + $obj->content = str_replace($uploaded_target_path,sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl,3), $filename), $obj->content); + + $oDocumentController = &getController('document'); + $obj->allow_comment = 'Y'; + $obj->allow_trackback = 'Y'; + $output = $oDocumentController->insertDocument($obj); + + if(!$output->toBool()) { + $content = getXmlRpcFailure(1, $output->getMessage()); + } else { + $content = getXmlRpcResponse(strval($document_srl)); + } + FileHandler::removeDir($tmp_uploaded_path); + + printContent($content); + break; + + // 글 수정 + case 'metaWeblog.editPost' : + $tmp_val = $params[0]->value->string->body; + if(!$tmp_val) $tmp_val = $params[0]->value->i4->body; + if(!$tmp_val) { + $content = getXmlRpcFailure(1, 'no permission'); + break; + } + $tmp_arr = explode('/', $tmp_val); + $document_srl = array_pop($tmp_arr); + if(!$document_srl) { + $content = getXmlRpcFailure(1, 'no permission'); + break; + } + + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + // 글 수정 권한 체크 + if(!$oDocument->isGranted()) { + $content = getXmlRpcFailure(1, 'no permission'); + break; + } + + $obj = $oDocument->getObjectVars(); + + $info = $params[3]; + + // 글, 제목, 카테고리 정보 구함 + for($i=0;$ivalue->struct->member);$i++) { + $val = $info->value->struct->member[$i]; + switch($val->name->body) { + case 'title' : + $obj->title = $val->value->string->body; + break; + case 'description' : + $obj->content = $val->value->string->body; + break; + case 'categories' : + $categories = $val->value->array->data->value; + if(!is_array($categories)) $categories = array($categories); + $category = $categories[0]->string->body; + if($category && $category_list) { + foreach($category_list as $category_srl => $category_info) { + if($category_info->title == $category) $obj->category_srl = $category_srl; + } + } + break; + case 'tagwords' : + $tags = $val->value->array->data->value; + if(!is_array($tags)) $tags = array($tags); + for($j=0;$jstring->body; + } + if(count($tag_list)) $obj->tags = implode(',',$tag_list); + break; + } + + } + + // 문서 번호 설정 + $obj->document_srl = $document_srl; + $obj->module_srl = $this->module_srl; + + // 첨부파일 정리 + if(is_dir($tmp_uploaded_path)) { + $file_list = FileHandler::readDir($tmp_uploaded_path); + $file_count = count($file_list); + if($file_count) { + $oFileController = &getController('file'); + for($i=0;$i<$file_count;$i++) { + $file_info['tmp_name'] = sprintf('%s%s', $tmp_uploaded_path, $file_list[$i]); + $file_info['name'] = $file_list[$i]; + + $moved_filename = sprintf('./files/attach/images/%s/%s/%s', $this->module_srl, $document_srl, $file_info['name']); + if(file_exists($moved_filename)) continue; + + $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true); + } + $obj->uploaded_count += $file_count; + } + } + + $obj->content = str_replace($uploaded_target_path,sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl,3), $filename), $obj->content); + + $oDocumentController = &getController('document'); + $output = $oDocumentController->updateDocument($oDocument,$obj); + + if(!$output->toBool()) { + $content = getXmlRpcFailure(1, $output->getMessage()); + } else { + $content = getXmlRpcResponse(true); + FileHandler::removeDir($tmp_uploaded_path); + } + + printContent($content); + break; + + // 글삭제 + case 'blogger.deletePost' : + $tmp_val = $params[0]->value->string->body; + $tmp_arr = explode('/', $tmp_val); + $document_srl = array_pop($tmp_arr); + + // 글 받아오기 + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + // 글 존재 + if(!$oDocument->isExists()) { + $content = getXmlRpcFailure(1, 'not exists'); + + // 글 삭제 권한 체크 + } elseif(!$oDocument->isGranted()) { + $content = getXmlRpcFailure(1, 'no permission'); + break; + + // 삭제 + } else { + $oDocumentController = &getController('document'); + $output = $oDocumentController->deleteDocument($document_srl); + if(!$output->toBool()) $content = getXmlRpcFailure(1, $output->getMessage()); + else $content = getXmlRpcResponse(true); + } + + printContent($content); + break; + + // 최신글 받기 + case 'metaWeblog.getRecentPosts' : + // 목록을 구하기 위한 옵션 + $args->module_srl = $this->module_srl; ///< 현재 모듈의 module_srl + $args->page = 1; + $args->list_count = 20; + $args->sort_index = 'list_order'; ///< 소팅 값 + $logged_info = Context::get('logged_info'); + $args->search_target = 'member_srl'; + $args->search_keyword = $logged_info->member_srl; + $output = $oDocumentModel->getDocumentList($args); + if(!$output->toBool() || !$output->data) { + $content = getXmlRpcFailure(1, 'post not founded'); + printContent($content); + } else { + $oEditorController = &getController('editor'); + + $posts = array(); + foreach($output->data as $key => $oDocument) { + $post = null; + $post->categories = array(); + $post->dateCreated = date("Ymd", $oDocument->getRegdateTime()).'T'.date("H:i:s", $oDocument->getRegdateTime()); + $post->description = htmlspecialchars($oEditorController->transComponent($oDocument->getContent(false,false,true,false))); + $post->link = $post->permaLink = getFullUrl('','document_srl',$oDocument->document_srl); + $post->postid = $oDocument->document_srl; + $post->title = htmlspecialchars($oDocument->get('title')); + $post->publish = 1; + $post->userid = $oDocument->get('user_id'); + $post->mt_allow_pings = 0; + $post->mt_allow_comments = $oDocument->allowComment()=='Y'?1:0; + $posts[] = $post; + } + $content = getXmlRpcResponse($posts); + printContent($content); + } + break; + + // 아무런 요청이 없을 경우 RSD 출력 + default : + + $homepagelink = getUrl('','mid',$this->mid); + $site_module_info = Context::get('site_module_info'); + $api_url = getFullSiteUrl($site_module_info->domain, '', 'mid',$site_module_info->mid, 'act','api'); + $content = << + + + XpressEngine + http://www.xpressengine.com/ + {$homepagelink} + + + + + +RSDContent; + printContent($content); + break; + } + } +?> diff --git a/addons/blogapi/blogapi.func.php b/addons/blogapi/blogapi.func.php index 65630f78e..511ac44e3 100644 --- a/addons/blogapi/blogapi.func.php +++ b/addons/blogapi/blogapi.func.php @@ -1,69 +1,69 @@ -\n\n\nfaultCode\n%d\n\n\nfaultString\n%s\n\n\n\n", - $error, - htmlspecialchars($message) - ); - } - - // 결과 표시 - function getXmlRpcResponse($params) { - $buff = ''."\n"; - $buff .= _getEncodedVal($params); - $buff .= "\n\n"; - - return $buff; - } - - // 인코딩 처리 - function _getEncodedVal($val, $is_sub_set = false) { - if(is_int($val)) $buff = sprintf("%d", $val); - elseif(is_string($val)&&preg_match('/^([0-9]+)T([0-9\:]+)$/', $val)) $buff = sprintf("%s\n", $val); - elseif(is_double($val)) $buff = sprintf("%f", $val); - elseif(is_bool($val)) $buff = sprintf("%d", $val?1:0); - elseif(is_object($val)) { - $values = get_object_vars($val); - $val_count = count($values); - $buff = ""; - foreach($values as $k => $v) { - $buff .= sprintf("\n%s\n%s\n", htmlspecialchars($k), _getEncodedVal($v, true)); - } - $buff .= "\n"; - } elseif(is_array($val)) { - $val_count = count($val); - $buff = "\n"; - for($i=0;$i<$val_count;$i++) { - $buff .= _getEncodedVal($val[$i], true); - } - $buff .= "\n"; - } else { - $buff = sprintf("%s\n", $val); - } - if(!$is_sub_set) return sprintf("\n%s", $buff); - return $buff; - } - - // 결과 출력 - function printContent($content) { - header("Content-Type: text/xml; charset=UTF-8"); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - print $content; - Context::close(); - exit(); - } -?> +\n\n\nfaultCode\n%d\n\n\nfaultString\n%s\n\n\n\n", + $error, + htmlspecialchars($message) + ); + } + + // 결과 표시 + function getXmlRpcResponse($params) { + $buff = ''."\n"; + $buff .= _getEncodedVal($params); + $buff .= "\n\n"; + + return $buff; + } + + // 인코딩 처리 + function _getEncodedVal($val, $is_sub_set = false) { + if(is_int($val)) $buff = sprintf("%d", $val); + elseif(is_string($val)&&preg_match('/^([0-9]+)T([0-9\:]+)$/', $val)) $buff = sprintf("%s\n", $val); + elseif(is_double($val)) $buff = sprintf("%f", $val); + elseif(is_bool($val)) $buff = sprintf("%d", $val?1:0); + elseif(is_object($val)) { + $values = get_object_vars($val); + $val_count = count($values); + $buff = ""; + foreach($values as $k => $v) { + $buff .= sprintf("\n%s\n%s\n", htmlspecialchars($k), _getEncodedVal($v, true)); + } + $buff .= "\n"; + } elseif(is_array($val)) { + $val_count = count($val); + $buff = "\n"; + for($i=0;$i<$val_count;$i++) { + $buff .= _getEncodedVal($val[$i], true); + } + $buff .= "\n"; + } else { + $buff = sprintf("%s\n", $val); + } + if(!$is_sub_set) return sprintf("\n%s", $buff); + return $buff; + } + + // 결과 출력 + function printContent($content) { + header("Content-Type: text/xml; charset=UTF-8"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + print $content; + Context::close(); + exit(); + } +?> diff --git a/addons/blogapi/conf/info.xml b/addons/blogapi/conf/info.xml index 4850ac4ee..f533cd4a6 100644 --- a/addons/blogapi/conf/info.xml +++ b/addons/blogapi/conf/info.xml @@ -1,80 +1,80 @@ - - - BlogAPI 애드온 - BlogAPIアドオン - BlogAPI - Addon for BlogAPI - BlogAPI Addon - Addon für BlogAPI - Addon para BlogAPI - Аддон для BlogAPI - 部落格 API - - metaWeblog를 지원하는 blogApi애드온입니다. - 사용으로 설정하시면 각 모듈마다 RSD 태그를 노출합니다. - api의 주소는 http://설치주소/모듈명/api 입니다. - 사용으로 하셔야 RSD태그 및 api가 동작을 합니다. - - - MetaWeblogをサポートするBlog APIアドオンです。 - 「使用する」にチェックすると各モジュールごとにRSDのアドレスを表示します。 - APIのアドレスは「http://インストールURL/モジュール名/api」です。 - 「使用する」に設定してから、RSDタグ、およびAPIが作動します。 - - - 支持metaWeblog的 blogApi插件。 - 设置为"启用"时,会使每个模块都会显示RSD标签。 - api地址为http://安装地址/模块名/api。 - 把状态设置为"使用"时,才会激活RSD标签及api。 - - - This blogApi addon supports metaWeblog. - By using this option, it lets the RSD tag to be exposed to each module. - URL to the api is http://setup_path/module_name/api. - RSD tag and the api will work only if u use this addon. - - - Addon BlogAPI này hỗ trợ metaWeblog.. - Bằng việc sử dụng tùy chọn này, Tag RSD sẽ được hiển thị đến mỗi Module. - URL cho API có dạng http://setup_path/module_name/api. - RSD Tag và API chỉ làm việc khi Addon này được kích hoạt. - - - Diese blogApi addon metaWeblog unterstützt. - Durch die Verwendung dieser Option, die es ermöglicht RSD Tag ausgesetzt werden jedes Modul. - URL der api ist http://setup_path/module_name/api. - RSD-Tag und dem API arbeiten und nur dann, wenn Sie über dieses Addon. - - - Este blogApi addon soporta el metaWeblog. - Si seleccionas la optión usar, cada módulo entregará la etiqueta RSD. - La dirección de api es http://dirección de la instalación/nombre de módulo/api. - Sólo si seleccionas la opción usar, funcionará la etiqueta RSD y api. - - - Этот blogApi аддон поддерживает metaWeblog. - Используя этот аддон, RSD тег становится доступным для каждого модуля. - URL для api - http://setup_path/module_name/api. - тег RSD и api работают только при включенном аддоне. - - - 支援 MetaWeblog 的部落格 API 附加元件。 - 設置成"啟用"時,會使每個模組都顯示 RSD 圖示。 - API網址是 http://安裝位置/模組名稱/api。 - 將狀態設置成"啟用"時,才可使用 RSD 和 API - - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + BlogAPI 애드온 + BlogAPIアドオン + BlogAPI + Addon for BlogAPI + BlogAPI Addon + Addon für BlogAPI + Addon para BlogAPI + Аддон для BlogAPI + 部落格 API + + metaWeblog를 지원하는 blogApi애드온입니다. + 사용으로 설정하시면 각 모듈마다 RSD 태그를 노출합니다. + api의 주소는 http://설치주소/모듈명/api 입니다. + 사용으로 하셔야 RSD태그 및 api가 동작을 합니다. + + + MetaWeblogをサポートするBlog APIアドオンです。 + 「使用する」にチェックすると各モジュールごとにRSDのアドレスを表示します。 + APIのアドレスは「http://インストールURL/モジュール名/api」です。 + 「使用する」に設定してから、RSDタグ、およびAPIが作動します。 + + + 支持metaWeblog的 blogApi插件。 + 设置为"启用"时,会使每个模块都会显示RSD标签。 + api地址为http://安装地址/模块名/api。 + 把状态设置为"使用"时,才会激活RSD标签及api。 + + + This blogApi addon supports metaWeblog. + By using this option, it lets the RSD tag to be exposed to each module. + URL to the api is http://setup_path/module_name/api. + RSD tag and the api will work only if u use this addon. + + + Addon BlogAPI này hỗ trợ metaWeblog.. + Bằng việc sử dụng tùy chọn này, Tag RSD sẽ được hiển thị đến mỗi Module. + URL cho API có dạng http://setup_path/module_name/api. + RSD Tag và API chỉ làm việc khi Addon này được kích hoạt. + + + Diese blogApi addon metaWeblog unterstützt. + Durch die Verwendung dieser Option, die es ermöglicht RSD Tag ausgesetzt werden jedes Modul. + URL der api ist http://setup_path/module_name/api. + RSD-Tag und dem API arbeiten und nur dann, wenn Sie über dieses Addon. + + + Este blogApi addon soporta el metaWeblog. + Si seleccionas la optión usar, cada módulo entregará la etiqueta RSD. + La dirección de api es http://dirección de la instalación/nombre de módulo/api. + Sólo si seleccionas la opción usar, funcionará la etiqueta RSD y api. + + + Этот blogApi аддон поддерживает metaWeblog. + Используя этот аддон, RSD тег становится доступным для каждого модуля. + URL для api - http://setup_path/module_name/api. + тег RSD и api работают только при включенном аддоне. + + + 支援 MetaWeblog 的部落格 API 附加元件。 + 設置成"啟用"時,會使每個模組都顯示 RSD 圖示。 + API網址是 http://安裝位置/模組名稱/api。 + 將狀態設置成"啟用"時,才可使用 RSD 和 API + + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/captcha/captcha.addon.php b/addons/captcha/captcha.addon.php index a07cd69ac..c5f8ca593 100644 --- a/addons/captcha/captcha.addon.php +++ b/addons/captcha/captcha.addon.php @@ -1,262 +1,262 @@ -addon_info = $addon_info; - } - - function before_module_proc() - { - if($this->addon_info->act_type == 'everytime' && $_SESSION['captcha_authed']) { - unset($_SESSION['captcha_authed']); - } - } - - function before_module_init(&$ModuleHandler) - { - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == 'Y' || $logged_info->is_site_admin) return false; - if($this->addon_info->target != 'all' && Context::get('is_logged')) return false; - - $target_acts = array('procBoardInsertDocument','procBoardInsertComment','procIssuetrackerInsertIssue','procIssuetrackerInsertHistory','procTextyleInsertComment'); - if($this->addon_info->apply_find_account=='apply') $target_acts[] = 'procMemberFindAccount'; - if($this->addon_info->apply_resend_auth_mail=='apply') $target_acts[] = 'procMemberResendAuthMail'; - if($this->addon_info->apply_signup=='apply') $target_acts[] = 'procMemberInsert'; - - if(Context::getRequestMethod()!='XMLRPC' && Context::getRequestMethod()!=='JSON') - { - Context::addHtmlHeader(''); - Context::addJsFile('./addons/captcha/captcha.js',false); - } - - // 게시판/ 이슈트래커의 글쓰기/댓글쓰기 액션 호출시 세션 비교 - if(!$_SESSION['captcha_authed'] && in_array(Context::get('act'), $target_acts)) { - Context::loadLang('./addons/captcha/lang'); - $ModuleHandler->error = "captcha_denied"; - } - - return true; - } - - function before_module_init_setCaptchaSession() - { - if($_SESSION['captcha_authed']) return false; - - // 언어파일 로드 - Context::loadLang(_XE_PATH_.'addons/captcha/lang'); - - // 키워드 생성 - $arr = range('A','Y'); - shuffle($arr); - $arr = array_slice($arr,0,6); - $_SESSION['captcha_keyword'] = join('', $arr); - - $target = Context::getLang('target_captcha'); - header("Content-Type: text/xml; charset=UTF-8"); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - printf("\r\n 0\r\n success\r\n \r\n \r\n \r\n \r\n \r\n " - ,Context::getLang('about_captcha') - ,Context::getLang('captcha_reload') - ,Context::getLang('captcha_play') - ,Context::getLang('cmd_input') - ,Context::getLang('cmd_cancel') - ); - Context::close(); - exit(); - } - - function before_module_init_captchaImage() - { - if($_SESSION['captcha_authed']) return false; - - $keyword = $_SESSION['captcha_keyword']; - $im = $this->createCaptchaImage($keyword); - - header("Cache-Control: "); - header("Pragma: "); - header("Content-Type: image/png"); - - imagepng($im); - imagedestroy($im); - - Context::close(); - exit(); - } - - function createCaptchaImage($string) - { - $arr = array(); - for($i=0,$c=strlen($string);$i<$c;$i++) $arr[] = $string{$i}; - - // 글자 하나 사이즈 - $w = 18; - $h = 25; - - // 글자 수 - $c = count($arr); - - // 글자 이미지 - $im = array(); - - // 총사이즈로 바탕 이미지 생성 - $im[] = imagecreate(($w+2)*count($arr), $h); - - $deg = range(-30,30); - shuffle($deg); - - // 글자별 이미지 생성 - foreach($arr as $i => $str) - { - $im[$i+1] = @imagecreate($w, $h); - $background_color = imagecolorallocate($im[$i+1], 255, 255, 255); - $text_color = imagecolorallocate($im[$i+1], 0, 0, 0); - - // 글자폰트(사이즈) 조절 - $ran = range(1,20); - shuffle($ran); - - if(function_exists('imagerotate')) - { - imagestring($im[$i+1], (array_pop($ran)%3)+3, 2, (array_pop($ran)%8), $str, $text_color); - $im[$i+1] = imagerotate($im[$i+1], array_pop($deg), 0); - - $background_color = imagecolorallocate($im[$i+1], 255, 255, 255); - imagecolortransparent($im[$i+1], $background_color); - } - else - { - imagestring($im[$i+1], (array_pop($ran)%3)+3, 2, (array_pop($ran)%4), $str, $text_color); - } - } - - // 각글자 이미지를 합침 - for($i=1;$icreateCaptchaAudio($keyword); - - header('Content-type: audio/mpeg'); - header("Content-Disposition: attachment; filename=\"captcha_audio.mp3\""); - header('Cache-Control: no-store, no-cache, must-revalidate'); - header('Expires: Sun, 1 Jan 2000 12:00:00 GMT'); - header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); - header('Content-Length: ' . strlen($data)); - - echo $data; - Context::close(); - exit(); - } - - function createCaptchaAudio($string) - { - $data = ''; - $_audio = './addons/captcha/audio/F_%s.mp3'; - for($i=0,$c=strlen($string);$i<$c;$i++) - { - $_data = FileHandler::readFile(sprintf($_audio, $string{$i})); - - $start = rand(5, 68); // 해더 4바이트, 데이터 영역 64바이트 정도 랜덤하게 시작 - $datalen = strlen($_data) - $start - 256; // 마지막 unchanged 256 바이트 - - for($j=$start;$j<$datalen;$j+=64) - { - $ch = ord($_data{$j}); - if($ch<9 || $ch>119) continue; - $_data{$j} = chr($ch+rand(-8,8)); - } - - $data .= $_data; - } - - return $data; - } - - function before_module_init_captchaCompare() - { - if($_SESSION['captcha_authed']) return false; - - if(strtoupper($_SESSION['captcha_keyword']) == strtoupper(Context::get('secret_text'))) $_SESSION['captcha_authed'] = true; - else $_SESSION['captcha_authed'] = false; - - header("Content-Type: text/xml; charset=UTF-8"); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - print("\r\n0\r\nsuccess\r\n"); - - Context::close(); - exit(); - } - } - - $GLOBALS['__AddonCaptcha__'] = new AddonCaptcha; - $GLOBALS['__AddonCaptcha__']->setInfo($addon_info); - } - - $oAddonCaptcha = &$GLOBALS['__AddonCaptcha__']; - - if(method_exists(&$oAddonCaptcha, $called_position)) - { - if(!call_user_func(array(&$oAddonCaptcha, $called_position), &$this)) return false; - } - - $addon_act = Context::get('captcha_action'); - if($addon_act && method_exists(&$oAddonCaptcha, $called_position.'_'.$addon_act)) - { - if(!call_user_func(array(&$oAddonCaptcha, $called_position.'_'.$addon_act), &$this)) return false; - } - -?> +addon_info = $addon_info; + } + + function before_module_proc() + { + if($this->addon_info->act_type == 'everytime' && $_SESSION['captcha_authed']) { + unset($_SESSION['captcha_authed']); + } + } + + function before_module_init(&$ModuleHandler) + { + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin == 'Y' || $logged_info->is_site_admin) return false; + if($this->addon_info->target != 'all' && Context::get('is_logged')) return false; + + $target_acts = array('procBoardInsertDocument','procBoardInsertComment','procIssuetrackerInsertIssue','procIssuetrackerInsertHistory','procTextyleInsertComment'); + if($this->addon_info->apply_find_account=='apply') $target_acts[] = 'procMemberFindAccount'; + if($this->addon_info->apply_resend_auth_mail=='apply') $target_acts[] = 'procMemberResendAuthMail'; + if($this->addon_info->apply_signup=='apply') $target_acts[] = 'procMemberInsert'; + + if(Context::getRequestMethod()!='XMLRPC' && Context::getRequestMethod()!=='JSON') + { + Context::addHtmlHeader(''); + Context::addJsFile('./addons/captcha/captcha.js',false); + } + + // 게시판/ 이슈트래커의 글쓰기/댓글쓰기 액션 호출시 세션 비교 + if(!$_SESSION['captcha_authed'] && in_array(Context::get('act'), $target_acts)) { + Context::loadLang('./addons/captcha/lang'); + $ModuleHandler->error = "captcha_denied"; + } + + return true; + } + + function before_module_init_setCaptchaSession() + { + if($_SESSION['captcha_authed']) return false; + + // 언어파일 로드 + Context::loadLang(_XE_PATH_.'addons/captcha/lang'); + + // 키워드 생성 + $arr = range('A','Y'); + shuffle($arr); + $arr = array_slice($arr,0,6); + $_SESSION['captcha_keyword'] = join('', $arr); + + $target = Context::getLang('target_captcha'); + header("Content-Type: text/xml; charset=UTF-8"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + printf("\r\n 0\r\n success\r\n \r\n \r\n \r\n \r\n \r\n " + ,Context::getLang('about_captcha') + ,Context::getLang('captcha_reload') + ,Context::getLang('captcha_play') + ,Context::getLang('cmd_input') + ,Context::getLang('cmd_cancel') + ); + Context::close(); + exit(); + } + + function before_module_init_captchaImage() + { + if($_SESSION['captcha_authed']) return false; + + $keyword = $_SESSION['captcha_keyword']; + $im = $this->createCaptchaImage($keyword); + + header("Cache-Control: "); + header("Pragma: "); + header("Content-Type: image/png"); + + imagepng($im); + imagedestroy($im); + + Context::close(); + exit(); + } + + function createCaptchaImage($string) + { + $arr = array(); + for($i=0,$c=strlen($string);$i<$c;$i++) $arr[] = $string{$i}; + + // 글자 하나 사이즈 + $w = 18; + $h = 25; + + // 글자 수 + $c = count($arr); + + // 글자 이미지 + $im = array(); + + // 총사이즈로 바탕 이미지 생성 + $im[] = imagecreate(($w+2)*count($arr), $h); + + $deg = range(-30,30); + shuffle($deg); + + // 글자별 이미지 생성 + foreach($arr as $i => $str) + { + $im[$i+1] = @imagecreate($w, $h); + $background_color = imagecolorallocate($im[$i+1], 255, 255, 255); + $text_color = imagecolorallocate($im[$i+1], 0, 0, 0); + + // 글자폰트(사이즈) 조절 + $ran = range(1,20); + shuffle($ran); + + if(function_exists('imagerotate')) + { + imagestring($im[$i+1], (array_pop($ran)%3)+3, 2, (array_pop($ran)%8), $str, $text_color); + $im[$i+1] = imagerotate($im[$i+1], array_pop($deg), 0); + + $background_color = imagecolorallocate($im[$i+1], 255, 255, 255); + imagecolortransparent($im[$i+1], $background_color); + } + else + { + imagestring($im[$i+1], (array_pop($ran)%3)+3, 2, (array_pop($ran)%4), $str, $text_color); + } + } + + // 각글자 이미지를 합침 + for($i=1;$icreateCaptchaAudio($keyword); + + header('Content-type: audio/mpeg'); + header("Content-Disposition: attachment; filename=\"captcha_audio.mp3\""); + header('Cache-Control: no-store, no-cache, must-revalidate'); + header('Expires: Sun, 1 Jan 2000 12:00:00 GMT'); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . 'GMT'); + header('Content-Length: ' . strlen($data)); + + echo $data; + Context::close(); + exit(); + } + + function createCaptchaAudio($string) + { + $data = ''; + $_audio = './addons/captcha/audio/F_%s.mp3'; + for($i=0,$c=strlen($string);$i<$c;$i++) + { + $_data = FileHandler::readFile(sprintf($_audio, $string{$i})); + + $start = rand(5, 68); // 해더 4바이트, 데이터 영역 64바이트 정도 랜덤하게 시작 + $datalen = strlen($_data) - $start - 256; // 마지막 unchanged 256 바이트 + + for($j=$start;$j<$datalen;$j+=64) + { + $ch = ord($_data{$j}); + if($ch<9 || $ch>119) continue; + $_data{$j} = chr($ch+rand(-8,8)); + } + + $data .= $_data; + } + + return $data; + } + + function before_module_init_captchaCompare() + { + if($_SESSION['captcha_authed']) return false; + + if(strtoupper($_SESSION['captcha_keyword']) == strtoupper(Context::get('secret_text'))) $_SESSION['captcha_authed'] = true; + else $_SESSION['captcha_authed'] = false; + + header("Content-Type: text/xml; charset=UTF-8"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + print("\r\n0\r\nsuccess\r\n"); + + Context::close(); + exit(); + } + } + + $GLOBALS['__AddonCaptcha__'] = new AddonCaptcha; + $GLOBALS['__AddonCaptcha__']->setInfo($addon_info); + } + + $oAddonCaptcha = &$GLOBALS['__AddonCaptcha__']; + + if(method_exists(&$oAddonCaptcha, $called_position)) + { + if(!call_user_func(array(&$oAddonCaptcha, $called_position), &$this)) return false; + } + + $addon_act = Context::get('captcha_action'); + if($addon_act && method_exists(&$oAddonCaptcha, $called_position.'_'.$addon_act)) + { + if(!call_user_func(array(&$oAddonCaptcha, $called_position.'_'.$addon_act), &$this)) return false; + } + +?> diff --git a/addons/captcha/conf/info.xml b/addons/captcha/conf/info.xml index a555e14ee..e2353c16b 100644 --- a/addons/captcha/conf/info.xml +++ b/addons/captcha/conf/info.xml @@ -1,222 +1,222 @@ - - - Captcha 애드온 - CAPTCHA - Captcha Addon - 验证码插件 - Captchaアドオン - Аддон Captcha - 圖形驗證 - - 프로그램 글 등록기를 막기 위해 게시판/ issueTracker에서 글/ 댓글을 입력하려 할 때 알파벳을 입력해야 글/댓글이 입력되는 애드온 입니다. - 로그인하지 않은 경우에만 해당됩니다. - - - To block spam written by programs, let users to choose a suitable image to text when writing a posting or comment. - This addon applies only to not-logged-in users. - - - Addon này tạo ra một hình ảnh xác nhận khi đăng kí, gửi bài, hay viết bình luận nếu thành viên không đăng nhập. - Addon này chỉ hoạt động khi được kích hoạt. - - - 为了解决互联网垃圾而开发的验证码机制。 - 非登录用户发布话题或评论时将会弹出验证图片选择框,选择正确的图片才可以正常发布(适用于版面/issueTracker)。 - - - ボット(bot)がプログラムによるスパム行為を防ぐために、掲示板/issueTrackerで書き込み・コメントを登録する際、ランダムな文字や数字の列を画面に表示し、表示されたものと一致した情報を入力した時、登録が出来るようにするアドオンです。 - ログインしてない時だけ、動作します。 - - - To block spam written by programs, let users to choose a suitable image to text when writing a posting or comment. - This addon applies only to not-logged-in users. - - - 可防止機器人程式的垃圾留言,非用戶要發表主題或回覆時,必須要輸入正確圖片中所顯示的文字才能發表。 - - 1.0 - 2010-08-19 - - - XE - XE - XE - XE - XE - XE - XE - - - - - Captcha 표시 대상 - 应用对象 - Captchaを表示する対象 - 選擇目標 - Captcha Target - Captcha Target - Mục tiêu Captcha hiển thị - 글/댓글 등록시 captcha가 동작할 대상을 정할 수 있습니다. 관리자는 무조건 제외됩니다 - 可以指定验证码应用对象(管理员除外)。 - 管理者を除き、書き込み・コメントを入力する際にcaptchaイメージを見せる対象を設定します。 - 除了管理員,可以選擇圖形驗證應用的對象。 - You may specify targets CAPTCHA work. It's not applied when administrator writes. - You may specify targets CAPTCHA work. It's not applied when administrator writes. - Khi gửi bài, bình luận, Capcha sẽ hiển thị để xác nhận hành động của người sử dụng. Chức năng này không hoạt động với người quản lý. - - 로그인하지 않은 사용자 - 非登录用户 - ログインしてないユーザー - 非用戶 - Not logged-in users - Not logged-in users - Người dùng chưa đăng nhập - - - 모든 사용자 - 所有用户 - すべてのユーザー - 所有用戶 - All users - All users - Tất cả mọi người - - - - 동작 방식 - 验证方式 - 動作方式 - 驗證模式 - How it works - How it works - Sử dụng - "1번만 동작"을 선택하시면 1번만 동작후 상태를 저장해서 다음부터 물어보지 않고 그렇지 않으면 매번 물어보게 됩니다 - "一次"就是每个IP只出现一次验证。 - 「1回だけ表示」を選択すると、最初だけ動作した後、その情報を記憶して次回からはCaptchaを見せないようにします。また、もう一つのオプションは毎回Captchaを表示します。 - 選擇"單次",下次不會再顯示;選擇"每次"則會一直顯示。 - If you choose "Once", CAPTCHA works only once for the user by storing status. Otherwise, this addon would show an image every time the user writes. - If you choose "Once", CAPTCHA works only once for the user by storing status. Otherwise, this addon would show an image every time the user writes. - Nếu chọn "Chỉ một lần" thì sau lần hiển thị đó Capcha sẽ không hiển thị với người sử dụng đó nữa. - - 1번만 동작 - 一次 - 1回だけ表示 - 單次 - Chỉ một lần - once - 1 раз - - - 매번 동작 - 每次 - 毎回表示 - 每次 - every time - каждый раз - Luôn sử dụng - - - - 비밀번호 찾기 적용 - 应用到查找密码功能 - 비밀번호 찾기 적용 - 忘記密碼 - applying to an action finding account - applying to an action finding account - Khi lấy lại mật khẩu - 적용으로 하시면 비밀번호 찾기 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. - 启用此项功能可以有效地拦截以查找密码名义发送的垃圾邮件。 - 적용으로 하시면 비밀번호찾기 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. - 開啟功能後在忘記密碼時會顯示驗證碼。 - If you set this option as apply, CAPTCHA will work for finding account action, too. - If you set this option as apply, CAPTCHA will work for finding account action, too. - Nếu áp dụng, khi thành viên cần lấy lại mật khẩu khi lỡ quên, Capcha sẽ hiện thị để xác nhận việc này. - - 적용하지 않음 - 不启用 - 적용하지 않음 - 關閉 - Not apply - Not apply - Không áp dụng - - - 적용 - 启用 - 적용 - 開啟 - Apply - Apply - Áp dụng - - - - 인증 메일 재발송 적용 - 应用到认证邮件重新发送功能 - 인증 메일 재발송 적용 - 重寄認證信 - apply to an action resending authmail - apply to an action resending authmail - Khi lấy lại mã kích hoạt - 적용으로 하시면 인증 메일 재발송 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. - 启用此项功能可以有效地拦截以重新发送认证邮件名义发送的垃圾邮件。 - 적용으로 하시면 인증 메일 재발송 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. - 開啟功能後在重寄認證信時會顯示驗證碼。 - If you set this option as apply, CAPTCHA will work for resending authmail action, too. - If you set this option as apply, CAPTCHA will work for resending authmail action, too. - Nếu áp dụng, khi thành viên cần lấy lại mã kích hoạt thành viên, Capcha sẽ hiện thị để xác nhận việc này. - - 적용하지 않음 - 不启用 - 적용하지 않음 - 關閉 - Not apply - Not apply - Không áp dụng - - - 적용 - 启用 - 적용 - 開啟 - Apply - Apply - Áp dụng - - - - 회원 가입 적용 - 应用到用户注册表单 - 인증 메일 재발송 적용 - 會員註冊 - Apply to member signup - Apply to member signup - Apply to member signup - 적용으로 하시면 회원가입 기능에도 적용되어 악의적인 봇(또는 프로그램)의 회원가입을 막을 수 있습니다. - 启用此项功能可以有效地拦截自动注册软件的施虐。 - 적용으로 하시면 회원가입 기능에도 적용되어 악의적인 봇(또는 프로그램)의 회원가입을 막을 수 있습니다. - 開啟功能後在註冊時會顯示驗證碼。 - If you set this option as apply, CAPTCHA will work for signup action, too. - If you set this option as apply, CAPTCHA will work for signup action, too. - If you set this option as apply, CAPTCHA will work for signup action, too. - - 적용하지 않음 - 不启用 - 적용하지 않음 - 關閉 - Not apply - Not apply - Không áp dụng - - - 적용 - 启用 - 적용 - 開啟 - Apply - Apply - Áp dụng - - - - + + + Captcha 애드온 + CAPTCHA + Captcha Addon + 验证码插件 + Captchaアドオン + Аддон Captcha + 圖形驗證 + + 프로그램 글 등록기를 막기 위해 게시판/ issueTracker에서 글/ 댓글을 입력하려 할 때 알파벳을 입력해야 글/댓글이 입력되는 애드온 입니다. + 로그인하지 않은 경우에만 해당됩니다. + + + To block spam written by programs, let users to choose a suitable image to text when writing a posting or comment. + This addon applies only to not-logged-in users. + + + Addon này tạo ra một hình ảnh xác nhận khi đăng kí, gửi bài, hay viết bình luận nếu thành viên không đăng nhập. + Addon này chỉ hoạt động khi được kích hoạt. + + + 为了解决互联网垃圾而开发的验证码机制。 + 非登录用户发布话题或评论时将会弹出验证图片选择框,选择正确的图片才可以正常发布(适用于版面/issueTracker)。 + + + ボット(bot)がプログラムによるスパム行為を防ぐために、掲示板/issueTrackerで書き込み・コメントを登録する際、ランダムな文字や数字の列を画面に表示し、表示されたものと一致した情報を入力した時、登録が出来るようにするアドオンです。 + ログインしてない時だけ、動作します。 + + + To block spam written by programs, let users to choose a suitable image to text when writing a posting or comment. + This addon applies only to not-logged-in users. + + + 可防止機器人程式的垃圾留言,非用戶要發表主題或回覆時,必須要輸入正確圖片中所顯示的文字才能發表。 + + 1.0 + 2010-08-19 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + + + + Captcha 표시 대상 + 应用对象 + Captchaを表示する対象 + 選擇目標 + Captcha Target + Captcha Target + Mục tiêu Captcha hiển thị + 글/댓글 등록시 captcha가 동작할 대상을 정할 수 있습니다. 관리자는 무조건 제외됩니다 + 可以指定验证码应用对象(管理员除外)。 + 管理者を除き、書き込み・コメントを入力する際にcaptchaイメージを見せる対象を設定します。 + 除了管理員,可以選擇圖形驗證應用的對象。 + You may specify targets CAPTCHA work. It's not applied when administrator writes. + You may specify targets CAPTCHA work. It's not applied when administrator writes. + Khi gửi bài, bình luận, Capcha sẽ hiển thị để xác nhận hành động của người sử dụng. Chức năng này không hoạt động với người quản lý. + + 로그인하지 않은 사용자 + 非登录用户 + ログインしてないユーザー + 非用戶 + Not logged-in users + Not logged-in users + Người dùng chưa đăng nhập + + + 모든 사용자 + 所有用户 + すべてのユーザー + 所有用戶 + All users + All users + Tất cả mọi người + + + + 동작 방식 + 验证方式 + 動作方式 + 驗證模式 + How it works + How it works + Sử dụng + "1번만 동작"을 선택하시면 1번만 동작후 상태를 저장해서 다음부터 물어보지 않고 그렇지 않으면 매번 물어보게 됩니다 + "一次"就是每个IP只出现一次验证。 + 「1回だけ表示」を選択すると、最初だけ動作した後、その情報を記憶して次回からはCaptchaを見せないようにします。また、もう一つのオプションは毎回Captchaを表示します。 + 選擇"單次",下次不會再顯示;選擇"每次"則會一直顯示。 + If you choose "Once", CAPTCHA works only once for the user by storing status. Otherwise, this addon would show an image every time the user writes. + If you choose "Once", CAPTCHA works only once for the user by storing status. Otherwise, this addon would show an image every time the user writes. + Nếu chọn "Chỉ một lần" thì sau lần hiển thị đó Capcha sẽ không hiển thị với người sử dụng đó nữa. + + 1번만 동작 + 一次 + 1回だけ表示 + 單次 + Chỉ một lần + once + 1 раз + + + 매번 동작 + 每次 + 毎回表示 + 每次 + every time + каждый раз + Luôn sử dụng + + + + 비밀번호 찾기 적용 + 应用到查找密码功能 + 비밀번호 찾기 적용 + 忘記密碼 + applying to an action finding account + applying to an action finding account + Khi lấy lại mật khẩu + 적용으로 하시면 비밀번호 찾기 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. + 启用此项功能可以有效地拦截以查找密码名义发送的垃圾邮件。 + 적용으로 하시면 비밀번호찾기 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. + 開啟功能後在忘記密碼時會顯示驗證碼。 + If you set this option as apply, CAPTCHA will work for finding account action, too. + If you set this option as apply, CAPTCHA will work for finding account action, too. + Nếu áp dụng, khi thành viên cần lấy lại mật khẩu khi lỡ quên, Capcha sẽ hiện thị để xác nhận việc này. + + 적용하지 않음 + 不启用 + 적용하지 않음 + 關閉 + Not apply + Not apply + Không áp dụng + + + 적용 + 启用 + 적용 + 開啟 + Apply + Apply + Áp dụng + + + + 인증 메일 재발송 적용 + 应用到认证邮件重新发送功能 + 인증 메일 재발송 적용 + 重寄認證信 + apply to an action resending authmail + apply to an action resending authmail + Khi lấy lại mã kích hoạt + 적용으로 하시면 인증 메일 재발송 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. + 启用此项功能可以有效地拦截以重新发送认证邮件名义发送的垃圾邮件。 + 적용으로 하시면 인증 메일 재발송 기능에도 적용되어 악의적인 봇(또는 프로그램)에 의한 메일 발송을 막을 수 있습니다. + 開啟功能後在重寄認證信時會顯示驗證碼。 + If you set this option as apply, CAPTCHA will work for resending authmail action, too. + If you set this option as apply, CAPTCHA will work for resending authmail action, too. + Nếu áp dụng, khi thành viên cần lấy lại mã kích hoạt thành viên, Capcha sẽ hiện thị để xác nhận việc này. + + 적용하지 않음 + 不启用 + 적용하지 않음 + 關閉 + Not apply + Not apply + Không áp dụng + + + 적용 + 启用 + 적용 + 開啟 + Apply + Apply + Áp dụng + + + + 회원 가입 적용 + 应用到用户注册表单 + 인증 메일 재발송 적용 + 會員註冊 + Apply to member signup + Apply to member signup + Apply to member signup + 적용으로 하시면 회원가입 기능에도 적용되어 악의적인 봇(또는 프로그램)의 회원가입을 막을 수 있습니다. + 启用此项功能可以有效地拦截自动注册软件的施虐。 + 적용으로 하시면 회원가입 기능에도 적용되어 악의적인 봇(또는 프로그램)의 회원가입을 막을 수 있습니다. + 開啟功能後在註冊時會顯示驗證碼。 + If you set this option as apply, CAPTCHA will work for signup action, too. + If you set this option as apply, CAPTCHA will work for signup action, too. + If you set this option as apply, CAPTCHA will work for signup action, too. + + 적용하지 않음 + 不启用 + 적용하지 않음 + 關閉 + Not apply + Not apply + Không áp dụng + + + 적용 + 启用 + 적용 + 開啟 + Apply + Apply + Áp dụng + + + + diff --git a/addons/counter/conf/info.xml b/addons/counter/conf/info.xml index ff3e54327..7114c2380 100644 --- a/addons/counter/conf/info.xml +++ b/addons/counter/conf/info.xml @@ -1,62 +1,62 @@ - - - 기본 카운터 애드온 - アクセスカウンターアドオン - 网站访问统计 - Counter Addon - Counter Addon - Counter Addon - Addon contador básico - Аддон счетчика - 網站訪問統計 - - XE의 기본 카운터 모듈을 이용하여 접속 정보를 기록합니다. - 이 애드온을 켜셔야 접속 정보 수집이 됩니다. - - - XEのアクセスカウンターモジュールで接続(アクセス)情報を記録します。 - このアドオンを「使用」に設定してから、接続(アクセス)情報が記録されます。 - - - 利用XE的网站访问统计模块记录网站访问信息。 - 把状态设置为"使用"时,才会记录网站访问信息. - - - This addon logs access information based on the basic counter module within XE. - The access information will be collected only if you turn on this addon. - - - Addon này sẽ tổng hợp tất cả những lượt truy cập vào Website qua Module Counter có sẵn bên trong XE. - Thông tin truy nhập chỉ được tập hợp khi bạn bật Addon này.. - - - Dieses Addon-Logs Zugriff auf Informationen basiert auf den grundlegenden Zähler-Modul innerhalb XE. - Der Zugang zu Informationen wird nur erhoben, wenn Sie über dieses Addon. - - - Este addon contador básico de XE permite llevar la información de acceso a la página web de los visitantes. - Es necesario activar este addon para agregar la información de acceso. - - - Этот аддон пишет в лог информацию о доступе к сайту, основанную на базовом модуле счетчика в XE. - Для сбора информации необходимо включить этот аддон. - - - 使用XE的網站訪問統計模組記錄網站訪問資料。 - 將狀態設置成"使用"時,才會紀錄網站訪問資料。 - - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 기본 카운터 애드온 + アクセスカウンターアドオン + 网站访问统计 + Counter Addon + Counter Addon + Counter Addon + Addon contador básico + Аддон счетчика + 網站訪問統計 + + XE의 기본 카운터 모듈을 이용하여 접속 정보를 기록합니다. + 이 애드온을 켜셔야 접속 정보 수집이 됩니다. + + + XEのアクセスカウンターモジュールで接続(アクセス)情報を記録します。 + このアドオンを「使用」に設定してから、接続(アクセス)情報が記録されます。 + + + 利用XE的网站访问统计模块记录网站访问信息。 + 把状态设置为"使用"时,才会记录网站访问信息. + + + This addon logs access information based on the basic counter module within XE. + The access information will be collected only if you turn on this addon. + + + Addon này sẽ tổng hợp tất cả những lượt truy cập vào Website qua Module Counter có sẵn bên trong XE. + Thông tin truy nhập chỉ được tập hợp khi bạn bật Addon này.. + + + Dieses Addon-Logs Zugriff auf Informationen basiert auf den grundlegenden Zähler-Modul innerhalb XE. + Der Zugang zu Informationen wird nur erhoben, wenn Sie über dieses Addon. + + + Este addon contador básico de XE permite llevar la información de acceso a la página web de los visitantes. + Es necesario activar este addon para agregar la información de acceso. + + + Этот аддон пишет в лог информацию о доступе к сайту, основанную на базовом модуле счетчика в XE. + Для сбора информации необходимо включить этот аддон. + + + 使用XE的網站訪問統計模組記錄網站訪問資料。 + 將狀態設置成"使用"時,才會紀錄網站訪問資料。 + + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/counter/counter.addon.php b/addons/counter/counter.addon.php index 6f896eee2..d46ad7b9e 100644 --- a/addons/counter/counter.addon.php +++ b/addons/counter/counter.addon.php @@ -1,14 +1,14 @@ -procCounterExecute(); - } -?> +procCounterExecute(); + } +?> diff --git a/addons/member_communication/conf/info.xml b/addons/member_communication/conf/info.xml index fe194c969..25f3b7677 100644 --- a/addons/member_communication/conf/info.xml +++ b/addons/member_communication/conf/info.xml @@ -1,58 +1,58 @@ - - - 커뮤니케이션 - コミュニケーション - 会员交流 - Communication - Truyền thông - 커뮤니케이션 - 커뮤니케이션 - Общение - 交流 - - 커뮤니케이션 모듈의 기능을 활성화 시켜 쪽지나 친구기능을 사용할 수 있도록 해줍니다. - 쪽지, 친구기능등을 사용하기 위해서는 이 애드온을 사용으로 해주시면 됩니다. - - - メッセージ・友達機能を使うにはこのアドオンを「使用」にして下さい。 - - - 此插件可激活短信箱及添加好友功能。 - - - This addon enables communication module in order to use message or friend function. - Please enable this addon in case you want to use those functions. - - - Addon này cho phép sử dụng Module truyền thông để sử dụng tin nhắn hay chức năng bạn bè. - Hãy kích hoạt nếu bạn muốn sử dụng chức năng này. - - - 커뮤니케이션 모듈의 기능을 활성화 시켜 쪽지나 친구기능을 사용할 수 있도록 해줍니다. - 쪽지, 친구기능등을 사용하기 위해서는 이 애드온을 사용으로 해주시면 됩니다. - - - 커뮤니케이션 모듈의 기능을 활성화 시켜 쪽지나 친구기능을 사용할 수 있도록 해줍니다. - 쪽지, 친구기능등을 사용하기 위해서는 이 애드온을 사용으로 해주시면 됩니다. - - - Активизирует модуль Общение, позволяет использование сообщений между друзьями. - - - 讓會員擁有短訊和新增好友功能。 - - 0.1 - 2008-05-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 커뮤니케이션 + コミュニケーション + 会员交流 + Communication + Truyền thông + 커뮤니케이션 + 커뮤니케이션 + Общение + 交流 + + 커뮤니케이션 모듈의 기능을 활성화 시켜 쪽지나 친구기능을 사용할 수 있도록 해줍니다. + 쪽지, 친구기능등을 사용하기 위해서는 이 애드온을 사용으로 해주시면 됩니다. + + + メッセージ・友達機能を使うにはこのアドオンを「使用」にして下さい。 + + + 此插件可激活短信箱及添加好友功能。 + + + This addon enables communication module in order to use message or friend function. + Please enable this addon in case you want to use those functions. + + + Addon này cho phép sử dụng Module truyền thông để sử dụng tin nhắn hay chức năng bạn bè. + Hãy kích hoạt nếu bạn muốn sử dụng chức năng này. + + + 커뮤니케이션 모듈의 기능을 활성화 시켜 쪽지나 친구기능을 사용할 수 있도록 해줍니다. + 쪽지, 친구기능등을 사용하기 위해서는 이 애드온을 사용으로 해주시면 됩니다. + + + 커뮤니케이션 모듈의 기능을 활성화 시켜 쪽지나 친구기능을 사용할 수 있도록 해줍니다. + 쪽지, 친구기능등을 사용하기 위해서는 이 애드온을 사용으로 해주시면 됩니다. + + + Активизирует модуль Общение, позволяет использование сообщений между друзьями. + + + 讓會員擁有短訊和新增好友功能。 + + 0.1 + 2008-05-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/member_communication/lang/ru.lang.php b/addons/member_communication/lang/ru.lang.php index 80929bbad..4e47c4c23 100644 --- a/addons/member_communication/lang/ru.lang.php +++ b/addons/member_communication/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief Russian basic language pack **/ diff --git a/addons/member_communication/lang/vi.lang.php b/addons/member_communication/lang/vi.lang.php index a8b416916..4015a8be0 100644 --- a/addons/member_communication/lang/vi.lang.php +++ b/addons/member_communication/lang/vi.lang.php @@ -1,7 +1,7 @@ module != 'member') { - - // 커뮤니케이션 모듈의 언어파일을 읽음 - Context::loadLang('./modules/communication/lang'); - - // 회원 로그인 정보중에서 쪽지등의 메뉴를 추가 - $oMemberController = &getController('member'); - $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); - $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); - - // 새로운 쪽지에 대한 플래그가 있으면 쪽지 보기 팝업 띄움 - $flag_path = './files/member_extra_info/new_message_flags/'.getNumberingPath($logged_info->member_srl); - $flag_file = sprintf('%s%s', $flag_path, $logged_info->member_srl); - - if(file_exists($flag_file)) { - $new_message_count = FileHandler::readFile($flag_file); - FileHandler::removeFile($flag_file); - Context::loadLang('./addons/member_communication/lang'); - - $script = sprintf('', sprintf(Context::getLang('alert_new_message_arrived'), $new_message_count), Context::getRequestUri().'?module=communication&act=dispCommunicationNewMessage'); - - Context::addHtmlHeader( $script ); - } - - /** - * 기능 수행 : 사용자 이름을 클릭시 요청되는 팝업메뉴의 메뉴에 쪽지 발송, 친구추가등의 링크 추가 - **/ - } elseif($called_position == 'before_module_proc' && $this->act == 'getMemberMenu') { - - $oMemberController = &getController('member'); - $member_srl = Context::get('target_srl'); - $mid = Context::get('cur_mid'); - - // communication 모델 객체 생성 - $oCommunicationModel = &getModel('communication'); - - // 자신이라면 쪽지함 보기 기능 추가 - if($logged_info->member_srl == $member_srl) { - - // 자신의 쪽지함 보기 기능 추가 - $oMemberController->addMemberPopupMenu(getUrl('','mid',$mid,'act','dispCommunicationMessages'), 'cmd_view_message_box', './modules/communication/tpl/images/icon_message_box.gif', 'self'); - - // 친구 목록 보기 - $oMemberController->addMemberPopupMenu(getUrl('','mid',$mid,'act','dispCommunicationFriend'), 'cmd_view_friend', './modules/communication/tpl/images/icon_friend_box.gif', 'self'); - - // 아니라면 쪽지 발송, 친구 등록 추가 - } else { - // 대상 회원의 정보를 가져옴 - $oMemberModel = &getModel('member'); - $target_member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - if(!$target_member_info->member_srl) return; - - // 로그인된 사용자 정보를 구함 - $logged_info = Context::get('logged_info'); - - // 쪽지 발송 메뉴를 만듬 - if( $logged_info->is_admin == 'Y' || $target_member_info->allow_message =='Y' || ($target_member_info->allow_message == 'F' && $oCommunicationModel->isFriend($member_srl))) - $oMemberController->addMemberPopupMenu(getUrl('','module','communication','act','dispCommunicationSendMessage','receiver_srl',$member_srl), 'cmd_send_message', './modules/communication/tpl/images/icon_write_message.gif', 'popup'); - - // 친구 등록 메뉴를 만듬 (이미 등록된 친구가 아닐 경우) - if(!$oCommunicationModel->isAddedFriend($member_srl)) - $oMemberController->addMemberPopupMenu(getUrl('','module','communication','act','dispCommunicationAddFriend','target_srl',$member_srl), 'cmd_add_friend', './modules/communication/tpl/images/icon_add_friend.gif', 'popup'); - } - } -?> +module != 'member') { + + // 커뮤니케이션 모듈의 언어파일을 읽음 + Context::loadLang('./modules/communication/lang'); + + // 회원 로그인 정보중에서 쪽지등의 메뉴를 추가 + $oMemberController = &getController('member'); + $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); + $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); + + // 새로운 쪽지에 대한 플래그가 있으면 쪽지 보기 팝업 띄움 + $flag_path = './files/member_extra_info/new_message_flags/'.getNumberingPath($logged_info->member_srl); + $flag_file = sprintf('%s%s', $flag_path, $logged_info->member_srl); + + if(file_exists($flag_file)) { + $new_message_count = FileHandler::readFile($flag_file); + FileHandler::removeFile($flag_file); + Context::loadLang('./addons/member_communication/lang'); + + $script = sprintf('', sprintf(Context::getLang('alert_new_message_arrived'), $new_message_count), Context::getRequestUri().'?module=communication&act=dispCommunicationNewMessage'); + + Context::addHtmlHeader( $script ); + } + + /** + * 기능 수행 : 사용자 이름을 클릭시 요청되는 팝업메뉴의 메뉴에 쪽지 발송, 친구추가등의 링크 추가 + **/ + } elseif($called_position == 'before_module_proc' && $this->act == 'getMemberMenu') { + + $oMemberController = &getController('member'); + $member_srl = Context::get('target_srl'); + $mid = Context::get('cur_mid'); + + // communication 모델 객체 생성 + $oCommunicationModel = &getModel('communication'); + + // 자신이라면 쪽지함 보기 기능 추가 + if($logged_info->member_srl == $member_srl) { + + // 자신의 쪽지함 보기 기능 추가 + $oMemberController->addMemberPopupMenu(getUrl('','mid',$mid,'act','dispCommunicationMessages'), 'cmd_view_message_box', './modules/communication/tpl/images/icon_message_box.gif', 'self'); + + // 친구 목록 보기 + $oMemberController->addMemberPopupMenu(getUrl('','mid',$mid,'act','dispCommunicationFriend'), 'cmd_view_friend', './modules/communication/tpl/images/icon_friend_box.gif', 'self'); + + // 아니라면 쪽지 발송, 친구 등록 추가 + } else { + // 대상 회원의 정보를 가져옴 + $oMemberModel = &getModel('member'); + $target_member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + if(!$target_member_info->member_srl) return; + + // 로그인된 사용자 정보를 구함 + $logged_info = Context::get('logged_info'); + + // 쪽지 발송 메뉴를 만듬 + if( $logged_info->is_admin == 'Y' || $target_member_info->allow_message =='Y' || ($target_member_info->allow_message == 'F' && $oCommunicationModel->isFriend($member_srl))) + $oMemberController->addMemberPopupMenu(getUrl('','module','communication','act','dispCommunicationSendMessage','receiver_srl',$member_srl), 'cmd_send_message', './modules/communication/tpl/images/icon_write_message.gif', 'popup'); + + // 친구 등록 메뉴를 만듬 (이미 등록된 친구가 아닐 경우) + if(!$oCommunicationModel->isAddedFriend($member_srl)) + $oMemberController->addMemberPopupMenu(getUrl('','module','communication','act','dispCommunicationAddFriend','target_srl',$member_srl), 'cmd_add_friend', './modules/communication/tpl/images/icon_add_friend.gif', 'popup'); + } + } +?> diff --git a/addons/member_extra_info/conf/info.xml b/addons/member_extra_info/conf/info.xml index 9e7ea28d5..9a82ec315 100644 --- a/addons/member_extra_info/conf/info.xml +++ b/addons/member_extra_info/conf/info.xml @@ -1,53 +1,53 @@ - - - 회원 확장 정보 출력 - 会員情報拡張表示 - 用户扩展信息 - Extra Member Info - Bổ xung thông tin thành viên - 회원 확장 정보 출력 - 회원 확장 정보 출력 - Экстраинформация о пользователях - 用戶延伸資料 - - 회원이 등록한 이미지이름, 이미지마크를 사용하기 위해서는 이 애드온을 활성화 시키세요. - - - 会員が登録したイメージニックネーム、イメージマークを使うためにはこのアドオンをオンにして下さい。 - - - 此插件将把用户信息中的昵称图片,用户图标,签名等信息显示到页面当中。 - - - This addon displays a member's image name, image mark. - - - Addon này sẽ hiển thị hình ảnh thay thế tên và hình đánh dấu của thành viên. - - - This addon displays a member's image name, image mark. - - - This addon displays a member's image name, image mark. - - - Аддон изображает имя, марку картинки пользователя. - - - 可將用戶資料中的暱稱圖片、用戶圖示、簽名檔等資料顯示到頁面當中。 - - 0.2 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 회원 확장 정보 출력 + 会員情報拡張表示 + 用户扩展信息 + Extra Member Info + Bổ xung thông tin thành viên + 회원 확장 정보 출력 + 회원 확장 정보 출력 + Экстраинформация о пользователях + 用戶延伸資料 + + 회원이 등록한 이미지이름, 이미지마크를 사용하기 위해서는 이 애드온을 활성화 시키세요. + + + 会員が登録したイメージニックネーム、イメージマークを使うためにはこのアドオンをオンにして下さい。 + + + 此插件将把用户信息中的昵称图片,用户图标,签名等信息显示到页面当中。 + + + This addon displays a member's image name, image mark. + + + Addon này sẽ hiển thị hình ảnh thay thế tên và hình đánh dấu của thành viên. + + + This addon displays a member's image name, image mark. + + + This addon displays a member's image name, image mark. + + + Аддон изображает имя, марку картинки пользователя. + + + 可將用戶資料中的暱稱圖片、用戶圖示、簽名檔等資料顯示到頁面當中。 + + 0.2 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/member_extra_info/member_extra_info.addon.php b/addons/member_extra_info/member_extra_info.addon.php index c20c14e77..585cc3f86 100644 --- a/addons/member_extra_info/member_extra_info.addon.php +++ b/addons/member_extra_info/member_extra_info.addon.php @@ -1,23 +1,23 @@ -.... 로 정의가 된 부분을 찾아 회원번호를 구해서 - * 이미지이름, 이미지마크가 있는지를 확인하여 있으면 내용을 변경해버립니다. - **/ - - /** - * 출력되기 바로 직전일 경우에 이미지이름/이미지마크등을 변경 - **/ - if($called_position != "before_display_content" || Context::get('act')=='dispPageAdminContentModify') return; - - // 회원 이미지이름/ 마크/ 찾아서 대체할 함수를 담고 있는 파일을 include - require_once('./addons/member_extra_info/member_extra_info.lib.php'); - - // 1. 출력문서중에서
content
를 찾아 MemberController::transImageName() 를 이용하여 이미지이름/마크로 변경 - $output = preg_replace_callback('!<(div|span|a)([^\>]*)member_([0-9]+)([^\>]*)>(.*?)\<\/(div|span|a)\>!is', 'memberTransImageName', $output); -?> +.... 로 정의가 된 부분을 찾아 회원번호를 구해서 + * 이미지이름, 이미지마크가 있는지를 확인하여 있으면 내용을 변경해버립니다. + **/ + + /** + * 출력되기 바로 직전일 경우에 이미지이름/이미지마크등을 변경 + **/ + if($called_position != "before_display_content" || Context::get('act')=='dispPageAdminContentModify') return; + + // 회원 이미지이름/ 마크/ 찾아서 대체할 함수를 담고 있는 파일을 include + require_once('./addons/member_extra_info/member_extra_info.lib.php'); + + // 1. 출력문서중에서
content
를 찾아 MemberController::transImageName() 를 이용하여 이미지이름/마크로 변경 + $output = preg_replace_callback('!<(div|span|a)([^\>]*)member_([0-9]+)([^\>]*)>(.*?)\<\/(div|span|a)\>!is', 'memberTransImageName', $output); +?> diff --git a/addons/mobile/classes/hdml.class.php b/addons/mobile/classes/hdml.class.php index 24a51a440..1c3ee4262 100644 --- a/addons/mobile/classes/hdml.class.php +++ b/addons/mobile/classes/hdml.class.php @@ -1,103 +1,103 @@ - - **/ - class wap extends mobileXE { - - /** - * @brief constructor - **/ - function wap() { - parent::mobileXE(); - } - - /** - * @brief hdml 헤더 출력 - **/ - function printHeader() { - header("Content-Type:text/x-hdml; charset=".$this->charset); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - - print ''; - print "\n"; - print $this->hasChilds()?'':''; - print "\n"; - - if($this->upperUrl) { - $url = $this->upperUrl; - printf('%s', $url->url, $url->text, "\n"); - } - } - - /** - * @brief 제목을 출력 - **/ - function printTitle() { - if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); - printf('<%s%s>%s', $this->title,$titlePageStr,"\n"); - } - - /** - * @brief 내용을 출력 - * hasChilds()가 있으면 목록형을 그렇지 않으면 컨텐츠를 출력 - **/ - function printContent() { - if($this->hasChilds()) { - foreach($this->getChilds() as $key => $val) { - if(!$val['link']) continue; - printf('%s%s',Context::getLang('cmd_select'), $val['href'], $val['text'], "\n"); - } - } else { - printf('%s
%s', $this->getContent(),"\n"); - } - } - - /** - * @brief 버튼을 출력함 - **/ - function printBtn() { - // 메뉴 형식 - if($this->hasChilds()) { - if($this->nextUrl) { - $url = $this->nextUrl; - printf('%s%s', $url->text, $url->url, $url->text, "\n"); - } - if($this->prevUrl) { - $url = $this->prevUrl; - printf('%s%s', $url->text, $url->url, $url->text, "\n"); - } - if($this->homeUrl) { - $url = $this->homeUrl; - printf('%s%s', $url->text, $url->url, $url->text, "\n"); - } - // 컨텐츠 형식 - } else { - if($this->nextUrl) { - $url = $this->nextUrl; - printf('%s', $url->text, $url->url, $url->text); - } - if($this->prevUrl) { - $url = $this->prevUrl; - printf('%s', $url->text, $url->url, $url->text); - } - if($this->homeUrl) { - $url = $this->homeUrl; - printf('%s', $url->text, $url->url, $url->text); - } - } - } - - /** - * @brief 푸터 정보를 출력 - **/ - function printFooter() { - print $this->hasChilds()?'
':''; - print "\n"; - print("
"); - } - - } -?> +charset); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + + print ''; + print "\n"; + print $this->hasChilds()?'':''; + print "\n"; + + if($this->upperUrl) { + $url = $this->upperUrl; + printf('%s', $url->url, $url->text, "\n"); + } + } + + /** + * @brief 제목을 출력 + **/ + function printTitle() { + if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); + printf('<%s%s>%s', $this->title,$titlePageStr,"\n"); + } + + /** + * @brief 내용을 출력 + * hasChilds()가 있으면 목록형을 그렇지 않으면 컨텐츠를 출력 + **/ + function printContent() { + if($this->hasChilds()) { + foreach($this->getChilds() as $key => $val) { + if(!$val['link']) continue; + printf('%s%s',Context::getLang('cmd_select'), $val['href'], $val['text'], "\n"); + } + } else { + printf('%s
%s', $this->getContent(),"\n"); + } + } + + /** + * @brief 버튼을 출력함 + **/ + function printBtn() { + // 메뉴 형식 + if($this->hasChilds()) { + if($this->nextUrl) { + $url = $this->nextUrl; + printf('%s%s', $url->text, $url->url, $url->text, "\n"); + } + if($this->prevUrl) { + $url = $this->prevUrl; + printf('%s%s', $url->text, $url->url, $url->text, "\n"); + } + if($this->homeUrl) { + $url = $this->homeUrl; + printf('%s%s', $url->text, $url->url, $url->text, "\n"); + } + // 컨텐츠 형식 + } else { + if($this->nextUrl) { + $url = $this->nextUrl; + printf('%s', $url->text, $url->url, $url->text); + } + if($this->prevUrl) { + $url = $this->prevUrl; + printf('%s', $url->text, $url->url, $url->text); + } + if($this->homeUrl) { + $url = $this->homeUrl; + printf('%s', $url->text, $url->url, $url->text); + } + } + } + + /** + * @brief 푸터 정보를 출력 + **/ + function printFooter() { + print $this->hasChilds()?'
':''; + print "\n"; + print("
"); + } + + } +?> diff --git a/addons/mobile/classes/mhtml.class.php b/addons/mobile/classes/mhtml.class.php index 185bf2da5..5b1b55ce6 100644 --- a/addons/mobile/classes/mhtml.class.php +++ b/addons/mobile/classes/mhtml.class.php @@ -1,82 +1,82 @@ - / lang_select : misol - **/ - class wap extends mobileXE { - - /** - * @brief constructor - **/ - function wap() { - parent::mobileXE(); - } - - /** - * @brief hdml 헤더 출력 - **/ - function printHeader() { - print("\n"); - if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); - printf("%s%s\n", htmlspecialchars($this->title),htmlspecialchars($titlePageStr)); - } - - // 제목을 출력 - function printTitle() { - if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); - printf('<%s%s>
%s', htmlspecialchars($this->title),htmlspecialchars($titlePageStr),"\n"); - } - - /** - * @brief 내용을 출력 - * hasChilds()가 있으면 목록형을 그렇지 않으면 컨텐츠를 출력 - **/ - function printContent() { - if($this->hasChilds()) { - foreach($this->getChilds() as $key => $val) { - if(!$val['link']) continue; - printf('%s
%s', $val['href'], $this->getNo(), $val['text'], "\n"); - if($val['extra']) printf("
%s\n",str_replace('
','
',$val['extra'])); - } - } else { - print(str_replace('
','
',$this->getContent())."\n"); - } - print "

"; - } - - /** - * @brief 버튼을 출력함 - **/ - function printBtn() { - if($this->nextUrl) { - $url = $this->nextUrl; - printf('%s
%s', $url->url, $url->text, "\n"); - } - if($this->prevUrl) { - $url = $this->prevUrl; - printf('%s
%s', $url->url, $url->text, "\n"); - } - // 언어선택 - if(!parent::isLangChange()){ - $url = getUrl('','lcm','1','sel_lang',Context::getLangType(),'return_uri',Context::get('current_url')); - printf('%s
%s', $url, 'Language : '.Context::getLang('select_lang'), "\n"); - } - else { - printf('%s
%s', Context::get('return_uri'), Context::getLang('lang_return'), "\n"); - } - if($this->upperUrl) { - $url = $this->upperUrl; - printf('%s', $url->url, $url->text, "\n"); - } - if($this->homeUrl) { - $url = $this->homeUrl; - printf('%s
%s', $url->text, $url->url, $url->text, "\n"); - } - } - - // 푸터 정보를 출력 - function printFooter() { - print("\n"); - } - } -?> +\n"); + if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); + printf("%s%s\n", htmlspecialchars($this->title),htmlspecialchars($titlePageStr)); + } + + // 제목을 출력 + function printTitle() { + if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); + printf('<%s%s>
%s', htmlspecialchars($this->title),htmlspecialchars($titlePageStr),"\n"); + } + + /** + * @brief 내용을 출력 + * hasChilds()가 있으면 목록형을 그렇지 않으면 컨텐츠를 출력 + **/ + function printContent() { + if($this->hasChilds()) { + foreach($this->getChilds() as $key => $val) { + if(!$val['link']) continue; + printf('%s
%s', $val['href'], $this->getNo(), $val['text'], "\n"); + if($val['extra']) printf("
%s\n",str_replace('
','
',$val['extra'])); + } + } else { + print(str_replace('
','
',$this->getContent())."\n"); + } + print "

"; + } + + /** + * @brief 버튼을 출력함 + **/ + function printBtn() { + if($this->nextUrl) { + $url = $this->nextUrl; + printf('%s
%s', $url->url, $url->text, "\n"); + } + if($this->prevUrl) { + $url = $this->prevUrl; + printf('%s
%s', $url->url, $url->text, "\n"); + } + // 언어선택 + if(!parent::isLangChange()){ + $url = getUrl('','lcm','1','sel_lang',Context::getLangType(),'return_uri',Context::get('current_url')); + printf('%s
%s', $url, 'Language : '.Context::getLang('select_lang'), "\n"); + } + else { + printf('%s
%s', Context::get('return_uri'), Context::getLang('lang_return'), "\n"); + } + if($this->upperUrl) { + $url = $this->upperUrl; + printf('%s', $url->url, $url->text, "\n"); + } + if($this->homeUrl) { + $url = $this->homeUrl; + printf('%s
%s', $url->text, $url->url, $url->text, "\n"); + } + } + + // 푸터 정보를 출력 + function printFooter() { + print("\n"); + } + } +?> diff --git a/addons/mobile/classes/mobile.class.php b/addons/mobile/classes/mobile.class.php index 1e26399b0..e6f7f6435 100644 --- a/addons/mobile/classes/mobile.class.php +++ b/addons/mobile/classes/mobile.class.php @@ -1,7 +1,7 @@ / lang_select : misol + * @author NHN (developers@xpressengine.com) / lang_select : misol * @brief WAP 태그 출력을 위한 XE 라이브러리 **/ diff --git a/addons/mobile/classes/wml.class.php b/addons/mobile/classes/wml.class.php index 2d9c8821e..08103b37c 100644 --- a/addons/mobile/classes/wml.class.php +++ b/addons/mobile/classes/wml.class.php @@ -1,106 +1,106 @@ - / lang_select : misol - **/ - class wap extends mobileXE { - - /** - * @brief constructor - **/ - function wap() { - parent::mobileXE(); - } - - /** - * @brief wml 헤더 출력 - **/ - function printHeader() { - header("Content-Type: text/vnd.wap.wml"); - header("charset: ".$this->charset); - if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); - print("charset."\"?>\n"); - // 카드제목 - printf("\n\n

\n",htmlspecialchars($this->title),htmlspecialchars($titlePageStr)); - } - - /** - * @brief 제목을 출력 - **/ - function printTitle() { - if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); - printf('<%s%s>
%s', htmlspecialchars($this->title),htmlspecialchars($titlePageStr),"\n"); - } - - /** - * @brief 내용을 출력 - * hasChilds()가 있으면 목록형을 그렇지 않으면 컨텐츠를 출력 - **/ - function printContent() { - if($this->hasChilds()) { - foreach($this->getChilds() as $key => $val) { - if(!$val['link']) continue; - printf('%s', $this->getNo(), htmlspecialchars($val['text']), $val['href'], "\n"); - if($val['extra']) printf("%s\n",$val['extra']); - } - } else { - printf('%s
%s', str_replace("
","
",$this->getContent()),"\n"); - } - print('
'); - } - - /** - * @brief 버튼을 출력함 - **/ - function printBtn() { - if($this->nextUrl) { - $url = $this->nextUrl; - printf('%s', $url->text, $url->url, "\n"); - } - if($this->prevUrl) { - $url = $this->prevUrl; - printf('%s', $url->text, $url->url, "\n"); - } - // 기타 해당사항 없는 버튼 출력 담당 (array로 전달) type?? - if($this->etcBtn) { - if(is_array($this->etcBtn)) { - foreach($this->etcBtn as $key=>$val) { - printf('%s', $key, $val['text'], $val['url'], "\n"); - } - } - } - // 언어선택 - if(!parent::isLangChange()){ - $url = getUrl('','lcm','1','sel_lang',Context::getLangType(),'return_uri',Context::get('current_url')); - printf('%s', 'Language : '.Context::getLang('select_lang'), $url, "\n"); - } - else { - printf('%s', Context::getLang('lang_return'), Context::get('return_uri'), "\n"); - } - if($this->homeUrl) { - $url = $this->homeUrl; - printf('%s', $url->text, $url->url, "\n"); - } - if($this->upperUrl) { - $url = $this->upperUrl; - printf('%s', $url->text, $url->url, "\n"); - } - } - - // 푸터 정보를 출력 - function printFooter() { - print("

\n
\n
"); - } - - // 목록등에서 일련 번호를 리턴한다 - function getNo() { - if(Context::get('mobile_skt')==1) { - return "vnd.skmn".parent::getNo(); - } - else { - return parent::getNo(); - } - return $str; - } - } -?> +charset); + if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); + print("charset."\"?>\n"); + // 카드제목 + printf("\n\n

\n",htmlspecialchars($this->title),htmlspecialchars($titlePageStr)); + } + + /** + * @brief 제목을 출력 + **/ + function printTitle() { + if($this->totalPage > $this->mobilePage) $titlePageStr = sprintf("(%d/%d)",$this->mobilePage, $this->totalPage); + printf('<%s%s>
%s', htmlspecialchars($this->title),htmlspecialchars($titlePageStr),"\n"); + } + + /** + * @brief 내용을 출력 + * hasChilds()가 있으면 목록형을 그렇지 않으면 컨텐츠를 출력 + **/ + function printContent() { + if($this->hasChilds()) { + foreach($this->getChilds() as $key => $val) { + if(!$val['link']) continue; + printf('%s', $this->getNo(), htmlspecialchars($val['text']), $val['href'], "\n"); + if($val['extra']) printf("%s\n",$val['extra']); + } + } else { + printf('%s
%s', str_replace("
","
",$this->getContent()),"\n"); + } + print('
'); + } + + /** + * @brief 버튼을 출력함 + **/ + function printBtn() { + if($this->nextUrl) { + $url = $this->nextUrl; + printf('%s', $url->text, $url->url, "\n"); + } + if($this->prevUrl) { + $url = $this->prevUrl; + printf('%s', $url->text, $url->url, "\n"); + } + // 기타 해당사항 없는 버튼 출력 담당 (array로 전달) type?? + if($this->etcBtn) { + if(is_array($this->etcBtn)) { + foreach($this->etcBtn as $key=>$val) { + printf('%s', $key, $val['text'], $val['url'], "\n"); + } + } + } + // 언어선택 + if(!parent::isLangChange()){ + $url = getUrl('','lcm','1','sel_lang',Context::getLangType(),'return_uri',Context::get('current_url')); + printf('%s', 'Language : '.Context::getLang('select_lang'), $url, "\n"); + } + else { + printf('%s', Context::getLang('lang_return'), Context::get('return_uri'), "\n"); + } + if($this->homeUrl) { + $url = $this->homeUrl; + printf('%s', $url->text, $url->url, "\n"); + } + if($this->upperUrl) { + $url = $this->upperUrl; + printf('%s', $url->text, $url->url, "\n"); + } + } + + // 푸터 정보를 출력 + function printFooter() { + print("

\n
\n
"); + } + + // 목록등에서 일련 번호를 리턴한다 + function getNo() { + if(Context::get('mobile_skt')==1) { + return "vnd.skmn".parent::getNo(); + } + else { + return parent::getNo(); + } + return $str; + } + } +?> diff --git a/addons/mobile/conf/info.xml b/addons/mobile/conf/info.xml index 4caf59ef8..3dcee3654 100644 --- a/addons/mobile/conf/info.xml +++ b/addons/mobile/conf/info.xml @@ -38,14 +38,14 @@ 0.1.1 2009-05-23 - - zero - zero - zero - zero - zero - zero - zero + + NHN + NHN + NHN + NHN + NHN + NHN + NHN diff --git a/addons/mobile/lang/en.lang.php b/addons/mobile/lang/en.lang.php index a0c93fd16..806187185 100644 --- a/addons/mobile/lang/en.lang.php +++ b/addons/mobile/lang/en.lang.php @@ -1,15 +1,15 @@ -president_lang = 'selected Language'; - $lang->select_lang = 'select Language'; - $lang->lang_return = 'Go Back'; - - $lang->cmd_go_upper = 'Upper'; - $lang->cmd_go_home = 'Go Home'; - $lang->cmd_view_sitemap = 'View site map'; -?> +president_lang = 'selected Language'; + $lang->select_lang = 'select Language'; + $lang->lang_return = 'Go Back'; + + $lang->cmd_go_upper = 'Upper'; + $lang->cmd_go_home = 'Go Home'; + $lang->cmd_view_sitemap = 'View site map'; +?> diff --git a/addons/mobile/lang/jp.lang.php b/addons/mobile/lang/jp.lang.php index 3aa8e74e7..d9300e7e6 100644 --- a/addons/mobile/lang/jp.lang.php +++ b/addons/mobile/lang/jp.lang.php @@ -1,17 +1,17 @@ -president_lang = '現在言語'; - $lang->select_lang = '言語選択'; - $lang->lang_return = '戻る'; - - $lang->cmd_go_upper = '上位メニュー'; - $lang->cmd_go_home = 'トップへ'; - $lang->cmd_view_sitemap = 'サイトマップ'; - -?> +president_lang = '現在言語'; + $lang->select_lang = '言語選択'; + $lang->lang_return = '戻る'; + + $lang->cmd_go_upper = '上位メニュー'; + $lang->cmd_go_home = 'トップへ'; + $lang->cmd_view_sitemap = 'サイトマップ'; + +?> diff --git a/addons/mobile/lang/ko.lang.php b/addons/mobile/lang/ko.lang.php index f0b28dc0f..48bf404a0 100644 --- a/addons/mobile/lang/ko.lang.php +++ b/addons/mobile/lang/ko.lang.php @@ -1,17 +1,17 @@ -president_lang = '현재 언어'; - $lang->select_lang = '언어 선택'; - $lang->lang_return = '돌아가기'; - - $lang->cmd_go_upper = '상위'; - $lang->cmd_go_home = '홈으로'; - $lang->cmd_view_sitemap = '사이트맵 보기'; - -?> +president_lang = '현재 언어'; + $lang->select_lang = '언어 선택'; + $lang->lang_return = '돌아가기'; + + $lang->cmd_go_upper = '상위'; + $lang->cmd_go_home = '홈으로'; + $lang->cmd_view_sitemap = '사이트맵 보기'; + +?> diff --git a/addons/mobile/lang/ru.lang.php b/addons/mobile/lang/ru.lang.php index 768d186f8..87cc015cf 100644 --- a/addons/mobile/lang/ru.lang.php +++ b/addons/mobile/lang/ru.lang.php @@ -1,17 +1,17 @@ -president_lang = 'Дейсвующй язык'; - $lang->select_lang = 'Выбор языка'; - $lang->lang_return = 'Вернуться'; - - $lang->cmd_go_upper = 'Вверх'; - $lang->cmd_go_home = 'На главную страницу'; - $lang->cmd_view_sitemap = 'Посмотреть карту сайта'; - -?> +president_lang = 'Дейсвующй язык'; + $lang->select_lang = 'Выбор языка'; + $lang->lang_return = 'Вернуться'; + + $lang->cmd_go_upper = 'Вверх'; + $lang->cmd_go_home = 'На главную страницу'; + $lang->cmd_view_sitemap = 'Посмотреть карту сайта'; + +?> diff --git a/addons/mobile/lang/vi.lang.php b/addons/mobile/lang/vi.lang.php index 489128e2d..1ed1fa8a5 100644 --- a/addons/mobile/lang/vi.lang.php +++ b/addons/mobile/lang/vi.lang.php @@ -1,18 +1,18 @@ -president_lang = 'Chọn ngôn ngữ'; - $lang->select_lang = 'Chọn ngôn ngữ'; - $lang->lang_return = 'Trở lại'; - - $lang->cmd_go_upper = 'Lên trên'; - $lang->cmd_go_home = 'Về trang chủ'; - $lang->cmd_view_sitemap = 'Xem sơ đồ Web'; -?> +president_lang = 'Chọn ngôn ngữ'; + $lang->select_lang = 'Chọn ngôn ngữ'; + $lang->lang_return = 'Trở lại'; + + $lang->cmd_go_upper = 'Lên trên'; + $lang->cmd_go_home = 'Về trang chủ'; + $lang->cmd_view_sitemap = 'Xem sơ đồ Web'; +?> diff --git a/addons/mobile/lang/zh-CN.lang.php b/addons/mobile/lang/zh-CN.lang.php index 6e9b084ed..1610b859f 100644 --- a/addons/mobile/lang/zh-CN.lang.php +++ b/addons/mobile/lang/zh-CN.lang.php @@ -1,11 +1,11 @@ -cmd_go_upper = '上一级'; - $lang->cmd_go_home = '首页'; - $lang->cmd_view_sitemap = '网站地图'; -?> +cmd_go_upper = '上一级'; + $lang->cmd_go_home = '首页'; + $lang->cmd_view_sitemap = '网站地图'; +?> diff --git a/addons/mobile/lang/zh-TW.lang.php b/addons/mobile/lang/zh-TW.lang.php index 13d8df620..6de5fd45e 100644 --- a/addons/mobile/lang/zh-TW.lang.php +++ b/addons/mobile/lang/zh-TW.lang.php @@ -1,15 +1,15 @@ -president_lang = '已選擇語言'; - $lang->select_lang = '選擇語言'; - $lang->lang_return = '返回'; - - $lang->cmd_go_upper = '回上頁'; - $lang->cmd_go_home = '回首頁'; - $lang->cmd_view_sitemap = '網站地圖'; -?> +president_lang = '已選擇語言'; + $lang->select_lang = '選擇語言'; + $lang->lang_return = '返回'; + + $lang->cmd_go_upper = '回上頁'; + $lang->cmd_go_home = '回首頁'; + $lang->cmd_view_sitemap = '網站地圖'; +?> diff --git a/addons/mobile/mobile.addon.php b/addons/mobile/mobile.addon.php index 3c1f2b50b..fd55b714c 100644 --- a/addons/mobile/mobile.addon.php +++ b/addons/mobile/mobile.addon.php @@ -1,61 +1,61 @@ - 모바일 처리를 위해 모듈의 일반 설정을 변경해야 할 경우 호출 - * - * after_module_proc > 모바일 컨텐츠 출력 - * 동작 조건 - **/ - - // 관리자 페이지는 무시 - if(Context::get('module')=='admin') return; - - // 동작 시점 관리 - if($called_position != 'before_module_proc' && $called_position != 'after_module_proc' ) return; - - // 모바일 브라우저가 아니라면 무시 - require_once(_XE_PATH_.'addons/mobile/classes/mobile.class.php'); - if(!mobileXE::getBrowserType()) return; - - // mobile instance 생성 - $oMobile = &mobileXE::getInstance(); - if(!$oMobile) return; - - // 애드온 설정에서 지정된 charset으로 지정 - $oMobile->setCharSet($addon_info->charset); - - // 모듈의 정보를 세팅 - $oMobile->setModuleInfo($this->module_info); - - // 현재 모듈 객체 등록 - $oMobile->setModuleInstance($this); - - // 네비게이트 모드이거나 WAP class가 있을 경우 미리 컨텐츠를 추출하여 출력/ 종료 - if($called_position == 'before_module_proc') { - - if($oMobile->isLangChange()) { - $oMobile->setLangType(); - $oMobile->displayLangSelect(); - } - - // 네비게이트 모드이면 네비게이션 컨텐츠 출력 - if($oMobile->isNavigationMode()) $oMobile->displayNavigationContent(); - - // WAP class가 있으면 WAP class를 통해 컨텐츠 출력 - else $oMobile->displayModuleContent(); - - // 네비게이트 모드가 아니고 WAP 클래스가 아니면 모듈의 결과를 출력 - } else if($called_position == 'after_module_proc') { - // 내용 준비 - $oMobile->displayContent(); - } -?> + 모바일 처리를 위해 모듈의 일반 설정을 변경해야 할 경우 호출 + * + * after_module_proc > 모바일 컨텐츠 출력 + * 동작 조건 + **/ + + // 관리자 페이지는 무시 + if(Context::get('module')=='admin') return; + + // 동작 시점 관리 + if($called_position != 'before_module_proc' && $called_position != 'after_module_proc' ) return; + + // 모바일 브라우저가 아니라면 무시 + require_once(_XE_PATH_.'addons/mobile/classes/mobile.class.php'); + if(!mobileXE::getBrowserType()) return; + + // mobile instance 생성 + $oMobile = &mobileXE::getInstance(); + if(!$oMobile) return; + + // 애드온 설정에서 지정된 charset으로 지정 + $oMobile->setCharSet($addon_info->charset); + + // 모듈의 정보를 세팅 + $oMobile->setModuleInfo($this->module_info); + + // 현재 모듈 객체 등록 + $oMobile->setModuleInstance($this); + + // 네비게이트 모드이거나 WAP class가 있을 경우 미리 컨텐츠를 추출하여 출력/ 종료 + if($called_position == 'before_module_proc') { + + if($oMobile->isLangChange()) { + $oMobile->setLangType(); + $oMobile->displayLangSelect(); + } + + // 네비게이트 모드이면 네비게이션 컨텐츠 출력 + if($oMobile->isNavigationMode()) $oMobile->displayNavigationContent(); + + // WAP class가 있으면 WAP class를 통해 컨텐츠 출력 + else $oMobile->displayModuleContent(); + + // 네비게이트 모드가 아니고 WAP 클래스가 아니면 모듈의 결과를 출력 + } else if($called_position == 'after_module_proc') { + // 내용 준비 + $oMobile->displayContent(); + } +?> diff --git a/addons/openid_delegation_id/conf/info.xml b/addons/openid_delegation_id/conf/info.xml index 887b18ee0..796abb29e 100644 --- a/addons/openid_delegation_id/conf/info.xml +++ b/addons/openid_delegation_id/conf/info.xml @@ -1,125 +1,125 @@ - - - OpenID delegation ID - OpenID - OpenID Delegation ID - OpenID Delegation ID - OpenID Delegation ID - Delegación ID para OpenID - OpenIDアドオン - Открытый ID(OpenID) - OpenID - - 본인의 도메인을 사용하여 오픈아이디로 활용할 수 있도록 합니다. - 꼭 설정을 통해서 openid provider관련 값을 입력후 사용해주세요. - - - 可以把本人的域名当分散式身份验证系统(OpenID)来使用。 - 必须在设置中输入openid provider相关值后再使用。 - - - This addon enables you to use your own domain name as an OpenID. - Just be sure to set the values related with openid provider before using. - - - Addon này cho phép bạn sử dụng tên miền của mình như một OpenID. - Hãy kiểm tra để đặt giá trị liên quan với OpenID trước khi sử dụng. - - - Dieses Addon ermöglicht es Ihnen, mit Ihrem eigenen Domain-Namen als OpenID. - Einfach sicher sein, dass die Werte im Zusammenhang mit OpenID-Provider, bevor Sie. - - - Utlizando su propio dominio puede usar como OpenID. - Debe utilizar luego de ingresar los valores relacionado con openid provider a través de la configuracion. - - - 保有しているオリジナルドメインをオープンIDとして活用することが出来ます。 - 必ず設定にて、OpenIDプロバイダーの関連情報を入力してから使用して下さい。 - - - Этот аддон позволяет Вам использовать Ваше доменное имя как OpenID. - Прежде, чем использовать, установите значения, имеющие отношение к openid-провайдеру . - - - 可將原本的域名當做OpenID來使用。 - 必須在設置中輸入openid provider相關資料後再使用。 - - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - - - - server - server - server - Server - server - Servidor - server - server - server - openid.server 값을 입력해 주세요. - 请输入 openid.server 值。 - Hãy nhập OpenID Server của bạn. - Please input your openid.server value. - Bitte geben Sie Ihre openid.server Wert. - Ingrese el valor del openid.server. - openid.server値を入力して下さい。 - Пожалуйста, введите Ваше значение openid.server - 請輸入 openid.server 值。 - - - delegate - delegate - Delegate - delegate - delegate - delegado - delegate - delegate - delegate - openid.delegate값을 입력해주세요. - 请输入 openid.delegate 值。 - Hãy nhập OpenID Delegate của bạn. - Please input your openid.delegate value. - Bitte geben Sie Ihre openid.delegate Wert. - Ingresar el valor del openid.delegate - openid.delegate値を入力して下さい。 - Пожалуйста, введите Ваше значение openid.delegate - 請輸入 openid.delegate 值。 - - - xrds - xrds - xrds - xrds - xrds - xrds - xrds - xrds - xrds - X-XRDS-Location값을 입력해주세요. - 请输入 X-XRDS-Location 值。 - Please input your X-XRDS-Location value. - Hãy nhập X-XRDS-Location của bạn. - Bitte geben Sie Ihre X-XRDS-Standort Wert. - Ingresar el valor de X-XRDS-Location - X-XRDS-Location値を入力して下さい。 - Пожалуйста, введите Ваше значение X-XRDS-Локации. - 請輸入 X-XRDS-Location 值。 - - - + + + OpenID delegation ID + OpenID + OpenID Delegation ID + OpenID Delegation ID + OpenID Delegation ID + Delegación ID para OpenID + OpenIDアドオン + Открытый ID(OpenID) + OpenID + + 본인의 도메인을 사용하여 오픈아이디로 활용할 수 있도록 합니다. + 꼭 설정을 통해서 openid provider관련 값을 입력후 사용해주세요. + + + 可以把本人的域名当分散式身份验证系统(OpenID)来使用。 + 必须在设置中输入openid provider相关值后再使用。 + + + This addon enables you to use your own domain name as an OpenID. + Just be sure to set the values related with openid provider before using. + + + Addon này cho phép bạn sử dụng tên miền của mình như một OpenID. + Hãy kiểm tra để đặt giá trị liên quan với OpenID trước khi sử dụng. + + + Dieses Addon ermöglicht es Ihnen, mit Ihrem eigenen Domain-Namen als OpenID. + Einfach sicher sein, dass die Werte im Zusammenhang mit OpenID-Provider, bevor Sie. + + + Utlizando su propio dominio puede usar como OpenID. + Debe utilizar luego de ingresar los valores relacionado con openid provider a través de la configuracion. + + + 保有しているオリジナルドメインをオープンIDとして活用することが出来ます。 + 必ず設定にて、OpenIDプロバイダーの関連情報を入力してから使用して下さい。 + + + Этот аддон позволяет Вам использовать Ваше доменное имя как OpenID. + Прежде, чем использовать, установите значения, имеющие отношение к openid-провайдеру . + + + 可將原本的域名當做OpenID來使用。 + 必須在設置中輸入openid provider相關資料後再使用。 + + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + + + + server + server + server + Server + server + Servidor + server + server + server + openid.server 값을 입력해 주세요. + 请输入 openid.server 值。 + Hãy nhập OpenID Server của bạn. + Please input your openid.server value. + Bitte geben Sie Ihre openid.server Wert. + Ingrese el valor del openid.server. + openid.server値を入力して下さい。 + Пожалуйста, введите Ваше значение openid.server + 請輸入 openid.server 值。 + + + delegate + delegate + Delegate + delegate + delegate + delegado + delegate + delegate + delegate + openid.delegate값을 입력해주세요. + 请输入 openid.delegate 值。 + Hãy nhập OpenID Delegate của bạn. + Please input your openid.delegate value. + Bitte geben Sie Ihre openid.delegate Wert. + Ingresar el valor del openid.delegate + openid.delegate値を入力して下さい。 + Пожалуйста, введите Ваше значение openid.delegate + 請輸入 openid.delegate 值。 + + + xrds + xrds + xrds + xrds + xrds + xrds + xrds + xrds + xrds + X-XRDS-Location값을 입력해주세요. + 请输入 X-XRDS-Location 值。 + Please input your X-XRDS-Location value. + Hãy nhập X-XRDS-Location của bạn. + Bitte geben Sie Ihre X-XRDS-Standort Wert. + Ingresar el valor de X-XRDS-Location + X-XRDS-Location値を入力して下さい。 + Пожалуйста, введите Ваше значение X-XRDS-Локации. + 請輸入 X-XRDS-Location 值。 + + + diff --git a/addons/openid_delegation_id/openid_delegation_id.addon.php b/addons/openid_delegation_id/openid_delegation_id.addon.php index ee53bc75a..aa5a373dd 100644 --- a/addons/openid_delegation_id/openid_delegation_id.addon.php +++ b/addons/openid_delegation_id/openid_delegation_id.addon.php @@ -1,29 +1,29 @@ -server||!$addon_info->delegate||!$addon_info->xrds) return; - - $header_script = sprintf( - ''."\n". - ''."\n". - '', - $addon_info->server, - $addon_info->delegate, - $addon_info->xrds - ); - - Context::addHtmlHeader($header_script); -?> +server||!$addon_info->delegate||!$addon_info->xrds) return; + + $header_script = sprintf( + ''."\n". + ''."\n". + '', + $addon_info->server, + $addon_info->delegate, + $addon_info->xrds + ); + + Context::addHtmlHeader($header_script); +?> diff --git a/addons/point_level_icon/conf/info.xml b/addons/point_level_icon/conf/info.xml index 07c503216..adde6ae69 100644 --- a/addons/point_level_icon/conf/info.xml +++ b/addons/point_level_icon/conf/info.xml @@ -1,62 +1,62 @@ - - - 포인트 레벨 아이콘 표시 애드온 - 积分级别图标 - ポイントレベルアイコン表示アドオン - Point Level Icon - Icon cấp độ của điểm - Point-Level-Symbol - Addon para mostar el nivel del ícono - Иконка уровня поинтов - 點數等級圖案 - - 포인트 시스템을 사용중일 경우 사용자 이름 앞에 레벨 아이콘을 표시하도록 합니다. - 레벨 아이콘은 모듈 > 포인트시스템에서 선택 가능합니다. - - - 使用积分系统时,可以在用户名前显示级别图标。 - 级别图标可以在模块 > 积分系统中进行选择。 - - - ポイントシステムを使用する場合、ユーザ名の前にレベルアイコンの表示します。 - レベルアイコンは、「モジュール > ポイントシステム」で選択します。 - - - This addon displays level icon in front of the user name when you are using the point system. - You can choose the level icon in Module > Point System. - - - Addon này sẽ hiển thị Icon cấp độ trước tên người sử dụng khi bạn sử dụng hệ thống tính điểm. - Bạn có thể chọn Icon cấp độ tại Module > cỉa hệ thống điểm. - - - Dieses Addon zeigt Level Icon vor dem Benutzernamen, wenn Sie die Punkte-System. - Sie können wählen, der Level Icon in Modul> Point-System. - - - Este addon muestra el nivel del ícono delante del nombre del usuario cuando es usado el sistema de puntos. - Tu puedes elegir los icono de cada nivel en el módulo > Sistema de Puntos. - - - Этот аддон отображает иконку уровня поинтов напротив имени пользователя, когда используется система поинтов. - Вы можете выбрать иконку уровня в Модуле Системы Поинтов. - - - 使用點數系統時,可以在用戶名前顯示等級圖案。 - 等級圖案可以在模組 > 點數系統中進行選擇。 - - 0.1 - 2007-07-26 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 포인트 레벨 아이콘 표시 애드온 + 积分级别图标 + ポイントレベルアイコン表示アドオン + Point Level Icon + Icon cấp độ của điểm + Point-Level-Symbol + Addon para mostar el nivel del ícono + Иконка уровня поинтов + 點數等級圖案 + + 포인트 시스템을 사용중일 경우 사용자 이름 앞에 레벨 아이콘을 표시하도록 합니다. + 레벨 아이콘은 모듈 > 포인트시스템에서 선택 가능합니다. + + + 使用积分系统时,可以在用户名前显示级别图标。 + 级别图标可以在模块 > 积分系统中进行选择。 + + + ポイントシステムを使用する場合、ユーザ名の前にレベルアイコンの表示します。 + レベルアイコンは、「モジュール > ポイントシステム」で選択します。 + + + This addon displays level icon in front of the user name when you are using the point system. + You can choose the level icon in Module > Point System. + + + Addon này sẽ hiển thị Icon cấp độ trước tên người sử dụng khi bạn sử dụng hệ thống tính điểm. + Bạn có thể chọn Icon cấp độ tại Module > cỉa hệ thống điểm. + + + Dieses Addon zeigt Level Icon vor dem Benutzernamen, wenn Sie die Punkte-System. + Sie können wählen, der Level Icon in Modul> Point-System. + + + Este addon muestra el nivel del ícono delante del nombre del usuario cuando es usado el sistema de puntos. + Tu puedes elegir los icono de cada nivel en el módulo > Sistema de Puntos. + + + Этот аддон отображает иконку уровня поинтов напротив имени пользователя, когда используется система поинтов. + Вы можете выбрать иконку уровня в Модуле Системы Поинтов. + + + 使用點數系統時,可以在用戶名前顯示等級圖案。 + 等級圖案可以在模組 > 點數系統中進行選擇。 + + 0.1 + 2007-07-26 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/point_level_icon/point_level_icon.addon.php b/addons/point_level_icon/point_level_icon.addon.php index 0e2edcefe..bbf847334 100644 --- a/addons/point_level_icon/point_level_icon.addon.php +++ b/addons/point_level_icon/point_level_icon.addon.php @@ -1,19 +1,19 @@ -]*)member_([0-9\-]+)([^\>]*)>(.*?)\<\/(div|span|a)\>!is', 'pointLevelIconTrans', $output); -?> +]*)member_([0-9\-]+)([^\>]*)>(.*?)\<\/(div|span|a)\>!is', 'pointLevelIconTrans', $output); +?> diff --git a/addons/resize_image/conf/info.xml b/addons/resize_image/conf/info.xml index 47f96b4f2..b16c38058 100644 --- a/addons/resize_image/conf/info.xml +++ b/addons/resize_image/conf/info.xml @@ -1,53 +1,53 @@ - - - 본문내 이미지 조절 애드온 - 本文内イメージリーサイズアドオン - 内容区图片缩放插件 - Image Resizer - Thay đổi cỡ hình ảnh - Imagen de control add-on bonmunnae - Аддон редактирования размера картинки в тексте - Image-Add-on bonmunnae - 圖片縮放 - - 본문내에 삽입된 이미지의 크기를 본문크기에 맞게 하고 클릭시 원본을 보여주는 애드온입니다. - - - 本文内に挿入されたイメージのサイズを本文の幅サイズに合わせてリーサイズし、クリックした時、オリジナルサイズのイメージを表示します。 - - - 自动调整主题内容区内的图片大小,点击将显示原始大小的插件。 - - - Addon này sẽ lấy lại kích thước nguyên bản của hình ảnh trong bài viết hoặc bình luận khi bạn bấm vào hình. - - - This addon resizes images inserted in the article, and shows original image when you click on them. - - - La imagen corporal se inserta dentro del cuerpo para que se adapte al tamaño de la muestra original cuando hago clic en los add-ons. - - - Аддон, изменяющий размер картинки к размеру текста, при клике на картинку, появляется полное изображение. - - - Body Bild eingefügt im Inneren des Körpers zu passen die Größe des Originals zeigen, wenn ich darauf klicke auf das Add-ons. - - - 自動調整文章内的圖片大小,點擊圖片後會顯示原始大小。 - - 0.1 - 2008-04-22 - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 본문내 이미지 조절 애드온 + 本文内イメージリーサイズアドオン + 内容区图片缩放插件 + Image Resizer + Thay đổi cỡ hình ảnh + Imagen de control add-on bonmunnae + Аддон редактирования размера картинки в тексте + Image-Add-on bonmunnae + 圖片縮放 + + 본문내에 삽입된 이미지의 크기를 본문크기에 맞게 하고 클릭시 원본을 보여주는 애드온입니다. + + + 本文内に挿入されたイメージのサイズを本文の幅サイズに合わせてリーサイズし、クリックした時、オリジナルサイズのイメージを表示します。 + + + 自动调整主题内容区内的图片大小,点击将显示原始大小的插件。 + + + Addon này sẽ lấy lại kích thước nguyên bản của hình ảnh trong bài viết hoặc bình luận khi bạn bấm vào hình. + + + This addon resizes images inserted in the article, and shows original image when you click on them. + + + La imagen corporal se inserta dentro del cuerpo para que se adapte al tamaño de la muestra original cuando hago clic en los add-ons. + + + Аддон, изменяющий размер картинки к размеру текста, при клике на картинку, появляется полное изображение. + + + Body Bild eingefügt im Inneren des Körpers zu passen die Größe des Originals zeigen, wenn ich darauf klicke auf das Add-ons. + + + 自動調整文章内的圖片大小,點擊圖片後會顯示原始大小。 + + 0.1 + 2008-04-22 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/addons/resize_image/resize_image.addon.php b/addons/resize_image/resize_image.addon.php index 2d127dfe6..447d377fa 100644 --- a/addons/resize_image/resize_image.addon.php +++ b/addons/resize_image/resize_image.addon.php @@ -1,14 +1,14 @@ - \ No newline at end of file diff --git a/classes/cache/CacheApc.class.php b/classes/cache/CacheApc.class.php index 3567b1fbe..84b6c88fc 100644 --- a/classes/cache/CacheApc.class.php +++ b/classes/cache/CacheApc.class.php @@ -1,72 +1,72 @@ -valid_time; - return apc_store(md5(_XE_PATH_.$key), array(time(), $buff), $valid_time); - } - - function isValid($key, $modified_time = 0) { - $_key = md5(_XE_PATH_.$key); - $obj = apc_fetch($_key, $success); - if(!$success || !is_array($obj)) return false; - unset($obj[1]); - - if($modified_time > 0 && $modified_time > $obj[0]) { - $this->_delete($_key); - return false; - } - - return true; - } - - function get($key, $modified_time = 0) { - $_key = md5(_XE_PATH_.$key); - $obj = apc_fetch($_key, $success); - if(!$success || !is_array($obj)) return false; - - if($modified_time > 0 && $modified_time > $obj[0]) { - $this->_delete($_key); - return false; - } - - return $obj[1]; - } - - function _delete($_key) { - $this->put($_key,null,1); - } - - function delete($key) { - $this->_delete(md5(_XE_PATH_.$key)); - } - - function truncate() { - return apc_clear_cache('user'); - } - } -?> +valid_time; + return apc_store(md5(_XE_PATH_.$key), array(time(), $buff), $valid_time); + } + + function isValid($key, $modified_time = 0) { + $_key = md5(_XE_PATH_.$key); + $obj = apc_fetch($_key, $success); + if(!$success || !is_array($obj)) return false; + unset($obj[1]); + + if($modified_time > 0 && $modified_time > $obj[0]) { + $this->_delete($_key); + return false; + } + + return true; + } + + function get($key, $modified_time = 0) { + $_key = md5(_XE_PATH_.$key); + $obj = apc_fetch($_key, $success); + if(!$success || !is_array($obj)) return false; + + if($modified_time > 0 && $modified_time > $obj[0]) { + $this->_delete($_key); + return false; + } + + return $obj[1]; + } + + function _delete($_key) { + $this->put($_key,null,1); + } + + function delete($key) { + $this->_delete(md5(_XE_PATH_.$key)); + } + + function truncate() { + return apc_clear_cache('user'); + } + } +?> diff --git a/classes/cache/CacheHandler.class.php b/classes/cache/CacheHandler.class.php index 65f71591c..4ca454a4e 100644 --- a/classes/cache/CacheHandler.class.php +++ b/classes/cache/CacheHandler.class.php @@ -1,95 +1,95 @@ -use_object_cache =='apc') $type = 'apc'; - else if(substr($info->use_object_cache,0,8)=='memcache'){ - $type = 'memcache'; - $url = $info->use_object_cache; - } - }else if($target == 'template'){ - if($info->use_template_cache =='apc') $type = 'apc'; - else if(substr($info->use_template_cache,0,8)=='memcache'){ - $type = 'memcache'; - $url = $info->use_template_cache; - } - } - - if($type){ - $class = 'Cache' . ucfirst($type); - include_once sprintf('%sclasses/cache/%s.class.php', _XE_PATH_, $class); - $this->handler = call_user_func(array($class,'getInstance'), $url); - } - } - } - - function isSupport(){ - if($this->handler && $this->handler->isSupport()) return true; - return false; - } - - function get($key, $modified_time = 0){ - if(!$this->handler) return false; - return $this->handler->get($key, $modified_time); - } - - function put($key, $obj, $valid_time = 0){ - if(!$this->handler) return false; - return $this->handler->put($key, $obj, $valid_time); - } - - function delete($key){ - if(!$this->handler) return false; - return $this->handler->delete($key); - } - - function isValid($key, $modified_time){ - if(!$this->handler) return false; - return $this->handler->isValid($key, $modified_time); - } - - function truncate(){ - if(!$this->handler) return false; - return $this->handler->truncate(); - } - } - - class CacheBase{ - function get($key, $modified_time = 0){ - return false; - } - - function put($key, $obj, $valid_time = 0){ - return false; - } - - function isValid($key, $modified_time = 0){ - return false; - } - - function isSupport(){ - return false; - } - - function truncate(){ - return false; - } - } -?> +use_object_cache =='apc') $type = 'apc'; + else if(substr($info->use_object_cache,0,8)=='memcache'){ + $type = 'memcache'; + $url = $info->use_object_cache; + } + }else if($target == 'template'){ + if($info->use_template_cache =='apc') $type = 'apc'; + else if(substr($info->use_template_cache,0,8)=='memcache'){ + $type = 'memcache'; + $url = $info->use_template_cache; + } + } + + if($type){ + $class = 'Cache' . ucfirst($type); + include_once sprintf('%sclasses/cache/%s.class.php', _XE_PATH_, $class); + $this->handler = call_user_func(array($class,'getInstance'), $url); + } + } + } + + function isSupport(){ + if($this->handler && $this->handler->isSupport()) return true; + return false; + } + + function get($key, $modified_time = 0){ + if(!$this->handler) return false; + return $this->handler->get($key, $modified_time); + } + + function put($key, $obj, $valid_time = 0){ + if(!$this->handler) return false; + return $this->handler->put($key, $obj, $valid_time); + } + + function delete($key){ + if(!$this->handler) return false; + return $this->handler->delete($key); + } + + function isValid($key, $modified_time){ + if(!$this->handler) return false; + return $this->handler->isValid($key, $modified_time); + } + + function truncate(){ + if(!$this->handler) return false; + return $this->handler->truncate(); + } + } + + class CacheBase{ + function get($key, $modified_time = 0){ + return false; + } + + function put($key, $obj, $valid_time = 0){ + return false; + } + + function isValid($key, $modified_time = 0){ + return false; + } + + function isSupport(){ + return false; + } + + function truncate(){ + return false; + } + } +?> diff --git a/classes/cache/CacheMemcache.class.php b/classes/cache/CacheMemcache.class.php index cd45c0eca..6ce27624c 100644 --- a/classes/cache/CacheMemcache.class.php +++ b/classes/cache/CacheMemcache.class.php @@ -1,91 +1,91 @@ -Memcache = new Memcache; - - foreach($config['url'] as $url) { - $info = parse_url($url); - $this->Memcache->addServer($info['host'], $info['port']); - } - } - - function isSupport(){ - return $this->Memcache->set('xe', 'xe', MEMCACHE_COMPRESSED, 1); - } - - function getKey($key){ - return md5(_XE_PATH_.$key); - } - - function put($key, $buff, $valid_time = 0){ - if($valid_time == 0) $valid_time = $this->valid_time; - - return $this->Memcache->set($this->getKey($key), array(time(), $buff), MEMCACHE_COMPRESSED, $valid_time); - } - - function isValid($key, $modified_time = 0) { - $_key = $this->getKey($key); - - $obj = $this->Memcache->get($_key); - if(!$obj || !is_array($obj)) return false; - unset($obj[1]); - - if($modified_time > 0 && $modified_time > $obj[0]) { - $this->_delete($_key); - return false; - } - - return true; - } - - function get($key, $modified_time = 0) { - $_key = $this->getKey($key); - $obj = $this->Memcache->get($_key); - if(!$obj || !is_array($obj)) return false; - - if($modified_time > 0 && $modified_time > $obj[0]) { - $this->_delete($_key); - return false; - } - - unset($obj[0]); - - return $obj[1]; - } - - function delete($key) { - $_key = $this->getKey($key); - $this->_delete($_key); - } - - function _delete($_key) { - $this->Memcache->delete($_key); - } - - function truncate() { - // not support memcached - return false; - } - } -?> +Memcache = new Memcache; + + foreach($config['url'] as $url) { + $info = parse_url($url); + $this->Memcache->addServer($info['host'], $info['port']); + } + } + + function isSupport(){ + return $this->Memcache->set('xe', 'xe', MEMCACHE_COMPRESSED, 1); + } + + function getKey($key){ + return md5(_XE_PATH_.$key); + } + + function put($key, $buff, $valid_time = 0){ + if($valid_time == 0) $valid_time = $this->valid_time; + + return $this->Memcache->set($this->getKey($key), array(time(), $buff), MEMCACHE_COMPRESSED, $valid_time); + } + + function isValid($key, $modified_time = 0) { + $_key = $this->getKey($key); + + $obj = $this->Memcache->get($_key); + if(!$obj || !is_array($obj)) return false; + unset($obj[1]); + + if($modified_time > 0 && $modified_time > $obj[0]) { + $this->_delete($_key); + return false; + } + + return true; + } + + function get($key, $modified_time = 0) { + $_key = $this->getKey($key); + $obj = $this->Memcache->get($_key); + if(!$obj || !is_array($obj)) return false; + + if($modified_time > 0 && $modified_time > $obj[0]) { + $this->_delete($_key); + return false; + } + + unset($obj[0]); + + return $obj[1]; + } + + function delete($key) { + $_key = $this->getKey($key); + $this->_delete($_key); + } + + function _delete($_key) { + $this->Memcache->delete($_key); + } + + function truncate() { + // not support memcached + return false; + } + } +?> diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 472d1121e..f469a898b 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -1,1557 +1,1557 @@ -.. - var $body_class = array(); ///< classnames of - var $body_header = NULL; ///< codes after - var $html_footer = NULL; ///< codes before - - 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 return static context object (Singleton) - * @return object - * @remarks it's to use Context without declaration of an object - **/ - function &getInstance() { - static $theInstance; - if(!isset($theInstance)) $theInstance = new Context(); - return $theInstance; - } - - /** - * @brief initialization, it sets DB information, request arguments and so on. - * @return none - * @remarks this function should be called only once - **/ - function init() { - // set context variables in $GLOBALS (to use in display handler) - $this->context = &$GLOBALS['__Context__']; - $this->context->lang = &$GLOBALS['lang']; - $this->context->_COOKIE = $_COOKIE; - - $this->_setRequestMethod(); - - $this->_setXmlRpcArgument(); - $this->_setJSONRequestArgument(); - $this->_setRequestArgument(); - $this->_setUploadedArgument(); - - $this->_loadDBInfo(); - - // If XE is installed, get virtual site information - if(Context::isInstalled()) { - $oModuleModel = &getModel('module'); - $site_module_info = $oModuleModel->getDefaultMid(); - // 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) { - $site_module_info->domain = $this->db_info->default_url; - } - - Context::set('site_module_info', $site_module_info); - if($site_module_info->site_srl && isSiteID($site_module_info->domain)) Context::set('vid', $site_module_info->domain, true); - - $this->db_info->lang_type = $site_module_info->default_language; - if(!$this->db_info->lang_type) $this->db_info->lang_type = 'en'; - } - - // Load Language File - $lang_supported = $this->loadLangSelected(); - // Retrieve language type set in user's cookie - if($this->get('l')) { - $this->lang_type = $this->get('l'); - if($_COOKIE['lang_type'] != $this->lang_type) - { - setcookie('lang_type', $this->lang_type); - } - } - else 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 still lang_type has not been set or has not-supported type , set as English. - if(!$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); - $this->setLangType($this->lang_type); - - // load module module's language file according to language setting - $this->loadLang(_XE_PATH_.'modules/module/lang'); - - // set session handler - if($this->db_info->use_db_session != 'N') { - $oSessionModel = &getModel('session'); - $oSessionController = &getController('session'); - session_set_save_handler( - array(&$oSessionController,"open"), - array(&$oSessionController,"close"), - array(&$oSessionModel,"read"), - array(&$oSessionController,"write"), - array(&$oSessionController,"destroy"), - array(&$oSessionController,"gc") - ); - } - session_start(); - - - // set authentication information in Context and session - if(Context::isInstalled()) { - $oMemberModel = &getModel('member'); - $oMemberController = &getController('member'); - - // if signed in, validate it. - if($oMemberModel->isLogged()) { - $oMemberController->setSessionInfo(); - } - elseif($_COOKIE['xeak']) { // check auto sign-in - $oMemberController->doAutologin(); - } - - $this->_set('is_logged', $oMemberModel->isLogged() ); - $this->_set('logged_info', $oMemberModel->getLoggedInfo() ); - } - - // load common language file - $this->lang = &$GLOBALS['lang']; - $this->_loadLang(_XE_PATH_."common/lang/"); - - // check if using rewrite module - if(file_exists(_XE_PATH_.'.htaccess')&&$this->db_info->use_rewrite == 'Y') $this->allow_rewrite = true; - else $this->allow_rewrite = false; - - - // set locations for javascript use - if($_SERVER['REQUEST_METHOD'] == 'GET') { - if($this->get_vars) { - foreach($this->get_vars as $key => $val) { - if(!$val) continue; - if(is_array($val)&&count($val)) { - foreach($val as $k => $v) { - $url .= ($url?'&':'').$key.'['.$k.']='.urlencode($v); - } - } else { - $url .= ($url?'&':'').$key.'='.urlencode($val); - } - } - Context::set('current_url',sprintf('%s?%s', $this->getRequestUri(), $url)); - } else { - Context::set('current_url',$this->getUrl()); - } - } else { - Context::set('current_url',$this->getRequestUri()); - } - Context::set('request_uri',Context::getRequestUri()); - } - - /** - * @brief finalize using resources, such as DB connection - * @return none - **/ - function close() { - // Session Close - if(function_exists('session_write_close')) session_write_close(); - - // DB close - $oDB = &DB::getInstance(); - if(is_object($oDB)&&method_exists($oDB, 'close')) $oDB->close(); - } - - /** - * @brief load DB information - * @return none - **/ - function loadDBInfo() { - $oContext = &Context::getInstance(); - return $oContext->_loadDBInfo(); - } - - /** - * @brief load DB information - * @return none - **/ - function _loadDBInfo() { - if(!$this->isInstalled()) return; - - $db_config_file = $this->getConfigFile(); - if(file_exists($db_config_file)) @include($db_config_file); - - if(!$db_info->time_zone) $db_info->time_zone = date("O"); - if(!$db_info->use_optimizer || $db_info->use_optimizer != 'N') $db_info->use_optimizer = 'Y'; - else $db_info->use_optimizer = 'N'; - if(!$db_info->qmail_compatibility || $db_info->qmail_compatibility != 'Y') $db_info->qmail_compatibility = 'N'; - else $db_info->qmail_compatibility = 'Y'; - if(!$db_info->use_ssl) $db_info->use_ssl = 'none'; - - $this->_setDBInfo($db_info); - - $GLOBALS['_time_zone'] = $db_info->time_zone; - $GLOBALS['_qmail_compatibility'] = $db_info->qmail_compatibility; - $this->set('_use_ssl', $db_info->use_ssl); - if($db_info->http_port) - { - $this->set('_http_port', $db_info->http_port); - } - if($db_info->https_port) - { - $this->set('_https_port', $db_info->https_port); - } - } - - /** - * @brief get DB's db_type - * @return DB's db_type string - **/ - function getDBType() { - $oContext = &Context::getInstance(); - return $oContext->_getDBType(); - } - - /** - * @brief get DB's db_type - * @return DB's db_type string - **/ - function _getDBType() { - return $this->db_info->db_type; - } - - /** - * @brief set DB information - * @param[in] DB information object - * @return none - **/ - function setDBInfo($db_info) { - $oContext = &Context::getInstance(); - $oContext->_setDBInfo($db_info); - } - - /** - * @brief set DB information - * @param[in] DB information object - * @return none - **/ - function _setDBInfo($db_info) { - $this->db_info = $db_info; - } - - /** - * @brief get DB information - * @return DB information object - **/ - function getDBInfo() { - $oContext = &Context::getInstance(); - return $oContext->_getDBInfo(); - } - - /** - * @brief get DB information - * @return DB information object - **/ - function _getDBInfo() { - return $this->db_info; - } - - /** - * @brief return default URL - * @return default URL string - **/ - function getDefaultUrl() { - $db_info = Context::getDBInfo(); - return $db_info->default_url; - } - - /** - * @brief find supported languages - * @return array of supported languages - **/ - function loadLangSupported() { - static $lang_supported = null; - if(is_null($lang_supported)) { - $langs = file(_XE_PATH_.'common/lang/lang.info'); - foreach($langs as $val) { - list($lang_prefix, $lang_text) = explode(',',$val); - $lang_text = trim($lang_text); - $lang_supported[$lang_prefix] = $lang_text; - } - } - return $lang_supported; - } - - /** - * @brief find selected languages to serve in the site - * @return array of selected languages - **/ - function loadLangSelected() { - static $lang_selected = null; - if(is_null($lang_selected)) { - $orig_lang_file = _XE_PATH_.'common/lang/lang.info'; - $selected_lang_file = _XE_PATH_.'files/config/lang_selected.info'; - if(!file_exists($selected_lang_file) || !filesize($selected_lang_file)) { - $old_selected_lang_file = _XE_PATH_.'files/cache/lang_selected.info'; - if(file_exists($old_selected_lang_file)) { - FileHandler::copyFile($old_selected_lang_file, $selected_lang_file); - FileHandler::removeFile($old_selected_lang_file); - } - } - - if(!file_exists($selected_lang_file) || !filesize($selected_lang_file)) { - $buff = FileHandler::readFile($orig_lang_file); - FileHandler::writeFile($selected_lang_file, $buff); - $lang_selected = Context::loadLangSupported(); - } else { - $langs = file($selected_lang_file); - foreach($langs as $val) { - list($lang_prefix, $lang_text) = explode(',',$val); - $lang_text = trim($lang_text); - $lang_selected[$lang_prefix] = $lang_text; - } - } - } - return $lang_selected; - } - - /** - * @brief Single Sign On (SSO) - * @return true if module handleing is necessary in the control path of current request - **/ - function checkSSO() { - // 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; - - // pass if default URL is not set - $default_url = trim($this->db_info->default_url); - if(!$default_url) return true; - if(substr($default_url,-1)!='/') $default_url .= '/'; - - // for sites recieving SSO valdiation - if($default_url == Context::getRequestUri()) { - if(Context::get('default_url')) { - $url = base64_decode(Context::get('default_url')); - $url_info = parse_url($url); - $url_info['query'].= ($url_info['query']?'&':'').'SSOID='.session_id(); - $redirect_url = sprintf('%s://%s%s%s?%s',$url_info['scheme'],$url_info['host'],$url_info['port']?':'.$url_info['port']:'',$url_info['path'], $url_info['query']); - header("location:".$redirect_url); - return false; - } - // for sites requesting SSO validation - } else { - // result handling : set session_name() - if(Context::get('SSOID')) { - $session_name = Context::get('SSOID'); - setcookie(session_name(), $session_name); - - $url = preg_replace('/([\?\&])$/','',str_replace('SSOID='.$session_name,'',Context::getRequestUrl())); - header("location:".$url); - return false; - // send SSO request - } else if($_COOKIE['sso']!=md5(Context::getRequestUri()) && !Context::get('SSOID')) { - setcookie('sso',md5(Context::getRequestUri()),0,'/'); - $url = sprintf("%s?default_url=%s", $default_url, base64_encode(Context::getRequestUrl())); - header("location:".$url); - return false; - } - } - - return true; - } - - /** - * @biref check if FTP info is registered - * @return true: FTP information is registered, false: otherwise - **/ - function isFTPRegisted() { - $ftp_config_file = Context::getFTPConfigFile(); - if(file_exists($ftp_config_file)) return true; - return false; - } - - /** - * @brief get FTP information object - * @return FTP information object - **/ - function getFTPInfo() { - $oContext = &Context::getInstance(); - return $oContext->_getFTPInfo(); - } - - /** - * @brief get FTP information object - * @return FTP information object - **/ - function _getFTPInfo() { - if(!$this->isFTPRegisted()) return null; - - $ftp_config_file = $this->getFTPConfigFile(); - @include($ftp_config_file); - return $ftp_info; - } - - /** - * @brief add string to browser title - * @param[in] $site_title string to be added - * @return none - **/ - function addBrowserTitle($site_title) { - if(!$site_title) return; - $oContext = &Context::getInstance(); - $oContext->_addBrowserTitle($site_title); - } - - /** - * @brief add string to browser title - * @param[in] $site_title string to be added - * @return none - **/ - function _addBrowserTitle($site_title) { - if($this->site_title) $this->site_title .= ' - '.$site_title; - else $this->site_title .= $site_title; - } - - /** - * @brief set string to browser title - * @param[in] $site_title string to be set - * @return none - **/ - function setBrowserTitle($site_title) { - if(!$site_title) return; - $oContext = &Context::getInstance(); - $oContext->_setBrowserTitle($site_title); - } - - /** - * @brief set string to browser title - * @param[in] $site_title string to be set - * @return none - **/ - function _setBrowserTitle($site_title) { - $this->site_title = $site_title; - } - - /** - * @brief get browser title - * @return browser title string (htmlspecialchars applied) - **/ - function getBrowserTitle() { - $oContext = &Context::getInstance(); - return htmlspecialchars($oContext->_getBrowserTitle()); - } - - /** - * @brief get browser title - * @return browser title string - **/ - function _getBrowserTitle() { - $oModuleController = &getController('module'); - $oModuleController->replaceDefinedLangCode($this->site_title); - return $this->site_title; - } - - /** - * @brief load language file according to language type - * @param[in] $path path of the language file - * @return none - **/ - function loadLang($path) { - $oContext = &Context::getInstance(); - $oContext->_loadLang($path); - } - - /** - * @brief load language file according to language type - * @param[in] $path path of the language file - * @return none - * @remarks using $loaded_lang_files it does not load once-loaded files - **/ - function _loadLang($path) { - global $lang; - if(!is_object($lang)) $lang = new stdClass; - if(!$this->lang_type) return; - if(substr($path,-1)!='/') $path .= '/'; - $filename = sprintf('%s%s.lang.php', $path, $this->lang_type); - if(!file_exists($filename)) $filename = sprintf('%s%s.lang.php', $path, 'ko'); - if(!file_exists($filename)) return; - if(!is_array($this->loaded_lang_files)) $this->loaded_lang_files = array(); - if(in_array($filename, $this->loaded_lang_files)) return; - $this->loaded_lang_files[] = $filename; - if(file_exists($filename)) @include($filename); - } - - /** - * @brief set lang_type - * @return none - **/ - function setLangType($lang_type = 'ko') { - $oContext = &Context::getInstance(); - $oContext->_setLangType($lang_type); - $_SESSION['lang_type'] = $lang_type; - } - - /** - * @brief set lang_type - * @return none - **/ - function _setLangType($lang_type = 'ko') { - $this->lang_type = $lang_type; - $this->_set('lang_type',$lang_type); - } - - /** - * @brief get lang_type - * @return lang_type string - **/ - function getLangType() { - $oContext = &Context::getInstance(); - return $oContext->_getLangType(); - } - - /** - * @brief get lang_type - * @return lang_type string - **/ - function _getLangType() { - return $this->lang_type; - } - - /** - * @brief return string accoring to the inputed code - * @param[in] $code language variable name - * @return if string for the code exists returns it, otherwise returns original code - **/ - function getLang($code) { - if(!$code) return; - if($GLOBALS['lang']->{$code}) return $GLOBALS['lang']->{$code}; - return $code; - } - - /** - * @brief set data to lang variable - * @return none - **/ - function setLang($code, $val) { - $GLOBALS['lang']->{$code} = $val; - } - - /** - * @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) { - $charset_list = array( - 'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932', - 'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS', - 'ISO2022-CN', 'ISO2022-CN-EXT', 'ISO2022-JP', 'ISO2022-JP-2', 'ISO2022-JP-1', - 'ISO8859-6', 'ISO8859-8', 'JOHAB', 'ISO2022-KR', 'CP1255', 'CP1256', 'CP862', - 'ASCII', 'ISO8859-1', 'ISO8850-2', 'ISO8850-3', 'ISO8850-4', 'ISO8850-5', - 'ISO8850-7', 'ISO8850-9', 'ISO8850-10', 'ISO8850-13', 'ISO8850-14', - 'ISO8850-15', 'ISO8850-16', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', - 'CP1257', 'CP850', 'CP866', - ); - - $obj = clone($source_obj); - - for($i=0;$i$val) { - if(!$val) continue; - if($val && iconv($charset,$charset,$val)!=$val) $flag = false; - } - if($flag == true) { - if($charset == 'UTF-8') return $obj; - foreach($obj as $key => $val) $obj->{$key} = iconv($charset,'UTF-8',$val); - return $obj; - } - } - return $obj; - } - - /** - * @brief convert strings into UTF-8 - * @param[in] $str string to convert - * @return converted string - **/ - function convertEncodingStr($str) { - $obj->str = $str; - $obj = Context::convertEncoding($obj); - return $obj->str; - } - - /** - * @brief force to set response method - * @param[in] $method response method (HTML/XMLRPC/JSON) - * @return none - **/ - function setResponseMethod($method = "HTML") { - $oContext = &Context::getInstance(); - return $oContext->_setResponseMethod($method); - } - - /** - * @brief force to set response method - * @param[in] $method response method (HTML/XMLRPC/JSON) - * @return none - **/ - function _setResponseMethod($method = "HTML") { - $this->response_method = $method; - } - - /* - * @brief get reponse method - * @return response method string (if it's not set, returns request method) - */ - function getResponseMethod() { - $oContext = &Context::getInstance(); - return $oContext->_getResponseMethod(); - } - - /* - * @brief get reponse method - * @return response method string (if it's not set, returns request method) - */ - function _getResponseMethod() { - if($this->response_method) return $this->response_method; - - $RequestMethod = $this->_getRequestMethod(); - if($RequestMethod=="XMLRPC") return "XMLRPC"; - else if($RequestMethod=="JSON") return "JSON"; - return "HTML"; - } - - /** - * @brief determine request method (GET/POST/XMLRPC/JSON) - * @param[in] $type request method - * @return none - **/ - function setRequestMethod($type) { - $oContext = &Context::getInstance(); - $oContext->_setRequestMethod($type); - } - - - /** - * @brief deteremine request method (GET/POST/XMLRPC/JSON) - * @param[in] $type request method - * @return none - **/ - function _setRequestMethod($type = '') { - if($type) return $this->request_method = $type; - - if(strpos($_SERVER['CONTENT_TYPE'],'json')) return $this->request_method = 'JSON'; - if($GLOBALS['HTTP_RAW_POST_DATA']) return $this->request_method = "XMLRPC"; - - $this->request_method = $_SERVER['REQUEST_METHOD']; - } - - /** - * @brief handle request areguments for GET/POST - * @return none - **/ - function _setRequestArgument() { - if(!count($_REQUEST)) return; - - foreach($_REQUEST as $key => $val) { - if($val === "" || Context::get($key)) continue; - $val = $this->_filterRequestVar($key, $val); - if($this->_getRequestMethod()=='GET'&&isset($_GET[$key])) $set_to_vars = true; - elseif($this->_getRequestMethod()=='POST'&&isset($_POST[$key])) $set_to_vars = true; - else $set_to_vars = false; - $this->_set($key, $val, $set_to_vars); - } - } - - /** - * @brief handle request arguments for JSON - * @return none - **/ - function _setJSONRequestArgument() { - if($this->_getRequestMethod() != 'JSON') return; - - $params = array(); - parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$params); - - foreach($params as $key => $val) { - $val = $this->_filterRequestVar($key, $val,0); - $this->_set($key, $val, true); - } - } - - /** - * @brief handle request arguments for XML RPC - * @return none - **/ - function _setXmlRpcArgument() { - if($this->_getRequestMethod() != 'XMLRPC') return; - $oXml = new XmlParser(); - $xml_obj = $oXml->parse(); - - $params = $xml_obj->methodcall->params; - unset($params->node_name); - - unset($params->attrs); - if(!count($params)) return; - foreach($params as $key => $obj) { - $val = $this->_filterRequestVar($key, $obj->body,0); - $this->_set($key, $val, true); - } - } - - /** - * @brief Filter request variable - * @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) { - if( ($key == "page" || $key == "cpage" || substr($key,-3)=="srl")) return !preg_match('/^[0-9,]+$/',$val)?(int)$val:$val; - if(is_array($val) && count($val) ) { - foreach($val as $k => $v) { - if($do_stripslashes && version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $v = stripslashes($v); - $v = trim($v); - $val[$k] = $v; - } - } else { - if($do_stripslashes && version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $val = stripslashes($val); - $val = trim($val); - } - return $val; - } - - /** - * @brief Check if there exists uploaded file - * @return true: exists, false: otherwise - **/ - function isUploaded() { - $oContext = &Context::getInstance(); - return $oContext->_isUploaded(); - } - - /** - * @brief Check if there exists uploaded file - * @return true: exists, false: otherwise - **/ - function _isUploaded() { - return $this->is_uploaded; - } - - /** - * @brief handle uploaded file - * @return none - **/ - function _setUploadedArgument() { - if($this->_getRequestMethod() != 'POST') return; - if(!preg_match("/multipart\/form-data/i",$_SERVER['CONTENT_TYPE'])) return; - if(!$_FILES) return; - - foreach($_FILES as $key => $val) { - $tmp_name = $val['tmp_name']; - if(!$tmp_name || !is_uploaded_file($tmp_name)) continue; - $this->_set($key, $val, true); - $this->is_uploaded = true; - } - } - - /** - * @brief return request method (GET/POST/XMLRPC/JSON); - * @return request method type - **/ - function getRequestMethod() { - $oContext = &Context::getInstance(); - return $oContext->_getRequestMethod(); - } - - /** - * @brief return request method (GET/POST/XMLRPC/JSON); - * @return request method type - **/ - function _getRequestMethod() { - return $this->request_method; - } - - /** - * @brief return request URL - * @return request URL - **/ - function getRequestUrl() { - static $url = null; - if(is_null($url)) { - $url = Context::getRequestUri(); - if(count($_GET)) { - foreach($_GET as $key => $val) $vars[] = $key.'='.urlencode(Context::convertEncodingStr($val)); - $url .= '?'.implode('&',$vars); - } - } - return $url; - } - - /** - * @brief make URL with args_list upon request URL - * @return result URL - **/ - function getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) { - $oContext = &Context::getInstance(); - return $oContext->_getUrl($num_args, $args_list, $domain, $encode); - } - - /** - * @brief make URL with args_list upon request URL - * @return result URL - **/ - function _getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) { - static $site_module_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 $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid) - if($domain && isSiteID($domain)) { - $vid = $domain; - $domain = ''; - } - - // If $domain, $vid are not set, use current site information - if(!$domain && !$vid) { - if($site_module_info->domain && isSiteID($site_module_info->domain)) $vid = $site_module_info->domain; - else $domain = $site_module_info->domain; - } - - // if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain. - if($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($domain_info['host'].$domain_info['path']==$current_info['host'].$current_info['path']) { - unset($domain); - } else { - $domain = preg_replace('/^(http|https):\/\//i','', trim($domain)); - if(substr($domain,-1) != '/') $domain .= '/'; - } - } - - $get_vars = null; - - // If there is no GET variables or first argument is '' to reset variables - if(!$this->get_vars || $args_list[0]=='') { - // rearrange args_list - if(is_array($args_list) && $args_list[0]=='') array_shift($args_list); - } else { - // Otherwise, make GET variables into array - $get_vars = get_object_vars($this->get_vars); - } - - // arrange args_list - for($i=0,$c=count($args_list);$i<$c;$i=$i+2) { - $key = $args_list[$i]; - $val = trim($args_list[$i+1]); - - // If value is not set, remove the key - if(!isset($val) || strlen($val)<1) { - unset($get_vars[$key]); - continue; - } - // set new variables - $get_vars[$key] = $val; - } - - // remove vid, rnd - unset($get_vars['rnd']); - if($vid) $get_vars['vid'] = $vid; - else unset($get_vars['vid']); - - // for compatibility to lower versions - switch($get_vars['act']) { - case 'dispMemberFriend' : $get_vars['act'] = 'dispCommunicationFriend'; break; - case 'dispMemberMessages' : $get_vars['act'] = 'dispCommunicationMessages'; break; - case 'dispDocumentAdminManageDocument' : $get_vars['act'] = 'dispDocumentManageDocument'; break; - case 'dispModuleAdminSelectList' : $get_vars['act'] = 'dispModuleSelectList'; break; - } - - // organize URL - $query = null; - if($var_count = count($get_vars)) { - // If using rewrite mod - if($this->allow_rewrite) { - $var_keys = array_keys($get_vars); - asort($var_keys); - $target = implode('.', $var_keys); - switch($target) { - case 'vid' : $query = $get_vars['vid']; break; - case 'mid' : $query = $get_vars['mid']; break; - case 'document_srl' : $query = $get_vars['document_srl']; break; - case 'document_srl.mid' : $query = $get_vars['mid'].'/'.$get_vars['document_srl']; break; - case 'entry.mid' : $query = $get_vars['mid'].'/entry/'.$get_vars['entry']; break; - case 'act.document_srl.key' : $query = $get_vars['act']=='trackback'?$get_vars['document_srl'].'/'.$get_vars['key'].'/'.$get_vars['act']:''; break; - case 'mid.vid' : $query = $get_vars['vid'].'/'.$get_vars['mid']; break; - case 'document_srl.vid' : $query = $get_vars['vid'].'/'.$get_vars['document_srl']; break; - case 'document_srl.mid.vid' : $query = $get_vars['vid'].'/'.$get_vars['mid'].'/'.$get_vars['document_srl']; break; - case 'entry.mid.vid' : $query = $get_vars['vid'].'/'.$get_vars['mid'].'/entry/'.$get_vars['entry']; break; - case 'act.document_srl.key.vid' : $query = $get_vars['act']=='trackback'?$get_vars['vid'].'/'.$get_vars['document_srl'].'/'.$get_vars['key'].'/'.$get_vars['act']:''; break; - case 'act.mid' : $query = (in_array($get_vars['act'], array('rss', 'atom', 'api'))) ? $get_vars['mid'].'/'.$get_vars['act'] : ''; break; - case 'act.mid.vid' : $query = (in_array($get_vars['act'], array('rss', 'atom', 'api'))) ? $get_vars['vid'].'/'.$get_vars['mid'].'/'.$get_vars['act']:''; break; - } - } - - if(!$query) { - foreach($get_vars as $key => $val) { - if(is_array($val) && count($val)) { - foreach($val as $k => $v) $query .= ($query?'&':'').$key.'['.$k.']='.urlencode($v); - } else { - $query .= ($query?'&':'').$key.'='.urlencode($val); - } - } - if($query) $query = '?'.$query; - } - } - - // If using SSL always - if(Context::get('_use_ssl')=='always') { - $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query; - // optional SSL use - } elseif(Context::get('_use_ssl')=='optional') { - $ssl_mode = RELEASE_SSL; - if($get_vars['act'] && $this->_isExistsSSLAction($get_vars['act'])) $ssl_mode = ENFORCE_SSL; - $query = $this->getRequestUri($ssl_mode, $domain).$query; - // no SSL - } else { - // currently on SSL but target is not based on SSL - if($_SERVER['HTTPS']=='on' ) $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query; - - // if $domain is set - else if($domain) $query = $this->getRequestUri(FOLLOW_REQUEST_SSL, $domain).$query; - - else $query = getScriptPath().$query; - } - - if($encode) return htmlspecialchars($query); - return $query; - } - - /** - * @brief 요청이 들어온 URL에서 argument를 제거하여 return - **/ - function getRequestUri($ssl_mode = FOLLOW_REQUEST_SSL, $domain = null) { - static $url = array(); - - // HTTP Request가 아니면 패스 - if(!isset($_SERVER['SERVER_PROTOCOL'])) return ; - if(Context::get('_use_ssl') == "always") $ssl_mode = ENFORCE_SSL; - - if($domain) $domain_key = md5($domain); - else $domain_key = 'default'; - - if(isset($url[$ssl_mode][$domain_key])) return $url[$ssl_mode][$domain_key]; - - $current_use_ssl = $_SERVER['HTTPS']=='on' ? true : false; - - switch($ssl_mode) { - case FOLLOW_REQUEST_SSL : - if($current_use_ssl) $use_ssl = true; - else $use_ssl = false; - break; - case ENFORCE_SSL : - $use_ssl = true; - break; - case RELEASE_SSL : - $use_ssl = false; - break; - } - - if($domain) { - $target_url = trim($domain); - if(substr($target_url,-1) != '/') $target_url.= '/'; - } else { - $target_url= $_SERVER['HTTP_HOST'].getScriptPath(); - } - - $url_info = parse_url('http://'.$target_url); - - if($current_use_ssl != $use_ssl) - { - unset($url_info['port']); - } - - if($use_ssl) { - if(Context::get("_https_port") && Context::get("_https_port") != 443) { - $url_info['port'] = Context::get("_https_port"); - } - elseif($url_info['port']==443) - { - unset($url_info['port']); - } - } else { - if(Context::get("_http_port") && Context::get("_http_port") != 80) { - $url_info['port'] = Context::get("_http_port"); - } - elseif($url_info['port']==80) - { - unset($url_info['port']); - } - } - - $url[$ssl_mode][$domain_key] = sprintf("%s://%s%s%s",$use_ssl?'https':$url_info['scheme'], $url_info['host'], $url_info['port']&&$url_info['port']!=80?':'.$url_info['port']:'',$url_info['path']); - - return $url[$ssl_mode][$domain_key]; - } - - /** - * @brief key/val로 context vars 세팅 - **/ - function set($key, $val, $set_to_get_vars = false) { - $oContext = &Context::getInstance(); - $oContext->_set($key, $val, $set_to_get_vars); - } - - /** - * @brief key/val로 context vars 세팅 - **/ - function _set($key, $val, $set_to_get_vars = false) { - $this->context->{$key} = $val; - if($set_to_get_vars || $this->get_vars->{$key}) $this->get_vars->{$key} = $val; - } - - /** - * @brief key값에 해당하는 값을 return - **/ - function get($key) { - $oContext = &Context::getInstance(); - return $oContext->_get($key); - } - - /** - * @brief key값에 해당하는 값을 return - **/ - function _get($key) { - return $this->context->{$key}; - } - - /** - * @brief 받고자 하는 변수만 object에 입력하여 받음 - * - * key1, key2, key3 .. 등의 인자를 주어 여러개의 변수를 object vars로 세팅하여 받을 수 있음 - **/ - function gets() { - $num_args = func_num_args(); - if($num_args<1) return; - $args_list = func_get_args(); - - $oContext = &Context::getInstance(); - return $oContext->_gets($num_args, $args_list); - } - - /** - * @brief 받고자 하는 변수만 object에 입력하여 받음 - * - * key1, key2, key3 .. 등의 인자를 주어 여러개의 변수를 object vars로 세팅하여 받을 수 있음 - **/ - function _gets($num_args, $args_list) { - for($i=0;$i<$num_args;$i++) { - $args = $args_list[$i]; - $output->{$args} = $this->_get($args); - } - return $output; - } - - /** - * @brief 모든 데이터를 return - **/ - function getAll() { - $oContext = &Context::getInstance(); - return $oContext->_getAll(); - } - - /** - * @brief 모든 데이터를 return - **/ - function _getAll() { - return $this->context; - } - - /** - * @brief GET/POST/XMLRPC에서 넘어온 변수값을 return - **/ - function getRequestVars() { - $oContext = &Context::getInstance(); - return $oContext->_getRequestVars(); - } - - /** - * @brief GET/POST/XMLRPC에서 넘어온 변수값을 return - **/ - function _getRequestVars() { - return clone($this->get_vars); - } - - /** - * @brief SSL로 인증되어야 할 action이 있을 경우 등록 - * common/js/xml_handler.js에서 이 action들에 대해서 https로 전송되도록 함 - **/ - function addSSLAction($action) { - $oContext = &Context::getInstance(); - return $oContext->_addSSLAction($action); - } - - function _addSSLAction($action) { - if(in_array($action, $this->ssl_actions)) return; - $this->ssl_actions[] = $action; - } - - function getSSLActions() { - $oContext = &Context::getInstance(); - return $oContext->_getSSLActions(); - } - - function _getSSLActions() { - return $this->ssl_actions; - } - - function isExistsSSLAction($action) { - $oContext = &Context::getInstance(); - return $oContext->_isExistsSSLAction($action); - } - - function _isExistsSSLAction($action) { - return in_array($action, $this->ssl_actions); - } - - /** - * @brief js file을 추가 - **/ - function addJsFile($file, $optimized = true, $targetie = '',$index=null) { - $oContext = &Context::getInstance(); - return $oContext->_addJsFile($file, $optimized, $targetie,$index); - } - - /** - * @brief js file을 추가 - **/ - function _addJsFile($file, $optimized = true, $targetie = '',$index=null) { - if(strpos($file,'://')===false && $file{0}!='/' && $file{0}!='.') $file = './'.$file; - $file = preg_replace('@/\./|(?js_files)) return; - - if(is_null($index)) $index=count($this->js_files); - for($i=$index;array_key_exists($i,$this->js_files);$i++); - $this->js_files[$i] = array('file' => $file, 'optimized' => $optimized, 'targetie' => $targetie); - } - - /** - * @brief js file을 제거 - **/ - function unloadJsFile($file, $optimized = true, $targetie = '') { - $oContext = &Context::getInstance(); - return $oContext->_unloadJsFile($file, $optimized, $targetie); - } - - /** - * @brief js file을 제거 - **/ - function _unloadJsFile($file, $optimized, $targetie) { - foreach($this->js_files as $key => $val) { - if(realpath($val['file'])==realpath($file) && $val['optimized'] == $optimized && $val['targetie'] == $targetie) { - unset($this->js_files[$key]); - return; - } - } - } - - /** - * @brief 모든 JS File을 제거 - **/ - function unloadAllJsFiles() { - $oContext = &Context::getInstance(); - return $oContext->_unloadAllJsFiles(); - } - - function _unloadAllJsFiles() { - $this->js_files = array(); - } - - /** - * @brief javascript filter 추가 - **/ - function addJsFilter($path, $filename) { - $oXmlFilter = new XmlJSFilter($path, $filename); - $oXmlFilter->compile(); - } - - /** - * @brief array_unique와 동작은 동일하나 file 첨자에 대해서만 동작함 - **/ - function _getUniqueFileList($files) { - ksort($files); - $files = array_values($files); - $filenames = array(); - $size = count($files); - for($i = 0; $i < $size; ++ $i) - { - if(in_array($files[$i]['file'], $filenames)) - unset($files[$i]); - $filenames[] = $files[$i]['file']; - } - - return $files; - } - - /** - * @brief js file 목록을 return - **/ - function getJsFile() { - $oContext = &Context::getInstance(); - return $oContext->_getJsFile(); - } - - /** - * @brief js file 목록을 return - **/ - function _getJsFile() { - require_once(_XE_PATH_."classes/optimizer/Optimizer.class.php"); - $oOptimizer = new Optimizer(); - return $oOptimizer->getOptimizedFiles($this->_getUniqueFileList($this->js_files), "js"); - } - - /** - * @brief CSS file 추가 - **/ - function addCSSFile($file, $optimized = true, $media = 'all', $targetie = '',$index = null) { - $oContext = &Context::getInstance(); - return $oContext->_addCSSFile($file, $optimized, $media, $targetie,$index); - } - - /** - * @brief CSS file 추가 - **/ - function _addCSSFile($file, $optimized = true, $media = 'all', $targetie = '', $index = null) { - if(strpos($file,'://')===false && substr($file,0,1)!='/' && substr($file,0,1)!='.') $file = './'.$file; - $file = str_replace(array('/./','//'),'/',$file); - while(strpos($file,'/../')) $file = preg_replace('/\/([^\/]+)\/\.\.\//s','/',$file,1); - - if(in_array($file, $this->css_files)) return; - - if(is_null($index)) $index=count($this->css_files); - for($i=$index;array_key_exists($i,$this->css_files);$i++); - - //if(preg_match('/^http:\/\//i',$file)) $file = str_replace(realpath("."), ".", realpath($file)); - $this->css_files[$i] = array('file' => $file, 'optimized' => $optimized, 'media' => $media, 'targetie' => $targetie); - } - - /** - * @brief css file을 제거 - **/ - function unloadCSSFile($file, $optimized = true, $media = 'all', $targetie = '') { - $oContext = &Context::getInstance(); - return $oContext->_unloadCSSFile($file, $optimized, $media, $targetie); - } - - /** - * @brief css file을 제거 - **/ - function _unloadCSSFile($file, $optimized, $media, $targetie) { - foreach($this->css_files as $key => $val) { - if(realpath($val['file'])==realpath($file) && $val['optimized'] == $optimized && $val['media'] == $media && $val['targetie'] == $targetie) { - unset($this->css_files[$key]); - return; - } - } - } - - /** - * @brief 모든 CSS File을 제거 - **/ - function unloadAllCSSFiles() { - $oContext = &Context::getInstance(); - return $oContext->_unloadAllCSSFiles(); - } - - function _unloadAllCSSFiles() { - $this->css_files = array(); - } - - /** - * @brief CSS file 목록 return - **/ - function getCSSFile() { - $oContext = &Context::getInstance(); - return $oContext->_getCSSFile(); - } - - /** - * @brief CSS file 목록 return - **/ - function _getCSSFile() { - require_once(_XE_PATH_."classes/optimizer/Optimizer.class.php"); - $oOptimizer = new Optimizer(); - return $oOptimizer->getOptimizedFiles($this->_getUniqueFileList($this->css_files), "css"); - } - - /** - * @brief javascript plugin load - **/ - function loadJavascriptPlugin($plugin_name) { - $oContext = &Context::getInstance(); - return $oContext->_loadJavascriptPlugin($plugin_name); - } - - function _loadJavascriptPlugin($plugin_name) { - static $loaded_plugins = array(); - if($loaded_plugins[$plugin_name]) return; - $loaded_plugins[$plugin_name] = true; - if($plugin_name == "ui.datepicker") return $this->_loadJavascriptPlugin("ui"); - - $plugin_path = './common/js/plugins/'.$plugin_name.'/'; - if(!is_dir($plugin_path)) return; - - $info_file = $plugin_path.'plugin.load'; - if(!file_exists($info_file)) return; - - $list = file($info_file); - for($i=0,$cnt=count($list);$i<$cnt;$i++) { - $filename = trim($list[$i]); - if(!$filename) continue; - if(substr($filename,0,2)=='./') $filename = substr($filename,2); - if(preg_match('/\.js$/i',$filename)) $this->_addJsFile($plugin_path.$filename, true, '', null); - elseif(preg_match('/\.css$/i',$filename)) $this->_addCSSFile($plugin_path.$filename, true, 'all','', null); - } - - if(is_dir($plugin_path.'lang')) $this->_loadLang($plugin_path.'lang'); - } - - /** - * @brief HtmlHeader 추가 - **/ - function addHtmlHeader($header) { - $oContext = &Context::getInstance(); - return $oContext->_addHtmlHeader($header); - } - - /** - * @brief HtmlHeader 추가 - **/ - function _addHtmlHeader($header) { - $this->html_header .= "\n".$header; - } - - /** - * @brief HtmlHeader return - **/ - function getHtmlHeader() { - $oContext = &Context::getInstance(); - return $oContext->_getHtmlHeader(); - } - - /** - * @brief HtmlHeader return - **/ - function _getHtmlHeader() { - return $this->html_header; - } - - /** - * @brief Html Body에 css class 추가 - **/ - function addBodyClass($class_name) { - $oContext = &Context::getInstance(); - return $oContext->_addBodyClass($class_name); - } - - /** - * @brief Html Body에 css class 추가 - **/ - function _addBodyClass($class_name) { - $this->body_class[] = $class_name; - } - - /** - * @brief Html Body에 css class return - **/ - function getBodyClass() { - $oContext = &Context::getInstance(); - return $oContext->_getBodyClass(); - } - - /** - * @brief Html Body에 css class return - **/ - function _getBodyClass() { - $this->body_class = array_unique($this->body_class); - if(count($this->body_class)>0) return sprintf(' class="%s"', join(' ',$this->body_class)); - else return ''; - } - - - /** - * @brief BodyHeader 추가 - **/ - function addBodyHeader($header) { - $oContext = &Context::getInstance(); - return $oContext->_addBodyHeader($header); - } - - /** - * @brief BodyHeader 추가 - **/ - function _addBodyHeader($header) { - $this->body_header .= "\n".$header; - } - - /** - * @brief BodyHeader return - **/ - function getBodyHeader() { - $oContext = &Context::getInstance(); - return $oContext->_getBodyHeader(); - } - - /** - * @brief BodyHeader return - **/ - function _getBodyHeader() { - return $this->body_header; - } - - /** - * @brief HtmlFooter 추가 - **/ - function addHtmlFooter($footer) { - $oContext = &Context::getInstance(); - return $oContext->_addHtmlFooter($footer); - } - - /** - * @brief HtmlFooter 추가 - **/ - function _addHtmlFooter ($footer) { - $this->html_footer .= ($this->Htmlfooter?"\n":"").$footer; - } - - /** - * @brief HtmlFooter return - **/ - function getHtmlFooter() { - $oContext = &Context::getInstance(); - return $oContext->_getHtmlFooter(); - } - - /** - * @brief HtmlFooter return - **/ - function _getHtmlFooter() { - return $this->html_footer; - } - - /** - * @brief db설정내용이 저장되어 있는 config file의 path를 return - **/ - function getConfigFile() { - return _XE_PATH_."files/config/db.config.php"; - } - - /** - * @brief ftp설정내용이 저장되어 있는 config file의 path를 return - **/ - function getFTPConfigFile() { - return _XE_PATH_."files/config/ftp.config.php"; - } - - /** - * @brief 설치가 되어 있는지에 대한 체크 - * - * 단순히 db config 파일의 존재 유무로 설치 여부를 체크한다 - **/ - function isInstalled() { - return file_exists(Context::getConfigFile()) && filesize(Context::getConfigFile()); - } - - /** - * @brief 내용의 위젯이나 기타 기능에 대한 code를 실제 code로 변경 - **/ - function transContent($content) { - return $content; - } - - /** - * @brief rewrite mod 사용에 대한 변수 return - **/ - function isAllowRewrite() { - $oContext = &Context::getInstance(); - return $oContext->allow_rewrite; - } - - /** - * @brief 로컬 경로를 웹 경로로 변경 - */ - function pathToUrl($path) { - $xe = _XE_PATH_; - $path = strtr($path, "\\", "/"); - - $base_url = preg_replace('@^https?://[^/]+/?@', '', Context::getRequestUri()); - - $_xe = explode('/', $xe); - $_path = explode('/', $path); - $_base = explode('/', $base_url); - - if (!$_base[count($_base)-1]) array_pop($_base); - - foreach($_xe as $idx=>$dir) { - if($_path[0] != $dir) break; - array_shift($_path); - } - - $idx = count($_xe) - $idx - 1; - while($idx--) { - if (count($_base)) array_shift($_base); - else array_unshift($_base, '..'); - } - - if (count($_base)) { - array_unshift($_path, implode('/', $_base)); - } - - $path = '/'.implode('/', $_path); - - return $path; - } - } -?> +.. + var $body_class = array(); ///< classnames of + var $body_header = NULL; ///< codes after + var $html_footer = NULL; ///< codes before + + 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 return static context object (Singleton) + * @return object + * @remarks it's to use Context without declaration of an object + **/ + function &getInstance() { + static $theInstance; + if(!isset($theInstance)) $theInstance = new Context(); + return $theInstance; + } + + /** + * @brief initialization, it sets DB information, request arguments and so on. + * @return none + * @remarks this function should be called only once + **/ + function init() { + // set context variables in $GLOBALS (to use in display handler) + $this->context = &$GLOBALS['__Context__']; + $this->context->lang = &$GLOBALS['lang']; + $this->context->_COOKIE = $_COOKIE; + + $this->_setRequestMethod(); + + $this->_setXmlRpcArgument(); + $this->_setJSONRequestArgument(); + $this->_setRequestArgument(); + $this->_setUploadedArgument(); + + $this->_loadDBInfo(); + + // If XE is installed, get virtual site information + if(Context::isInstalled()) { + $oModuleModel = &getModel('module'); + $site_module_info = $oModuleModel->getDefaultMid(); + // 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) { + $site_module_info->domain = $this->db_info->default_url; + } + + Context::set('site_module_info', $site_module_info); + if($site_module_info->site_srl && isSiteID($site_module_info->domain)) Context::set('vid', $site_module_info->domain, true); + + $this->db_info->lang_type = $site_module_info->default_language; + if(!$this->db_info->lang_type) $this->db_info->lang_type = 'en'; + } + + // Load Language File + $lang_supported = $this->loadLangSelected(); + // Retrieve language type set in user's cookie + if($this->get('l')) { + $this->lang_type = $this->get('l'); + if($_COOKIE['lang_type'] != $this->lang_type) + { + setcookie('lang_type', $this->lang_type); + } + } + else 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 still lang_type has not been set or has not-supported type , set as English. + if(!$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); + $this->setLangType($this->lang_type); + + // load module module's language file according to language setting + $this->loadLang(_XE_PATH_.'modules/module/lang'); + + // set session handler + if($this->db_info->use_db_session != 'N') { + $oSessionModel = &getModel('session'); + $oSessionController = &getController('session'); + session_set_save_handler( + array(&$oSessionController,"open"), + array(&$oSessionController,"close"), + array(&$oSessionModel,"read"), + array(&$oSessionController,"write"), + array(&$oSessionController,"destroy"), + array(&$oSessionController,"gc") + ); + } + session_start(); + + + // set authentication information in Context and session + if(Context::isInstalled()) { + $oMemberModel = &getModel('member'); + $oMemberController = &getController('member'); + + // if signed in, validate it. + if($oMemberModel->isLogged()) { + $oMemberController->setSessionInfo(); + } + elseif($_COOKIE['xeak']) { // check auto sign-in + $oMemberController->doAutologin(); + } + + $this->_set('is_logged', $oMemberModel->isLogged() ); + $this->_set('logged_info', $oMemberModel->getLoggedInfo() ); + } + + // load common language file + $this->lang = &$GLOBALS['lang']; + $this->_loadLang(_XE_PATH_."common/lang/"); + + // check if using rewrite module + if(file_exists(_XE_PATH_.'.htaccess')&&$this->db_info->use_rewrite == 'Y') $this->allow_rewrite = true; + else $this->allow_rewrite = false; + + + // set locations for javascript use + if($_SERVER['REQUEST_METHOD'] == 'GET') { + if($this->get_vars) { + foreach($this->get_vars as $key => $val) { + if(!$val) continue; + if(is_array($val)&&count($val)) { + foreach($val as $k => $v) { + $url .= ($url?'&':'').$key.'['.$k.']='.urlencode($v); + } + } else { + $url .= ($url?'&':'').$key.'='.urlencode($val); + } + } + Context::set('current_url',sprintf('%s?%s', $this->getRequestUri(), $url)); + } else { + Context::set('current_url',$this->getUrl()); + } + } else { + Context::set('current_url',$this->getRequestUri()); + } + Context::set('request_uri',Context::getRequestUri()); + } + + /** + * @brief finalize using resources, such as DB connection + * @return none + **/ + function close() { + // Session Close + if(function_exists('session_write_close')) session_write_close(); + + // DB close + $oDB = &DB::getInstance(); + if(is_object($oDB)&&method_exists($oDB, 'close')) $oDB->close(); + } + + /** + * @brief load DB information + * @return none + **/ + function loadDBInfo() { + $oContext = &Context::getInstance(); + return $oContext->_loadDBInfo(); + } + + /** + * @brief load DB information + * @return none + **/ + function _loadDBInfo() { + if(!$this->isInstalled()) return; + + $db_config_file = $this->getConfigFile(); + if(file_exists($db_config_file)) @include($db_config_file); + + if(!$db_info->time_zone) $db_info->time_zone = date("O"); + if(!$db_info->use_optimizer || $db_info->use_optimizer != 'N') $db_info->use_optimizer = 'Y'; + else $db_info->use_optimizer = 'N'; + if(!$db_info->qmail_compatibility || $db_info->qmail_compatibility != 'Y') $db_info->qmail_compatibility = 'N'; + else $db_info->qmail_compatibility = 'Y'; + if(!$db_info->use_ssl) $db_info->use_ssl = 'none'; + + $this->_setDBInfo($db_info); + + $GLOBALS['_time_zone'] = $db_info->time_zone; + $GLOBALS['_qmail_compatibility'] = $db_info->qmail_compatibility; + $this->set('_use_ssl', $db_info->use_ssl); + if($db_info->http_port) + { + $this->set('_http_port', $db_info->http_port); + } + if($db_info->https_port) + { + $this->set('_https_port', $db_info->https_port); + } + } + + /** + * @brief get DB's db_type + * @return DB's db_type string + **/ + function getDBType() { + $oContext = &Context::getInstance(); + return $oContext->_getDBType(); + } + + /** + * @brief get DB's db_type + * @return DB's db_type string + **/ + function _getDBType() { + return $this->db_info->db_type; + } + + /** + * @brief set DB information + * @param[in] DB information object + * @return none + **/ + function setDBInfo($db_info) { + $oContext = &Context::getInstance(); + $oContext->_setDBInfo($db_info); + } + + /** + * @brief set DB information + * @param[in] DB information object + * @return none + **/ + function _setDBInfo($db_info) { + $this->db_info = $db_info; + } + + /** + * @brief get DB information + * @return DB information object + **/ + function getDBInfo() { + $oContext = &Context::getInstance(); + return $oContext->_getDBInfo(); + } + + /** + * @brief get DB information + * @return DB information object + **/ + function _getDBInfo() { + return $this->db_info; + } + + /** + * @brief return default URL + * @return default URL string + **/ + function getDefaultUrl() { + $db_info = Context::getDBInfo(); + return $db_info->default_url; + } + + /** + * @brief find supported languages + * @return array of supported languages + **/ + function loadLangSupported() { + static $lang_supported = null; + if(is_null($lang_supported)) { + $langs = file(_XE_PATH_.'common/lang/lang.info'); + foreach($langs as $val) { + list($lang_prefix, $lang_text) = explode(',',$val); + $lang_text = trim($lang_text); + $lang_supported[$lang_prefix] = $lang_text; + } + } + return $lang_supported; + } + + /** + * @brief find selected languages to serve in the site + * @return array of selected languages + **/ + function loadLangSelected() { + static $lang_selected = null; + if(is_null($lang_selected)) { + $orig_lang_file = _XE_PATH_.'common/lang/lang.info'; + $selected_lang_file = _XE_PATH_.'files/config/lang_selected.info'; + if(!file_exists($selected_lang_file) || !filesize($selected_lang_file)) { + $old_selected_lang_file = _XE_PATH_.'files/cache/lang_selected.info'; + if(file_exists($old_selected_lang_file)) { + FileHandler::copyFile($old_selected_lang_file, $selected_lang_file); + FileHandler::removeFile($old_selected_lang_file); + } + } + + if(!file_exists($selected_lang_file) || !filesize($selected_lang_file)) { + $buff = FileHandler::readFile($orig_lang_file); + FileHandler::writeFile($selected_lang_file, $buff); + $lang_selected = Context::loadLangSupported(); + } else { + $langs = file($selected_lang_file); + foreach($langs as $val) { + list($lang_prefix, $lang_text) = explode(',',$val); + $lang_text = trim($lang_text); + $lang_selected[$lang_prefix] = $lang_text; + } + } + } + return $lang_selected; + } + + /** + * @brief Single Sign On (SSO) + * @return true if module handleing is necessary in the control path of current request + **/ + function checkSSO() { + // 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; + + // pass if default URL is not set + $default_url = trim($this->db_info->default_url); + if(!$default_url) return true; + if(substr($default_url,-1)!='/') $default_url .= '/'; + + // for sites recieving SSO valdiation + if($default_url == Context::getRequestUri()) { + if(Context::get('default_url')) { + $url = base64_decode(Context::get('default_url')); + $url_info = parse_url($url); + $url_info['query'].= ($url_info['query']?'&':'').'SSOID='.session_id(); + $redirect_url = sprintf('%s://%s%s%s?%s',$url_info['scheme'],$url_info['host'],$url_info['port']?':'.$url_info['port']:'',$url_info['path'], $url_info['query']); + header("location:".$redirect_url); + return false; + } + // for sites requesting SSO validation + } else { + // result handling : set session_name() + if(Context::get('SSOID')) { + $session_name = Context::get('SSOID'); + setcookie(session_name(), $session_name); + + $url = preg_replace('/([\?\&])$/','',str_replace('SSOID='.$session_name,'',Context::getRequestUrl())); + header("location:".$url); + return false; + // send SSO request + } else if($_COOKIE['sso']!=md5(Context::getRequestUri()) && !Context::get('SSOID')) { + setcookie('sso',md5(Context::getRequestUri()),0,'/'); + $url = sprintf("%s?default_url=%s", $default_url, base64_encode(Context::getRequestUrl())); + header("location:".$url); + return false; + } + } + + return true; + } + + /** + * @biref check if FTP info is registered + * @return true: FTP information is registered, false: otherwise + **/ + function isFTPRegisted() { + $ftp_config_file = Context::getFTPConfigFile(); + if(file_exists($ftp_config_file)) return true; + return false; + } + + /** + * @brief get FTP information object + * @return FTP information object + **/ + function getFTPInfo() { + $oContext = &Context::getInstance(); + return $oContext->_getFTPInfo(); + } + + /** + * @brief get FTP information object + * @return FTP information object + **/ + function _getFTPInfo() { + if(!$this->isFTPRegisted()) return null; + + $ftp_config_file = $this->getFTPConfigFile(); + @include($ftp_config_file); + return $ftp_info; + } + + /** + * @brief add string to browser title + * @param[in] $site_title string to be added + * @return none + **/ + function addBrowserTitle($site_title) { + if(!$site_title) return; + $oContext = &Context::getInstance(); + $oContext->_addBrowserTitle($site_title); + } + + /** + * @brief add string to browser title + * @param[in] $site_title string to be added + * @return none + **/ + function _addBrowserTitle($site_title) { + if($this->site_title) $this->site_title .= ' - '.$site_title; + else $this->site_title .= $site_title; + } + + /** + * @brief set string to browser title + * @param[in] $site_title string to be set + * @return none + **/ + function setBrowserTitle($site_title) { + if(!$site_title) return; + $oContext = &Context::getInstance(); + $oContext->_setBrowserTitle($site_title); + } + + /** + * @brief set string to browser title + * @param[in] $site_title string to be set + * @return none + **/ + function _setBrowserTitle($site_title) { + $this->site_title = $site_title; + } + + /** + * @brief get browser title + * @return browser title string (htmlspecialchars applied) + **/ + function getBrowserTitle() { + $oContext = &Context::getInstance(); + return htmlspecialchars($oContext->_getBrowserTitle()); + } + + /** + * @brief get browser title + * @return browser title string + **/ + function _getBrowserTitle() { + $oModuleController = &getController('module'); + $oModuleController->replaceDefinedLangCode($this->site_title); + return $this->site_title; + } + + /** + * @brief load language file according to language type + * @param[in] $path path of the language file + * @return none + **/ + function loadLang($path) { + $oContext = &Context::getInstance(); + $oContext->_loadLang($path); + } + + /** + * @brief load language file according to language type + * @param[in] $path path of the language file + * @return none + * @remarks using $loaded_lang_files it does not load once-loaded files + **/ + function _loadLang($path) { + global $lang; + if(!is_object($lang)) $lang = new stdClass; + if(!$this->lang_type) return; + if(substr($path,-1)!='/') $path .= '/'; + $filename = sprintf('%s%s.lang.php', $path, $this->lang_type); + if(!file_exists($filename)) $filename = sprintf('%s%s.lang.php', $path, 'ko'); + if(!file_exists($filename)) return; + if(!is_array($this->loaded_lang_files)) $this->loaded_lang_files = array(); + if(in_array($filename, $this->loaded_lang_files)) return; + $this->loaded_lang_files[] = $filename; + if(file_exists($filename)) @include($filename); + } + + /** + * @brief set lang_type + * @return none + **/ + function setLangType($lang_type = 'ko') { + $oContext = &Context::getInstance(); + $oContext->_setLangType($lang_type); + $_SESSION['lang_type'] = $lang_type; + } + + /** + * @brief set lang_type + * @return none + **/ + function _setLangType($lang_type = 'ko') { + $this->lang_type = $lang_type; + $this->_set('lang_type',$lang_type); + } + + /** + * @brief get lang_type + * @return lang_type string + **/ + function getLangType() { + $oContext = &Context::getInstance(); + return $oContext->_getLangType(); + } + + /** + * @brief get lang_type + * @return lang_type string + **/ + function _getLangType() { + return $this->lang_type; + } + + /** + * @brief return string accoring to the inputed code + * @param[in] $code language variable name + * @return if string for the code exists returns it, otherwise returns original code + **/ + function getLang($code) { + if(!$code) return; + if($GLOBALS['lang']->{$code}) return $GLOBALS['lang']->{$code}; + return $code; + } + + /** + * @brief set data to lang variable + * @return none + **/ + function setLang($code, $val) { + $GLOBALS['lang']->{$code} = $val; + } + + /** + * @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) { + $charset_list = array( + 'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932', + 'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS', + 'ISO2022-CN', 'ISO2022-CN-EXT', 'ISO2022-JP', 'ISO2022-JP-2', 'ISO2022-JP-1', + 'ISO8859-6', 'ISO8859-8', 'JOHAB', 'ISO2022-KR', 'CP1255', 'CP1256', 'CP862', + 'ASCII', 'ISO8859-1', 'ISO8850-2', 'ISO8850-3', 'ISO8850-4', 'ISO8850-5', + 'ISO8850-7', 'ISO8850-9', 'ISO8850-10', 'ISO8850-13', 'ISO8850-14', + 'ISO8850-15', 'ISO8850-16', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', + 'CP1257', 'CP850', 'CP866', + ); + + $obj = clone($source_obj); + + for($i=0;$i$val) { + if(!$val) continue; + if($val && iconv($charset,$charset,$val)!=$val) $flag = false; + } + if($flag == true) { + if($charset == 'UTF-8') return $obj; + foreach($obj as $key => $val) $obj->{$key} = iconv($charset,'UTF-8',$val); + return $obj; + } + } + return $obj; + } + + /** + * @brief convert strings into UTF-8 + * @param[in] $str string to convert + * @return converted string + **/ + function convertEncodingStr($str) { + $obj->str = $str; + $obj = Context::convertEncoding($obj); + return $obj->str; + } + + /** + * @brief force to set response method + * @param[in] $method response method (HTML/XMLRPC/JSON) + * @return none + **/ + function setResponseMethod($method = "HTML") { + $oContext = &Context::getInstance(); + return $oContext->_setResponseMethod($method); + } + + /** + * @brief force to set response method + * @param[in] $method response method (HTML/XMLRPC/JSON) + * @return none + **/ + function _setResponseMethod($method = "HTML") { + $this->response_method = $method; + } + + /* + * @brief get reponse method + * @return response method string (if it's not set, returns request method) + */ + function getResponseMethod() { + $oContext = &Context::getInstance(); + return $oContext->_getResponseMethod(); + } + + /* + * @brief get reponse method + * @return response method string (if it's not set, returns request method) + */ + function _getResponseMethod() { + if($this->response_method) return $this->response_method; + + $RequestMethod = $this->_getRequestMethod(); + if($RequestMethod=="XMLRPC") return "XMLRPC"; + else if($RequestMethod=="JSON") return "JSON"; + return "HTML"; + } + + /** + * @brief determine request method (GET/POST/XMLRPC/JSON) + * @param[in] $type request method + * @return none + **/ + function setRequestMethod($type) { + $oContext = &Context::getInstance(); + $oContext->_setRequestMethod($type); + } + + + /** + * @brief deteremine request method (GET/POST/XMLRPC/JSON) + * @param[in] $type request method + * @return none + **/ + function _setRequestMethod($type = '') { + if($type) return $this->request_method = $type; + + if(strpos($_SERVER['CONTENT_TYPE'],'json')) return $this->request_method = 'JSON'; + if($GLOBALS['HTTP_RAW_POST_DATA']) return $this->request_method = "XMLRPC"; + + $this->request_method = $_SERVER['REQUEST_METHOD']; + } + + /** + * @brief handle request areguments for GET/POST + * @return none + **/ + function _setRequestArgument() { + if(!count($_REQUEST)) return; + + foreach($_REQUEST as $key => $val) { + if($val === "" || Context::get($key)) continue; + $val = $this->_filterRequestVar($key, $val); + if($this->_getRequestMethod()=='GET'&&isset($_GET[$key])) $set_to_vars = true; + elseif($this->_getRequestMethod()=='POST'&&isset($_POST[$key])) $set_to_vars = true; + else $set_to_vars = false; + $this->_set($key, $val, $set_to_vars); + } + } + + /** + * @brief handle request arguments for JSON + * @return none + **/ + function _setJSONRequestArgument() { + if($this->_getRequestMethod() != 'JSON') return; + + $params = array(); + parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$params); + + foreach($params as $key => $val) { + $val = $this->_filterRequestVar($key, $val,0); + $this->_set($key, $val, true); + } + } + + /** + * @brief handle request arguments for XML RPC + * @return none + **/ + function _setXmlRpcArgument() { + if($this->_getRequestMethod() != 'XMLRPC') return; + $oXml = new XmlParser(); + $xml_obj = $oXml->parse(); + + $params = $xml_obj->methodcall->params; + unset($params->node_name); + + unset($params->attrs); + if(!count($params)) return; + foreach($params as $key => $obj) { + $val = $this->_filterRequestVar($key, $obj->body,0); + $this->_set($key, $val, true); + } + } + + /** + * @brief Filter request variable + * @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) { + if( ($key == "page" || $key == "cpage" || substr($key,-3)=="srl")) return !preg_match('/^[0-9,]+$/',$val)?(int)$val:$val; + if(is_array($val) && count($val) ) { + foreach($val as $k => $v) { + if($do_stripslashes && version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $v = stripslashes($v); + $v = trim($v); + $val[$k] = $v; + } + } else { + if($do_stripslashes && version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $val = stripslashes($val); + $val = trim($val); + } + return $val; + } + + /** + * @brief Check if there exists uploaded file + * @return true: exists, false: otherwise + **/ + function isUploaded() { + $oContext = &Context::getInstance(); + return $oContext->_isUploaded(); + } + + /** + * @brief Check if there exists uploaded file + * @return true: exists, false: otherwise + **/ + function _isUploaded() { + return $this->is_uploaded; + } + + /** + * @brief handle uploaded file + * @return none + **/ + function _setUploadedArgument() { + if($this->_getRequestMethod() != 'POST') return; + if(!preg_match("/multipart\/form-data/i",$_SERVER['CONTENT_TYPE'])) return; + if(!$_FILES) return; + + foreach($_FILES as $key => $val) { + $tmp_name = $val['tmp_name']; + if(!$tmp_name || !is_uploaded_file($tmp_name)) continue; + $this->_set($key, $val, true); + $this->is_uploaded = true; + } + } + + /** + * @brief return request method (GET/POST/XMLRPC/JSON); + * @return request method type + **/ + function getRequestMethod() { + $oContext = &Context::getInstance(); + return $oContext->_getRequestMethod(); + } + + /** + * @brief return request method (GET/POST/XMLRPC/JSON); + * @return request method type + **/ + function _getRequestMethod() { + return $this->request_method; + } + + /** + * @brief return request URL + * @return request URL + **/ + function getRequestUrl() { + static $url = null; + if(is_null($url)) { + $url = Context::getRequestUri(); + if(count($_GET)) { + foreach($_GET as $key => $val) $vars[] = $key.'='.urlencode(Context::convertEncodingStr($val)); + $url .= '?'.implode('&',$vars); + } + } + return $url; + } + + /** + * @brief make URL with args_list upon request URL + * @return result URL + **/ + function getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) { + $oContext = &Context::getInstance(); + return $oContext->_getUrl($num_args, $args_list, $domain, $encode); + } + + /** + * @brief make URL with args_list upon request URL + * @return result URL + **/ + function _getUrl($num_args=0, $args_list=array(), $domain = null, $encode = true) { + static $site_module_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 $domain is set, handle it (if $domain is vid type, remove $domain and handle with $vid) + if($domain && isSiteID($domain)) { + $vid = $domain; + $domain = ''; + } + + // If $domain, $vid are not set, use current site information + if(!$domain && !$vid) { + if($site_module_info->domain && isSiteID($site_module_info->domain)) $vid = $site_module_info->domain; + else $domain = $site_module_info->domain; + } + + // if $domain is set, compare current URL. If they are same, remove the domain, otherwise link to the domain. + if($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($domain_info['host'].$domain_info['path']==$current_info['host'].$current_info['path']) { + unset($domain); + } else { + $domain = preg_replace('/^(http|https):\/\//i','', trim($domain)); + if(substr($domain,-1) != '/') $domain .= '/'; + } + } + + $get_vars = null; + + // If there is no GET variables or first argument is '' to reset variables + if(!$this->get_vars || $args_list[0]=='') { + // rearrange args_list + if(is_array($args_list) && $args_list[0]=='') array_shift($args_list); + } else { + // Otherwise, make GET variables into array + $get_vars = get_object_vars($this->get_vars); + } + + // arrange args_list + for($i=0,$c=count($args_list);$i<$c;$i=$i+2) { + $key = $args_list[$i]; + $val = trim($args_list[$i+1]); + + // If value is not set, remove the key + if(!isset($val) || strlen($val)<1) { + unset($get_vars[$key]); + continue; + } + // set new variables + $get_vars[$key] = $val; + } + + // remove vid, rnd + unset($get_vars['rnd']); + if($vid) $get_vars['vid'] = $vid; + else unset($get_vars['vid']); + + // for compatibility to lower versions + switch($get_vars['act']) { + case 'dispMemberFriend' : $get_vars['act'] = 'dispCommunicationFriend'; break; + case 'dispMemberMessages' : $get_vars['act'] = 'dispCommunicationMessages'; break; + case 'dispDocumentAdminManageDocument' : $get_vars['act'] = 'dispDocumentManageDocument'; break; + case 'dispModuleAdminSelectList' : $get_vars['act'] = 'dispModuleSelectList'; break; + } + + // organize URL + $query = null; + if($var_count = count($get_vars)) { + // If using rewrite mod + if($this->allow_rewrite) { + $var_keys = array_keys($get_vars); + asort($var_keys); + $target = implode('.', $var_keys); + switch($target) { + case 'vid' : $query = $get_vars['vid']; break; + case 'mid' : $query = $get_vars['mid']; break; + case 'document_srl' : $query = $get_vars['document_srl']; break; + case 'document_srl.mid' : $query = $get_vars['mid'].'/'.$get_vars['document_srl']; break; + case 'entry.mid' : $query = $get_vars['mid'].'/entry/'.$get_vars['entry']; break; + case 'act.document_srl.key' : $query = $get_vars['act']=='trackback'?$get_vars['document_srl'].'/'.$get_vars['key'].'/'.$get_vars['act']:''; break; + case 'mid.vid' : $query = $get_vars['vid'].'/'.$get_vars['mid']; break; + case 'document_srl.vid' : $query = $get_vars['vid'].'/'.$get_vars['document_srl']; break; + case 'document_srl.mid.vid' : $query = $get_vars['vid'].'/'.$get_vars['mid'].'/'.$get_vars['document_srl']; break; + case 'entry.mid.vid' : $query = $get_vars['vid'].'/'.$get_vars['mid'].'/entry/'.$get_vars['entry']; break; + case 'act.document_srl.key.vid' : $query = $get_vars['act']=='trackback'?$get_vars['vid'].'/'.$get_vars['document_srl'].'/'.$get_vars['key'].'/'.$get_vars['act']:''; break; + case 'act.mid' : $query = (in_array($get_vars['act'], array('rss', 'atom', 'api'))) ? $get_vars['mid'].'/'.$get_vars['act'] : ''; break; + case 'act.mid.vid' : $query = (in_array($get_vars['act'], array('rss', 'atom', 'api'))) ? $get_vars['vid'].'/'.$get_vars['mid'].'/'.$get_vars['act']:''; break; + } + } + + if(!$query) { + foreach($get_vars as $key => $val) { + if(is_array($val) && count($val)) { + foreach($val as $k => $v) $query .= ($query?'&':'').$key.'['.$k.']='.urlencode($v); + } else { + $query .= ($query?'&':'').$key.'='.urlencode($val); + } + } + if($query) $query = '?'.$query; + } + } + + // If using SSL always + if(Context::get('_use_ssl')=='always') { + $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query; + // optional SSL use + } elseif(Context::get('_use_ssl')=='optional') { + $ssl_mode = RELEASE_SSL; + if($get_vars['act'] && $this->_isExistsSSLAction($get_vars['act'])) $ssl_mode = ENFORCE_SSL; + $query = $this->getRequestUri($ssl_mode, $domain).$query; + // no SSL + } else { + // currently on SSL but target is not based on SSL + if($_SERVER['HTTPS']=='on' ) $query = $this->getRequestUri(ENFORCE_SSL, $domain).$query; + + // if $domain is set + else if($domain) $query = $this->getRequestUri(FOLLOW_REQUEST_SSL, $domain).$query; + + else $query = getScriptPath().$query; + } + + if($encode) return htmlspecialchars($query); + return $query; + } + + /** + * @brief 요청이 들어온 URL에서 argument를 제거하여 return + **/ + function getRequestUri($ssl_mode = FOLLOW_REQUEST_SSL, $domain = null) { + static $url = array(); + + // HTTP Request가 아니면 패스 + if(!isset($_SERVER['SERVER_PROTOCOL'])) return ; + if(Context::get('_use_ssl') == "always") $ssl_mode = ENFORCE_SSL; + + if($domain) $domain_key = md5($domain); + else $domain_key = 'default'; + + if(isset($url[$ssl_mode][$domain_key])) return $url[$ssl_mode][$domain_key]; + + $current_use_ssl = $_SERVER['HTTPS']=='on' ? true : false; + + switch($ssl_mode) { + case FOLLOW_REQUEST_SSL : + if($current_use_ssl) $use_ssl = true; + else $use_ssl = false; + break; + case ENFORCE_SSL : + $use_ssl = true; + break; + case RELEASE_SSL : + $use_ssl = false; + break; + } + + if($domain) { + $target_url = trim($domain); + if(substr($target_url,-1) != '/') $target_url.= '/'; + } else { + $target_url= $_SERVER['HTTP_HOST'].getScriptPath(); + } + + $url_info = parse_url('http://'.$target_url); + + if($current_use_ssl != $use_ssl) + { + unset($url_info['port']); + } + + if($use_ssl) { + if(Context::get("_https_port") && Context::get("_https_port") != 443) { + $url_info['port'] = Context::get("_https_port"); + } + elseif($url_info['port']==443) + { + unset($url_info['port']); + } + } else { + if(Context::get("_http_port") && Context::get("_http_port") != 80) { + $url_info['port'] = Context::get("_http_port"); + } + elseif($url_info['port']==80) + { + unset($url_info['port']); + } + } + + $url[$ssl_mode][$domain_key] = sprintf("%s://%s%s%s",$use_ssl?'https':$url_info['scheme'], $url_info['host'], $url_info['port']&&$url_info['port']!=80?':'.$url_info['port']:'',$url_info['path']); + + return $url[$ssl_mode][$domain_key]; + } + + /** + * @brief key/val로 context vars 세팅 + **/ + function set($key, $val, $set_to_get_vars = false) { + $oContext = &Context::getInstance(); + $oContext->_set($key, $val, $set_to_get_vars); + } + + /** + * @brief key/val로 context vars 세팅 + **/ + function _set($key, $val, $set_to_get_vars = false) { + $this->context->{$key} = $val; + if($set_to_get_vars || $this->get_vars->{$key}) $this->get_vars->{$key} = $val; + } + + /** + * @brief key값에 해당하는 값을 return + **/ + function get($key) { + $oContext = &Context::getInstance(); + return $oContext->_get($key); + } + + /** + * @brief key값에 해당하는 값을 return + **/ + function _get($key) { + return $this->context->{$key}; + } + + /** + * @brief 받고자 하는 변수만 object에 입력하여 받음 + * + * key1, key2, key3 .. 등의 인자를 주어 여러개의 변수를 object vars로 세팅하여 받을 수 있음 + **/ + function gets() { + $num_args = func_num_args(); + if($num_args<1) return; + $args_list = func_get_args(); + + $oContext = &Context::getInstance(); + return $oContext->_gets($num_args, $args_list); + } + + /** + * @brief 받고자 하는 변수만 object에 입력하여 받음 + * + * key1, key2, key3 .. 등의 인자를 주어 여러개의 변수를 object vars로 세팅하여 받을 수 있음 + **/ + function _gets($num_args, $args_list) { + for($i=0;$i<$num_args;$i++) { + $args = $args_list[$i]; + $output->{$args} = $this->_get($args); + } + return $output; + } + + /** + * @brief 모든 데이터를 return + **/ + function getAll() { + $oContext = &Context::getInstance(); + return $oContext->_getAll(); + } + + /** + * @brief 모든 데이터를 return + **/ + function _getAll() { + return $this->context; + } + + /** + * @brief GET/POST/XMLRPC에서 넘어온 변수값을 return + **/ + function getRequestVars() { + $oContext = &Context::getInstance(); + return $oContext->_getRequestVars(); + } + + /** + * @brief GET/POST/XMLRPC에서 넘어온 변수값을 return + **/ + function _getRequestVars() { + return clone($this->get_vars); + } + + /** + * @brief SSL로 인증되어야 할 action이 있을 경우 등록 + * common/js/xml_handler.js에서 이 action들에 대해서 https로 전송되도록 함 + **/ + function addSSLAction($action) { + $oContext = &Context::getInstance(); + return $oContext->_addSSLAction($action); + } + + function _addSSLAction($action) { + if(in_array($action, $this->ssl_actions)) return; + $this->ssl_actions[] = $action; + } + + function getSSLActions() { + $oContext = &Context::getInstance(); + return $oContext->_getSSLActions(); + } + + function _getSSLActions() { + return $this->ssl_actions; + } + + function isExistsSSLAction($action) { + $oContext = &Context::getInstance(); + return $oContext->_isExistsSSLAction($action); + } + + function _isExistsSSLAction($action) { + return in_array($action, $this->ssl_actions); + } + + /** + * @brief js file을 추가 + **/ + function addJsFile($file, $optimized = true, $targetie = '',$index=null) { + $oContext = &Context::getInstance(); + return $oContext->_addJsFile($file, $optimized, $targetie,$index); + } + + /** + * @brief js file을 추가 + **/ + function _addJsFile($file, $optimized = true, $targetie = '',$index=null) { + if(strpos($file,'://')===false && $file{0}!='/' && $file{0}!='.') $file = './'.$file; + $file = preg_replace('@/\./|(?js_files)) return; + + if(is_null($index)) $index=count($this->js_files); + for($i=$index;array_key_exists($i,$this->js_files);$i++); + $this->js_files[$i] = array('file' => $file, 'optimized' => $optimized, 'targetie' => $targetie); + } + + /** + * @brief js file을 제거 + **/ + function unloadJsFile($file, $optimized = true, $targetie = '') { + $oContext = &Context::getInstance(); + return $oContext->_unloadJsFile($file, $optimized, $targetie); + } + + /** + * @brief js file을 제거 + **/ + function _unloadJsFile($file, $optimized, $targetie) { + foreach($this->js_files as $key => $val) { + if(realpath($val['file'])==realpath($file) && $val['optimized'] == $optimized && $val['targetie'] == $targetie) { + unset($this->js_files[$key]); + return; + } + } + } + + /** + * @brief 모든 JS File을 제거 + **/ + function unloadAllJsFiles() { + $oContext = &Context::getInstance(); + return $oContext->_unloadAllJsFiles(); + } + + function _unloadAllJsFiles() { + $this->js_files = array(); + } + + /** + * @brief javascript filter 추가 + **/ + function addJsFilter($path, $filename) { + $oXmlFilter = new XmlJSFilter($path, $filename); + $oXmlFilter->compile(); + } + + /** + * @brief array_unique와 동작은 동일하나 file 첨자에 대해서만 동작함 + **/ + function _getUniqueFileList($files) { + ksort($files); + $files = array_values($files); + $filenames = array(); + $size = count($files); + for($i = 0; $i < $size; ++ $i) + { + if(in_array($files[$i]['file'], $filenames)) + unset($files[$i]); + $filenames[] = $files[$i]['file']; + } + + return $files; + } + + /** + * @brief js file 목록을 return + **/ + function getJsFile() { + $oContext = &Context::getInstance(); + return $oContext->_getJsFile(); + } + + /** + * @brief js file 목록을 return + **/ + function _getJsFile() { + require_once(_XE_PATH_."classes/optimizer/Optimizer.class.php"); + $oOptimizer = new Optimizer(); + return $oOptimizer->getOptimizedFiles($this->_getUniqueFileList($this->js_files), "js"); + } + + /** + * @brief CSS file 추가 + **/ + function addCSSFile($file, $optimized = true, $media = 'all', $targetie = '',$index = null) { + $oContext = &Context::getInstance(); + return $oContext->_addCSSFile($file, $optimized, $media, $targetie,$index); + } + + /** + * @brief CSS file 추가 + **/ + function _addCSSFile($file, $optimized = true, $media = 'all', $targetie = '', $index = null) { + if(strpos($file,'://')===false && substr($file,0,1)!='/' && substr($file,0,1)!='.') $file = './'.$file; + $file = str_replace(array('/./','//'),'/',$file); + while(strpos($file,'/../')) $file = preg_replace('/\/([^\/]+)\/\.\.\//s','/',$file,1); + + if(in_array($file, $this->css_files)) return; + + if(is_null($index)) $index=count($this->css_files); + for($i=$index;array_key_exists($i,$this->css_files);$i++); + + //if(preg_match('/^http:\/\//i',$file)) $file = str_replace(realpath("."), ".", realpath($file)); + $this->css_files[$i] = array('file' => $file, 'optimized' => $optimized, 'media' => $media, 'targetie' => $targetie); + } + + /** + * @brief css file을 제거 + **/ + function unloadCSSFile($file, $optimized = true, $media = 'all', $targetie = '') { + $oContext = &Context::getInstance(); + return $oContext->_unloadCSSFile($file, $optimized, $media, $targetie); + } + + /** + * @brief css file을 제거 + **/ + function _unloadCSSFile($file, $optimized, $media, $targetie) { + foreach($this->css_files as $key => $val) { + if(realpath($val['file'])==realpath($file) && $val['optimized'] == $optimized && $val['media'] == $media && $val['targetie'] == $targetie) { + unset($this->css_files[$key]); + return; + } + } + } + + /** + * @brief 모든 CSS File을 제거 + **/ + function unloadAllCSSFiles() { + $oContext = &Context::getInstance(); + return $oContext->_unloadAllCSSFiles(); + } + + function _unloadAllCSSFiles() { + $this->css_files = array(); + } + + /** + * @brief CSS file 목록 return + **/ + function getCSSFile() { + $oContext = &Context::getInstance(); + return $oContext->_getCSSFile(); + } + + /** + * @brief CSS file 목록 return + **/ + function _getCSSFile() { + require_once(_XE_PATH_."classes/optimizer/Optimizer.class.php"); + $oOptimizer = new Optimizer(); + return $oOptimizer->getOptimizedFiles($this->_getUniqueFileList($this->css_files), "css"); + } + + /** + * @brief javascript plugin load + **/ + function loadJavascriptPlugin($plugin_name) { + $oContext = &Context::getInstance(); + return $oContext->_loadJavascriptPlugin($plugin_name); + } + + function _loadJavascriptPlugin($plugin_name) { + static $loaded_plugins = array(); + if($loaded_plugins[$plugin_name]) return; + $loaded_plugins[$plugin_name] = true; + if($plugin_name == "ui.datepicker") return $this->_loadJavascriptPlugin("ui"); + + $plugin_path = './common/js/plugins/'.$plugin_name.'/'; + if(!is_dir($plugin_path)) return; + + $info_file = $plugin_path.'plugin.load'; + if(!file_exists($info_file)) return; + + $list = file($info_file); + for($i=0,$cnt=count($list);$i<$cnt;$i++) { + $filename = trim($list[$i]); + if(!$filename) continue; + if(substr($filename,0,2)=='./') $filename = substr($filename,2); + if(preg_match('/\.js$/i',$filename)) $this->_addJsFile($plugin_path.$filename, true, '', null); + elseif(preg_match('/\.css$/i',$filename)) $this->_addCSSFile($plugin_path.$filename, true, 'all','', null); + } + + if(is_dir($plugin_path.'lang')) $this->_loadLang($plugin_path.'lang'); + } + + /** + * @brief HtmlHeader 추가 + **/ + function addHtmlHeader($header) { + $oContext = &Context::getInstance(); + return $oContext->_addHtmlHeader($header); + } + + /** + * @brief HtmlHeader 추가 + **/ + function _addHtmlHeader($header) { + $this->html_header .= "\n".$header; + } + + /** + * @brief HtmlHeader return + **/ + function getHtmlHeader() { + $oContext = &Context::getInstance(); + return $oContext->_getHtmlHeader(); + } + + /** + * @brief HtmlHeader return + **/ + function _getHtmlHeader() { + return $this->html_header; + } + + /** + * @brief Html Body에 css class 추가 + **/ + function addBodyClass($class_name) { + $oContext = &Context::getInstance(); + return $oContext->_addBodyClass($class_name); + } + + /** + * @brief Html Body에 css class 추가 + **/ + function _addBodyClass($class_name) { + $this->body_class[] = $class_name; + } + + /** + * @brief Html Body에 css class return + **/ + function getBodyClass() { + $oContext = &Context::getInstance(); + return $oContext->_getBodyClass(); + } + + /** + * @brief Html Body에 css class return + **/ + function _getBodyClass() { + $this->body_class = array_unique($this->body_class); + if(count($this->body_class)>0) return sprintf(' class="%s"', join(' ',$this->body_class)); + else return ''; + } + + + /** + * @brief BodyHeader 추가 + **/ + function addBodyHeader($header) { + $oContext = &Context::getInstance(); + return $oContext->_addBodyHeader($header); + } + + /** + * @brief BodyHeader 추가 + **/ + function _addBodyHeader($header) { + $this->body_header .= "\n".$header; + } + + /** + * @brief BodyHeader return + **/ + function getBodyHeader() { + $oContext = &Context::getInstance(); + return $oContext->_getBodyHeader(); + } + + /** + * @brief BodyHeader return + **/ + function _getBodyHeader() { + return $this->body_header; + } + + /** + * @brief HtmlFooter 추가 + **/ + function addHtmlFooter($footer) { + $oContext = &Context::getInstance(); + return $oContext->_addHtmlFooter($footer); + } + + /** + * @brief HtmlFooter 추가 + **/ + function _addHtmlFooter ($footer) { + $this->html_footer .= ($this->Htmlfooter?"\n":"").$footer; + } + + /** + * @brief HtmlFooter return + **/ + function getHtmlFooter() { + $oContext = &Context::getInstance(); + return $oContext->_getHtmlFooter(); + } + + /** + * @brief HtmlFooter return + **/ + function _getHtmlFooter() { + return $this->html_footer; + } + + /** + * @brief db설정내용이 저장되어 있는 config file의 path를 return + **/ + function getConfigFile() { + return _XE_PATH_."files/config/db.config.php"; + } + + /** + * @brief ftp설정내용이 저장되어 있는 config file의 path를 return + **/ + function getFTPConfigFile() { + return _XE_PATH_."files/config/ftp.config.php"; + } + + /** + * @brief 설치가 되어 있는지에 대한 체크 + * + * 단순히 db config 파일의 존재 유무로 설치 여부를 체크한다 + **/ + function isInstalled() { + return file_exists(Context::getConfigFile()) && filesize(Context::getConfigFile()); + } + + /** + * @brief 내용의 위젯이나 기타 기능에 대한 code를 실제 code로 변경 + **/ + function transContent($content) { + return $content; + } + + /** + * @brief rewrite mod 사용에 대한 변수 return + **/ + function isAllowRewrite() { + $oContext = &Context::getInstance(); + return $oContext->allow_rewrite; + } + + /** + * @brief 로컬 경로를 웹 경로로 변경 + */ + function pathToUrl($path) { + $xe = _XE_PATH_; + $path = strtr($path, "\\", "/"); + + $base_url = preg_replace('@^https?://[^/]+/?@', '', Context::getRequestUri()); + + $_xe = explode('/', $xe); + $_path = explode('/', $path); + $_base = explode('/', $base_url); + + if (!$_base[count($_base)-1]) array_pop($_base); + + foreach($_xe as $idx=>$dir) { + if($_path[0] != $dir) break; + array_shift($_path); + } + + $idx = count($_xe) - $idx - 1; + while($idx--) { + if (count($_base)) array_shift($_base); + else array_unshift($_base, '..'); + } + + if (count($_base)) { + array_unshift($_path, implode('/', $_base)); + } + + $path = '/'.implode('/', $_path); + + return $path; + } + } +?> diff --git a/classes/db/DB.class.php b/classes/db/DB.class.php index 29de6cf01..d16299c1f 100644 --- a/classes/db/DB.class.php +++ b/classes/db/DB.class.php @@ -1,628 +1,628 @@ - '=', - 'more' => '>=', - 'excess' => '>', - 'less' => '<=', - 'below' => '<', - 'notequal' => '<>', - 'notnull' => 'is not null', - 'null' => 'is null', - ); - - var $fd = NULL; ///< connector resource or file description - - var $result = NULL; ///< result - - var $errno = 0; ///< error code (0 means no error) - var $errstr = ''; ///< error message - var $query = ''; ///< query string of latest executed query - var $elapsed_time = 0; ///< elapsed time of latest executed query - - var $transaction_started = false; ///< transaction flag - - var $is_connected = false; ///< is db connected - - var $supported_list = array(); ///< list of supported db, (will be written by classes/DB/DB***.class.php) - - var $cache_file = 'files/cache/queries/'; ///< location of query cache - - /** - * @brief returns instance of certain db type - * @param[in] $db_type type of db - * @return instance - **/ - function &getInstance($db_type = NULL) { - if(!$db_type) $db_type = Context::getDBType(); - if(!$db_type && Context::isInstalled()) return new Object(-1, 'msg_db_not_setted'); - - if(!$GLOBALS['__DB__']) { - $class_name = sprintf("DB%s%s", strtoupper(substr($db_type, 0, 1)), strtolower(substr($db_type,1))); - $class_file = sprintf("%sclasses/db/%s.class.php", _XE_PATH_, $class_name); - if(!file_exists($class_file)) new Object(-1, 'msg_db_not_setted'); - - require_once($class_file); - $eval_str = sprintf('$GLOBALS[\'__DB__\'][\''.$db_type.'\'] = new %s();', $class_name); - eval($eval_str); - } - - return $GLOBALS['__DB__'][$db_type]; - } - - /** - * @brief constructor - * @return none - **/ - function DB() { - $this->count_cache_path = _XE_PATH_.$this->count_cache_path; - $this->cache_file = _XE_PATH_.$this->cache_file; - } - - /** - * @brief returns list of supported db - * @return list of supported db - **/ - function getSupportedList() { - $oDB = new DB(); - return $oDB->_getSupportedList(); - } - - /** - * @brief returns list of supported db - * @return list of supported db - **/ - function _getSupportedList() { - $db_classes_path = _XE_PATH_."classes/db/"; - $filter = "/^DB([^\.]+)\.class\.php/i"; - $supported_list = FileHandler::readDir($db_classes_path, $filter, true); - sort($supported_list); - - // after creating instance of class, check is supported - for($i = 0; $i < count($supported_list); $i++) { - $db_type = $supported_list[$i]; - - if(version_compare(phpversion(), '5.0') < 0 && preg_match('/pdo/i',$db_type)) continue; - - $class_name = sprintf("DB%s%s", strtoupper(substr($db_type,0,1)), strtolower(substr($db_type,1))); - $class_file = sprintf(_XE_PATH_."classes/db/%s.class.php", $class_name); - if(!file_exists($class_file)) continue; - - unset($oDB); - require_once($class_file); - $eval_str = sprintf('$oDB = new %s();', $class_name); - eval($eval_str); - - if(!$oDB) continue; - - $obj = null; - $obj->db_type = $db_type; - $obj->enable = $oDB->isSupported() ? true : false; - - $this->supported_list[] = $obj; - } - - return $this->supported_list; - } - - /** - * @brief check if the db_type is supported - * @param[in] $db_type type of db to check - * @return true: is supported, false: is not supported - **/ - function isSupported($db_type) { - $supported_list = DB::getSupportedList(); - return in_array($db_type, $supported_list); - } - - /** - * @brief check if is connected - * @return true: connected, false: not connected - **/ - function isConnected() { - return $this->is_connected ? true : false; - } - - /** - * @brief start recording log - * @return none - **/ - function actStart($query) { - $this->setError(0, 'success'); - $this->query = $query; - $this->act_start = getMicroTime(); - $this->elapsed_time = 0; - } - - /** - * @brief finish recording log - * @return none - **/ - function actFinish() { - if(!$this->query) return; - $this->act_finish = getMicroTime(); - $elapsed_time = $this->act_finish - $this->act_start; - $this->elapsed_time = $elapsed_time; - $GLOBALS['__db_elapsed_time__'] += $elapsed_time; - - $log['query'] = $this->query; - $log['elapsed_time'] = $elapsed_time; - - // leave error log if an error occured (if __DEBUG_DB_OUTPUT__ is defined) - if($this->isError()) { - $site_module_info = Context::get('site_module_info'); - $log['module'] = $site_module_info->module; - $log['act'] = Context::get('act'); - $log['query_id'] = $this->query_id; - $log['time'] = date('Y-m-d H:i:s'); - $log['result'] = 'Failed'; - $log['errno'] = $this->errno; - $log['errstr'] = $this->errstr; - - if(__DEBUG_DB_OUTPUT__ == 1) { - $debug_file = _XE_PATH_."files/_debug_db_query.php"; - $buff = array(); - if(!file_exists($debug_file)) $buff[] = ''; - $buff[] = print_r($log, true); - - if(@!$fp = fopen($debug_file, "a")) return; - fwrite($fp, implode("\n", $buff)."\n\n"); - fclose($fp); - } - } else { - $log['result'] = 'Success'; - } - $GLOBALS['__db_queries__'][] = $log; - - // if __LOG_SLOW_QUERY__ if defined, check elapsed time and leave query log - if(__LOG_SLOW_QUERY__ > 0 && $elapsed_time > __LOG_SLOW_QUERY__) { - $buff = ''; - $log_file = _XE_PATH_.'files/_db_slow_query.php'; - if(!file_exists($log_file)) { - $buff = ''."\n"; - } - - $buff .= sprintf("%s\t%s\n\t%0.6f sec\tquery_id:%s\n\n", date("Y-m-d H:i"), $this->query, $elapsed_time, $this->query_id); - - if($fp = fopen($log_file, 'a')) { - fwrite($fp, $buff); - fclose($fp); - } - } - } - - /** - * @brief set error - * @param[in] $errno error code - * @param[in] $errstr error message - * @return none - **/ - function setError($errno = 0, $errstr = 'success') { - $this->errno = $errno; - $this->errstr = $errstr; - } - - /** - * @brief check if an error occured - * @return true: error, false: no error - **/ - function isError() { - return $this->errno === 0 ? false : true; - } - - /** - * @brief returns object of error info - * @return object of error - **/ - function getError() { - $this->errstr = Context::convertEncodingStr($this->errstr); - return new Object($this->errno, $this->errstr); - } - - /** - * @brief query xml 파일을 실행하여 결과를 return - * @param[in] $query_id query id (module.queryname - * @param[in] $args arguments for query - * @return result of query - * @remarks this function finds xml file or cache file of $query_id, compiles it and then execute it - **/ - function executeQuery($query_id, $args = NULL) { - if(!$query_id) return new Object(-1, 'msg_invalid_queryid'); - $this->query_id = $query_id; - - $id_args = explode('.', $query_id); - if(count($id_args) == 2) { - $target = 'modules'; - $module = $id_args[0]; - $id = $id_args[1]; - } elseif(count($id_args) == 3) { - $target = $id_args[0]; - if(!in_array($target, array('addons','widgets'))) return; - $module = $id_args[1]; - $id = $id_args[2]; - } - if(!$target || !$module || !$id) return new Object(-1, 'msg_invalid_queryid'); - - $xml_file = sprintf('%s%s/%s/queries/%s.xml', _XE_PATH_, $target, $module, $id); - if(!file_exists($xml_file)) return new Object(-1, 'msg_invalid_queryid'); - - // look for cache file - $cache_file = $this->checkQueryCacheFile($query_id, $xml_file); - - // execute query - return $this->_executeQuery($cache_file, $args, $query_id); - } - - - /** - * @brief look for cache file - * @param[in] $query_id query id for finding - * @param[in] $xml_file original xml query file - * @return cache file - **/ - function checkQueryCacheFile($query_id,$xml_file){ - - // first try finding cache file - $cache_file = sprintf('%s%s%s.cache.php', _XE_PATH_, $this->cache_file, $query_id); - - if(file_exists($cache_file)) $cache_time = filemtime($cache_file); - else $cache_time = -1; - - // if there is no cache file or is not new, find original xml query file and parse it - if($cache_time < filemtime($xml_file) || $cache_time < filemtime(_XE_PATH_.'classes/db/DB.class.php')) { - require_once(_XE_PATH_.'classes/xml/XmlQueryParser.class.php'); - $oParser = new XmlQueryParser(); - $oParser->parse($query_id, $xml_file, $cache_file); - } - - return $cache_file; - } - - - /** - * @brief execute query and return the result - * @param[in] $cache_file cache file of query - * @param[in] $source_args arguments for query - * @param[in] $query_id query id - * @return result of query - **/ - function _executeQuery($cache_file, $source_args, $query_id) { - global $lang; - - if(!file_exists($cache_file)) return new Object(-1, 'msg_invalid_queryid'); - - if($source_args) $args = @clone($source_args); - - $output = @include($cache_file); - - if( (is_a($output, 'Object') || is_subclass_of($output, 'Object')) && !$output->toBool()) return $output; - $output->_tables = ($output->_tables && is_array($output->_tables)) ? $output->_tables : array(); - - // execute appropriate query - switch($output->action) { - case 'insert' : - $this->resetCountCache($output->tables); - $output = $this->_executeInsertAct($output); - break; - case 'update' : - $this->resetCountCache($output->tables); - $output = $this->_executeUpdateAct($output); - break; - case 'delete' : - $this->resetCountCache($output->tables); - $output = $this->_executeDeleteAct($output); - break; - case 'select' : - $output = $this->_executeSelectAct($output); - break; - } - if($this->isError()) $output = $this->getError(); - else if(!is_a($output, 'Object') && !is_subclass_of($output, 'Object')) $output = new Object(); - $output->add('_query', $this->query); - $output->add('_elapsed_time', sprintf("%0.5f", $this->elapsed_time)); - - return $output; - } - - /** - * @brief check $val with $filter_type - * @param[in] $key key value - * @param[in] $val value of $key - * @param[in] $filter_type type of filter to check $val - * @return object - * @remarks this function is to be used from XmlQueryParser - **/ - function checkFilter($key, $val, $filter_type) { - global $lang; - - switch($filter_type) { - case 'email' : - case 'email_address' : - if(!preg_match('/^[_0-9a-z-]+(\.[_0-9a-z-]+)*@[0-9a-z-]+(\.[0-9a-z-]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_email, $lang->{$key} ? $lang->{$key} : $key)); - break; - case 'homepage' : - if(!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_homepage, $lang->{$key} ? $lang->{$key} : $key)); - break; - case 'userid' : - case 'user_id' : - if(!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_userid, $lang->{$key} ? $lang->{$key} : $key)); - break; - case 'number' : - case 'numbers' : - if(!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key)); - break; - case 'alpha' : - if(!preg_match('/^[a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key} ? $lang->{$key} : $key)); - break; - case 'alpha_number' : - if(!preg_match('/^[0-9a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key} ? $lang->{$key} : $key)); - break; - } - - return new Object(); - } - - /** - * @brief returns type of column - * @param[in] $column_type_list list of column type - * @param[in] $name name of column type - * @return column type of $name - * @remarks columns are usually like a.b, so it needs another function - **/ - function getColumnType($column_type_list, $name) { - if(strpos($name, '.') === false) return $column_type_list[$name]; - list($prefix, $name) = explode('.', $name); - return $column_type_list[$name]; - } - - /** - * @brief returns the value of condition - * @param[in] $name name of condition - * @param[in] $value value of condition - * @param[in] $operation operation this is used in condition - * @param[in] $type type of condition - * @param[in] $column_type type of column - * @return well modified $value - * @remarks if $operation is like or like_prefix, $value itself will be modified - * @remarks if $type is not 'number', call addQuotes() and wrap with ' ' - **/ - function getConditionValue($name, $value, $operation, $type, $column_type) { - if($type == 'number') { - if(strpos($value, ',') === false && strpos($value, '(') === false) return (int)$value; - return $value; - } - - if(strpos($name, '.') !== false && strpos($value, '.') !== false) { - list($table_name, $column_name) = explode('.', $value); - if($column_type[$column_name]) return $value; - } - - $value = preg_replace('/(^\'|\'$){1}/', '', $value); - - switch($operation) { - case 'like_prefix' : - $value = $value.'%'; - break; - case 'like_tail' : - $value = '%'.$value; - break; - case 'like' : - $value = '%'.$value.'%'; - break; - case 'notin' : - return "'".$value."'"; - break; - case 'in' : - return "'".$value."'"; - break; - } - - return "'".$this->addQuotes($value)."'"; - } - - /** - * @brief returns part of condition - * @param[in] $name name of condition - * @param[in] $value value of condition - * @param[in] $operation operation that is used in condition - * @return detail condition - **/ - function getConditionPart($name, $value, $operation) { - switch($operation) { - case 'equal' : - case 'more' : - case 'excess' : - case 'less' : - case 'below' : - case 'like_tail' : - case 'like_prefix' : - case 'like' : - case 'in' : - case 'notin' : - case 'notequal' : - // if variable is not set or is not string or number, return - if(!isset($value)) return; - if($value === '') return; - if(!in_array(gettype($value), array('string', 'integer'))) return; - } - - switch($operation) { - case 'equal' : - return $name.' = '.$value; - break; - case 'more' : - return $name.' >= '.$value; - break; - case 'excess' : - return $name.' > '.$value; - break; - case 'less' : - return $name.' <= '.$value; - break; - case 'below' : - return $name.' < '.$value; - break; - case 'like_tail' : - case 'like_prefix' : - case 'like' : - return $name.' like '.$value; - break; - case 'in' : - return $name.' in ('.$value.')'; - break; - case 'notin' : - return $name.' not in ('.$value.')'; - break; - case 'notequal' : - return $name.' <> '.$value; - break; - case 'notnull' : - return $name.' is not null'; - break; - case 'null' : - return $name.' is null'; - break; - } - } - - /** - * @brief returns condition key - * @param[in] $output result of query - * @return array of conditions of $output - **/ - function getConditionList($output) { - $conditions = array(); - if(count($output->conditions)) { - foreach($output->conditions as $key => $val) { - if($val['condition']) { - foreach($val['condition'] as $k => $v) { - $conditions[] = $v['column']; - } - } - } - } - - return $conditions; - } - - /** - * @brief returns counter cache data - * @param[in] $tables tables to get data - * @param[in] $condition condition to get data - * @return count of cache data - **/ - function getCountCache($tables, $condition) { - return false; - if(!$tables) return false; - if(!is_dir($this->count_cache_path)) return FileHandler::makeDir($this->count_cache_path); - - $condition = md5($condition); - - if(!is_array($tables)) $tables_str = $tables; - else $tables_str = implode('.',$tables); - - $cache_path = sprintf('%s/%s%s', $this->count_cache_path, $this->prefix, $tables_str); - if(!is_dir($cache_path)) FileHandler::makeDir($cache_path); - - $cache_filename = sprintf('%s/%s.%s', $cache_path, $tables_str, $condition); - if(!file_exists($cache_filename)) return false; - - $cache_mtime = filemtime($cache_filename); - - if(!is_array($tables)) $tables = array($tables); - foreach($tables as $alias => $table) { - $table_filename = sprintf('%s/cache.%s%s', $this->count_cache_path, $this->prefix, $table) ; - if(!file_exists($table_filename) || filemtime($table_filename) > $cache_mtime) return false; - } - - $count = (int)FileHandler::readFile($cache_filename); - return $count; - } - - /** - * @brief save counter cache data - * @param[in] $tables tables to save data - * @param[in] $condition condition to save data - * @param[in] $count count of cache data to save - * @return none - **/ - function putCountCache($tables, $condition, $count = 0) { - return false; - if(!$tables) return false; - if(!is_dir($this->count_cache_path)) return FileHandler::makeDir($this->count_cache_path); - - $condition = md5($condition); - - if(!is_array($tables)) $tables_str = $tables; - else $tables_str = implode('.',$tables); - - $cache_path = sprintf('%s/%s%s', $this->count_cache_path, $this->prefix, $tables_str); - if(!is_dir($cache_path)) FileHandler::makeDir($cache_path); - - $cache_filename = sprintf('%s/%s.%s', $cache_path, $tables_str, $condition); - - FileHandler::writeFile($cache_filename, $count); - } - - /** - * @brief reset counter cache data - * @param[in] $tables tables to reset cache data - * @return true: success, false: failed - **/ - function resetCountCache($tables) { - return false; - if(!$tables) return false; - if(!is_dir($this->count_cache_path)) return FileHandler::makeDir($this->count_cache_path); - - if(!is_array($tables)) $tables = array($tables); - foreach($tables as $alias => $table) { - $filename = sprintf('%s/cache.%s%s', $this->count_cache_path, $this->prefix, $table); - FileHandler::removeFile($filename); - FileHandler::writeFile($filename, ''); - } - - return true; - } - - /** - * @brief returns supported database list - * @return list of supported database - **/ - function getSupportedDatabase(){ - $result = array(); - - if(function_exists('mysql_connect')) $result[] = 'MySQL'; - if(function_exists('cubrid_connect')) $result[] = 'Cubrid'; - if(function_exists('ibase_connect')) $result[] = 'FireBird'; - if(function_exists('pg_connect')) $result[] = 'Postgre'; - if(function_exists('sqlite_open')) $result[] = 'sqlite2'; - if(function_exists('mssql_connect')) $result[] = 'MSSQL'; - if(function_exists('PDO')) $result[] = 'sqlite3(PDO)'; - - return $result; - } - - function dropTable($table_name){ - if(!$table_name) return; - $query = sprintf("drop table %s%s", $this->prefix, $table_name); - $this->_query($query); - } - } -?> + '=', + 'more' => '>=', + 'excess' => '>', + 'less' => '<=', + 'below' => '<', + 'notequal' => '<>', + 'notnull' => 'is not null', + 'null' => 'is null', + ); + + var $fd = NULL; ///< connector resource or file description + + var $result = NULL; ///< result + + var $errno = 0; ///< error code (0 means no error) + var $errstr = ''; ///< error message + var $query = ''; ///< query string of latest executed query + var $elapsed_time = 0; ///< elapsed time of latest executed query + + var $transaction_started = false; ///< transaction flag + + var $is_connected = false; ///< is db connected + + var $supported_list = array(); ///< list of supported db, (will be written by classes/DB/DB***.class.php) + + var $cache_file = 'files/cache/queries/'; ///< location of query cache + + /** + * @brief returns instance of certain db type + * @param[in] $db_type type of db + * @return instance + **/ + function &getInstance($db_type = NULL) { + if(!$db_type) $db_type = Context::getDBType(); + if(!$db_type && Context::isInstalled()) return new Object(-1, 'msg_db_not_setted'); + + if(!$GLOBALS['__DB__']) { + $class_name = sprintf("DB%s%s", strtoupper(substr($db_type, 0, 1)), strtolower(substr($db_type,1))); + $class_file = sprintf("%sclasses/db/%s.class.php", _XE_PATH_, $class_name); + if(!file_exists($class_file)) new Object(-1, 'msg_db_not_setted'); + + require_once($class_file); + $eval_str = sprintf('$GLOBALS[\'__DB__\'][\''.$db_type.'\'] = new %s();', $class_name); + eval($eval_str); + } + + return $GLOBALS['__DB__'][$db_type]; + } + + /** + * @brief constructor + * @return none + **/ + function DB() { + $this->count_cache_path = _XE_PATH_.$this->count_cache_path; + $this->cache_file = _XE_PATH_.$this->cache_file; + } + + /** + * @brief returns list of supported db + * @return list of supported db + **/ + function getSupportedList() { + $oDB = new DB(); + return $oDB->_getSupportedList(); + } + + /** + * @brief returns list of supported db + * @return list of supported db + **/ + function _getSupportedList() { + $db_classes_path = _XE_PATH_."classes/db/"; + $filter = "/^DB([^\.]+)\.class\.php/i"; + $supported_list = FileHandler::readDir($db_classes_path, $filter, true); + sort($supported_list); + + // after creating instance of class, check is supported + for($i = 0; $i < count($supported_list); $i++) { + $db_type = $supported_list[$i]; + + if(version_compare(phpversion(), '5.0') < 0 && preg_match('/pdo/i',$db_type)) continue; + + $class_name = sprintf("DB%s%s", strtoupper(substr($db_type,0,1)), strtolower(substr($db_type,1))); + $class_file = sprintf(_XE_PATH_."classes/db/%s.class.php", $class_name); + if(!file_exists($class_file)) continue; + + unset($oDB); + require_once($class_file); + $eval_str = sprintf('$oDB = new %s();', $class_name); + eval($eval_str); + + if(!$oDB) continue; + + $obj = null; + $obj->db_type = $db_type; + $obj->enable = $oDB->isSupported() ? true : false; + + $this->supported_list[] = $obj; + } + + return $this->supported_list; + } + + /** + * @brief check if the db_type is supported + * @param[in] $db_type type of db to check + * @return true: is supported, false: is not supported + **/ + function isSupported($db_type) { + $supported_list = DB::getSupportedList(); + return in_array($db_type, $supported_list); + } + + /** + * @brief check if is connected + * @return true: connected, false: not connected + **/ + function isConnected() { + return $this->is_connected ? true : false; + } + + /** + * @brief start recording log + * @return none + **/ + function actStart($query) { + $this->setError(0, 'success'); + $this->query = $query; + $this->act_start = getMicroTime(); + $this->elapsed_time = 0; + } + + /** + * @brief finish recording log + * @return none + **/ + function actFinish() { + if(!$this->query) return; + $this->act_finish = getMicroTime(); + $elapsed_time = $this->act_finish - $this->act_start; + $this->elapsed_time = $elapsed_time; + $GLOBALS['__db_elapsed_time__'] += $elapsed_time; + + $log['query'] = $this->query; + $log['elapsed_time'] = $elapsed_time; + + // leave error log if an error occured (if __DEBUG_DB_OUTPUT__ is defined) + if($this->isError()) { + $site_module_info = Context::get('site_module_info'); + $log['module'] = $site_module_info->module; + $log['act'] = Context::get('act'); + $log['query_id'] = $this->query_id; + $log['time'] = date('Y-m-d H:i:s'); + $log['result'] = 'Failed'; + $log['errno'] = $this->errno; + $log['errstr'] = $this->errstr; + + if(__DEBUG_DB_OUTPUT__ == 1) { + $debug_file = _XE_PATH_."files/_debug_db_query.php"; + $buff = array(); + if(!file_exists($debug_file)) $buff[] = ''; + $buff[] = print_r($log, true); + + if(@!$fp = fopen($debug_file, "a")) return; + fwrite($fp, implode("\n", $buff)."\n\n"); + fclose($fp); + } + } else { + $log['result'] = 'Success'; + } + $GLOBALS['__db_queries__'][] = $log; + + // if __LOG_SLOW_QUERY__ if defined, check elapsed time and leave query log + if(__LOG_SLOW_QUERY__ > 0 && $elapsed_time > __LOG_SLOW_QUERY__) { + $buff = ''; + $log_file = _XE_PATH_.'files/_db_slow_query.php'; + if(!file_exists($log_file)) { + $buff = ''."\n"; + } + + $buff .= sprintf("%s\t%s\n\t%0.6f sec\tquery_id:%s\n\n", date("Y-m-d H:i"), $this->query, $elapsed_time, $this->query_id); + + if($fp = fopen($log_file, 'a')) { + fwrite($fp, $buff); + fclose($fp); + } + } + } + + /** + * @brief set error + * @param[in] $errno error code + * @param[in] $errstr error message + * @return none + **/ + function setError($errno = 0, $errstr = 'success') { + $this->errno = $errno; + $this->errstr = $errstr; + } + + /** + * @brief check if an error occured + * @return true: error, false: no error + **/ + function isError() { + return $this->errno === 0 ? false : true; + } + + /** + * @brief returns object of error info + * @return object of error + **/ + function getError() { + $this->errstr = Context::convertEncodingStr($this->errstr); + return new Object($this->errno, $this->errstr); + } + + /** + * @brief query xml 파일을 실행하여 결과를 return + * @param[in] $query_id query id (module.queryname + * @param[in] $args arguments for query + * @return result of query + * @remarks this function finds xml file or cache file of $query_id, compiles it and then execute it + **/ + function executeQuery($query_id, $args = NULL) { + if(!$query_id) return new Object(-1, 'msg_invalid_queryid'); + $this->query_id = $query_id; + + $id_args = explode('.', $query_id); + if(count($id_args) == 2) { + $target = 'modules'; + $module = $id_args[0]; + $id = $id_args[1]; + } elseif(count($id_args) == 3) { + $target = $id_args[0]; + if(!in_array($target, array('addons','widgets'))) return; + $module = $id_args[1]; + $id = $id_args[2]; + } + if(!$target || !$module || !$id) return new Object(-1, 'msg_invalid_queryid'); + + $xml_file = sprintf('%s%s/%s/queries/%s.xml', _XE_PATH_, $target, $module, $id); + if(!file_exists($xml_file)) return new Object(-1, 'msg_invalid_queryid'); + + // look for cache file + $cache_file = $this->checkQueryCacheFile($query_id, $xml_file); + + // execute query + return $this->_executeQuery($cache_file, $args, $query_id); + } + + + /** + * @brief look for cache file + * @param[in] $query_id query id for finding + * @param[in] $xml_file original xml query file + * @return cache file + **/ + function checkQueryCacheFile($query_id,$xml_file){ + + // first try finding cache file + $cache_file = sprintf('%s%s%s.cache.php', _XE_PATH_, $this->cache_file, $query_id); + + if(file_exists($cache_file)) $cache_time = filemtime($cache_file); + else $cache_time = -1; + + // if there is no cache file or is not new, find original xml query file and parse it + if($cache_time < filemtime($xml_file) || $cache_time < filemtime(_XE_PATH_.'classes/db/DB.class.php')) { + require_once(_XE_PATH_.'classes/xml/XmlQueryParser.class.php'); + $oParser = new XmlQueryParser(); + $oParser->parse($query_id, $xml_file, $cache_file); + } + + return $cache_file; + } + + + /** + * @brief execute query and return the result + * @param[in] $cache_file cache file of query + * @param[in] $source_args arguments for query + * @param[in] $query_id query id + * @return result of query + **/ + function _executeQuery($cache_file, $source_args, $query_id) { + global $lang; + + if(!file_exists($cache_file)) return new Object(-1, 'msg_invalid_queryid'); + + if($source_args) $args = @clone($source_args); + + $output = @include($cache_file); + + if( (is_a($output, 'Object') || is_subclass_of($output, 'Object')) && !$output->toBool()) return $output; + $output->_tables = ($output->_tables && is_array($output->_tables)) ? $output->_tables : array(); + + // execute appropriate query + switch($output->action) { + case 'insert' : + $this->resetCountCache($output->tables); + $output = $this->_executeInsertAct($output); + break; + case 'update' : + $this->resetCountCache($output->tables); + $output = $this->_executeUpdateAct($output); + break; + case 'delete' : + $this->resetCountCache($output->tables); + $output = $this->_executeDeleteAct($output); + break; + case 'select' : + $output = $this->_executeSelectAct($output); + break; + } + if($this->isError()) $output = $this->getError(); + else if(!is_a($output, 'Object') && !is_subclass_of($output, 'Object')) $output = new Object(); + $output->add('_query', $this->query); + $output->add('_elapsed_time', sprintf("%0.5f", $this->elapsed_time)); + + return $output; + } + + /** + * @brief check $val with $filter_type + * @param[in] $key key value + * @param[in] $val value of $key + * @param[in] $filter_type type of filter to check $val + * @return object + * @remarks this function is to be used from XmlQueryParser + **/ + function checkFilter($key, $val, $filter_type) { + global $lang; + + switch($filter_type) { + case 'email' : + case 'email_address' : + if(!preg_match('/^[_0-9a-z-]+(\.[_0-9a-z-]+)*@[0-9a-z-]+(\.[0-9a-z-]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_email, $lang->{$key} ? $lang->{$key} : $key)); + break; + case 'homepage' : + if(!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_homepage, $lang->{$key} ? $lang->{$key} : $key)); + break; + case 'userid' : + case 'user_id' : + if(!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_userid, $lang->{$key} ? $lang->{$key} : $key)); + break; + case 'number' : + case 'numbers' : + if(!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_number, $lang->{$key} ? $lang->{$key} : $key)); + break; + case 'alpha' : + if(!preg_match('/^[a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key} ? $lang->{$key} : $key)); + break; + case 'alpha_number' : + if(!preg_match('/^[0-9a-z]+$/is', $val)) return new Object(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key} ? $lang->{$key} : $key)); + break; + } + + return new Object(); + } + + /** + * @brief returns type of column + * @param[in] $column_type_list list of column type + * @param[in] $name name of column type + * @return column type of $name + * @remarks columns are usually like a.b, so it needs another function + **/ + function getColumnType($column_type_list, $name) { + if(strpos($name, '.') === false) return $column_type_list[$name]; + list($prefix, $name) = explode('.', $name); + return $column_type_list[$name]; + } + + /** + * @brief returns the value of condition + * @param[in] $name name of condition + * @param[in] $value value of condition + * @param[in] $operation operation this is used in condition + * @param[in] $type type of condition + * @param[in] $column_type type of column + * @return well modified $value + * @remarks if $operation is like or like_prefix, $value itself will be modified + * @remarks if $type is not 'number', call addQuotes() and wrap with ' ' + **/ + function getConditionValue($name, $value, $operation, $type, $column_type) { + if($type == 'number') { + if(strpos($value, ',') === false && strpos($value, '(') === false) return (int)$value; + return $value; + } + + if(strpos($name, '.') !== false && strpos($value, '.') !== false) { + list($table_name, $column_name) = explode('.', $value); + if($column_type[$column_name]) return $value; + } + + $value = preg_replace('/(^\'|\'$){1}/', '', $value); + + switch($operation) { + case 'like_prefix' : + $value = $value.'%'; + break; + case 'like_tail' : + $value = '%'.$value; + break; + case 'like' : + $value = '%'.$value.'%'; + break; + case 'notin' : + return "'".$value."'"; + break; + case 'in' : + return "'".$value."'"; + break; + } + + return "'".$this->addQuotes($value)."'"; + } + + /** + * @brief returns part of condition + * @param[in] $name name of condition + * @param[in] $value value of condition + * @param[in] $operation operation that is used in condition + * @return detail condition + **/ + function getConditionPart($name, $value, $operation) { + switch($operation) { + case 'equal' : + case 'more' : + case 'excess' : + case 'less' : + case 'below' : + case 'like_tail' : + case 'like_prefix' : + case 'like' : + case 'in' : + case 'notin' : + case 'notequal' : + // if variable is not set or is not string or number, return + if(!isset($value)) return; + if($value === '') return; + if(!in_array(gettype($value), array('string', 'integer'))) return; + } + + switch($operation) { + case 'equal' : + return $name.' = '.$value; + break; + case 'more' : + return $name.' >= '.$value; + break; + case 'excess' : + return $name.' > '.$value; + break; + case 'less' : + return $name.' <= '.$value; + break; + case 'below' : + return $name.' < '.$value; + break; + case 'like_tail' : + case 'like_prefix' : + case 'like' : + return $name.' like '.$value; + break; + case 'in' : + return $name.' in ('.$value.')'; + break; + case 'notin' : + return $name.' not in ('.$value.')'; + break; + case 'notequal' : + return $name.' <> '.$value; + break; + case 'notnull' : + return $name.' is not null'; + break; + case 'null' : + return $name.' is null'; + break; + } + } + + /** + * @brief returns condition key + * @param[in] $output result of query + * @return array of conditions of $output + **/ + function getConditionList($output) { + $conditions = array(); + if(count($output->conditions)) { + foreach($output->conditions as $key => $val) { + if($val['condition']) { + foreach($val['condition'] as $k => $v) { + $conditions[] = $v['column']; + } + } + } + } + + return $conditions; + } + + /** + * @brief returns counter cache data + * @param[in] $tables tables to get data + * @param[in] $condition condition to get data + * @return count of cache data + **/ + function getCountCache($tables, $condition) { + return false; + if(!$tables) return false; + if(!is_dir($this->count_cache_path)) return FileHandler::makeDir($this->count_cache_path); + + $condition = md5($condition); + + if(!is_array($tables)) $tables_str = $tables; + else $tables_str = implode('.',$tables); + + $cache_path = sprintf('%s/%s%s', $this->count_cache_path, $this->prefix, $tables_str); + if(!is_dir($cache_path)) FileHandler::makeDir($cache_path); + + $cache_filename = sprintf('%s/%s.%s', $cache_path, $tables_str, $condition); + if(!file_exists($cache_filename)) return false; + + $cache_mtime = filemtime($cache_filename); + + if(!is_array($tables)) $tables = array($tables); + foreach($tables as $alias => $table) { + $table_filename = sprintf('%s/cache.%s%s', $this->count_cache_path, $this->prefix, $table) ; + if(!file_exists($table_filename) || filemtime($table_filename) > $cache_mtime) return false; + } + + $count = (int)FileHandler::readFile($cache_filename); + return $count; + } + + /** + * @brief save counter cache data + * @param[in] $tables tables to save data + * @param[in] $condition condition to save data + * @param[in] $count count of cache data to save + * @return none + **/ + function putCountCache($tables, $condition, $count = 0) { + return false; + if(!$tables) return false; + if(!is_dir($this->count_cache_path)) return FileHandler::makeDir($this->count_cache_path); + + $condition = md5($condition); + + if(!is_array($tables)) $tables_str = $tables; + else $tables_str = implode('.',$tables); + + $cache_path = sprintf('%s/%s%s', $this->count_cache_path, $this->prefix, $tables_str); + if(!is_dir($cache_path)) FileHandler::makeDir($cache_path); + + $cache_filename = sprintf('%s/%s.%s', $cache_path, $tables_str, $condition); + + FileHandler::writeFile($cache_filename, $count); + } + + /** + * @brief reset counter cache data + * @param[in] $tables tables to reset cache data + * @return true: success, false: failed + **/ + function resetCountCache($tables) { + return false; + if(!$tables) return false; + if(!is_dir($this->count_cache_path)) return FileHandler::makeDir($this->count_cache_path); + + if(!is_array($tables)) $tables = array($tables); + foreach($tables as $alias => $table) { + $filename = sprintf('%s/cache.%s%s', $this->count_cache_path, $this->prefix, $table); + FileHandler::removeFile($filename); + FileHandler::writeFile($filename, ''); + } + + return true; + } + + /** + * @brief returns supported database list + * @return list of supported database + **/ + function getSupportedDatabase(){ + $result = array(); + + if(function_exists('mysql_connect')) $result[] = 'MySQL'; + if(function_exists('cubrid_connect')) $result[] = 'Cubrid'; + if(function_exists('ibase_connect')) $result[] = 'FireBird'; + if(function_exists('pg_connect')) $result[] = 'Postgre'; + if(function_exists('sqlite_open')) $result[] = 'sqlite2'; + if(function_exists('mssql_connect')) $result[] = 'MSSQL'; + if(function_exists('PDO')) $result[] = 'sqlite3(PDO)'; + + return $result; + } + + function dropTable($table_name){ + if(!$table_name) return; + $query = sprintf("drop table %s%s", $this->prefix, $table_name); + $this->_query($query); + } + } +?> diff --git a/classes/db/DBCubrid.class.php b/classes/db/DBCubrid.class.php index 434ae368d..9bed8399d 100644 --- a/classes/db/DBCubrid.class.php +++ b/classes/db/DBCubrid.class.php @@ -1,975 +1,975 @@ - 'numeric(20)', - 'number' => 'integer', - 'varchar' => 'character varying', - 'char' => 'character', - 'text' => 'character varying(1073741823)', - 'bigtext' => 'character varying(1073741823)', - 'date' => 'character varying(14)', - 'float' => 'float', - ); - - /** - * @brief constructor - **/ - function DBCubrid() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if(!function_exists('cubrid_connect')) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->hostname = $db_info->db_hostname; - $this->userid = $db_info->db_userid; - $this->password = $db_info->db_password; - $this->database = $db_info->db_database; - $this->port = $db_info->db_port; - $this->prefix = $db_info->db_table_prefix; - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->hostname || !$this->userid || !$this->password || !$this->database || !$this->port) return; - - // 접속시도 - $this->fd = @cubrid_connect($this->hostname, $this->port, $this->database, $this->userid, $this->password); - - // 접속체크 - if(!$this->fd) { - $this->setError(-1, 'database connect fail'); - return $this->is_connected = false; - } - - $this->is_connected = true; - $this->password = md5($this->password); - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if(!$this->isConnected()) return; - @cubrid_commit($this->fd); - @cubrid_disconnect($this->fd); - $this->transaction_started = false; - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(!$this->fd) return $string; - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = str_replace("'","''",$string); - return $string; - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - if(!$this->isConnected() || $this->transaction_started) return; - $this->transaction_started = true; - } - - /** - * @brief 롤백 - **/ - function rollback() { - if(!$this->isConnected() || !$this->transaction_started) return; - @cubrid_rollback($this->fd); - $this->transaction_started = false; - } - - /** - * @brief 커밋 - **/ - function commit() { - if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; - @cubrid_commit($this->fd); - $this->transaction_started = false; - } - - - /** - * @brief : 쿼리문의 실행 및 결과의 fetch 처리 - * - * query : query문 실행하고 result return\n - * fetch : reutrn 된 값이 없으면 NULL\n - * rows이면 array object\n - * row이면 object\n - * return\n - **/ - function _query($query) { - //echo "(((".$this->backtrace().")))"; - if(!$query || !$this->isConnected()) return; - - // 쿼리 시작을 알림 - $this->actStart($query); - - // 쿼리 문 실행 - $result = @cubrid_execute($this->fd, $query); - - // 오류 체크 - if(cubrid_error_code()) $this->setError(cubrid_error_code(), cubrid_error_msg()); - - // 쿼리 실행 종료를 알림 - $this->actFinish(); - - // 결과 리턴 - return $result; - } - - /** - * @brief 결과를 fetch - **/ - function _fetch($result) { - if(!$this->isConnected() || $this->isError() || !$result) return; - - $col_types = cubrid_column_types ($result); - $col_names = cubrid_column_names ($result); - if (($max = count ($col_types)) == count ($col_names)) { - $count = 0; - while ($count < $max) { - if (preg_match ("/^char/", $col_types[$count]) > 0) { - $char_type_fields[] = $col_names[$count]; - } - $count++; - } - } - - while($tmp = cubrid_fetch($result, CUBRID_OBJECT)) { - if (is_array ($char_type_fields)) { - foreach ($char_type_fields as $val) { - $tmp->{$val} = rtrim ($tmp->{$val}); - } - } - $output[] = $tmp; - } - unset ($char_type_fields); - - if($result) cubrid_close_request($result); - - if(count($output)==1) return $output[0]; - return $output; - } - - /** - * @brief 1씩 증가되는 sequence값을 return (cubrid의 auto_increment는 sequence테이블에서만 사용) - **/ - function getNextSequence() { - $query = sprintf("select %ssequence.nextval as seq from db_root", $this->prefix); - $result = $this->_query($query); - $output = $this->_fetch($result); - return $output->seq; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - if($target_name == 'sequence') - $query = sprintf("select * from \"db_serial\" where \"name\" = '%s%s'", $this->prefix, $target_name); - else - $query = sprintf("select * from \"db_class\" where \"class_name\" = '%s%s'", $this->prefix, $target_name); - $result = $this->_query($query); - - if(cubrid_num_rows($result)>0) $output = true; - else $output = false; - - if($result) cubrid_close_request($result); - return $output; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter class \"%s%s\" add \"%s\" ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) { - if ($type == 'number' || $type == 'bignumber') $query .= sprintf (" default %d ", $default); - else $query .= sprintf(" default '%s' ", $default); - } - if($notnull) $query .= " not null "; - - $this->_query($query); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - $query = sprintf("alter class \"%s%s\" drop \"%s\" ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("select * from \"db_attribute\" where \"attr_name\" ='%s' and \"class_name\" = '%s%s'", - $column_name, $this->prefix, $table_name); - $result = $this->_query($query); - if(cubrid_num_rows($result)>0) $output = true; - else $output = false; - - if($result) cubrid_close_request($result); - return $output; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $query = sprintf("create %s index \"%s\" on \"%s%s\" (%s);", $is_unique?'unique':'', $index_name, $this->prefix, $table_name, '"'.implode('","',$target_columns).'"'); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - $query = sprintf("drop %s index \"%s\" on \"%s%s\"", $is_unique?'unique':'', $index_name, $this->prefix, $table_name); - $this->_query($query); - } - - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - $query = sprintf("select * from \"db_index\" where \"class_name\" = '%s%s' and \"index_name\" = '%s' ", $this->prefix, $table_name, $index_name); - $result = $this->_query($query); - if($this->isError()) return false; - $output = $this->_fetch($result); - if(!$output) return false; - return true; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create class query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - - // 만약 테이블 이름이 sequence라면 serial 생성 - if($table_name == 'sequence') { - $query = sprintf('create serial "%s" start with 1 increment by 1 minvalue 1 maxvalue 10000000000000000000000000000000000000 nocycle;', $this->prefix.$table_name); - return $this->_query($query); - } - - if($this->isTableExists($table_name)) return; - - $table_name = $this->prefix.$table_name; - - $query = sprintf('create class "%s";', $table_name); - $this->_query($query); - - /*$query = sprintf("call change_owner('%s','%s') on class db_root;", $table_name, $this->userid); - $this->_query($query); */ - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - $query = sprintf("alter class \"%s\" add attribute ", $table_name); - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - - switch($this->column_type[$type]) { - case 'integer' : - $size = null; - break; - case 'text' : - $size = null; - break; - } - - if(isset ($default) && ($type == 'varchar' || $type == 'char')) $default = "'".$default."'"; - - $column_schema[] = sprintf('"%s" %s%s %s %s', - $name, - $this->column_type[$type], - $size?'('.$size.')':'', - isset($default)?"default ".$default:'', - $notnull?'not null':'' - ); - - if($primary_key) $primary_list[] = $name; - else if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - $query .= implode(',', $column_schema).';'; - $this->_query($query); - - if(count($primary_list)) { - $query = sprintf("alter class %s add attribute constraint \"pkey_%s\" PRIMARY KEY(%s);", $table_name, $table_name, '"'.implode('","',$primary_list).'"'); - $this->_query($query); - } - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $query = sprintf("create unique index %s_%s on %s (%s);", $table_name, $key, $table_name, '"'.implode('","',$val).'"'); - $this->_query($query); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $query = sprintf("create index \"%s_%s\" on %s (%s);", $table_name, $key, $table_name, '"'.implode('","',$val).'"'); - $this->_query($query); - } - } - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if (!$value) { - $value = $v['value']; - if (strpos ($value, '(')) $valuetmp = $value; - elseif (strpos ($value, ".") === false) $valuetmp = $value; - else $valuetmp = '"'.str_replace('.', '"."', $value).'"'; - } else $valuetmp = $value; - if (strpos ($name, '(') > 0) $nametmp = $name; - elseif (strpos ($name, ".") === false) $nametmp = '"'.$name.'"'; - else $nametmp = '"'.str_replace('.', '"."', $name).'"'; - $str = $this->getConditionPart($nametmp, $valuetmp, $operation); - if ($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - if($this->getColumnType($output->column_type,$name)!='number') { - $clen=strlen($value); - if ($clen <= $this->cutlen) - $value = "'".$this->addQuotes($value)."'"; - else { - $wrk=""; - $off=0; - while ($off<$clen) { - $wlen=$clen-$off; - if ($wlen>$this->cutlen) $wlen=$this->cutlen; - if ($off>0) $wrk .= "+\n"; - $wrk .= "'".$this->addQuotes(substr($value, $off, $wlen))."'"; - $off += $wlen; - } - $value = $wrk; - } - if(!$value) $value = 'null'; - } elseif(!$value || is_numeric($value)) $value = (int)$value; - - if(strpos($name,'.')===false) $column_list[] = '"'.$name.'"'; - else $column_list[] = $name; - $value_list[] = $value; - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - $result = $this->_query($query); - if($result && !$this->transaction_started) @cubrid_commit($this->fd); - return $result; - - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; - } - - $check_click_count = true; - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - - if(substr($value,-2)!='+1' || $output->column_type[$name]!='number') $check_click_count = false; - - for ($i = 0; $i < $key; $i++) { // 한문장에 같은 속성에 대한 중복 설정은 큐브리드에서는 허용치 않음 - if ($output->columns[$i]['name'] == $name) break; - } - if ($i < $key) continue; // 중복이 발견되면 이후의 설정은 무시 - - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') { - $check_column = false; - $clen=strlen($value); - if ($clen <= $this->cutlen) - $value = "'".$this->addQuotes($value)."'"; - else { - $wrk=""; - $off=0; - while ($off<$clen) { - $wlen=$clen-$off; - if ($wlen>$this->cutlen) $wlen=$this->cutlen; - if ($off>0) $wrk .= "+\n"; - $wrk .= "'".$this->addQuotes(substr($value, $off, $wlen))."'"; - $off += $wlen; - } - $value = $wrk; - } - } - elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = sprintf("\"%s\" = %s", $name, $value); - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $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; - } - - 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 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'"'; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - $result = $this->_query($query); - if($result && !$this->transaction_started) @cubrid_commit($this->fd); - return $result; - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; - } - - $left_join = array(); - // why??? - $left_tables = (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition) { - $left_join[] = $val.' "'.$this->prefix.$output->_tables[$key].'" "'.$key.'" on ('.$condition.')'; - } - } - - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - - $click_count = '%s'; - if($val['click_count'] && count($output->conditions)>0) { - $click_count = 'incr(%s)'; - } - - $alias = $val['alias'] ? sprintf('"%s"',$val['alias']) : null; - if($name == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - $name = sprintf($click_count,$name); - if ($alias) $column_list[] = sprintf('"%s" as %s', $name, $alias); - else $column_list[] = sprintf('"%s"',$name); - } else { - if(strpos($name,'.')!=false) { - list($prefix, $name) = explode('.',$name); - if (($now_matchs = preg_match_all ("/\(/", $prefix, $xtmp)) > 0) { - if ($now_matchs == 1) { - $tmpval = explode ("(", $prefix); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $prefix = implode ("(", $tmpval); - $tmpval = explode (")", $name); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $name = implode (")", $tmpval); - } - } - else { - $prefix = sprintf('"%s"',$prefix); - $name = ($name == '*') ? $name : sprintf('"%s"',$name); - } - $xtmp = null; - $now_matchs = null; - $column_list[] = sprintf($click_count,sprintf('%s.%s', $prefix, $name)) . ($alias ? sprintf(' as %s',$alias) : ''); - } elseif (($now_matchs = preg_match_all ("/\(/", $name, $xtmp)) > 0) { - if ($now_matchs == 1 && preg_match ("/[a-zA-Z0-9]*\(\*\)/", $name) < 1) { - $open_pos = strpos ($name, "("); - $close_pos = strpos ($name, ")"); - if (preg_match ("/,/", $name)) { - $tmp_func_name = sprintf ('%s', substr ($name, 0, $open_pos)); - $tmp_params = sprintf ('%s', substr ($name, $open_pos + 1, $close_pos - $open_pos - 1)); - $tmpval = null; - $tmpval = explode (',', $tmp_params); - foreach ($tmpval as $tmp_param) { - $tmp_param_list[] = (!is_numeric ($tmp_param)) ? sprintf ('"%s"', $tmp_param) : $tmp_param; - } - $tmpval = implode (',', $tmp_param_list); - $name = sprintf ('%s(%s)', $tmp_func_name, $tmpval); - } else { - $name = sprintf ('%s("%s")', - substr ($name, 0, $open_pos), - substr ($name, $open_pos + 1, $close_pos - $open_pos - 1)); - } - } - $column_list[] = sprintf ($click_count,$name) . ($alias ? sprintf (' as %s', $alias) : ''); - } else { - $column_list[] = sprintf($click_count,$name) . ($alias ? sprintf(' as %s',$alias) : ''); - } - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if (count ($output->groups)) { - foreach ($output->groups as $key => $value) { - if (strpos ($value, '.')) { - $tmp = explode ('.', $value); - $tmp[0] = sprintf ('"%s"', $tmp[0]); - $tmp[1] = sprintf ('"%s"', $tmp[1]); - $value = implode ('.', $tmp); - } - elseif (strpos ($value, '(')) $value = $value; - else $value = sprintf ('"%s"', $value); - $output->groups[$key] = $value; - } - $query .= sprintf(' group by %s', implode(',',$output->groups)); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) { - - $start_count = 0; - $list_count = $output->list_count['value']; - - if ($output->order) { - foreach($output->order as $key => $val) { - if (strpos ($val[0], '.')) { - $tmpval = explode ('.', $val[0]); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $val[0] = implode ('.', $tmpval); - } - elseif (strpos ($val[0], '(')) $val[0] = $val[0]; - elseif ($val[0] == 'count') $val[0] = 'count (*)'; - else $val[0] = sprintf ('"%s"', $val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - $query = sprintf('%s for orderby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - } - else { - if (count($output->groups)) - $query = sprintf('%s having groupby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - else { - if ($condition) - $query = sprintf('%s and inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - else - $query = sprintf('%s where inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - } - } - - } else { - - if($output->order) { - foreach($output->order as $key => $val) { - if (strpos ($val[0], '.')) { - $tmpval = explode ('.', $val[0]); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $val[0] = implode ('.', $tmpval); - } - elseif (strpos ($val[0], '(')) $val[0] = $val[0]; - elseif ($val[0] == 'count') $val[0] = 'count (*)'; - else $val[0] = sprintf ('"%s"', $val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - } - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) return; - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief 현재 시점의 Stack trace를 보여줌.결과를 fetch - **/ - function backtrace() - { - $output = "
\n"; - $output .= "Backtrace:
\n"; - $backtrace = debug_backtrace(); - - foreach ($backtrace as $bt) { - $args = ''; - foreach ($bt['args'] as $a) { - if (!empty($args)) { - $args .= ', '; - } - switch (gettype($a)) { - case 'integer': - case 'double': - $args .= $a; - break; - case 'string': - $a = htmlspecialchars(substr($a, 0, 64)).((strlen($a) > 64) ? '...' : ''); - $args .= "\"$a\""; - break; - case 'array': - $args .= 'Array('.count($a).')'; - break; - case 'object': - $args .= 'Object('.get_class($a).')'; - break; - case 'resource': - $args .= 'Resource('.strstr($a, '#').')'; - break; - case 'boolean': - $args .= $a ? 'True' : 'False'; - break; - case 'NULL': - $args .= 'Null'; - break; - default: - $args .= 'Unknown'; - } - } - $output .= "
\n"; - $output .= "file: {$bt['line']} - {$bt['file']}
\n"; - $output .= "call: {$bt['class']}{$bt['type']}{$bt['function']}($args)
\n"; - } - $output .= "
\n"; - return $output; - } - - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - /* - // group by 절이 포함된 SELECT 쿼리의 전체 갯수를 구하기 위한 수정 - // 정상적인 동작이 확인되면 주석으로 막아둔 부분으로 대체합니다. - // - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf('select count(*) as "count" from %s %s %s', implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - */ - - // 전체 개수를 구함 - $count_query = sprintf("select count(*) as \"count\" from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); - $total_count = $this->getCountCache($output->tables, $condition); - if($total_count === false) { - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); - - if (count ($output->groups)) { - foreach ($output->groups as $key => $value) { - if (strpos ($value, '.')) { - $tmp = explode ('.', $value); - $tmp[0] = sprintf ('"%s"', $tmp[0]); - $tmp[1] = sprintf ('"%s"', $tmp[1]); - $value = implode ('.', $tmp); - } - elseif (strpos ($value, '(')) $value = $value; - else $value = sprintf ('"%s"', $value); - $output->groups[$key] = $value; - } - $query .= sprintf(' group by %s', implode(',',$output->groups)); - } - - if ($output->order) { - foreach($output->order as $key => $val) { - if (strpos ($val[0], '.')) { - $tmpval = explode ('.', $val[0]); - $tmpval[0] = sprintf ('"%s"', $tmpval[0]); - $tmpval[1] = sprintf ('"%s"', $tmpval[1]); - $val[0] = implode ('.', $tmpval); - } - elseif (strpos ($val[0], '(')) $val[0] = $val[0]; - elseif ($val[0] == 'count') $val[0] = 'count (*)'; - else $val[0] = sprintf ('"%s"', $val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - $query = sprintf('%s for orderby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - } - else { - if (count($output->groups)) - $query = sprintf('%s having groupby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - else { - if ($condition) - $query = sprintf('%s and inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - else - $query = sprintf('%s where inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); - } - } - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = cubrid_fetch($result, CUBRID_OBJECT)) { - $data[$virtual_no--] = $tmp; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - } -?> + 'numeric(20)', + 'number' => 'integer', + 'varchar' => 'character varying', + 'char' => 'character', + 'text' => 'character varying(1073741823)', + 'bigtext' => 'character varying(1073741823)', + 'date' => 'character varying(14)', + 'float' => 'float', + ); + + /** + * @brief constructor + **/ + function DBCubrid() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if(!function_exists('cubrid_connect')) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->hostname = $db_info->db_hostname; + $this->userid = $db_info->db_userid; + $this->password = $db_info->db_password; + $this->database = $db_info->db_database; + $this->port = $db_info->db_port; + $this->prefix = $db_info->db_table_prefix; + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->hostname || !$this->userid || !$this->password || !$this->database || !$this->port) return; + + // 접속시도 + $this->fd = @cubrid_connect($this->hostname, $this->port, $this->database, $this->userid, $this->password); + + // 접속체크 + if(!$this->fd) { + $this->setError(-1, 'database connect fail'); + return $this->is_connected = false; + } + + $this->is_connected = true; + $this->password = md5($this->password); + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if(!$this->isConnected()) return; + @cubrid_commit($this->fd); + @cubrid_disconnect($this->fd); + $this->transaction_started = false; + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(!$this->fd) return $string; + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + if(!is_numeric($string)) $string = str_replace("'","''",$string); + return $string; + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + if(!$this->isConnected() || $this->transaction_started) return; + $this->transaction_started = true; + } + + /** + * @brief 롤백 + **/ + function rollback() { + if(!$this->isConnected() || !$this->transaction_started) return; + @cubrid_rollback($this->fd); + $this->transaction_started = false; + } + + /** + * @brief 커밋 + **/ + function commit() { + if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; + @cubrid_commit($this->fd); + $this->transaction_started = false; + } + + + /** + * @brief : 쿼리문의 실행 및 결과의 fetch 처리 + * + * query : query문 실행하고 result return\n + * fetch : reutrn 된 값이 없으면 NULL\n + * rows이면 array object\n + * row이면 object\n + * return\n + **/ + function _query($query) { + //echo "(((".$this->backtrace().")))"; + if(!$query || !$this->isConnected()) return; + + // 쿼리 시작을 알림 + $this->actStart($query); + + // 쿼리 문 실행 + $result = @cubrid_execute($this->fd, $query); + + // 오류 체크 + if(cubrid_error_code()) $this->setError(cubrid_error_code(), cubrid_error_msg()); + + // 쿼리 실행 종료를 알림 + $this->actFinish(); + + // 결과 리턴 + return $result; + } + + /** + * @brief 결과를 fetch + **/ + function _fetch($result) { + if(!$this->isConnected() || $this->isError() || !$result) return; + + $col_types = cubrid_column_types ($result); + $col_names = cubrid_column_names ($result); + if (($max = count ($col_types)) == count ($col_names)) { + $count = 0; + while ($count < $max) { + if (preg_match ("/^char/", $col_types[$count]) > 0) { + $char_type_fields[] = $col_names[$count]; + } + $count++; + } + } + + while($tmp = cubrid_fetch($result, CUBRID_OBJECT)) { + if (is_array ($char_type_fields)) { + foreach ($char_type_fields as $val) { + $tmp->{$val} = rtrim ($tmp->{$val}); + } + } + $output[] = $tmp; + } + unset ($char_type_fields); + + if($result) cubrid_close_request($result); + + if(count($output)==1) return $output[0]; + return $output; + } + + /** + * @brief 1씩 증가되는 sequence값을 return (cubrid의 auto_increment는 sequence테이블에서만 사용) + **/ + function getNextSequence() { + $query = sprintf("select %ssequence.nextval as seq from db_root", $this->prefix); + $result = $this->_query($query); + $output = $this->_fetch($result); + return $output->seq; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + if($target_name == 'sequence') + $query = sprintf("select * from \"db_serial\" where \"name\" = '%s%s'", $this->prefix, $target_name); + else + $query = sprintf("select * from \"db_class\" where \"class_name\" = '%s%s'", $this->prefix, $target_name); + $result = $this->_query($query); + + if(cubrid_num_rows($result)>0) $output = true; + else $output = false; + + if($result) cubrid_close_request($result); + return $output; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter class \"%s%s\" add \"%s\" ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) { + if ($type == 'number' || $type == 'bignumber') $query .= sprintf (" default %d ", $default); + else $query .= sprintf(" default '%s' ", $default); + } + if($notnull) $query .= " not null "; + + $this->_query($query); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + $query = sprintf("alter class \"%s%s\" drop \"%s\" ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("select * from \"db_attribute\" where \"attr_name\" ='%s' and \"class_name\" = '%s%s'", + $column_name, $this->prefix, $table_name); + $result = $this->_query($query); + if(cubrid_num_rows($result)>0) $output = true; + else $output = false; + + if($result) cubrid_close_request($result); + return $output; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $query = sprintf("create %s index \"%s\" on \"%s%s\" (%s);", $is_unique?'unique':'', $index_name, $this->prefix, $table_name, '"'.implode('","',$target_columns).'"'); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + $query = sprintf("drop %s index \"%s\" on \"%s%s\"", $is_unique?'unique':'', $index_name, $this->prefix, $table_name); + $this->_query($query); + } + + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + $query = sprintf("select * from \"db_index\" where \"class_name\" = '%s%s' and \"index_name\" = '%s' ", $this->prefix, $table_name, $index_name); + $result = $this->_query($query); + if($this->isError()) return false; + $output = $this->_fetch($result); + if(!$output) return false; + return true; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create class query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + + // 만약 테이블 이름이 sequence라면 serial 생성 + if($table_name == 'sequence') { + $query = sprintf('create serial "%s" start with 1 increment by 1 minvalue 1 maxvalue 10000000000000000000000000000000000000 nocycle;', $this->prefix.$table_name); + return $this->_query($query); + } + + if($this->isTableExists($table_name)) return; + + $table_name = $this->prefix.$table_name; + + $query = sprintf('create class "%s";', $table_name); + $this->_query($query); + + /*$query = sprintf("call change_owner('%s','%s') on class db_root;", $table_name, $this->userid); + $this->_query($query); */ + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + $query = sprintf("alter class \"%s\" add attribute ", $table_name); + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + + switch($this->column_type[$type]) { + case 'integer' : + $size = null; + break; + case 'text' : + $size = null; + break; + } + + if(isset ($default) && ($type == 'varchar' || $type == 'char')) $default = "'".$default."'"; + + $column_schema[] = sprintf('"%s" %s%s %s %s', + $name, + $this->column_type[$type], + $size?'('.$size.')':'', + isset($default)?"default ".$default:'', + $notnull?'not null':'' + ); + + if($primary_key) $primary_list[] = $name; + else if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + $query .= implode(',', $column_schema).';'; + $this->_query($query); + + if(count($primary_list)) { + $query = sprintf("alter class %s add attribute constraint \"pkey_%s\" PRIMARY KEY(%s);", $table_name, $table_name, '"'.implode('","',$primary_list).'"'); + $this->_query($query); + } + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $query = sprintf("create unique index %s_%s on %s (%s);", $table_name, $key, $table_name, '"'.implode('","',$val).'"'); + $this->_query($query); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $query = sprintf("create index \"%s_%s\" on %s (%s);", $table_name, $key, $table_name, '"'.implode('","',$val).'"'); + $this->_query($query); + } + } + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + $operation = $v['operation']; + $value = $v['value']; + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if (!$value) { + $value = $v['value']; + if (strpos ($value, '(')) $valuetmp = $value; + elseif (strpos ($value, ".") === false) $valuetmp = $value; + else $valuetmp = '"'.str_replace('.', '"."', $value).'"'; + } else $valuetmp = $value; + if (strpos ($name, '(') > 0) $nametmp = $name; + elseif (strpos ($name, ".") === false) $nametmp = '"'.$name.'"'; + else $nametmp = '"'.str_replace('.', '"."', $name).'"'; + $str = $this->getConditionPart($nametmp, $valuetmp, $operation); + if ($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '"'.$this->prefix.$val.'"'; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + if($this->getColumnType($output->column_type,$name)!='number') { + $clen=strlen($value); + if ($clen <= $this->cutlen) + $value = "'".$this->addQuotes($value)."'"; + else { + $wrk=""; + $off=0; + while ($off<$clen) { + $wlen=$clen-$off; + if ($wlen>$this->cutlen) $wlen=$this->cutlen; + if ($off>0) $wrk .= "+\n"; + $wrk .= "'".$this->addQuotes(substr($value, $off, $wlen))."'"; + $off += $wlen; + } + $value = $wrk; + } + if(!$value) $value = 'null'; + } elseif(!$value || is_numeric($value)) $value = (int)$value; + + if(strpos($name,'.')===false) $column_list[] = '"'.$name.'"'; + else $column_list[] = $name; + $value_list[] = $value; + } + + $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + $result = $this->_query($query); + if($result && !$this->transaction_started) @cubrid_commit($this->fd); + return $result; + + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; + } + + $check_click_count = true; + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + + if(substr($value,-2)!='+1' || $output->column_type[$name]!='number') $check_click_count = false; + + for ($i = 0; $i < $key; $i++) { // 한문장에 같은 속성에 대한 중복 설정은 큐브리드에서는 허용치 않음 + if ($output->columns[$i]['name'] == $name) break; + } + if ($i < $key) continue; // 중복이 발견되면 이후의 설정은 무시 + + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; + else { + if($output->column_type[$name]!='number') { + $check_column = false; + $clen=strlen($value); + if ($clen <= $this->cutlen) + $value = "'".$this->addQuotes($value)."'"; + else { + $wrk=""; + $off=0; + while ($off<$clen) { + $wlen=$clen-$off; + if ($wlen>$this->cutlen) $wlen=$this->cutlen; + if ($off>0) $wrk .= "+\n"; + $wrk .= "'".$this->addQuotes(substr($value, $off, $wlen))."'"; + $off += $wlen; + } + $value = $wrk; + } + } + elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = sprintf("\"%s\" = %s", $name, $value); + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $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; + } + + 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 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '"'.$this->prefix.$val.'"'; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + $result = $this->_query($query); + if($result && !$this->transaction_started) @cubrid_commit($this->fd); + return $result; + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = '"'.$this->prefix.$val.'" as "'.$key.'"'; + } + + $left_join = array(); + // why??? + $left_tables = (array)$output->left_tables; + + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition) { + $left_join[] = $val.' "'.$this->prefix.$output->_tables[$key].'" "'.$key.'" on ('.$condition.')'; + } + } + + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + + $click_count = '%s'; + if($val['click_count'] && count($output->conditions)>0) { + $click_count = 'incr(%s)'; + } + + $alias = $val['alias'] ? sprintf('"%s"',$val['alias']) : null; + if($name == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + $name = sprintf($click_count,$name); + if ($alias) $column_list[] = sprintf('"%s" as %s', $name, $alias); + else $column_list[] = sprintf('"%s"',$name); + } else { + if(strpos($name,'.')!=false) { + list($prefix, $name) = explode('.',$name); + if (($now_matchs = preg_match_all ("/\(/", $prefix, $xtmp)) > 0) { + if ($now_matchs == 1) { + $tmpval = explode ("(", $prefix); + $tmpval[1] = sprintf ('"%s"', $tmpval[1]); + $prefix = implode ("(", $tmpval); + $tmpval = explode (")", $name); + $tmpval[0] = sprintf ('"%s"', $tmpval[0]); + $name = implode (")", $tmpval); + } + } + else { + $prefix = sprintf('"%s"',$prefix); + $name = ($name == '*') ? $name : sprintf('"%s"',$name); + } + $xtmp = null; + $now_matchs = null; + $column_list[] = sprintf($click_count,sprintf('%s.%s', $prefix, $name)) . ($alias ? sprintf(' as %s',$alias) : ''); + } elseif (($now_matchs = preg_match_all ("/\(/", $name, $xtmp)) > 0) { + if ($now_matchs == 1 && preg_match ("/[a-zA-Z0-9]*\(\*\)/", $name) < 1) { + $open_pos = strpos ($name, "("); + $close_pos = strpos ($name, ")"); + if (preg_match ("/,/", $name)) { + $tmp_func_name = sprintf ('%s', substr ($name, 0, $open_pos)); + $tmp_params = sprintf ('%s', substr ($name, $open_pos + 1, $close_pos - $open_pos - 1)); + $tmpval = null; + $tmpval = explode (',', $tmp_params); + foreach ($tmpval as $tmp_param) { + $tmp_param_list[] = (!is_numeric ($tmp_param)) ? sprintf ('"%s"', $tmp_param) : $tmp_param; + } + $tmpval = implode (',', $tmp_param_list); + $name = sprintf ('%s(%s)', $tmp_func_name, $tmpval); + } else { + $name = sprintf ('%s("%s")', + substr ($name, 0, $open_pos), + substr ($name, $open_pos + 1, $close_pos - $open_pos - 1)); + } + } + $column_list[] = sprintf ($click_count,$name) . ($alias ? sprintf (' as %s', $alias) : ''); + } else { + $column_list[] = sprintf($click_count,$name) . ($alias ? sprintf(' as %s',$alias) : ''); + } + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if (count ($output->groups)) { + foreach ($output->groups as $key => $value) { + if (strpos ($value, '.')) { + $tmp = explode ('.', $value); + $tmp[0] = sprintf ('"%s"', $tmp[0]); + $tmp[1] = sprintf ('"%s"', $tmp[1]); + $value = implode ('.', $tmp); + } + elseif (strpos ($value, '(')) $value = $value; + else $value = sprintf ('"%s"', $value); + $output->groups[$key] = $value; + } + $query .= sprintf(' group by %s', implode(',',$output->groups)); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) { + + $start_count = 0; + $list_count = $output->list_count['value']; + + if ($output->order) { + foreach($output->order as $key => $val) { + if (strpos ($val[0], '.')) { + $tmpval = explode ('.', $val[0]); + $tmpval[0] = sprintf ('"%s"', $tmpval[0]); + $tmpval[1] = sprintf ('"%s"', $tmpval[1]); + $val[0] = implode ('.', $tmpval); + } + elseif (strpos ($val[0], '(')) $val[0] = $val[0]; + elseif ($val[0] == 'count') $val[0] = 'count (*)'; + else $val[0] = sprintf ('"%s"', $val[0]); + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + $query = sprintf('%s for orderby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + } + else { + if (count($output->groups)) + $query = sprintf('%s having groupby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + else { + if ($condition) + $query = sprintf('%s and inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + else + $query = sprintf('%s where inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + } + } + + } else { + + if($output->order) { + foreach($output->order as $key => $val) { + if (strpos ($val[0], '.')) { + $tmpval = explode ('.', $val[0]); + $tmpval[0] = sprintf ('"%s"', $tmpval[0]); + $tmpval[1] = sprintf ('"%s"', $tmpval[1]); + $val[0] = implode ('.', $tmpval); + } + elseif (strpos ($val[0], '(')) $val[0] = $val[0]; + elseif ($val[0] == 'count') $val[0] = 'count (*)'; + else $val[0] = sprintf ('"%s"', $val[0]); + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + } + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) return; + $data = $this->_fetch($result); + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief 현재 시점의 Stack trace를 보여줌.결과를 fetch + **/ + function backtrace() + { + $output = "
\n"; + $output .= "Backtrace:
\n"; + $backtrace = debug_backtrace(); + + foreach ($backtrace as $bt) { + $args = ''; + foreach ($bt['args'] as $a) { + if (!empty($args)) { + $args .= ', '; + } + switch (gettype($a)) { + case 'integer': + case 'double': + $args .= $a; + break; + case 'string': + $a = htmlspecialchars(substr($a, 0, 64)).((strlen($a) > 64) ? '...' : ''); + $args .= "\"$a\""; + break; + case 'array': + $args .= 'Array('.count($a).')'; + break; + case 'object': + $args .= 'Object('.get_class($a).')'; + break; + case 'resource': + $args .= 'Resource('.strstr($a, '#').')'; + break; + case 'boolean': + $args .= $a ? 'True' : 'False'; + break; + case 'NULL': + $args .= 'Null'; + break; + default: + $args .= 'Unknown'; + } + } + $output .= "
\n"; + $output .= "file: {$bt['line']} - {$bt['file']}
\n"; + $output .= "call: {$bt['class']}{$bt['type']}{$bt['function']}($args)
\n"; + } + $output .= "
\n"; + return $output; + } + + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + /* + // group by 절이 포함된 SELECT 쿼리의 전체 갯수를 구하기 위한 수정 + // 정상적인 동작이 확인되면 주석으로 막아둔 부분으로 대체합니다. + // + $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf('select count(*) as "count" from %s %s %s', implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) + $count_query = sprintf('select count(*) as "count" from (%s) xet', $count_query); + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + */ + + // 전체 개수를 구함 + $count_query = sprintf("select count(*) as \"count\" from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); + $total_count = $this->getCountCache($output->tables, $condition); + if($total_count === false) { + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); + + if (count ($output->groups)) { + foreach ($output->groups as $key => $value) { + if (strpos ($value, '.')) { + $tmp = explode ('.', $value); + $tmp[0] = sprintf ('"%s"', $tmp[0]); + $tmp[1] = sprintf ('"%s"', $tmp[1]); + $value = implode ('.', $tmp); + } + elseif (strpos ($value, '(')) $value = $value; + else $value = sprintf ('"%s"', $value); + $output->groups[$key] = $value; + } + $query .= sprintf(' group by %s', implode(',',$output->groups)); + } + + if ($output->order) { + foreach($output->order as $key => $val) { + if (strpos ($val[0], '.')) { + $tmpval = explode ('.', $val[0]); + $tmpval[0] = sprintf ('"%s"', $tmpval[0]); + $tmpval[1] = sprintf ('"%s"', $tmpval[1]); + $val[0] = implode ('.', $tmpval); + } + elseif (strpos ($val[0], '(')) $val[0] = $val[0]; + elseif ($val[0] == 'count') $val[0] = 'count (*)'; + else $val[0] = sprintf ('"%s"', $val[0]); + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + $query = sprintf('%s for orderby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + } + else { + if (count($output->groups)) + $query = sprintf('%s having groupby_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + else { + if ($condition) + $query = sprintf('%s and inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + else + $query = sprintf('%s where inst_num() between %d and %d', $query, $start_count + 1, $list_count + $start_count); + } + } + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) { + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + $virtual_no = $total_count - ($page-1)*$list_count; + while($tmp = cubrid_fetch($result, CUBRID_OBJECT)) { + $data[$virtual_no--] = $tmp; + } + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + } +?> diff --git a/classes/db/DBMssql.class.php b/classes/db/DBMssql.class.php index 21183c5db..afacb6262 100644 --- a/classes/db/DBMssql.class.php +++ b/classes/db/DBMssql.class.php @@ -1,874 +1,874 @@ - 'bigint', - 'number' => 'int', - 'varchar' => 'varchar', - 'char' => 'char', - 'text' => 'text', - 'bigtext' => 'text', - 'date' => 'varchar(14)', - 'float' => 'float', - ); - - /** - * @brief constructor - **/ - function DBMssql() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if (!extension_loaded("sqlsrv")) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->hostname = $db_info->db_hostname; - $this->port = $db_info->db_port; - $this->userid = $db_info->db_userid; - $this->password = $db_info->db_password; - $this->database = $db_info->db_database; - $this->prefix = $db_info->db_table_prefix; - - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->hostname || !$this->database) return; - - //sqlsrv_configure( 'WarningsReturnAsErrors', 0 ); - //sqlsrv_configure( 'LogSeverity', SQLSRV_LOG_SEVERITY_ALL ); - //sqlsrv_configure( 'LogSubsystems', SQLSRV_LOG_SYSTEM_ALL ); - - $this->conn = sqlsrv_connect( $this->hostname, - array( 'Database' => $this->database,'UID'=>$this->userid,'PWD'=>$this->password )); - - - // 접속체크 - if($this->conn){ - $this->is_connected = true; - $this->password = md5($this->password); - }else{ - $this->is_connected = false; - } - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if($this->is_connected == false) return; - - $this->commit(); - sqlsrv_close($this->conn); - $this->conn = null; - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - //if(!is_numeric($string)) $string = str_replace("'","''",$string); - - return $string; - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - if($this->is_connected == false || $this->transaction_started) return; - if(sqlsrv_begin_transaction( $this->conn ) === false) return; - - $this->transaction_started = true; - } - - /** - * @brief 롤백 - **/ - function rollback() { - if($this->is_connected == false || !$this->transaction_started) return; - - $this->transaction_started = false; - sqlsrv_rollback( $this->conn ); - } - - /** - * @brief 커밋 - **/ - function commit($force = false) { - if(!$force && ($this->is_connected == false || !$this->transaction_started)) return; - - $this->transaction_started = false; - sqlsrv_commit( $this->conn ); - } - - /** - * @brief : 쿼리문의 실행 및 결과의 fetch 처리 - * - * query : query문 실행하고 result return\n - * fetch : reutrn 된 값이 없으면 NULL\n - * rows이면 array object\n - * row이면 object\n - * return\n - **/ - function _query($query) { - if($this->is_connected == false || !$query) return; - - $_param = array(); - - if(count($this->param)){ - foreach($this->param as $k => $o){ - if($o['type'] == 'number'){ - $_param[] = &$o['value']; - }else{ - $_param[] = array(&$o['value'], SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')); - } - } - } - - // 쿼리 시작을 알림 - $this->actStart($query); - - // 쿼리 문 실행 - $result = false; - if(count($_param)){ - $result = @sqlsrv_query($this->conn, $query, $_param); - }else{ - $result = @sqlsrv_query($this->conn, $query); - } - - // 오류 체크 - if(!$result) $this->setError(print_r(sqlsrv_errors(),true)); - - // 쿼리 실행 종료를 알림 - $this->actFinish(); - $this->param = array(); - - return $result; - } - - /** - * @brief 결과를 fetch - **/ - function _fetch($result) { - if(!$this->isConnected() || $this->isError() || !$result) return; - - $c = sqlsrv_num_fields($result); - $m = null; - $output = array(); - - while(sqlsrv_fetch($result)){ - if(!$m) $m = sqlsrv_field_metadata($result); - unset($row); - for($i=0;$i<$c;$i++){ - $row->{$m[$i]['Name']} = sqlsrv_get_field( $result, $i, SQLSRV_PHPTYPE_STRING( 'utf-8' )); - } - $output[] = $row; - } - - if(count($output)==1) return $output[0]; - return $output; - - } - - /** - * @brief 1씩 증가되는 sequence값을 return (mssql의 auto_increment는 sequence테이블에서만 사용) - **/ - function getNextSequence() { - $query = sprintf("insert into %ssequence (seq) values (ident_incr('%ssequence'))", $this->prefix, $this->prefix); - $this->_query($query); - - $query = sprintf("select ident_current('%ssequence')+1 as sequence", $this->prefix); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - - - return $tmp->sequence; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - $query = sprintf("select name from sysobjects where name = '%s%s' and xtype='U'", $this->prefix, $this->addQuotes($target_name)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - - if(!$tmp) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - if($this->isColumnExists($table_name, $column_name)) return; - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) $query .= sprintf(" default '%s' ", $default); - if($notnull) $query .= " not null "; - - $this->_query($query); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - if(!$this->isColumnExists($table_name, $column_name)) return; - $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("select syscolumns.name as name from syscolumns, sysobjects where sysobjects.name = '%s%s' and sysobjects.id = syscolumns.id and syscolumns.name = '%s'", $this->prefix, $table_name, $column_name); - $result = $this->_query($query); - if($this->isError()) return; - $tmp = $this->_fetch($result); - if(!$tmp->name) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if($this->isIndexExists($table_name, $index_name)) return; - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $query = sprintf("create %s index %s on %s%s (%s)", $is_unique?'unique':'', $index_name, $this->prefix, $table_name, implode(',',$target_columns)); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - if(!$this->isIndexExists($table_name, $index_name)) return; - $query = sprintf("drop index %s%s.%s", $this->prefix, $table_name, $index_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - $query = sprintf("select sysindexes.name as name from sysindexes, sysobjects where sysobjects.name = '%s%s' and sysobjects.id = sysindexes.id and sysindexes.name = '%s'", $this->prefix, $table_name, $index_name); - - $result = $this->_query($query); - if($this->isError()) return; - $tmp = $this->_fetch($result); - - if(!$tmp->name) return false; - return true; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create table query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - if($this->isTableExists($table_name)) return; - - if($table_name == 'sequence') { - $table_name = $this->prefix.$table_name; - $query = sprintf('create table %s ( sequence int identity(1,1), seq int )', $table_name); - return $this->_query($query); - } else { - $table_name = $this->prefix.$table_name; - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - $auto_increment = $column->attrs->auto_increment; - - $column_schema[] = sprintf('[%s] %s%s %s %s %s %s', - $name, - $this->column_type[$type], - !in_array($type,array('number','text'))&&$size?'('.$size.')':'', - $primary_key?'primary key':'', - isset($default)?"default '".$default."'":'', - $notnull?'not null':'null', - $auto_increment?'identity(1,1)':'' - ); - - if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - $schema = sprintf('create table [%s] (xe_seq int identity(1,1),%s%s)', $this->addQuotes($table_name), "\n", implode($column_schema,",\n")); - $output = $this->_query($schema); - if(!$output) return false; - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $query = sprintf("create unique index %s on %s (%s);", $key, $table_name, '['.implode('],[',$val).']'); - $this->_query($query); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $query = sprintf("create index %s on %s (%s);", $key, $table_name, '['.implode('],[',$val).']'); - $this->_query($query); - } - } - return true; - } - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name); - $operation = $v['operation']; - $value = $v['value']; - - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - - function getConditionValue($name, $value, $operation, $type, $column_type) { - - if($type == 'number') { - if(strpos($value,',')===false && strpos($value,'(')===false){ - - if(is_integer($value)){ - $this->param[] = array('type'=>'number','value'=>(int)$value); - return '?'; - }else{ - return $value; - } - } - } - - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) { - list($table_name, $column_name) = explode('.',$value); - if($column_type[$column_name]){ - return $value; - } - } - - switch($operation) { - case 'like_prefix' : - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - - $value = "? + '%'"; - break; - case 'like_tail' : - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - - $value = "'%' + ?"; - break; - case 'like' : - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - - $value = "'%' + ? + '%'"; - break; - case 'notin' : - preg_match_all('/,?\'([^\']*)\'/',$value,$match); - $val = array(); - foreach($match[1] as $k => $v){ - $this->param[] = array('type'=>$column_type[$name],'value'=>trim($v)); - $val[] ='?'; - } - $value = join(',',$val); - break; - case 'in' : - preg_match_all('/,?\'([^\']*)\'/',$value,$match); - $val = array(); - foreach($match[1] as $k => $v){ - $this->param[] = array('type'=>$column_type[$name],'value'=>trim($v)); - $val[] ='?'; - } - $value = join(',',$val); - break; - default: - $value = preg_replace('/(^\'|\'$){1}/','',$value); - $this->param[] = array('type'=>$column_type[$name],'value'=>$value); - $value = '?'; - break; - } - - return $value; - } - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.']'; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - - if($output->column_type[$name]!='number') { - $value = $this->addQuotes($value); - if(!$value) $value = ''; - } elseif(is_numeric($value)){ - if(!$value) $value = ''; - $value = (int)$value; - } elseif(!$value){ - $value = ''; - } - - $column_list[] = '['.$name.']'; - $value_list[] = '?'; - - $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - - return $this->_query($query); - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.']'; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false){ - $column_list[] = $name.' = '.$value; - } else { - if($output->column_type[$name]!='number'){ - $value = $this->addQuotes($value); - if(!$value) $value = ''; - - $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); - $column_list[] = sprintf("[%s] = ?", $name); - }elseif(!$value || is_numeric($value)){ - $value = (int)$value; - - $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); - $column_list[] = sprintf("[%s] = ?", $name); - }else{ - if(!$value) $value = ''; - $column_list[] = sprintf("[%s] = %s", $name, $value); - } - - - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); - - return $this->_query($query); - } - - /** - * @brief deleteAct 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.']'; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - return $this->_query($query); - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '['.$this->prefix.$val.'] as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' ['.$this->prefix.$output->_tables[$key].'] as '.$key . ' on (' . $condition . ')'; - } - } - - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name); - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[] = sprintf('[%s] as [%s]', $name, $alias); - else $column_list[] = sprintf('[%s]',$name); - } else { - if($alias) $column_list[] = sprintf('%s as [%s]', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("%s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if(count($output->groups)){ - foreach($output->groups as $k => $v ){ - if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); - } - $query .= sprintf(' group by %s', implode(',',$output->groups)); - } - - - - - if($output->order && !preg_match('/count\(\*\)/i',$columns) ) { - foreach($output->order as $key => $val) { - if(preg_match('/^substr\(/i',$val[0])) $name = preg_replace('/^substr\(/i','substring(',$val[0]); - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) $query = sprintf('select top %d %s', $output->list_count['value'], $query); - else $query = "select ".$query; - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - // 전체 개수를 구함 - if(count($output->groups)){ - foreach($output->groups as $k => $v ){ - if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); - } - $count_condition = sprintf('%s group by %s', $condition, implode(', ', $output->groups)); - }else{ - $count_condition = $condition; - } - - - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - - $param = $this->param; - $result = $this->_query($count_query); - - $this->param = $param; - $count_output = $this->_fetch($result); - - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - $conditions = $this->getConditionList($output); - if($output->order) { - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' %s < 2100000000 ', $col); - } - } - } - - - // group by 절 추가 - if(count($output->groups)){ - foreach($output->groups as $k => $v ){ - if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); - } - $group .= sprintf('group by %s', implode(',',$output->groups)); - } - - // order 절 추가 - $order_targets = array(); - if($output->order) { - foreach($output->order as $key => $val) { - if(preg_match('/^substr\(/i',$val[0])) $name = preg_replace('/^substr\(/i','substring(',$val[0]); - $order_targets[$val[0]] = $val[1]; - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $order .= 'order by '.implode(',',$index_list); - } - if(!count($order_targets)) { - if(in_array('list_order',$conditions)) $order_targets['list_order'] = 'asc'; - else $order_targets['xe_seq'] = 'desc'; - } - - if($start_count<1) { - $query = sprintf('select top %d %s from %s %s %s %s %s', $list_count, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); - - } else { - foreach($order_targets as $k => $v) { - $first_columns[] = sprintf('%s(%s) as %s', $v=='asc'?'max':'min', $k, $k); - $first_sub_columns[] = $k; - } - - // 1차로 order 대상에 해당 하는 값을 가져옴 - $param = $this->param; - $first_query = sprintf("select %s from (select top %d %s from %s %s %s %s %s) xet", implode(',',$first_columns), $start_count, implode(',',$first_sub_columns), implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); - $result = $this->_query($first_query); - $this->param = $param; - $tmp = $this->_fetch($result); - - - - // 1차에서 나온 값을 이용 다시 쿼리 실행 - $sub_cond = array(); - foreach($order_targets as $k => $v) { - $sub_cond[] = sprintf("%s %s '%s'", $k, $v=='asc'?'>':'<', $tmp->{$k}); - } - $sub_condition = ' and( '.implode(' and ',$sub_cond).' )'; - - if($condition) $condition .= $sub_condition; - else $condition = ' where '.$sub_condition; - $query = sprintf('select top %d %s from %s %s %s %s %s', $list_count, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); - } - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - - $output = $this->_fetch($result); - if(!is_array($output)) $output = array($output); - - foreach($output as $k => $v) { - $data[$virtual_no--] = $v; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - } -?> + 'bigint', + 'number' => 'int', + 'varchar' => 'varchar', + 'char' => 'char', + 'text' => 'text', + 'bigtext' => 'text', + 'date' => 'varchar(14)', + 'float' => 'float', + ); + + /** + * @brief constructor + **/ + function DBMssql() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if (!extension_loaded("sqlsrv")) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->hostname = $db_info->db_hostname; + $this->port = $db_info->db_port; + $this->userid = $db_info->db_userid; + $this->password = $db_info->db_password; + $this->database = $db_info->db_database; + $this->prefix = $db_info->db_table_prefix; + + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->hostname || !$this->database) return; + + //sqlsrv_configure( 'WarningsReturnAsErrors', 0 ); + //sqlsrv_configure( 'LogSeverity', SQLSRV_LOG_SEVERITY_ALL ); + //sqlsrv_configure( 'LogSubsystems', SQLSRV_LOG_SYSTEM_ALL ); + + $this->conn = sqlsrv_connect( $this->hostname, + array( 'Database' => $this->database,'UID'=>$this->userid,'PWD'=>$this->password )); + + + // 접속체크 + if($this->conn){ + $this->is_connected = true; + $this->password = md5($this->password); + }else{ + $this->is_connected = false; + } + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if($this->is_connected == false) return; + + $this->commit(); + sqlsrv_close($this->conn); + $this->conn = null; + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + //if(!is_numeric($string)) $string = str_replace("'","''",$string); + + return $string; + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + if($this->is_connected == false || $this->transaction_started) return; + if(sqlsrv_begin_transaction( $this->conn ) === false) return; + + $this->transaction_started = true; + } + + /** + * @brief 롤백 + **/ + function rollback() { + if($this->is_connected == false || !$this->transaction_started) return; + + $this->transaction_started = false; + sqlsrv_rollback( $this->conn ); + } + + /** + * @brief 커밋 + **/ + function commit($force = false) { + if(!$force && ($this->is_connected == false || !$this->transaction_started)) return; + + $this->transaction_started = false; + sqlsrv_commit( $this->conn ); + } + + /** + * @brief : 쿼리문의 실행 및 결과의 fetch 처리 + * + * query : query문 실행하고 result return\n + * fetch : reutrn 된 값이 없으면 NULL\n + * rows이면 array object\n + * row이면 object\n + * return\n + **/ + function _query($query) { + if($this->is_connected == false || !$query) return; + + $_param = array(); + + if(count($this->param)){ + foreach($this->param as $k => $o){ + if($o['type'] == 'number'){ + $_param[] = &$o['value']; + }else{ + $_param[] = array(&$o['value'], SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')); + } + } + } + + // 쿼리 시작을 알림 + $this->actStart($query); + + // 쿼리 문 실행 + $result = false; + if(count($_param)){ + $result = @sqlsrv_query($this->conn, $query, $_param); + }else{ + $result = @sqlsrv_query($this->conn, $query); + } + + // 오류 체크 + if(!$result) $this->setError(print_r(sqlsrv_errors(),true)); + + // 쿼리 실행 종료를 알림 + $this->actFinish(); + $this->param = array(); + + return $result; + } + + /** + * @brief 결과를 fetch + **/ + function _fetch($result) { + if(!$this->isConnected() || $this->isError() || !$result) return; + + $c = sqlsrv_num_fields($result); + $m = null; + $output = array(); + + while(sqlsrv_fetch($result)){ + if(!$m) $m = sqlsrv_field_metadata($result); + unset($row); + for($i=0;$i<$c;$i++){ + $row->{$m[$i]['Name']} = sqlsrv_get_field( $result, $i, SQLSRV_PHPTYPE_STRING( 'utf-8' )); + } + $output[] = $row; + } + + if(count($output)==1) return $output[0]; + return $output; + + } + + /** + * @brief 1씩 증가되는 sequence값을 return (mssql의 auto_increment는 sequence테이블에서만 사용) + **/ + function getNextSequence() { + $query = sprintf("insert into %ssequence (seq) values (ident_incr('%ssequence'))", $this->prefix, $this->prefix); + $this->_query($query); + + $query = sprintf("select ident_current('%ssequence')+1 as sequence", $this->prefix); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + + + return $tmp->sequence; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + $query = sprintf("select name from sysobjects where name = '%s%s' and xtype='U'", $this->prefix, $this->addQuotes($target_name)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + + if(!$tmp) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + if($this->isColumnExists($table_name, $column_name)) return; + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) $query .= sprintf(" default '%s' ", $default); + if($notnull) $query .= " not null "; + + $this->_query($query); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + if(!$this->isColumnExists($table_name, $column_name)) return; + $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("select syscolumns.name as name from syscolumns, sysobjects where sysobjects.name = '%s%s' and sysobjects.id = syscolumns.id and syscolumns.name = '%s'", $this->prefix, $table_name, $column_name); + $result = $this->_query($query); + if($this->isError()) return; + $tmp = $this->_fetch($result); + if(!$tmp->name) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if($this->isIndexExists($table_name, $index_name)) return; + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $query = sprintf("create %s index %s on %s%s (%s)", $is_unique?'unique':'', $index_name, $this->prefix, $table_name, implode(',',$target_columns)); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + if(!$this->isIndexExists($table_name, $index_name)) return; + $query = sprintf("drop index %s%s.%s", $this->prefix, $table_name, $index_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + $query = sprintf("select sysindexes.name as name from sysindexes, sysobjects where sysobjects.name = '%s%s' and sysobjects.id = sysindexes.id and sysindexes.name = '%s'", $this->prefix, $table_name, $index_name); + + $result = $this->_query($query); + if($this->isError()) return; + $tmp = $this->_fetch($result); + + if(!$tmp->name) return false; + return true; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create table query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + if($this->isTableExists($table_name)) return; + + if($table_name == 'sequence') { + $table_name = $this->prefix.$table_name; + $query = sprintf('create table %s ( sequence int identity(1,1), seq int )', $table_name); + return $this->_query($query); + } else { + $table_name = $this->prefix.$table_name; + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + $auto_increment = $column->attrs->auto_increment; + + $column_schema[] = sprintf('[%s] %s%s %s %s %s %s', + $name, + $this->column_type[$type], + !in_array($type,array('number','text'))&&$size?'('.$size.')':'', + $primary_key?'primary key':'', + isset($default)?"default '".$default."'":'', + $notnull?'not null':'null', + $auto_increment?'identity(1,1)':'' + ); + + if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + $schema = sprintf('create table [%s] (xe_seq int identity(1,1),%s%s)', $this->addQuotes($table_name), "\n", implode($column_schema,",\n")); + $output = $this->_query($schema); + if(!$output) return false; + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $query = sprintf("create unique index %s on %s (%s);", $key, $table_name, '['.implode('],[',$val).']'); + $this->_query($query); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $query = sprintf("create index %s on %s (%s);", $key, $table_name, '['.implode('],[',$val).']'); + $this->_query($query); + } + } + return true; + } + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name); + $operation = $v['operation']; + $value = $v['value']; + + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if(!$value) $value = $v['value']; + $str = $this->getConditionPart($name, $value, $operation); + if($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + + function getConditionValue($name, $value, $operation, $type, $column_type) { + + if($type == 'number') { + if(strpos($value,',')===false && strpos($value,'(')===false){ + + if(is_integer($value)){ + $this->param[] = array('type'=>'number','value'=>(int)$value); + return '?'; + }else{ + return $value; + } + } + } + + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) { + list($table_name, $column_name) = explode('.',$value); + if($column_type[$column_name]){ + return $value; + } + } + + switch($operation) { + case 'like_prefix' : + $value = preg_replace('/(^\'|\'$){1}/','',$value); + $this->param[] = array('type'=>$column_type[$name],'value'=>$value); + + $value = "? + '%'"; + break; + case 'like_tail' : + $value = preg_replace('/(^\'|\'$){1}/','',$value); + $this->param[] = array('type'=>$column_type[$name],'value'=>$value); + + $value = "'%' + ?"; + break; + case 'like' : + $value = preg_replace('/(^\'|\'$){1}/','',$value); + $this->param[] = array('type'=>$column_type[$name],'value'=>$value); + + $value = "'%' + ? + '%'"; + break; + case 'notin' : + preg_match_all('/,?\'([^\']*)\'/',$value,$match); + $val = array(); + foreach($match[1] as $k => $v){ + $this->param[] = array('type'=>$column_type[$name],'value'=>trim($v)); + $val[] ='?'; + } + $value = join(',',$val); + break; + case 'in' : + preg_match_all('/,?\'([^\']*)\'/',$value,$match); + $val = array(); + foreach($match[1] as $k => $v){ + $this->param[] = array('type'=>$column_type[$name],'value'=>trim($v)); + $val[] ='?'; + } + $value = join(',',$val); + break; + default: + $value = preg_replace('/(^\'|\'$){1}/','',$value); + $this->param[] = array('type'=>$column_type[$name],'value'=>$value); + $value = '?'; + break; + } + + return $value; + } + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '['.$this->prefix.$val.']'; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + + if($output->column_type[$name]!='number') { + $value = $this->addQuotes($value); + if(!$value) $value = ''; + } elseif(is_numeric($value)){ + if(!$value) $value = ''; + $value = (int)$value; + } elseif(!$value){ + $value = ''; + } + + $column_list[] = '['.$name.']'; + $value_list[] = '?'; + + $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); + } + + $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + + return $this->_query($query); + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '['.$this->prefix.$val.']'; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + + $name = $val['name']; + $value = $val['value']; + if(strpos($name,'.')!==false&&strpos($value,'.')!==false){ + $column_list[] = $name.' = '.$value; + } else { + if($output->column_type[$name]!='number'){ + $value = $this->addQuotes($value); + if(!$value) $value = ''; + + $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); + $column_list[] = sprintf("[%s] = ?", $name); + }elseif(!$value || is_numeric($value)){ + $value = (int)$value; + + $this->param[] = array('type'=>$output->column_type[$name], 'value'=>$value); + $column_list[] = sprintf("[%s] = ?", $name); + }else{ + if(!$value) $value = ''; + $column_list[] = sprintf("[%s] = %s", $name, $value); + } + + + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); + + return $this->_query($query); + } + + /** + * @brief deleteAct 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '['.$this->prefix.$val.']'; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + + return $this->_query($query); + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = '['.$this->prefix.$val.'] as '.$key; + } + + $left_join = array(); + // why??? + $left_tables= (array)$output->left_tables; + + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition){ + $left_join[] = $val . ' ['.$this->prefix.$output->_tables[$key].'] as '.$key . ' on (' . $condition . ')'; + } + } + + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + if(preg_match('/^substr\(/i',$name)) $name = preg_replace('/^substr\(/i','substring(',$name); + $alias = $val['alias']; + if($val['click_count']) $click_count[] = $val['name']; + + if(substr($name,-1) == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + if($alias) $column_list[] = sprintf('[%s] as [%s]', $name, $alias); + else $column_list[] = sprintf('[%s]',$name); + } else { + if($alias) $column_list[] = sprintf('%s as [%s]', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("%s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if(count($output->groups)){ + foreach($output->groups as $k => $v ){ + if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); + } + $query .= sprintf(' group by %s', implode(',',$output->groups)); + } + + + + + if($output->order && !preg_match('/count\(\*\)/i',$columns) ) { + foreach($output->order as $key => $val) { + if(preg_match('/^substr\(/i',$val[0])) $name = preg_replace('/^substr\(/i','substring(',$val[0]); + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) $query = sprintf('select top %d %s', $output->list_count['value'], $query); + else $query = "select ".$query; + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) return; + + if(count($click_count)>0 && count($output->conditions)>0){ + $_query = ''; + foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); + $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); + $this->_query($_query); + } + + $data = $this->_fetch($result); + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + // 전체 개수를 구함 + if(count($output->groups)){ + foreach($output->groups as $k => $v ){ + if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); + } + $count_condition = sprintf('%s group by %s', $condition, implode(', ', $output->groups)); + }else{ + $count_condition = $condition; + } + + + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); + + $param = $this->param; + $result = $this->_query($count_query); + + $this->param = $param; + $count_output = $this->_fetch($result); + + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + $conditions = $this->getConditionList($output); + if($output->order) { + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' %s < 2100000000 ', $col); + } + } + } + + + // group by 절 추가 + if(count($output->groups)){ + foreach($output->groups as $k => $v ){ + if(preg_match('/^substr\(/i',$v)) $output->groups[$k] = preg_replace('/^substr\(/i','substring(',$v); + } + $group .= sprintf('group by %s', implode(',',$output->groups)); + } + + // order 절 추가 + $order_targets = array(); + if($output->order) { + foreach($output->order as $key => $val) { + if(preg_match('/^substr\(/i',$val[0])) $name = preg_replace('/^substr\(/i','substring(',$val[0]); + $order_targets[$val[0]] = $val[1]; + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $order .= 'order by '.implode(',',$index_list); + } + if(!count($order_targets)) { + if(in_array('list_order',$conditions)) $order_targets['list_order'] = 'asc'; + else $order_targets['xe_seq'] = 'desc'; + } + + if($start_count<1) { + $query = sprintf('select top %d %s from %s %s %s %s %s', $list_count, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); + + } else { + foreach($order_targets as $k => $v) { + $first_columns[] = sprintf('%s(%s) as %s', $v=='asc'?'max':'min', $k, $k); + $first_sub_columns[] = $k; + } + + // 1차로 order 대상에 해당 하는 값을 가져옴 + $param = $this->param; + $first_query = sprintf("select %s from (select top %d %s from %s %s %s %s %s) xet", implode(',',$first_columns), $start_count, implode(',',$first_sub_columns), implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); + $result = $this->_query($first_query); + $this->param = $param; + $tmp = $this->_fetch($result); + + + + // 1차에서 나온 값을 이용 다시 쿼리 실행 + $sub_cond = array(); + foreach($order_targets as $k => $v) { + $sub_cond[] = sprintf("%s %s '%s'", $k, $v=='asc'?'>':'<', $tmp->{$k}); + } + $sub_condition = ' and( '.implode(' and ',$sub_cond).' )'; + + if($condition) $condition .= $sub_condition; + else $condition = ' where '.$sub_condition; + $query = sprintf('select top %d %s from %s %s %s %s %s', $list_count, $columns, implode(',',$table_list), implode(' ',$left_join), $condition, $group, $order); + } + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + + if($this->isError()) { + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + $virtual_no = $total_count - ($page-1)*$list_count; + + $output = $this->_fetch($result); + if(!is_array($output)) $output = array($output); + + foreach($output as $k => $v) { + $data[$virtual_no--] = $v; + } + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + } +?> diff --git a/classes/db/DBMysql.class.php b/classes/db/DBMysql.class.php index 167eb6891..477922c01 100644 --- a/classes/db/DBMysql.class.php +++ b/classes/db/DBMysql.class.php @@ -1,687 +1,687 @@ - 'bigint', - 'number' => 'bigint', - 'varchar' => 'varchar', - 'char' => 'char', - 'text' => 'text', - 'bigtext' => 'longtext', - 'date' => 'varchar(14)', - 'float' => 'float', - ); - - /** - * @brief constructor - **/ - function DBMysql() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if(!function_exists('mysql_connect')) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->hostname = $db_info->db_hostname; - $this->port = $db_info->db_port; - $this->userid = $db_info->db_userid; - $this->password = $db_info->db_password; - $this->database = $db_info->db_database; - $this->prefix = $db_info->db_table_prefix; - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return; - - if(strpos($this->hostname, ':')===false && $this->port) $this->hostname .= ':'.$this->port; - - // 접속시도 - $this->fd = @mysql_connect($this->hostname, $this->userid, $this->password); - if(mysql_error()) { - $this->setError(mysql_errno(), mysql_error()); - return; - } - - // 버전 확인후 4.1 이하면 오류 표시 - if(mysql_get_server_info($this->fd)<"4.1") { - $this->setError(-1, "XE cannot be installed under the version of mysql 4.1. Current mysql version is ".mysql_get_server_info()); - return; - } - - // db 선택 - @mysql_select_db($this->database, $this->fd); - if(mysql_error()) { - $this->setError(mysql_errno(), mysql_error()); - return; - } - - // 접속체크 - $this->is_connected = true; - $this->password = md5($this->password); - - // mysql의 경우 utf8임을 지정 - $this->_query("set names 'utf8'"); - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if(!$this->isConnected()) return; - @mysql_close($this->fd); - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = @mysql_escape_string($string); - return $string; - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - } - - /** - * @brief 롤백 - **/ - function rollback() { - } - - /** - * @brief 커밋 - **/ - function commit() { - } - - /** - * @brief : 쿼리문의 실행 및 결과의 fetch 처리 - * - * query : query문 실행하고 result return\n - * fetch : reutrn 된 값이 없으면 NULL\n - * rows이면 array object\n - * row이면 object\n - * return\n - **/ - function _query($query) { - if(!$this->isConnected()) return; - - // 쿼리 시작을 알림 - $this->actStart($query); - - // 쿼리 문 실행 - $result = @mysql_query($query, $this->fd); - - // 오류 체크 - if(mysql_error($this->fd)) $this->setError(mysql_errno($this->fd), mysql_error($this->fd)); - - // 쿼리 실행 종료를 알림 - $this->actFinish(); - - // 결과 리턴 - return $result; - } - - /** - * @brief 결과를 fetch - **/ - function _fetch($result) { - if(!$this->isConnected() || $this->isError() || !$result) return; - while($tmp = mysql_fetch_object($result)) { - $output[] = $tmp; - } - if(count($output)==1) return $output[0]; - return $output; - } - - /** - * @brief 1씩 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용) - **/ - function getNextSequence() { - $query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix); - $this->_query($query); - $sequence = mysql_insert_id($this->fd); - if($sequence % 10000 == 0) { - $query = sprintf("delete from `%ssequence` where seq < %d", $this->prefix, $sequence); - $this->_query($query); - } - - return $sequence; - } - - /** - * @brief mysql old password를 가져오는 함수 (mysql에서만 사용) - **/ - function isValidOldPassword($password, $saved_password) { - $query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - if($tmp->password == $saved_password || $tmp->old_password == $saved_password) return true; - return false; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - $query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - if(!$tmp) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) $query .= sprintf(" default '%s' ", $default); - if($notnull) $query .= " not null "; - - $this->_query($query); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("show fields from %s%s", $this->prefix, $table_name); - $result = $this->_query($query); - if($this->isError()) return; - $output = $this->_fetch($result); - if($output) { - $column_name = strtolower($column_name); - foreach($output as $key => $val) { - $name = strtolower($val->Field); - if($column_name == $name) return true; - } - } - return false; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $query = sprintf("alter table %s%s add %s index %s (%s);", $this->prefix, $table_name, $is_unique?'unique':'', $index_name, implode(',',$target_columns)); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - $query = sprintf("alter table %s%s drop index %s;", $this->prefix, $table_name, $index_name); - $this->_query($query); - } - - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - //$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name); - $query = sprintf("show indexes from %s%s", $this->prefix, $table_name); - $result = $this->_query($query); - if($this->isError()) return; - $output = $this->_fetch($result); - if(!$output) return; - if(!is_array($output)) $output = array($output); - - for($i=0;$iKey_name == $index_name) return true; - } - return false; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create table query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - if($this->isTableExists($table_name)) return; - $table_name = $this->prefix.$table_name; - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - $auto_increment = $column->attrs->auto_increment; - - $column_schema[] = sprintf('`%s` %s%s %s %s %s', - $name, - $this->column_type[$type], - $size?'('.$size.')':'', - isset($default)?"default '".$default."'":'', - $notnull?'not null':'', - $auto_increment?'auto_increment':'' - ); - - if($primary_key) $primary_list[] = $name; - else if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - if(count($primary_list)) { - $column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`'); - } - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`'); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`'); - } - } - - $schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"), "ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci"); - - $output = $this->_query($schema); - if(!$output) return false; - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - if($output->column_type[$name]!='number') { - $value = "'".$this->addQuotes($value)."'"; - if(!$value) $value = 'null'; - } elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = '`'.$name.'`'; - $value_list[] = $value; - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - return $this->_query($query); - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = sprintf("`%s` = %s", $name, $value); - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); - - return $this->_query($query); - } - - /** - * @brief deleteAct 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - return $this->_query($query); - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; - } - } - - $click_count = array(); - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[] = sprintf('`%s` as `%s`', $name, $alias); - else $column_list[] = sprintf('`%s`',$name); - } else { - if($alias) $column_list[] = sprintf('%s as `%s`', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - // 전체 개수를 구함 - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if(count($output->order)) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = mysql_fetch_object($result)) { - $data[$virtual_no--] = $tmp; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - } -?> + 'bigint', + 'number' => 'bigint', + 'varchar' => 'varchar', + 'char' => 'char', + 'text' => 'text', + 'bigtext' => 'longtext', + 'date' => 'varchar(14)', + 'float' => 'float', + ); + + /** + * @brief constructor + **/ + function DBMysql() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if(!function_exists('mysql_connect')) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->hostname = $db_info->db_hostname; + $this->port = $db_info->db_port; + $this->userid = $db_info->db_userid; + $this->password = $db_info->db_password; + $this->database = $db_info->db_database; + $this->prefix = $db_info->db_table_prefix; + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return; + + if(strpos($this->hostname, ':')===false && $this->port) $this->hostname .= ':'.$this->port; + + // 접속시도 + $this->fd = @mysql_connect($this->hostname, $this->userid, $this->password); + if(mysql_error()) { + $this->setError(mysql_errno(), mysql_error()); + return; + } + + // 버전 확인후 4.1 이하면 오류 표시 + if(mysql_get_server_info($this->fd)<"4.1") { + $this->setError(-1, "XE cannot be installed under the version of mysql 4.1. Current mysql version is ".mysql_get_server_info()); + return; + } + + // db 선택 + @mysql_select_db($this->database, $this->fd); + if(mysql_error()) { + $this->setError(mysql_errno(), mysql_error()); + return; + } + + // 접속체크 + $this->is_connected = true; + $this->password = md5($this->password); + + // mysql의 경우 utf8임을 지정 + $this->_query("set names 'utf8'"); + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if(!$this->isConnected()) return; + @mysql_close($this->fd); + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + if(!is_numeric($string)) $string = @mysql_escape_string($string); + return $string; + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + } + + /** + * @brief 롤백 + **/ + function rollback() { + } + + /** + * @brief 커밋 + **/ + function commit() { + } + + /** + * @brief : 쿼리문의 실행 및 결과의 fetch 처리 + * + * query : query문 실행하고 result return\n + * fetch : reutrn 된 값이 없으면 NULL\n + * rows이면 array object\n + * row이면 object\n + * return\n + **/ + function _query($query) { + if(!$this->isConnected()) return; + + // 쿼리 시작을 알림 + $this->actStart($query); + + // 쿼리 문 실행 + $result = @mysql_query($query, $this->fd); + + // 오류 체크 + if(mysql_error($this->fd)) $this->setError(mysql_errno($this->fd), mysql_error($this->fd)); + + // 쿼리 실행 종료를 알림 + $this->actFinish(); + + // 결과 리턴 + return $result; + } + + /** + * @brief 결과를 fetch + **/ + function _fetch($result) { + if(!$this->isConnected() || $this->isError() || !$result) return; + while($tmp = mysql_fetch_object($result)) { + $output[] = $tmp; + } + if(count($output)==1) return $output[0]; + return $output; + } + + /** + * @brief 1씩 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용) + **/ + function getNextSequence() { + $query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix); + $this->_query($query); + $sequence = mysql_insert_id($this->fd); + if($sequence % 10000 == 0) { + $query = sprintf("delete from `%ssequence` where seq < %d", $this->prefix, $sequence); + $this->_query($query); + } + + return $sequence; + } + + /** + * @brief mysql old password를 가져오는 함수 (mysql에서만 사용) + **/ + function isValidOldPassword($password, $saved_password) { + $query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + if($tmp->password == $saved_password || $tmp->old_password == $saved_password) return true; + return false; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + $query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + if(!$tmp) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) $query .= sprintf(" default '%s' ", $default); + if($notnull) $query .= " not null "; + + $this->_query($query); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("show fields from %s%s", $this->prefix, $table_name); + $result = $this->_query($query); + if($this->isError()) return; + $output = $this->_fetch($result); + if($output) { + $column_name = strtolower($column_name); + foreach($output as $key => $val) { + $name = strtolower($val->Field); + if($column_name == $name) return true; + } + } + return false; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $query = sprintf("alter table %s%s add %s index %s (%s);", $this->prefix, $table_name, $is_unique?'unique':'', $index_name, implode(',',$target_columns)); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + $query = sprintf("alter table %s%s drop index %s;", $this->prefix, $table_name, $index_name); + $this->_query($query); + } + + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + //$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name); + $query = sprintf("show indexes from %s%s", $this->prefix, $table_name); + $result = $this->_query($query); + if($this->isError()) return; + $output = $this->_fetch($result); + if(!$output) return; + if(!is_array($output)) $output = array($output); + + for($i=0;$iKey_name == $index_name) return true; + } + return false; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create table query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + if($this->isTableExists($table_name)) return; + $table_name = $this->prefix.$table_name; + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + $auto_increment = $column->attrs->auto_increment; + + $column_schema[] = sprintf('`%s` %s%s %s %s %s', + $name, + $this->column_type[$type], + $size?'('.$size.')':'', + isset($default)?"default '".$default."'":'', + $notnull?'not null':'', + $auto_increment?'auto_increment':'' + ); + + if($primary_key) $primary_list[] = $name; + else if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + if(count($primary_list)) { + $column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`'); + } + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`'); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`'); + } + } + + $schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"), "ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci"); + + $output = $this->_query($schema); + if(!$output) return false; + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + $operation = $v['operation']; + $value = $v['value']; + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if(!$value) $value = $v['value']; + $str = $this->getConditionPart($name, $value, $operation); + if($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'`'; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + if($output->column_type[$name]!='number') { + $value = "'".$this->addQuotes($value)."'"; + if(!$value) $value = 'null'; + } elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = '`'.$name.'`'; + $value_list[] = $value; + } + + $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + return $this->_query($query); + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'` as '.$key; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; + else { + if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; + elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = sprintf("`%s` = %s", $name, $value); + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); + + return $this->_query($query); + } + + /** + * @brief deleteAct 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'`'; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + + return $this->_query($query); + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'` as '.$key; + } + + $left_join = array(); + // why??? + $left_tables= (array)$output->left_tables; + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition){ + $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; + } + } + + $click_count = array(); + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + $alias = $val['alias']; + if($val['click_count']) $click_count[] = $val['name']; + + if(substr($name,-1) == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + if($alias) $column_list[] = sprintf('`%s` as `%s`', $name, $alias); + else $column_list[] = sprintf('`%s`',$name); + } else { + if($alias) $column_list[] = sprintf('%s as `%s`', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + $result = $this->_query($query); + if($this->isError()) return; + + if(count($click_count)>0 && count($output->conditions)>0){ + $_query = ''; + foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); + $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); + $this->_query($_query); + } + + $data = $this->_fetch($result); + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + // 전체 개수를 구함 + $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) + $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if(count($output->order)) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + $result = $this->_query($query); + if($this->isError()) { + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + $virtual_no = $total_count - ($page-1)*$list_count; + while($tmp = mysql_fetch_object($result)) { + $data[$virtual_no--] = $tmp; + } + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + } +?> diff --git a/classes/db/DBMysql_innodb.class.php b/classes/db/DBMysql_innodb.class.php index ac6f5fb1c..a9a2d9993 100644 --- a/classes/db/DBMysql_innodb.class.php +++ b/classes/db/DBMysql_innodb.class.php @@ -1,697 +1,697 @@ - 'bigint', - 'number' => 'bigint', - 'varchar' => 'varchar', - 'char' => 'char', - 'text' => 'text', - 'bigtext' => 'longtext', - 'date' => 'varchar(14)', - 'float' => 'float', - ); - - /** - * @brief constructor - **/ - function DBMysql_innodb() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if(!function_exists('mysql_connect')) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->hostname = $db_info->db_hostname; - $this->port = $db_info->db_port; - $this->userid = $db_info->db_userid; - $this->password = $db_info->db_password; - $this->database = $db_info->db_database; - $this->prefix = $db_info->db_table_prefix; - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return; - - if(strpos($this->hostname, ':')===false && $this->port) $this->hostname .= ':'.$this->port; - - // 접속시도 - $this->fd = @mysql_connect($this->hostname, $this->userid, $this->password); - if(mysql_error()) { - $this->setError(mysql_errno(), mysql_error()); - return; - } - - // 버전 확인후 4.1 이하면 오류 표시 - if(mysql_get_server_info($this->fd)<"4.1") { - $this->setError(-1, "XE can not install under mysql 4.1. Current mysql version is ".mysql_get_server_info()); - return; - } - - // db 선택 - @mysql_select_db($this->database, $this->fd); - if(mysql_error()) { - $this->setError(mysql_errno(), mysql_error()); - return; - } - - // 접속체크 - $this->is_connected = true; - $this->password = md5($this->password); - - // mysql의 경우 utf8임을 지정 - $this->_query("set names 'utf8'"); - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if(!$this->isConnected()) return; - $this->_query("commit"); - @mysql_close($this->fd); - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = @mysql_escape_string($string); - return $string; - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - if(!$this->isConnected() || $this->transaction_started) return; - $this->transaction_started = true; - $this->_query("begin"); - } - - /** - * @brief 롤백 - **/ - function rollback() { - if(!$this->isConnected() || !$this->transaction_started) return; - $this->_query("rollback"); - $this->transaction_started = false; - } - - /** - * @brief 커밋 - **/ - function commit($force = false) { - if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; - $this->_query("commit"); - $this->transaction_started = false; - } - - /** - * @brief : 쿼리문의 실행 및 결과의 fetch 처리 - * - * query : query문 실행하고 result return\n - * fetch : reutrn 된 값이 없으면 NULL\n - * rows이면 array object\n - * row이면 object\n - * return\n - **/ - function _query($query) { - if(!$this->isConnected()) return; - - // 쿼리 시작을 알림 - $this->actStart($query); - - // 쿼리 문 실행 - $result = @mysql_query($query, $this->fd); - - // 오류 체크 - if(mysql_error($this->fd)) $this->setError(mysql_errno($this->fd), mysql_error($this->fd)); - - // 쿼리 실행 종료를 알림 - $this->actFinish(); - - // 결과 리턴 - return $result; - } - - /** - * @brief 결과를 fetch - **/ - function _fetch($result) { - if(!$this->isConnected() || $this->isError() || !$result) return; - while($tmp = mysql_fetch_object($result)) { - $output[] = $tmp; - } - if(count($output)==1) return $output[0]; - return $output; - } - - /** - * @brief 1씩 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용) - **/ - function getNextSequence() { - $query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix); - $this->_query($query); - $sequence = mysql_insert_id($this->fd); - if($sequence % 10000 == 0) { - $query = sprintf("delete from `%ssequence` where seq < %d", $this->prefix, $sequence); - $this->_query($query); - } - - return $sequence; - } - - /** - * @brief mysql old password를 가져오는 함수 (mysql에서만 사용) - **/ - function isValidOldPassword($password, $saved_password) { - $query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - if($tmp->password == $saved_password || $tmp->old_password == $saved_password) return true; - return false; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - $query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - if(!$tmp) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) $query .= sprintf(" default '%s' ", $default); - if($notnull) $query .= " not null "; - - $this->_query($query); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("show fields from %s%s", $this->prefix, $table_name); - $result = $this->_query($query); - if($this->isError()) return; - $output = $this->_fetch($result); - if($output) { - $column_name = strtolower($column_name); - foreach($output as $key => $val) { - $name = strtolower($val->Field); - if($column_name == $name) return true; - } - } - return false; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $query = sprintf("alter table %s%s add %s index %s (%s);", $this->prefix, $table_name, $is_unique?'unique':'', $index_name, implode(',',$target_columns)); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - $query = sprintf("alter table %s%s drop index %s;", $this->prefix, $table_name, $index_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - //$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name); - $query = sprintf("show indexes from %s%s", $this->prefix, $table_name); - $result = $this->_query($query); - if($this->isError()) return; - $output = $this->_fetch($result); - if(!$output) return; - if(!is_array($output)) $output = array($output); - - for($i=0;$iKey_name == $index_name) return true; - } - return false; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create table query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - if($this->isTableExists($table_name)) return; - $table_name = $this->prefix.$table_name; - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - $auto_increment = $column->attrs->auto_increment; - - $column_schema[] = sprintf('`%s` %s%s %s %s %s', - $name, - $this->column_type[$type], - $size?'('.$size.')':'', - isset($default)?"default '".$default."'":'', - $notnull?'not null':'', - $auto_increment?'auto_increment':'' - ); - - if($primary_key) $primary_list[] = $name; - else if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - if(count($primary_list)) { - $column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`'); - } - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`'); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`'); - } - } - - $schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"), "ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci"); - - $output = $this->_query($schema); - if(!$output) return false; - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - if($output->column_type[$name]!='number') { - $value = "'".$this->addQuotes($value)."'"; - if(!$value) $value = 'null'; - } elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = '`'.$name.'`'; - $value_list[] = $value; - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - return $this->_query($query); - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = sprintf("`%s` = %s", $name, $value); - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); - - return $this->_query($query); - } - - /** - * @brief deleteAct 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - return $this->_query($query); - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; - } - } - - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[] = sprintf('`%s` as `%s`', $name, $alias); - else $column_list[] = sprintf('`%s`',$name); - } else { - if($alias) $column_list[] = sprintf('%s as `%s`', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - // 전체 개수를 구함 - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = mysql_fetch_object($result)) { - $data[$virtual_no--] = $tmp; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - } -?> + 'bigint', + 'number' => 'bigint', + 'varchar' => 'varchar', + 'char' => 'char', + 'text' => 'text', + 'bigtext' => 'longtext', + 'date' => 'varchar(14)', + 'float' => 'float', + ); + + /** + * @brief constructor + **/ + function DBMysql_innodb() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if(!function_exists('mysql_connect')) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->hostname = $db_info->db_hostname; + $this->port = $db_info->db_port; + $this->userid = $db_info->db_userid; + $this->password = $db_info->db_password; + $this->database = $db_info->db_database; + $this->prefix = $db_info->db_table_prefix; + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return; + + if(strpos($this->hostname, ':')===false && $this->port) $this->hostname .= ':'.$this->port; + + // 접속시도 + $this->fd = @mysql_connect($this->hostname, $this->userid, $this->password); + if(mysql_error()) { + $this->setError(mysql_errno(), mysql_error()); + return; + } + + // 버전 확인후 4.1 이하면 오류 표시 + if(mysql_get_server_info($this->fd)<"4.1") { + $this->setError(-1, "XE can not install under mysql 4.1. Current mysql version is ".mysql_get_server_info()); + return; + } + + // db 선택 + @mysql_select_db($this->database, $this->fd); + if(mysql_error()) { + $this->setError(mysql_errno(), mysql_error()); + return; + } + + // 접속체크 + $this->is_connected = true; + $this->password = md5($this->password); + + // mysql의 경우 utf8임을 지정 + $this->_query("set names 'utf8'"); + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if(!$this->isConnected()) return; + $this->_query("commit"); + @mysql_close($this->fd); + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + if(!is_numeric($string)) $string = @mysql_escape_string($string); + return $string; + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + if(!$this->isConnected() || $this->transaction_started) return; + $this->transaction_started = true; + $this->_query("begin"); + } + + /** + * @brief 롤백 + **/ + function rollback() { + if(!$this->isConnected() || !$this->transaction_started) return; + $this->_query("rollback"); + $this->transaction_started = false; + } + + /** + * @brief 커밋 + **/ + function commit($force = false) { + if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; + $this->_query("commit"); + $this->transaction_started = false; + } + + /** + * @brief : 쿼리문의 실행 및 결과의 fetch 처리 + * + * query : query문 실행하고 result return\n + * fetch : reutrn 된 값이 없으면 NULL\n + * rows이면 array object\n + * row이면 object\n + * return\n + **/ + function _query($query) { + if(!$this->isConnected()) return; + + // 쿼리 시작을 알림 + $this->actStart($query); + + // 쿼리 문 실행 + $result = @mysql_query($query, $this->fd); + + // 오류 체크 + if(mysql_error($this->fd)) $this->setError(mysql_errno($this->fd), mysql_error($this->fd)); + + // 쿼리 실행 종료를 알림 + $this->actFinish(); + + // 결과 리턴 + return $result; + } + + /** + * @brief 결과를 fetch + **/ + function _fetch($result) { + if(!$this->isConnected() || $this->isError() || !$result) return; + while($tmp = mysql_fetch_object($result)) { + $output[] = $tmp; + } + if(count($output)==1) return $output[0]; + return $output; + } + + /** + * @brief 1씩 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용) + **/ + function getNextSequence() { + $query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix); + $this->_query($query); + $sequence = mysql_insert_id($this->fd); + if($sequence % 10000 == 0) { + $query = sprintf("delete from `%ssequence` where seq < %d", $this->prefix, $sequence); + $this->_query($query); + } + + return $sequence; + } + + /** + * @brief mysql old password를 가져오는 함수 (mysql에서만 사용) + **/ + function isValidOldPassword($password, $saved_password) { + $query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + if($tmp->password == $saved_password || $tmp->old_password == $saved_password) return true; + return false; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + $query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + if(!$tmp) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) $query .= sprintf(" default '%s' ", $default); + if($notnull) $query .= " not null "; + + $this->_query($query); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("show fields from %s%s", $this->prefix, $table_name); + $result = $this->_query($query); + if($this->isError()) return; + $output = $this->_fetch($result); + if($output) { + $column_name = strtolower($column_name); + foreach($output as $key => $val) { + $name = strtolower($val->Field); + if($column_name == $name) return true; + } + } + return false; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $query = sprintf("alter table %s%s add %s index %s (%s);", $this->prefix, $table_name, $is_unique?'unique':'', $index_name, implode(',',$target_columns)); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + $query = sprintf("alter table %s%s drop index %s;", $this->prefix, $table_name, $index_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + //$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name); + $query = sprintf("show indexes from %s%s", $this->prefix, $table_name); + $result = $this->_query($query); + if($this->isError()) return; + $output = $this->_fetch($result); + if(!$output) return; + if(!is_array($output)) $output = array($output); + + for($i=0;$iKey_name == $index_name) return true; + } + return false; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create table query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + if($this->isTableExists($table_name)) return; + $table_name = $this->prefix.$table_name; + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + $auto_increment = $column->attrs->auto_increment; + + $column_schema[] = sprintf('`%s` %s%s %s %s %s', + $name, + $this->column_type[$type], + $size?'('.$size.')':'', + isset($default)?"default '".$default."'":'', + $notnull?'not null':'', + $auto_increment?'auto_increment':'' + ); + + if($primary_key) $primary_list[] = $name; + else if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + if(count($primary_list)) { + $column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`'); + } + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`'); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`'); + } + } + + $schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"), "ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci"); + + $output = $this->_query($schema); + if(!$output) return false; + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + $operation = $v['operation']; + $value = $v['value']; + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if(!$value) $value = $v['value']; + $str = $this->getConditionPart($name, $value, $operation); + if($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'`'; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + if($output->column_type[$name]!='number') { + $value = "'".$this->addQuotes($value)."'"; + if(!$value) $value = 'null'; + } elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = '`'.$name.'`'; + $value_list[] = $value; + } + + $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + return $this->_query($query); + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'` as '.$key; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; + else { + if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; + elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = sprintf("`%s` = %s", $name, $value); + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); + + return $this->_query($query); + } + + /** + * @brief deleteAct 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'`'; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + + return $this->_query($query); + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'` as '.$key; + } + + $left_join = array(); + // why??? + $left_tables= (array)$output->left_tables; + + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition){ + $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; + } + } + + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + $alias = $val['alias']; + if($val['click_count']) $click_count[] = $val['name']; + + if(substr($name,-1) == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + if($alias) $column_list[] = sprintf('`%s` as `%s`', $name, $alias); + else $column_list[] = sprintf('`%s`',$name); + } else { + if($alias) $column_list[] = sprintf('%s as `%s`', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) return; + + if(count($click_count)>0 && count($output->conditions)>0){ + $_query = ''; + foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); + $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); + $this->_query($_query); + } + + + $data = $this->_fetch($result); + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + // 전체 개수를 구함 + $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) + $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + $result = $this->_query($query); + if($this->isError()) { + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + $virtual_no = $total_count - ($page-1)*$list_count; + while($tmp = mysql_fetch_object($result)) { + $data[$virtual_no--] = $tmp; + } + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + } +?> diff --git a/classes/db/DBMysqli.class.php b/classes/db/DBMysqli.class.php index 3203acac0..dfb009eaf 100644 --- a/classes/db/DBMysqli.class.php +++ b/classes/db/DBMysqli.class.php @@ -1,675 +1,675 @@ - 'bigint', - 'number' => 'bigint', - 'varchar' => 'varchar', - 'char' => 'char', - 'text' => 'text', - 'bigtext' => 'longtext', - 'date' => 'varchar(14)', - 'float' => 'float', - ); - - /** - * @brief constructor - **/ - function DBMysqli() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if(!function_exists('mysqli_connect')) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->hostname = $db_info->db_hostname; - $this->port = $db_info->db_port; - $this->userid = $db_info->db_userid; - $this->password = $db_info->db_password; - $this->database = $db_info->db_database; - $this->prefix = $db_info->db_table_prefix; - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return; - - // 접속시도 - if($this->port){ - $this->fd = @mysqli_connect($this->hostname, $this->userid, $this->password, $this->database, $this->port); - }else{ - $this->fd = @mysqli_connect($this->hostname, $this->userid, $this->password, $this->database); - } - $error = mysqli_connect_errno(); - if($error) { - $this->setError($error,mysqli_connect_error()); - return; - } - mysqli_set_charset($this->fd,'utf8'); - - // 접속체크 - $this->is_connected = true; - $this->password = md5($this->password); - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if(!$this->isConnected()) return; - mysqli_close($this->fd); - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = mysqli_escape_string($this->fd,$string); - return $string; - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - } - - /** - * @brief 롤백 - **/ - function rollback() { - } - - /** - * @brief 커밋 - **/ - function commit() { - } - - /** - * @brief : 쿼리문의 실행 및 결과의 fetch 처리 - * - * query : query문 실행하고 result return\n - * fetch : reutrn 된 값이 없으면 NULL\n - * rows이면 array object\n - * row이면 object\n - * return\n - **/ - function _query($query) { - if(!$this->isConnected()) return; - - // 쿼리 시작을 알림 - $this->actStart($query); - - // 쿼리 문 실행 - $result = mysqli_query($this->fd,$query); - - // 오류 체크 - $error = mysqli_error($this->fd); - if($error) $this->setError(mysqli_errno($this->fd), $error); - - // 쿼리 실행 종료를 알림 - $this->actFinish(); - - // 결과 리턴 - return $result; - } - - /** - * @brief 결과를 fetch - **/ - function _fetch($result) { - if(!$this->isConnected() || $this->isError() || !$result) return; - while($tmp = mysqli_fetch_object($result)) { - $output[] = $tmp; - } - if(count($output)==1) return $output[0]; - return $output; - } - - /** - * @brief 1씩 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용) - **/ - function getNextSequence() { - $query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix); - $this->_query($query); - $sequence = mysqli_insert_id($this->fd); - if($sequence % 10000 == 0) { - $query = sprintf("delete from `%ssequence` where seq < %d", $this->prefix, $sequence); - $this->_query($query); - } - - return $sequence; - } - - /** - * @brief mysql old password를 가져오는 함수 (mysql에서만 사용) - **/ - function isValidOldPassword($password, $saved_password) { - $query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - if($tmp->password == $saved_password || $tmp->old_password == $saved_password) return true; - return false; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - $query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name)); - $result = $this->_query($query); - $tmp = $this->_fetch($result); - if(!$tmp) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) $query .= sprintf(" default '%s' ", $default); - if($notnull) $query .= " not null "; - - $this->_query($query); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("show fields from %s%s", $this->prefix, $table_name); - $result = $this->_query($query); - if($this->isError()) return; - $output = $this->_fetch($result); - if($output) { - $column_name = strtolower($column_name); - foreach($output as $key => $val) { - $name = strtolower($val->Field); - if($column_name == $name) return true; - } - } - return false; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $query = sprintf("alter table %s%s add %s index %s (%s);", $this->prefix, $table_name, $is_unique?'unique':'', $index_name, implode(',',$target_columns)); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - $query = sprintf("alter table %s%s drop index %s;", $this->prefix, $table_name, $index_name); - $this->_query($query); - } - - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - //$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name); - $query = sprintf("show indexes from %s%s", $this->prefix, $table_name); - $result = $this->_query($query); - if($this->isError()) return; - $output = $this->_fetch($result); - if(!$output) return; - if(!is_array($output)) $output = array($output); - - for($i=0;$iKey_name == $index_name) return true; - } - return false; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create table query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - if($this->isTableExists($table_name)) return; - $table_name = $this->prefix.$table_name; - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - $auto_increment = $column->attrs->auto_increment; - - $column_schema[] = sprintf('`%s` %s%s %s %s %s', - $name, - $this->column_type[$type], - $size?'('.$size.')':'', - isset($default)?"default '".$default."'":'', - $notnull?'not null':'', - $auto_increment?'auto_increment':'' - ); - - if($primary_key) $primary_list[] = $name; - else if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - if(count($primary_list)) { - $column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`'); - } - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`'); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`'); - } - } - - $schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"), "ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci"); - - $output = $this->_query($schema); - if(!$output) return false; - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - - if($output->column_type[$name]!='number') { - $value = "'".$this->addQuotes($value)."'"; - if(!$value) $value = 'null'; - } elseif(!$value || is_numeric($value)) $value = (int)$value; - $column_list[] = '`'.$name.'`'; - $value_list[] = $value; - } - - $query = sprintf("insert into %s (%s) values (%s)", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - - return $this->_query($query); - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = sprintf("`%s` = %s", $name, $value); - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); - - return $this->_query($query); - } - - /** - * @brief deleteAct 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'`'; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - return $this->_query($query); - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = '`'.$this->prefix.$val.'` as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; - } - } - - $click_count = array(); - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[] = sprintf('`%s` as `%s`', $name, $alias); - else $column_list[] = sprintf('`%s`',$name); - } else { - if($alias) $column_list[] = sprintf('%s as `%s`', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - // 전체 개수를 구함 - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if(count($output->order)) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = mysqli_fetch_object($result)) { - $data[$virtual_no--] = $tmp; - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - } -?> + 'bigint', + 'number' => 'bigint', + 'varchar' => 'varchar', + 'char' => 'char', + 'text' => 'text', + 'bigtext' => 'longtext', + 'date' => 'varchar(14)', + 'float' => 'float', + ); + + /** + * @brief constructor + **/ + function DBMysqli() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if(!function_exists('mysqli_connect')) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->hostname = $db_info->db_hostname; + $this->port = $db_info->db_port; + $this->userid = $db_info->db_userid; + $this->password = $db_info->db_password; + $this->database = $db_info->db_database; + $this->prefix = $db_info->db_table_prefix; + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return; + + // 접속시도 + if($this->port){ + $this->fd = @mysqli_connect($this->hostname, $this->userid, $this->password, $this->database, $this->port); + }else{ + $this->fd = @mysqli_connect($this->hostname, $this->userid, $this->password, $this->database); + } + $error = mysqli_connect_errno(); + if($error) { + $this->setError($error,mysqli_connect_error()); + return; + } + mysqli_set_charset($this->fd,'utf8'); + + // 접속체크 + $this->is_connected = true; + $this->password = md5($this->password); + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if(!$this->isConnected()) return; + mysqli_close($this->fd); + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + if(!is_numeric($string)) $string = mysqli_escape_string($this->fd,$string); + return $string; + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + } + + /** + * @brief 롤백 + **/ + function rollback() { + } + + /** + * @brief 커밋 + **/ + function commit() { + } + + /** + * @brief : 쿼리문의 실행 및 결과의 fetch 처리 + * + * query : query문 실행하고 result return\n + * fetch : reutrn 된 값이 없으면 NULL\n + * rows이면 array object\n + * row이면 object\n + * return\n + **/ + function _query($query) { + if(!$this->isConnected()) return; + + // 쿼리 시작을 알림 + $this->actStart($query); + + // 쿼리 문 실행 + $result = mysqli_query($this->fd,$query); + + // 오류 체크 + $error = mysqli_error($this->fd); + if($error) $this->setError(mysqli_errno($this->fd), $error); + + // 쿼리 실행 종료를 알림 + $this->actFinish(); + + // 결과 리턴 + return $result; + } + + /** + * @brief 결과를 fetch + **/ + function _fetch($result) { + if(!$this->isConnected() || $this->isError() || !$result) return; + while($tmp = mysqli_fetch_object($result)) { + $output[] = $tmp; + } + if(count($output)==1) return $output[0]; + return $output; + } + + /** + * @brief 1씩 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용) + **/ + function getNextSequence() { + $query = sprintf("insert into `%ssequence` (seq) values ('0')", $this->prefix); + $this->_query($query); + $sequence = mysqli_insert_id($this->fd); + if($sequence % 10000 == 0) { + $query = sprintf("delete from `%ssequence` where seq < %d", $this->prefix, $sequence); + $this->_query($query); + } + + return $sequence; + } + + /** + * @brief mysql old password를 가져오는 함수 (mysql에서만 사용) + **/ + function isValidOldPassword($password, $saved_password) { + $query = sprintf("select password('%s') as password, old_password('%s') as old_password", $this->addQuotes($password), $this->addQuotes($password)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + if($tmp->password == $saved_password || $tmp->old_password == $saved_password) return true; + return false; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + $query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name)); + $result = $this->_query($query); + $tmp = $this->_fetch($result); + if(!$tmp) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) $query .= sprintf(" default '%s' ", $default); + if($notnull) $query .= " not null "; + + $this->_query($query); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + $query = sprintf("alter table %s%s drop %s ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("show fields from %s%s", $this->prefix, $table_name); + $result = $this->_query($query); + if($this->isError()) return; + $output = $this->_fetch($result); + if($output) { + $column_name = strtolower($column_name); + foreach($output as $key => $val) { + $name = strtolower($val->Field); + if($column_name == $name) return true; + } + } + return false; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $query = sprintf("alter table %s%s add %s index %s (%s);", $this->prefix, $table_name, $is_unique?'unique':'', $index_name, implode(',',$target_columns)); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + $query = sprintf("alter table %s%s drop index %s;", $this->prefix, $table_name, $index_name); + $this->_query($query); + } + + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + //$query = sprintf("show indexes from %s%s where key_name = '%s' ", $this->prefix, $table_name, $index_name); + $query = sprintf("show indexes from %s%s", $this->prefix, $table_name); + $result = $this->_query($query); + if($this->isError()) return; + $output = $this->_fetch($result); + if(!$output) return; + if(!is_array($output)) $output = array($output); + + for($i=0;$iKey_name == $index_name) return true; + } + return false; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create table query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + if($this->isTableExists($table_name)) return; + $table_name = $this->prefix.$table_name; + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + $auto_increment = $column->attrs->auto_increment; + + $column_schema[] = sprintf('`%s` %s%s %s %s %s', + $name, + $this->column_type[$type], + $size?'('.$size.')':'', + isset($default)?"default '".$default."'":'', + $notnull?'not null':'', + $auto_increment?'auto_increment':'' + ); + + if($primary_key) $primary_list[] = $name; + else if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + if(count($primary_list)) { + $column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`'); + } + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`'); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`'); + } + } + + $schema = sprintf('create table `%s` (%s%s) %s;', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"), "ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci"); + + $output = $this->_query($schema); + if(!$output) return false; + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + $operation = $v['operation']; + $value = $v['value']; + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if(!$value) $value = $v['value']; + $str = $this->getConditionPart($name, $value, $operation); + if($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'`'; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + + if($output->column_type[$name]!='number') { + $value = "'".$this->addQuotes($value)."'"; + if(!$value) $value = 'null'; + } elseif(!$value || is_numeric($value)) $value = (int)$value; + $column_list[] = '`'.$name.'`'; + $value_list[] = $value; + } + + $query = sprintf("insert into %s (%s) values (%s)", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + + return $this->_query($query); + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'` as '.$key; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; + else { + if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; + elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = sprintf("`%s` = %s", $name, $value); + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("update %s set %s %s", implode(',',$table_list), implode(',',$column_list), $condition); + + return $this->_query($query); + } + + /** + * @brief deleteAct 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'`'; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + + return $this->_query($query); + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = '`'.$this->prefix.$val.'` as '.$key; + } + + $left_join = array(); + // why??? + $left_tables= (array)$output->left_tables; + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition){ + $left_join[] = $val . ' `'.$this->prefix.$output->_tables[$key].'` as '.$key . ' on (' . $condition . ')'; + } + } + + $click_count = array(); + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + $alias = $val['alias']; + if($val['click_count']) $click_count[] = $val['name']; + + if(substr($name,-1) == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + if($alias) $column_list[] = sprintf('`%s` as `%s`', $name, $alias); + else $column_list[] = sprintf('`%s`',$name); + } else { + if($alias) $column_list[] = sprintf('%s as `%s`', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) return; + + if(count($click_count)>0 && count($output->conditions)>0){ + $_query = ''; + foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); + $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); + $this->_query($_query); + } + + $data = $this->_fetch($result); + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + // 전체 개수를 구함 + $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) + $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if(count($output->order)) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) { + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + $virtual_no = $total_count - ($page-1)*$list_count; + while($tmp = mysqli_fetch_object($result)) { + $data[$virtual_no--] = $tmp; + } + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + } +?> diff --git a/classes/db/DBSqlite2.class.php b/classes/db/DBSqlite2.class.php index 913f7ddc9..ce7eb276c 100644 --- a/classes/db/DBSqlite2.class.php +++ b/classes/db/DBSqlite2.class.php @@ -1,728 +1,728 @@ - 'INTEGER', - 'number' => 'INTEGER', - 'varchar' => 'VARHAR', - 'char' => 'CHAR', - 'text' => 'TEXT', - 'bigtext' => 'TEXT', - 'date' => 'VARCHAR(14)', - 'float' => 'FLOAT', - ); - - /** - * @brief constructor - **/ - function DBSqlite2() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if(!function_exists('sqlite_open')) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->database = $db_info->db_database; - $this->prefix = $db_info->db_table_prefix; - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->database) return; - - // 데이터 베이스 파일 접속 시도 - $this->fd = sqlite_open($this->database, 0666, $error); - if(!file_exists($this->database) || $error) { - $this->setError(-1,$error); - $this->is_connected = false; - return; - } - - // 접속체크 - $this->is_connected = true; - $this->password = md5($this->password); - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if(!$this->isConnected()) return; - sqlite_close($this->fd); - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - if(!$this->is_connected || $this->transaction_started) return; - if($this->_query("BEGIN;")) $this->transaction_started = true; - } - - /** - * @brief 롤백 - **/ - function rollback() { - if(!$this->is_connected || !$this->transaction_started) return; - $this->_query("ROLLBACK;"); - $this->transaction_started = false; - } - - /** - * @brief 커밋 - **/ - function commit($force = false) { - if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; - if(!$this->is_connected || !$this->transaction_started) return; - $this->_query("COMMIT;"); - $this->transaction_started = false; - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = str_replace("'","''", $string); - return $string; - } - - /** - * @brief : 쿼리문의 실행 및 결과의 fetch 처리 - * - * query : query문 실행하고 result return\n - * fetch : reutrn 된 값이 없으면 NULL\n - * rows이면 array object\n - * row이면 object\n - * return\n - **/ - function _query($query) { - if(!$this->isConnected()) return; - - // 쿼리 시작을 알림 - $this->actStart($query); - - // 쿼리 문 실행 - $result = @sqlite_query($query, $this->fd); - - // 오류 체크 - if(sqlite_last_error($this->fd)) $this->setError(sqlite_last_error($this->fd), sqlite_error_string(sqlite_last_error($this->fd))); - - // 쿼리 실행 알림 - $this->actFinish(); - - return $result; - } - - /** - * @brief 결과를 fetch - **/ - function _fetch($result) { - if($this->isError() || !$result) return; - - while($tmp = sqlite_fetch_array($result, SQLITE_ASSOC)) { - unset($obj); - foreach($tmp as $key => $val) { - $pos = strpos($key, '.'); - if($pos) $key = substr($key, $pos+1); - $obj->{$key} = $val; - } - $output[] = $obj; - } - - if(count($output)==1) return $output[0]; - return $output; - } - - /** - * @brief 1씩 증가되는 sequence값을 return - **/ - function getNextSequence() { - $query = sprintf("insert into %ssequence (seq) values ('')", $this->prefix); - $this->_query($query); - $sequence = sqlite_last_insert_rowid($this->fd); - if($sequence % 10000 == 0) { - $query = sprintf("delete from %ssequence where seq < %d", $this->prefix, $sequence); - $this->_query($query); - } - - return $sequence; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - $query = sprintf('pragma table_info(%s%s)', $this->prefix, $this->addQuotes($target_name)); - $result = $this->_query($query); - if(sqlite_num_rows($result)==0) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) $query .= sprintf(" default '%s' ", $default); - if($notnull) $query .= " not null "; - - return $this->_query($query); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - $query = sprintf("alter table %s%s drop column %s ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("pragma table_info(%s%s)", $this->prefix, $table_name); - $result = $this->_query($query); - $output = $this->_fetch($result); - if($output) { - $column_name = strtolower($column_name); - foreach($output as $key => $val) { - $name = strtolower($val->name); - if($column_name == $name) return true; - } - } - return false; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); - $query = sprintf("pragma table_info(%s%s)", $this->prefix, $table_name); - - $query = sprintf('CREATE %s INDEX %s ON %s%s (%s)', $is_unique?'UNIQUE':'', $key_name, $this->prefix, $table_name, implode(',',$target_columns)); - return $this->_query($query); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); - $query = sprintf("DROP INDEX %s", $this->prefix, $table_name, $key_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); - $query = sprintf("pragma index_info(%s)", $key_name); - $result = $this->_query($query); - $output = $this->_fetch($result); - if(!$output) return false; - return true; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create table query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - if($this->isTableExists($table_name)) return; - $table_name = $this->prefix.$table_name; - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - if(strtoupper($this->column_type[$type])=='INTEGER') $size = ''; - else $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - $auto_increment = $column->attrs->auto_increment; - - if($auto_increment) { - $column_schema[] = sprintf('%s %s %s', - $name, - $this->column_type[$type], - $auto_increment?'AUTOINCREMENT':'' - ); - } else { - $column_schema[] = sprintf('%s %s%s %s %s %s %s', - $name, - $this->column_type[$type], - $size?'('.$size.')':'', - $notnull?'NOT NULL':'', - $primary_key?'PRIMARY KEY':'', - isset($default)?"DEFAULT '".$default."'":'', - $auto_increment?'AUTOINCREMENT':'' - ); - } - - if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - $schema = sprintf('CREATE TABLE %s (%s%s) ;', $this->addQuotes($table_name)," ", implode($column_schema,", ")); - $this->_query($schema); - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $query = sprintf('CREATE UNIQUE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); - $this->_query($query); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $query = sprintf('CREATE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); - $this->_query($query); - } - } - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - if($output->column_type[$name]!='number') { - $value = "'".$this->addQuotes($value)."'"; - if(!$value) $value = 'null'; - } elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = $name; - $value_list[] = $value; - } - - $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); - return $this->_query($query); - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - $table_count = count(array_values($output->tables)); - - // 대상 테이블이 1개일 경우 - if($table_count == 1) { - // 테이블 정리 - list($target_table) = array_values($output->tables); - $target_table = $this->prefix.$target_table; - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = sprintf("%s = %s", $name, $value); - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", $target_table, implode(',',$column_list), $condition); - - // 대상 테이블이 2개일 경우 (sqlite에서 update 테이블을 1개 이상 지정 못해서 이렇게 꽁수로... 다른 방법이 있으려나..) - } elseif($table_count == 2) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[$val] = $this->prefix.$key; - } - list($source_table, $target_table) = array_values($table_list); - - // 조건절 정리 - $condition = $this->getCondition($output); - foreach($table_list as $key => $val) { - $condition = eregi_replace($key.'\\.', $val.'.', $condition); - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - list($s_prefix, $s_column) = explode('.',$name); - list($t_prefix, $t_column) = explode('.',$value); - - $s_table = $table_list[$s_prefix]; - $t_table = $table_list[$t_prefix]; - $column_list[] = sprintf(' %s = (select %s from %s %s) ', $s_column, $t_column, $t_table, $condition); - } - - $query = sprintf('update %s set %s where exists(select * from %s %s)', $source_table, implode(',', $column_list), $target_table, $condition); - } else { - return; - } - - return $this->_query($query); - } - - /** - * @brief deleteAct 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - return $this->_query($query); - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val.' as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' '.$this->prefix.$output->_tables[$key].' as '.$key . ' on ' . $condition . ''; - } - } - - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } else { - if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $result = $this->_query($query); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $data = $this->_fetch($result); - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - /* - // group by 절이 포함된 SELECT 쿼리의 전체 갯수를 구하기 위한 수정 - // 정상적인 동작이 확인되면 주석으로 막아둔 부분으로 대체합니다. - // - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - */ - - // 전체 개수를 구함 - $count_query = sprintf("select count(*) as count from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); - - $total_count = $this->getCountCache($output->tables, $condition); - - if($total_count === false) { - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); - - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $result = $this->_query($query); - if($this->isError()) { - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - - if($result) { - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = sqlite_fetch_array($result, SQLITE_ASSOC)) { - unset($obj); - foreach($tmp as $key => $val) { - $pos = strpos($key, '.'); - if($pos) $key = substr($key, $pos+1); - $obj->{$key} = $val; - } - $data[$virtual_no--] = $obj; - } - } - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - } -?> + 'INTEGER', + 'number' => 'INTEGER', + 'varchar' => 'VARHAR', + 'char' => 'CHAR', + 'text' => 'TEXT', + 'bigtext' => 'TEXT', + 'date' => 'VARCHAR(14)', + 'float' => 'FLOAT', + ); + + /** + * @brief constructor + **/ + function DBSqlite2() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if(!function_exists('sqlite_open')) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->database = $db_info->db_database; + $this->prefix = $db_info->db_table_prefix; + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->database) return; + + // 데이터 베이스 파일 접속 시도 + $this->fd = sqlite_open($this->database, 0666, $error); + if(!file_exists($this->database) || $error) { + $this->setError(-1,$error); + $this->is_connected = false; + return; + } + + // 접속체크 + $this->is_connected = true; + $this->password = md5($this->password); + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if(!$this->isConnected()) return; + sqlite_close($this->fd); + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + if(!$this->is_connected || $this->transaction_started) return; + if($this->_query("BEGIN;")) $this->transaction_started = true; + } + + /** + * @brief 롤백 + **/ + function rollback() { + if(!$this->is_connected || !$this->transaction_started) return; + $this->_query("ROLLBACK;"); + $this->transaction_started = false; + } + + /** + * @brief 커밋 + **/ + function commit($force = false) { + if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; + if(!$this->is_connected || !$this->transaction_started) return; + $this->_query("COMMIT;"); + $this->transaction_started = false; + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + if(!is_numeric($string)) $string = str_replace("'","''", $string); + return $string; + } + + /** + * @brief : 쿼리문의 실행 및 결과의 fetch 처리 + * + * query : query문 실행하고 result return\n + * fetch : reutrn 된 값이 없으면 NULL\n + * rows이면 array object\n + * row이면 object\n + * return\n + **/ + function _query($query) { + if(!$this->isConnected()) return; + + // 쿼리 시작을 알림 + $this->actStart($query); + + // 쿼리 문 실행 + $result = @sqlite_query($query, $this->fd); + + // 오류 체크 + if(sqlite_last_error($this->fd)) $this->setError(sqlite_last_error($this->fd), sqlite_error_string(sqlite_last_error($this->fd))); + + // 쿼리 실행 알림 + $this->actFinish(); + + return $result; + } + + /** + * @brief 결과를 fetch + **/ + function _fetch($result) { + if($this->isError() || !$result) return; + + while($tmp = sqlite_fetch_array($result, SQLITE_ASSOC)) { + unset($obj); + foreach($tmp as $key => $val) { + $pos = strpos($key, '.'); + if($pos) $key = substr($key, $pos+1); + $obj->{$key} = $val; + } + $output[] = $obj; + } + + if(count($output)==1) return $output[0]; + return $output; + } + + /** + * @brief 1씩 증가되는 sequence값을 return + **/ + function getNextSequence() { + $query = sprintf("insert into %ssequence (seq) values ('')", $this->prefix); + $this->_query($query); + $sequence = sqlite_last_insert_rowid($this->fd); + if($sequence % 10000 == 0) { + $query = sprintf("delete from %ssequence where seq < %d", $this->prefix, $sequence); + $this->_query($query); + } + + return $sequence; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + $query = sprintf('pragma table_info(%s%s)', $this->prefix, $this->addQuotes($target_name)); + $result = $this->_query($query); + if(sqlite_num_rows($result)==0) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) $query .= sprintf(" default '%s' ", $default); + if($notnull) $query .= " not null "; + + return $this->_query($query); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + $query = sprintf("alter table %s%s drop column %s ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("pragma table_info(%s%s)", $this->prefix, $table_name); + $result = $this->_query($query); + $output = $this->_fetch($result); + if($output) { + $column_name = strtolower($column_name); + foreach($output as $key => $val) { + $name = strtolower($val->name); + if($column_name == $name) return true; + } + } + return false; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); + $query = sprintf("pragma table_info(%s%s)", $this->prefix, $table_name); + + $query = sprintf('CREATE %s INDEX %s ON %s%s (%s)', $is_unique?'UNIQUE':'', $key_name, $this->prefix, $table_name, implode(',',$target_columns)); + return $this->_query($query); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); + $query = sprintf("DROP INDEX %s", $this->prefix, $table_name, $key_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); + $query = sprintf("pragma index_info(%s)", $key_name); + $result = $this->_query($query); + $output = $this->_fetch($result); + if(!$output) return false; + return true; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create table query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + if($this->isTableExists($table_name)) return; + $table_name = $this->prefix.$table_name; + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + if(strtoupper($this->column_type[$type])=='INTEGER') $size = ''; + else $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + $auto_increment = $column->attrs->auto_increment; + + if($auto_increment) { + $column_schema[] = sprintf('%s %s %s', + $name, + $this->column_type[$type], + $auto_increment?'AUTOINCREMENT':'' + ); + } else { + $column_schema[] = sprintf('%s %s%s %s %s %s %s', + $name, + $this->column_type[$type], + $size?'('.$size.')':'', + $notnull?'NOT NULL':'', + $primary_key?'PRIMARY KEY':'', + isset($default)?"DEFAULT '".$default."'":'', + $auto_increment?'AUTOINCREMENT':'' + ); + } + + if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + $schema = sprintf('CREATE TABLE %s (%s%s) ;', $this->addQuotes($table_name)," ", implode($column_schema,", ")); + $this->_query($schema); + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $query = sprintf('CREATE UNIQUE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); + $this->_query($query); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $query = sprintf('CREATE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); + $this->_query($query); + } + } + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + $operation = $v['operation']; + $value = $v['value']; + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if(!$value) $value = $v['value']; + $str = $this->getConditionPart($name, $value, $operation); + if($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = $this->prefix.$val; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + if($output->column_type[$name]!='number') { + $value = "'".$this->addQuotes($value)."'"; + if(!$value) $value = 'null'; + } elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = $name; + $value_list[] = $value; + } + + $query = sprintf("insert into %s (%s) values (%s);", implode(',',$table_list), implode(',',$column_list), implode(',', $value_list)); + return $this->_query($query); + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + $table_count = count(array_values($output->tables)); + + // 대상 테이블이 1개일 경우 + if($table_count == 1) { + // 테이블 정리 + list($target_table) = array_values($output->tables); + $target_table = $this->prefix.$target_table; + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; + else { + if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; + elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = sprintf("%s = %s", $name, $value); + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("update %s set %s %s", $target_table, implode(',',$column_list), $condition); + + // 대상 테이블이 2개일 경우 (sqlite에서 update 테이블을 1개 이상 지정 못해서 이렇게 꽁수로... 다른 방법이 있으려나..) + } elseif($table_count == 2) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[$val] = $this->prefix.$key; + } + list($source_table, $target_table) = array_values($table_list); + + // 조건절 정리 + $condition = $this->getCondition($output); + foreach($table_list as $key => $val) { + $condition = eregi_replace($key.'\\.', $val.'.', $condition); + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + list($s_prefix, $s_column) = explode('.',$name); + list($t_prefix, $t_column) = explode('.',$value); + + $s_table = $table_list[$s_prefix]; + $t_table = $table_list[$t_prefix]; + $column_list[] = sprintf(' %s = (select %s from %s %s) ', $s_column, $t_column, $t_table, $condition); + } + + $query = sprintf('update %s set %s where exists(select * from %s %s)', $source_table, implode(',', $column_list), $target_table, $condition); + } else { + return; + } + + return $this->_query($query); + } + + /** + * @brief deleteAct 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = $this->prefix.$val; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + + return $this->_query($query); + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = $this->prefix.$val.' as '.$key; + } + + $left_join = array(); + // why??? + $left_tables= (array)$output->left_tables; + + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition){ + $left_join[] = $val . ' '.$this->prefix.$output->_tables[$key].' as '.$key . ' on ' . $condition . ''; + } + } + + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + $alias = $val['alias']; + if($val['click_count']) $click_count[] = $val['name']; + + if(substr($name,-1) == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } else { + if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $result = $this->_query($query); + if($this->isError()) return; + + if(count($click_count)>0 && count($output->conditions)>0){ + $_query = ''; + foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); + $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); + $this->_query($_query); + } + + $data = $this->_fetch($result); + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + /* + // group by 절이 포함된 SELECT 쿼리의 전체 갯수를 구하기 위한 수정 + // 정상적인 동작이 확인되면 주석으로 막아둔 부분으로 대체합니다. + // + $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) + $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + */ + + // 전체 개수를 구함 + $count_query = sprintf("select count(*) as count from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); + + $total_count = $this->getCountCache($output->tables, $condition); + + if($total_count === false) { + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); + + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + $result = $this->_query($query); + if($this->isError()) { + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + + if($result) { + $virtual_no = $total_count - ($page-1)*$list_count; + while($tmp = sqlite_fetch_array($result, SQLITE_ASSOC)) { + unset($obj); + foreach($tmp as $key => $val) { + $pos = strpos($key, '.'); + if($pos) $key = substr($key, $pos+1); + $obj->{$key} = $val; + } + $data[$virtual_no--] = $obj; + } + } + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + } +?> diff --git a/classes/db/DBSqlite3_pdo.class.php b/classes/db/DBSqlite3_pdo.class.php index 70835f3d8..3f66848fb 100644 --- a/classes/db/DBSqlite3_pdo.class.php +++ b/classes/db/DBSqlite3_pdo.class.php @@ -1,782 +1,782 @@ - 'INTEGER', - 'number' => 'INTEGER', - 'varchar' => 'VARHAR', - 'char' => 'CHAR', - 'text' => 'TEXT', - 'bigtext' => 'TEXT', - 'date' => 'VARCHAR(14)', - 'float' => 'REAL', - ); - - /** - * @brief constructor - **/ - function DBSqlite3_pdo() { - $this->_setDBInfo(); - $this->_connect(); - } - - /** - * @brief 설치 가능 여부를 return - **/ - function isSupported() { - if(!class_exists('PDO')) return false; - return true; - } - - /** - * @brief DB정보 설정 및 connect/ close - **/ - function _setDBInfo() { - $db_info = Context::getDBInfo(); - $this->database = $db_info->db_database; - $this->prefix = $db_info->db_table_prefix; - if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; - } - - /** - * @brief DB 접속 - **/ - function _connect() { - // db 정보가 없으면 무시 - if(!$this->database) return; - - // 데이터 베이스 파일 접속 시도 - $this->handler = new PDO('sqlite:'.$this->database); - - if(!file_exists($this->database) || $error) { - $this->setError(-1,'permission denied to access database'); - //$this->setError(-1,$error); - $this->is_connected = false; - return; - } - - // 접속체크 - $this->is_connected = true; - $this->password = md5($this->password); - } - - /** - * @brief DB접속 해제 - **/ - function close() { - if(!$this->isConnected()) return; - $this->commit(); - } - - /** - * @brief 트랜잭션 시작 - **/ - function begin() { - if(!$this->isConnected() || $this->transaction_started) return; - if($this->handler->beginTransaction()) $this->transaction_started = true; - } - - /** - * @brief 롤백 - **/ - function rollback() { - if(!$this->isConnected() || !$this->transaction_started) return; - $this->handler->rollBack(); - $this->transaction_started = false; - } - - /** - * @brief 커밋 - **/ - function commit($force = false) { - if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; - $this->handler->commit(); - $this->transaction_started = false; - } - - /** - * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 - **/ - function addQuotes($string) { - if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); - if(!is_numeric($string)) $string = str_replace("'","''",$string); - return $string; - } - - /** - * @brief : 쿼리문의 prepare - **/ - function _prepare($query) { - if(!$this->isConnected()) return; - - // 쿼리 시작을 알림 - $this->actStart($query); - - $this->stmt = $this->handler->prepare($query); - - if($this->handler->errorCode() != '00000') { - $this->setError($this->handler->errorCode(), print_r($this->handler->errorInfo(),true)); - $this->actFinish(); - } - $this->bind_idx = 0; - $this->bind_vars = array(); - } - - /** - * @brief : stmt에 binding params - **/ - function _bind($val) { - if(!$this->isConnected() || !$this->stmt) return; - - $this->bind_idx ++; - $this->bind_vars[] = $val; - $this->stmt->bindParam($this->bind_idx, $val); - } - - /** - * @brief : prepare된 쿼리의 execute - **/ - function _execute() { - if(!$this->isConnected() || !$this->stmt) return; - - $this->stmt->execute(); - - if($this->stmt->errorCode() === '00000') { - $output = null; - while($tmp = $this->stmt->fetch(PDO::FETCH_ASSOC)) { - unset($obj); - foreach($tmp as $key => $val) { - $pos = strpos($key, '.'); - if($pos) $key = substr($key, $pos+1); - $obj->{$key} = str_replace("''","'",$val); - } - $output[] = $obj; - } - } else { - $this->setError($this->stmt->errorCode(),print_r($this->stmt->errorInfo(),true)); - } - - $this->stmt = null; - $this->actFinish(); - - if(is_array($output) && count($output)==1) return $output[0]; - return $output; - } - - /** - * @brief 1씩 증가되는 sequence값을 return - **/ - function getNextSequence() { - $query = sprintf("insert into %ssequence (seq) values (NULL)", $this->prefix); - $this->_prepare($query); - $result = $this->_execute(); - $sequence = $this->handler->lastInsertId(); - if($sequence % 10000 == 0) { - $query = sprintf("delete from %ssequence where seq < %d", $this->prefix, $sequence); - $this->_prepare($query); - $result = $this->_execute(); - } - - return $sequence; - } - - /** - * @brief 테이블 기생성 여부 return - **/ - function isTableExists($target_name) { - $query = sprintf('pragma table_info(%s%s)', $this->prefix, $target_name); - $this->_prepare($query); - if(!$this->_execute()) return false; - return true; - } - - /** - * @brief 특정 테이블에 특정 column 추가 - **/ - function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { - $type = $this->column_type[$type]; - if(strtoupper($type)=='INTEGER') $size = ''; - - $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); - if($size) $query .= sprintf(" %s(%s) ", $type, $size); - else $query .= sprintf(" %s ", $type); - if($default) $query .= sprintf(" default '%s' ", $default); - if($notnull) $query .= " not null "; - - $this->_prepare($query); - return $this->_execute(); - } - - /** - * @brief 특정 테이블에 특정 column 제거 - **/ - function dropColumn($table_name, $column_name) { - $query = sprintf("alter table %s%s drop column %s ", $this->prefix, $table_name, $column_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 column의 정보를 return - **/ - function isColumnExists($table_name, $column_name) { - $query = sprintf("pragma table_info(%s%s)", $this->prefix, $table_name); - $this->_prepare($query); - $output = $this->_execute(); - - if($output) { - $column_name = strtolower($column_name); - foreach($output as $key => $val) { - $name = strtolower($val->name); - if($column_name == $name) return true; - } - } - return false; - } - - /** - * @brief 특정 테이블에 특정 인덱스 추가 - * $target_columns = array(col1, col2) - * $is_unique? unique : none - **/ - function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { - if(!is_array($target_columns)) $target_columns = array($target_columns); - - $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); - - $query = sprintf('CREATE %s INDEX %s ON %s%s (%s)', $is_unique?'UNIQUE':'', $key_name, $this->prefix, $table_name, implode(',',$target_columns)); - $this->_prepare($query); - $this->_execute(); - } - - /** - * @brief 특정 테이블의 특정 인덱스 삭제 - **/ - function dropIndex($table_name, $index_name, $is_unique = false) { - $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); - $query = sprintf("DROP INDEX %s", $this->prefix, $table_name, $key_name); - $this->_query($query); - } - - /** - * @brief 특정 테이블의 index 정보를 return - **/ - function isIndexExists($table_name, $index_name) { - $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); - - $query = sprintf("pragma index_info(%s)", $key_name); - $this->_prepare($query); - $output = $this->_execute(); - if(!$output) return false; - return true; - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXml($xml_doc) { - return $this->_createTable($xml_doc); - } - - /** - * @brief xml 을 받아서 테이블을 생성 - **/ - function createTableByXmlFile($file_name) { - if(!file_exists($file_name)) return; - // xml 파일을 읽음 - $buff = FileHandler::readFile($file_name); - return $this->_createTable($buff); - } - - /** - * @brief schema xml을 이용하여 create table query생성 - * - * type : number, varchar, text, char, date, \n - * opt : notnull, default, size\n - * index : primary key, index, unique\n - **/ - function _createTable($xml_doc) { - // xml parsing - $oXml = new XmlParser(); - $xml_obj = $oXml->parse($xml_doc); - - // 테이블 생성 schema 작성 - $table_name = $xml_obj->table->attrs->name; - if($this->isTableExists($table_name)) return; - $table_name = $this->prefix.$table_name; - - if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; - else $columns = $xml_obj->table->column; - - foreach($columns as $column) { - $name = $column->attrs->name; - $type = $column->attrs->type; - if(strtoupper($this->column_type[$type])=='INTEGER') $size = ''; - else $size = $column->attrs->size; - $notnull = $column->attrs->notnull; - $primary_key = $column->attrs->primary_key; - $index = $column->attrs->index; - $unique = $column->attrs->unique; - $default = $column->attrs->default; - $auto_increment = $column->attrs->auto_increment; - - if($auto_increment) { - $column_schema[] = sprintf('%s %s PRIMARY KEY %s', - $name, - $this->column_type[$type], - $auto_increment?'AUTOINCREMENT':'' - ); - } else { - $column_schema[] = sprintf('%s %s%s %s %s %s', - $name, - $this->column_type[$type], - $size?'('.$size.')':'', - $notnull?'NOT NULL':'', - $primary_key?'PRIMARY KEY':'', - isset($default)?"DEFAULT '".$default."'":'' - ); - } - - if($unique) $unique_list[$unique][] = $name; - else if($index) $index_list[$index][] = $name; - } - - $schema = sprintf('CREATE TABLE %s (%s%s) ;', $table_name," ", implode($column_schema,", ")); - $this->_prepare($schema); - $this->_execute(); - if($this->isError()) return; - - if(count($unique_list)) { - foreach($unique_list as $key => $val) { - $query = sprintf('CREATE UNIQUE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); - $this->_prepare($query); - $this->_execute(); - if($this->isError()) $this->rollback(); - } - } - - if(count($index_list)) { - foreach($index_list as $key => $val) { - $query = sprintf('CREATE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); - $this->_prepare($query); - $this->_execute(); - if($this->isError()) $this->rollback(); - } - } - } - - /** - * @brief 조건문 작성하여 return - **/ - function getCondition($output) { - if(!$output->conditions) return; - $condition = $this->_getCondition($output->conditions,$output->column_type); - if($condition) $condition = ' where '.$condition; - return $condition; - } - - function getLeftCondition($conditions,$column_type){ - return $this->_getCondition($conditions,$column_type); - } - - - function _getCondition($conditions,$column_type) { - $condition = ''; - foreach($conditions as $val) { - $sub_condition = ''; - foreach($val['condition'] as $v) { - if(!isset($v['value'])) continue; - if($v['value'] === '') continue; - if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; - - $name = $v['column']; - $operation = $v['operation']; - $value = $v['value']; - $type = $this->getColumnType($column_type,$name); - $pipe = $v['pipe']; - - $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); - if(!$value) $value = $v['value']; - $str = $this->getConditionPart($name, $value, $operation); - if($sub_condition) $sub_condition .= ' '.$pipe.' '; - $sub_condition .= $str; - } - if($sub_condition) { - if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; - $condition .= '('.$sub_condition.')'; - } - } - return $condition; - } - - /** - * @brief insertAct 처리 - **/ - function _executeInsertAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val; - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - $name = $val['name']; - $value = $val['value']; - - $key_list[] = $name; - - if($output->column_type[$name]!='number') $val_list[] = $this->addQuotes($value); - else { - if(!$value || is_numeric($value)) $value = (int)$value; - $val_list[] = $value; - } - - $prepare_list[] = '?'; - } - - $query = sprintf("INSERT INTO %s (%s) VALUES (%s);", implode(',',$table_list), implode(',',$key_list), implode(',',$prepare_list)); - - $this->_prepare($query); - - $val_count = count($val_list); - for($i=0;$i<$val_count;$i++) $this->_bind($val_list[$i]); - - return $this->_execute(); - } - - /** - * @brief updateAct 처리 - **/ - function _executeUpdateAct($output) { - $table_count = count(array_values($output->tables)); - - // 대상 테이블이 1개일 경우 - if($table_count == 1) { - // 테이블 정리 - list($target_table) = array_values($output->tables); - $target_table = $this->prefix.$target_table; - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; - else { - if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; - elseif(!$value || is_numeric($value)) $value = (int)$value; - - $column_list[] = sprintf("%s = %s", $name, $value); - } - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("update %s set %s %s", $target_table, implode(',',$column_list), $condition); - - // 대상 테이블이 2개일 경우 (sqlite에서 update 테이블을 1개 이상 지정 못해서 이렇게 꽁수로... 다른 방법이 있으려나..) - } elseif($table_count == 2) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[$val] = $this->prefix.$key; - } - list($source_table, $target_table) = array_values($table_list); - - // 조건절 정리 - $condition = $this->getCondition($output); - foreach($table_list as $key => $val) { - $condition = eregi_replace($key.'\\.', $val.'.', $condition); - } - - // 컬럼 정리 - foreach($output->columns as $key => $val) { - if(!isset($val['value'])) continue; - $name = $val['name']; - $value = $val['value']; - list($s_prefix, $s_column) = explode('.',$name); - list($t_prefix, $t_column) = explode('.',$value); - - $s_table = $table_list[$s_prefix]; - $t_table = $table_list[$t_prefix]; - $column_list[] = sprintf(' %s = (select %s from %s %s) ', $s_column, $t_column, $t_table, $condition); - } - - $query = sprintf('update %s set %s where exists(select * from %s %s)', $source_table, implode(',', $column_list), $target_table, $condition); - } else { - return; - } - - $this->_prepare($query); - return $this->_execute(); - } - - /** - * @brief deleteAct 처리 - **/ - function _executeDeleteAct($output) { - // 테이블 정리 - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val; - } - - // 조건절 정리 - $condition = $this->getCondition($output); - - $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); - - $this->_prepare($query); - return $this->_execute(); - } - - /** - * @brief selectAct 처리 - * - * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n - * navigation이라는 method를 제공 - **/ - function _executeSelectAct($output) { - // 테이블 정리 - $table_list = array(); - foreach($output->tables as $key => $val) { - $table_list[] = $this->prefix.$val.' as '.$key; - } - - $left_join = array(); - // why??? - $left_tables= (array)$output->left_tables; - - foreach($left_tables as $key => $val) { - $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); - if($condition){ - $left_join[] = $val . ' '.$this->prefix.$output->_tables[$key].' as '.$key . ' on (' . $condition . ')'; - } - } - - - - if(!$output->columns) { - $columns = '*'; - } else { - $column_list = array(); - foreach($output->columns as $key => $val) { - $name = $val['name']; - $alias = $val['alias']; - if($val['click_count']) $click_count[] = $val['name']; - - if(substr($name,-1) == '*') { - $column_list[] = $name; - } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { - if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } else { - if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); - else $column_list[] = sprintf('%s',$name); - } - } - $columns = implode(',',$column_list); - } - - $condition = $this->getCondition($output); - - if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // list_count를 사용할 경우 적용 - if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); - - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - $this->_prepare($query); - $data = $this->_execute(); - if($this->isError()) return; - - if(count($click_count)>0 && count($output->conditions)>0){ - $_query = ''; - foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); - $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); - $this->_query($_query); - } - - $buff = new Object(); - $buff->data = $data; - return $buff; - } - - /** - * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 - * - * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; - **/ - function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { - require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); - - /* - // group by 절이 포함된 SELECT 쿼리의 전체 갯수를 구하기 위한 수정 - // 정상적인 동작이 확인되면 주석으로 막아둔 부분으로 대체합니다. - // - $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; - $total_count = $this->getCountCache($output->tables, $count_condition); - if($total_count === false) { - $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); - if (count($output->groups)) - $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); - $result = $this->_query($count_query); - $count_output = $this->_fetch($result); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $count_condition, $total_count); - } - */ - - // 전체 개수를 구함 - $count_query = sprintf("select count(*) as count from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); - $total_count = $this->getCountCache($output->tables, $condition); - if($total_count === false) { - $this->_prepare($count_query); - $count_output = $this->_execute(); - $total_count = (int)$count_output->count; - $this->putCountCache($output->tables, $condition, $total_count); - } - - $list_count = $output->list_count['value']; - if(!$list_count) $list_count = 20; - $page_count = $output->page_count['value']; - if(!$page_count) $page_count = 10; - $page = $output->page['value']; - if(!$page) $page = 1; - - // 전체 페이지를 구함 - if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; - else $total_page = 1; - - // 페이지 변수를 체크 - if($page > $total_page) $page = $total_page; - $start_count = ($page-1)*$list_count; - - // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 - if($output->order) { - $conditions = $this->getConditionList($output); - if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { - foreach($output->order as $key => $val) { - $col = $val[0]; - if(!in_array($col, array('list_order','update_order'))) continue; - if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); - else $condition = sprintf(' where %s < 2100000000 ', $col); - } - } - } - - $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); - - if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); - - if($output->order) { - foreach($output->order as $key => $val) { - $index_list[] = sprintf('%s %s', $val[0], $val[1]); - } - if(count($index_list)) $query .= ' order by '.implode(',',$index_list); - } - - // return 결과물 생성 - $buff = new Object(); - $buff->total_count = 0; - $buff->total_page = 0; - $buff->page = 1; - $buff->data = array(); - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - - // 쿼리 실행 - $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); - $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; - - $this->_prepare($query); - - if($this->isError()) { - $this->setError($this->handler->errorCode(), print_r($this->handler->errorInfo(),true)); - $this->actFinish(); - return $buff; - } - - $this->stmt->execute(); - - if($this->stmt->errorCode() != '00000') { - $this->setError($this->stmt->errorCode(), print_r($this->stmt->errorInfo(),true)); - $this->actFinish(); - return $buff; - } - - $output = null; - $virtual_no = $total_count - ($page-1)*$list_count; - while($tmp = $this->stmt->fetch(PDO::FETCH_ASSOC)) { - unset($obj); - foreach($tmp as $key => $val) { - $pos = strpos($key, '.'); - if($pos) $key = substr($key, $pos+1); - $obj->{$key} = $val; - } - $data[$virtual_no--] = $obj; - } - - $this->stmt = null; - $this->actFinish(); - - $buff = new Object(); - $buff->total_count = $total_count; - $buff->total_page = $total_page; - $buff->page = $page; - $buff->data = $data; - - $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); - return $buff; - } - } -?> + 'INTEGER', + 'number' => 'INTEGER', + 'varchar' => 'VARHAR', + 'char' => 'CHAR', + 'text' => 'TEXT', + 'bigtext' => 'TEXT', + 'date' => 'VARCHAR(14)', + 'float' => 'REAL', + ); + + /** + * @brief constructor + **/ + function DBSqlite3_pdo() { + $this->_setDBInfo(); + $this->_connect(); + } + + /** + * @brief 설치 가능 여부를 return + **/ + function isSupported() { + if(!class_exists('PDO')) return false; + return true; + } + + /** + * @brief DB정보 설정 및 connect/ close + **/ + function _setDBInfo() { + $db_info = Context::getDBInfo(); + $this->database = $db_info->db_database; + $this->prefix = $db_info->db_table_prefix; + if(!substr($this->prefix,-1)!='_') $this->prefix .= '_'; + } + + /** + * @brief DB 접속 + **/ + function _connect() { + // db 정보가 없으면 무시 + if(!$this->database) return; + + // 데이터 베이스 파일 접속 시도 + $this->handler = new PDO('sqlite:'.$this->database); + + if(!file_exists($this->database) || $error) { + $this->setError(-1,'permission denied to access database'); + //$this->setError(-1,$error); + $this->is_connected = false; + return; + } + + // 접속체크 + $this->is_connected = true; + $this->password = md5($this->password); + } + + /** + * @brief DB접속 해제 + **/ + function close() { + if(!$this->isConnected()) return; + $this->commit(); + } + + /** + * @brief 트랜잭션 시작 + **/ + function begin() { + if(!$this->isConnected() || $this->transaction_started) return; + if($this->handler->beginTransaction()) $this->transaction_started = true; + } + + /** + * @brief 롤백 + **/ + function rollback() { + if(!$this->isConnected() || !$this->transaction_started) return; + $this->handler->rollBack(); + $this->transaction_started = false; + } + + /** + * @brief 커밋 + **/ + function commit($force = false) { + if(!$force && (!$this->isConnected() || !$this->transaction_started)) return; + $this->handler->commit(); + $this->transaction_started = false; + } + + /** + * @brief 쿼리에서 입력되는 문자열 변수들의 quotation 조절 + **/ + function addQuotes($string) { + if(version_compare(PHP_VERSION, "5.9.0", "<") && get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string)); + if(!is_numeric($string)) $string = str_replace("'","''",$string); + return $string; + } + + /** + * @brief : 쿼리문의 prepare + **/ + function _prepare($query) { + if(!$this->isConnected()) return; + + // 쿼리 시작을 알림 + $this->actStart($query); + + $this->stmt = $this->handler->prepare($query); + + if($this->handler->errorCode() != '00000') { + $this->setError($this->handler->errorCode(), print_r($this->handler->errorInfo(),true)); + $this->actFinish(); + } + $this->bind_idx = 0; + $this->bind_vars = array(); + } + + /** + * @brief : stmt에 binding params + **/ + function _bind($val) { + if(!$this->isConnected() || !$this->stmt) return; + + $this->bind_idx ++; + $this->bind_vars[] = $val; + $this->stmt->bindParam($this->bind_idx, $val); + } + + /** + * @brief : prepare된 쿼리의 execute + **/ + function _execute() { + if(!$this->isConnected() || !$this->stmt) return; + + $this->stmt->execute(); + + if($this->stmt->errorCode() === '00000') { + $output = null; + while($tmp = $this->stmt->fetch(PDO::FETCH_ASSOC)) { + unset($obj); + foreach($tmp as $key => $val) { + $pos = strpos($key, '.'); + if($pos) $key = substr($key, $pos+1); + $obj->{$key} = str_replace("''","'",$val); + } + $output[] = $obj; + } + } else { + $this->setError($this->stmt->errorCode(),print_r($this->stmt->errorInfo(),true)); + } + + $this->stmt = null; + $this->actFinish(); + + if(is_array($output) && count($output)==1) return $output[0]; + return $output; + } + + /** + * @brief 1씩 증가되는 sequence값을 return + **/ + function getNextSequence() { + $query = sprintf("insert into %ssequence (seq) values (NULL)", $this->prefix); + $this->_prepare($query); + $result = $this->_execute(); + $sequence = $this->handler->lastInsertId(); + if($sequence % 10000 == 0) { + $query = sprintf("delete from %ssequence where seq < %d", $this->prefix, $sequence); + $this->_prepare($query); + $result = $this->_execute(); + } + + return $sequence; + } + + /** + * @brief 테이블 기생성 여부 return + **/ + function isTableExists($target_name) { + $query = sprintf('pragma table_info(%s%s)', $this->prefix, $target_name); + $this->_prepare($query); + if(!$this->_execute()) return false; + return true; + } + + /** + * @brief 특정 테이블에 특정 column 추가 + **/ + function addColumn($table_name, $column_name, $type='number', $size='', $default = '', $notnull=false) { + $type = $this->column_type[$type]; + if(strtoupper($type)=='INTEGER') $size = ''; + + $query = sprintf("alter table %s%s add %s ", $this->prefix, $table_name, $column_name); + if($size) $query .= sprintf(" %s(%s) ", $type, $size); + else $query .= sprintf(" %s ", $type); + if($default) $query .= sprintf(" default '%s' ", $default); + if($notnull) $query .= " not null "; + + $this->_prepare($query); + return $this->_execute(); + } + + /** + * @brief 특정 테이블에 특정 column 제거 + **/ + function dropColumn($table_name, $column_name) { + $query = sprintf("alter table %s%s drop column %s ", $this->prefix, $table_name, $column_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 column의 정보를 return + **/ + function isColumnExists($table_name, $column_name) { + $query = sprintf("pragma table_info(%s%s)", $this->prefix, $table_name); + $this->_prepare($query); + $output = $this->_execute(); + + if($output) { + $column_name = strtolower($column_name); + foreach($output as $key => $val) { + $name = strtolower($val->name); + if($column_name == $name) return true; + } + } + return false; + } + + /** + * @brief 특정 테이블에 특정 인덱스 추가 + * $target_columns = array(col1, col2) + * $is_unique? unique : none + **/ + function addIndex($table_name, $index_name, $target_columns, $is_unique = false) { + if(!is_array($target_columns)) $target_columns = array($target_columns); + + $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); + + $query = sprintf('CREATE %s INDEX %s ON %s%s (%s)', $is_unique?'UNIQUE':'', $key_name, $this->prefix, $table_name, implode(',',$target_columns)); + $this->_prepare($query); + $this->_execute(); + } + + /** + * @brief 특정 테이블의 특정 인덱스 삭제 + **/ + function dropIndex($table_name, $index_name, $is_unique = false) { + $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); + $query = sprintf("DROP INDEX %s", $this->prefix, $table_name, $key_name); + $this->_query($query); + } + + /** + * @brief 특정 테이블의 index 정보를 return + **/ + function isIndexExists($table_name, $index_name) { + $key_name = sprintf('%s%s_%s', $this->prefix, $table_name, $index_name); + + $query = sprintf("pragma index_info(%s)", $key_name); + $this->_prepare($query); + $output = $this->_execute(); + if(!$output) return false; + return true; + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXml($xml_doc) { + return $this->_createTable($xml_doc); + } + + /** + * @brief xml 을 받아서 테이블을 생성 + **/ + function createTableByXmlFile($file_name) { + if(!file_exists($file_name)) return; + // xml 파일을 읽음 + $buff = FileHandler::readFile($file_name); + return $this->_createTable($buff); + } + + /** + * @brief schema xml을 이용하여 create table query생성 + * + * type : number, varchar, text, char, date, \n + * opt : notnull, default, size\n + * index : primary key, index, unique\n + **/ + function _createTable($xml_doc) { + // xml parsing + $oXml = new XmlParser(); + $xml_obj = $oXml->parse($xml_doc); + + // 테이블 생성 schema 작성 + $table_name = $xml_obj->table->attrs->name; + if($this->isTableExists($table_name)) return; + $table_name = $this->prefix.$table_name; + + if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column; + else $columns = $xml_obj->table->column; + + foreach($columns as $column) { + $name = $column->attrs->name; + $type = $column->attrs->type; + if(strtoupper($this->column_type[$type])=='INTEGER') $size = ''; + else $size = $column->attrs->size; + $notnull = $column->attrs->notnull; + $primary_key = $column->attrs->primary_key; + $index = $column->attrs->index; + $unique = $column->attrs->unique; + $default = $column->attrs->default; + $auto_increment = $column->attrs->auto_increment; + + if($auto_increment) { + $column_schema[] = sprintf('%s %s PRIMARY KEY %s', + $name, + $this->column_type[$type], + $auto_increment?'AUTOINCREMENT':'' + ); + } else { + $column_schema[] = sprintf('%s %s%s %s %s %s', + $name, + $this->column_type[$type], + $size?'('.$size.')':'', + $notnull?'NOT NULL':'', + $primary_key?'PRIMARY KEY':'', + isset($default)?"DEFAULT '".$default."'":'' + ); + } + + if($unique) $unique_list[$unique][] = $name; + else if($index) $index_list[$index][] = $name; + } + + $schema = sprintf('CREATE TABLE %s (%s%s) ;', $table_name," ", implode($column_schema,", ")); + $this->_prepare($schema); + $this->_execute(); + if($this->isError()) return; + + if(count($unique_list)) { + foreach($unique_list as $key => $val) { + $query = sprintf('CREATE UNIQUE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); + $this->_prepare($query); + $this->_execute(); + if($this->isError()) $this->rollback(); + } + } + + if(count($index_list)) { + foreach($index_list as $key => $val) { + $query = sprintf('CREATE INDEX %s_%s ON %s (%s)', $this->addQuotes($table_name), $key, $this->addQuotes($table_name), implode(',',$val)); + $this->_prepare($query); + $this->_execute(); + if($this->isError()) $this->rollback(); + } + } + } + + /** + * @brief 조건문 작성하여 return + **/ + function getCondition($output) { + if(!$output->conditions) return; + $condition = $this->_getCondition($output->conditions,$output->column_type); + if($condition) $condition = ' where '.$condition; + return $condition; + } + + function getLeftCondition($conditions,$column_type){ + return $this->_getCondition($conditions,$column_type); + } + + + function _getCondition($conditions,$column_type) { + $condition = ''; + foreach($conditions as $val) { + $sub_condition = ''; + foreach($val['condition'] as $v) { + if(!isset($v['value'])) continue; + if($v['value'] === '') continue; + if(!in_array(gettype($v['value']), array('string', 'integer', 'double'))) continue; + + $name = $v['column']; + $operation = $v['operation']; + $value = $v['value']; + $type = $this->getColumnType($column_type,$name); + $pipe = $v['pipe']; + + $value = $this->getConditionValue($name, $value, $operation, $type, $column_type); + if(!$value) $value = $v['value']; + $str = $this->getConditionPart($name, $value, $operation); + if($sub_condition) $sub_condition .= ' '.$pipe.' '; + $sub_condition .= $str; + } + if($sub_condition) { + if($condition && $val['pipe']) $condition .= ' '.$val['pipe'].' '; + $condition .= '('.$sub_condition.')'; + } + } + return $condition; + } + + /** + * @brief insertAct 처리 + **/ + function _executeInsertAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = $this->prefix.$val; + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + $name = $val['name']; + $value = $val['value']; + + $key_list[] = $name; + + if($output->column_type[$name]!='number') $val_list[] = $this->addQuotes($value); + else { + if(!$value || is_numeric($value)) $value = (int)$value; + $val_list[] = $value; + } + + $prepare_list[] = '?'; + } + + $query = sprintf("INSERT INTO %s (%s) VALUES (%s);", implode(',',$table_list), implode(',',$key_list), implode(',',$prepare_list)); + + $this->_prepare($query); + + $val_count = count($val_list); + for($i=0;$i<$val_count;$i++) $this->_bind($val_list[$i]); + + return $this->_execute(); + } + + /** + * @brief updateAct 처리 + **/ + function _executeUpdateAct($output) { + $table_count = count(array_values($output->tables)); + + // 대상 테이블이 1개일 경우 + if($table_count == 1) { + // 테이블 정리 + list($target_table) = array_values($output->tables); + $target_table = $this->prefix.$target_table; + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + if(strpos($name,'.')!==false&&strpos($value,'.')!==false) $column_list[] = $name.' = '.$value; + else { + if($output->column_type[$name]!='number') $value = "'".$this->addQuotes($value)."'"; + elseif(!$value || is_numeric($value)) $value = (int)$value; + + $column_list[] = sprintf("%s = %s", $name, $value); + } + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("update %s set %s %s", $target_table, implode(',',$column_list), $condition); + + // 대상 테이블이 2개일 경우 (sqlite에서 update 테이블을 1개 이상 지정 못해서 이렇게 꽁수로... 다른 방법이 있으려나..) + } elseif($table_count == 2) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[$val] = $this->prefix.$key; + } + list($source_table, $target_table) = array_values($table_list); + + // 조건절 정리 + $condition = $this->getCondition($output); + foreach($table_list as $key => $val) { + $condition = eregi_replace($key.'\\.', $val.'.', $condition); + } + + // 컬럼 정리 + foreach($output->columns as $key => $val) { + if(!isset($val['value'])) continue; + $name = $val['name']; + $value = $val['value']; + list($s_prefix, $s_column) = explode('.',$name); + list($t_prefix, $t_column) = explode('.',$value); + + $s_table = $table_list[$s_prefix]; + $t_table = $table_list[$t_prefix]; + $column_list[] = sprintf(' %s = (select %s from %s %s) ', $s_column, $t_column, $t_table, $condition); + } + + $query = sprintf('update %s set %s where exists(select * from %s %s)', $source_table, implode(',', $column_list), $target_table, $condition); + } else { + return; + } + + $this->_prepare($query); + return $this->_execute(); + } + + /** + * @brief deleteAct 처리 + **/ + function _executeDeleteAct($output) { + // 테이블 정리 + foreach($output->tables as $key => $val) { + $table_list[] = $this->prefix.$val; + } + + // 조건절 정리 + $condition = $this->getCondition($output); + + $query = sprintf("delete from %s %s", implode(',',$table_list), $condition); + + $this->_prepare($query); + return $this->_execute(); + } + + /** + * @brief selectAct 처리 + * + * select의 경우 특정 페이지의 목록을 가져오는 것을 편하게 하기 위해\n + * navigation이라는 method를 제공 + **/ + function _executeSelectAct($output) { + // 테이블 정리 + $table_list = array(); + foreach($output->tables as $key => $val) { + $table_list[] = $this->prefix.$val.' as '.$key; + } + + $left_join = array(); + // why??? + $left_tables= (array)$output->left_tables; + + foreach($left_tables as $key => $val) { + $condition = $this->_getCondition($output->left_conditions[$key],$output->column_type); + if($condition){ + $left_join[] = $val . ' '.$this->prefix.$output->_tables[$key].' as '.$key . ' on (' . $condition . ')'; + } + } + + + + if(!$output->columns) { + $columns = '*'; + } else { + $column_list = array(); + foreach($output->columns as $key => $val) { + $name = $val['name']; + $alias = $val['alias']; + if($val['click_count']) $click_count[] = $val['name']; + + if(substr($name,-1) == '*') { + $column_list[] = $name; + } elseif(strpos($name,'.')===false && strpos($name,'(')===false) { + if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } else { + if($alias) $column_list[] = sprintf('%s as %s', $name, $alias); + else $column_list[] = sprintf('%s',$name); + } + } + $columns = implode(',',$column_list); + } + + $condition = $this->getCondition($output); + + if($output->list_count && $output->page) return $this->_getNavigationData($table_list, $columns, $left_join, $condition, $output); + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list),implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // list_count를 사용할 경우 적용 + if($output->list_count['value']) $query = sprintf('%s limit %d', $query, $output->list_count['value']); + + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + $this->_prepare($query); + $data = $this->_execute(); + if($this->isError()) return; + + if(count($click_count)>0 && count($output->conditions)>0){ + $_query = ''; + foreach($click_count as $k => $c) $_query .= sprintf(',%s=%s+1 ',$c,$c); + $_query = sprintf('update %s set %s %s',implode(',',$table_list), substr($_query,1), $condition); + $this->_query($_query); + } + + $buff = new Object(); + $buff->data = $data; + return $buff; + } + + /** + * @brief query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다 + * + * 그닥 좋지는 않은 구조이지만 편리하다.. -_-; + **/ + function _getNavigationData($table_list, $columns, $left_join, $condition, $output) { + require_once(_XE_PATH_.'classes/page/PageHandler.class.php'); + + /* + // group by 절이 포함된 SELECT 쿼리의 전체 갯수를 구하기 위한 수정 + // 정상적인 동작이 확인되면 주석으로 막아둔 부분으로 대체합니다. + // + $count_condition = count($output->groups) ? sprintf('%s group by %s', $condition, implode(', ', $output->groups)) : $condition; + $total_count = $this->getCountCache($output->tables, $count_condition); + if($total_count === false) { + $count_query = sprintf("select count(*) as count from %s %s %s", implode(', ', $table_list), implode(' ', $left_join), $count_condition); + if (count($output->groups)) + $count_query = sprintf('select count(*) as count from (%s) xet', $count_query); + $result = $this->_query($count_query); + $count_output = $this->_fetch($result); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $count_condition, $total_count); + } + */ + + // 전체 개수를 구함 + $count_query = sprintf("select count(*) as count from %s %s %s", implode(',',$table_list),implode(' ',$left_join), $condition); + $total_count = $this->getCountCache($output->tables, $condition); + if($total_count === false) { + $this->_prepare($count_query); + $count_output = $this->_execute(); + $total_count = (int)$count_output->count; + $this->putCountCache($output->tables, $condition, $total_count); + } + + $list_count = $output->list_count['value']; + if(!$list_count) $list_count = 20; + $page_count = $output->page_count['value']; + if(!$page_count) $page_count = 10; + $page = $output->page['value']; + if(!$page) $page = 1; + + // 전체 페이지를 구함 + if($total_count) $total_page = (int)( ($total_count-1) / $list_count) + 1; + else $total_page = 1; + + // 페이지 변수를 체크 + if($page > $total_page) $page = $total_page; + $start_count = ($page-1)*$list_count; + + // list_order, update_order 로 정렬시에 인덱스 사용을 위해 condition에 쿼리 추가 + if($output->order) { + $conditions = $this->getConditionList($output); + if(!in_array('list_order', $conditions) && !in_array('update_order', $conditions)) { + foreach($output->order as $key => $val) { + $col = $val[0]; + if(!in_array($col, array('list_order','update_order'))) continue; + if($condition) $condition .= sprintf(' and %s < 2100000000 ', $col); + else $condition = sprintf(' where %s < 2100000000 ', $col); + } + } + } + + $query = sprintf("select %s from %s %s %s", $columns, implode(',',$table_list), implode(' ',$left_join), $condition); + + if(count($output->groups)) $query .= sprintf(' group by %s', implode(',',$output->groups)); + + if($output->order) { + foreach($output->order as $key => $val) { + $index_list[] = sprintf('%s %s', $val[0], $val[1]); + } + if(count($index_list)) $query .= ' order by '.implode(',',$index_list); + } + + // return 결과물 생성 + $buff = new Object(); + $buff->total_count = 0; + $buff->total_page = 0; + $buff->page = 1; + $buff->data = array(); + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + + // 쿼리 실행 + $query = sprintf('%s limit %d, %d', $query, $start_count, $list_count); + $query .= (__DEBUG_QUERY__&1 && $output->query_id)?sprintf(' '.$this->comment_syntax,$this->query_id):''; + + $this->_prepare($query); + + if($this->isError()) { + $this->setError($this->handler->errorCode(), print_r($this->handler->errorInfo(),true)); + $this->actFinish(); + return $buff; + } + + $this->stmt->execute(); + + if($this->stmt->errorCode() != '00000') { + $this->setError($this->stmt->errorCode(), print_r($this->stmt->errorInfo(),true)); + $this->actFinish(); + return $buff; + } + + $output = null; + $virtual_no = $total_count - ($page-1)*$list_count; + while($tmp = $this->stmt->fetch(PDO::FETCH_ASSOC)) { + unset($obj); + foreach($tmp as $key => $val) { + $pos = strpos($key, '.'); + if($pos) $key = substr($key, $pos+1); + $obj->{$key} = $val; + } + $data[$virtual_no--] = $obj; + } + + $this->stmt = null; + $this->actFinish(); + + $buff = new Object(); + $buff->total_count = $total_count; + $buff->total_page = $total_page; + $buff->page = $page; + $buff->data = $data; + + $buff->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count); + return $buff; + } + } +?> diff --git a/classes/display/DisplayHandler.class.php b/classes/display/DisplayHandler.class.php index c6116eb93..8ad991f7a 100644 --- a/classes/display/DisplayHandler.class.php +++ b/classes/display/DisplayHandler.class.php @@ -1,278 +1,278 @@ -gz_enabled = true; - - // request method에 따른 컨텐츠 결과물 추출 - if(Context::get('xeVirtualRequestMethod')=='xml') { - require_once("./classes/display/VirtualXMLDisplayHandler.php"); - $handler = new VirtualXMLDisplayHandler(); - } - else if(Context::getRequestMethod() == 'XMLRPC') { - require_once("./classes/display/XMLDisplayHandler.php"); - $handler = new XMLDisplayHandler(); - if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) $this->gz_enabled = false; - } - else if(Context::getRequestMethod() == 'JSON') { - require_once("./classes/display/JSONDisplayHandler.php"); - $handler = new JSONDisplayHandler(); - } - else { - require_once("./classes/display/HTMLDisplayHandler.php"); - $handler = new HTMLDisplayHandler(); - } - - $output = $handler->toDoc($oModule); - - // 출력하기 전에 trigger 호출 (before) - ModuleHandler::triggerCall('display', 'before', $output); - - // 애드온 실행 - $called_position = 'before_display_content'; - $oAddonController = &getController('addon'); - $addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone()?"mobile":"pc"); - @include($addon_file); - - if(method_exists($handler, "prepareToPrint")) $handler->prepareToPrint($output); - - // header 출력 - if($this->gz_enabled) header("Content-Encoding: gzip"); - if(Context::getResponseMethod() == 'JSON') $this->_printJSONHeader(); - else if(Context::getResponseMethod() != 'HTML') $this->_printXMLHeader(); - else $this->_printHTMLHeader(); - - // debugOutput 출력 - $this->content_size = strlen($output); - $output .= $this->_debugOutput(); - - // 결과물 직접 출력 - if($this->gz_enabled) print ob_gzhandler($output, 5); - else print $output; - - // 출력 후 trigger 호출 (after) - ModuleHandler::triggerCall('display', 'after', $content); - } - - - /** - * @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_OUTPUT__ == 0, messages are written in ./files/_debug_message.php - **/ - function _debugOutput() { - if(!__DEBUG__) return; - - $end = getMicroTime(); - - // Firebug 콘솔 출력 - if(__DEBUG_OUTPUT__ == 2 && version_compare(PHP_VERSION, '6.0.0') === -1) { - static $firephp; - if(!isset($firephp)) $firephp = FirePHP::getInstance(true); - - if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { - $firephp->fb('Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php', 'The IP address is not allowed.'); - return; - } - - // 전체 실행 시간 출력, Request/Response info 출력 - if(__DEBUG__ & 2) { - $firephp->fb( - array('Request / Response info >>> '.$_SERVER['REQUEST_METHOD'].' / '.Context::getResponseMethod(), - array( - array('Request URI', 'Request method', 'Response method', 'Response contents size'), - array( - sprintf("%s:%s%s%s%s", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['PHP_SELF'], $_SERVER['QUERY_STRING']?'?':'', $_SERVER['QUERY_STRING']), - $_SERVER['REQUEST_METHOD'], - Context::getResponseMethod(), - $this->content_size.' byte' - ) - ) - ), - 'TABLE' - ); - $firephp->fb( - array('Elapsed time >>> Total : '.sprintf('%0.5f sec', $end - __StartTime__), - array(array('DB queries', 'class file load', 'Template compile', 'XmlParse compile', 'PHP', 'Widgets', 'Trans Content'), - array( - sprintf('%0.5f sec', $GLOBALS['__db_elapsed_time__']), - sprintf('%0.5f sec', $GLOBALS['__elapsed_class_load__']), - sprintf('%0.5f sec (%d called)', $GLOBALS['__template_elapsed__'], $GLOBALS['__TemplateHandlerCalled__']), - sprintf('%0.5f sec', $GLOBALS['__xmlparse_elapsed__']), - sprintf('%0.5f sec', $end-__StartTime__-$GLOBALS['__template_elapsed__']-$GLOBALS['__xmlparse_elapsed__']-$GLOBALS['__db_elapsed_time__']-$GLOBALS['__elapsed_class_load__']), - sprintf('%0.5f sec', $GLOBALS['__widget_excute_elapsed__']), - sprintf('%0.5f sec', $GLOBALS['__trans_content_elapsed__']) - ) - ) - ), - 'TABLE' - ); - } - - // DB 쿼리 내역 출력 - if((__DEBUG__ & 4) && $GLOBALS['__db_queries__']) { - $queries_output = array(array('Query', 'Elapsed time', 'Result')); - foreach($GLOBALS['__db_queries__'] as $query) { - array_push($queries_output, array($query['query'], sprintf('%0.5f', $query['elapsed_time']), $query['result'])); - } - $firephp->fb( - array( - 'DB Queries >>> '.count($GLOBALS['__db_queries__']).' Queries, '.sprintf('%0.5f sec', $GLOBALS['__db_elapsed_time__']), - $queries_output - ), - 'TABLE' - ); - } - - - // 파일 및 HTML 주석으로 출력 - } else { - - // 전체 실행 시간 출력, Request/Response info 출력 - if(__DEBUG__ & 2) { - if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { - return; - } - - // Request/Response 정보 작성 - $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 method \t\t\t: %s\n", $_SERVER['REQUEST_METHOD']); - $buff .= sprintf("\tResponse method \t\t: %s\n", Context::getResponseMethod()); - $buff .= sprintf("\tResponse contents size\t\t: %d byte\n", $this->content_size); - - // 전체 실행 시간 - $buff .= sprintf("\n- Total elapsed time : %0.5f sec\n", $end-__StartTime__); - - $buff .= sprintf("\tclass file load elapsed time \t: %0.5f sec\n", $GLOBALS['__elapsed_class_load__']); - $buff .= sprintf("\tTemplate compile elapsed time\t: %0.5f sec (%d called)\n", $GLOBALS['__template_elapsed__'], $GLOBALS['__TemplateHandlerCalled__']); - $buff .= sprintf("\tXmlParse compile elapsed time\t: %0.5f sec\n", $GLOBALS['__xmlparse_elapsed__']); - $buff .= sprintf("\tPHP elapsed time \t\t: %0.5f sec\n", $end-__StartTime__-$GLOBALS['__template_elapsed__']-$GLOBALS['__xmlparse_elapsed__']-$GLOBALS['__db_elapsed_time__']-$GLOBALS['__elapsed_class_load__']); - - // 위젯 실행 시간 작성 - $buff .= sprintf("\n\tWidgets elapsed time \t\t: %0.5f sec", $GLOBALS['__widget_excute_elapsed__']); - - // 레이아웃 실행 시간 - $buff .= sprintf("\n\tLayout compile elapsed time \t: %0.5f sec", $GLOBALS['__layout_compile_elapsed__']); - - // 위젯, 에디터 컴포넌트 치환 시간 - $buff .= sprintf("\n\tTrans Content \t\t\t: %0.5f sec\n", $GLOBALS['__trans_content_elapsed__']); - } - - // DB 로그 작성 - if(__DEBUG__ & 4) { - if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { - return; - } - - if($GLOBALS['__db_queries__']) { - $buff .= sprintf("\n- DB Queries : %d Queries. %0.5f sec\n", count($GLOBALS['__db_queries__']), $GLOBALS['__db_elapsed_time__']); - $num = 0; - - foreach($GLOBALS['__db_queries__'] as $query) { - $buff .= sprintf("\t%02d. %s\n\t\t%0.6f sec. ", ++$num, $query['query'], $query['elapsed_time']); - if($query['result'] == 'Success') { - $buff .= "Query Success\n"; - } else { - $buff .= sprintf("Query $s : %d\n\t\t\t %s\n", $query['result'], $query['errno'], $query['errstr']); - } - } - } - } - - // HTML 주석으로 출력 - if($buff && __DEBUG_OUTPUT__ == 1 && Context::getResponseMethod() == 'HTML') { - $buff = sprintf("[%s %s:%d]\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, print_r($buff, true)); - - if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { - $buff = 'The IP address is not allowed. Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php'; - } - - return ""; - } - - // 파일에 출력 - if($buff && __DEBUG_OUTPUT__ == 0) { - $debug_file = _XE_PATH_.'files/_debug_message.php'; - $buff = sprintf("[%s %s:%d]\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, print_r($buff, true)); - - $buff = str_repeat('=', 40)."\n".$buff.str_repeat('-', 40); - $buff = "\n\n"; - - if(@!$fp = fopen($debug_file, 'a')) return; - fwrite($fp, $buff); - fclose($fp); - } - } - } - - /** - * @brief print a HTTP HEADER for XML, which is encoded in UTF-8 - **/ - function _printXMLHeader() { - header("Content-Type: text/xml; charset=UTF-8"); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - } - - - /** - * @brief print a HTTP HEADER for HTML, which is encoded in UTF-8 - **/ - function _printHTMLHeader() { - header("Content-Type: text/html; charset=UTF-8"); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - } - - - /** - * @brief print a HTTP HEADER for JSON, which is encoded in UTF-8 - **/ - function _printJSONHeader() { - header("Content-Type: text/html; charset=UTF-8"); - header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - header("Cache-Control: no-store, no-cache, must-revalidate"); - header("Cache-Control: post-check=0, pre-check=0", false); - header("Pragma: no-cache"); - } - - - - - } -?> +gz_enabled = true; + + // request method에 따른 컨텐츠 결과물 추출 + if(Context::get('xeVirtualRequestMethod')=='xml') { + require_once("./classes/display/VirtualXMLDisplayHandler.php"); + $handler = new VirtualXMLDisplayHandler(); + } + else if(Context::getRequestMethod() == 'XMLRPC') { + require_once("./classes/display/XMLDisplayHandler.php"); + $handler = new XMLDisplayHandler(); + if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false) $this->gz_enabled = false; + } + else if(Context::getRequestMethod() == 'JSON') { + require_once("./classes/display/JSONDisplayHandler.php"); + $handler = new JSONDisplayHandler(); + } + else { + require_once("./classes/display/HTMLDisplayHandler.php"); + $handler = new HTMLDisplayHandler(); + } + + $output = $handler->toDoc($oModule); + + // 출력하기 전에 trigger 호출 (before) + ModuleHandler::triggerCall('display', 'before', $output); + + // 애드온 실행 + $called_position = 'before_display_content'; + $oAddonController = &getController('addon'); + $addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone()?"mobile":"pc"); + @include($addon_file); + + if(method_exists($handler, "prepareToPrint")) $handler->prepareToPrint($output); + + // header 출력 + if($this->gz_enabled) header("Content-Encoding: gzip"); + if(Context::getResponseMethod() == 'JSON') $this->_printJSONHeader(); + else if(Context::getResponseMethod() != 'HTML') $this->_printXMLHeader(); + else $this->_printHTMLHeader(); + + // debugOutput 출력 + $this->content_size = strlen($output); + $output .= $this->_debugOutput(); + + // 결과물 직접 출력 + if($this->gz_enabled) print ob_gzhandler($output, 5); + else print $output; + + // 출력 후 trigger 호출 (after) + ModuleHandler::triggerCall('display', 'after', $content); + } + + + /** + * @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_OUTPUT__ == 0, messages are written in ./files/_debug_message.php + **/ + function _debugOutput() { + if(!__DEBUG__) return; + + $end = getMicroTime(); + + // Firebug 콘솔 출력 + if(__DEBUG_OUTPUT__ == 2 && version_compare(PHP_VERSION, '6.0.0') === -1) { + static $firephp; + if(!isset($firephp)) $firephp = FirePHP::getInstance(true); + + if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { + $firephp->fb('Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php', 'The IP address is not allowed.'); + return; + } + + // 전체 실행 시간 출력, Request/Response info 출력 + if(__DEBUG__ & 2) { + $firephp->fb( + array('Request / Response info >>> '.$_SERVER['REQUEST_METHOD'].' / '.Context::getResponseMethod(), + array( + array('Request URI', 'Request method', 'Response method', 'Response contents size'), + array( + sprintf("%s:%s%s%s%s", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['PHP_SELF'], $_SERVER['QUERY_STRING']?'?':'', $_SERVER['QUERY_STRING']), + $_SERVER['REQUEST_METHOD'], + Context::getResponseMethod(), + $this->content_size.' byte' + ) + ) + ), + 'TABLE' + ); + $firephp->fb( + array('Elapsed time >>> Total : '.sprintf('%0.5f sec', $end - __StartTime__), + array(array('DB queries', 'class file load', 'Template compile', 'XmlParse compile', 'PHP', 'Widgets', 'Trans Content'), + array( + sprintf('%0.5f sec', $GLOBALS['__db_elapsed_time__']), + sprintf('%0.5f sec', $GLOBALS['__elapsed_class_load__']), + sprintf('%0.5f sec (%d called)', $GLOBALS['__template_elapsed__'], $GLOBALS['__TemplateHandlerCalled__']), + sprintf('%0.5f sec', $GLOBALS['__xmlparse_elapsed__']), + sprintf('%0.5f sec', $end-__StartTime__-$GLOBALS['__template_elapsed__']-$GLOBALS['__xmlparse_elapsed__']-$GLOBALS['__db_elapsed_time__']-$GLOBALS['__elapsed_class_load__']), + sprintf('%0.5f sec', $GLOBALS['__widget_excute_elapsed__']), + sprintf('%0.5f sec', $GLOBALS['__trans_content_elapsed__']) + ) + ) + ), + 'TABLE' + ); + } + + // DB 쿼리 내역 출력 + if((__DEBUG__ & 4) && $GLOBALS['__db_queries__']) { + $queries_output = array(array('Query', 'Elapsed time', 'Result')); + foreach($GLOBALS['__db_queries__'] as $query) { + array_push($queries_output, array($query['query'], sprintf('%0.5f', $query['elapsed_time']), $query['result'])); + } + $firephp->fb( + array( + 'DB Queries >>> '.count($GLOBALS['__db_queries__']).' Queries, '.sprintf('%0.5f sec', $GLOBALS['__db_elapsed_time__']), + $queries_output + ), + 'TABLE' + ); + } + + + // 파일 및 HTML 주석으로 출력 + } else { + + // 전체 실행 시간 출력, Request/Response info 출력 + if(__DEBUG__ & 2) { + if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { + return; + } + + // Request/Response 정보 작성 + $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 method \t\t\t: %s\n", $_SERVER['REQUEST_METHOD']); + $buff .= sprintf("\tResponse method \t\t: %s\n", Context::getResponseMethod()); + $buff .= sprintf("\tResponse contents size\t\t: %d byte\n", $this->content_size); + + // 전체 실행 시간 + $buff .= sprintf("\n- Total elapsed time : %0.5f sec\n", $end-__StartTime__); + + $buff .= sprintf("\tclass file load elapsed time \t: %0.5f sec\n", $GLOBALS['__elapsed_class_load__']); + $buff .= sprintf("\tTemplate compile elapsed time\t: %0.5f sec (%d called)\n", $GLOBALS['__template_elapsed__'], $GLOBALS['__TemplateHandlerCalled__']); + $buff .= sprintf("\tXmlParse compile elapsed time\t: %0.5f sec\n", $GLOBALS['__xmlparse_elapsed__']); + $buff .= sprintf("\tPHP elapsed time \t\t: %0.5f sec\n", $end-__StartTime__-$GLOBALS['__template_elapsed__']-$GLOBALS['__xmlparse_elapsed__']-$GLOBALS['__db_elapsed_time__']-$GLOBALS['__elapsed_class_load__']); + + // 위젯 실행 시간 작성 + $buff .= sprintf("\n\tWidgets elapsed time \t\t: %0.5f sec", $GLOBALS['__widget_excute_elapsed__']); + + // 레이아웃 실행 시간 + $buff .= sprintf("\n\tLayout compile elapsed time \t: %0.5f sec", $GLOBALS['__layout_compile_elapsed__']); + + // 위젯, 에디터 컴포넌트 치환 시간 + $buff .= sprintf("\n\tTrans Content \t\t\t: %0.5f sec\n", $GLOBALS['__trans_content_elapsed__']); + } + + // DB 로그 작성 + if(__DEBUG__ & 4) { + if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { + return; + } + + if($GLOBALS['__db_queries__']) { + $buff .= sprintf("\n- DB Queries : %d Queries. %0.5f sec\n", count($GLOBALS['__db_queries__']), $GLOBALS['__db_elapsed_time__']); + $num = 0; + + foreach($GLOBALS['__db_queries__'] as $query) { + $buff .= sprintf("\t%02d. %s\n\t\t%0.6f sec. ", ++$num, $query['query'], $query['elapsed_time']); + if($query['result'] == 'Success') { + $buff .= "Query Success\n"; + } else { + $buff .= sprintf("Query $s : %d\n\t\t\t %s\n", $query['result'], $query['errno'], $query['errstr']); + } + } + } + } + + // HTML 주석으로 출력 + if($buff && __DEBUG_OUTPUT__ == 1 && Context::getResponseMethod() == 'HTML') { + $buff = sprintf("[%s %s:%d]\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, print_r($buff, true)); + + if(__DEBUG_PROTECT__ == 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { + $buff = 'The IP address is not allowed. Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php'; + } + + return ""; + } + + // 파일에 출력 + if($buff && __DEBUG_OUTPUT__ == 0) { + $debug_file = _XE_PATH_.'files/_debug_message.php'; + $buff = sprintf("[%s %s:%d]\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, print_r($buff, true)); + + $buff = str_repeat('=', 40)."\n".$buff.str_repeat('-', 40); + $buff = "\n\n"; + + if(@!$fp = fopen($debug_file, 'a')) return; + fwrite($fp, $buff); + fclose($fp); + } + } + } + + /** + * @brief print a HTTP HEADER for XML, which is encoded in UTF-8 + **/ + function _printXMLHeader() { + header("Content-Type: text/xml; charset=UTF-8"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + } + + + /** + * @brief print a HTTP HEADER for HTML, which is encoded in UTF-8 + **/ + function _printHTMLHeader() { + header("Content-Type: text/html; charset=UTF-8"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + } + + + /** + * @brief print a HTTP HEADER for JSON, which is encoded in UTF-8 + **/ + function _printJSONHeader() { + header("Content-Type: text/html; charset=UTF-8"); + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + header("Cache-Control: no-store, no-cache, must-revalidate"); + header("Cache-Control: post-check=0, pre-check=0", false); + header("Pragma: no-cache"); + } + + + + + } +?> diff --git a/classes/editor/EditorHandler.class.php b/classes/editor/EditorHandler.class.php index 252619d24..930139792 100644 --- a/classes/editor/EditorHandler.class.php +++ b/classes/editor/EditorHandler.class.php @@ -1,27 +1,27 @@ -extra_vars) return; - - foreach($info->extra_vars as $key => $val) { - $this->{$key} = trim($val->value); - } - } - - } - -?> +extra_vars) return; + + foreach($info->extra_vars as $key => $val) { + $this->{$key} = trim($val->value); + } + } + + } + +?> diff --git a/classes/extravar/Extravar.class.php b/classes/extravar/Extravar.class.php index 8b24e3595..b4b8e7162 100644 --- a/classes/extravar/Extravar.class.php +++ b/classes/extravar/Extravar.class.php @@ -1,300 +1,300 @@ -module_srl = $module_srl; - } - - /** - * @brief 확장변수 키를 등록 - * @param module_srl, idx, name, type, default, desc, is_required, search, value - **/ - function setExtraVarKeys($extra_keys) { - if(!is_array($extra_keys) || !count($extra_keys)) return; - foreach($extra_keys as $key => $val) { - $obj = null; - $obj = new ExtraItem($val->module_srl, $val->idx, $val->name, $val->type, $val->default, $val->desc, $val->is_required, $val->search, $val->value, $val->eid); - $this->keys[$val->idx] = $obj; - } - } - - /** - * @brief 확장변수 객체 배열 return - **/ - function getExtraVars() { - return $this->keys; - } - } - - /** - * @class ExtraItem - * @author zero (zero@nzeo.com) - * @brief 확장변수의 개별 값 - **/ - class ExtraItem { - var $module_srl = 0; - var $idx = 0; - var $name = 0; - var $type = 'text'; - var $default = null; - var $desc = ''; - var $is_required = 'N'; - var $search = 'N'; - var $value = null; - var $eid = ''; - - /** - * @brief constructor - **/ - function ExtraItem($module_srl, $idx, $name, $type = 'text', $default = null, $desc = '', $is_required = 'N', $search = 'N', $value = null, $eid = '') { - if(!$idx) return; - $this->module_srl = $module_srl; - $this->idx = $idx; - $this->name = $name; - $this->type = $type; - $this->default = $default; - $this->desc = $desc; - $this->is_required = $is_required; - $this->search = $search; - $this->value = $value; - $this->eid = $eid; - } - - /** - * @brief 값 지정 - **/ - function setValue($value) { - $this->value = $value; - } - - /** - * @brief type에 따라서 주어진 값을 변형하여 원형 값을 return - **/ - function _getTypeValue($type, $value) { - $value = trim($value); - if(!isset($value)) return; - switch($type) { - case 'homepage' : - if($value && !preg_match('/^([a-z]+):\/\//i',$value)) $value = 'http://'.$value; - return htmlspecialchars($value); - break; - case 'tel' : - if(is_array($value)) $values = $value; - elseif(strpos($value,'|@|')!==false) $values = explode('|@|', $value); - elseif(strpos($value,',')!==false) $values = explode(',', $value); - $values[0] = $values[0]; - $values[1] = $values[1]; - $values[2] = $values[2]; - return $values; - break; - break; - case 'checkbox' : - case 'radio' : - case 'select' : - if(is_array($value)) $values = $value; - elseif(strpos($value,'|@|')!==false) $values = explode('|@|', $value); - elseif(strpos($value,',')!==false) $values = explode(',', $value); - else $values = array($value); - for($i=0;$i_getTypeValue($this->type, $this->value); - switch($this->type) { - case 'homepage' : - return ($value)?sprintf('%s', $value, $value):""; - case 'email_address' : - return ($value)?sprintf('%s', $value, $value):""; - break; - case 'tel' : - return sprintf('%s - %s - %s', $value[0],$value[1],$value[2]); - break; - case 'textarea' : - return nl2br($value); - break; - case 'checkbox' : - if(is_array($value)) return implode(', ',$value); - else return $value; - break; - case 'date' : - return zdate($value,"Y-m-d"); - break; - case 'select' : - case 'radio' : - if(is_array($value)) return implode(', ',$value); - else return $value; - break; - case 'kr_zip' : - if(is_array($value)) return implode(' ',$value); - else return $value; - break; - // case 'text' : - default : - return $value; - } - } - - /** - * @brief type에 따른 form을 리턴 - **/ - function getFormHTML() { - $type = $this->type; - $name = $this->name; - $value = $this->_getTypeValue($this->type, $this->value); - $default = $this->_getTypeValue($this->type, $this->default); - $column_name = 'extra_vars'.$this->idx; - - $buff = ''; - switch($type) { - // 홈페이지 주소 - case 'homepage' : - $buff .= ''; - break; - - // Email 주소 - case 'email_address' : - $buff .= ''; - break; - - // 전화번호 - case 'tel' : - $buff .= - ''. - ''. - ''; - break; - - // textarea - case 'textarea' : - $buff .= ''; - break; - - // 다중 선택 - case 'checkbox' : - $buff .= '
    '; - foreach($default as $v) { - if($value && in_array($v, $value)) $checked = ' checked="checked"'; - else $checked = ''; - $buff .='
  • '.$v.'
  • '; - } - $buff .= '
'; - break; - - // 단일 선택 - case 'select' : - $buff .= ''; - break; - - // radio - case 'radio' : - $buff .= '
    '; - foreach($default as $v) { - if($value && in_array($v,$value)) $checked = ' checked="checked"'; - else $checked = ''; - $buff .= '
  • '.$v.'
  • '; - } - $buff .= '
'; - break; - - // 날짜 입력 - case 'date' : - // datepicker javascript plugin load - Context::loadJavascriptPlugin('ui.datepicker'); - - $buff .= - ''. - ''."\n". - ''; - break; - - // 주소 입력 - case "kr_zip" : - // krzip address javascript plugin load - Context::loadJavascriptPlugin('ui.krzip'); - - $buff .= - ''. - - ''. - - ''. - - ''. - ''; - break; - - // 일반 text - default : - $buff .=' '; - break; - } - if($this->desc) $buff .= '

'.$this->desc.'

'; - return $buff; - } - } -?> +module_srl = $module_srl; + } + + /** + * @brief 확장변수 키를 등록 + * @param module_srl, idx, name, type, default, desc, is_required, search, value + **/ + function setExtraVarKeys($extra_keys) { + if(!is_array($extra_keys) || !count($extra_keys)) return; + foreach($extra_keys as $key => $val) { + $obj = null; + $obj = new ExtraItem($val->module_srl, $val->idx, $val->name, $val->type, $val->default, $val->desc, $val->is_required, $val->search, $val->value, $val->eid); + $this->keys[$val->idx] = $obj; + } + } + + /** + * @brief 확장변수 객체 배열 return + **/ + function getExtraVars() { + return $this->keys; + } + } + + /** + * @class ExtraItem + * @author NHN (developers@xpressengine.com) + * @brief 확장변수의 개별 값 + **/ + class ExtraItem { + var $module_srl = 0; + var $idx = 0; + var $name = 0; + var $type = 'text'; + var $default = null; + var $desc = ''; + var $is_required = 'N'; + var $search = 'N'; + var $value = null; + var $eid = ''; + + /** + * @brief constructor + **/ + function ExtraItem($module_srl, $idx, $name, $type = 'text', $default = null, $desc = '', $is_required = 'N', $search = 'N', $value = null, $eid = '') { + if(!$idx) return; + $this->module_srl = $module_srl; + $this->idx = $idx; + $this->name = $name; + $this->type = $type; + $this->default = $default; + $this->desc = $desc; + $this->is_required = $is_required; + $this->search = $search; + $this->value = $value; + $this->eid = $eid; + } + + /** + * @brief 값 지정 + **/ + function setValue($value) { + $this->value = $value; + } + + /** + * @brief type에 따라서 주어진 값을 변형하여 원형 값을 return + **/ + function _getTypeValue($type, $value) { + $value = trim($value); + if(!isset($value)) return; + switch($type) { + case 'homepage' : + if($value && !preg_match('/^([a-z]+):\/\//i',$value)) $value = 'http://'.$value; + return htmlspecialchars($value); + break; + case 'tel' : + if(is_array($value)) $values = $value; + elseif(strpos($value,'|@|')!==false) $values = explode('|@|', $value); + elseif(strpos($value,',')!==false) $values = explode(',', $value); + $values[0] = $values[0]; + $values[1] = $values[1]; + $values[2] = $values[2]; + return $values; + break; + break; + case 'checkbox' : + case 'radio' : + case 'select' : + if(is_array($value)) $values = $value; + elseif(strpos($value,'|@|')!==false) $values = explode('|@|', $value); + elseif(strpos($value,',')!==false) $values = explode(',', $value); + else $values = array($value); + for($i=0;$i_getTypeValue($this->type, $this->value); + switch($this->type) { + case 'homepage' : + return ($value)?sprintf('%s', $value, $value):""; + case 'email_address' : + return ($value)?sprintf('%s', $value, $value):""; + break; + case 'tel' : + return sprintf('%s - %s - %s', $value[0],$value[1],$value[2]); + break; + case 'textarea' : + return nl2br($value); + break; + case 'checkbox' : + if(is_array($value)) return implode(', ',$value); + else return $value; + break; + case 'date' : + return zdate($value,"Y-m-d"); + break; + case 'select' : + case 'radio' : + if(is_array($value)) return implode(', ',$value); + else return $value; + break; + case 'kr_zip' : + if(is_array($value)) return implode(' ',$value); + else return $value; + break; + // case 'text' : + default : + return $value; + } + } + + /** + * @brief type에 따른 form을 리턴 + **/ + function getFormHTML() { + $type = $this->type; + $name = $this->name; + $value = $this->_getTypeValue($this->type, $this->value); + $default = $this->_getTypeValue($this->type, $this->default); + $column_name = 'extra_vars'.$this->idx; + + $buff = ''; + switch($type) { + // 홈페이지 주소 + case 'homepage' : + $buff .= ''; + break; + + // Email 주소 + case 'email_address' : + $buff .= ''; + break; + + // 전화번호 + case 'tel' : + $buff .= + ''. + ''. + ''; + break; + + // textarea + case 'textarea' : + $buff .= ''; + break; + + // 다중 선택 + case 'checkbox' : + $buff .= '
    '; + foreach($default as $v) { + if($value && in_array($v, $value)) $checked = ' checked="checked"'; + else $checked = ''; + $buff .='
  • '.$v.'
  • '; + } + $buff .= '
'; + break; + + // 단일 선택 + case 'select' : + $buff .= ''; + break; + + // radio + case 'radio' : + $buff .= '
    '; + foreach($default as $v) { + if($value && in_array($v,$value)) $checked = ' checked="checked"'; + else $checked = ''; + $buff .= '
  • '.$v.'
  • '; + } + $buff .= '
'; + break; + + // 날짜 입력 + case 'date' : + // datepicker javascript plugin load + Context::loadJavascriptPlugin('ui.datepicker'); + + $buff .= + ''. + ''."\n". + ''; + break; + + // 주소 입력 + case "kr_zip" : + // krzip address javascript plugin load + Context::loadJavascriptPlugin('ui.krzip'); + + $buff .= + ''. + + ''. + + ''. + + ''. + ''; + break; + + // 일반 text + default : + $buff .=' '; + break; + } + if($this->desc) $buff .= '

'.$this->desc.'

'; + return $buff; + } + } +?> diff --git a/classes/file/FileHandler.class.php b/classes/file/FileHandler.class.php index c3d2277b1..74c0ec6fe 100644 --- a/classes/file/FileHandler.class.php +++ b/classes/file/FileHandler.class.php @@ -1,658 +1,658 @@ -read()) { - if(substr($file,0,1)=='.') continue; - if($filter && preg_match($filter, $file)) continue; - if(is_dir($source_dir.$file)){ - FileHandler::copyDir($source_dir.$file,$target_dir.$file,$type); - }else{ - if($type == 'force'){ - @unlink($target_dir.$file); - }else{ - if(!file_exists($target_dir.$file)) @copy($source_dir.$file,$target_dir.$file); - } - } - } - } - - /** - * @brief copy a file to target - * @param[in] $source path of source file - * @param[in] $target path of target file - * @param[in] $force Y: overwrite - * @return none - **/ - function copyFile($source, $target, $force='Y'){ - setlocale(LC_CTYPE, 'en_US.UTF8', 'ko_KR.UTF8'); - $source = FileHandler::getRealPath($source); - $target_dir = FileHandler::getRealPath(dirname($target)); - $target = basename($target); - if(!file_exists($target_dir)) FileHandler::makeDir($target_dir); - if($force=='Y') @unlink($target_dir.'/'.$target); - @copy($source, $target_dir.'/'.$target); - } - - /** - * @brief returns the content of the file - * @param[in] $file_name path of target file - * @return the content of the file. if target file does not exist, this function returns nothing. - **/ - function readFile($file_name) { - $file_name = FileHandler::getRealPath($file_name); - - if(!file_exists($file_name)) return; - $filesize = filesize($file_name); - if($filesize<1) return; - - if(function_exists('file_get_contents')) return file_get_contents($file_name); - - $fp = fopen($file_name, "r"); - $buff = ''; - if($fp) { - while(!feof($fp) && strlen($buff)<=$filesize) { - $str = fgets($fp, 1024); - $buff .= $str; - } - fclose($fp); - } - return $buff; - } - - /** - * @brief write $buff into the specified file - * @param[in] $file_name path of target file - * @param[in] $buff content to be writeen - * @param[in] $mode a(append) / w(write) - * @return none - **/ - function writeFile($file_name, $buff, $mode = "w") { - $file_name = FileHandler::getRealPath($file_name); - - $pathinfo = pathinfo($file_name); - $path = $pathinfo['dirname']; - if(!is_dir($path)) FileHandler::makeDir($path); - - $mode = strtolower($mode); - if($mode != "a") $mode = "w"; - if(@!$fp = fopen($file_name,$mode)) return false; - fwrite($fp, $buff); - fclose($fp); - @chmod($file_name, 0644); - } - - /** - * @brief remove a file - * @param[in] $file_name path of target file - * @return none - **/ - function removeFile($file_name) { - $file_name = FileHandler::getRealPath($file_name); - if(file_exists($file_name)) @unlink($file_name); - } - - /** - * @brief rename a file - * @param[in] $source path of source file - * @param[in] $target path of target file - * @remarks In order to move a file, use this function. - * @return none - **/ - function rename($source, $target) { - $source = FileHandler::getRealPath($source); - $target = FileHandler::getRealPath($target); - @rename($source, $target); - } - - /** - * @brief move a directory - * @param[in] $source_dir path of source directory - * @param[in] $target_dir path of target directory - * @remarks this function just wraps rename function. - * @return none - **/ - function moveDir($source_dir, $target_dir) { - FileHandler::rename($source_dir, $target_dir); - } - - /** - * @brief return list of the files in the path - * @param[in] $path path of target directory - * @param[in] $filter if specified, return only files matching with the filter - * @param[in] $to_lower if true, file names will be changed into lower case. - * @param[in] $concat_prefix if true, return file name as absolute path - * @remarks the array does not contain files, such as '.', '..', and files starting with '.' - * @return array of the filenames in the path - **/ - function readDir($path, $filter = '', $to_lower = false, $concat_prefix = false) { - $path = FileHandler::getRealPath($path); - - if(substr($path,-1)!='/') $path .= '/'; - if(!is_dir($path)) return array(); - - $oDir = dir($path); - while($file = $oDir->read()) { - if(substr($file,0,1)=='.') continue; - - if($filter && !preg_match($filter, $file)) continue; - - if($to_lower) $file = strtolower($file); - - if($filter) $file = preg_replace($filter, '$1', $file); - else $file = $file; - - if($concat_prefix) { - $file = sprintf('%s%s', str_replace(_XE_PATH_, '', $path), $file); - } - - $output[] = $file; - } - if(!$output) return array(); - - return $output; - } - - /** - * @brief creates a directory - * @param[in] $path_string path of target directory - * @return true if success. it might return nothing when ftp is used and connection to the ftp address failed. - * @remarks This function creates directories recursively, which means that if ancestors of the target directory does not exist, they will be created too. - **/ - function makeDir($path_string) { - static $oFtp = null; - - // if safe_mode is on, use FTP - if(ini_get('safe_mode')) { - $ftp_info = Context::getFTPInfo(); - if($oFtp == null) { - if(!Context::isFTPRegisted()) return; - - require_once(_XE_PATH_.'libs/ftp.class.php'); - $oFtp = new ftp(); - if(!$ftp_info->ftp_host) $ftp_info->ftp_host = "127.0.0.1"; - if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21; - if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return; - if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) { - $oFtp->ftp_quit(); - return; - } - } - $ftp_path = $ftp_info->ftp_root_path; - if(!$ftp_path) $ftp_path = "/"; - } - - $path_string = str_replace(_XE_PATH_,'',$path_string); - $path_list = explode('/', $path_string); - - $path = _XE_PATH_; - for($i=0;$iftp_mkdir($ftp_path); - $oFtp->ftp_site("CHMOD 777 ".$ftp_path); - } else { - @mkdir($path, 0755); - @chmod($path, 0755); - } - } - } - - return is_dir($path_string); - } - - /** - * @brief remove all files under the path - * @param[in] $path path of the target directory - * @return none - **/ - function removeDir($path) { - $path = FileHandler::getRealPath($path); - if(!is_dir($path)) return; - $directory = dir($path); - while($entry = $directory->read()) { - if ($entry != "." && $entry != "..") { - if (is_dir($path."/".$entry)) { - FileHandler::removeDir($path."/".$entry); - } else { - @unlink($path."/".$entry); - } - } - } - $directory->close(); - @rmdir($path); - } - - /** - * @brief remove a directory only if it is empty - * @param[in] $path path of the target directory - * @return none - **/ - function removeBlankDir($path) { - $item_cnt = 0; - - $path = FileHandler::getRealPath($path); - if(!is_dir($path)) return; - $directory = dir($path); - while($entry = $directory->read()) { - if ($entry == "." || $entry == "..") continue; - if (is_dir($path."/".$entry)) $item_cnt = FileHandler::removeBlankDir($path.'/'.$entry); - } - $directory->close(); - - if($item_cnt < 1) @rmdir($path); - } - - - /** - * @biref remove files in the target directory. - * @param[in] $path path of the target directory - * @remarks This function keeps the directory structure. - * @return none - **/ - function removeFilesInDir($path) { - $path = FileHandler::getRealPath($path); - if(!is_dir($path)) return; - $directory = dir($path); - while($entry = $directory->read()) { - if ($entry != "." && $entry != "..") { - if (is_dir($path."/".$entry)) { - FileHandler::removeFilesInDir($path."/".$entry); - } else { - @unlink($path."/".$entry); - } - } - } - $directory->close(); - } - - /** - * @brief makes file size byte into KB, MB according to the size - * @param[in] $size number of the size - * @return file size string - **/ - function filesize($size) { - if(!$size) return "0Byte"; - if($size < 1024) return ($size."Byte"); - if($size >= 1024 && $size < 1024*1024) return sprintf("%0.1fKB",$size / 1024); - return sprintf("%0.2fMB",$size / (1024*1024)); - } - - /** - * @brief return remote file's content via HTTP - * @param[in] $url the address of the target file - * @param[in] $body HTTP request body - * @param[in] $timeout connection timeout - * @param[in] $method GET/POST - * @param[in] $content_type content type header of HTTP request - * @param[in] $headers headers key vaule array. - * @param[in] $cookies cookies key value array. - * @param[in] $post_data request arguments array for POST method - * @return if success, the content of the target file. otherwise: none - * @remarks if the target is moved (when return code is 300~399), this function follows the location specified response header. - **/ - function getRemoteResource($url, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array(), $cookies = array(), $post_data = array()) { - requirePear(); - require_once('HTTP/Request.php'); - - $parsed_url = parse_url(__PROXY_SERVER__); - if($parsed_url["host"]) { - $oRequest = new HTTP_Request(__PROXY_SERVER__); - $oRequest->setMethod('POST'); - $oRequest->_timeout = $timeout; - $oRequest->addPostData('arg', serialize(array('Destination'=>$url, 'method'=>$method, 'body'=>$body, 'content_type'=>$content_type, "headers"=>$headers, "post_data"=>$post_data))); - } else { - $oRequest = new HTTP_Request($url); - if(count($headers)) { - foreach($headers as $key => $val) { - $oRequest->addHeader($key, $val); - } - } - if($cookies[$host]) { - foreach($cookies[$host] as $key => $val) { - $oRequest->addCookie($key, $val); - } - } - if(count($post_data)) { - foreach($post_data as $key => $val) { - $oRequest->addPostData($key, $val); - } - } - if(!$content_type) $oRequest->addHeader('Content-Type', 'text/html'); - else $oRequest->addHeader('Content-Type', $content_type); - $oRequest->setMethod($method); - if($body) $oRequest->setBody($body); - - $oRequest->_timeout = $timeout; - } - - $oResponse = $oRequest->sendRequest(); - - $code = $oRequest->getResponseCode(); - $header = $oRequest->getResponseHeader(); - $response = $oRequest->getResponseBody(); - if($c = $oRequest->getResponseCookies()) { - foreach($c as $k => $v) { - $cookies[$host][$v['name']] = $v['value']; - } - } - - if($code > 300 && $code < 399 && $header['location']) { - return FileHandler::getRemoteResource($header['location'], $body, $timeout, $method, $content_type, $headers, $cookies, $post_data); - } - - if($code != 200) return; - - return $response; - } - - /** - * @brief retrieves remote file, then stores it into target path. - * @param[in] $url the address of the target file - * @param[in] $target_file the location to store - * @param[in] $body HTTP request body - * @param[in] $timeout connection timeout - * @param[in] $method GET/POST - * @param[in] $content_type content type header of HTTP request - * @param[in] $headers headers key vaule array. - * @return true: success, false: failed - **/ - function getRemoteFile($url, $target_filename, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array()) { - $body = FileHandler::getRemoteResource($url, $body, $timeout, $method, $content_type, $headers); - if(!$body) return false; - $target_filename = FileHandler::getRealPath($target_filename); - FileHandler::writeFile($target_filename, $body); - return true; - } - - /** - * @brief convert size in string into numeric value - * @param[in] $val size in string (ex., 10, 10K, 10M, 10G ) - * @return converted size - */ - function returnBytes($val) - { - $val = trim($val); - $last = strtolower(substr($val, -1)); - if($last == 'g') $val *= 1024*1024*1024; - else if($last == 'm') $val *= 1024*1024; - else if($last == 'k') $val *= 1024; - - return $val; - } - - /** - * @brief check available memory to load image file - * @param[in] $imageInfo image info retrieved by getimagesize function - * @return true: it's ok, false: otherwise - */ - function checkMemoryLoadImage(&$imageInfo) - { - if(!function_exists('memory_get_usage')) return true; - $K64 = 65536; - $TWEAKFACTOR = 1.5; - $channels = $imageInfo['channels']; - if(!$channels) $channels = 6; //for png - $memoryNeeded = round( ($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $channels / 8 + $K64 ) * $TWEAKFACTOR ); - $availableMemory = FileHandler::returnBytes(ini_get('memory_limit')) - memory_get_usage(); - if($availableMemory < $memoryNeeded) return false; - return true; - } - - /** - * @brief moves an image file (resizing is possible) - * @param[in] $source_file path of the source file - * @param[in] $target_file path of the target file - * @param[in] $resize_width width to resize - * @param[in] $resize_height height to resize - * @param[in] $target_type if $target_type is set (gif, jpg, png, bmp), result image will be saved as target type - * @param[in] $thumbnail_type thumbnail type(crop, ratio) - * @return true: success, false: failed - **/ - function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop') { - $source_file = FileHandler::getRealPath($source_file); - $target_file = FileHandler::getRealPath($target_file); - - if(!file_exists($source_file)) return; - if(!$resize_width) $resize_width = 100; - if(!$resize_height) $resize_height = $resize_width; - - // retrieve source image's information - $imageInfo = getimagesize($source_file); - if(!FileHandler::checkMemoryLoadImage($imageInfo)) return false; - list($width, $height, $type, $attrs) = $imageInfo; - - if($width<1 || $height<1) return; - - switch($type) { - case '1' : - $type = 'gif'; - break; - case '2' : - $type = 'jpg'; - break; - case '3' : - $type = 'png'; - break; - case '6' : - $type = 'bmp'; - break; - default : - return; - break; - } - - // if original image is larger than specified size to resize, calculate the ratio - if($resize_width > 0 && $width >= $resize_width) $width_per = $resize_width / $width; - else $width_per = 1; - - if($resize_height>0 && $height >= $resize_height) $height_per = $resize_height / $height; - else $height_per = 1; - - if($thumbnail_type == 'ratio') { - if($width_per>$height_per) $per = $height_per; - else $per = $width_per; - $resize_width = $width * $per; - $resize_height = $height * $per; - } else { - if($width_per < $height_per) $per = $height_per; - else $per = $width_per; - } - - if(!$per) $per = 1; - - // get type of target file - if(!$target_type) $target_type = $type; - $target_type = strtolower($target_type); - - // create temporary image with target size - if(function_exists('imagecreatetruecolor')) $thumb = imagecreatetruecolor($resize_width, $resize_height); - else if(function_exists('imagecreate')) $thumb = imagecreate($resize_width, $resize_height); - else return false; - if(!$thumb) return false; - - $white = imagecolorallocate($thumb, 255,255,255); - imagefilledrectangle($thumb,0,0,$resize_width-1,$resize_height-1,$white); - - // create temporary image having original type - switch($type) { - case 'gif' : - if(!function_exists('imagecreatefromgif')) return false; - $source = imagecreatefromgif($source_file); - break; - // jpg - case 'jpeg' : - case 'jpg' : - if(!function_exists('imagecreatefromjpeg')) return false; - $source = imagecreatefromjpeg($source_file); - break; - // png - case 'png' : - if(!function_exists('imagecreatefrompng')) return false; - $source = imagecreatefrompng($source_file); - break; - // bmp - case 'wbmp' : - case 'bmp' : - if(!function_exists('imagecreatefromwbmp')) return false; - $source = imagecreatefromwbmp($source_file); - break; - default : - return; - } - - // resize original image and put it into temporary image - $new_width = (int)($width * $per); - $new_height = (int)($height * $per); - - if($thumbnail_type == 'crop') { - $x = (int)($resize_width/2 - $new_width/2); - $y = (int)($resize_height/2 - $new_height/2); - } else { - $x = 0; - $y = 0; - } - - if($source) { - if(function_exists('imagecopyresampled')) imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); - else imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); - } else return false; - - // create directory - $path = dirname($target_file); - if(!is_dir($path)) FileHandler::makeDir($path); - - // write into the file - switch($target_type) { - case 'gif' : - if(!function_exists('imagegif')) return false; - $output = imagegif($thumb, $target_file); - break; - case 'jpeg' : - case 'jpg' : - if(!function_exists('imagejpeg')) return false; - $output = imagejpeg($thumb, $target_file, 100); - break; - case 'png' : - if(!function_exists('imagepng')) return false; - $output = imagepng($thumb, $target_file, 9); - break; - case 'wbmp' : - case 'bmp' : - if(!function_exists('imagewbmp')) return false; - $output = imagewbmp($thumb, $target_file, 100); - break; - } - - imagedestroy($thumb); - imagedestroy($source); - - if(!$output) return false; - @chmod($target_file, 0644); - - return true; - } - - - /** - * @brief reads ini file, and puts result into array - * @param[in] $filename path of the ini file - * @return ini array (if the target file does not exist, it returns false) - **/ - function readIniFile($filename){ - $filename = FileHandler::getRealPath($filename); - if(!file_exists($filename)) return false; - $arr = parse_ini_file($filename, true); - if(is_array($arr) && count($arr)>0) return $arr; - else return array(); - } - - - /** - * @brief write array into ini file - * @param[in] $filename target ini file name - * @param[in] $arr array - * @return if array contains nothing it returns false, otherwise true - **/ - function writeIniFile($filename, $arr){ - if(count($arr)==0) return false; - FileHandler::writeFile($filename, FileHandler::_makeIniBuff($arr)); - return true; - } - - function _makeIniBuff($arr){ - $return = ''; - foreach($arr as $key => $val){ - // section - if(is_array($val)){ - $return .= sprintf("[%s]\n",$key); - foreach($val as $k => $v){ - $return .= sprintf("%s=\"%s\"\n",$k,$v); - } - // value - }else if(is_string($val) || is_int($val)){ - $return .= sprintf("%s=\"%s\"\n",$key,$val); - } - } - return $return; - } - - /** - * @brief return file object - * @param[in] $file_name target file name - * @param[in] $mode file mode for fopen - * @remarks if the directory of the file does not exist, create it. - * @return file object - **/ - function openFile($file_name, $mode) - { - $pathinfo = pathinfo($file_name); - $path = $pathinfo['dirname']; - if(!is_dir($path)) FileHandler::makeDir($path); - - require_once("FileObject.class.php"); - $file_object = new FileObject($file_name, $mode); - return $file_object; - } - } -?> +read()) { + if(substr($file,0,1)=='.') continue; + if($filter && preg_match($filter, $file)) continue; + if(is_dir($source_dir.$file)){ + FileHandler::copyDir($source_dir.$file,$target_dir.$file,$type); + }else{ + if($type == 'force'){ + @unlink($target_dir.$file); + }else{ + if(!file_exists($target_dir.$file)) @copy($source_dir.$file,$target_dir.$file); + } + } + } + } + + /** + * @brief copy a file to target + * @param[in] $source path of source file + * @param[in] $target path of target file + * @param[in] $force Y: overwrite + * @return none + **/ + function copyFile($source, $target, $force='Y'){ + setlocale(LC_CTYPE, 'en_US.UTF8', 'ko_KR.UTF8'); + $source = FileHandler::getRealPath($source); + $target_dir = FileHandler::getRealPath(dirname($target)); + $target = basename($target); + if(!file_exists($target_dir)) FileHandler::makeDir($target_dir); + if($force=='Y') @unlink($target_dir.'/'.$target); + @copy($source, $target_dir.'/'.$target); + } + + /** + * @brief returns the content of the file + * @param[in] $file_name path of target file + * @return the content of the file. if target file does not exist, this function returns nothing. + **/ + function readFile($file_name) { + $file_name = FileHandler::getRealPath($file_name); + + if(!file_exists($file_name)) return; + $filesize = filesize($file_name); + if($filesize<1) return; + + if(function_exists('file_get_contents')) return file_get_contents($file_name); + + $fp = fopen($file_name, "r"); + $buff = ''; + if($fp) { + while(!feof($fp) && strlen($buff)<=$filesize) { + $str = fgets($fp, 1024); + $buff .= $str; + } + fclose($fp); + } + return $buff; + } + + /** + * @brief write $buff into the specified file + * @param[in] $file_name path of target file + * @param[in] $buff content to be writeen + * @param[in] $mode a(append) / w(write) + * @return none + **/ + function writeFile($file_name, $buff, $mode = "w") { + $file_name = FileHandler::getRealPath($file_name); + + $pathinfo = pathinfo($file_name); + $path = $pathinfo['dirname']; + if(!is_dir($path)) FileHandler::makeDir($path); + + $mode = strtolower($mode); + if($mode != "a") $mode = "w"; + if(@!$fp = fopen($file_name,$mode)) return false; + fwrite($fp, $buff); + fclose($fp); + @chmod($file_name, 0644); + } + + /** + * @brief remove a file + * @param[in] $file_name path of target file + * @return none + **/ + function removeFile($file_name) { + $file_name = FileHandler::getRealPath($file_name); + if(file_exists($file_name)) @unlink($file_name); + } + + /** + * @brief rename a file + * @param[in] $source path of source file + * @param[in] $target path of target file + * @remarks In order to move a file, use this function. + * @return none + **/ + function rename($source, $target) { + $source = FileHandler::getRealPath($source); + $target = FileHandler::getRealPath($target); + @rename($source, $target); + } + + /** + * @brief move a directory + * @param[in] $source_dir path of source directory + * @param[in] $target_dir path of target directory + * @remarks this function just wraps rename function. + * @return none + **/ + function moveDir($source_dir, $target_dir) { + FileHandler::rename($source_dir, $target_dir); + } + + /** + * @brief return list of the files in the path + * @param[in] $path path of target directory + * @param[in] $filter if specified, return only files matching with the filter + * @param[in] $to_lower if true, file names will be changed into lower case. + * @param[in] $concat_prefix if true, return file name as absolute path + * @remarks the array does not contain files, such as '.', '..', and files starting with '.' + * @return array of the filenames in the path + **/ + function readDir($path, $filter = '', $to_lower = false, $concat_prefix = false) { + $path = FileHandler::getRealPath($path); + + if(substr($path,-1)!='/') $path .= '/'; + if(!is_dir($path)) return array(); + + $oDir = dir($path); + while($file = $oDir->read()) { + if(substr($file,0,1)=='.') continue; + + if($filter && !preg_match($filter, $file)) continue; + + if($to_lower) $file = strtolower($file); + + if($filter) $file = preg_replace($filter, '$1', $file); + else $file = $file; + + if($concat_prefix) { + $file = sprintf('%s%s', str_replace(_XE_PATH_, '', $path), $file); + } + + $output[] = $file; + } + if(!$output) return array(); + + return $output; + } + + /** + * @brief creates a directory + * @param[in] $path_string path of target directory + * @return true if success. it might return nothing when ftp is used and connection to the ftp address failed. + * @remarks This function creates directories recursively, which means that if ancestors of the target directory does not exist, they will be created too. + **/ + function makeDir($path_string) { + static $oFtp = null; + + // if safe_mode is on, use FTP + if(ini_get('safe_mode')) { + $ftp_info = Context::getFTPInfo(); + if($oFtp == null) { + if(!Context::isFTPRegisted()) return; + + require_once(_XE_PATH_.'libs/ftp.class.php'); + $oFtp = new ftp(); + if(!$ftp_info->ftp_host) $ftp_info->ftp_host = "127.0.0.1"; + if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21; + if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return; + if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) { + $oFtp->ftp_quit(); + return; + } + } + $ftp_path = $ftp_info->ftp_root_path; + if(!$ftp_path) $ftp_path = "/"; + } + + $path_string = str_replace(_XE_PATH_,'',$path_string); + $path_list = explode('/', $path_string); + + $path = _XE_PATH_; + for($i=0;$iftp_mkdir($ftp_path); + $oFtp->ftp_site("CHMOD 777 ".$ftp_path); + } else { + @mkdir($path, 0755); + @chmod($path, 0755); + } + } + } + + return is_dir($path_string); + } + + /** + * @brief remove all files under the path + * @param[in] $path path of the target directory + * @return none + **/ + function removeDir($path) { + $path = FileHandler::getRealPath($path); + if(!is_dir($path)) return; + $directory = dir($path); + while($entry = $directory->read()) { + if ($entry != "." && $entry != "..") { + if (is_dir($path."/".$entry)) { + FileHandler::removeDir($path."/".$entry); + } else { + @unlink($path."/".$entry); + } + } + } + $directory->close(); + @rmdir($path); + } + + /** + * @brief remove a directory only if it is empty + * @param[in] $path path of the target directory + * @return none + **/ + function removeBlankDir($path) { + $item_cnt = 0; + + $path = FileHandler::getRealPath($path); + if(!is_dir($path)) return; + $directory = dir($path); + while($entry = $directory->read()) { + if ($entry == "." || $entry == "..") continue; + if (is_dir($path."/".$entry)) $item_cnt = FileHandler::removeBlankDir($path.'/'.$entry); + } + $directory->close(); + + if($item_cnt < 1) @rmdir($path); + } + + + /** + * @biref remove files in the target directory. + * @param[in] $path path of the target directory + * @remarks This function keeps the directory structure. + * @return none + **/ + function removeFilesInDir($path) { + $path = FileHandler::getRealPath($path); + if(!is_dir($path)) return; + $directory = dir($path); + while($entry = $directory->read()) { + if ($entry != "." && $entry != "..") { + if (is_dir($path."/".$entry)) { + FileHandler::removeFilesInDir($path."/".$entry); + } else { + @unlink($path."/".$entry); + } + } + } + $directory->close(); + } + + /** + * @brief makes file size byte into KB, MB according to the size + * @param[in] $size number of the size + * @return file size string + **/ + function filesize($size) { + if(!$size) return "0Byte"; + if($size < 1024) return ($size."Byte"); + if($size >= 1024 && $size < 1024*1024) return sprintf("%0.1fKB",$size / 1024); + return sprintf("%0.2fMB",$size / (1024*1024)); + } + + /** + * @brief return remote file's content via HTTP + * @param[in] $url the address of the target file + * @param[in] $body HTTP request body + * @param[in] $timeout connection timeout + * @param[in] $method GET/POST + * @param[in] $content_type content type header of HTTP request + * @param[in] $headers headers key vaule array. + * @param[in] $cookies cookies key value array. + * @param[in] $post_data request arguments array for POST method + * @return if success, the content of the target file. otherwise: none + * @remarks if the target is moved (when return code is 300~399), this function follows the location specified response header. + **/ + function getRemoteResource($url, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array(), $cookies = array(), $post_data = array()) { + requirePear(); + require_once('HTTP/Request.php'); + + $parsed_url = parse_url(__PROXY_SERVER__); + if($parsed_url["host"]) { + $oRequest = new HTTP_Request(__PROXY_SERVER__); + $oRequest->setMethod('POST'); + $oRequest->_timeout = $timeout; + $oRequest->addPostData('arg', serialize(array('Destination'=>$url, 'method'=>$method, 'body'=>$body, 'content_type'=>$content_type, "headers"=>$headers, "post_data"=>$post_data))); + } else { + $oRequest = new HTTP_Request($url); + if(count($headers)) { + foreach($headers as $key => $val) { + $oRequest->addHeader($key, $val); + } + } + if($cookies[$host]) { + foreach($cookies[$host] as $key => $val) { + $oRequest->addCookie($key, $val); + } + } + if(count($post_data)) { + foreach($post_data as $key => $val) { + $oRequest->addPostData($key, $val); + } + } + if(!$content_type) $oRequest->addHeader('Content-Type', 'text/html'); + else $oRequest->addHeader('Content-Type', $content_type); + $oRequest->setMethod($method); + if($body) $oRequest->setBody($body); + + $oRequest->_timeout = $timeout; + } + + $oResponse = $oRequest->sendRequest(); + + $code = $oRequest->getResponseCode(); + $header = $oRequest->getResponseHeader(); + $response = $oRequest->getResponseBody(); + if($c = $oRequest->getResponseCookies()) { + foreach($c as $k => $v) { + $cookies[$host][$v['name']] = $v['value']; + } + } + + if($code > 300 && $code < 399 && $header['location']) { + return FileHandler::getRemoteResource($header['location'], $body, $timeout, $method, $content_type, $headers, $cookies, $post_data); + } + + if($code != 200) return; + + return $response; + } + + /** + * @brief retrieves remote file, then stores it into target path. + * @param[in] $url the address of the target file + * @param[in] $target_file the location to store + * @param[in] $body HTTP request body + * @param[in] $timeout connection timeout + * @param[in] $method GET/POST + * @param[in] $content_type content type header of HTTP request + * @param[in] $headers headers key vaule array. + * @return true: success, false: failed + **/ + function getRemoteFile($url, $target_filename, $body = null, $timeout = 3, $method = 'GET', $content_type = null, $headers = array()) { + $body = FileHandler::getRemoteResource($url, $body, $timeout, $method, $content_type, $headers); + if(!$body) return false; + $target_filename = FileHandler::getRealPath($target_filename); + FileHandler::writeFile($target_filename, $body); + return true; + } + + /** + * @brief convert size in string into numeric value + * @param[in] $val size in string (ex., 10, 10K, 10M, 10G ) + * @return converted size + */ + function returnBytes($val) + { + $val = trim($val); + $last = strtolower(substr($val, -1)); + if($last == 'g') $val *= 1024*1024*1024; + else if($last == 'm') $val *= 1024*1024; + else if($last == 'k') $val *= 1024; + + return $val; + } + + /** + * @brief check available memory to load image file + * @param[in] $imageInfo image info retrieved by getimagesize function + * @return true: it's ok, false: otherwise + */ + function checkMemoryLoadImage(&$imageInfo) + { + if(!function_exists('memory_get_usage')) return true; + $K64 = 65536; + $TWEAKFACTOR = 1.5; + $channels = $imageInfo['channels']; + if(!$channels) $channels = 6; //for png + $memoryNeeded = round( ($imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $channels / 8 + $K64 ) * $TWEAKFACTOR ); + $availableMemory = FileHandler::returnBytes(ini_get('memory_limit')) - memory_get_usage(); + if($availableMemory < $memoryNeeded) return false; + return true; + } + + /** + * @brief moves an image file (resizing is possible) + * @param[in] $source_file path of the source file + * @param[in] $target_file path of the target file + * @param[in] $resize_width width to resize + * @param[in] $resize_height height to resize + * @param[in] $target_type if $target_type is set (gif, jpg, png, bmp), result image will be saved as target type + * @param[in] $thumbnail_type thumbnail type(crop, ratio) + * @return true: success, false: failed + **/ + function createImageFile($source_file, $target_file, $resize_width = 0, $resize_height = 0, $target_type = '', $thumbnail_type = 'crop') { + $source_file = FileHandler::getRealPath($source_file); + $target_file = FileHandler::getRealPath($target_file); + + if(!file_exists($source_file)) return; + if(!$resize_width) $resize_width = 100; + if(!$resize_height) $resize_height = $resize_width; + + // retrieve source image's information + $imageInfo = getimagesize($source_file); + if(!FileHandler::checkMemoryLoadImage($imageInfo)) return false; + list($width, $height, $type, $attrs) = $imageInfo; + + if($width<1 || $height<1) return; + + switch($type) { + case '1' : + $type = 'gif'; + break; + case '2' : + $type = 'jpg'; + break; + case '3' : + $type = 'png'; + break; + case '6' : + $type = 'bmp'; + break; + default : + return; + break; + } + + // if original image is larger than specified size to resize, calculate the ratio + if($resize_width > 0 && $width >= $resize_width) $width_per = $resize_width / $width; + else $width_per = 1; + + if($resize_height>0 && $height >= $resize_height) $height_per = $resize_height / $height; + else $height_per = 1; + + if($thumbnail_type == 'ratio') { + if($width_per>$height_per) $per = $height_per; + else $per = $width_per; + $resize_width = $width * $per; + $resize_height = $height * $per; + } else { + if($width_per < $height_per) $per = $height_per; + else $per = $width_per; + } + + if(!$per) $per = 1; + + // get type of target file + if(!$target_type) $target_type = $type; + $target_type = strtolower($target_type); + + // create temporary image with target size + if(function_exists('imagecreatetruecolor')) $thumb = imagecreatetruecolor($resize_width, $resize_height); + else if(function_exists('imagecreate')) $thumb = imagecreate($resize_width, $resize_height); + else return false; + if(!$thumb) return false; + + $white = imagecolorallocate($thumb, 255,255,255); + imagefilledrectangle($thumb,0,0,$resize_width-1,$resize_height-1,$white); + + // create temporary image having original type + switch($type) { + case 'gif' : + if(!function_exists('imagecreatefromgif')) return false; + $source = imagecreatefromgif($source_file); + break; + // jpg + case 'jpeg' : + case 'jpg' : + if(!function_exists('imagecreatefromjpeg')) return false; + $source = imagecreatefromjpeg($source_file); + break; + // png + case 'png' : + if(!function_exists('imagecreatefrompng')) return false; + $source = imagecreatefrompng($source_file); + break; + // bmp + case 'wbmp' : + case 'bmp' : + if(!function_exists('imagecreatefromwbmp')) return false; + $source = imagecreatefromwbmp($source_file); + break; + default : + return; + } + + // resize original image and put it into temporary image + $new_width = (int)($width * $per); + $new_height = (int)($height * $per); + + if($thumbnail_type == 'crop') { + $x = (int)($resize_width/2 - $new_width/2); + $y = (int)($resize_height/2 - $new_height/2); + } else { + $x = 0; + $y = 0; + } + + if($source) { + if(function_exists('imagecopyresampled')) imagecopyresampled($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); + else imagecopyresized($thumb, $source, $x, $y, 0, 0, $new_width, $new_height, $width, $height); + } else return false; + + // create directory + $path = dirname($target_file); + if(!is_dir($path)) FileHandler::makeDir($path); + + // write into the file + switch($target_type) { + case 'gif' : + if(!function_exists('imagegif')) return false; + $output = imagegif($thumb, $target_file); + break; + case 'jpeg' : + case 'jpg' : + if(!function_exists('imagejpeg')) return false; + $output = imagejpeg($thumb, $target_file, 100); + break; + case 'png' : + if(!function_exists('imagepng')) return false; + $output = imagepng($thumb, $target_file, 9); + break; + case 'wbmp' : + case 'bmp' : + if(!function_exists('imagewbmp')) return false; + $output = imagewbmp($thumb, $target_file, 100); + break; + } + + imagedestroy($thumb); + imagedestroy($source); + + if(!$output) return false; + @chmod($target_file, 0644); + + return true; + } + + + /** + * @brief reads ini file, and puts result into array + * @param[in] $filename path of the ini file + * @return ini array (if the target file does not exist, it returns false) + **/ + function readIniFile($filename){ + $filename = FileHandler::getRealPath($filename); + if(!file_exists($filename)) return false; + $arr = parse_ini_file($filename, true); + if(is_array($arr) && count($arr)>0) return $arr; + else return array(); + } + + + /** + * @brief write array into ini file + * @param[in] $filename target ini file name + * @param[in] $arr array + * @return if array contains nothing it returns false, otherwise true + **/ + function writeIniFile($filename, $arr){ + if(count($arr)==0) return false; + FileHandler::writeFile($filename, FileHandler::_makeIniBuff($arr)); + return true; + } + + function _makeIniBuff($arr){ + $return = ''; + foreach($arr as $key => $val){ + // section + if(is_array($val)){ + $return .= sprintf("[%s]\n",$key); + foreach($val as $k => $v){ + $return .= sprintf("%s=\"%s\"\n",$k,$v); + } + // value + }else if(is_string($val) || is_int($val)){ + $return .= sprintf("%s=\"%s\"\n",$key,$val); + } + } + return $return; + } + + /** + * @brief return file object + * @param[in] $file_name target file name + * @param[in] $mode file mode for fopen + * @remarks if the directory of the file does not exist, create it. + * @return file object + **/ + function openFile($file_name, $mode) + { + $pathinfo = pathinfo($file_name); + $path = $pathinfo['dirname']; + if(!is_dir($path)) FileHandler::makeDir($path); + + require_once("FileObject.class.php"); + $file_object = new FileObject($file_name, $mode); + return $file_object; + } + } +?> diff --git a/classes/file/FileObject.class.php b/classes/file/FileObject.class.php index a35c90bbe..cbe1ae2b0 100644 --- a/classes/file/FileObject.class.php +++ b/classes/file/FileObject.class.php @@ -1,128 +1,128 @@ -Open($path, $mode); - } - - /** - * @brief append target file's content to current file - * @param[in] $file_name path of target file - * @return none - **/ - function append($file_name) - { - $target = new FileObject($file_name, "r"); - while(!$target->feof()) - { - $readstr = $target->read(); - $this->write($readstr); - } - $target->close(); - } - - /** - * @brief check current file meets eof - * @return true: if eof. false: otherwise - **/ - function feof() - { - return feof($this->fp); - } - - /** - * @brief read from current file - * @param[in] $size size to read - * @return read bytes - **/ - function read($size = 1024) - { - return fread($this->fp, $size); - } - - - /** - * @brief write string to current file - * @param[in] $str string to write - * @return written bytes. if failed, it returns false - **/ - function write($str) - { - $len = strlen($str); - if(!$str || $len <= 0) return false; - if(!$this->fp) return false; - $written = fwrite($this->fp, $str); - return $written; - } - - /** - * @brief open a file - * @param[in] $path path of target file - * @param[in] $mode file open mode - * @remarks if file is opened, close it and open the new path - * @return true if succeed, false otherwise. - */ - function open($path, $mode) - { - if($this->fp != null) - { - $this->close(); - } - $this->fp = fopen($path, $mode); - if(! is_resource($this->fp) ) - { - $this->fp = null; - return false; - } - $this->path = $path; - return true; - } - - /** - * @brief return current file's path - * @return file path - **/ - function getPath() - { - if($this->fp != null) - { - return $this->path; - } - else - { - return null; - } - } - - /** - * @brief close file - * @return none - **/ - function close() - { - if($this->fp != null) - { - fclose($this->fp); - $this->fp = null; - } - } - - } -?> +Open($path, $mode); + } + + /** + * @brief append target file's content to current file + * @param[in] $file_name path of target file + * @return none + **/ + function append($file_name) + { + $target = new FileObject($file_name, "r"); + while(!$target->feof()) + { + $readstr = $target->read(); + $this->write($readstr); + } + $target->close(); + } + + /** + * @brief check current file meets eof + * @return true: if eof. false: otherwise + **/ + function feof() + { + return feof($this->fp); + } + + /** + * @brief read from current file + * @param[in] $size size to read + * @return read bytes + **/ + function read($size = 1024) + { + return fread($this->fp, $size); + } + + + /** + * @brief write string to current file + * @param[in] $str string to write + * @return written bytes. if failed, it returns false + **/ + function write($str) + { + $len = strlen($str); + if(!$str || $len <= 0) return false; + if(!$this->fp) return false; + $written = fwrite($this->fp, $str); + return $written; + } + + /** + * @brief open a file + * @param[in] $path path of target file + * @param[in] $mode file open mode + * @remarks if file is opened, close it and open the new path + * @return true if succeed, false otherwise. + */ + function open($path, $mode) + { + if($this->fp != null) + { + $this->close(); + } + $this->fp = fopen($path, $mode); + if(! is_resource($this->fp) ) + { + $this->fp = null; + return false; + } + $this->path = $path; + return true; + } + + /** + * @brief return current file's path + * @return file path + **/ + function getPath() + { + if($this->fp != null) + { + return $this->path; + } + else + { + return null; + } + } + + /** + * @brief close file + * @return none + **/ + function close() + { + if($this->fp != null) + { + fclose($this->fp); + $this->fp = null; + } + } + + } +?> diff --git a/classes/handler/Handler.class.php b/classes/handler/Handler.class.php index 6c74b760a..375dfe281 100644 --- a/classes/handler/Handler.class.php +++ b/classes/handler/Handler.class.php @@ -1,11 +1,11 @@ - + diff --git a/classes/httprequest/XEHttpRequest.class.php b/classes/httprequest/XEHttpRequest.class.php index 13b27fc68..cf09444ff 100644 --- a/classes/httprequest/XEHttpRequest.class.php +++ b/classes/httprequest/XEHttpRequest.class.php @@ -1,85 +1,85 @@ -m_host = $host; - $this->m_port = $port; - $this->m_headers = array(); - } - - /** - * @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) - { - $this->m_headers[$key] = $value; - } - - /** - * @brief send HTTP message to the host - * @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) - { - $socket = @fsockopen($this->m_host, $this->m_port, $errno, $errstr, $timeout); - if(!$socket) - { - return new Object(-1, "socket_connect_failed"); - } - - $this->AddToHeader('Host', $this->m_host); - $this->AddToHeader('Connection', "close"); - - $crlf = "\r\n"; - $request = "$method $target HTTP/1.1$crlf"; - - foreach($this->m_headers as $equiv => $content) - { - $request .= "$equiv: $content$crlf"; - } - $request .= $crlf; - fwrite($socket, $request); - - list($httpver, $code, $status) = split(' +', rtrim(fgets($socket))); - // read response header - while(strlen(trim($line = fgets($socket)))) - { - list($equiv, $content) = split(' *: *', rtrim($line)); - } - $body = ''; - while(!feof($socket)) - { - $body .= fgets($socket, 128); - } - fclose($socket); - - $ret->result_code = $code; - $ret->body = $body; - - return $ret; - } - } -?> +m_host = $host; + $this->m_port = $port; + $this->m_headers = array(); + } + + /** + * @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) + { + $this->m_headers[$key] = $value; + } + + /** + * @brief send HTTP message to the host + * @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) + { + $socket = @fsockopen($this->m_host, $this->m_port, $errno, $errstr, $timeout); + if(!$socket) + { + return new Object(-1, "socket_connect_failed"); + } + + $this->AddToHeader('Host', $this->m_host); + $this->AddToHeader('Connection', "close"); + + $crlf = "\r\n"; + $request = "$method $target HTTP/1.1$crlf"; + + foreach($this->m_headers as $equiv => $content) + { + $request .= "$equiv: $content$crlf"; + } + $request .= $crlf; + fwrite($socket, $request); + + list($httpver, $code, $status) = split(' +', rtrim(fgets($socket))); + // read response header + while(strlen(trim($line = fgets($socket)))) + { + list($equiv, $content) = split(' *: *', rtrim($line)); + } + $body = ''; + while(!feof($socket)) + { + $body .= fgets($socket, 128); + } + fclose($socket); + + $ret->result_code = $code; + $ret->body = $body; + + return $ret; + } + } +?> diff --git a/classes/mail/Mail.class.php b/classes/mail/Mail.class.php index 2654f5686..ad5b3d19a 100644 --- a/classes/mail/Mail.class.php +++ b/classes/mail/Mail.class.php @@ -1,353 +1,353 @@ -additional_params = $additional_params; - } - - function addAttachment($filename, $orgfilename) - { - $this->attachments[$orgfilename] = $filename; - } - - function addCidAttachment($filename, $cid) - { - $this->cidAttachments[$cid] = $filename; - } - - function setSender($name, $email) { - $this->sender_name = $name; - $this->sender_email = $email; - } - - function getSender() { - if(!stristr(PHP_OS, 'win') && $this->sender_name) return sprintf("%s <%s>", '=?utf-8?b?'.base64_encode($this->sender_name).'?=', $this->sender_email); - return $this->sender_email; - } - - function setReceiptor($name, $email) { - $this->receiptor_name = $name; - $this->receiptor_email = $email; - } - - function getReceiptor() { - if(!stristr(PHP_OS, 'win') && $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; - } - - function setTitle($title) { - $this->title = $title; - } - - function getTitle() { - 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) { - $content = preg_replace_callback('/]+)>/i',array($this,'replaceResourceRealPath'), $content); - $this->content = $content; - } - - function replaceResourceRealPath($matches) { - return preg_replace('/src=(["\']?)files/i','src=$1'.Context::getRequestUri().'files', $matches[0]); - } - - function getPlainContent() { - return chunk_split(base64_encode(str_replace(array("<",">","&"), array("<",">","&"), $this->content))); - } - - function getHTMLContent() { - return chunk_split(base64_encode($this->content_type!='html'?nl2br($this->content):$this->content)); - } - - function setContentType($mode = '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() { - $boundary = '----=='.uniqid(rand(),true); - $this->eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n"; - - $this->header = "Content-Type: multipart/alternative;".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol; - $this->body = sprintf( - "--%s".$this->eol. - "Content-Type: text/plain; charset=utf-8; format=flowed".$this->eol. - "Content-Transfer-Encoding: base64".$this->eol. - "Content-Disposition: inline".$this->eol.$this->eol. - "%s". - "--%s".$this->eol. - "Content-Type: text/html; charset=utf-8".$this->eol. - "Content-Transfer-Encoding: base64".$this->eol. - "Content-Disposition: inline".$this->eol.$this->eol. - "%s". - "--%s--". - "", - $boundary, - $this->getPlainContent(), - $boundary, - $this->getHTMLContent(), - $boundary - ); - - $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; - if($this->additional_params) return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers, $this->additional_params); - return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers); - } - - function checkMailMX($email_address) { - if(!Mail::isVaildMailAddress($email_address)) return false; - list($user, $host) = explode("@", $email_address); - if(function_exists('checkdnsrr')) { - if (checkdnsrr($host, "MX") or checkdnsrr($host, "A")) return true; - else return false; - } - return true; - } - - function isVaildMailAddress($email_address) { - if( preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address) ) return $email_address; - 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], "."); - } - } - } -?> +additional_params = $additional_params; + } + + function addAttachment($filename, $orgfilename) + { + $this->attachments[$orgfilename] = $filename; + } + + function addCidAttachment($filename, $cid) + { + $this->cidAttachments[$cid] = $filename; + } + + function setSender($name, $email) { + $this->sender_name = $name; + $this->sender_email = $email; + } + + function getSender() { + if(!stristr(PHP_OS, 'win') && $this->sender_name) return sprintf("%s <%s>", '=?utf-8?b?'.base64_encode($this->sender_name).'?=', $this->sender_email); + return $this->sender_email; + } + + function setReceiptor($name, $email) { + $this->receiptor_name = $name; + $this->receiptor_email = $email; + } + + function getReceiptor() { + if(!stristr(PHP_OS, 'win') && $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; + } + + function setTitle($title) { + $this->title = $title; + } + + function getTitle() { + 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) { + $content = preg_replace_callback('/]+)>/i',array($this,'replaceResourceRealPath'), $content); + $this->content = $content; + } + + function replaceResourceRealPath($matches) { + return preg_replace('/src=(["\']?)files/i','src=$1'.Context::getRequestUri().'files', $matches[0]); + } + + function getPlainContent() { + return chunk_split(base64_encode(str_replace(array("<",">","&"), array("<",">","&"), $this->content))); + } + + function getHTMLContent() { + return chunk_split(base64_encode($this->content_type!='html'?nl2br($this->content):$this->content)); + } + + function setContentType($mode = '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() { + $boundary = '----=='.uniqid(rand(),true); + $this->eol = $GLOBALS['_qmail_compatibility'] == "Y" ? "\n" : "\r\n"; + + $this->header = "Content-Type: multipart/alternative;".$this->eol."\tboundary=\"".$boundary."\"".$this->eol.$this->eol; + $this->body = sprintf( + "--%s".$this->eol. + "Content-Type: text/plain; charset=utf-8; format=flowed".$this->eol. + "Content-Transfer-Encoding: base64".$this->eol. + "Content-Disposition: inline".$this->eol.$this->eol. + "%s". + "--%s".$this->eol. + "Content-Type: text/html; charset=utf-8".$this->eol. + "Content-Transfer-Encoding: base64".$this->eol. + "Content-Disposition: inline".$this->eol.$this->eol. + "%s". + "--%s--". + "", + $boundary, + $this->getPlainContent(), + $boundary, + $this->getHTMLContent(), + $boundary + ); + + $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; + if($this->additional_params) return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers, $this->additional_params); + return mail($this->getReceiptor(), $this->getTitle(), $this->body, $headers); + } + + function checkMailMX($email_address) { + if(!Mail::isVaildMailAddress($email_address)) return false; + list($user, $host) = explode("@", $email_address); + if(function_exists('checkdnsrr')) { + if (checkdnsrr($host, "MX") or checkdnsrr($host, "A")) return true; + else return false; + } + return true; + } + + function isVaildMailAddress($email_address) { + if( preg_match("/([a-z0-9\_\-\.]+)@([a-z0-9\_\-\.]+)/i", $email_address) ) return $email_address; + 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], "."); + } + } + } +?> diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index 57d8cd2ef..3ff8f5f3f 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -1,557 +1,557 @@ -module = 'install'; - $this->act = Context::get('act'); - return; - } - - // Set variables from request arguments - if(!$module) $this->module = Context::get('module'); - else $this->module = $module; - - if(!$act) $this->act = Context::get('act'); - else $this->act = $act; - - if(!$mid) $this->mid = Context::get('mid'); - else $this->mid = $mid; - - if(!$document_srl) $this->document_srl = (int)Context::get('document_srl'); - else $this->document_srl = (int)$document_srl; - - if(!$module_srl) $this->module_srl = (int)Context::get('module_srl'); - else $this->module_srl = (int)$module_srl; - - $this->entry = Context::convertEncodingStr(Context::get('entry')); - - // Validate variables to prevent XSS - if($this->module && !preg_match("/^([a-z0-9\_\-]+)$/i",$this->module)) die(Context::getLang("msg_invalid_request")); - if($this->mid && !preg_match("/^([a-z0-9\_\-]+)$/i",$this->mid)) die(Context::getLang("msg_invalid_request")); - if($this->act && !preg_match("/^([a-z0-9\_\-]+)$/i",$this->act)) die(Context::getLang("msg_invalid_request")); - - // execute addon (before module initialization) - $called_position = 'before_module_init'; - $oAddonController = &getController('addon'); - $addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone()?"mobile":"pc"); - @include($addon_file); - } - - /** - * @brief Initialization. It finds the target module based on module, mid, document_srl, and prepares to execute an action - * @return true: OK, false: redirected - **/ - function init() { - $oModuleModel = &getModel('module'); - - $site_module_info = Context::get('site_module_info'); - - if(!$this->document_srl && $this->mid && $this->entry) { - $oDocumentModel = &getModel('document'); - $this->document_srl = $oDocumentModel->getDocumentSrlByAlias($this->mid, $this->entry); - if($this->document_srl) Context::set('document_srl', $this->document_srl); - } - - // Get module's information based on document_srl, if it's specified - if($this->document_srl && !$this->module) { - $module_info = $oModuleModel->getModuleInfoByDocumentSrl($this->document_srl); - - // If the document does not exist, remove document_srl - if(!$module_info) { - unset($this->document_srl); - } else { - // If it exists, compare mid based on the module information - // if mids are not matching, set it as the document's mid - if($this->mid != $module_info->mid) { - $this->mid = $module_info->mid; - Context::set('mid', $module_info->mid, true); - } - } - // if requested module is different from one of the document, remove the module information retrieved based on the document number - if($this->module && $module_info->module != $this->module) unset($module_info); - } - - // If module_info is not set yet, and there exists mid information, get module information based on the mid - if(!$module_info && $this->mid) { - $module_info = $oModuleModel->getModuleInfoByMid($this->mid, $site_module_info->site_srl); - //if($this->module && $module_info->module != $this->module) unset($module_info); - } - - // redirect, if module_site_srl and site_srl are different - if(!$this->module && !$module_info && $site_module_info->site_srl == 0 && $site_module_info->module_site_srl > 0) { - $site_info = $oModuleModel->getSiteInfo($site_module_info->module_site_srl); - header("location:".getNotEncodedSiteUrl($site_info->domain,'mid',$site_module_info->mid)); - return false; - } - - // If module_info is not set still, and $module does not exist, find the default module - if(!$module_info && !$this->module) $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 - if($module_info && $module_info->site_srl != $site_module_info->site_srl && !isCrawler()) { - // If the module is of virtual site - if($module_info->site_srl) { - $site_info = $oModuleModel->getSiteInfo($module_info->site_srl); - $redirect_url = getNotEncodedSiteUrl($site_info->domain, 'mid',Context::get('mid'),'document_srl',Context::get('document_srl'),'module_srl',Context::get('module_srl'),'entry',Context::get('entry')); - // If it's called from a virtual site, though it's not a module of the virtual site - } else { - $db_info = Context::getDBInfo(); - if(!$db_info->default_url) return Context::getLang('msg_default_url_is_not_defined'); - else $redirect_url = getNotEncodedSiteUrl($db_info->default_url, 'mid',Context::get('mid'),'document_srl',Context::get('document_srl'),'module_srl',Context::get('module_srl'),'entry',Context::get('entry')); - } - header("location:".$redirect_url); - return false; - } - - // If module info was set, retrieve variables from the module information - if($module_info) { - $this->module = $module_info->module; - $this->mid = $module_info->mid; - $this->module_info = $module_info; - Context::setBrowserTitle($module_info->browser_title); - $part_config= $oModuleModel->getModulePartConfig('layout',$module_info->layout_srl); - Context::addHtmlHeader($part_config->header_script); - } - - // Set module and mid into module_info - $this->module_info->module = $this->module; - $this->module_info->mid = $this->mid; - - // Still no module? it's an error - if(!$this->module) $this->error = 'msg_module_is_not_exists'; - - // If mid exists, set mid into context - if($this->mid) Context::set('mid', $this->mid, true); - - // Call a trigger after moduleHandler init - $output = ModuleHandler::triggerCall('moduleHandler.init', 'after', $this->module_info); - if(!$output->toBool()) { - $this->error = $output->getMessage(); - return false; - } - - // Set current module info into context - Context::set('current_module_info', $this->module_info); - - return true; - } - - /** - * @brief get a module instance and execute an action - * @return executed module instance - **/ - function procModule() { - // If error occurred while preparation, return a message instance - if($this->error) { - $type = Mobile::isFromMobilePhone() ? 'mobile' : 'view'; - $oMessageObject = &ModuleHandler::getModuleInstance('message',$type); - $oMessageObject->setError(-1); - $oMessageObject->setMessage($this->error); - $oMessageObject->dispMessage(); - return $oMessageObject; - } - - $oModuleModel = &getModel('module'); - - // Get action information with conf/action.xml - $xml_info = $oModuleModel->getModuleActionXml($this->module); - - // If not installed yet, modify act - if($this->module=="install") { - if(!$this->act || !$xml_info->action->{$this->act}) $this->act = $xml_info->default_index_act; - } - - // if act exists, find type of the action, if not use default index act - if(!$this->act) $this->act = $xml_info->default_index_act; - - // still no act means error - if(!$this->act) { - $this->error = 'msg_module_is_not_exists'; - return; - } - - // get type, kind - $type = $xml_info->action->{$this->act}->type; - $kind = strpos(strtolower($this->act),'admin')!==false?'admin':''; - if(!$kind && $this->module == 'admin') $kind = 'admin'; - if($this->module_info->use_mobile != "Y") Mobile::setMobile(false); - - // if(type == view, and case for using mobilephone) - if($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled()) - { - $orig_type = "view"; - $type = "mobile"; - // create a module instance - $oModule = &$this->getModuleInstance($this->module, $type, $kind); - if(!is_object($oModule) || !method_exists($oModule, $this->act)) { - $type = $orig_type; - Mobile::setMobile(false); - $oModule = &$this->getModuleInstance($this->module, $type, $kind); - } - } - else - { - // create a module instance - $oModule = &$this->getModuleInstance($this->module, $type, $kind); - } - - if(!is_object($oModule)) { - $this->error = 'msg_module_is_not_exists'; - return; - } - - // If there is no such action in the module object - if(!isset($xml_info->action->{$this->act}) || !method_exists($oModule, $this->act)) - { - if(!Context::isInstalled()) - { - $this->error = 'msg_invalid_request'; - return; - } - - $forward = null; - // 1. Look for the module with action name - if(preg_match('/^([a-z]+)([A-Z])([a-z0-9\_]+)(.*)$/', $this->act, $matches)) { - $module = strtolower($matches[2].$matches[3]); - $xml_info = $oModuleModel->getModuleActionXml($module); - if($xml_info->action->{$this->act}) { - $forward->module = $module; - $forward->type = $xml_info->action->{$this->act}->type; - $forward->act = $this->act; - } - } - - if(!$forward) - { - $forward = $oModuleModel->getActionForward($this->act); - } - - if($forward->module && $forward->type && $forward->act && $forward->act == $this->act) { - $kind = strpos(strtolower($forward->act),'admin')!==false?'admin':''; - $type = $forward->type; - $tpl_path = $oModule->getTemplatePath(); - $orig_module = $oModule; - - if($type == "view" && Mobile::isFromMobilePhone()) - { - $orig_type = "view"; - $type = "mobile"; - // create a module instance - $oModule = &$this->getModuleInstance($forward->module, $type, $kind); - if(!is_object($oModule) || !method_exists($oModule, $this->act)) { - $type = $orig_type; - Mobile::setMobile(false); - $oModule = &$this->getModuleInstance($forward->module, $type, $kind); - } - } - else - { - $oModule = &$this->getModuleInstance($forward->module, $type, $kind); - } - $xml_info = $oModuleModel->getModuleActionXml($forward->module); - if($this->module == "admin" && $type == "view") - { - $oMemberModel = &getModel('member'); - $logged_info = $oMemberModel->getLoggedInfo(); - if($logged_info->is_admin=='Y') { - $orig_module->loadSideBar(); - $oModule->setLayoutPath("./modules/admin/tpl"); - $oModule->setLayoutFile("layout.html"); - } - } - } - else if($xml_info->default_index_act && method_exists($oModule, $xml_info->default_index_act)) - { - $this->act = $xml_info->default_index_act; - } - else - { - $this->error = 'msg_invalid_request'; - return; - } - } - - $oModule->setAct($this->act); - - $this->module_info->module_type = $type; - $oModule->setModuleInfo($this->module_info, $xml_info); - - // execute the action, and if failed, set error - if(!$oModule->proc()) $this->error = $oModule->getMessage(); - - return $oModule; - } - - /** - * @brief display contents from executed module - * @param[in] $oModule module instance - * @return none - **/ - function displayContent($oModule = NULL) { - // If the module is not set or not an object, set error - if(!$oModule || !is_object($oModule)) { - $this->error = 'msg_module_is_not_exists'; - } - - // If connection to DB has a problem even though it's not install module, set error - if($this->module != 'install' && $GLOBALS['__DB__'][Context::getDBType()]->is_connected == false) { - $this->error = 'msg_dbconnect_failed'; - } - - // Call trigger after moduleHandler proc - $output = ModuleHandler::triggerCall('moduleHandler.proc', 'after', $oModule); - if(!$output->toBool()) $this->error = $output->getMessage(); - - // Use message view object, if HTML call - if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) { - // If error occurred, handle it - if($this->error) { - // display content with message module instance - $type = Mobile::isFromMobilePhone() ? 'mobile' : 'view'; - $oMessageObject = &ModuleHandler::getModuleInstance('message',$type); - $oMessageObject->setError(-1); - $oMessageObject->setMessage($this->error); - $oMessageObject->dispMessage(); - - // If module was called normally, change the templates of the module into ones of the message view module - if($oModule) { - $oModule->setTemplatePath($oMessageObject->getTemplatePath()); - $oModule->setTemplateFile($oMessageObject->getTemplateFile()); - - // Otherwise, set message instance as the target module - } else { - $oModule = $oMessageObject; - } - } - - // Check if layout_srl exists for the module - if(Mobile::isFromMobilePhone()) - { - $layout_srl = $oModule->module_info->mlayout_srl; - } - else - { - $layout_srl = $oModule->module_info->layout_srl; - } - - if($layout_srl && !$oModule->getLayoutFile()) { - - // If layout_srl exists, get information of the layout, and set the location of layout_path/ layout_file - $oLayoutModel = &getModel('layout'); - $layout_info = $oLayoutModel->getLayout($layout_srl); - if($layout_info) { - - // Input extra_vars into $layout_info - if($layout_info->extra_var_count) { - - foreach($layout_info->extra_var as $var_id => $val) { - if($val->type == 'image') { - if(preg_match('/^\.\/files\/attach\/images\/(.+)/i',$val->value)) $val->value = Context::getRequestUri().substr($val->value,2); - } - $layout_info->{$var_id} = $val->value; - } - } - // Set menus into context - if($layout_info->menu_count) { - foreach($layout_info->menu as $menu_id => $menu) { - if(file_exists($menu->php_file)) @include($menu->php_file); - Context::set($menu_id, $menu); - } - } - - // Set layout information into context - Context::set('layout_info', $layout_info); - - $oModule->setLayoutPath($layout_info->path); - $oModule->setLayoutFile('layout'); - - // If layout was modified, use the modified version - $edited_layout = $oLayoutModel->getUserLayoutHtml($layout_info->layout_srl); - if(file_exists($edited_layout)) $oModule->setEditedLayoutFile($edited_layout); - } - } - } - - // Display contents - $oDisplayHandler = new DisplayHandler(); - $oDisplayHandler->printContent($oModule); - } - - /** - * @brief returns module's path - * @param[in] $module module name - * @return path of the module - **/ - function getModulePath($module) { - return sprintf('./modules/%s/', $module); - } - - /** - * @brief It creates a module instance - * @param[in] $module module name - * @param[in] $type instance type, (e.g., view, controller, model) - * @param[in] $kind admin or svc - * @return module instance (if failed it returns null) - * @remarks if there exists a module instance created before, returns it. - **/ - function &getModuleInstance($module, $type = 'view', $kind = '') { - $class_path = ModuleHandler::getModulePath($module); - if(!is_dir(_XE_PATH_.$class_path)) return NULL; - - if(__DEBUG__==3) $start_time = getMicroTime(); - - if($kind != 'admin') $kind = 'svc'; - - // if there is no instance of the module in global variable, create a new one - if(!$GLOBALS['_loaded_module'][$module][$type][$kind]) { - // Get base class name and load the file contains it - if(!class_exists($module)) { - $high_class_file = sprintf('%s%s%s.class.php', _XE_PATH_,$class_path, $module); - if(!file_exists($high_class_file)) return NULL; - require_once($high_class_file); - } - - // Get the object's name - switch($type) { - case 'controller' : - if($kind == 'admin') { - $instance_name = sprintf("%sAdmin%s",$module,"Controller"); - $class_file = sprintf('%s%s%s.admin.%s.php', _XE_PATH_, $class_path, $module, $type); - } else { - $instance_name = sprintf("%s%s",$module,"Controller"); - $class_file = sprintf('%s%s%s.%s.php', _XE_PATH_, $class_path, $module, $type); - } - break; - case 'model' : - if($kind == 'admin') { - $instance_name = sprintf("%sAdmin%s",$module,"Model"); - $class_file = sprintf('%s%s%s.admin.%s.php', _XE_PATH_, $class_path, $module, $type); - } else { - $instance_name = sprintf("%s%s",$module,"Model"); - $class_file = sprintf('%s%s%s.%s.php', _XE_PATH_, $class_path, $module, $type); - } - break; - case 'api' : - $instance_name = sprintf("%s%s",$module,"API"); - $class_file = sprintf('%s%s%s.api.php', _XE_PATH_, $class_path, $module); - break; - case 'wap' : - $instance_name = sprintf("%s%s",$module,"WAP"); - $class_file = sprintf('%s%s%s.wap.php', _XE_PATH_, $class_path, $module); - break; - case 'mobile' : - $instance_name = sprintf("%s%s",$module,"Mobile"); - $class_file = sprintf("%s%s%s.mobile.php", _XE_PATH_, $class_path, $module); - break; - case 'class' : - $instance_name = $module; - $class_file = sprintf('%s%s%s.class.php', _XE_PATH_, $class_path, $module); - break; - default : - $type = 'view'; - if($kind == 'admin') { - $instance_name = sprintf("%sAdmin%s",$module,"View"); - $class_file = sprintf('%s%s%s.admin.view.php', _XE_PATH_, $class_path, $module, $type); - } else { - $instance_name = sprintf("%s%s",$module,"View"); - $class_file = sprintf('%s%s%s.view.php', _XE_PATH_, $class_path, $module, $type); - } - break; - } - - // Get the name of the class file - if(!file_exists($class_file)) return NULL; - - // Create an instance with eval function - require_once($class_file); - if(!class_exists($instance_name)) return NULL; - $eval_str = sprintf('$oModule = new %s();', $instance_name); - @eval($eval_str); - if(!is_object($oModule)) return NULL; - - // Load language files for the class - Context::loadLang($class_path.'lang'); - - // Set variables to the instance - $oModule->setModule($module); - $oModule->setModulePath($class_path); - - // If the module has a constructor, run it. - if(!isset($GLOBALS['_called_constructor'][$instance_name])) { - $GLOBALS['_called_constructor'][$instance_name] = true; - if(@method_exists($oModule, $instance_name)) $oModule->{$instance_name}(); - } - - // Store the created instance into GLOBALS variable - $GLOBALS['_loaded_module'][$module][$type][$kind] = $oModule; - } - - if(__DEBUG__==3) $GLOBALS['__elapsed_class_load__'] += getMicroTime() - $start_time; - - // return the instance - return $GLOBALS['_loaded_module'][$module][$type][$kind]; - } - - /** - * @brief call a trigger - * @param[in] $trigger_name trigger's name to call - * @param[in] $called_position called position - * @param[in] $obj an object as a parameter to trigger - * @return Object - **/ - function triggerCall($trigger_name, $called_position, &$obj) { - // skip if not installed - if(!Context::isInstalled()) return new Object(); - - $oModuleModel = &getModel('module'); - $triggers = $oModuleModel->getTriggers($trigger_name, $called_position); - if(!$triggers || !count($triggers)) return new Object(); - - foreach($triggers as $item) { - $module = $item->module; - $type = $item->type; - $called_method = $item->called_method; - - $oModule = null; - $oModule = &getModule($module, $type); - if(!$oModule || !method_exists($oModule, $called_method)) continue; - - $output = $oModule->{$called_method}($obj); - if(is_object($output) && method_exists($output, 'toBool') && !$output->toBool()) return $output; - unset($oModule); - } - - return new Object(); - } - } -?> +module = 'install'; + $this->act = Context::get('act'); + return; + } + + // Set variables from request arguments + if(!$module) $this->module = Context::get('module'); + else $this->module = $module; + + if(!$act) $this->act = Context::get('act'); + else $this->act = $act; + + if(!$mid) $this->mid = Context::get('mid'); + else $this->mid = $mid; + + if(!$document_srl) $this->document_srl = (int)Context::get('document_srl'); + else $this->document_srl = (int)$document_srl; + + if(!$module_srl) $this->module_srl = (int)Context::get('module_srl'); + else $this->module_srl = (int)$module_srl; + + $this->entry = Context::convertEncodingStr(Context::get('entry')); + + // Validate variables to prevent XSS + if($this->module && !preg_match("/^([a-z0-9\_\-]+)$/i",$this->module)) die(Context::getLang("msg_invalid_request")); + if($this->mid && !preg_match("/^([a-z0-9\_\-]+)$/i",$this->mid)) die(Context::getLang("msg_invalid_request")); + if($this->act && !preg_match("/^([a-z0-9\_\-]+)$/i",$this->act)) die(Context::getLang("msg_invalid_request")); + + // execute addon (before module initialization) + $called_position = 'before_module_init'; + $oAddonController = &getController('addon'); + $addon_file = $oAddonController->getCacheFilePath(Mobile::isFromMobilePhone()?"mobile":"pc"); + @include($addon_file); + } + + /** + * @brief Initialization. It finds the target module based on module, mid, document_srl, and prepares to execute an action + * @return true: OK, false: redirected + **/ + function init() { + $oModuleModel = &getModel('module'); + + $site_module_info = Context::get('site_module_info'); + + if(!$this->document_srl && $this->mid && $this->entry) { + $oDocumentModel = &getModel('document'); + $this->document_srl = $oDocumentModel->getDocumentSrlByAlias($this->mid, $this->entry); + if($this->document_srl) Context::set('document_srl', $this->document_srl); + } + + // Get module's information based on document_srl, if it's specified + if($this->document_srl && !$this->module) { + $module_info = $oModuleModel->getModuleInfoByDocumentSrl($this->document_srl); + + // If the document does not exist, remove document_srl + if(!$module_info) { + unset($this->document_srl); + } else { + // If it exists, compare mid based on the module information + // if mids are not matching, set it as the document's mid + if($this->mid != $module_info->mid) { + $this->mid = $module_info->mid; + Context::set('mid', $module_info->mid, true); + } + } + // if requested module is different from one of the document, remove the module information retrieved based on the document number + if($this->module && $module_info->module != $this->module) unset($module_info); + } + + // If module_info is not set yet, and there exists mid information, get module information based on the mid + if(!$module_info && $this->mid) { + $module_info = $oModuleModel->getModuleInfoByMid($this->mid, $site_module_info->site_srl); + //if($this->module && $module_info->module != $this->module) unset($module_info); + } + + // redirect, if module_site_srl and site_srl are different + if(!$this->module && !$module_info && $site_module_info->site_srl == 0 && $site_module_info->module_site_srl > 0) { + $site_info = $oModuleModel->getSiteInfo($site_module_info->module_site_srl); + header("location:".getNotEncodedSiteUrl($site_info->domain,'mid',$site_module_info->mid)); + return false; + } + + // If module_info is not set still, and $module does not exist, find the default module + if(!$module_info && !$this->module) $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 + if($module_info && $module_info->site_srl != $site_module_info->site_srl && !isCrawler()) { + // If the module is of virtual site + if($module_info->site_srl) { + $site_info = $oModuleModel->getSiteInfo($module_info->site_srl); + $redirect_url = getNotEncodedSiteUrl($site_info->domain, 'mid',Context::get('mid'),'document_srl',Context::get('document_srl'),'module_srl',Context::get('module_srl'),'entry',Context::get('entry')); + // If it's called from a virtual site, though it's not a module of the virtual site + } else { + $db_info = Context::getDBInfo(); + if(!$db_info->default_url) return Context::getLang('msg_default_url_is_not_defined'); + else $redirect_url = getNotEncodedSiteUrl($db_info->default_url, 'mid',Context::get('mid'),'document_srl',Context::get('document_srl'),'module_srl',Context::get('module_srl'),'entry',Context::get('entry')); + } + header("location:".$redirect_url); + return false; + } + + // If module info was set, retrieve variables from the module information + if($module_info) { + $this->module = $module_info->module; + $this->mid = $module_info->mid; + $this->module_info = $module_info; + Context::setBrowserTitle($module_info->browser_title); + $part_config= $oModuleModel->getModulePartConfig('layout',$module_info->layout_srl); + Context::addHtmlHeader($part_config->header_script); + } + + // Set module and mid into module_info + $this->module_info->module = $this->module; + $this->module_info->mid = $this->mid; + + // Still no module? it's an error + if(!$this->module) $this->error = 'msg_module_is_not_exists'; + + // If mid exists, set mid into context + if($this->mid) Context::set('mid', $this->mid, true); + + // Call a trigger after moduleHandler init + $output = ModuleHandler::triggerCall('moduleHandler.init', 'after', $this->module_info); + if(!$output->toBool()) { + $this->error = $output->getMessage(); + return false; + } + + // Set current module info into context + Context::set('current_module_info', $this->module_info); + + return true; + } + + /** + * @brief get a module instance and execute an action + * @return executed module instance + **/ + function procModule() { + // If error occurred while preparation, return a message instance + if($this->error) { + $type = Mobile::isFromMobilePhone() ? 'mobile' : 'view'; + $oMessageObject = &ModuleHandler::getModuleInstance('message',$type); + $oMessageObject->setError(-1); + $oMessageObject->setMessage($this->error); + $oMessageObject->dispMessage(); + return $oMessageObject; + } + + $oModuleModel = &getModel('module'); + + // Get action information with conf/action.xml + $xml_info = $oModuleModel->getModuleActionXml($this->module); + + // If not installed yet, modify act + if($this->module=="install") { + if(!$this->act || !$xml_info->action->{$this->act}) $this->act = $xml_info->default_index_act; + } + + // if act exists, find type of the action, if not use default index act + if(!$this->act) $this->act = $xml_info->default_index_act; + + // still no act means error + if(!$this->act) { + $this->error = 'msg_module_is_not_exists'; + return; + } + + // get type, kind + $type = $xml_info->action->{$this->act}->type; + $kind = strpos(strtolower($this->act),'admin')!==false?'admin':''; + if(!$kind && $this->module == 'admin') $kind = 'admin'; + if($this->module_info->use_mobile != "Y") Mobile::setMobile(false); + + // if(type == view, and case for using mobilephone) + if($type == "view" && Mobile::isFromMobilePhone() && Context::isInstalled()) + { + $orig_type = "view"; + $type = "mobile"; + // create a module instance + $oModule = &$this->getModuleInstance($this->module, $type, $kind); + if(!is_object($oModule) || !method_exists($oModule, $this->act)) { + $type = $orig_type; + Mobile::setMobile(false); + $oModule = &$this->getModuleInstance($this->module, $type, $kind); + } + } + else + { + // create a module instance + $oModule = &$this->getModuleInstance($this->module, $type, $kind); + } + + if(!is_object($oModule)) { + $this->error = 'msg_module_is_not_exists'; + return; + } + + // If there is no such action in the module object + if(!isset($xml_info->action->{$this->act}) || !method_exists($oModule, $this->act)) + { + if(!Context::isInstalled()) + { + $this->error = 'msg_invalid_request'; + return; + } + + $forward = null; + // 1. Look for the module with action name + if(preg_match('/^([a-z]+)([A-Z])([a-z0-9\_]+)(.*)$/', $this->act, $matches)) { + $module = strtolower($matches[2].$matches[3]); + $xml_info = $oModuleModel->getModuleActionXml($module); + if($xml_info->action->{$this->act}) { + $forward->module = $module; + $forward->type = $xml_info->action->{$this->act}->type; + $forward->act = $this->act; + } + } + + if(!$forward) + { + $forward = $oModuleModel->getActionForward($this->act); + } + + if($forward->module && $forward->type && $forward->act && $forward->act == $this->act) { + $kind = strpos(strtolower($forward->act),'admin')!==false?'admin':''; + $type = $forward->type; + $tpl_path = $oModule->getTemplatePath(); + $orig_module = $oModule; + + if($type == "view" && Mobile::isFromMobilePhone()) + { + $orig_type = "view"; + $type = "mobile"; + // create a module instance + $oModule = &$this->getModuleInstance($forward->module, $type, $kind); + if(!is_object($oModule) || !method_exists($oModule, $this->act)) { + $type = $orig_type; + Mobile::setMobile(false); + $oModule = &$this->getModuleInstance($forward->module, $type, $kind); + } + } + else + { + $oModule = &$this->getModuleInstance($forward->module, $type, $kind); + } + $xml_info = $oModuleModel->getModuleActionXml($forward->module); + if($this->module == "admin" && $type == "view") + { + $oMemberModel = &getModel('member'); + $logged_info = $oMemberModel->getLoggedInfo(); + if($logged_info->is_admin=='Y') { + $orig_module->loadSideBar(); + $oModule->setLayoutPath("./modules/admin/tpl"); + $oModule->setLayoutFile("layout.html"); + } + } + } + else if($xml_info->default_index_act && method_exists($oModule, $xml_info->default_index_act)) + { + $this->act = $xml_info->default_index_act; + } + else + { + $this->error = 'msg_invalid_request'; + return; + } + } + + $oModule->setAct($this->act); + + $this->module_info->module_type = $type; + $oModule->setModuleInfo($this->module_info, $xml_info); + + // execute the action, and if failed, set error + if(!$oModule->proc()) $this->error = $oModule->getMessage(); + + return $oModule; + } + + /** + * @brief display contents from executed module + * @param[in] $oModule module instance + * @return none + **/ + function displayContent($oModule = NULL) { + // If the module is not set or not an object, set error + if(!$oModule || !is_object($oModule)) { + $this->error = 'msg_module_is_not_exists'; + } + + // If connection to DB has a problem even though it's not install module, set error + if($this->module != 'install' && $GLOBALS['__DB__'][Context::getDBType()]->is_connected == false) { + $this->error = 'msg_dbconnect_failed'; + } + + // Call trigger after moduleHandler proc + $output = ModuleHandler::triggerCall('moduleHandler.proc', 'after', $oModule); + if(!$output->toBool()) $this->error = $output->getMessage(); + + // Use message view object, if HTML call + if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) { + // If error occurred, handle it + if($this->error) { + // display content with message module instance + $type = Mobile::isFromMobilePhone() ? 'mobile' : 'view'; + $oMessageObject = &ModuleHandler::getModuleInstance('message',$type); + $oMessageObject->setError(-1); + $oMessageObject->setMessage($this->error); + $oMessageObject->dispMessage(); + + // If module was called normally, change the templates of the module into ones of the message view module + if($oModule) { + $oModule->setTemplatePath($oMessageObject->getTemplatePath()); + $oModule->setTemplateFile($oMessageObject->getTemplateFile()); + + // Otherwise, set message instance as the target module + } else { + $oModule = $oMessageObject; + } + } + + // Check if layout_srl exists for the module + if(Mobile::isFromMobilePhone()) + { + $layout_srl = $oModule->module_info->mlayout_srl; + } + else + { + $layout_srl = $oModule->module_info->layout_srl; + } + + if($layout_srl && !$oModule->getLayoutFile()) { + + // If layout_srl exists, get information of the layout, and set the location of layout_path/ layout_file + $oLayoutModel = &getModel('layout'); + $layout_info = $oLayoutModel->getLayout($layout_srl); + if($layout_info) { + + // Input extra_vars into $layout_info + if($layout_info->extra_var_count) { + + foreach($layout_info->extra_var as $var_id => $val) { + if($val->type == 'image') { + if(preg_match('/^\.\/files\/attach\/images\/(.+)/i',$val->value)) $val->value = Context::getRequestUri().substr($val->value,2); + } + $layout_info->{$var_id} = $val->value; + } + } + // Set menus into context + if($layout_info->menu_count) { + foreach($layout_info->menu as $menu_id => $menu) { + if(file_exists($menu->php_file)) @include($menu->php_file); + Context::set($menu_id, $menu); + } + } + + // Set layout information into context + Context::set('layout_info', $layout_info); + + $oModule->setLayoutPath($layout_info->path); + $oModule->setLayoutFile('layout'); + + // If layout was modified, use the modified version + $edited_layout = $oLayoutModel->getUserLayoutHtml($layout_info->layout_srl); + if(file_exists($edited_layout)) $oModule->setEditedLayoutFile($edited_layout); + } + } + } + + // Display contents + $oDisplayHandler = new DisplayHandler(); + $oDisplayHandler->printContent($oModule); + } + + /** + * @brief returns module's path + * @param[in] $module module name + * @return path of the module + **/ + function getModulePath($module) { + return sprintf('./modules/%s/', $module); + } + + /** + * @brief It creates a module instance + * @param[in] $module module name + * @param[in] $type instance type, (e.g., view, controller, model) + * @param[in] $kind admin or svc + * @return module instance (if failed it returns null) + * @remarks if there exists a module instance created before, returns it. + **/ + function &getModuleInstance($module, $type = 'view', $kind = '') { + $class_path = ModuleHandler::getModulePath($module); + if(!is_dir(_XE_PATH_.$class_path)) return NULL; + + if(__DEBUG__==3) $start_time = getMicroTime(); + + if($kind != 'admin') $kind = 'svc'; + + // if there is no instance of the module in global variable, create a new one + if(!$GLOBALS['_loaded_module'][$module][$type][$kind]) { + // Get base class name and load the file contains it + if(!class_exists($module)) { + $high_class_file = sprintf('%s%s%s.class.php', _XE_PATH_,$class_path, $module); + if(!file_exists($high_class_file)) return NULL; + require_once($high_class_file); + } + + // Get the object's name + switch($type) { + case 'controller' : + if($kind == 'admin') { + $instance_name = sprintf("%sAdmin%s",$module,"Controller"); + $class_file = sprintf('%s%s%s.admin.%s.php', _XE_PATH_, $class_path, $module, $type); + } else { + $instance_name = sprintf("%s%s",$module,"Controller"); + $class_file = sprintf('%s%s%s.%s.php', _XE_PATH_, $class_path, $module, $type); + } + break; + case 'model' : + if($kind == 'admin') { + $instance_name = sprintf("%sAdmin%s",$module,"Model"); + $class_file = sprintf('%s%s%s.admin.%s.php', _XE_PATH_, $class_path, $module, $type); + } else { + $instance_name = sprintf("%s%s",$module,"Model"); + $class_file = sprintf('%s%s%s.%s.php', _XE_PATH_, $class_path, $module, $type); + } + break; + case 'api' : + $instance_name = sprintf("%s%s",$module,"API"); + $class_file = sprintf('%s%s%s.api.php', _XE_PATH_, $class_path, $module); + break; + case 'wap' : + $instance_name = sprintf("%s%s",$module,"WAP"); + $class_file = sprintf('%s%s%s.wap.php', _XE_PATH_, $class_path, $module); + break; + case 'mobile' : + $instance_name = sprintf("%s%s",$module,"Mobile"); + $class_file = sprintf("%s%s%s.mobile.php", _XE_PATH_, $class_path, $module); + break; + case 'class' : + $instance_name = $module; + $class_file = sprintf('%s%s%s.class.php', _XE_PATH_, $class_path, $module); + break; + default : + $type = 'view'; + if($kind == 'admin') { + $instance_name = sprintf("%sAdmin%s",$module,"View"); + $class_file = sprintf('%s%s%s.admin.view.php', _XE_PATH_, $class_path, $module, $type); + } else { + $instance_name = sprintf("%s%s",$module,"View"); + $class_file = sprintf('%s%s%s.view.php', _XE_PATH_, $class_path, $module, $type); + } + break; + } + + // Get the name of the class file + if(!file_exists($class_file)) return NULL; + + // Create an instance with eval function + require_once($class_file); + if(!class_exists($instance_name)) return NULL; + $eval_str = sprintf('$oModule = new %s();', $instance_name); + @eval($eval_str); + if(!is_object($oModule)) return NULL; + + // Load language files for the class + Context::loadLang($class_path.'lang'); + + // Set variables to the instance + $oModule->setModule($module); + $oModule->setModulePath($class_path); + + // If the module has a constructor, run it. + if(!isset($GLOBALS['_called_constructor'][$instance_name])) { + $GLOBALS['_called_constructor'][$instance_name] = true; + if(@method_exists($oModule, $instance_name)) $oModule->{$instance_name}(); + } + + // Store the created instance into GLOBALS variable + $GLOBALS['_loaded_module'][$module][$type][$kind] = $oModule; + } + + if(__DEBUG__==3) $GLOBALS['__elapsed_class_load__'] += getMicroTime() - $start_time; + + // return the instance + return $GLOBALS['_loaded_module'][$module][$type][$kind]; + } + + /** + * @brief call a trigger + * @param[in] $trigger_name trigger's name to call + * @param[in] $called_position called position + * @param[in] $obj an object as a parameter to trigger + * @return Object + **/ + function triggerCall($trigger_name, $called_position, &$obj) { + // skip if not installed + if(!Context::isInstalled()) return new Object(); + + $oModuleModel = &getModel('module'); + $triggers = $oModuleModel->getTriggers($trigger_name, $called_position); + if(!$triggers || !count($triggers)) return new Object(); + + foreach($triggers as $item) { + $module = $item->module; + $type = $item->type; + $called_method = $item->called_method; + + $oModule = null; + $oModule = &getModule($module, $type); + if(!$oModule || !method_exists($oModule, $called_method)) continue; + + $output = $oModule->{$called_method}($obj); + if(is_object($output) && method_exists($output, 'toBool') && !$output->toBool()) return $output; + unset($oModule); + } + + return new Object(); + } + } +?> diff --git a/classes/object/Object.class.php b/classes/object/Object.class.php index 50dc57b03..4cf8bab11 100644 --- a/classes/object/Object.class.php +++ b/classes/object/Object.class.php @@ -1,137 +1,137 @@ -setError($error); - $this->setMessage($message); - } - - /** - * @brief Setter to set error code - * @param[in] $error error code - **/ - function setError($error = 0) { - $this->error = $error; - } - - /** - * @brief Getter to retrieve error code - **/ - function getError() { - return $this->error; - } - - /** - * @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') { - if(Context::getLang($message)) $message = Context::getLang($message); - $this->message = $message; - return true; - } - - /** - * @brief getter to retrieve an error message - **/ - function getMessage() { - return $this->message; - } - - /** - * @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) { - $this->variables[$key] = $val; - } - - /** - * @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) { - if(is_object($object)) { - $vars = get_object_vars($object); - foreach($vars as $key => $val) $this->add($key, $val); - } elseif(is_array($object)) { - foreach($object as $key => $val) $this->add($key, $val); - } - } - - /** - * @brief method to retrieve a corresponding value to a given key - **/ - function get($key) { - return $this->variables[$key]; - } - - - /** - * @brief method to retrieve an object containing a key/value paris - * @return Returns an object containing key/value pairs - **/ - function gets() { - $num_args = func_num_args(); - $args_list = func_get_args(); - for($i=0;$i<$num_args;$i++) { - $key = $args_list[$i]; - $output->{$key} = $this->get($key); - } - return $output; - } - - /** - * @brief method to retrieve an array of key/value pairs - * @return Return a list of key/value pairs - **/ - function getVariables() { - return $this->variables; - } - - /** - * @brief method to retrieve an object of key/value pairs - * @return Return an object of key/value pairs - **/ - function getObjectVars() { - foreach($this->variables as $key => $val) $output->{$key} = $val; - return $output; - } - - /** - * @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() { - return $this->error==0?true:false; - } - - - /** - * @brief method to return either true or false depnding on the value in a 'error' variable - **/ - function toBoolean() { - return $this->toBool(); - } - } -?> +setError($error); + $this->setMessage($message); + } + + /** + * @brief Setter to set error code + * @param[in] $error error code + **/ + function setError($error = 0) { + $this->error = $error; + } + + /** + * @brief Getter to retrieve error code + **/ + function getError() { + return $this->error; + } + + /** + * @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') { + if(Context::getLang($message)) $message = Context::getLang($message); + $this->message = $message; + return true; + } + + /** + * @brief getter to retrieve an error message + **/ + function getMessage() { + return $this->message; + } + + /** + * @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) { + $this->variables[$key] = $val; + } + + /** + * @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) { + if(is_object($object)) { + $vars = get_object_vars($object); + foreach($vars as $key => $val) $this->add($key, $val); + } elseif(is_array($object)) { + foreach($object as $key => $val) $this->add($key, $val); + } + } + + /** + * @brief method to retrieve a corresponding value to a given key + **/ + function get($key) { + return $this->variables[$key]; + } + + + /** + * @brief method to retrieve an object containing a key/value paris + * @return Returns an object containing key/value pairs + **/ + function gets() { + $num_args = func_num_args(); + $args_list = func_get_args(); + for($i=0;$i<$num_args;$i++) { + $key = $args_list[$i]; + $output->{$key} = $this->get($key); + } + return $output; + } + + /** + * @brief method to retrieve an array of key/value pairs + * @return Return a list of key/value pairs + **/ + function getVariables() { + return $this->variables; + } + + /** + * @brief method to retrieve an object of key/value pairs + * @return Return an object of key/value pairs + **/ + function getObjectVars() { + foreach($this->variables as $key => $val) $output->{$key} = $val; + return $output; + } + + /** + * @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() { + return $this->error==0?true:false; + } + + + /** + * @brief method to return either true or false depnding on the value in a 'error' variable + **/ + function toBoolean() { + return $this->toBool(); + } + } +?> diff --git a/classes/optimizer/Optimizer.class.php b/classes/optimizer/Optimizer.class.php index 78dbc8c45..d85648e40 100644 --- a/classes/optimizer/Optimizer.class.php +++ b/classes/optimizer/Optimizer.class.php @@ -1,109 +1,109 @@ -cache_path)) { - FileHandler::makeDir($this->cache_path); - } - } - - /** - * @brief file that removes 'optimized' in a given array - * @param[in] $files an array to be modified - **/ - function _getOptimizedRemoved($files) { - foreach($files as $key => $val) unset($files[$key]['optimized']); - return $files; - } - - /** - * @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") { - if(!is_array($source_files) || !count($source_files)) return; - - // 관리자 설정시 설정이 되어 있지 않으면 패스 - // 캐시 디렉토리가 없으면 실행하지 않음 - $db_info = Context::getDBInfo(); - if($db_info->use_optimizer == 'N' || !is_dir($this->cache_path)) return $this->_getOptimizedRemoved($source_files); - - if(!count($source_files)) return; - - $files = array(); - $hash = ""; - foreach($source_files as $key => $file) { - if($file['file'][0] == '/'){ - if(!file_exists($file['file'])){ - if(file_exists($_SERVER['DOCUMENT_ROOT'] . $file['file'])){ - if($file['optimized']) $source_files[$key]['file'] = $file['file'] = $_SERVER['DOCUMENT_ROOT'].$file['file']; - }else{ - continue; - } - } - } else if(!$file || !$file['file'] || !file_exists($file['file'])) continue; - $file['file'] = $source_files[$key]['file'] = str_replace("\\","/",$file['file']); - if(empty($file['optimized']) || preg_match('/^https?:\/\//i', $file['file']) ) $files[] = $file; - else{ - $targets[] = $file; - $hash .= $file['file']; - } - } - if(!count($targets)) return $this->_getOptimizedRemoved($files); - $list_file_hash = md5($hash); - $oCacheHandler = &CacheHandler::getInstance('template'); - if($oCacheHandler->isSupport()){ - if(!$oCacheHandler->isValid($list_file_hash)){ - $buff = array(); - foreach($targets as $file) $buff[] = $file['file']; - $oCacheHandler->put($list_file_hash, $buff); - } - }else{ - $list_file = FileHandler::getRealPath($this->cache_path . $list_file_hash . '.info.php'); - - if(!file_exists($list_file)){ - $str = ''; - - FileHandler::writeFile($list_file, $str); - } - } - - array_unshift($files, array('file' => sprintf($this->script_file, $list_file_hash, $type) , 'media' => 'all')); - $files = $this->_getOptimizedRemoved($files); - if(!count($files)) return $files; - - $url_info = parse_url(Context::getRequestUri()); - $abpath = $url_info['path']; - foreach($files as $key => $val) { - $file = $val['file']; - - if($file{0} == '/' || strpos($file,'://')!==false) continue; - if(substr($file,0,2)=='./') $file = substr($file,2); - $file = $abpath.$file; - while(strpos($file,'/../')!==false) { - $file = preg_replace('/\/([^\/]+)\/\.\.\//','/',$file); - } - $files[$key]['file'] = $file; - } - - return $files; - } - } -?> +cache_path)) { + FileHandler::makeDir($this->cache_path); + } + } + + /** + * @brief file that removes 'optimized' in a given array + * @param[in] $files an array to be modified + **/ + function _getOptimizedRemoved($files) { + foreach($files as $key => $val) unset($files[$key]['optimized']); + return $files; + } + + /** + * @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") { + if(!is_array($source_files) || !count($source_files)) return; + + // 관리자 설정시 설정이 되어 있지 않으면 패스 + // 캐시 디렉토리가 없으면 실행하지 않음 + $db_info = Context::getDBInfo(); + if($db_info->use_optimizer == 'N' || !is_dir($this->cache_path)) return $this->_getOptimizedRemoved($source_files); + + if(!count($source_files)) return; + + $files = array(); + $hash = ""; + foreach($source_files as $key => $file) { + if($file['file'][0] == '/'){ + if(!file_exists($file['file'])){ + if(file_exists($_SERVER['DOCUMENT_ROOT'] . $file['file'])){ + if($file['optimized']) $source_files[$key]['file'] = $file['file'] = $_SERVER['DOCUMENT_ROOT'].$file['file']; + }else{ + continue; + } + } + } else if(!$file || !$file['file'] || !file_exists($file['file'])) continue; + $file['file'] = $source_files[$key]['file'] = str_replace("\\","/",$file['file']); + if(empty($file['optimized']) || preg_match('/^https?:\/\//i', $file['file']) ) $files[] = $file; + else{ + $targets[] = $file; + $hash .= $file['file']; + } + } + if(!count($targets)) return $this->_getOptimizedRemoved($files); + $list_file_hash = md5($hash); + $oCacheHandler = &CacheHandler::getInstance('template'); + if($oCacheHandler->isSupport()){ + if(!$oCacheHandler->isValid($list_file_hash)){ + $buff = array(); + foreach($targets as $file) $buff[] = $file['file']; + $oCacheHandler->put($list_file_hash, $buff); + } + }else{ + $list_file = FileHandler::getRealPath($this->cache_path . $list_file_hash . '.info.php'); + + if(!file_exists($list_file)){ + $str = ''; + + FileHandler::writeFile($list_file, $str); + } + } + + array_unshift($files, array('file' => sprintf($this->script_file, $list_file_hash, $type) , 'media' => 'all')); + $files = $this->_getOptimizedRemoved($files); + if(!count($files)) return $files; + + $url_info = parse_url(Context::getRequestUri()); + $abpath = $url_info['path']; + foreach($files as $key => $val) { + $file = $val['file']; + + if($file{0} == '/' || strpos($file,'://')!==false) continue; + if(substr($file,0,2)=='./') $file = substr($file,2); + $file = $abpath.$file; + while(strpos($file,'/../')!==false) { + $file = preg_replace('/\/([^\/]+)\/\.\.\//','/',$file); + } + $files[$key]['file'] = $file; + } + + return $files; + } + } +?> diff --git a/classes/page/PageHandler.class.php b/classes/page/PageHandler.class.php index 3620e1ef1..6e0beba92 100644 --- a/classes/page/PageHandler.class.php +++ b/classes/page/PageHandler.class.php @@ -1,57 +1,57 @@ -total_count = $total_count; - $this->total_page = $total_page; - $this->cur_page = $cur_page; - $this->page_count = $page_count; - $this->point = 0; - - $first_page = $cur_page - (int)($page_count/2); - if($first_page<1) $first_page = 1; - $last_page = $total_page; - if($last_page>$total_page) $last_page = $total_page; - - $this->first_page = $first_page; - $this->last_page = $last_page; - - if($total_page < $this->page_count) $this->page_count = $total_page; - } - - /** - * @brief request next page - * @return next page number - **/ - function getNextPage() { - $page = $this->first_page+$this->point++; - if($this->point > $this->page_count || $page > $this->last_page) $page = 0; - return $page; - } - } -?> +total_count = $total_count; + $this->total_page = $total_page; + $this->cur_page = $cur_page; + $this->page_count = $page_count; + $this->point = 0; + + $first_page = $cur_page - (int)($page_count/2); + if($first_page<1) $first_page = 1; + $last_page = $total_page; + if($last_page>$total_page) $last_page = $total_page; + + $this->first_page = $first_page; + $this->last_page = $last_page; + + if($total_page < $this->page_count) $this->page_count = $total_page; + } + + /** + * @brief request next page + * @return next page number + **/ + function getNextPage() { + $page = $this->first_page+$this->point++; + if($this->point > $this->page_count || $page > $this->last_page) $page = 0; + return $page; + } + } +?> diff --git a/classes/template/TemplateHandler.class.php b/classes/template/TemplateHandler.class.php index 51f8a678c..86c00ae83 100644 --- a/classes/template/TemplateHandler.class.php +++ b/classes/template/TemplateHandler.class.php @@ -1,535 +1,535 @@ -tpl_path = preg_replace('/^\.\//','',$tpl_path); - $this->tpl_file = $tpl_file; - - $oCacheHandler = &CacheHandler::getInstance('template'); - if($oCacheHandler->isSupport()){ - $cache_key = 'template:' . $tpl_file; - $buff = $oCacheHandler->get($cache_key, filemtime(FileHandler::getRealPath($tpl_file))); - if(!$buff){ - $buff = $this->_compileTplFile($tpl_file); - $oCacheHandler->put($cache_key, $buff); - } - - $output = $this->_fetch('', $buff, $tpl_path); - }else{ - // get cached compiled file name - $compiled_tpl_file = FileHandler::getRealPath($this->_getCompiledFileName($tpl_file)); - - // compile - $buff = $this->_compile($tpl_file, $compiled_tpl_file); - - // make a result, combining Context and compiled_tpl_file - $output = $this->_fetch($compiled_tpl_file, $buff, $tpl_path); - } - - if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start; - - return $output; - } - - /** - * @brief compile specified file and immediately return - * @param[in] $tpl_path path of the directory containing target template file - * @param[in] $tpl_filename target template file's name - * @return Returns compiled content in case of success or NULL in case of failure - **/ - function compileDirect($tpl_path, $tpl_filename) { - $this->tpl_path = $tpl_path; - $this->tpl_file = $tpl_file; - - $tpl_file = $tpl_path.$tpl_filename; - if(!file_exists($tpl_file)) return; - - return $this->_compileTplFile($tpl_file); - } - - /** - * @brief compile a template file only if a cached template file does not exist or it is outdated. - * @param[in] $tpl_path a file path of the target template file - * @param[in] $compiled_tpl_file a file path of cached template file - * @return Returns compiled template file if cached one does not exists or it is outdated, NULL otherwise - **/ - function _compile($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)); - $target_ftime = filemtime($compiled_tpl_file); - if($source_ftime>$target_ftime) return $this->_compileTplFile($tpl_file, $compiled_tpl_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] $compiled_tpl_file if specified, write compiled result into the file - * @return compiled result in case of success or NULL in case of error - **/ - function _compileTplFile($tpl_file, $compiled_tpl_file = '') { - - // read tpl file - $buff = FileHandler::readFile($tpl_file); - if(!$buff) return; - - // replace include - $buff = preg_replace_callback('!<\!--#include\(([^\)]*?)\)-->!is', array($this, '_compileIncludeToCode'), $buff); - - // if value of src in img/input tag starts with ./ or with filename replace the path - $buff = preg_replace_callback('/<(img|input)([^>]*)src=[\'"]{1}(.*?)[\'"]{1}/is', array($this, '_compileImgPath'), $buff); - - // replace variables - $buff = preg_replace_callback('/\{[^@^ ]([^\{\}\n]+)\}/i', array($this, '_compileVarToContext'), $buff); - - // replace parts not displaying results - $buff = preg_replace_callback('/\{\@([^\{\}]+)\}/i', array($this, '_compileVarToSilenceExecute'), $buff); - - // replace - $buff = preg_replace_callback('!<\!--@(.*?)-->!is', array($this, '_compileFuncToCode'), $buff); - - // remove comments - $buff = preg_replace('!(\n?)( *?)<\!--//(.*?)-->!is', '', $buff); - - // import xml filter/ css/ js/ files (media is applied to only css) - $buff = preg_replace_callback('!<\!--%import\(\"([^\"]*?)\"(,optimized\=(true|false))?(,media\=\"([^\"]*)\")?(,targetie=\"([^\"]*)\")?\)-->!is', array($this, '_compileImportCode'), $buff); - - // unload css/ js (media is applied to only css) - $buff = preg_replace_callback('!<\!--%unload\(\"([^\"]*?)\"(,optimized\=(true|false))?(,media\=\"([^\"]*)\")?(,targetie=\"([^\"]*)\")?\)-->!is', array($this, '_compileUnloadCode'), $buff); - - // javascript plugin import - $buff = preg_replace_callback('!<\!--%load_js_plugin\(\"([^\"]*?)\"\)-->!is', array($this, '_compileLoadJavascriptPlugin'), $buff); - - // prevent from calling directly before writing into file - $buff = sprintf('%s%s%s','',"\n",$buff); - - // write compiled code into file only if $compiled_tpl_file is not NULL - if($compiled_tpl_file) FileHandler::writeFile($compiled_tpl_file, $buff); - - return $buff; - } - - /** - * @brief replace $... variables in { } with Context::get(...) - * @param[in] $matches match - * @return replaced result in case of success or NULL in case of error - **/ - function _compileVarToContext($matches) { - $str = trim(substr($matches[0],1,strlen($matches[0])-2)); - if(!$str) return $matches[0]; - if(!in_array(substr($str,0,1),array('(','$','\'','"'))) { - if(preg_match('/^([^\( \.]+)(\(| \.)/i',$str,$m)) { - $func = trim($m[1]); - if(strpos($func,'::')===false) { - if(!function_exists($func)) { - return $matches[0]; - } - } else { - 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))) { - // In some environment, the name of classes and methods may be case-sensitive - list($class, $method) = explode('::',strtolower($func)); - if(!class_exists($class) || !in_array($method, get_class_methods($class))) { - return $matches[0]; - } - } - } - } else { - if(!defined($str)) return $matches[0]; - } - } - return ']+)/i','$__Context->\\1', $str).');?>'; - } - - /** - * @brief change image path - * @pre $matches is an array containg three elements - * @param[in] $matches match - * @return changed result - **/ - function _compileImgPath($matches) { - static $real_path = null; - $str1 = $matches[0]; - $str2 = $path = trim($matches[3]); - - if(substr($path,0,1)=='/' || substr($path,0,1)=='{' || strpos($path,'://')!==false) return $str1; - if(substr($path,0,2)=='./') $path = substr($path,2); - - if(is_null($real_path)) { - $url = parse_url(Context::getRequestUri()); - $real_path = $url['path']; - } - - $target = $real_path.$this->tpl_path.$path; - while(strpos($target,'/../')!==false) { - $target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target); - } - return str_replace($str2, $target, $str1); - } - - /** - * @brief replace @... function in { } into print func(..) - * @param[in] $matches match - * @return replaced result - **/ - function _compileVarToSilenceExecute($matches) { - if(strtolower(trim(str_replace(array(';',' '),'', $matches[1])))=='return') return ''; - return ']+)/i','$__Context->\\1', trim($matches[1])).';?>'; - } - - /** - * @brief replace code in with php code - * @param[in] $matches match - * @return changed result - **/ - function _compileFuncToCode($matches) { - static $idx = 0; - $code = trim($matches[1]); - if(!$code) return; - - switch(strtolower($code)) { - case 'else' : - $output = '}else{'; - break; - case 'end' : - case 'endif' : - case 'endfor' : - case 'endforeach' : - case 'endswitch' : - $output = '}'; - break; - case 'break' : - $output = 'break;'; - break; - case 'default' : - $output = 'default :'; - break; - case 'break@default' : - $output = 'break; default :'; - break; - default : - $suffix = '{'; - - if(substr($code, 0, 4) == 'else') { - $code = '}'.$code; - } elseif(substr($code, 0, 7) == 'foreach') { - $tmp_str = substr($code, 8); - $tmp_arr = explode(' ', $tmp_str); - $var_name = $tmp_arr[0]; - $prefix = '$Context->__idx['.$idx.']=0;'; - if(substr($var_name, 0, 1) == '$') { - $prefix .= sprintf('if(count($__Context->%s)) ', substr($var_name, 1)); - } else { - $prefix .= sprintf('if(count(%s)) ', $var_name); - } - $idx++; - $suffix .= '$__idx['.$idx.']=($__idx['.$idx.']+1)%2; $cycle_idx = $__idx['.$idx.']+1;'; - } elseif(substr($code, 0, 4) == 'case') { - $suffix = ':'; - } elseif(substr($code, 0, 10) == 'break@case') { - $code = 'break; case'.substr($code, 10); - $suffix = ':'; - } - $output = preg_replace('/\$([a-zA-Z0-9\_\-]+)/i', '$__Context->\\1', $code.$suffix); - break; - } - - return sprintf('', $prefix, $output); - } - - /** - * @brief replace with php code - * @param[in] $matches match - * @return replaced result - **/ - function _compileIncludeToCode($matches) { - // if target string to include contains variables handle them - $arg = str_replace(array('"','\''), '', $matches[1]); - if(!$arg) return; - - $tmp_arr = explode("/", $arg); - for($i=0;$itpl_file), $arg); - - // step2: check path from root - if(!file_exists($source_filename)) $source_filename = './'.$arg; - if(!file_exists($source_filename)) return; - - // split into path and filename - $tmp_arr = explode('/', $source_filename); - $filename = array_pop($tmp_arr); - $path = implode('/', $tmp_arr).'/'; - - // try to include - $output = sprintf( - 'compile(\'%s\',\'%s\');%s'. - '?>%s', - - "\n", - - "\n", - - $path, $filename, "\n", - - "\n" - ); - - return $output; - } - - /** - * @brief replace xe specific code, "" with appropriate php code - * @param[in] $matches match - * @return Returns modified result or NULL in case of error - **/ - function _compileImportCode($matches) { - // find xml file - $base_path = $this->tpl_path; - $given_file = trim($matches[1]); - if(!$given_file) return; - if(isset($matches[3])) $optimized = strtolower(trim($matches[3])); - if(!$optimized) $optimized = 'true'; - if(isset($matches[5])) $media = trim($matches[5]); - if(!$media) $media = 'all'; - if(isset($matches[7])) $targetie = trim($matches[7]); - if(!$targetie) $targetie = ''; - else $optimized = 'false'; - - // if given_file ends with lang, load language pack - if(substr($given_file, -4)=='lang') { - if(substr($given_file,0,2)=='./') $given_file = substr($given_file, 2); - $lang_dir = sprintf('%s%s', $this->tpl_path, $given_file); - if(is_dir($lang_dir)) $output = sprintf('', $lang_dir); - - // otherwise try to load xml, css, js file - } else { - if(substr($given_file,0,1)!='/') $source_filename = sprintf("%s%s",$base_path, $given_file); - else $source_filename = $given_file; - - // get filename and path - $tmp_arr = explode("/",$source_filename); - $filename = array_pop($tmp_arr); - - $base_path = implode("/",$tmp_arr)."/"; - - // get the ext - $tmp_arr = explode(".",$filename); - $ext = strtolower(array_pop($tmp_arr)); - - // according to ext., import the file - switch($ext) { - // xml js filter - case 'xml' : - // create an instance of XmlJSFilter class, then create js and handle Context::addJsFile - $output = sprintf( - 'compile();%s'. - '?>%s', - "\n", - "\n", - $base_path, - $filename, - "\n", - "\n", - "\n" - ); - break; - // css file - case 'css' : - if(preg_match('/^(http|\/)/i',$source_filename)) { - $output = sprintf('', $source_filename, 'false', $media, $targetie); - } else { - $meta_file = sprintf('%s%s', $base_path, $filename); - $output = sprintf('', $base_path, $filename, $optimized, $media, $targetie); - } - break; - // js file - case 'js' : - if(preg_match('/^(http|\/)/i',$source_filename)) { - $output = sprintf('', $source_filename, 'false', $targetie); - } else { - $meta_file = sprintf('%s%s', $base_path, $filename); - $output = sprintf('', $base_path, $filename, $optimized, $targetie); - } - break; - } - } - - if($meta_file) $output = ''.$output; - return $output; - } - - /** - * @brief import javascript plugin - * @param[in] $matches match - * @return result loading the plugin - * @remarks javascript plugin works as optimized = false - **/ - function _compileLoadJavascriptPlugin($matches) { - $base_path = $this->tpl_path; - $plugin = trim($matches[1]); - return sprintf('', $plugin); - } - - /** - * @brief remove loading part of css/ js file - * @param[in] $matches match - * @return removed result - **/ - function _compileUnloadCode($matches) { - // find xml file - $base_path = $this->tpl_path; - $given_file = trim($matches[1]); - if(!$given_file) return; - if(isset($matches[3])) $optimized = strtolower(trim($matches[3])); - if(!$optimized) $optimized = 'true'; - if(isset($matches[5])) $media = trim($matches[5]); - if(!$media) $media = 'all'; - if(isset($matches[7])) $targetie = trim($matches[7]); - if(!$targetie) $targetie = ''; - else $optimized = 'false'; - - if(substr($given_file,0,1)!='/') $source_filename = sprintf("%s%s",$base_path, $given_file); - else $source_filename = $given_file; - - // get path and file nam - $tmp_arr = explode("/",$source_filename); - $filename = array_pop($tmp_arr); - - $base_path = implode("/",$tmp_arr)."/"; - - // get an ext. - $tmp_arr = explode(".",$filename); - $ext = strtolower(array_pop($tmp_arr)); - - switch($ext) { - // css file - case 'css' : - if(preg_match('/^(http|\/)/i',$source_filename)) { - $output = sprintf('', $source_filename, 'false', $media, $targetie); - } else { - $meta_file = sprintf('%s%s', $base_path, $filename); - $output = sprintf('', $base_path, $filename, $optimized, $media, $targetie); - } - break; - // js file - case 'js' : - if(preg_match('/^(http|\/)/i',$source_filename)) { - $output = sprintf('', $source_filename, 'false', $targetie); - } else { - $meta_file = sprintf('%s%s', $base_path, $filename); - $output = sprintf('', $base_path, $filename, $optimized, $targetie); - } - break; - } - - return $output; - } - - /** - * @brief return compiled_tpl_file's name accroding to template file name - * @param[in] $tpl_file template file name - * @return compiled template file's name - **/ - function _getCompiledFileName($tpl_file) { - return sprintf('%s%s.compiled.php',$this->compiled_path, md5($tpl_file)); - } - - /** - * @brief fetch using ob_* function - * @param[in] $compiled_tpl_file path of compiled template file - * @param[in] $buff if buff is not null, eval it instead of including compiled template file - * @param[in] $tpl_path set context's tpl path - * @return result string - **/ - function _fetch($compiled_tpl_file, $buff = NULL, $tpl_path = '') { - $__Context = &$GLOBALS['__Context__']; - $__Context->tpl_path = $tpl_path; - - if($_SESSION['is_logged']) $__Context->logged_info = $_SESSION['logged_info']; - - ob_start(); - - if($buff) { - $eval_str = "?>".$buff; - eval($eval_str); - } else { - include($compiled_tpl_file); - } - - return ob_get_clean(); - } - } -?> +tpl_path = preg_replace('/^\.\//','',$tpl_path); + $this->tpl_file = $tpl_file; + + $oCacheHandler = &CacheHandler::getInstance('template'); + if($oCacheHandler->isSupport()){ + $cache_key = 'template:' . $tpl_file; + $buff = $oCacheHandler->get($cache_key, filemtime(FileHandler::getRealPath($tpl_file))); + if(!$buff){ + $buff = $this->_compileTplFile($tpl_file); + $oCacheHandler->put($cache_key, $buff); + } + + $output = $this->_fetch('', $buff, $tpl_path); + }else{ + // get cached compiled file name + $compiled_tpl_file = FileHandler::getRealPath($this->_getCompiledFileName($tpl_file)); + + // compile + $buff = $this->_compile($tpl_file, $compiled_tpl_file); + + // make a result, combining Context and compiled_tpl_file + $output = $this->_fetch($compiled_tpl_file, $buff, $tpl_path); + } + + if(__DEBUG__==3 ) $GLOBALS['__template_elapsed__'] += getMicroTime() - $start; + + return $output; + } + + /** + * @brief compile specified file and immediately return + * @param[in] $tpl_path path of the directory containing target template file + * @param[in] $tpl_filename target template file's name + * @return Returns compiled content in case of success or NULL in case of failure + **/ + function compileDirect($tpl_path, $tpl_filename) { + $this->tpl_path = $tpl_path; + $this->tpl_file = $tpl_file; + + $tpl_file = $tpl_path.$tpl_filename; + if(!file_exists($tpl_file)) return; + + return $this->_compileTplFile($tpl_file); + } + + /** + * @brief compile a template file only if a cached template file does not exist or it is outdated. + * @param[in] $tpl_path a file path of the target template file + * @param[in] $compiled_tpl_file a file path of cached template file + * @return Returns compiled template file if cached one does not exists or it is outdated, NULL otherwise + **/ + function _compile($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)); + $target_ftime = filemtime($compiled_tpl_file); + if($source_ftime>$target_ftime) return $this->_compileTplFile($tpl_file, $compiled_tpl_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] $compiled_tpl_file if specified, write compiled result into the file + * @return compiled result in case of success or NULL in case of error + **/ + function _compileTplFile($tpl_file, $compiled_tpl_file = '') { + + // read tpl file + $buff = FileHandler::readFile($tpl_file); + if(!$buff) return; + + // replace include + $buff = preg_replace_callback('!<\!--#include\(([^\)]*?)\)-->!is', array($this, '_compileIncludeToCode'), $buff); + + // if value of src in img/input tag starts with ./ or with filename replace the path + $buff = preg_replace_callback('/<(img|input)([^>]*)src=[\'"]{1}(.*?)[\'"]{1}/is', array($this, '_compileImgPath'), $buff); + + // replace variables + $buff = preg_replace_callback('/\{[^@^ ]([^\{\}\n]+)\}/i', array($this, '_compileVarToContext'), $buff); + + // replace parts not displaying results + $buff = preg_replace_callback('/\{\@([^\{\}]+)\}/i', array($this, '_compileVarToSilenceExecute'), $buff); + + // replace + $buff = preg_replace_callback('!<\!--@(.*?)-->!is', array($this, '_compileFuncToCode'), $buff); + + // remove comments + $buff = preg_replace('!(\n?)( *?)<\!--//(.*?)-->!is', '', $buff); + + // import xml filter/ css/ js/ files (media is applied to only css) + $buff = preg_replace_callback('!<\!--%import\(\"([^\"]*?)\"(,optimized\=(true|false))?(,media\=\"([^\"]*)\")?(,targetie=\"([^\"]*)\")?\)-->!is', array($this, '_compileImportCode'), $buff); + + // unload css/ js (media is applied to only css) + $buff = preg_replace_callback('!<\!--%unload\(\"([^\"]*?)\"(,optimized\=(true|false))?(,media\=\"([^\"]*)\")?(,targetie=\"([^\"]*)\")?\)-->!is', array($this, '_compileUnloadCode'), $buff); + + // javascript plugin import + $buff = preg_replace_callback('!<\!--%load_js_plugin\(\"([^\"]*?)\"\)-->!is', array($this, '_compileLoadJavascriptPlugin'), $buff); + + // prevent from calling directly before writing into file + $buff = sprintf('%s%s%s','',"\n",$buff); + + // write compiled code into file only if $compiled_tpl_file is not NULL + if($compiled_tpl_file) FileHandler::writeFile($compiled_tpl_file, $buff); + + return $buff; + } + + /** + * @brief replace $... variables in { } with Context::get(...) + * @param[in] $matches match + * @return replaced result in case of success or NULL in case of error + **/ + function _compileVarToContext($matches) { + $str = trim(substr($matches[0],1,strlen($matches[0])-2)); + if(!$str) return $matches[0]; + if(!in_array(substr($str,0,1),array('(','$','\'','"'))) { + if(preg_match('/^([^\( \.]+)(\(| \.)/i',$str,$m)) { + $func = trim($m[1]); + if(strpos($func,'::')===false) { + if(!function_exists($func)) { + return $matches[0]; + } + } else { + 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))) { + // In some environment, the name of classes and methods may be case-sensitive + list($class, $method) = explode('::',strtolower($func)); + if(!class_exists($class) || !in_array($method, get_class_methods($class))) { + return $matches[0]; + } + } + } + } else { + if(!defined($str)) return $matches[0]; + } + } + return ']+)/i','$__Context->\\1', $str).');?>'; + } + + /** + * @brief change image path + * @pre $matches is an array containg three elements + * @param[in] $matches match + * @return changed result + **/ + function _compileImgPath($matches) { + static $real_path = null; + $str1 = $matches[0]; + $str2 = $path = trim($matches[3]); + + if(substr($path,0,1)=='/' || substr($path,0,1)=='{' || strpos($path,'://')!==false) return $str1; + if(substr($path,0,2)=='./') $path = substr($path,2); + + if(is_null($real_path)) { + $url = parse_url(Context::getRequestUri()); + $real_path = $url['path']; + } + + $target = $real_path.$this->tpl_path.$path; + while(strpos($target,'/../')!==false) { + $target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target); + } + return str_replace($str2, $target, $str1); + } + + /** + * @brief replace @... function in { } into print func(..) + * @param[in] $matches match + * @return replaced result + **/ + function _compileVarToSilenceExecute($matches) { + if(strtolower(trim(str_replace(array(';',' '),'', $matches[1])))=='return') return ''; + return ']+)/i','$__Context->\\1', trim($matches[1])).';?>'; + } + + /** + * @brief replace code in with php code + * @param[in] $matches match + * @return changed result + **/ + function _compileFuncToCode($matches) { + static $idx = 0; + $code = trim($matches[1]); + if(!$code) return; + + switch(strtolower($code)) { + case 'else' : + $output = '}else{'; + break; + case 'end' : + case 'endif' : + case 'endfor' : + case 'endforeach' : + case 'endswitch' : + $output = '}'; + break; + case 'break' : + $output = 'break;'; + break; + case 'default' : + $output = 'default :'; + break; + case 'break@default' : + $output = 'break; default :'; + break; + default : + $suffix = '{'; + + if(substr($code, 0, 4) == 'else') { + $code = '}'.$code; + } elseif(substr($code, 0, 7) == 'foreach') { + $tmp_str = substr($code, 8); + $tmp_arr = explode(' ', $tmp_str); + $var_name = $tmp_arr[0]; + $prefix = '$Context->__idx['.$idx.']=0;'; + if(substr($var_name, 0, 1) == '$') { + $prefix .= sprintf('if(count($__Context->%s)) ', substr($var_name, 1)); + } else { + $prefix .= sprintf('if(count(%s)) ', $var_name); + } + $idx++; + $suffix .= '$__idx['.$idx.']=($__idx['.$idx.']+1)%2; $cycle_idx = $__idx['.$idx.']+1;'; + } elseif(substr($code, 0, 4) == 'case') { + $suffix = ':'; + } elseif(substr($code, 0, 10) == 'break@case') { + $code = 'break; case'.substr($code, 10); + $suffix = ':'; + } + $output = preg_replace('/\$([a-zA-Z0-9\_\-]+)/i', '$__Context->\\1', $code.$suffix); + break; + } + + return sprintf('', $prefix, $output); + } + + /** + * @brief replace with php code + * @param[in] $matches match + * @return replaced result + **/ + function _compileIncludeToCode($matches) { + // if target string to include contains variables handle them + $arg = str_replace(array('"','\''), '', $matches[1]); + if(!$arg) return; + + $tmp_arr = explode("/", $arg); + for($i=0;$itpl_file), $arg); + + // step2: check path from root + if(!file_exists($source_filename)) $source_filename = './'.$arg; + if(!file_exists($source_filename)) return; + + // split into path and filename + $tmp_arr = explode('/', $source_filename); + $filename = array_pop($tmp_arr); + $path = implode('/', $tmp_arr).'/'; + + // try to include + $output = sprintf( + 'compile(\'%s\',\'%s\');%s'. + '?>%s', + + "\n", + + "\n", + + $path, $filename, "\n", + + "\n" + ); + + return $output; + } + + /** + * @brief replace xe specific code, "" with appropriate php code + * @param[in] $matches match + * @return Returns modified result or NULL in case of error + **/ + function _compileImportCode($matches) { + // find xml file + $base_path = $this->tpl_path; + $given_file = trim($matches[1]); + if(!$given_file) return; + if(isset($matches[3])) $optimized = strtolower(trim($matches[3])); + if(!$optimized) $optimized = 'true'; + if(isset($matches[5])) $media = trim($matches[5]); + if(!$media) $media = 'all'; + if(isset($matches[7])) $targetie = trim($matches[7]); + if(!$targetie) $targetie = ''; + else $optimized = 'false'; + + // if given_file ends with lang, load language pack + if(substr($given_file, -4)=='lang') { + if(substr($given_file,0,2)=='./') $given_file = substr($given_file, 2); + $lang_dir = sprintf('%s%s', $this->tpl_path, $given_file); + if(is_dir($lang_dir)) $output = sprintf('', $lang_dir); + + // otherwise try to load xml, css, js file + } else { + if(substr($given_file,0,1)!='/') $source_filename = sprintf("%s%s",$base_path, $given_file); + else $source_filename = $given_file; + + // get filename and path + $tmp_arr = explode("/",$source_filename); + $filename = array_pop($tmp_arr); + + $base_path = implode("/",$tmp_arr)."/"; + + // get the ext + $tmp_arr = explode(".",$filename); + $ext = strtolower(array_pop($tmp_arr)); + + // according to ext., import the file + switch($ext) { + // xml js filter + case 'xml' : + // create an instance of XmlJSFilter class, then create js and handle Context::addJsFile + $output = sprintf( + 'compile();%s'. + '?>%s', + "\n", + "\n", + $base_path, + $filename, + "\n", + "\n", + "\n" + ); + break; + // css file + case 'css' : + if(preg_match('/^(http|\/)/i',$source_filename)) { + $output = sprintf('', $source_filename, 'false', $media, $targetie); + } else { + $meta_file = sprintf('%s%s', $base_path, $filename); + $output = sprintf('', $base_path, $filename, $optimized, $media, $targetie); + } + break; + // js file + case 'js' : + if(preg_match('/^(http|\/)/i',$source_filename)) { + $output = sprintf('', $source_filename, 'false', $targetie); + } else { + $meta_file = sprintf('%s%s', $base_path, $filename); + $output = sprintf('', $base_path, $filename, $optimized, $targetie); + } + break; + } + } + + if($meta_file) $output = ''.$output; + return $output; + } + + /** + * @brief import javascript plugin + * @param[in] $matches match + * @return result loading the plugin + * @remarks javascript plugin works as optimized = false + **/ + function _compileLoadJavascriptPlugin($matches) { + $base_path = $this->tpl_path; + $plugin = trim($matches[1]); + return sprintf('', $plugin); + } + + /** + * @brief remove loading part of css/ js file + * @param[in] $matches match + * @return removed result + **/ + function _compileUnloadCode($matches) { + // find xml file + $base_path = $this->tpl_path; + $given_file = trim($matches[1]); + if(!$given_file) return; + if(isset($matches[3])) $optimized = strtolower(trim($matches[3])); + if(!$optimized) $optimized = 'true'; + if(isset($matches[5])) $media = trim($matches[5]); + if(!$media) $media = 'all'; + if(isset($matches[7])) $targetie = trim($matches[7]); + if(!$targetie) $targetie = ''; + else $optimized = 'false'; + + if(substr($given_file,0,1)!='/') $source_filename = sprintf("%s%s",$base_path, $given_file); + else $source_filename = $given_file; + + // get path and file nam + $tmp_arr = explode("/",$source_filename); + $filename = array_pop($tmp_arr); + + $base_path = implode("/",$tmp_arr)."/"; + + // get an ext. + $tmp_arr = explode(".",$filename); + $ext = strtolower(array_pop($tmp_arr)); + + switch($ext) { + // css file + case 'css' : + if(preg_match('/^(http|\/)/i',$source_filename)) { + $output = sprintf('', $source_filename, 'false', $media, $targetie); + } else { + $meta_file = sprintf('%s%s', $base_path, $filename); + $output = sprintf('', $base_path, $filename, $optimized, $media, $targetie); + } + break; + // js file + case 'js' : + if(preg_match('/^(http|\/)/i',$source_filename)) { + $output = sprintf('', $source_filename, 'false', $targetie); + } else { + $meta_file = sprintf('%s%s', $base_path, $filename); + $output = sprintf('', $base_path, $filename, $optimized, $targetie); + } + break; + } + + return $output; + } + + /** + * @brief return compiled_tpl_file's name accroding to template file name + * @param[in] $tpl_file template file name + * @return compiled template file's name + **/ + function _getCompiledFileName($tpl_file) { + return sprintf('%s%s.compiled.php',$this->compiled_path, md5($tpl_file)); + } + + /** + * @brief fetch using ob_* function + * @param[in] $compiled_tpl_file path of compiled template file + * @param[in] $buff if buff is not null, eval it instead of including compiled template file + * @param[in] $tpl_path set context's tpl path + * @return result string + **/ + function _fetch($compiled_tpl_file, $buff = NULL, $tpl_path = '') { + $__Context = &$GLOBALS['__Context__']; + $__Context->tpl_path = $tpl_path; + + if($_SESSION['is_logged']) $__Context->logged_info = $_SESSION['logged_info']; + + ob_start(); + + if($buff) { + $eval_str = "?>".$buff; + eval($eval_str); + } else { + include($compiled_tpl_file); + } + + return ob_get_clean(); + } + } +?> diff --git a/classes/widget/WidgetHandler.class.php b/classes/widget/WidgetHandler.class.php index 6c6230e37..c35e4a188 100644 --- a/classes/widget/WidgetHandler.class.php +++ b/classes/widget/WidgetHandler.class.php @@ -1,14 +1,14 @@ - + diff --git a/classes/xml/GeneralXmlParser.class.php b/classes/xml/GeneralXmlParser.class.php index 2b4db9e88..18b938ab0 100644 --- a/classes/xml/GeneralXmlParser.class.php +++ b/classes/xml/GeneralXmlParser.class.php @@ -1,83 +1,83 @@ -output)) return; - $this->output = array_shift($this->output); - - return $this->output; - } - - /** - * @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) { - $obj->node_name = strtolower($node_name); - $obj->attrs = $attrs; - $obj->childNodes = array(); - - 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) { - //if(!trim($body)) return; - $this->output[count($this->output)-1]->body .= $body; - } - - - /** - * @brief end element handler - * @param[in] $parse an instance of parser - * @param[in] $node_name name of xml node - */ - function _tagClosed($parser, $node_name) { - $node_name = strtolower($node_name); - $cur_obj = array_pop($this->output); - $parent_obj = &$this->output[count($this->output)-1]; - - if($parent_obj->childNodes[$node_name]) - { - $tmp_obj = $parent_obj->childNodes[$node_name]; - if(is_array($tmp_obj)) { - array_push($parent_obj->childNodes[$node_name], $cur_obj); - } else { - $parent_obj->childNodes[$node_name] = array(); - 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; - } - } - - } -?> +output)) return; + $this->output = array_shift($this->output); + + return $this->output; + } + + /** + * @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) { + $obj->node_name = strtolower($node_name); + $obj->attrs = $attrs; + $obj->childNodes = array(); + + 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) { + //if(!trim($body)) return; + $this->output[count($this->output)-1]->body .= $body; + } + + + /** + * @brief end element handler + * @param[in] $parse an instance of parser + * @param[in] $node_name name of xml node + */ + function _tagClosed($parser, $node_name) { + $node_name = strtolower($node_name); + $cur_obj = array_pop($this->output); + $parent_obj = &$this->output[count($this->output)-1]; + + if($parent_obj->childNodes[$node_name]) + { + $tmp_obj = $parent_obj->childNodes[$node_name]; + if(is_array($tmp_obj)) { + array_push($parent_obj->childNodes[$node_name], $cur_obj); + } else { + $parent_obj->childNodes[$node_name] = array(); + 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; + } + } + + } +?> diff --git a/classes/xml/XmlJsFilter.class.php b/classes/xml/XmlJsFilter.class.php index c79240240..00dcfea0a 100644 --- a/classes/xml/XmlJsFilter.class.php +++ b/classes/xml/XmlJsFilter.class.php @@ -1,298 +1,298 @@ - - *
<-- code to validate data in the form - * - * - * <-- 폼 항목을 조합하여 key=val 의 js array로 return, act는 필수 - * - * - * <-- 서버에 ajax로 전송하여 받을 결과값 - * <-- error이름의 결과값을 받겠다는 것 - * - * - * } - * - * @detail { - * - syntax description of
node - * target = name of for element - * required = flag indicating whether a field is mandatory or not - * minlength, maxlength = mininum, maxinum length of string allowed for the field - * filter = name of filter to be used for javascript validation. Following is the description of filter available - * 1) email : validate the confirmance of the value against an email format - * 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) - * 3) alpha : check if the value is consists of alphabatic characters. - * 4) number : check if the value is consists of numerical digits - * 5) equalto = target : indicate that values in the form should be equal to those in target - * - * - parameter - param - * name = key : indicate that a new array, 'key' will be created and a value will be assigned to it - * target = target_name : target form element의 값을 가져옴 - * - * - response - * tag = key : name of variable that will contain the result of the execution - * } - **/ - - class XmlJsFilter extends XmlParser { - var $version = '0.2.4'; - var $compiled_path = './files/cache/js_filter_compiled/'; ///< 컴파일된 캐시 파일이 놓일 위치 - var $xml_file = NULL; ///< 대상 xml 파일 - var $js_file = NULL; ///< 컴파일된 js 파일 - - /** - * @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 compile() { - if(!file_exists($this->xml_file)) return; - 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); - } - - /** - * @brief compile a xml_file into js_file - **/ - function _compile() { - global $lang; - - // xml 파일을 읽음 - $buff = FileHandler::readFile($this->xml_file); - - // xml parsing - $xml_obj = parent::parse($buff); - - // XmlJsFilter는 filter_name, field, parameter 3개의 데이터를 핸들링 - $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; - - $field_node = $xml_obj->filter->form->node; - if($field_node && !is_array($field_node)) $field_node = array($field_node); - - $parameter_param = $xml_obj->filter->parameter->param; - if($parameter_param && !is_array($parameter_param)) $parameter_param = array($parameter_param); - - $response_tag = $xml_obj->filter->response->tag; - if($response_tag && !is_array($response_tag)) $response_tag = array($response_tag); - - // extend_filter가 있을 경우 해당 method를 호출하여 결과를 받음 - if($extend_filter) { - - // extend_filter가 있을 경우 캐시 사용을 못하도록 js 캐시 파일명을 변경 - $this->js_file .= '.nocache.js'; - - // extend_filter는 module.method 로 지칭되어 이를 분리 - list($module_name, $method) = explode('.',$extend_filter); - - // 모듈 이름과 method가 있을 경우 진행 - if($module_name&&$method) { - // 해당 module의 model 객체를 받음 - $oExtendFilter = &getModel($module_name); - - // method가 존재하면 실행 - if(method_exists($oExtendFilter, $method)) { - // 결과를 받음 - $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"; - - // 언어 입력을 위한 사용되는 필드 조사 - $target_list = array(); - $target_type_list = array(); - - // js function 을 만들기 시작 - $js_doc = 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('');"; - $js_doc[] = "\tfo_obj.elements['_filter'].value = '{$filter_name}';"; - - $jsdoc = array(); - $jsdoc[] = '(function($){'; - $jsdoc[] = "\tvar validator = xe.getApp('Validator')[0];"; - $jsdoc[] = "\tif(!validator) return false;"; - $jsdoc[] = "\tvalidator.cast('ADD_FILTER', ['{$filter_name}', {"; - - $fields = array(); - - // field, 즉 체크항목의 script 생성 - $node_count = count($field_node); - if($node_count) { - foreach($field_node as $key =>$node) { - $attrs = $node->attrs; - $target = trim($attrs->target); - if(!$target) continue; - $filter = $attrs->filter; - - $attrs->equalto = trim($attrs->equalto); - - $field = array(); - if($attrs->required == 'true') $field[] = 'required:true'; - if($attrs->minlength > 0) $field[] = 'minlength:'.$attrs->minlength; - if($attrs->maxlength > 0) $field[] = 'maxlength:'.$attrs->maxlength; - if($attrs->equalto) $field[] = "equalto:'{$attrs->equalto}'"; - if($attrs->filter) $field[] = "rule:'{$attrs->filter}'"; - $s_field = implode(',', $field); - $fields[] = "\t\t'{$target}': {{$s_field}}"; - - if(!in_array($target, $target_list)) $target_list[] = $target; - if(!$target_type_list[$target]) $target_type_list[$target] = $filter; - } - } - - // extend_filter_item 체크 - for($i=0;$i<$extend_filter_count;$i++) { - $filter_item = $extend_filter_list[$i]; - $target = trim($filter_item->name); - if(!$target) continue; - $type = $filter_item->type; - $required = $filter_item->required?'true':'false'; - - // extend filter item의 type으로 filter를 구함 - $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}}"; - - if(!in_array($target, $target_list)) $target_list[] = $target; - if(!$target_type_list[$target]) $target_type_list[$target] = $type; - } - - $jsdoc[] = implode(",\n", $fields); - $jsdoc[] = "\t}]);"; - - // javascript callback function - $js_doc[] = "\tvalidator.cast('ADD_CALLBACK', ['{$filter_name}', function(form){"; - $js_doc[] = "\t\tvar params={}, responses=[], elms=form.elements, data=jQuery(form).serializeArray();"; - $js_doc[] = "\t\tjQuery.each(data, function(i, field){"; - $js_doc[] = "\t\t\tvar val = jQuery.trim(field.value);"; - $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});"; - - // 데이터를 만들기 위한 parameter script 생성 - $parameter_count = count($parameter_param); - if($parameter_count) { - // 기본 필터 내용의 parameter로 구성 - foreach($parameter_param as $key =>$param) { - $attrs = $param->attrs; - $name = trim($attrs->name); - $target = trim($attrs->target); - - //if($name && $target && ($name != $target)) $js_doc[] = "\t\tparams['{$name}'] = params['{$target}']; delete params['{$target}'];"; - if($name && $target && ($name != $target)) $js_doc[] = "\t\tif(params['{$target}']) { params['{$name}'] = params['{$target}']; delete params['{$target}']; }"; - if($name && !in_array($name, $target_list)) $target_list[] = $name; - } - - // extend_filter_item 체크 - for($i=0;$i<$extend_filter_count;$i++) { - $filter_item = $extend_filter_list[$i]; - $target = $name = trim($filter_item->name); - if(!$name || !$target) continue; - - if(!in_array($name, $target_list)) $target_list[] = $name; - } - } - - // response script 생성 - $response_count = count($response_tag); - $responses = array(); - for($i=0;$i<$response_count;$i++) { - $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}); - - $js_doc[] = "\t\texec_xml('{$module}','{$act}', params, {$callback_func}, responses, params, form);"; - $js_doc[] = "\t}]);"; - - // form 필드 lang 값을 기록 - $target_count = count($target_list); - for($i=0;$i<$target_count;$i++) { - $target = $target_list[$i]; - 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()); - } - } -?> + + * <-- code to validate data in the form + * + * + * <-- 폼 항목을 조합하여 key=val 의 js array로 return, act는 필수 + * + * + * <-- 서버에 ajax로 전송하여 받을 결과값 + * <-- error이름의 결과값을 받겠다는 것 + * + * + * } + * + * @detail { + * - syntax description of
node + * target = name of for element + * required = flag indicating whether a field is mandatory or not + * minlength, maxlength = mininum, maxinum length of string allowed for the field + * filter = name of filter to be used for javascript validation. Following is the description of filter available + * 1) email : validate the confirmance of the value against an email format + * 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) + * 3) alpha : check if the value is consists of alphabatic characters. + * 4) number : check if the value is consists of numerical digits + * 5) equalto = target : indicate that values in the form should be equal to those in target + * + * - parameter - param + * name = key : indicate that a new array, 'key' will be created and a value will be assigned to it + * target = target_name : target form element의 값을 가져옴 + * + * - response + * tag = key : name of variable that will contain the result of the execution + * } + **/ + + class XmlJsFilter extends XmlParser { + var $version = '0.2.4'; + var $compiled_path = './files/cache/js_filter_compiled/'; ///< 컴파일된 캐시 파일이 놓일 위치 + var $xml_file = NULL; ///< 대상 xml 파일 + var $js_file = NULL; ///< 컴파일된 js 파일 + + /** + * @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 compile() { + if(!file_exists($this->xml_file)) return; + 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); + } + + /** + * @brief compile a xml_file into js_file + **/ + function _compile() { + global $lang; + + // xml 파일을 읽음 + $buff = FileHandler::readFile($this->xml_file); + + // xml parsing + $xml_obj = parent::parse($buff); + + // XmlJsFilter는 filter_name, field, parameter 3개의 데이터를 핸들링 + $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; + + $field_node = $xml_obj->filter->form->node; + if($field_node && !is_array($field_node)) $field_node = array($field_node); + + $parameter_param = $xml_obj->filter->parameter->param; + if($parameter_param && !is_array($parameter_param)) $parameter_param = array($parameter_param); + + $response_tag = $xml_obj->filter->response->tag; + if($response_tag && !is_array($response_tag)) $response_tag = array($response_tag); + + // extend_filter가 있을 경우 해당 method를 호출하여 결과를 받음 + if($extend_filter) { + + // extend_filter가 있을 경우 캐시 사용을 못하도록 js 캐시 파일명을 변경 + $this->js_file .= '.nocache.js'; + + // extend_filter는 module.method 로 지칭되어 이를 분리 + list($module_name, $method) = explode('.',$extend_filter); + + // 모듈 이름과 method가 있을 경우 진행 + if($module_name&&$method) { + // 해당 module의 model 객체를 받음 + $oExtendFilter = &getModel($module_name); + + // method가 존재하면 실행 + if(method_exists($oExtendFilter, $method)) { + // 결과를 받음 + $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"; + + // 언어 입력을 위한 사용되는 필드 조사 + $target_list = array(); + $target_type_list = array(); + + // js function 을 만들기 시작 + $js_doc = 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('');"; + $js_doc[] = "\tfo_obj.elements['_filter'].value = '{$filter_name}';"; + + $jsdoc = array(); + $jsdoc[] = '(function($){'; + $jsdoc[] = "\tvar validator = xe.getApp('Validator')[0];"; + $jsdoc[] = "\tif(!validator) return false;"; + $jsdoc[] = "\tvalidator.cast('ADD_FILTER', ['{$filter_name}', {"; + + $fields = array(); + + // field, 즉 체크항목의 script 생성 + $node_count = count($field_node); + if($node_count) { + foreach($field_node as $key =>$node) { + $attrs = $node->attrs; + $target = trim($attrs->target); + if(!$target) continue; + $filter = $attrs->filter; + + $attrs->equalto = trim($attrs->equalto); + + $field = array(); + if($attrs->required == 'true') $field[] = 'required:true'; + if($attrs->minlength > 0) $field[] = 'minlength:'.$attrs->minlength; + if($attrs->maxlength > 0) $field[] = 'maxlength:'.$attrs->maxlength; + if($attrs->equalto) $field[] = "equalto:'{$attrs->equalto}'"; + if($attrs->filter) $field[] = "rule:'{$attrs->filter}'"; + $s_field = implode(',', $field); + $fields[] = "\t\t'{$target}': {{$s_field}}"; + + if(!in_array($target, $target_list)) $target_list[] = $target; + if(!$target_type_list[$target]) $target_type_list[$target] = $filter; + } + } + + // extend_filter_item 체크 + for($i=0;$i<$extend_filter_count;$i++) { + $filter_item = $extend_filter_list[$i]; + $target = trim($filter_item->name); + if(!$target) continue; + $type = $filter_item->type; + $required = $filter_item->required?'true':'false'; + + // extend filter item의 type으로 filter를 구함 + $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}}"; + + if(!in_array($target, $target_list)) $target_list[] = $target; + if(!$target_type_list[$target]) $target_type_list[$target] = $type; + } + + $jsdoc[] = implode(",\n", $fields); + $jsdoc[] = "\t}]);"; + + // javascript callback function + $js_doc[] = "\tvalidator.cast('ADD_CALLBACK', ['{$filter_name}', function(form){"; + $js_doc[] = "\t\tvar params={}, responses=[], elms=form.elements, data=jQuery(form).serializeArray();"; + $js_doc[] = "\t\tjQuery.each(data, function(i, field){"; + $js_doc[] = "\t\t\tvar val = jQuery.trim(field.value);"; + $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});"; + + // 데이터를 만들기 위한 parameter script 생성 + $parameter_count = count($parameter_param); + if($parameter_count) { + // 기본 필터 내용의 parameter로 구성 + foreach($parameter_param as $key =>$param) { + $attrs = $param->attrs; + $name = trim($attrs->name); + $target = trim($attrs->target); + + //if($name && $target && ($name != $target)) $js_doc[] = "\t\tparams['{$name}'] = params['{$target}']; delete params['{$target}'];"; + if($name && $target && ($name != $target)) $js_doc[] = "\t\tif(params['{$target}']) { params['{$name}'] = params['{$target}']; delete params['{$target}']; }"; + if($name && !in_array($name, $target_list)) $target_list[] = $name; + } + + // extend_filter_item 체크 + for($i=0;$i<$extend_filter_count;$i++) { + $filter_item = $extend_filter_list[$i]; + $target = $name = trim($filter_item->name); + if(!$name || !$target) continue; + + if(!in_array($name, $target_list)) $target_list[] = $name; + } + } + + // response script 생성 + $response_count = count($response_tag); + $responses = array(); + for($i=0;$i<$response_count;$i++) { + $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}); + + $js_doc[] = "\t\texec_xml('{$module}','{$act}', params, {$callback_func}, responses, params, form);"; + $js_doc[] = "\t}]);"; + + // form 필드 lang 값을 기록 + $target_count = count($target_list); + for($i=0;$i<$target_count;$i++) { + $target = $target_list[$i]; + 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()); + } + } +?> diff --git a/classes/xml/XmlParser.class.php b/classes/xml/XmlParser.class.php index 3c7f78533..4e68a2abf 100644 --- a/classes/xml/XmlParser.class.php +++ b/classes/xml/XmlParser.class.php @@ -1,154 +1,154 @@ -parse($buff); - } - - /** - * @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 = '') { - // 디버그를 위한 컴파일 시작 시간 저장 - if(__DEBUG__==3) $start = getMicroTime(); - - $this->lang = Context::getLangType(); - - $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); - - // xml:lang이 쓰였을 경우 지원하는 언어종류를 뽑음 - if(count($matches[1]) && $supported_lang = array_unique($matches[1])) { - // supported_lang에 현재 접속자의 lang이 없으면 en이 있는지 확인하여 en이 있으면 en을 기본, 아니면 첫번째것을.. - if(!in_array($this->lang, $supported_lang)) { - if(in_array('en', $supported_lang)) { - $this->lang = 'en'; - } else { - $this->lang = array_shift($supported_lang); - } - } - // 특별한 언어가 지정되지 않았다면 언어체크를 하지 않음 - } else { - unset($this->lang); - } - - $this->oParser = xml_parser_create('UTF-8'); - - xml_set_object($this->oParser, $this); - xml_set_element_handler($this->oParser, "_tagOpen", "_tagClosed"); - xml_set_character_data_handler($this->oParser, "_tagBody"); - - xml_parse($this->oParser, $this->input); - xml_parser_free($this->oParser); - - if(!count($this->output)) return; - - $output = array_shift($this->output); - - // 디버그를 위한 컴파일 시작 시간 저장 - if(__DEBUG__==3) $GLOBALS['__xmlparse_elapsed__'] += getMicroTime() - $start; - - return $output; - } - - - /** - * @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) { - $obj->node_name = strtolower($node_name); - $obj->attrs = $this->_arrToObj($attrs); - - 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 - * @remark the first parameter, $parser ought to be remove since it is not used. - */ - function _tagBody($parser, $body) { - //if(!trim($body)) return; - $this->output[count($this->output)-1]->body .= $body; - } - - /** - * @brief end element handler - * @param[in] $parse an instance of parser - * @param[in] $node_name name of xml node - */ - function _tagClosed($parser, $node_name) { - $node_name = strtolower($node_name); - $cur_obj = array_pop($this->output); - $parent_obj = &$this->output[count($this->output)-1]; - if($this->lang&&$cur_obj->attrs->{'xml:lang'}&&$cur_obj->attrs->{'xml:lang'}!=$this->lang) return; - if($this->lang&&$parent_obj->{$node_name}->attrs->{'xml:lang'}&&$parent_obj->{$node_name}->attrs->{'xml:lang'}!=$this->lang) return; - - if($parent_obj->{$node_name}) { - $tmp_obj = $parent_obj->{$node_name}; - if(is_array($tmp_obj)) { - array_push($parent_obj->{$node_name}, $cur_obj); - } else { - $parent_obj->{$node_name} = array(); - array_push($parent_obj->{$node_name}, $tmp_obj); - array_push($parent_obj->{$node_name}, $cur_obj); - } - } else { - $parent_obj->{$node_name} = $cur_obj; - } - } - - /** - * @brief method to transfer values in an array to a data object - * @param[in] $arr data array - **/ - function _arrToObj($arr) { - if(!count($arr)) return; - foreach($arr as $key => $val) { - $key = strtolower($key); - $output->{$key} = $val; - } - return $output; - } - } -?> +parse($buff); + } + + /** + * @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 = '') { + // 디버그를 위한 컴파일 시작 시간 저장 + if(__DEBUG__==3) $start = getMicroTime(); + + $this->lang = Context::getLangType(); + + $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); + + // xml:lang이 쓰였을 경우 지원하는 언어종류를 뽑음 + if(count($matches[1]) && $supported_lang = array_unique($matches[1])) { + // supported_lang에 현재 접속자의 lang이 없으면 en이 있는지 확인하여 en이 있으면 en을 기본, 아니면 첫번째것을.. + if(!in_array($this->lang, $supported_lang)) { + if(in_array('en', $supported_lang)) { + $this->lang = 'en'; + } else { + $this->lang = array_shift($supported_lang); + } + } + // 특별한 언어가 지정되지 않았다면 언어체크를 하지 않음 + } else { + unset($this->lang); + } + + $this->oParser = xml_parser_create('UTF-8'); + + xml_set_object($this->oParser, $this); + xml_set_element_handler($this->oParser, "_tagOpen", "_tagClosed"); + xml_set_character_data_handler($this->oParser, "_tagBody"); + + xml_parse($this->oParser, $this->input); + xml_parser_free($this->oParser); + + if(!count($this->output)) return; + + $output = array_shift($this->output); + + // 디버그를 위한 컴파일 시작 시간 저장 + if(__DEBUG__==3) $GLOBALS['__xmlparse_elapsed__'] += getMicroTime() - $start; + + return $output; + } + + + /** + * @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) { + $obj->node_name = strtolower($node_name); + $obj->attrs = $this->_arrToObj($attrs); + + 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 + * @remark the first parameter, $parser ought to be remove since it is not used. + */ + function _tagBody($parser, $body) { + //if(!trim($body)) return; + $this->output[count($this->output)-1]->body .= $body; + } + + /** + * @brief end element handler + * @param[in] $parse an instance of parser + * @param[in] $node_name name of xml node + */ + function _tagClosed($parser, $node_name) { + $node_name = strtolower($node_name); + $cur_obj = array_pop($this->output); + $parent_obj = &$this->output[count($this->output)-1]; + if($this->lang&&$cur_obj->attrs->{'xml:lang'}&&$cur_obj->attrs->{'xml:lang'}!=$this->lang) return; + if($this->lang&&$parent_obj->{$node_name}->attrs->{'xml:lang'}&&$parent_obj->{$node_name}->attrs->{'xml:lang'}!=$this->lang) return; + + if($parent_obj->{$node_name}) { + $tmp_obj = $parent_obj->{$node_name}; + if(is_array($tmp_obj)) { + array_push($parent_obj->{$node_name}, $cur_obj); + } else { + $parent_obj->{$node_name} = array(); + array_push($parent_obj->{$node_name}, $tmp_obj); + array_push($parent_obj->{$node_name}, $cur_obj); + } + } else { + $parent_obj->{$node_name} = $cur_obj; + } + } + + /** + * @brief method to transfer values in an array to a data object + * @param[in] $arr data array + **/ + function _arrToObj($arr) { + if(!count($arr)) return; + foreach($arr as $key => $val) { + $key = strtolower($key); + $output->{$key} = $val; + } + return $output; + } + } +?> diff --git a/classes/xml/XmlQueryParser.class.php b/classes/xml/XmlQueryParser.class.php index bdc58ef02..941b7a58d 100644 --- a/classes/xml/XmlQueryParser.class.php +++ b/classes/xml/XmlQueryParser.class.php @@ -1,520 +1,520 @@ -query->attrs->action); - if(!$action) return; - - // 테이블 정리 (배열코드로 변환) - $tables = $xml_obj->query->tables->table; - $output->left_tables = array(); - - $left_conditions = array(); - - if(!$tables) return; - if(!is_array($tables)) $tables = array($tables); - foreach($tables as $key => $val) { - - // 테이블과 alias의 이름을 구함 - $table_name = $val->attrs->name; - $alias = $val->attrs->alias; - if(!$alias) $alias = $table_name; - - $output->tables[$alias] = $table_name; - - if(in_array($val->attrs->type,array('left join','left outer join','right join','right outer join')) && count($val->conditions)){ - $output->left_tables[$alias] = $val->attrs->type; - $left_conditions[$alias] = $val->conditions; - } - - // 테이블을 찾아서 컬럼의 속성을 구함 - $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $module, $table_name); - if(!file_exists($table_file)) { - $searched_list = FileHandler::readDir(_XE_PATH_.'modules'); - $searched_count = count($searched_list); - for($i=0;$i<$searched_count;$i++) { - $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $searched_list[$i], $table_name); - if(file_exists($table_file)) break; - } - } - - if(file_exists($table_file)) { - $table_xml = FileHandler::readFile($table_file); - $table_obj = parent::parse($table_xml); - if($table_obj->table) { - if(isset($table_obj->table->column) && !is_array($table_obj->table->column)) - { - $table_obj->table->column = array($table_obj->table->column); - } - - foreach($table_obj->table->column as $k => $v) { - $buff .= sprintf('$output->column_type["%s"] = "%s";%s', $v->attrs->name, $v->attrs->type, "\n"); - } - } - } - } - - - // 컬럼 정리 - $columns = $xml_obj->query->columns->column; - $out = $this->_setColumn($columns); - $output->columns = $out->columns; - - $conditions = $xml_obj->query->conditions; - $out = $this->_setConditions($conditions); - $output->conditions = $out->conditions; - - foreach($output->left_tables as $key => $val){ - if($left_conditions[$key]){ - $out = $this->_setConditions($left_conditions[$key]); - $output->left_conditions[$key] = $out->conditions; - } - } - - $group_list = $xml_obj->query->groups->group; - $out = $this->_setGroup($group_list); - $output->groups = $out->groups; - - // 네비게이션 정리 - $out = $this->_setNavigation($xml_obj); - $output->order = $out->order; - $output->list_count = $out->list_count; - $output->page_count = $out->page_count; - $output->page = $out->page; - - $column_count = count($output->columns); - $condition_count = count($output->conditions); - - $buff .= '$output->tables = array( '; - foreach($output->tables as $key => $val) { - if(!array_key_exists($key,$output->left_tables)){ - $buff .= sprintf('"%s"=>"%s",', $key, $val); - } - } - $buff .= ' );'."\n"; - - // php script 생성 - $buff .= '$output->_tables = array( '; - foreach($output->tables as $key => $val) { - $buff .= sprintf('"%s"=>"%s",', $key, $val); - } - $buff .= ' );'."\n"; - - if(count($output->left_tables)){ - $buff .= '$output->left_tables = array( '; - foreach($output->left_tables as $key => $val) { - $buff .= sprintf('"%s"=>"%s",', $key, $val); - } - $buff .= ' );'."\n"; - } - - // column 정리 - if($column_count) { - $buff .= '$output->columns = array ( '; - $buff .= $this->_getColumn($output->columns); - $buff .= ' );'."\n"; - } - - // conditions 정리 - if($condition_count) { - $buff .= '$output->conditions = array ( '; - $buff .= $this->_getConditions($output->conditions); - $buff .= ' );'."\n"; - } - - // conditions 정리 - if(count($output->left_conditions)) { - $buff .= '$output->left_conditions = array ( '; - foreach($output->left_conditions as $key => $val){ - $buff .= "'{$key}' => array ( "; - $buff .= $this->_getConditions($val); - $buff .= "),\n"; - } - $buff .= ' );'."\n"; - } - - // order 정리 - if($output->order) { - $buff .= '$output->order = array('; - foreach($output->order as $key => $val) { - $buff .= sprintf('array($args->%s?$args->%s:"%s",in_array($args->%s,array("asc","desc"))?$args->%s:("%s"?"%s":"asc")),', $val->var, $val->var, $val->default, $val->order, $val->order, $val->order, $val->order); - } - $buff .= ');'."\n"; - } - - // list_count 정리 - if($output->list_count) { - $buff .= sprintf('$output->list_count = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->list_count->var, $output->list_count->var, $output->list_count->var, $output->list_count->default,"\n"); - } - - // page_count 정리 - if($output->page_count) { - $buff .= sprintf('$output->page_count = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->page_count->var, $output->page_count->var, $output->page_count->var, $output->list_count->default,"\n"); - } - - // page 정리 - if($output->page) { - $buff .= sprintf('$output->page = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->page->var, $output->page->var, $output->page->var, $output->list->default,"\n"); - } - - // group by 정리 - if($output->groups) { - $buff .= sprintf('$output->groups = array("%s");%s', implode('","',$output->groups),"\n"); - } - - // minlength check - if(count($minlength_list)) { - foreach($minlength_list as $key => $val) { - $pre_buff .= 'if($args->'.$key.'&&strlen($args->'.$key.')<'.$val.') return new Object(-1, sprintf($lang->filter->outofrange, $lang->'.$key.'?$lang->'.$key.':\''.$key.'\'));'."\n"; - } - } - - // maxlength check - if(count($maxlength_list)) { - foreach($maxlength_list as $key => $val) { - $pre_buff .= 'if($args->'.$key.'&&strlen($args->'.$key.')>'.$val.') return new Object(-1, sprintf($lang->filter->outofrange, $lang->'.$key.'?$lang->'.$key.':\''.$key.'\'));'."\n"; - } - } - - // filter check - if(count($this->filter_list)) { - foreach($this->filter_list as $key => $val) { - $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"); - } - } - - // default check - if(count($this->default_list)) { - foreach($this->default_list as $key => $val) { - $pre_buff .= 'if(!isset($args->'.$key.')) $args->'.$key.' = '.$val.';'."\n"; - } - } - - // not null check - if(count($this->notnull_list)) { - 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"; - } - } - - $buff = "query_id = "%s";%s', $query_id, "\n") - . sprintf('$output->action = "%s";%s', $action, "\n") - . $pre_buff - . $buff - . 'return $output; ?>'; - - // 저장 - FileHandler::writeFile($cache_file, $buff); - } - - /** - * @brief transfer given column information to object->columns - * @param[in] column information - * @result Returns $object - */ - - function _setColumn($columns){ - if(!$columns) { - $output->column[] = array("*" => "*"); - } else { - if(!is_array($columns)) $columns = array($columns); - foreach($columns as $key => $val) { - $name = $val->attrs->name; - /* - if(strpos('.',$name)===false && count($output->tables)==1) { - $tmp = array_values($output->tables); - $name = sprintf('%s.%s', $tmp[0], $val->attrs->name); - } - */ - - $output->columns[] = array( - "name" => $name, - "var" => $val->attrs->var, - "default" => $val->attrs->default, - "notnull" => $val->attrs->notnull, - "filter" => $val->attrs->filter, - "minlength" => $val->attrs->minlength, - "maxlength" => $val->attrs->maxlength, - "alias" => $val->attrs->alias, - "click_count" => $val->attrs->click_count, - ); - } - } - return $output; - } - - /** - * @brief transfer condition information to $object->conditions - * @param[in] SQL condition information - * @result Returns $output - */ - function _setConditions($conditions){ - // 조건절 정리 - - $condition = $conditions->condition; - if($condition) { - $obj->condition = $condition; - unset($condition); - $condition = array($obj); - } - $condition_group = $conditions->group; - if($condition_group && !is_array($condition_group)) $condition_group = array($condition_group); - - if($condition && $condition_group) $cond = array_merge($condition, $condition_group); - elseif($condition_group) $cond = $condition_group; - else $cond = $condition; - - if($cond) { - foreach($cond as $key => $val) { - unset($cond_output); - - if($val->attrs->pipe) $cond_output->pipe = $val->attrs->pipe; - else $cond_output->pipe = null; - - if(!$val->condition) continue; - if(!is_array($val->condition)) $val->condition = array($val->condition); - - foreach($val->condition as $k => $v) { - $obj = $v->attrs; - if(!$obj->alias) $obj->alias = $obj->column; - $cond_output->condition[] = $obj; - } - - $output->conditions[] = $cond_output; - } - } - return $output; - } - - /** - * @brief transfer condition information to $object->groups - * @param[in] SQL group information - * @result Returns $output - */ - function _setGroup($group_list){ - // group 정리 - - if($group_list) { - if(!is_array($group_list)) $group_list = array($group_list); - for($i=0;$iattrs->column); - if(!$column) continue; - $group_column_list[] = $column; - } - if(count($group_column_list)) $output->groups = $group_column_list; - } - return $output; - } - - - /** - * @brief transfer pagnation information to $output - * @param[in] $xml_obj xml object containing Navigation information - * @result Returns $output - */ - function _setNavigation($xml_obj){ - $navigation = $xml_obj->query->navigation; - if($navigation) { - $order = $navigation->index; - if($order) { - if(!is_array($order)) $order = array($order); - foreach($order as $order_info) { - $output->order[] = $order_info->attrs; - } - } - - $list_count = $navigation->list_count->attrs; - $output->list_count = $list_count; - - $page_count = $navigation->page_count->attrs; - $output->page_count = $page_count; - - $page = $navigation->page->attrs; - $output->page = $page ; - } - 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){ - $buff = ''; - $str = ''; - $print_vars = array(); - - foreach($columns as $key => $val) { - $str = 'array("name"=>"%s","alias"=>"%s"'; - $print_vars = array(); - $print_vars[] = $val['name']; - $print_vars[] = $val['alias']; - - $val['default'] = $this->getDefault($val['name'], $val['default']); - if($val['var'] && strpos($val['var'],'.')===false) { - - if($val['default']){ - $str .= ',"value"=>$args->%s?$args->%s:%s'; - $print_vars[] = $val['var']; - $print_vars[] = $val['var']; - $print_vars[] = $val['default']; - }else{ - $str .= ',"value"=>$args->%s'; - $print_vars[] = $val['var']; - } - - } else { - if($val['default']){ - $str .= ',"value"=>%s'; - $print_vars[] = $val['default']; - } - } - - if($val['click_count']){ - $str .= ',"click_count"=>$args->%s'; - $print_vars[] = $val['click_count']; - } - - $str .= '),%s'; - $print_vars[] = "\n"; - - $buff .= vsprintf($str, $print_vars); - } - 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){ - $buff = ''; - foreach($conditions as $key => $val) { - $buff .= sprintf('array("pipe"=>"%s",%s"condition"=>array(', $val->pipe,"\n"); - foreach($val->condition as $k => $v) { - $v->default = $this->getDefault($v->column, $v->default); - if($v->var) { - if(strpos($v->var,".")===false) { - if($v->default) $this->default_list[$v->var] = $v->default; - if($v->filter) $this->filter_list[] = $v; - 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"); - 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"=>"%s","pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n"); - } - } else { - if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->default ,$v->pipe, $v->operation,"\n"); - else $buff .= sprintf('array("column"=>"%s", "pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->pipe, $v->operation,"\n"); - } - } - $buff .= ')),'."\n"; - } - return $buff; - } - - - /** - * @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) { - $db_info = Context::getDBInfo (); - if(!isset($value)) return; - $str_pos = strpos($value, '('); - if($str_pos===false) return '"'.$value.'"'; - - $func_name = substr($value, 0, $str_pos); - $args = substr($value, $str_pos+1, strlen($value)-1); - - switch($func_name) { - case 'ipaddress' : - $val = '$_SERVER[\'REMOTE_ADDR\']'; - break; - case 'unixtime' : - $val = 'time()'; - break; - case 'curdate' : - $val = 'date("YmdHis")'; - break; - case 'sequence' : - $val = '$this->getNextSequence()'; - break; - case 'plus' : - $args = abs($args); - if ($db_info->db_type == 'cubrid') { - $val = sprintf ('"\\"%s\\"+%d"', $name, $args); - } else { - $val = sprintf('"%s+%d"', $name, $args); - } - break; - case 'minus' : - $args = abs($args); - if ($db_info->db_type == 'cubrid') { - $val = sprintf ('"\\"%s\\"-%d"', $name, $args); - } else { - $val = sprintf('"%s-%d"', $name, $args); - } - break; - case 'multiply' : - $args = intval($args); - if ($db_info->db_type == 'cubrid') { - $val = sprintf ('"\\"%s\\"*%d"', $name, $args); - } else { - $val = sprintf('"%s*%d"', $name, $args); - } - break; - } - - return $val; - } - } -?> +query->attrs->action); + if(!$action) return; + + // 테이블 정리 (배열코드로 변환) + $tables = $xml_obj->query->tables->table; + $output->left_tables = array(); + + $left_conditions = array(); + + if(!$tables) return; + if(!is_array($tables)) $tables = array($tables); + foreach($tables as $key => $val) { + + // 테이블과 alias의 이름을 구함 + $table_name = $val->attrs->name; + $alias = $val->attrs->alias; + if(!$alias) $alias = $table_name; + + $output->tables[$alias] = $table_name; + + if(in_array($val->attrs->type,array('left join','left outer join','right join','right outer join')) && count($val->conditions)){ + $output->left_tables[$alias] = $val->attrs->type; + $left_conditions[$alias] = $val->conditions; + } + + // 테이블을 찾아서 컬럼의 속성을 구함 + $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $module, $table_name); + if(!file_exists($table_file)) { + $searched_list = FileHandler::readDir(_XE_PATH_.'modules'); + $searched_count = count($searched_list); + for($i=0;$i<$searched_count;$i++) { + $table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $searched_list[$i], $table_name); + if(file_exists($table_file)) break; + } + } + + if(file_exists($table_file)) { + $table_xml = FileHandler::readFile($table_file); + $table_obj = parent::parse($table_xml); + if($table_obj->table) { + if(isset($table_obj->table->column) && !is_array($table_obj->table->column)) + { + $table_obj->table->column = array($table_obj->table->column); + } + + foreach($table_obj->table->column as $k => $v) { + $buff .= sprintf('$output->column_type["%s"] = "%s";%s', $v->attrs->name, $v->attrs->type, "\n"); + } + } + } + } + + + // 컬럼 정리 + $columns = $xml_obj->query->columns->column; + $out = $this->_setColumn($columns); + $output->columns = $out->columns; + + $conditions = $xml_obj->query->conditions; + $out = $this->_setConditions($conditions); + $output->conditions = $out->conditions; + + foreach($output->left_tables as $key => $val){ + if($left_conditions[$key]){ + $out = $this->_setConditions($left_conditions[$key]); + $output->left_conditions[$key] = $out->conditions; + } + } + + $group_list = $xml_obj->query->groups->group; + $out = $this->_setGroup($group_list); + $output->groups = $out->groups; + + // 네비게이션 정리 + $out = $this->_setNavigation($xml_obj); + $output->order = $out->order; + $output->list_count = $out->list_count; + $output->page_count = $out->page_count; + $output->page = $out->page; + + $column_count = count($output->columns); + $condition_count = count($output->conditions); + + $buff .= '$output->tables = array( '; + foreach($output->tables as $key => $val) { + if(!array_key_exists($key,$output->left_tables)){ + $buff .= sprintf('"%s"=>"%s",', $key, $val); + } + } + $buff .= ' );'."\n"; + + // php script 생성 + $buff .= '$output->_tables = array( '; + foreach($output->tables as $key => $val) { + $buff .= sprintf('"%s"=>"%s",', $key, $val); + } + $buff .= ' );'."\n"; + + if(count($output->left_tables)){ + $buff .= '$output->left_tables = array( '; + foreach($output->left_tables as $key => $val) { + $buff .= sprintf('"%s"=>"%s",', $key, $val); + } + $buff .= ' );'."\n"; + } + + // column 정리 + if($column_count) { + $buff .= '$output->columns = array ( '; + $buff .= $this->_getColumn($output->columns); + $buff .= ' );'."\n"; + } + + // conditions 정리 + if($condition_count) { + $buff .= '$output->conditions = array ( '; + $buff .= $this->_getConditions($output->conditions); + $buff .= ' );'."\n"; + } + + // conditions 정리 + if(count($output->left_conditions)) { + $buff .= '$output->left_conditions = array ( '; + foreach($output->left_conditions as $key => $val){ + $buff .= "'{$key}' => array ( "; + $buff .= $this->_getConditions($val); + $buff .= "),\n"; + } + $buff .= ' );'."\n"; + } + + // order 정리 + if($output->order) { + $buff .= '$output->order = array('; + foreach($output->order as $key => $val) { + $buff .= sprintf('array($args->%s?$args->%s:"%s",in_array($args->%s,array("asc","desc"))?$args->%s:("%s"?"%s":"asc")),', $val->var, $val->var, $val->default, $val->order, $val->order, $val->order, $val->order); + } + $buff .= ');'."\n"; + } + + // list_count 정리 + if($output->list_count) { + $buff .= sprintf('$output->list_count = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->list_count->var, $output->list_count->var, $output->list_count->var, $output->list_count->default,"\n"); + } + + // page_count 정리 + if($output->page_count) { + $buff .= sprintf('$output->page_count = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->page_count->var, $output->page_count->var, $output->page_count->var, $output->list_count->default,"\n"); + } + + // page 정리 + if($output->page) { + $buff .= sprintf('$output->page = array("var"=>"%s", "value"=>$args->%s?$args->%s:"%s");%s', $output->page->var, $output->page->var, $output->page->var, $output->list->default,"\n"); + } + + // group by 정리 + if($output->groups) { + $buff .= sprintf('$output->groups = array("%s");%s', implode('","',$output->groups),"\n"); + } + + // minlength check + if(count($minlength_list)) { + foreach($minlength_list as $key => $val) { + $pre_buff .= 'if($args->'.$key.'&&strlen($args->'.$key.')<'.$val.') return new Object(-1, sprintf($lang->filter->outofrange, $lang->'.$key.'?$lang->'.$key.':\''.$key.'\'));'."\n"; + } + } + + // maxlength check + if(count($maxlength_list)) { + foreach($maxlength_list as $key => $val) { + $pre_buff .= 'if($args->'.$key.'&&strlen($args->'.$key.')>'.$val.') return new Object(-1, sprintf($lang->filter->outofrange, $lang->'.$key.'?$lang->'.$key.':\''.$key.'\'));'."\n"; + } + } + + // filter check + if(count($this->filter_list)) { + foreach($this->filter_list as $key => $val) { + $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"); + } + } + + // default check + if(count($this->default_list)) { + foreach($this->default_list as $key => $val) { + $pre_buff .= 'if(!isset($args->'.$key.')) $args->'.$key.' = '.$val.';'."\n"; + } + } + + // not null check + if(count($this->notnull_list)) { + 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"; + } + } + + $buff = "query_id = "%s";%s', $query_id, "\n") + . sprintf('$output->action = "%s";%s', $action, "\n") + . $pre_buff + . $buff + . 'return $output; ?>'; + + // 저장 + FileHandler::writeFile($cache_file, $buff); + } + + /** + * @brief transfer given column information to object->columns + * @param[in] column information + * @result Returns $object + */ + + function _setColumn($columns){ + if(!$columns) { + $output->column[] = array("*" => "*"); + } else { + if(!is_array($columns)) $columns = array($columns); + foreach($columns as $key => $val) { + $name = $val->attrs->name; + /* + if(strpos('.',$name)===false && count($output->tables)==1) { + $tmp = array_values($output->tables); + $name = sprintf('%s.%s', $tmp[0], $val->attrs->name); + } + */ + + $output->columns[] = array( + "name" => $name, + "var" => $val->attrs->var, + "default" => $val->attrs->default, + "notnull" => $val->attrs->notnull, + "filter" => $val->attrs->filter, + "minlength" => $val->attrs->minlength, + "maxlength" => $val->attrs->maxlength, + "alias" => $val->attrs->alias, + "click_count" => $val->attrs->click_count, + ); + } + } + return $output; + } + + /** + * @brief transfer condition information to $object->conditions + * @param[in] SQL condition information + * @result Returns $output + */ + function _setConditions($conditions){ + // 조건절 정리 + + $condition = $conditions->condition; + if($condition) { + $obj->condition = $condition; + unset($condition); + $condition = array($obj); + } + $condition_group = $conditions->group; + if($condition_group && !is_array($condition_group)) $condition_group = array($condition_group); + + if($condition && $condition_group) $cond = array_merge($condition, $condition_group); + elseif($condition_group) $cond = $condition_group; + else $cond = $condition; + + if($cond) { + foreach($cond as $key => $val) { + unset($cond_output); + + if($val->attrs->pipe) $cond_output->pipe = $val->attrs->pipe; + else $cond_output->pipe = null; + + if(!$val->condition) continue; + if(!is_array($val->condition)) $val->condition = array($val->condition); + + foreach($val->condition as $k => $v) { + $obj = $v->attrs; + if(!$obj->alias) $obj->alias = $obj->column; + $cond_output->condition[] = $obj; + } + + $output->conditions[] = $cond_output; + } + } + return $output; + } + + /** + * @brief transfer condition information to $object->groups + * @param[in] SQL group information + * @result Returns $output + */ + function _setGroup($group_list){ + // group 정리 + + if($group_list) { + if(!is_array($group_list)) $group_list = array($group_list); + for($i=0;$iattrs->column); + if(!$column) continue; + $group_column_list[] = $column; + } + if(count($group_column_list)) $output->groups = $group_column_list; + } + return $output; + } + + + /** + * @brief transfer pagnation information to $output + * @param[in] $xml_obj xml object containing Navigation information + * @result Returns $output + */ + function _setNavigation($xml_obj){ + $navigation = $xml_obj->query->navigation; + if($navigation) { + $order = $navigation->index; + if($order) { + if(!is_array($order)) $order = array($order); + foreach($order as $order_info) { + $output->order[] = $order_info->attrs; + } + } + + $list_count = $navigation->list_count->attrs; + $output->list_count = $list_count; + + $page_count = $navigation->page_count->attrs; + $output->page_count = $page_count; + + $page = $navigation->page->attrs; + $output->page = $page ; + } + 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){ + $buff = ''; + $str = ''; + $print_vars = array(); + + foreach($columns as $key => $val) { + $str = 'array("name"=>"%s","alias"=>"%s"'; + $print_vars = array(); + $print_vars[] = $val['name']; + $print_vars[] = $val['alias']; + + $val['default'] = $this->getDefault($val['name'], $val['default']); + if($val['var'] && strpos($val['var'],'.')===false) { + + if($val['default']){ + $str .= ',"value"=>$args->%s?$args->%s:%s'; + $print_vars[] = $val['var']; + $print_vars[] = $val['var']; + $print_vars[] = $val['default']; + }else{ + $str .= ',"value"=>$args->%s'; + $print_vars[] = $val['var']; + } + + } else { + if($val['default']){ + $str .= ',"value"=>%s'; + $print_vars[] = $val['default']; + } + } + + if($val['click_count']){ + $str .= ',"click_count"=>$args->%s'; + $print_vars[] = $val['click_count']; + } + + $str .= '),%s'; + $print_vars[] = "\n"; + + $buff .= vsprintf($str, $print_vars); + } + 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){ + $buff = ''; + foreach($conditions as $key => $val) { + $buff .= sprintf('array("pipe"=>"%s",%s"condition"=>array(', $val->pipe,"\n"); + foreach($val->condition as $k => $v) { + $v->default = $this->getDefault($v->column, $v->default); + if($v->var) { + if(strpos($v->var,".")===false) { + if($v->default) $this->default_list[$v->var] = $v->default; + if($v->filter) $this->filter_list[] = $v; + 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"); + 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"=>"%s","pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n"); + } + } else { + if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->default ,$v->pipe, $v->operation,"\n"); + else $buff .= sprintf('array("column"=>"%s", "pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->pipe, $v->operation,"\n"); + } + } + $buff .= ')),'."\n"; + } + return $buff; + } + + + /** + * @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) { + $db_info = Context::getDBInfo (); + if(!isset($value)) return; + $str_pos = strpos($value, '('); + if($str_pos===false) return '"'.$value.'"'; + + $func_name = substr($value, 0, $str_pos); + $args = substr($value, $str_pos+1, strlen($value)-1); + + switch($func_name) { + case 'ipaddress' : + $val = '$_SERVER[\'REMOTE_ADDR\']'; + break; + case 'unixtime' : + $val = 'time()'; + break; + case 'curdate' : + $val = 'date("YmdHis")'; + break; + case 'sequence' : + $val = '$this->getNextSequence()'; + break; + case 'plus' : + $args = abs($args); + if ($db_info->db_type == 'cubrid') { + $val = sprintf ('"\\"%s\\"+%d"', $name, $args); + } else { + $val = sprintf('"%s+%d"', $name, $args); + } + break; + case 'minus' : + $args = abs($args); + if ($db_info->db_type == 'cubrid') { + $val = sprintf ('"\\"%s\\"-%d"', $name, $args); + } else { + $val = sprintf('"%s-%d"', $name, $args); + } + break; + case 'multiply' : + $args = intval($args); + if ($db_info->db_type == 'cubrid') { + $val = sprintf ('"\\"%s\\"*%d"', $name, $args); + } else { + $val = sprintf('"%s*%d"', $name, $args); + } + break; + } + + return $val; + } + } +?> diff --git a/common/css/button.css b/common/css/button.css index 230332434..fb9661cd9 100644 --- a/common/css/button.css +++ b/common/css/button.css @@ -1,4 +1,4 @@ -/* NHN > UIT Center > Open UI Platform Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ /* Anchor Button */ a.button, diff --git a/common/js/common.js b/common/js/common.js index 22a957822..ec9b81572 100644 --- a/common/js/common.js +++ b/common/js/common.js @@ -1,113 +1,113 @@ -/** - * @file common.js - * @author zero (zero@nzeo.com) - * @brief 몇가지 유용한 & 기본적으로 자주 사용되는 자바스크립트 함수들 모음 - **/ - -if(jQuery)jQuery.noConflict();(function($){var UA=navigator.userAgent.toLowerCase();$.os={Linux:/linux/.test(UA),Unix:/x11/.test(UA),Mac:/mac/.test(UA),Windows:/win/.test(UA)};$.os.name=($.os.Windows)?'Windows':($.os.Linux)?'Linux':($.os.Unix)?'Unix':($.os.Mac)?'Mac':'';window.XE={loaded_popup_menus:new Array(),addedDocument:new Array(),checkboxToggleAll:function(){var itemName='cart';var options={wrap:null,checked:'toggle',doClick:false};switch(arguments.length){case 1:if(typeof(arguments[0])=="string"){itemName=arguments[0];}else{$.extend(options,arguments[0]||{});} -break;case 2:itemName=arguments[0];$.extend(options,arguments[1]||{});} -if(options.doClick==true)options.checked=null;if(typeof(options.wrap)=="string")options.wrap='#'+options.wrap;if(options.wrap){var obj=$(options.wrap).find('input[name='+itemName+']:checkbox');}else{var obj=$('input[name='+itemName+']:checkbox');} -if(options.checked=='toggle'){obj.each(function(){$(this).attr('checked',($(this).attr('checked'))?false:true);});}else{(options.doClick==true)?obj.click():obj.attr('checked',options.checked);}},displayPopupMenu:function(ret_obj,response_tags,params){var target_srl=params["target_srl"];var menu_id=params["menu_id"];var menus=ret_obj['menus'];var html="";if(this.loaded_popup_menus[menu_id]){html=this.loaded_popup_menus[menu_id];}else{if(menus){var item=menus['item'];if(typeof(item.length)=='undefined'||item.length<1)item=new Array(item);if(item.length){for(var i=0;i'+str+' ';}}} -this.loaded_popup_menus[menu_id]=html;} -if(html){var area=$('#popup_menu_area').html('
    '+html+'
');var areaOffset={top:params['page_y'],left:params['page_x']};if(area.outerHeight()+areaOffset.top>$(window).height()+$(window).scrollTop()) -areaOffset.top=$(window).height()-area.outerHeight()+$(window).scrollTop();if(area.outerWidth()+areaOffset.left>$(window).width()+$(window).scrollLeft()) -areaOffset.left=$(window).width()-area.outerWidth()+$(window).scrollLeft();area.css({top:areaOffset.top,left:areaOffset.left}).show();}}}})(jQuery);jQuery(function($){if(!$('#popup_menu_area').length){var menuObj=$('
').attr('id','popup_menu_area').css({display:'none',zIndex:9999});$(document.body).append(menuObj);} -$(document).click(function(evt){var area=$('#popup_menu_area');if(!area.length)return;area.hide();var targetObj=$(evt.target);if(!targetObj.length)return;if(targetObj.length&&$.inArray(targetObj.attr('nodeName'),['DIV','SPAN','A'])==-1)targetObj=targetObj.parent();if(!targetObj.length||$.inArray(targetObj.attr('nodeName'),['DIV','SPAN','A'])==-1)return;var class_name=targetObj.attr('className');if(class_name.indexOf('_')<=0)return;var class_name_list=class_name.split(' ');var menu_id='';var menu_id_regx=/^([a-zA-Z]+)_([0-9]+)$/;for(var i=0,c=class_name_list.length;i-1)?first_enable[i]:j;}} -if(!disabled_exists)return;sels.oldonchange=sels.onchange;sels.onchange=function(){if(this.options[this.selectedIndex].disabled){this.selectedIndex=first_enable[i];}else{if(this.oldonchange)this.oldonchange();}};if(sels.selectedIndex>=0&&sels.options[sels.selectedIndex].disabled)sels.onchange();});} -var drEditorFold=$('.xe_content .fold_button');if(drEditorFold.size()){var fold_container=$('div.fold_container',drEditorFold);$('button.more',drEditorFold).click(function(){$(this).hide().next('button').show().parent().next(fold_container).show();});$('button.less',drEditorFold).click(function(){$(this).hide().prev('button').show().parent().next(fold_container).hide();});}});String.prototype.getQuery=function(key){var idx=this.indexOf('?');if(idx==-1)return null;var query_string=this.substr(idx+1,this.length);var args={};query_string.replace(/([^=]+)=([^&]*)(&|$)/g,function(){args[arguments[1]]=arguments[2];});var q=args[key];if(typeof(q)=="undefined")q="";return q;} -String.prototype.setQuery=function(key,val){var idx=this.indexOf('?');var uri=this;uri=uri.replace(/#$/,'');if(idx!=-1){uri=this.substr(0,idx);var query_string=this.substr(idx+1,this.length);var args=new Array();query_string.replace(/([^=]+)=([^&]*)(&|$)/g,function(){args[arguments[1]]=arguments[2];});args[key]=val;var q_list=new Array();for(var i in args){if(!args.hasOwnProperty(i))continue;var arg=args[i];if(!arg.toString().trim())continue;arg=decodeURI(arg);q_list[q_list.length]=i+'='+arg;} -uri=uri+"?"+q_list.join("&");}else{if(val.toString().trim())uri=uri+"?"+key+"="+val;} -var re=/https:\/\/([^:\/]+)(:\d+|)/i;var check=re.exec(uri);if(check) -{var toReplace="http://"+check[1];if(typeof(http_port)!='undefined'&&http_port!=80) -{toReplace+=":"+http_port;} -uri=uri.replace(re,toReplace);} -var bUseSSL=false;if(typeof(enforce_ssl)!='undefined'&&enforce_ssl) -{bUseSSL=true;} -else if(typeof(ssl_actions)!='undefined'&&typeof(ssl_actions.length)!='undefined'&&uri.getQuery('act')){var act=uri.getQuery('act');for(i=0;i-1&&!url.getQuery('vid'))url=url.setQuery('vid',xeVid);try{if(target!="_blank"&&winopen_list[target]){winopen_list[target].close();winopen_list[target]=null;}}catch(e){} -if(typeof(target)=='undefined')target='_blank';if(typeof(attribute)=='undefined')attribute='';var win=window.open(url,target,attribute);win.focus();if(target!="_blank")winopen_list[target]=win;} -function popopen(url,target){if(typeof(target)=="undefined")target="_blank";if(typeof(xeVid)!='undefined'&&url.indexOf(request_uri)>-1&&!url.getQuery('vid'))url=url.setQuery('vid',xeVid);winopen(url,target,"left=10,top=10,width=10,height=10,scrollbars=no,resizable=yes,toolbars=no");} -function sendMailTo(to){location.href="mailto:"+to;} -function move_url(url,open_wnidow){if(!url)return false;if(typeof(open_wnidow)=='undefined')open_wnidow='N';if(open_wnidow=='N'){open_wnidow=false;}else{open_wnidow=true;} -if(/^\./.test(url))url=request_uri+url;if(open_wnidow){winopen(url);}else{location.href=url;} -return false;} -function displayMultimedia(src,width,height,options){var html=_displayMultimedia(src,width,height,options);if(html)document.writeln(html);} -function _displayMultimedia(src,width,height,options){if(src.indexOf('files')==0)src=request_uri+src;var defaults={wmode:'transparent',allowScriptAccess:'sameDomain',quality:'high',flashvars:'',autostart:false};var params=jQuery.extend(defaults,options||{});var autostart=(params.autostart&¶ms.autostart!='false')?'true':'false';delete(params.autostart);var clsid="";var codebase="";var html="";if(/\.(gif|jpg|jpeg|bmp|png)$/i.test(src)){html='';}else if(/\.flv$/i.test(src)||/\.mov$/i.test(src)||/\.moov$/i.test(src)||/\.m4v$/i.test(src)){html='';}else if(/\.swf/i.test(src)){clsid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';if(typeof(enforce_ssl)!='undefined'&&enforce_ssl){codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0";} -else{codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0";} -html='';html+='';for(var name in params){if(params[name]!='undefined'&¶ms[name]!=''){html+='';}} -html+='' -+'' -+'';}else{if(jQuery.browser.mozilla||jQuery.browser.opera){autostart=(params.autostart&¶ms.autostart!='false')?'1':'0';} -html='400){$body.css({overflow:'auto',overflowX:'hidden',height:400+'px'});}} -var $win=$(window);var $pc=$('#popup_content');var w=Math.max($pc[0].offsetWidth,600);var h=$pc[0].offsetHeight;var dw=$win.width();var dh=$win.height();var _w=0,_h=0;if(w!=dw)_w=w-dw;if(h!=dh)_h=h-dh;if(_w||_h){window.resizeBy(_w,_h);} -if(!arguments.callee.executed){setTimeout(setFixedPopupSize,300);arguments.callee.executed=true;}} -function doCallModuleAction(module,action,target_srl){var params=new Array();params['target_srl']=target_srl;params['cur_mid']=current_mid;exec_xml(module,action,params,completeCallModuleAction);} -function completeCallModuleAction(ret_obj,response_tags){if(ret_obj['message']!='success')alert(ret_obj['message']);location.reload();} -function completeMessage(ret_obj){alert(ret_obj['message']);location.reload();} -function doChangeLangType(obj){if(typeof(obj)=="string"){setLangType(obj);}else{var val=obj.options[obj.selectedIndex].value;setLangType(val);} -location.reload();} -function setLangType(lang_type){var expire=new Date();expire.setTime(expire.getTime()+(7000*24*3600000));xSetCookie('lang_type',lang_type,expire,'/');} -function doDocumentPreview(obj){var fo_obj=obj;while(fo_obj.nodeName!="FORM"){fo_obj=fo_obj.parentNode;} -if(fo_obj.nodeName!="FORM")return;var editor_sequence=fo_obj.getAttribute('editor_sequence');var content=editorGetContent(editor_sequence);var win=window.open("","previewDocument","toolbars=no,width=700px;height=800px,scrollbars=yes,resizable=yes");var dummy_obj=jQuery("#previewDocument");if(!dummy_obj.length){jQuery(''+''+''+''+'').appendTo(document.body);dummy_obj=jQuery("#previewDocument")[0];} -if(dummy_obj){dummy_obj.content.value=content;dummy_obj.submit();}} -function doDocumentSave(obj){var editor_sequence=obj.form.getAttribute('editor_sequence');var prev_content=editorRelKeys[editor_sequence]['content'].value;if(typeof(editor_sequence)!='undefined'&&editor_sequence&&typeof(editorRelKeys)!='undefined'&&typeof(editorGetContent)=='function'){var content=editorGetContent(editor_sequence);editorRelKeys[editor_sequence]['content'].value=content;} -var params={},responses=['error','message','document_srl'],elms=obj.form.elements,data=jQuery(obj.form).serializeArray();;jQuery.each(data,function(i,field){var val=jQuery.trim(field.value);if(!val)return true;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;return false;} -function completeDocumentSave(ret_obj){jQuery('input[name=document_srl]').eq(0).val(ret_obj['document_srl']);alert(ret_obj['message']);} -var objForSavedDoc=null;function doDocumentLoad(obj){objForSavedDoc=obj.form;popopen(request_uri.setQuery('module','member').setQuery('act','dispSavedDocumentList'));} -function doDocumentSelect(document_srl){if(!opener||!opener.objForSavedDoc){window.close();return;} -opener.location.href=opener.current_url.setQuery('document_srl',document_srl).setQuery('act','dispBoardWrite');window.close();} -function viewSkinInfo(module,skin){popopen("./?module=module&act=dispModuleSkinInfo&selected_module="+module+"&skin="+skin,'SkinInfo');} -var addedDocument=new Array();function doAddDocumentCart(obj){var srl=obj.value;addedDocument[addedDocument.length]=srl;setTimeout(function(){callAddDocumentCart(addedDocument.length);},100);} -function callAddDocumentCart(document_length){if(addedDocument.length<1||document_length!=addedDocument.length)return;var params=new Array();params["srls"]=addedDocument.join(",");exec_xml("document","procDocumentAddCart",params,null);addedDocument=new Array();} -function transRGB2Hex(value){if(!value)return value;if(value.indexOf('#')>-1)return value.replace(/^#/,'');if(value.toLowerCase().indexOf('rgb')<0)return value;value=value.replace(/^rgb\(/i,'').replace(/\)$/,'');value_list=value.split(',');var hex='';for(var i=0;i>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64;}else if(isNaN(chr3)){enc4=64;} -output=output+ -this._keyStr.charAt(enc1)+this._keyStr.charAt(enc2)+ -this._keyStr.charAt(enc3)+this._keyStr.charAt(enc4);} -return output;},decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2);} -if(enc4!=64){output=output+String.fromCharCode(chr3);}} -output=Base64._utf8_decode(output);return output;},_utf8_encode:function(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n127)&&(c<2048)){utftext+=String.fromCharCode((c>>6)|192);utftext+=String.fromCharCode((c&63)|128);} -else{utftext+=String.fromCharCode((c>>12)|224);utftext+=String.fromCharCode(((c>>6)&63)|128);utftext+=String.fromCharCode((c&63)|128);}} -return utftext;},_utf8_decode:function(utftext){var string="";var i=0;var c=c1=c2=0;while(i191)&&(c<224)){c2=utftext.charCodeAt(i+1);string+=String.fromCharCode(((c&31)<<6)|(c2&63));i+=2;} -else{c2=utftext.charCodeAt(i+1);c3=utftext.charCodeAt(i+2);string+=String.fromCharCode(((c&15)<<12)|((c2&63)<<6)|(c3&63));i+=3;}} -return string;}} -if(typeof(resizeImageContents)=='undefined'){function resizeImageContents(){}} -if(typeof(activateOptionDisabled)=='undefined'){function activateOptionDisabled(){}} -objectExtend=jQuery.extend;function toggleDisplay(objId){jQuery('#'+objId).toggle();} -function checkboxSelectAll(formObj,name,checked){var itemName=name;var option={};if(typeof(formObj)!="undefined")option.wrap=formObj;if(typeof(checked)!="undefined")option.checked=checked;XE.checkboxToggleAll(itemName,option);} -function clickCheckBoxAll(formObj,name){var itemName=name;var option={doClick:true};if(typeof(formObj)!="undefined")option.wrap=formObj;XE.checkboxToggleAll(itemName,option);} -function svc_folder_open(id){jQuery("#_folder_open_"+id).hide();jQuery("#_folder_close_"+id).show();jQuery("#_folder_"+id).show();} -function svc_folder_close(id){jQuery("#_folder_open_"+id).show();jQuery("#_folder_close_"+id).hide();jQuery("#_folder_"+id).hide();} -function open_calendar(fo_id,day_str,callback_func){if(typeof(day_str)=="undefined")day_str="";var url="./common/tpl/calendar.php?";if(fo_id)url+="fo_id="+fo_id;if(day_str)url+="&day_str="+day_str;if(callback_func)url+="&callback_func="+callback_func;popopen(url,'Calendar');} -var loaded_popup_menus=XE.loaded_popup_menus;function createPopupMenu(){} -function chkPopupMenu(){} -function displayPopupMenu(ret_obj,response_tags,params){XE.displayPopupMenu(ret_obj,response_tags,params);} -function GetObjLeft(obj){return jQuery(obj).offset().left;} -function GetObjTop(obj){return jQuery(obj).offset().top;} -function replaceOuterHTML(obj,html){jQuery(obj).replaceWith(html);} -function getOuterHTML(obj){return jQuery(obj).html().trim();} -jQuery(function(){jQuery(".lang_code").each(function() +/** + * @file common.js + * @author NHN (developers@xpressengine.com) + * @brief 몇가지 유용한 & 기본적으로 자주 사용되는 자바스크립트 함수들 모음 + **/ + +if(jQuery)jQuery.noConflict();(function($){var UA=navigator.userAgent.toLowerCase();$.os={Linux:/linux/.test(UA),Unix:/x11/.test(UA),Mac:/mac/.test(UA),Windows:/win/.test(UA)};$.os.name=($.os.Windows)?'Windows':($.os.Linux)?'Linux':($.os.Unix)?'Unix':($.os.Mac)?'Mac':'';window.XE={loaded_popup_menus:new Array(),addedDocument:new Array(),checkboxToggleAll:function(){var itemName='cart';var options={wrap:null,checked:'toggle',doClick:false};switch(arguments.length){case 1:if(typeof(arguments[0])=="string"){itemName=arguments[0];}else{$.extend(options,arguments[0]||{});} +break;case 2:itemName=arguments[0];$.extend(options,arguments[1]||{});} +if(options.doClick==true)options.checked=null;if(typeof(options.wrap)=="string")options.wrap='#'+options.wrap;if(options.wrap){var obj=$(options.wrap).find('input[name='+itemName+']:checkbox');}else{var obj=$('input[name='+itemName+']:checkbox');} +if(options.checked=='toggle'){obj.each(function(){$(this).attr('checked',($(this).attr('checked'))?false:true);});}else{(options.doClick==true)?obj.click():obj.attr('checked',options.checked);}},displayPopupMenu:function(ret_obj,response_tags,params){var target_srl=params["target_srl"];var menu_id=params["menu_id"];var menus=ret_obj['menus'];var html="";if(this.loaded_popup_menus[menu_id]){html=this.loaded_popup_menus[menu_id];}else{if(menus){var item=menus['item'];if(typeof(item.length)=='undefined'||item.length<1)item=new Array(item);if(item.length){for(var i=0;i'+str+' ';}}} +this.loaded_popup_menus[menu_id]=html;} +if(html){var area=$('#popup_menu_area').html('
    '+html+'
');var areaOffset={top:params['page_y'],left:params['page_x']};if(area.outerHeight()+areaOffset.top>$(window).height()+$(window).scrollTop()) +areaOffset.top=$(window).height()-area.outerHeight()+$(window).scrollTop();if(area.outerWidth()+areaOffset.left>$(window).width()+$(window).scrollLeft()) +areaOffset.left=$(window).width()-area.outerWidth()+$(window).scrollLeft();area.css({top:areaOffset.top,left:areaOffset.left}).show();}}}})(jQuery);jQuery(function($){if(!$('#popup_menu_area').length){var menuObj=$('
').attr('id','popup_menu_area').css({display:'none',zIndex:9999});$(document.body).append(menuObj);} +$(document).click(function(evt){var area=$('#popup_menu_area');if(!area.length)return;area.hide();var targetObj=$(evt.target);if(!targetObj.length)return;if(targetObj.length&&$.inArray(targetObj.attr('nodeName'),['DIV','SPAN','A'])==-1)targetObj=targetObj.parent();if(!targetObj.length||$.inArray(targetObj.attr('nodeName'),['DIV','SPAN','A'])==-1)return;var class_name=targetObj.attr('className');if(class_name.indexOf('_')<=0)return;var class_name_list=class_name.split(' ');var menu_id='';var menu_id_regx=/^([a-zA-Z]+)_([0-9]+)$/;for(var i=0,c=class_name_list.length;i-1)?first_enable[i]:j;}} +if(!disabled_exists)return;sels.oldonchange=sels.onchange;sels.onchange=function(){if(this.options[this.selectedIndex].disabled){this.selectedIndex=first_enable[i];}else{if(this.oldonchange)this.oldonchange();}};if(sels.selectedIndex>=0&&sels.options[sels.selectedIndex].disabled)sels.onchange();});} +var drEditorFold=$('.xe_content .fold_button');if(drEditorFold.size()){var fold_container=$('div.fold_container',drEditorFold);$('button.more',drEditorFold).click(function(){$(this).hide().next('button').show().parent().next(fold_container).show();});$('button.less',drEditorFold).click(function(){$(this).hide().prev('button').show().parent().next(fold_container).hide();});}});String.prototype.getQuery=function(key){var idx=this.indexOf('?');if(idx==-1)return null;var query_string=this.substr(idx+1,this.length);var args={};query_string.replace(/([^=]+)=([^&]*)(&|$)/g,function(){args[arguments[1]]=arguments[2];});var q=args[key];if(typeof(q)=="undefined")q="";return q;} +String.prototype.setQuery=function(key,val){var idx=this.indexOf('?');var uri=this;uri=uri.replace(/#$/,'');if(idx!=-1){uri=this.substr(0,idx);var query_string=this.substr(idx+1,this.length);var args=new Array();query_string.replace(/([^=]+)=([^&]*)(&|$)/g,function(){args[arguments[1]]=arguments[2];});args[key]=val;var q_list=new Array();for(var i in args){if(!args.hasOwnProperty(i))continue;var arg=args[i];if(!arg.toString().trim())continue;arg=decodeURI(arg);q_list[q_list.length]=i+'='+arg;} +uri=uri+"?"+q_list.join("&");}else{if(val.toString().trim())uri=uri+"?"+key+"="+val;} +var re=/https:\/\/([^:\/]+)(:\d+|)/i;var check=re.exec(uri);if(check) +{var toReplace="http://"+check[1];if(typeof(http_port)!='undefined'&&http_port!=80) +{toReplace+=":"+http_port;} +uri=uri.replace(re,toReplace);} +var bUseSSL=false;if(typeof(enforce_ssl)!='undefined'&&enforce_ssl) +{bUseSSL=true;} +else if(typeof(ssl_actions)!='undefined'&&typeof(ssl_actions.length)!='undefined'&&uri.getQuery('act')){var act=uri.getQuery('act');for(i=0;i-1&&!url.getQuery('vid'))url=url.setQuery('vid',xeVid);try{if(target!="_blank"&&winopen_list[target]){winopen_list[target].close();winopen_list[target]=null;}}catch(e){} +if(typeof(target)=='undefined')target='_blank';if(typeof(attribute)=='undefined')attribute='';var win=window.open(url,target,attribute);win.focus();if(target!="_blank")winopen_list[target]=win;} +function popopen(url,target){if(typeof(target)=="undefined")target="_blank";if(typeof(xeVid)!='undefined'&&url.indexOf(request_uri)>-1&&!url.getQuery('vid'))url=url.setQuery('vid',xeVid);winopen(url,target,"left=10,top=10,width=10,height=10,scrollbars=no,resizable=yes,toolbars=no");} +function sendMailTo(to){location.href="mailto:"+to;} +function move_url(url,open_wnidow){if(!url)return false;if(typeof(open_wnidow)=='undefined')open_wnidow='N';if(open_wnidow=='N'){open_wnidow=false;}else{open_wnidow=true;} +if(/^\./.test(url))url=request_uri+url;if(open_wnidow){winopen(url);}else{location.href=url;} +return false;} +function displayMultimedia(src,width,height,options){var html=_displayMultimedia(src,width,height,options);if(html)document.writeln(html);} +function _displayMultimedia(src,width,height,options){if(src.indexOf('files')==0)src=request_uri+src;var defaults={wmode:'transparent',allowScriptAccess:'sameDomain',quality:'high',flashvars:'',autostart:false};var params=jQuery.extend(defaults,options||{});var autostart=(params.autostart&¶ms.autostart!='false')?'true':'false';delete(params.autostart);var clsid="";var codebase="";var html="";if(/\.(gif|jpg|jpeg|bmp|png)$/i.test(src)){html='';}else if(/\.flv$/i.test(src)||/\.mov$/i.test(src)||/\.moov$/i.test(src)||/\.m4v$/i.test(src)){html='';}else if(/\.swf/i.test(src)){clsid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';if(typeof(enforce_ssl)!='undefined'&&enforce_ssl){codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0";} +else{codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0";} +html='';html+='';for(var name in params){if(params[name]!='undefined'&¶ms[name]!=''){html+='';}} +html+='' ++'' ++'';}else{if(jQuery.browser.mozilla||jQuery.browser.opera){autostart=(params.autostart&¶ms.autostart!='false')?'1':'0';} +html='400){$body.css({overflow:'auto',overflowX:'hidden',height:400+'px'});}} +var $win=$(window);var $pc=$('#popup_content');var w=Math.max($pc[0].offsetWidth,600);var h=$pc[0].offsetHeight;var dw=$win.width();var dh=$win.height();var _w=0,_h=0;if(w!=dw)_w=w-dw;if(h!=dh)_h=h-dh;if(_w||_h){window.resizeBy(_w,_h);} +if(!arguments.callee.executed){setTimeout(setFixedPopupSize,300);arguments.callee.executed=true;}} +function doCallModuleAction(module,action,target_srl){var params=new Array();params['target_srl']=target_srl;params['cur_mid']=current_mid;exec_xml(module,action,params,completeCallModuleAction);} +function completeCallModuleAction(ret_obj,response_tags){if(ret_obj['message']!='success')alert(ret_obj['message']);location.reload();} +function completeMessage(ret_obj){alert(ret_obj['message']);location.reload();} +function doChangeLangType(obj){if(typeof(obj)=="string"){setLangType(obj);}else{var val=obj.options[obj.selectedIndex].value;setLangType(val);} +location.reload();} +function setLangType(lang_type){var expire=new Date();expire.setTime(expire.getTime()+(7000*24*3600000));xSetCookie('lang_type',lang_type,expire,'/');} +function doDocumentPreview(obj){var fo_obj=obj;while(fo_obj.nodeName!="FORM"){fo_obj=fo_obj.parentNode;} +if(fo_obj.nodeName!="FORM")return;var editor_sequence=fo_obj.getAttribute('editor_sequence');var content=editorGetContent(editor_sequence);var win=window.open("","previewDocument","toolbars=no,width=700px;height=800px,scrollbars=yes,resizable=yes");var dummy_obj=jQuery("#previewDocument");if(!dummy_obj.length){jQuery('
'+''+''+''+'
').appendTo(document.body);dummy_obj=jQuery("#previewDocument")[0];} +if(dummy_obj){dummy_obj.content.value=content;dummy_obj.submit();}} +function doDocumentSave(obj){var editor_sequence=obj.form.getAttribute('editor_sequence');var prev_content=editorRelKeys[editor_sequence]['content'].value;if(typeof(editor_sequence)!='undefined'&&editor_sequence&&typeof(editorRelKeys)!='undefined'&&typeof(editorGetContent)=='function'){var content=editorGetContent(editor_sequence);editorRelKeys[editor_sequence]['content'].value=content;} +var params={},responses=['error','message','document_srl'],elms=obj.form.elements,data=jQuery(obj.form).serializeArray();;jQuery.each(data,function(i,field){var val=jQuery.trim(field.value);if(!val)return true;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;return false;} +function completeDocumentSave(ret_obj){jQuery('input[name=document_srl]').eq(0).val(ret_obj['document_srl']);alert(ret_obj['message']);} +var objForSavedDoc=null;function doDocumentLoad(obj){objForSavedDoc=obj.form;popopen(request_uri.setQuery('module','member').setQuery('act','dispSavedDocumentList'));} +function doDocumentSelect(document_srl){if(!opener||!opener.objForSavedDoc){window.close();return;} +opener.location.href=opener.current_url.setQuery('document_srl',document_srl).setQuery('act','dispBoardWrite');window.close();} +function viewSkinInfo(module,skin){popopen("./?module=module&act=dispModuleSkinInfo&selected_module="+module+"&skin="+skin,'SkinInfo');} +var addedDocument=new Array();function doAddDocumentCart(obj){var srl=obj.value;addedDocument[addedDocument.length]=srl;setTimeout(function(){callAddDocumentCart(addedDocument.length);},100);} +function callAddDocumentCart(document_length){if(addedDocument.length<1||document_length!=addedDocument.length)return;var params=new Array();params["srls"]=addedDocument.join(",");exec_xml("document","procDocumentAddCart",params,null);addedDocument=new Array();} +function transRGB2Hex(value){if(!value)return value;if(value.indexOf('#')>-1)return value.replace(/^#/,'');if(value.toLowerCase().indexOf('rgb')<0)return value;value=value.replace(/^rgb\(/i,'').replace(/\)$/,'');value_list=value.split(',');var hex='';for(var i=0;i>2;enc2=((chr1&3)<<4)|(chr2>>4);enc3=((chr2&15)<<2)|(chr3>>6);enc4=chr3&63;if(isNaN(chr2)){enc3=enc4=64;}else if(isNaN(chr3)){enc4=64;} +output=output+ +this._keyStr.charAt(enc1)+this._keyStr.charAt(enc2)+ +this._keyStr.charAt(enc3)+this._keyStr.charAt(enc4);} +return output;},decode:function(input){var output="";var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(i>4);chr2=((enc2&15)<<4)|(enc3>>2);chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){output=output+String.fromCharCode(chr2);} +if(enc4!=64){output=output+String.fromCharCode(chr3);}} +output=Base64._utf8_decode(output);return output;},_utf8_encode:function(string){string=string.replace(/\r\n/g,"\n");var utftext="";for(var n=0;n127)&&(c<2048)){utftext+=String.fromCharCode((c>>6)|192);utftext+=String.fromCharCode((c&63)|128);} +else{utftext+=String.fromCharCode((c>>12)|224);utftext+=String.fromCharCode(((c>>6)&63)|128);utftext+=String.fromCharCode((c&63)|128);}} +return utftext;},_utf8_decode:function(utftext){var string="";var i=0;var c=c1=c2=0;while(i191)&&(c<224)){c2=utftext.charCodeAt(i+1);string+=String.fromCharCode(((c&31)<<6)|(c2&63));i+=2;} +else{c2=utftext.charCodeAt(i+1);c3=utftext.charCodeAt(i+2);string+=String.fromCharCode(((c&15)<<12)|((c2&63)<<6)|(c3&63));i+=3;}} +return string;}} +if(typeof(resizeImageContents)=='undefined'){function resizeImageContents(){}} +if(typeof(activateOptionDisabled)=='undefined'){function activateOptionDisabled(){}} +objectExtend=jQuery.extend;function toggleDisplay(objId){jQuery('#'+objId).toggle();} +function checkboxSelectAll(formObj,name,checked){var itemName=name;var option={};if(typeof(formObj)!="undefined")option.wrap=formObj;if(typeof(checked)!="undefined")option.checked=checked;XE.checkboxToggleAll(itemName,option);} +function clickCheckBoxAll(formObj,name){var itemName=name;var option={doClick:true};if(typeof(formObj)!="undefined")option.wrap=formObj;XE.checkboxToggleAll(itemName,option);} +function svc_folder_open(id){jQuery("#_folder_open_"+id).hide();jQuery("#_folder_close_"+id).show();jQuery("#_folder_"+id).show();} +function svc_folder_close(id){jQuery("#_folder_open_"+id).show();jQuery("#_folder_close_"+id).hide();jQuery("#_folder_"+id).hide();} +function open_calendar(fo_id,day_str,callback_func){if(typeof(day_str)=="undefined")day_str="";var url="./common/tpl/calendar.php?";if(fo_id)url+="fo_id="+fo_id;if(day_str)url+="&day_str="+day_str;if(callback_func)url+="&callback_func="+callback_func;popopen(url,'Calendar');} +var loaded_popup_menus=XE.loaded_popup_menus;function createPopupMenu(){} +function chkPopupMenu(){} +function displayPopupMenu(ret_obj,response_tags,params){XE.displayPopupMenu(ret_obj,response_tags,params);} +function GetObjLeft(obj){return jQuery(obj).offset().left;} +function GetObjTop(obj){return jQuery(obj).offset().top;} +function replaceOuterHTML(obj,html){jQuery(obj).replaceWith(html);} +function getOuterHTML(obj){return jQuery(obj).html().trim();} +jQuery(function(){jQuery(".lang_code").each(function() {var objText=jQuery(this);var targetName=objText.attr("id");if(typeof(targetName)=="undefined")targetName=objText.attr("name");if(typeof(targetName)=="undefined")return;objText.after("find_langcode");});}); \ No newline at end of file diff --git a/common/js/js_app.js b/common/js/js_app.js index 592e0268b..c18aab213 100644 --- a/common/js/js_app.js +++ b/common/js/js_app.js @@ -1,17 +1,17 @@ -/** - * @file js_app.js - * @author taggon (gonom9@gmail.com) - * @brief XE JavaScript Application Framework (JAF) - * @namespace xe - * @update 20100701 - */ - -(function($){var _xe_base,_app_base,_plugin_base;var _apps=[];_xe_base={getName:function(){return'Core';},createApp:function(sName,oDef){var _base=getTypeBase();$.extend(_base.prototype,_app_base,oDef);_base.prototype.getName=function(){return sName;};return _base;},createPlugin:function(sName,oDef){var _base=getTypeBase();$.extend(_base.prototype,_plugin_base,oDef);_base.prototype.getName=function(){return sName;};return _base;},getApps:function(){return $.makeArray(_apps);},getApp:function(indexOrName){indexOrName=(indexOrName||'').toLowerCase();if(typeof _apps[indexOrName]!='undefined'){return _apps[indexOrName];}else{return null;}},registerApp:function(oApp){var sName=oApp.getName().toLowerCase();_apps.push(oApp);if(!$.isArray(_apps[sName])){_apps[sName]=[];} -_apps[sName].push(oApp);oApp.parent=this;if($.isFunction(oApp.activate))oApp.activate();},unregisterApp:function(oApp){var sName=oPlugin.getName().toLowerCase();var nIndex=$.inArray(oApp,_apps);if(nIndex>=0)_apps.splice(nIndex,1);if($.isArray(_apps[sName])){nIndex=$.inArray(oApp,_apps[sName]);if(nIndex>=0)_apps[sName].splice(nIndex,1);} -if($.isFunction(oApp.deactivate))oApp.deactivate();},broadcast:function(msg,params){this._broadcast(this,msg,params);},_broadcast:function(sender,msg,params){for(var i=0;i<_apps.length;i++){_apps[i]._cast(sender,msg,params);} -this._cast(sender,msg,params);}} -_app_base={_plugins:[],_messages:{},getPlugin:function(sPluginName){sPluginName=sPluginName.toLowerCase();if($.isArray(this._plugins[sPluginName])){return this._plugins[sPluginName];}else{return[];}},registerPlugin:function(oPlugin){var self=this;var sName=oPlugin.getName().toLowerCase();if($.inArray(oPlugin,this._plugins)>=0)return false;this._plugins.push(oPlugin);if(!$.isArray(this._plugins[sName]))this._plugins[sName]=[];this._plugins[sName].push(oPlugin);$.each(oPlugin._binded_fn,function(api,fn){self.registerHandler(api,fn);});oPlugin.oApp=this;if($.isFunction(oPlugin.activate))oPlugin.activate();return true;},registerHandler:function(api,func){var msgs=this._messages;api=api.toUpperCase();if(!$.isArray(msgs[api]))msgs[api]=[];msgs[api].push(func);},cast:function(msg,params){return this._cast(this,msg,params||[]);},broadcast:function(sender,msg,params){if(this.parent&&this.parent._broadcast){this.parent._broadcast(sender,msg,params);}},_cast:function(sender,msg,params){var i,len;var aMsg=this._messages;msg=msg.toUpperCase();if(aMsg['BEFORE_'+msg]||this['API_BEFORE_'+msg]){var bContinue=this._cast(sender,'BEFORE_'+msg,params);if(!bContinue)return;} -var vRet=[],sFn='API_'+msg;if($.isArray(aMsg[msg])){for(i=0;i=0)_apps.splice(nIndex,1);if($.isArray(_apps[sName])){nIndex=$.inArray(oApp,_apps[sName]);if(nIndex>=0)_apps[sName].splice(nIndex,1);} +if($.isFunction(oApp.deactivate))oApp.deactivate();},broadcast:function(msg,params){this._broadcast(this,msg,params);},_broadcast:function(sender,msg,params){for(var i=0;i<_apps.length;i++){_apps[i]._cast(sender,msg,params);} +this._cast(sender,msg,params);}} +_app_base={_plugins:[],_messages:{},getPlugin:function(sPluginName){sPluginName=sPluginName.toLowerCase();if($.isArray(this._plugins[sPluginName])){return this._plugins[sPluginName];}else{return[];}},registerPlugin:function(oPlugin){var self=this;var sName=oPlugin.getName().toLowerCase();if($.inArray(oPlugin,this._plugins)>=0)return false;this._plugins.push(oPlugin);if(!$.isArray(this._plugins[sName]))this._plugins[sName]=[];this._plugins[sName].push(oPlugin);$.each(oPlugin._binded_fn,function(api,fn){self.registerHandler(api,fn);});oPlugin.oApp=this;if($.isFunction(oPlugin.activate))oPlugin.activate();return true;},registerHandler:function(api,func){var msgs=this._messages;api=api.toUpperCase();if(!$.isArray(msgs[api]))msgs[api]=[];msgs[api].push(func);},cast:function(msg,params){return this._cast(this,msg,params||[]);},broadcast:function(sender,msg,params){if(this.parent&&this.parent._broadcast){this.parent._broadcast(sender,msg,params);}},_cast:function(sender,msg,params){var i,len;var aMsg=this._messages;msg=msg.toUpperCase();if(aMsg['BEFORE_'+msg]||this['API_BEFORE_'+msg]){var bContinue=this._cast(sender,'BEFORE_'+msg,params);if(!bContinue)return;} +var vRet=[],sFn='API_'+msg;if($.isArray(aMsg[msg])){for(i=0;i 9?v['m']:'0'+v['m']; - - // 연간 달력이 아니라면 이 달의 날짜를 구한다. - if (cal.options.type != 'month') { - // 날짜에 사용할 달력 - v['weeks'] = []; - - var d = new Date(cal.date.getTime()), w = []; - var last = (v.m!=2)? ((v.m+(v.m>7?1:0))%2?31:30) : ((new Date(v.yyyy,v.m-1,29)).getMonth()==v.m?29:28); // 마지막 날 - - d.setDate(1); // 1일로 설정 후 1일의 요일을 가져온다. - var start = d.getDay(), end = last+start; - - for(var i=0,len=end+(7-(end%7||7));i= end) w.push(' '); - else w.push(''); - } - } - - // 템플릿 처리 - tpl = this._processTemplate(tpl, v); - obj.html(tpl); - - // 선택한 날짜 - if (cal.options.type == 'month') { - - } else { - var t = new Date(); - obj.find('td>button.day'+t.getFullYear()+'-'+(t.getMonth()+1)+'-'+t.getDate()).addClass('today'); - - t = cal.activeDate; - obj.find('td>button.day'+t.getFullYear()+'-'+(t.getMonth()+1)+'-'+t.getDate()).addClass('active'); - } - - // 이벤트 핸들러 - obj.find('button.close').click(function(){ $.calendar._hide(obj); }); - obj.find('button.today').click(function(){ $.calendar._moveToday(obj); }); - if (cal.options.type == 'month') { - obj.find('button.prev').click(function(){ $.calendar._prevYear(obj) }); - obj.find('button.next').click(function(){ $.calendar._nextYear(obj) }); - } else { - obj.find('button.prev').click(function(){ $.calendar._prevMonth(obj) }); - obj.find('button.next').click(function(){ $.calendar._nextMonth(obj) }); - obj.find('button.prev_year').click(function(){ $.calendar._prevYear(obj) }); - obj.find('button.next_year').click(function(){ $.calendar._nextYear(obj) }); - } - obj.find('td>button').click(function(){ $.calendar._selectDate(obj, $(this)) }); - }, - _selectDate : function(obj, btn) { - var cal = calendars[ this._getuid(obj) ]; - var date = btn.attr('class').match(/day([\d\-]+)/); - if (!date) return; - - date = date[1].split('-'); - - var ad = cal.activeDate; - ad.setFullYear(date[0]-0); - ad.setMonth(date[1]-1); - ad.setDate(date[2]-0); - - this._setDate(obj, ad); - }, - _setDate : function(obj, newDate) { - var uid = this._getuid(obj); - if (uid < 0) return null; - if (!newDate || !(newDate instanceof Date)) newDate = new Date(); - - var cal = calendars[uid]; - cal.activeDate = new Date(newDate.getTime()); - cal.date = new Date(newDate.getTime()); - this._draw(obj); - - if ($.isFunction(cal.options.select) && obj.hasClass('ui-calendar')) { - cal.options.select(newDate.getFullYear(), newDate.getMonth()+1, newDate.getDate()); - } - }, - _getDate : function(obj, format) { - var uid = this._getuid(obj); - if (uid < 0) return null; - if (typeof format != 'string') return calendars[uid].activeDate; - - // format string - }, - _moveToday : function(obj) { - calendars[this._getuid(obj)].date = new Date(); - this._draw(obj); - }, - _prevMonth : function(obj) { - var cal = calendars[this._getuid(obj)]; - var m = cal.date.getMonth(); - - cal.date.setDate(1); - if (m == 0) { - cal.date.setFullYear(cal.date.getFullYear()-1); - cal.date.setMonth(11); - } else { - cal.date.setMonth(m-1); - } - - this._draw(obj); - }, - _nextMonth : function(obj) { - var cal = calendars[this._getuid(obj)]; - var m = cal.date.getMonth(); - - cal.date.setDate(1); - if (m == 11) { - cal.date.setFullYear(cal.date.getFullYear()+1); - cal.date.setMonth(0); - } else { - cal.date.setMonth(m+1); - } - - this._draw(obj); - }, - _prevYear : function(obj) { - var cal = calendars[this._getuid(obj)]; - - cal.date.setFullYear(cal.date.getFullYear()-1); - this._draw(obj); - }, - _nextYear : function(obj) { - var cal = calendars[this._getuid(obj)]; - - cal.date.setFullYear(cal.date.getFullYear()+1); - this._draw(obj); - } -}); - -/** - * Invoke the calednar functionallity - * @return jQuery object - */ -$.fn.calendar = function(options) { - var args = $.makeArray(arguments); - - if (!$.calendar.initialized) { - $(document).mousedown($.calendar._checkExternalClick); - $.calendar.initialized = true; - } - - if (typeof options == 'string' && $.inArray(options, ['getDate'])) { - args.shift(); - return $.calendar['_'+options].apply($.calendar, [$(this[0])].concat(args) ); - } - - return this.each(function(){ - if (typeof options == 'string') { - args.shift(); - $.calendar['_'+ options].apply($.calendar, [$(this)].concat(args)); - } else { - $.calendar._attachCalendar($(this), options); - } - }); -} - -$.calendar = new Calendar(); // singleton instance -$.calendar.initialized = false; -$.calendar.uuid = new Date().getTime(); -$.calendar.version = $.ui.calendar.version; - -// template -template.calendar = '\ -\ -\ -\ - \ - \ - \ - \ - \ - \ - \ - \ - \ -\ -\ - {@week in weeks}\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - {/}\ -\ -
\ - \ - {yyyy}.{mm}.\ - \ - \ - \ - \ - \ - \ -
{lang.weekdays[0]}{lang.weekdays[1]}{lang.weekdays[2]}{lang.weekdays[3]}{lang.weekdays[4]}{lang.weekdays[5]}{lang.weekdays[6]}
{week[0]}{week[1]}{week[2]}{week[3]}{week[4]}{week[5]}{week[6]}
\ -'; - -template.month = '\ -\ -\ -\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -\ -
\ - \ - {yyyy}.{mm} \ - \ - \ - \ -
\ -'; - +/** + * @brief XE Calendar + * @author NHN (developers@xpressengine.com) + * + * 사용법 + * + **/ +(function($){ + +if (!$.ui) $.ui = {}; +$.extend($.ui, { calendar: { version:'0.3' } }); + +var PROP_NAME = 'calendar'; +var index = 0; +var calendars = {}; +var template = {calendar:'',month:''}; + +function Calendar() { +} + +$.extend(Calendar.prototype, { + _activeCalendar : null, + _getuid : function(obj) { + var uid = obj.attr('class').match(/ui-calendar-(\d+-\d+)/); + + if (!uid) return -1; + return uid[1]; + }, + _show : function(obj) { + if (this._activeCalendar) this._hide(this._activeCalendar); + + // disabled? + if (obj.hasClass('ui-calendar-disabled')) return; + + // Active Calendar + this._activeCalendar = obj.show(300); + }, + _hide : function(obj) { + if (this._activeCalendar && this._activeCalendar.get(0) == obj.get(0)) this._activeCalendar = null; + obj.hide(300); + }, + _toggle : function(obj) { + (obj.css('display' ) == 'none')?this._show(obj):this._hide(obj); + }, + _attachCalendar : function(obj, options) { + if ((obj=$(obj)).hasClass('ui-calendar')) return; + + var uid = $.calendar.uuid+'-'+(index++); + var c = calendars[uid] = {}; + + // uid 추가 + obj.addClass('ui-calendar-'+uid).mousedown(function(){return false}); + + // default options + c.options = $.extend({ + type : 'day', + activeDate : '' + }, options||{}); + c.lang = $.extend({ + weekdays : 'Sun,Mon,Tue,Wed,Thu,Fri,Sat', + today : 'Today', + prevmonth : 'Prev Month', + nextmonth : 'Next Month', + prevyear : 'Prev Year', + nextyear : 'Next Year', + close : 'Close' + }, options.lang||{}); + + c.lang.weekdays = c.lang.weekdays.split(','); + + // 날짜 설정 + var d; + if (typeof c.options.activeDate == 'string' && c.options.activeDate) { + var s = c.options.activeDate.split('/'); + d = new Date(s[0], s[1]-1, s[2]-0); + } else { + d = new Date(); + } + this._setDate(obj, d); + + // 토글 버튼 + if (c.options.button) { + (c.button=$(c.options.button)).click(function(){ obj.calendar('toggle') }); + } + + // 클래스 추가 + obj.addClass('ui-calendar'); + + // position 설정한 후, 좌표를 (0,0)으로 변경 + var pos = obj.css({position:'absolute',top:0,left:0}).show().offset(); + + // 버튼의 위치 구해서 좌표 조정 + var bpos = c.button.offset(); + var dx = bpos.left - pos.left; + var dy = bpos.top - pos.top; + + // 좌표 조정 후 레이어 숨김 + obj.css({top:(dy+c.button.height())+'px',left:dx+'px'}).hide(); + }, + _checkExternalClick : function(e) { + if ($.calendar._activeCalendar) $.calendar._hide($.calendar._activeCalendar); + }, + _processTemplate : function(tpl, vars) { + tpl = (' '+tpl+' ').split(/[\{\}]/g); + + for(var i=0; i < tpl.length; i++) { + if (i%2) { + if (/^[\w\.\[\]]+$/.test(tpl[i])) tpl[i] = 'try{v=vv.'+tpl[i]+'}catch(e){v=""};ret.push(v);'; + else if (/^@(\w+)\s+in\s+(\w+)$/.test(tpl[i])) tpl[i] = 'for(i=0,l=vv.'+RegExp.$2+'.length;i 9?v['m']:'0'+v['m']; + + // 연간 달력이 아니라면 이 달의 날짜를 구한다. + if (cal.options.type != 'month') { + // 날짜에 사용할 달력 + v['weeks'] = []; + + var d = new Date(cal.date.getTime()), w = []; + var last = (v.m!=2)? ((v.m+(v.m>7?1:0))%2?31:30) : ((new Date(v.yyyy,v.m-1,29)).getMonth()==v.m?29:28); // 마지막 날 + + d.setDate(1); // 1일로 설정 후 1일의 요일을 가져온다. + var start = d.getDay(), end = last+start; + + for(var i=0,len=end+(7-(end%7||7));i= end) w.push(' '); + else w.push(''); + } + } + + // 템플릿 처리 + tpl = this._processTemplate(tpl, v); + obj.html(tpl); + + // 선택한 날짜 + if (cal.options.type == 'month') { + + } else { + var t = new Date(); + obj.find('td>button.day'+t.getFullYear()+'-'+(t.getMonth()+1)+'-'+t.getDate()).addClass('today'); + + t = cal.activeDate; + obj.find('td>button.day'+t.getFullYear()+'-'+(t.getMonth()+1)+'-'+t.getDate()).addClass('active'); + } + + // 이벤트 핸들러 + obj.find('button.close').click(function(){ $.calendar._hide(obj); }); + obj.find('button.today').click(function(){ $.calendar._moveToday(obj); }); + if (cal.options.type == 'month') { + obj.find('button.prev').click(function(){ $.calendar._prevYear(obj) }); + obj.find('button.next').click(function(){ $.calendar._nextYear(obj) }); + } else { + obj.find('button.prev').click(function(){ $.calendar._prevMonth(obj) }); + obj.find('button.next').click(function(){ $.calendar._nextMonth(obj) }); + obj.find('button.prev_year').click(function(){ $.calendar._prevYear(obj) }); + obj.find('button.next_year').click(function(){ $.calendar._nextYear(obj) }); + } + obj.find('td>button').click(function(){ $.calendar._selectDate(obj, $(this)) }); + }, + _selectDate : function(obj, btn) { + var cal = calendars[ this._getuid(obj) ]; + var date = btn.attr('class').match(/day([\d\-]+)/); + if (!date) return; + + date = date[1].split('-'); + + var ad = cal.activeDate; + ad.setFullYear(date[0]-0); + ad.setMonth(date[1]-1); + ad.setDate(date[2]-0); + + this._setDate(obj, ad); + }, + _setDate : function(obj, newDate) { + var uid = this._getuid(obj); + if (uid < 0) return null; + if (!newDate || !(newDate instanceof Date)) newDate = new Date(); + + var cal = calendars[uid]; + cal.activeDate = new Date(newDate.getTime()); + cal.date = new Date(newDate.getTime()); + this._draw(obj); + + if ($.isFunction(cal.options.select) && obj.hasClass('ui-calendar')) { + cal.options.select(newDate.getFullYear(), newDate.getMonth()+1, newDate.getDate()); + } + }, + _getDate : function(obj, format) { + var uid = this._getuid(obj); + if (uid < 0) return null; + if (typeof format != 'string') return calendars[uid].activeDate; + + // format string + }, + _moveToday : function(obj) { + calendars[this._getuid(obj)].date = new Date(); + this._draw(obj); + }, + _prevMonth : function(obj) { + var cal = calendars[this._getuid(obj)]; + var m = cal.date.getMonth(); + + cal.date.setDate(1); + if (m == 0) { + cal.date.setFullYear(cal.date.getFullYear()-1); + cal.date.setMonth(11); + } else { + cal.date.setMonth(m-1); + } + + this._draw(obj); + }, + _nextMonth : function(obj) { + var cal = calendars[this._getuid(obj)]; + var m = cal.date.getMonth(); + + cal.date.setDate(1); + if (m == 11) { + cal.date.setFullYear(cal.date.getFullYear()+1); + cal.date.setMonth(0); + } else { + cal.date.setMonth(m+1); + } + + this._draw(obj); + }, + _prevYear : function(obj) { + var cal = calendars[this._getuid(obj)]; + + cal.date.setFullYear(cal.date.getFullYear()-1); + this._draw(obj); + }, + _nextYear : function(obj) { + var cal = calendars[this._getuid(obj)]; + + cal.date.setFullYear(cal.date.getFullYear()+1); + this._draw(obj); + } +}); + +/** + * Invoke the calednar functionallity + * @return jQuery object + */ +$.fn.calendar = function(options) { + var args = $.makeArray(arguments); + + if (!$.calendar.initialized) { + $(document).mousedown($.calendar._checkExternalClick); + $.calendar.initialized = true; + } + + if (typeof options == 'string' && $.inArray(options, ['getDate'])) { + args.shift(); + return $.calendar['_'+options].apply($.calendar, [$(this[0])].concat(args) ); + } + + return this.each(function(){ + if (typeof options == 'string') { + args.shift(); + $.calendar['_'+ options].apply($.calendar, [$(this)].concat(args)); + } else { + $.calendar._attachCalendar($(this), options); + } + }); +} + +$.calendar = new Calendar(); // singleton instance +$.calendar.initialized = false; +$.calendar.uuid = new Date().getTime(); +$.calendar.version = $.ui.calendar.version; + +// template +template.calendar = '\ +\ +\ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +\ +\ + {@week in weeks}\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + {/}\ +\ +
\ + \ + {yyyy}.{mm}.\ + \ + \ + \ + \ + \ + \ +
{lang.weekdays[0]}{lang.weekdays[1]}{lang.weekdays[2]}{lang.weekdays[3]}{lang.weekdays[4]}{lang.weekdays[5]}{lang.weekdays[6]}
{week[0]}{week[1]}{week[2]}{week[3]}{week[4]}{week[5]}{week[6]}
\ +'; + +template.month = '\ +\ +\ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +\ +
\ + \ + {yyyy}.{mm} \ + \ + \ + \ +
\ +'; + })(jQuery); \ No newline at end of file diff --git a/common/js/plugins/ui.colorpicker/xe_colorpicker.js b/common/js/plugins/ui.colorpicker/xe_colorpicker.js index a88aecb31..8e592ce4d 100644 --- a/common/js/plugins/ui.colorpicker/xe_colorpicker.js +++ b/common/js/plugins/ui.colorpicker/xe_colorpicker.js @@ -1,366 +1,366 @@ -/** - * @brief XE Colorpicker - * @author mygony (http://mygony.com) - **/ -jQuery(function($){ - var ready = false; - var tmp = $('').hide(); - // var panel = null; - - $.fn.xe_colorpicker = function(settings){ - var selection = this; - - if (!ready) { - ColorPicker.init(settings); - ready = true; - } - - this.each(function(){ - var col = color($(this).val()); - - $(this).val( col ).css('background-color', col ); - setTextColor( $(this) ); - }).focus(function(event){ - var t = this; - $(this).select(); - - // show color picker - ColorPicker.show(this); - }).keypress(function(event){ - if (!ColorPicker.is(':visible')) return; - - if (/^#?[0-9a-f]{6}$/i.test( event.target.value )) { - ColorPicker.color( event.target.value ); - } - }); - - $(document).mousedown(function(event){ - var target = event.target; - - if (selection.index(target) > -1) return; - if ($(target).parents().add(target).index(ColorPicker.element) > -1) return; - if ($(target).parents().add(target).index(ColorPicker.buttons) > -1) return; - - ColorPicker.hide(); - }); - - return this; - }; - - var ColorPicker = { - element : null, - picker : null, - colpane: null, - buttons : null, - _target : null, - _backup : null, - _hsv : null, - _mode : 'none', - - init : function() { - var cp = this; - - this.element = $('
'); - - this.picker = this.element.find('> div.colorpicker'); - this.colpane = this.picker.find('div.colortable > div.background'); - this.colpoint = this.colpane.find('> .indicator'); - this.buttons = this.element.find('> div.buttons'); - this.huepane = this.element.find('div.huebar > .background'); - this.huepoint = this.huepane.find('> .indicator'); - - this._mousedown = method(this.onmousedown, this); - this._mousemove = method(this.onmousemove, this); - this._mouseup = method(this.onmouseup, this); - - this.picker.find('.background').mousedown(this._mousedown); - - this.buttons.find('button.ok').click(method(this.ok,this)); - this.buttons.find('button.cancel').click(method(this.cancel,this)); - this.buttons.find('button.none').click(method(this.none,this)); - - // only for IE6 - if ($.browser.msie && parseInt($.browser.version) < 7) { - this.element.append( $(''.replace(/%id%/g, frame_id)).appendTo(document.body); - } - - $('#'+form_id).remove(); - var form = $('
'.replace(/%id%/g, form_id)).attr({ - 'id' : form_id, - 'method' : 'post', - 'action' : url, - 'target' : frame_id - }); - - params['xeVirtualRequestMethod'] = 'xml'; - params['xeRequestURI'] = location.href.replace(/#(.*)$/i,''); - params['xeVirtualRequestUrl'] = request_uri; - - $.each(params, function(key, value){ - $('').attr('name', key).attr('value', value).appendTo(form); - }); - - form.appendTo(document.body).submit(); -} -function arr2obj(arr) { - var ret = {}; - for(var key in arr) { - if(arr.hasOwnProperty(key)) ret[key] = arr[key]; - } - return ret; -} - -/** - * @brief exec_json (exec_xml와 같은 용도) - **/ -$.exec_json = function(action,data,func){ - if(typeof(data) == 'undefined') data = {}; - action = action.split("."); - if(action.length == 2){ - - if(show_waiting_message) { - $("#waitingforserverresponse").html(waiting_message).css('top',$(document).scrollTop()+20).css('left',$(document).scrollLeft()+20).css('visibility','visible'); - } - - $.extend(data,{module:action[0],act:action[1]}); - if(typeof(xeVid)!='undefined') $.extend(data,{vid:xeVid}); - $.ajax({ - type:"POST" - ,dataType:"json" - ,url:request_uri - ,contentType:"application/json" - ,data:$.param(data) - ,success : function(data){ - $("#waitingforserverresponse").css('visibility','hidden'); - if(data.error > 0) alert(data.message); - if($.isFunction(func)) func(data); - } - }); - } -}; - -$.fn.exec_html = function(action,data,type,func,args){ - if(typeof(data) == 'undefined') data = {}; - if(!$.inArray(type, ['html','append','prepend'])) type = 'html'; - - var self = $(this); - action = action.split("."); - if(action.length == 2){ - if(show_waiting_message) { - $("#waitingforserverresponse").html(waiting_message).css('top',$(document).scrollTop()+20).css('left',$(document).scrollLeft()+20).css('visibility','visible'); - } - - $.extend(data,{module:action[0],act:action[1]}); - $.ajax({ - type:"POST" - ,dataType:"html" - ,url:request_uri - ,data:$.param(data) - ,success : function(html){ - $("#waitingforserverresponse").css('visibility','hidden'); - self[type](html); - if($.isFunction(func)) func(args); - } - }); - } -}; -})(jQuery); +/** + * @file common/js/xml_handler.js + * @brief XE에서 ajax기능을 이용함에 있어 module, act를 잘 사용하기 위한 자바스크립트 + **/ + +// xml handler을 이용하는 user function +var show_waiting_message = true; + +/* This work is licensed under Creative Commons GNU LGPL License. + + License: http://creativecommons.org/licenses/LGPL/2.1/ + Version: 0.9 + Author: Stefan Goessner/2006 + Web: http://goessner.net/ +*/ +function xml2json(xml, tab, ignoreAttrib) { + var X = { + toObj: function(xml) { + var o = {}; + if (xml.nodeType==1) { // element node .. + if (ignoreAttrib && xml.attributes.length) // element with attributes .. + for (var i=0; i 1) + o = X.escape(X.innerXml(xml)); + else + for (var n=xml.firstChild; n; n=n.nextSibling){ + //o["#cdata"] = X.escape(n.nodeValue); + o = X.escape(n.nodeValue); + } + } + } + if (!xml.attributes.length && !xml.firstChild) o = null; + } + else if (xml.nodeType==9) { // document.node + o = X.toObj(xml.documentElement); + } + else + alert("unhandled node type: " + xml.nodeType); + return o; + }, + toJson: function(o, name, ind) { + var json = name ? ("\""+name+"\"") : ""; + if (o instanceof Array) { + for (var i=0,n=o.length; i 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]"; + } + else if (o == null) + json += (name&&":") + "null"; + else if (typeof(o) == "object") { + var arr = []; + for (var m in o) + arr[arr.length] = X.toJson(o[m], m, ind+"\t"); + json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}"; + } + else if (typeof(o) == "string") + json += (name&&":") + "\"" + o.toString() + "\""; + else + json += (name&&":") + o.toString(); + return json; + }, + innerXml: function(node) { + var s = "" + if ("innerHTML" in node) + s = node.innerHTML; + else { + var asXml = function(n) { + var s = ""; + if (n.nodeType == 1) { + s += "<" + n.nodeName; + for (var i=0; i"; + } + else + s += "/>"; + } + else if (n.nodeType == 3) + s += n.nodeValue; + else if (n.nodeType == 4) + s += ""; + return s; + }; + for (var c=node.firstChild; c; c=c.nextSibling) + s += asXml(c); + } + return s; + }, + escape: function(txt) { + return txt.replace(/[\\]/g, "\\\\") + .replace(/[\"]/g, '\\"') + .replace(/[\n]/g, '\\n') + .replace(/[\r]/g, '\\r'); + }, + removeWhite: function(e) { + e.normalize(); + for (var n = e.firstChild; n; ) { + if (n.nodeType == 3) { // text node + if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node + var nxt = n.nextSibling; + e.removeChild(n); + n = nxt; + } + else + n = n.nextSibling; + } + else if (n.nodeType == 1) { // element node + X.removeWhite(n); + n = n.nextSibling; + } + else // any other node + n = n.nextSibling; + } + return e; + } + }; + if (xml.nodeType == 9) // document node + xml = xml.documentElement; + + var json_obj = X.toObj(X.removeWhite(xml)), json_str; + + if (typeof(JSON)=='object' && jQuery.isFunction(JSON.stringify) && false) { + var obj = {}; obj[xml.nodeName] = json_obj; + json_str = JSON.stringify(obj); + return json_str; + } else { + json_str = X.toJson(json_obj, xml.nodeName, ""); + return "{" + (tab ? json_str.replace(/\t/g, tab) : json_str.replace(/\t|\n/g, "")) + "}"; + } +} + +(function($){ +/** + * @brief exec_xml + * @author NHN (developers@xpressengine.com) + **/ +$.exec_xml = window.exec_xml = function(module, act, params, callback_func, response_tags, callback_func_arg, fo_obj) { + var xml_path = request_uri+"index.php" + if(!params) params = {}; + + // {{{ set parameters + if($.isArray(params)) params = arr2obj(params); + params['module'] = module; + params['act'] = act; + + if(typeof(xeVid)!='undefined') params['vid'] = xeVid; + if(typeof(response_tags)=="undefined" || response_tags.length<1) response_tags = ['error','message']; + else { + response_tags.push('error', 'message'); + } + // }}} set parameters + + // use ssl? + if ($.isArray(ssl_actions) && params['act'] && $.inArray(params['act'], ssl_actions) >= 0) + { + var url = default_url || request_uri; + var port = window.https_port || 443; + var _ul = $('').attr('href', url)[0]; + var target = 'https://' + _ul.hostname.replace(/:\d+$/, ''); + + if(port != 443) target += ':'+port; + if(_ul.pathname[0] != '/') target += '/'; + + target += _ul.pathname; + xml_path = target.replace(/\/$/, '')+'/index.php'; + } + + var _u1 = $('').attr('href', location.href)[0]; + var _u2 = $('').attr('href', xml_path)[0]; + + // 현 url과 ajax call 대상 url의 schema 또는 port가 다르면 직접 form 전송 + if(_u1.protocol != _u2.protocol || _u1.port != _u2.port) return send_by_form(xml_path, params); + + var xml = [], i = 0; + xml[i++] = ''; + xml[i++] = ''; + xml[i++] = ''; + + $.each(params, function(key, val) { + xml[i++] = '<'+key+'>'; + }); + + xml[i++] = ''; + xml[i++] = ''; + + var _xhr = null; + if (_xhr && _xhr.readyState != 0) _xhr.abort(); + + // 전송 성공시 + function onsuccess(data, textStatus, xhr) { + var resp_xml = $(data).find('response')[0], resp_obj, txt='', ret=[], tags={}, json_str=''; + + waiting_obj.css('visibility', 'hidden'); + + if(!resp_xml) { + alert(_xhr.responseText); + return null; + } + + json_str = xml2json(resp_xml, false, false); + resp_obj = (typeof(JSON)=='object' && $.isFunction(JSON.parse))?JSON.parse(json_str):eval('('+json_str+')'); + resp_obj = resp_obj.response; + + if (typeof(resp_obj)=='undefined') { + ret['error'] = -1; + ret['message'] = 'Unexpected error occured.'; + try { + if(typeof(txt=resp_xml.childNodes[0].firstChild.data)!='undefined') ret['message'] += '\r\n'+txt; + } catch(e){}; + return ret; + } + + $.each(response_tags, function(key, val){ tags[val] = true; }); + tags["redirect_url"] = true; + tags["act"] = true; + $.each(resp_obj, function(key, val){ if(tags[key]) ret[key] = val; }); + + if(ret['error'] != 0) { + if ($.isFunction($.exec_xml.onerror)) { + return $.exec_xml.onerror(module, act, ret, callback_func, response_tags, callback_func_arg, fo_obj); + } + + alert(ret['message'] || 'error!'); + return null; + } + + if(ret['redirect_url']) { + location.href = ret['redirect_url'].replace(/&/g, '&'); + return null; + } + + if($.isFunction(callback_func)) callback_func(ret, response_tags, callback_func_arg, fo_obj); + } + + // 모든 xml데이터는 POST방식으로 전송. try-catch문으로 오류 발생시 대처 + try { + $.ajax({ + url : xml_path, + type : 'POST', + dataType : 'xml', + data : xml.join('\n'), + contentType : 'text/plain', + beforeSend : function(xhr){ _xhr = xhr; }, + success : onsuccess, + error : function(xhr, textStatus) { + waiting_obj.css('visibility', 'hidden'); + + var msg = ''; + if (textStatus == 'parsererror') { + msg = 'The result is not valid XML :\n-------------------------------------\n'; + if(xhr.responseText == "") return; + msg += xhr.responseText.replace(/<[^>]+>/g, ''); + } else { + msg = textStatus; + } + + alert(msg); + } + }); + } catch(e) { + alert(e); + return; + } + + // ajax 통신중 대기 메세지 출력 (show_waiting_message값을 false로 세팅시 보이지 않음) + var waiting_obj = $('#waitingforserverresponse'); + if(show_waiting_message && waiting_obj.length) { + var d = $(document); + waiting_obj.html(waiting_message).css({ + 'top' : (d.scrollTop()+20)+'px', + 'left' : (d.scrollLeft()+20)+'px', + 'visibility' : 'visible' + }); + } +} +function send_by_form(url, params) { + var frame_id = 'xeTmpIframe'; + var form_id = 'xeVirtualForm'; + + if (!$('#'+frame_id).length) { + $(''.replace(/%id%/g, frame_id)).appendTo(document.body); + } + + $('#'+form_id).remove(); + var form = $('
'.replace(/%id%/g, form_id)).attr({ + 'id' : form_id, + 'method' : 'post', + 'action' : url, + 'target' : frame_id + }); + + params['xeVirtualRequestMethod'] = 'xml'; + params['xeRequestURI'] = location.href.replace(/#(.*)$/i,''); + params['xeVirtualRequestUrl'] = request_uri; + + $.each(params, function(key, value){ + $('').attr('name', key).attr('value', value).appendTo(form); + }); + + form.appendTo(document.body).submit(); +} +function arr2obj(arr) { + var ret = {}; + for(var key in arr) { + if(arr.hasOwnProperty(key)) ret[key] = arr[key]; + } + return ret; +} + +/** + * @brief exec_json (exec_xml와 같은 용도) + **/ +$.exec_json = function(action,data,func){ + if(typeof(data) == 'undefined') data = {}; + action = action.split("."); + if(action.length == 2){ + + if(show_waiting_message) { + $("#waitingforserverresponse").html(waiting_message).css('top',$(document).scrollTop()+20).css('left',$(document).scrollLeft()+20).css('visibility','visible'); + } + + $.extend(data,{module:action[0],act:action[1]}); + if(typeof(xeVid)!='undefined') $.extend(data,{vid:xeVid}); + $.ajax({ + type:"POST" + ,dataType:"json" + ,url:request_uri + ,contentType:"application/json" + ,data:$.param(data) + ,success : function(data){ + $("#waitingforserverresponse").css('visibility','hidden'); + if(data.error > 0) alert(data.message); + if($.isFunction(func)) func(data); + } + }); + } +}; + +$.fn.exec_html = function(action,data,type,func,args){ + if(typeof(data) == 'undefined') data = {}; + if(!$.inArray(type, ['html','append','prepend'])) type = 'html'; + + var self = $(this); + action = action.split("."); + if(action.length == 2){ + if(show_waiting_message) { + $("#waitingforserverresponse").html(waiting_message).css('top',$(document).scrollTop()+20).css('left',$(document).scrollLeft()+20).css('visibility','visible'); + } + + $.extend(data,{module:action[0],act:action[1]}); + $.ajax({ + type:"POST" + ,dataType:"html" + ,url:request_uri + ,data:$.param(data) + ,success : function(html){ + $("#waitingforserverresponse").css('visibility','hidden'); + self[type](html); + if($.isFunction(func)) func(args); + } + }); + } +}; +})(jQuery); diff --git a/common/js/src/xml_js_filter.js b/common/js/src/xml_js_filter.js index 6113346ef..d2cedc243 100644 --- a/common/js/src/xml_js_filter.js +++ b/common/js/src/xml_js_filter.js @@ -1,301 +1,301 @@ -/** - * @file common/js/xml_js_filter.js - * @author taggon (taggon@gmail.com) - * @brief xml filter (validator) plugin - * - * A rule is a method validate one field. - * A filter is made up of one or more rules. - **/ -(function($){ - -var messages = []; -var rules = []; -var filters = []; -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; - - var params = [oForm, filter]; - var result = this.cast('VALIDATE', params); - if (typeof result == 'undefined') result = false; - - return result; - }, - 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.minlength) || 0; - var maxlen = parseInt(this.maxlength) || 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 && val.length < minlen) || (maxlen && 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 (minlen||maxlen) 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 - * @brief ajax로 서버에 요청후 결과를 처리할 callback_function을 지정하지 않았을 시 호출되는 기본 함수 - **/ -function filterAlertMessage(ret_obj) { - var error = ret_obj["error"]; - var message = ret_obj["message"]; - var act = ret_obj["act"]; - var redirect_url = ret_obj["redirect_url"]; - var url = location.href; - - if(typeof(message)!="undefined"&&message&&message!="success") alert(message); - - if(typeof(act)!="undefined" && act) url = current_url.setQuery("act", act); - else if(typeof(redirect_url)!="undefined" && redirect_url) url = redirect_url; - - if(url == location.href) url = url.replace(/#(.*)$/,''); - - location.href = url; -} - -/** - * @brief Function to process filters - * @deprecated - */ -function procFilter(fo_obj, filter_func) -{ - filter_func(fo_obj); - return false; -} +/** + * @file common/js/xml_js_filter.js + * @author NHN (developers@xpressengine.com) + * @brief xml filter (validator) plugin + * + * A rule is a method validate one field. + * A filter is made up of one or more rules. + **/ +(function($){ + +var messages = []; +var rules = []; +var filters = []; +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; + + var params = [oForm, filter]; + var result = this.cast('VALIDATE', params); + if (typeof result == 'undefined') result = false; + + return result; + }, + 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.minlength) || 0; + var maxlen = parseInt(this.maxlength) || 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 && val.length < minlen) || (maxlen && 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 (minlen||maxlen) 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 + * @brief ajax로 서버에 요청후 결과를 처리할 callback_function을 지정하지 않았을 시 호출되는 기본 함수 + **/ +function filterAlertMessage(ret_obj) { + var error = ret_obj["error"]; + var message = ret_obj["message"]; + var act = ret_obj["act"]; + var redirect_url = ret_obj["redirect_url"]; + var url = location.href; + + if(typeof(message)!="undefined"&&message&&message!="success") alert(message); + + if(typeof(act)!="undefined" && act) url = current_url.setQuery("act", act); + else if(typeof(redirect_url)!="undefined" && redirect_url) url = redirect_url; + + if(url == location.href) url = url.replace(/#(.*)$/,''); + + location.href = url; +} + +/** + * @brief Function to process filters + * @deprecated + */ +function procFilter(fo_obj, filter_func) +{ + filter_func(fo_obj); + return false; +} diff --git a/common/js/unittest/unittest_common.html b/common/js/unittest/unittest_common.html index d18927e9c..7cfdf728a 100644 --- a/common/js/unittest/unittest_common.html +++ b/common/js/unittest/unittest_common.html @@ -1,74 +1,74 @@ - - - - -JSSpec results - - - - - - - -

A

B

- + + + + +JSSpec results + + + + + + + +

A

B

+ diff --git a/common/js/xml_js_filter.js b/common/js/xml_js_filter.js index 9f727cd93..7eef1ff94 100644 --- a/common/js/xml_js_filter.js +++ b/common/js/xml_js_filter.js @@ -1,12 +1,12 @@ -/** - * @file common/js/xml_js_filter.js - * @author taggon (taggon@gmail.com) - * @brief xml filter (validator) plugin - * - * A rule is a method validate one field. - * A filter is made up of one or more rules. - **/ -(function($){var messages=[];var rules=[];var filters=[];var callbacks=[];var extras={};var Validator=xe.createApp('Validator',{init:function(){var regEmail=/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)*$/;this.cast('ADD_RULE',['email',regEmail]);this.cast('ADD_RULE',['email_address',regEmail]);var regUserid=/^[a-z]+[\w-]*[a-z0-9_]+$/i;this.cast('ADD_RULE',['userid',regUserid]);this.cast('ADD_RULE',['user_id',regUserid]);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]);var regKor=/^[가-힣]*$/;this.cast('ADD_RULE',['korean',regKor]);var regKorNum=/^[가-힣0-9]*$/;this.cast('ADD_RULE',['korean_number',regKorNum]);var regAlpha=/^[a-z]*$/i;this.cast('ADD_RULE',['alpha',regAlpha]);var regAlphaNum=/^[a-z][a-z0-9_]*$/i;this.cast('ADD_RULE',['alpha_number',regAlphaNum]);var regNum=/^[0-9]*$/;this.cast('ADD_RULE',['number',regNum]);},run:function(oForm){var filter='';if(oForm._filter)filter=oForm._filter.value;var params=[oForm,filter];var result=this.cast('VALIDATE',params);if(typeof result=='undefined')result=false;return result;},API_ONREADY:function(){var self=this;$('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.minlength)||0;var maxlen=parseInt(this.maxlength)||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&&val.lengthmaxlen))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;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(minlen||maxlen)msg+='('+(minlen||'')+'~'+(maxlen||'')+')';this.cast('SHOW_ALERT',[msg]);$(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;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);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(ret_obj){var error=ret_obj["error"];var message=ret_obj["message"];var act=ret_obj["act"];var redirect_url=ret_obj["redirect_url"];var url=location.href;if(typeof(message)!="undefined"&&message&&message!="success")alert(message);if(typeof(act)!="undefined"&&act)url=current_url.setQuery("act",act);else if(typeof(redirect_url)!="undefined"&&redirect_url)url=redirect_url;if(url==location.href)url=url.replace(/#(.*)$/,'');location.href=url;} -function procFilter(fo_obj,filter_func) +/** + * @file common/js/xml_js_filter.js + * @author NHN (developers@xpressengine.com) + * @brief xml filter (validator) plugin + * + * A rule is a method validate one field. + * A filter is made up of one or more rules. + **/ +(function($){var messages=[];var rules=[];var filters=[];var callbacks=[];var extras={};var Validator=xe.createApp('Validator',{init:function(){var regEmail=/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)*$/;this.cast('ADD_RULE',['email',regEmail]);this.cast('ADD_RULE',['email_address',regEmail]);var regUserid=/^[a-z]+[\w-]*[a-z0-9_]+$/i;this.cast('ADD_RULE',['userid',regUserid]);this.cast('ADD_RULE',['user_id',regUserid]);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]);var regKor=/^[가-힣]*$/;this.cast('ADD_RULE',['korean',regKor]);var regKorNum=/^[가-힣0-9]*$/;this.cast('ADD_RULE',['korean_number',regKorNum]);var regAlpha=/^[a-z]*$/i;this.cast('ADD_RULE',['alpha',regAlpha]);var regAlphaNum=/^[a-z][a-z0-9_]*$/i;this.cast('ADD_RULE',['alpha_number',regAlphaNum]);var regNum=/^[0-9]*$/;this.cast('ADD_RULE',['number',regNum]);},run:function(oForm){var filter='';if(oForm._filter)filter=oForm._filter.value;var params=[oForm,filter];var result=this.cast('VALIDATE',params);if(typeof result=='undefined')result=false;return result;},API_ONREADY:function(){var self=this;$('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.minlength)||0;var maxlen=parseInt(this.maxlength)||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&&val.lengthmaxlen))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;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(minlen||maxlen)msg+='('+(minlen||'')+'~'+(maxlen||'')+')';this.cast('SHOW_ALERT',[msg]);$(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;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);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(ret_obj){var error=ret_obj["error"];var message=ret_obj["message"];var act=ret_obj["act"];var redirect_url=ret_obj["redirect_url"];var url=location.href;if(typeof(message)!="undefined"&&message&&message!="success")alert(message);if(typeof(act)!="undefined"&&act)url=current_url.setQuery("act",act);else if(typeof(redirect_url)!="undefined"&&redirect_url)url=redirect_url;if(url==location.href)url=url.replace(/#(.*)$/,'');location.href=url;} +function procFilter(fo_obj,filter_func) {filter_func(fo_obj);return false;} \ No newline at end of file diff --git a/common/lang/en.lang.php b/common/lang/en.lang.php index 43fd3b752..e26e94966 100644 --- a/common/lang/en.lang.php +++ b/common/lang/en.lang.php @@ -1,7 +1,7 @@ filter->isnull = 'Please input a value for %s'; $lang->filter->outofrange = 'Please align the text length of %s'; $lang->filter->equalto = "The value of %s is invalid"; - $lang->filter->invalid_email = "The format of %s is invalid. ex) zbxe@zeroboard.com"; + $lang->filter->invalid_email = "The format of %s is invalid. ex) developers@xpressengine.com"; $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "The format of %s is invalid.\\nAll values should consist of alphabets, numbers or underscore(_) and the first letter should be alphabet"; - $lang->filter->invalid_homepage = "The format of %s is invalid. ex) http://www.zeroboard.com"; + $lang->filter->invalid_homepage = "The format of %s is invalid. ex) http://xpressengine.com/"; $lang->filter->invalid_korean = "The format of %s is invalid. Please input Korean only"; $lang->filter->invalid_korean_number = "The format of %s is invalid. Please input Korean or numbers"; $lang->filter->invalid_alpha = "The format of %s is invalid. Please input alphabets only"; diff --git a/common/lang/es.lang.php b/common/lang/es.lang.php index 21c841a2f..c0b45ad03 100644 --- a/common/lang/es.lang.php +++ b/common/lang/es.lang.php @@ -1,7 +1,7 @@ filter->isnull = 'Introduzca valor en el %s'; $lang->filter->outofrange = 'Se ha excedido el máximo número de letras permitido en el %s'; $lang->filter->equalto = 'Valor inválido en el %s'; - $lang->filter->invalid_email = 'Formato email inválido en el %s (ej. zbxe@zeroboard.com)'; + $lang->filter->invalid_email = 'Formato email inválido en el %s (ej. developers@xpressengine.com)'; $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "Formato inválido en el %s.\\nSólo pueden introducir los alfabetos o los dígitos númericos o el guión bajo(_). Además, el primer valor sólo puede ser una letra de alfabeto"; - $lang->filter->invalid_homepage = 'Formato url inválido en el %s (ej: http://www.zeroboard.com)'; + $lang->filter->invalid_homepage = 'Formato url inválido en el %s (ej: http://xpressengine.com/)'; $lang->filter->invalid_korean = 'Sólo puede introducir los caracteres coreanos en el %s'; $lang->filter->invalid_korean_number = 'Sólo puede introducir los caracteres coreanos o números en el %s'; $lang->filter->invalid_alpha = 'Sólo puede introducir los alfabetos en el %s'; diff --git a/common/lang/fr.lang.php b/common/lang/fr.lang.php index 0740492cc..cb38f359a 100644 --- a/common/lang/fr.lang.php +++ b/common/lang/fr.lang.php @@ -1,320 +1,320 @@ -cmd_write = 'Ecrire'; - $lang->cmd_reply = 'Répondre'; - $lang->cmd_delete = 'Supprimer'; - $lang->cmd_modify = 'Modifier'; - $lang->cmd_edit = 'Editer'; - $lang->cmd_view = 'Voir'; - $lang->cmd_view_all = 'Voir tout'; - $lang->cmd_list = 'Liste'; - $lang->cmd_prev = 'Précédent'; - $lang->cmd_next = 'Suivant'; - $lang->cmd_send_trackback = 'Envoyer Rétrolien'; - $lang->cmd_registration = $lang->cmd_submit = 'Enrégistrer'; - $lang->cmd_comment_registration = 'Ajouter un Commentaire'; - $lang->cmd_insert = 'Insérer'; - $lang->cmd_save = 'Conserver'; - $lang->cmd_load = 'Charger'; - $lang->cmd_input = 'Entrer'; - $lang->cmd_search = 'Rechercher'; - $lang->cmd_find = '찾기'; - $lang->cmd_replace = '바꾸기'; - $lang->cmd_confirm = '확인'; - $lang->cmd_cancel = 'Annuler'; - $lang->cmd_back = 'Retourner'; - $lang->cmd_vote = 'Recommander'; - $lang->cmd_vote_down = 'Critiquer'; - $lang->cmd_declare = 'Déclarer'; - $lang->cmd_cancel_declare = 'Annuler déclaration'; - $lang->cmd_declared_list = 'Liste des déclarations'; - $lang->cmd_copy = 'Copier'; - $lang->cmd_move = 'Bouger'; - $lang->cmd_move_up = 'En haut'; - $lang->cmd_move_down = 'En bas'; - $lang->cmd_add_indent = 'Ajouter un Rentré'; - $lang->cmd_remove_indent = 'Enlever un Rentré'; - $lang->cmd_management = 'Administrer'; - $lang->cmd_make = 'Créer'; - $lang->cmd_select = 'Choisir'; - $lang->cmd_select_all = 'Choisir Tout'; - $lang->cmd_unselect_all = 'Annuler Tout'; - $lang->cmd_reverse_all = 'Renverser la Sélection'; - $lang->cmd_close_all = 'Fermer Tout'; - $lang->cmd_open_all = 'Ouvrir Tout'; - $lang->cmd_reload = 'Recharger'; - $lang->cmd_close = 'Fermer'; - $lang->cmd_open = 'Ouvrir'; - $lang->cmd_setup = 'Configuration'; - $lang->cmd_addition_setup = 'Configuration Additionnelle'; - $lang->cmd_option = 'Option'; - $lang->cmd_apply = 'Appliquer'; - $lang->cmd_open_calendar = 'Choisir un Jour'; - $lang->cmd_send = 'Envoyer'; - $lang->cmd_print = 'Imprimer'; - $lang->cmd_scrap = 'Coupure'; - $lang->cmd_preview = 'Avant-première'; - $lang->cmd_reset = 'Restaurer'; - $lang->cmd_remake_cache = "Recréer l'antémémoire du Fichier"; - $lang->cmd_publish = "Publier"; - $lang->cmd_layout_setup = 'Configurer la Mise en page'; - $lang->cmd_layout_edit = 'Editer la Mise en page'; - $lang->cmd_search_by_ipaddress = 'Recherce par l\'Address IP'; - $lang->cmd_add_ip_to_spamfilter = 'Add IP to spamfilter'; - - $lang->enable = 'Valide'; - $lang->disable = 'Invalide'; - - // Mots essentiels - $lang->menu = 'Menu'; - $lang->no = 'No'; - $lang->notice = 'Notice'; - $lang->secret = 'Secret'; - $lang->category = $lang->category_srl = 'Catégorie'; - $lang->none_category = 'None category'; - $lang->none_image = '이미지 없음'; - $lang->document_srl = 'Numéro de série du Document'; - $lang->user_id = 'Compte'; - $lang->author = 'Auteur'; - $lang->password = 'Mot de Passe'; - $lang->password1 = 'Mot de Passe'; - $lang->password2 = 'Confirmer du Mot de Passe'; - $lang->admin_id = 'Compte d\'Administrateur'; - $lang->writer = 'Auteur'; - $lang->user_name = 'Nom'; - $lang->nick_name = 'Surnom'; - $lang->email_address = 'Mél'; - $lang->homepage = 'Page d\'accueil'; - $lang->blog = 'Blogue'; - $lang->birthday = 'Anniversaire'; - $lang->browser_title = 'Titre de Navigateur'; - $lang->title = 'Titre'; - $lang->title_content = 'Titre + Contenu'; - $lang->topic = 'Sujet'; - $lang->replies = 'Répondse'; - $lang->content = 'Contenu'; - $lang->document = 'Document'; - $lang->comment = 'Commentaire'; - $lang->description = 'Description'; - $lang->trackback = 'Rétrolien'; - $lang->tag = 'Tag'; - $lang->allow_comment = 'Permettre Commentaires'; - $lang->lock_comment = 'Bloquer Commentaires'; - $lang->allow_trackback = 'Permettre Rétrolien'; - $lang->uploaded_file = 'Fichier Attaché'; - $lang->grant = 'Permission'; - $lang->target = 'Objet'; - $lang->total = 'Total'; - $lang->total_count = 'Somme'; - $lang->ipaddress = 'Addresse IP'; - $lang->path = 'Chemin'; - $lang->cart = 'Article Choisi'; - $lang->friend = 'Les Amis'; - $lang->notify = 'Annoncer'; - $lang->order_target = 'Align Target'; - $lang->order_type = 'Sorting Type'; - $lang->order_asc = 'Ascend'; - $lang->order_desc = 'Descendre'; - $lang->file = 'file'; - - $lang->mid = 'Nom'; - $lang->sid = 'Site Name'; - $lang->layout = 'Mise en Page'; - $lang->mobile_layout = 'Mobile Layout'; - $lang->widget = 'Gadget'; - $lang->module = 'Module'; - $lang->skin = 'Habillage'; - $lang->mobile_skin = 'Mobile Habillage'; - $lang->colorset = 'Arrangement de couleur'; - $lang->extra_vars = 'Variables Supplémentaires'; - - $lang->domain = "Domain Name"; - $lang->url = "URL"; - $lang->document_url = 'Document URL'; - $lang->trackback_url = 'Rétrolien URL'; - $lang->blog_name = 'Nom du Blogue'; - $lang->excerpt = 'Extrait'; - - $lang->document_count = ' Documents'; - $lang->page_count = 'Pages'; - $lang->list_count = 'Item'; - $lang->search_list_count = 'Trouvés'; - $lang->readed_count = ' Vues'; - $lang->voted_count = 'Recommandés'; - $lang->comment_count = 'Commentaires'; - $lang->member_count = 'Membres'; - $lang->date = 'Jour'; - $lang->regdate = 'Enrégistré'; - $lang->last_update = 'Dernière Mise à Jour'; - $lang->last_post = 'Dernière Affichage'; - $lang->signup_date = 'Inscription'; - $lang->last_login = 'Dernière connexion'; - $lang->first_page = 'Première Page'; - $lang->last_page = 'Dernière Page'; - $lang->search_target = 'Champ à Rechercher'; - $lang->search_keyword = 'Mot-clé à Rechercher'; - $lang->is_default = 'Par Défaut'; - - $lang->no_documents = 'Nul Document'; - - $lang->board_manager = 'Administration des Panneaux'; - $lang->member_manager = 'Administration des Membres'; - $lang->layout_manager = 'Administration des Mises en Page'; - - $lang->use = 'Utiliser'; - $lang->notuse = 'Pas Utilisé'; - $lang->not_exists = 'Rien'; - - $lang->public = 'public'; - $lang->private = 'privé'; - - $lang->unit_sec = 'seconde'; - $lang->unit_min = 'minute'; - $lang->unit_hour = 'heure'; - $lang->unit_day = 'jour'; - $lang->unit_month = 'mois'; - $lang->unit_year = 'année';; - - $lang->unit_week = array( - 'Monday' => 'Lundi', - 'Tuesday' => 'Mardi', - 'Wednesday' => 'Mer.', - 'Thursday' => 'Jeu.', - 'Friday' => 'Vendredi', - 'Saturday' => 'Samedi', - 'Sunday' => 'Dimanche', - ); - - $lang->unit_meridiem = array( - 'am' => 'am', - 'pm' => 'pm', - 'AM' => 'AM', - 'PM' => 'PM', - ); - - $lang->time_gap = array( - 'min' => '%d heure', - 'mins' => 'Il ya %d minutes', - 'hour' => 'Il ya %d jour', - 'hours' => 'Il ya %d jours', - ); - - // Descriptions et information - $lang->about_tag = 'Vous pouvez enrégistrer plusieurs balises en utilisant ,(virgule) entre chaque balise'; - $lang->about_layout = 'Le Mise en Page décore l\'apparence des modules. Vous pouvez les configurer avec le menu de Mise en Page en haut'; - - // Messages et alertes - $lang->msg_call_server = 'En demandant sur le serveur, attendez S.V.P.'; - $lang->msg_db_not_setted = 'La configuration de Base de Données n\'a pas été établie.'; - $lang->msg_dbconnect_failed = "Erreur a lieu en essayant connecter à la Base de Données.\nVérifiez encore une fois les informations sur la Base de Données, S.V.P."; - $lang->msg_invalid_queryid = 'La valeur spécifiée d\'identite de query est invalide.'; - $lang->msg_not_permitted = 'Vous n\'avez pas le droit d\'accès.'; - $lang->msg_input_password = 'Veuillez entrer votre mot de passe.'; - $lang->msg_invalid_document = 'Numéro de Document invalide'; - $lang->msg_invalid_request = 'Requête invalide'; - $lang->msg_invalid_password = 'Mot de passe invalide'; - $lang->msg_error_occured = 'Une erreur a lieu'; - $lang->msg_not_founded = 'L\'objet n\'est pas trouvé.'; - $lang->msg_no_result = 'Nul Résultat'; - $lang->msg_fail_to_request_open = 'Fail to open your request'; - $lang->msg_invalid_format = 'Invalid Format'; - - $lang->msg_not_permitted_act = 'Vous n\'êtes pas autorisés à exécuter l\'action que vous avez demandé.'; - $lang->msg_module_is_not_exists = "요청하신 모듈을 찾을 수 없습니다.\n사이트 관리자에게 모듈 점검 요청 바랍니다"; - $lang->msg_module_is_not_standalone = 'Le module demandé ne peut pas être exécuté indépendamment.'; - $lang->msg_default_url_is_not_defined = '기본 URL이 정해지지 않아서 동작을 중지합니다'; - - $lang->success_registed = 'Enregistré avec succès'; - $lang->success_declared = 'Accusé avec succès'; - $lang->success_updated = 'Mise à jour avec succès'; - $lang->success_deleted = 'Supprimé avec succès'; - $lang->success_voted = 'Voté avec succès'; - $lang->success_blamed = 'Blâmé avec succès'; - $lang->success_moved = 'Bougé avec succès'; - $lang->success_sended = 'Envoyé avec succès'; - $lang->success_reset = 'Restauré avec succès'; - $lang->success_leaved = 'Toutes vos informations sont complètement supprimés'; - $lang->success_saved = 'Conservé avec succès'; - - $lang->fail_to_delete = 'N\'a pas pu être supprimé.'; - $lang->fail_to_move = 'N\'a pas pu être bougé'; - - $lang->failed_voted = 'N\'a pas pu recommander'; - $lang->failed_blamed = 'N\'a pas pu blâmer'; - $lang->failed_declared = 'N\'a pas pu accuser'; - $lang->fail_to_delete_have_children = 'Essayez encore une fois après avoir suprimé les reponses, S.V.P.'; - - $lang->confirm_submit = 'Vous voulez sûrement soumettre?'; - $lang->confirm_logout = 'Vous voulez sûrement fermer la session?'; - $lang->confirm_vote = 'Vous voulez recommander?'; - $lang->confirm_delete = 'Vous voulez sûrement supprimer?'; - $lang->confirm_move = 'Vous voulez sûrement bouger?'; - $lang->confirm_reset = 'Vous voulez sûrement restaurer?'; - $lang->confirm_leave = 'Vous voulez sûrement supprimer votre compte?'; - $lang->confirm_update = 'Are you sure to update?'; - - $lang->column_type = 'Types de la colonne'; - $lang->column_type_list['text'] = 'Texte en une seul ligne'; - $lang->column_type_list['homepage'] = 'URL'; - $lang->column_type_list['email_address'] = 'Mél'; - $lang->column_type_list['tel'] = 'Numéro de Telephone'; - $lang->column_type_list['textarea'] = 'Texte en plusieurs lignes'; - $lang->column_type_list['checkbox'] = 'Case à cocher (multichoix)'; - $lang->column_type_list['select'] = 'Case d\'option (seul choix)'; - $lang->column_type_list['radio'] = 'radio button (radio)'; - $lang->column_type_list['kr_zip'] = 'Code postal (coréen)'; - $lang->column_type_list['date'] = 'Jour (yyyy/mm/dd)'; - //$lang->column_type_list['jp_zip'] = 'code postal (japonais)'; - $lang->column_name = 'Nom de la colonne'; - $lang->column_title = 'Titre de la colonne'; - $lang->default_value = 'Valeur par défaut'; - $lang->is_active = 'Actif'; - $lang->is_required = 'Item essentielle'; - $lang->eid = '확장변수 이름'; - - // ftp 관련 - $lang->ftp_form_title = 'FTP 정보 입력'; - $lang->ftp = 'FTP'; - $lang->ftp_host = 'FTP hostname'; - $lang->ftp_port = 'FTP port'; - $lang->about_ftp_password = 'FTP password will not be stored'; - $lang->cmd_check_ftp_connect = 'FTP 접속 확인'; - $lang->about_ftp_info = " - FTP 정보는 다음의 경우에 이용될 수 있습니다.
- 1. PHP의 safe_mode=On일 경우에 FTP 정보를 이용해서 XE를 정상적으로 동작할 수 있게 합니다.
- 2. 자동 업데이트등에서 FTP 정보를 이용할 수 있습니다.
- 이 FTP정보는 files/config/ftp.config.php 파일내에 정보가 저장됩니다.
- 그리고 설치 후 관리자 페이지에서 FTP 정보를 변경하거나 제거할 수 있습니다.
- "; - - $lang->msg_safe_mode_ftp_needed = "PHP의 safe_mode가 On일 경우 FTP 정보를 꼭 입력해주셔야 XE의 설치 및 사용이 가능합니다"; - $lang->msg_ftp_not_connected = "localhost로의 FTP 접속 오류가 발생하였습니다. ftp 포트 번호를 확인해주시거나 ftp 서비스가 가능한지 확인해주세요"; - $lang->msg_ftp_invalid_auth_info = "입력하신 FTP 정보로 로그인을 하지 못했습니다. FTP정보를 확인해주세요"; - $lang->msg_ftp_mkdir_fail = "FTP를 이용한 디렉토리 생성 명령을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; - $lang->msg_ftp_chmod_fail = "FTP를 이용한 디렉토리의 속성 변경을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; - $lang->msg_ftp_connect_success = "FTP 접속 및 인증 성공하였습니다"; - - $lang->ftp_path_title = 'FTP 경로 정보 입력'; - $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; - $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; - - - // Messages d\'alerte de le Javascript qui est utilisé dans les filtres en XML - $lang->filter->isnull = 'Entrez une valeur pour %s'; - $lang->filter->outofrange = 'Aligner la longueur du texte de %s'; - $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_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_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_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_number = "La format de %s n\'est pas convenable. Entrez seulement des chiffres."; -?> +cmd_write = 'Ecrire'; + $lang->cmd_reply = 'Répondre'; + $lang->cmd_delete = 'Supprimer'; + $lang->cmd_modify = 'Modifier'; + $lang->cmd_edit = 'Editer'; + $lang->cmd_view = 'Voir'; + $lang->cmd_view_all = 'Voir tout'; + $lang->cmd_list = 'Liste'; + $lang->cmd_prev = 'Précédent'; + $lang->cmd_next = 'Suivant'; + $lang->cmd_send_trackback = 'Envoyer Rétrolien'; + $lang->cmd_registration = $lang->cmd_submit = 'Enrégistrer'; + $lang->cmd_comment_registration = 'Ajouter un Commentaire'; + $lang->cmd_insert = 'Insérer'; + $lang->cmd_save = 'Conserver'; + $lang->cmd_load = 'Charger'; + $lang->cmd_input = 'Entrer'; + $lang->cmd_search = 'Rechercher'; + $lang->cmd_find = '찾기'; + $lang->cmd_replace = '바꾸기'; + $lang->cmd_confirm = '확인'; + $lang->cmd_cancel = 'Annuler'; + $lang->cmd_back = 'Retourner'; + $lang->cmd_vote = 'Recommander'; + $lang->cmd_vote_down = 'Critiquer'; + $lang->cmd_declare = 'Déclarer'; + $lang->cmd_cancel_declare = 'Annuler déclaration'; + $lang->cmd_declared_list = 'Liste des déclarations'; + $lang->cmd_copy = 'Copier'; + $lang->cmd_move = 'Bouger'; + $lang->cmd_move_up = 'En haut'; + $lang->cmd_move_down = 'En bas'; + $lang->cmd_add_indent = 'Ajouter un Rentré'; + $lang->cmd_remove_indent = 'Enlever un Rentré'; + $lang->cmd_management = 'Administrer'; + $lang->cmd_make = 'Créer'; + $lang->cmd_select = 'Choisir'; + $lang->cmd_select_all = 'Choisir Tout'; + $lang->cmd_unselect_all = 'Annuler Tout'; + $lang->cmd_reverse_all = 'Renverser la Sélection'; + $lang->cmd_close_all = 'Fermer Tout'; + $lang->cmd_open_all = 'Ouvrir Tout'; + $lang->cmd_reload = 'Recharger'; + $lang->cmd_close = 'Fermer'; + $lang->cmd_open = 'Ouvrir'; + $lang->cmd_setup = 'Configuration'; + $lang->cmd_addition_setup = 'Configuration Additionnelle'; + $lang->cmd_option = 'Option'; + $lang->cmd_apply = 'Appliquer'; + $lang->cmd_open_calendar = 'Choisir un Jour'; + $lang->cmd_send = 'Envoyer'; + $lang->cmd_print = 'Imprimer'; + $lang->cmd_scrap = 'Coupure'; + $lang->cmd_preview = 'Avant-première'; + $lang->cmd_reset = 'Restaurer'; + $lang->cmd_remake_cache = "Recréer l'antémémoire du Fichier"; + $lang->cmd_publish = "Publier"; + $lang->cmd_layout_setup = 'Configurer la Mise en page'; + $lang->cmd_layout_edit = 'Editer la Mise en page'; + $lang->cmd_search_by_ipaddress = 'Recherce par l\'Address IP'; + $lang->cmd_add_ip_to_spamfilter = 'Add IP to spamfilter'; + + $lang->enable = 'Valide'; + $lang->disable = 'Invalide'; + + // Mots essentiels + $lang->menu = 'Menu'; + $lang->no = 'No'; + $lang->notice = 'Notice'; + $lang->secret = 'Secret'; + $lang->category = $lang->category_srl = 'Catégorie'; + $lang->none_category = 'None category'; + $lang->none_image = '이미지 없음'; + $lang->document_srl = 'Numéro de série du Document'; + $lang->user_id = 'Compte'; + $lang->author = 'Auteur'; + $lang->password = 'Mot de Passe'; + $lang->password1 = 'Mot de Passe'; + $lang->password2 = 'Confirmer du Mot de Passe'; + $lang->admin_id = 'Compte d\'Administrateur'; + $lang->writer = 'Auteur'; + $lang->user_name = 'Nom'; + $lang->nick_name = 'Surnom'; + $lang->email_address = 'Mél'; + $lang->homepage = 'Page d\'accueil'; + $lang->blog = 'Blogue'; + $lang->birthday = 'Anniversaire'; + $lang->browser_title = 'Titre de Navigateur'; + $lang->title = 'Titre'; + $lang->title_content = 'Titre + Contenu'; + $lang->topic = 'Sujet'; + $lang->replies = 'Répondse'; + $lang->content = 'Contenu'; + $lang->document = 'Document'; + $lang->comment = 'Commentaire'; + $lang->description = 'Description'; + $lang->trackback = 'Rétrolien'; + $lang->tag = 'Tag'; + $lang->allow_comment = 'Permettre Commentaires'; + $lang->lock_comment = 'Bloquer Commentaires'; + $lang->allow_trackback = 'Permettre Rétrolien'; + $lang->uploaded_file = 'Fichier Attaché'; + $lang->grant = 'Permission'; + $lang->target = 'Objet'; + $lang->total = 'Total'; + $lang->total_count = 'Somme'; + $lang->ipaddress = 'Addresse IP'; + $lang->path = 'Chemin'; + $lang->cart = 'Article Choisi'; + $lang->friend = 'Les Amis'; + $lang->notify = 'Annoncer'; + $lang->order_target = 'Align Target'; + $lang->order_type = 'Sorting Type'; + $lang->order_asc = 'Ascend'; + $lang->order_desc = 'Descendre'; + $lang->file = 'file'; + + $lang->mid = 'Nom'; + $lang->sid = 'Site Name'; + $lang->layout = 'Mise en Page'; + $lang->mobile_layout = 'Mobile Layout'; + $lang->widget = 'Gadget'; + $lang->module = 'Module'; + $lang->skin = 'Habillage'; + $lang->mobile_skin = 'Mobile Habillage'; + $lang->colorset = 'Arrangement de couleur'; + $lang->extra_vars = 'Variables Supplémentaires'; + + $lang->domain = "Domain Name"; + $lang->url = "URL"; + $lang->document_url = 'Document URL'; + $lang->trackback_url = 'Rétrolien URL'; + $lang->blog_name = 'Nom du Blogue'; + $lang->excerpt = 'Extrait'; + + $lang->document_count = ' Documents'; + $lang->page_count = 'Pages'; + $lang->list_count = 'Item'; + $lang->search_list_count = 'Trouvés'; + $lang->readed_count = ' Vues'; + $lang->voted_count = 'Recommandés'; + $lang->comment_count = 'Commentaires'; + $lang->member_count = 'Membres'; + $lang->date = 'Jour'; + $lang->regdate = 'Enrégistré'; + $lang->last_update = 'Dernière Mise à Jour'; + $lang->last_post = 'Dernière Affichage'; + $lang->signup_date = 'Inscription'; + $lang->last_login = 'Dernière connexion'; + $lang->first_page = 'Première Page'; + $lang->last_page = 'Dernière Page'; + $lang->search_target = 'Champ à Rechercher'; + $lang->search_keyword = 'Mot-clé à Rechercher'; + $lang->is_default = 'Par Défaut'; + + $lang->no_documents = 'Nul Document'; + + $lang->board_manager = 'Administration des Panneaux'; + $lang->member_manager = 'Administration des Membres'; + $lang->layout_manager = 'Administration des Mises en Page'; + + $lang->use = 'Utiliser'; + $lang->notuse = 'Pas Utilisé'; + $lang->not_exists = 'Rien'; + + $lang->public = 'public'; + $lang->private = 'privé'; + + $lang->unit_sec = 'seconde'; + $lang->unit_min = 'minute'; + $lang->unit_hour = 'heure'; + $lang->unit_day = 'jour'; + $lang->unit_month = 'mois'; + $lang->unit_year = 'année';; + + $lang->unit_week = array( + 'Monday' => 'Lundi', + 'Tuesday' => 'Mardi', + 'Wednesday' => 'Mer.', + 'Thursday' => 'Jeu.', + 'Friday' => 'Vendredi', + 'Saturday' => 'Samedi', + 'Sunday' => 'Dimanche', + ); + + $lang->unit_meridiem = array( + 'am' => 'am', + 'pm' => 'pm', + 'AM' => 'AM', + 'PM' => 'PM', + ); + + $lang->time_gap = array( + 'min' => '%d heure', + 'mins' => 'Il ya %d minutes', + 'hour' => 'Il ya %d jour', + 'hours' => 'Il ya %d jours', + ); + + // Descriptions et information + $lang->about_tag = 'Vous pouvez enrégistrer plusieurs balises en utilisant ,(virgule) entre chaque balise'; + $lang->about_layout = 'Le Mise en Page décore l\'apparence des modules. Vous pouvez les configurer avec le menu de Mise en Page en haut'; + + // Messages et alertes + $lang->msg_call_server = 'En demandant sur le serveur, attendez S.V.P.'; + $lang->msg_db_not_setted = 'La configuration de Base de Données n\'a pas été établie.'; + $lang->msg_dbconnect_failed = "Erreur a lieu en essayant connecter à la Base de Données.\nVérifiez encore une fois les informations sur la Base de Données, S.V.P."; + $lang->msg_invalid_queryid = 'La valeur spécifiée d\'identite de query est invalide.'; + $lang->msg_not_permitted = 'Vous n\'avez pas le droit d\'accès.'; + $lang->msg_input_password = 'Veuillez entrer votre mot de passe.'; + $lang->msg_invalid_document = 'Numéro de Document invalide'; + $lang->msg_invalid_request = 'Requête invalide'; + $lang->msg_invalid_password = 'Mot de passe invalide'; + $lang->msg_error_occured = 'Une erreur a lieu'; + $lang->msg_not_founded = 'L\'objet n\'est pas trouvé.'; + $lang->msg_no_result = 'Nul Résultat'; + $lang->msg_fail_to_request_open = 'Fail to open your request'; + $lang->msg_invalid_format = 'Invalid Format'; + + $lang->msg_not_permitted_act = 'Vous n\'êtes pas autorisés à exécuter l\'action que vous avez demandé.'; + $lang->msg_module_is_not_exists = "요청하신 모듈을 찾을 수 없습니다.\n사이트 관리자에게 모듈 점검 요청 바랍니다"; + $lang->msg_module_is_not_standalone = 'Le module demandé ne peut pas être exécuté indépendamment.'; + $lang->msg_default_url_is_not_defined = '기본 URL이 정해지지 않아서 동작을 중지합니다'; + + $lang->success_registed = 'Enregistré avec succès'; + $lang->success_declared = 'Accusé avec succès'; + $lang->success_updated = 'Mise à jour avec succès'; + $lang->success_deleted = 'Supprimé avec succès'; + $lang->success_voted = 'Voté avec succès'; + $lang->success_blamed = 'Blâmé avec succès'; + $lang->success_moved = 'Bougé avec succès'; + $lang->success_sended = 'Envoyé avec succès'; + $lang->success_reset = 'Restauré avec succès'; + $lang->success_leaved = 'Toutes vos informations sont complètement supprimés'; + $lang->success_saved = 'Conservé avec succès'; + + $lang->fail_to_delete = 'N\'a pas pu être supprimé.'; + $lang->fail_to_move = 'N\'a pas pu être bougé'; + + $lang->failed_voted = 'N\'a pas pu recommander'; + $lang->failed_blamed = 'N\'a pas pu blâmer'; + $lang->failed_declared = 'N\'a pas pu accuser'; + $lang->fail_to_delete_have_children = 'Essayez encore une fois après avoir suprimé les reponses, S.V.P.'; + + $lang->confirm_submit = 'Vous voulez sûrement soumettre?'; + $lang->confirm_logout = 'Vous voulez sûrement fermer la session?'; + $lang->confirm_vote = 'Vous voulez recommander?'; + $lang->confirm_delete = 'Vous voulez sûrement supprimer?'; + $lang->confirm_move = 'Vous voulez sûrement bouger?'; + $lang->confirm_reset = 'Vous voulez sûrement restaurer?'; + $lang->confirm_leave = 'Vous voulez sûrement supprimer votre compte?'; + $lang->confirm_update = 'Are you sure to update?'; + + $lang->column_type = 'Types de la colonne'; + $lang->column_type_list['text'] = 'Texte en une seul ligne'; + $lang->column_type_list['homepage'] = 'URL'; + $lang->column_type_list['email_address'] = 'Mél'; + $lang->column_type_list['tel'] = 'Numéro de Telephone'; + $lang->column_type_list['textarea'] = 'Texte en plusieurs lignes'; + $lang->column_type_list['checkbox'] = 'Case à cocher (multichoix)'; + $lang->column_type_list['select'] = 'Case d\'option (seul choix)'; + $lang->column_type_list['radio'] = 'radio button (radio)'; + $lang->column_type_list['kr_zip'] = 'Code postal (coréen)'; + $lang->column_type_list['date'] = 'Jour (yyyy/mm/dd)'; + //$lang->column_type_list['jp_zip'] = 'code postal (japonais)'; + $lang->column_name = 'Nom de la colonne'; + $lang->column_title = 'Titre de la colonne'; + $lang->default_value = 'Valeur par défaut'; + $lang->is_active = 'Actif'; + $lang->is_required = 'Item essentielle'; + $lang->eid = '확장변수 이름'; + + // ftp 관련 + $lang->ftp_form_title = 'FTP 정보 입력'; + $lang->ftp = 'FTP'; + $lang->ftp_host = 'FTP hostname'; + $lang->ftp_port = 'FTP port'; + $lang->about_ftp_password = 'FTP password will not be stored'; + $lang->cmd_check_ftp_connect = 'FTP 접속 확인'; + $lang->about_ftp_info = " + FTP 정보는 다음의 경우에 이용될 수 있습니다.
+ 1. PHP의 safe_mode=On일 경우에 FTP 정보를 이용해서 XE를 정상적으로 동작할 수 있게 합니다.
+ 2. 자동 업데이트등에서 FTP 정보를 이용할 수 있습니다.
+ 이 FTP정보는 files/config/ftp.config.php 파일내에 정보가 저장됩니다.
+ 그리고 설치 후 관리자 페이지에서 FTP 정보를 변경하거나 제거할 수 있습니다.
+ "; + + $lang->msg_safe_mode_ftp_needed = "PHP의 safe_mode가 On일 경우 FTP 정보를 꼭 입력해주셔야 XE의 설치 및 사용이 가능합니다"; + $lang->msg_ftp_not_connected = "localhost로의 FTP 접속 오류가 발생하였습니다. ftp 포트 번호를 확인해주시거나 ftp 서비스가 가능한지 확인해주세요"; + $lang->msg_ftp_invalid_auth_info = "입력하신 FTP 정보로 로그인을 하지 못했습니다. FTP정보를 확인해주세요"; + $lang->msg_ftp_mkdir_fail = "FTP를 이용한 디렉토리 생성 명령을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; + $lang->msg_ftp_chmod_fail = "FTP를 이용한 디렉토리의 속성 변경을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; + $lang->msg_ftp_connect_success = "FTP 접속 및 인증 성공하였습니다"; + + $lang->ftp_path_title = 'FTP 경로 정보 입력'; + $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; + $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; + + + // Messages d\'alerte de le Javascript qui est utilisé dans les filtres en XML + $lang->filter->isnull = 'Entrez une valeur pour %s'; + $lang->filter->outofrange = 'Aligner la longueur du texte de %s'; + $lang->filter->equalto = "La valeur de %s est invalide."; + $lang->filter->invalid_email = "Le format de %s est invalide. ex) developers@xpressengine.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_homepage = "La format de %s n\'est pas convenable. ex) http://xpressengine.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_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_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."; +?> diff --git a/common/lang/ge.lang.php b/common/lang/ge.lang.php index 61d3f186d..02cbb0849 100644 --- a/common/lang/ge.lang.php +++ b/common/lang/ge.lang.php @@ -1,322 +1,322 @@ -cmd_write = 'Schreiben'; - $lang->cmd_reply = 'Antworten'; - $lang->cmd_delete = 'Löschen'; - $lang->cmd_modify = 'Ändern'; - $lang->cmd_edit = 'Bearbeiten'; - $lang->cmd_view = 'Anzeigen'; - $lang->cmd_view_all = 'Alle anzeigen'; - $lang->cmd_list = 'US -'; - $lang->cmd_prev = 'Zurück'; - $lang->cmd_next = 'Nächster'; - $lang->cmd_send_trackback = 'Trackback senden'; - $lang->cmd_registration = $lang->cmd_submit = 'Übermitteln'; - $lang->cmd_comment_registration = 'Kommentar hinzufügen'; - $lang->cmd_insert = 'Legen Sie'; - $lang->cmd_save = 'sichern'; - $lang->cmd_load = 'Laden'; - $lang->cmd_input = 'Input'; - $lang->cmd_search = 'Suche'; - $lang->cmd_find = '찾기'; - $lang->cmd_replace = '바꾸기'; - $lang->cmd_confirm = '확인'; - $lang->cmd_cancel = 'Abbrechen'; - $lang->cmd_back = 'Zurück'; - $lang->cmd_vote = 'Weiterempfehlen'; - $lang->cmd_vote_down = 'Criticize'; - $lang->cmd_declare = 'accuse'; - $lang->cmd_cancel_declare = 'accuse Abbrechen'; - $lang->cmd_declared_list = 'Vorwürfe Liste'; - $lang->cmd_copy = 'Kopieren'; - $lang->cmd_move = 'Verschieben'; - $lang->cmd_move_up = 'Nach oben'; - $lang->cmd_move_down = 'Down'; - $lang->cmd_add_indent = 'Einrücken'; - $lang->cmd_remove_indent = 'Ausrücken'; - $lang->cmd_management = 'Verwaltung'; - $lang->cmd_make = 'Erstellen'; - $lang->cmd_select = 'Select'; - $lang->cmd_select_all = 'Alle auswählen'; - $lang->cmd_unselect_all = 'Alle abwählen'; - $lang->cmd_reverse_all = 'Reverse'; - $lang->cmd_close_all = 'Schließen Sie alle'; - $lang->cmd_open_all = 'Open All'; - $lang->cmd_reload = 'Reload'; - $lang->cmd_close = 'Schließen'; - $lang->cmd_open = 'Open'; - $lang->cmd_setup = 'Konfiguration'; - $lang->cmd_addition_setup = 'Zusätzliche Setup '; - $lang->cmd_option = 'Option'; - $lang->cmd_apply = 'Übernehmen'; - $lang->cmd_open_calendar = 'Wählen Sie ein Datum'; - $lang->cmd_send = 'Senden'; - $lang->cmd_print = 'Drucken'; - $lang->cmd_scrap = 'Schrott'; - $lang->cmd_preview = 'Vorschau'; - $lang->cmd_reset = 'Reset'; - $lang->cmd_remake_cache = 'Re-Cache-Datei erstellen'; - $lang->cmd_publish = 'Veröffentlichen'; - $lang->cmd_layout_setup = 'Konfiguration Layout'; - $lang->cmd_layout_edit = 'Layout bearbeiten'; - $lang->cmd_search_by_ipaddress = 'Search by IP Address'; - $lang->cmd_add_ip_to_spamfilter = 'Add IP to spamfilter'; - - $lang->enable = 'Aktivieren'; - $lang->deaktivieren = 'Deaktivieren'; - - // Essential Words - $lang->menu = 'Menu'; - $lang->no = 'Nein'; - $lang->notice = 'Hinweis'; - $lang->secret = 'Geheim'; - $lang->category = $lang->category_srl = 'Kategorie'; - $lang->none_category = '분류없음'; - $lang->none_image = '이미지 없음'; - $lang->document_srl = 'Doc. No '; - $lang->user_id = 'User-ID'; - $lang->author = 'Entwickler'; - $lang->password = 'Passwort'; - $lang->password1 = 'Passwort'; - $lang->password2 = 'Passwort bestätigen'; - $lang->admin_id = 'Admin ID'; - $lang->writer = 'Autor'; - $lang->user_name = 'Username'; - $lang->nick_name = 'Nick Name'; - $lang->email_address = 'E-Mail'; - $lang->homepage = 'Startseite'; - $lang->blog = 'Blog'; - $lang->birthday = 'Geburtstag'; - $lang->browser_title = 'Browser-Titel'; - $lang->title = 'Betreff'; - $lang->title_content = 'Betreff + Inhalt'; - $lang->topic = 'Thema'; - $lang->replies = 'Antwort'; - $lang->content = 'Inhalt'; - $lang->document = 'Artikel'; - $lang->comment = 'Kommentar'; - $lang->description = 'Beschreibung'; - $lang->trackback = 'Trackback'; - $lang->tag = 'Tag'; - $lang->allow_comment = 'Kommentare erlauben'; - $lang->lock_comment = 'Block Kommentare'; - $lang->allow_trackback = 'Allow Trackbacks'; - $lang->uploaded_file = 'Anlage'; - $lang->grant = 'Erlaubnis'; - $lang->target = 'target'; - $lang->total = 'Gesamt'; - $lang->total_count = 'count Gesamt'; - $lang->ipaddress = 'IP-Adresse'; - $lang->path = 'Pfad'; - $lang->cart = 'Ausgewählte Posten'; - $lang->friend = 'Freunde'; - $lang->notify = 'Meldung'; - $lang->order_target = 'Ausrichten Target'; - $lang->order_type = 'Sortieren Typ'; - $lang->order_asc = 'Aufstieg'; - $lang->order_desc = 'Abstieg'; - $lang->file = 'file'; - - $lang->mid = 'Module Name'; - $lang->sid = 'Site Name'; - $lang->layout = 'Layout'; - $lang->mobile_layout = 'Mobile Layout'; - $lang->widget = 'Widget'; - $lang->module = 'Modul'; - $lang->skin = 'Thema'; - $lang->mobile_skin = 'Mobile Theme'; - $lang->colorset = 'Colorset'; - $lang->extra_vars = 'Extra Vars'; - - $lang->domain = "Domain Name"; - $lang->url = "URL"; - $lang->document_url = 'Artikel-URL'; - $lang->trackback_url = 'Trackback-URL'; - $lang->blog_name = 'Blog-Titel'; - $lang->excerpt = 'Zitat'; - - $lang->document_count = 'Total Artikel'; - $lang->page_count = 'Page Count'; - $lang->list_count = 'US-Count '; - $lang->search_list_count = 'Suchen US-Count'; - $lang->readed_count = 'Views'; - $lang->voted_count = 'Stimmen'; - $lang->comment_count = 'Kommentare'; - $lang->member_count = 'Mitglied Count'; - $lang->date = 'Datum'; - $lang->regdate = 'Anmeldungsdatum Datum'; - $lang->last_update = 'Letzte Aktualisierung'; - $lang->last_post = 'Letzter Beitrag'; - $lang->signup_date = 'Join Date'; - $lang->last_login = 'Letzter Login'; - $lang->first_page = 'Erste Seite'; - $lang->last_page = 'Letzte Seite'; - $lang->search_target = 'Target für die Google-Suche'; - $lang->search_keyword = 'Stichwort'; - $lang->is_default = 'Standard'; - - $lang->no_documents = 'Keine Artikel'; - - $lang->board_manager = 'Board'; - $lang->member_manager = 'Mitglied'; - $lang->layout_manager = 'Layout-Einstellungen'; - - $lang->use = 'Use'; - $lang->notuse = 'nicht verwenden'; - $lang->not_exists = 'nicht vorhanden'; - - $lang->public = 'öffentlich'; - $lang->private = 'private'; - - $lang->unit_sec = 's'; - $lang->unit_min = 'mindestens'; - $lang->unit_hour = 'h'; - $lang->unit_day = 'th'; - $lang->unit_month = 'Monat'; - $lang->unit_year = 'Jahr'; - - $lang->unit_week = array( - 'Monday' => 'Montag', - 'Tuesday' => 'Dienstag', - 'Wednesday' => 'Mittwoch', - 'Thursday' => 'Donnerstag', - 'Friday' => 'Freitag', - 'Saturday' => 'Samstag', - 'Sunday' => 'Sonntag', - ); - - $lang->unit_meridiem = array( - 'am' => 'am', - 'pm' => 'pm', - 'AM' => 'AM', - 'PM' => 'PM', - ); - - $lang->time_gap = array( - 'min' => 'Vor %d Minute', - 'mins' => '%d Stunden', - 'hour' => '%d Tag', - 'hours' => '%d Tage', - ); - - // Beschreibungen - $lang->about_tag = 'Sie können mehrere Tags, indem Sie ein Komma (,) zwischen den einzelnen Tag'; - $lang->about_layout = 'Layouts schmücken das Aussehen Ihrer Module. Sie können sie von Layout-Menü am oberen Rand '; - - // Messages - $lang->msg_call_server = 'Anfordern an den Server, bitte warten'; - $lang->msg_db_not_setted = 'DB-Konfiguration wurde nicht festgelegt'; - $lang->msg_dbconnect_failed = "Error has occurred while connecting DB.\nPlease check DB information again"; // TODO:translation en -> ge - $lang->msg_invalid_queryid = 'spezifiziert Abfrage ID-Wert ist ungültig'; - $lang->msg_not_permitted = 'Sie haben keine Berechtigung zum Zugriff auf'; - $lang->msg_input_password = 'Bitte geben Sie das Passwort'; - $lang->msg_invalid_document = 'Ungültige Article Number'; - $lang->msg_invalid_request = 'Invalid request '; - $lang->msg_invalid_password = 'Ungültiges Passwort'; - $lang->msg_error_occured = 'Ein Fehler ist aufgetreten '; - $lang->msg_not_founded = 'Target konnte nicht gefunden werden'; - $lang->msg_no_result = 'Nichts gefunden'; - $lang->msg_fail_to_request_open = 'Fail to open your request'; - $lang->msg_invalid_format = 'Invalid Format'; - - $lang->msg_not_permitted_act = 'Sie haben keine Berechtigung zur Ausführung angeforderte Aktion'; - $lang->msg_module_is_not_exists = "요청하신 모듈을 찾을 수 없습니다.\n사이트 관리자에게 모듈 점검 요청 바랍니다"; - $lang->msg_module_is_not_standalone = 'Gewünschte Modul kann nicht ausgeführt werden unabhängig'; - $lang->msg_default_url_is_not_defined = '기본 URL이 정해지지 않아서 동작을 중지합니다'; - - $lang->success_registed = 'Anmeldungsdatum'; - $lang->success_declared = 'Accused erfolgreich'; - $lang->success_updated = 'erfolgreich aktualisiert'; - $lang->success_deleted = 'erfolgreich gelöscht'; - $lang->success_voted = 'Empfohlen'; - $lang->success_blamed = 'Schuld success_blamed'; - $lang->success_moved = 'Umzug'; - $lang->success_sended = 'Gesendet'; - $lang->success_reset = 'Reset'; - $lang->success_leaved = 'Alle Mitglieder Daten wurden komplett gestrichen. '; - $lang->success_saved = 'erfolgreich gespeichert '; - - $lang->fail_to_delete = 'konnte nicht gelöscht werden'; - $lang->fail_to_move = 'konnte nicht verschoben werden'; - - $lang->failed_voted = 'konnte nicht empfehlen'; - $lang->failed_blamed = 'Es konnte keine Schuld'; - $lang->failed_declared = 'Konnte nicht vorwerfen'; - $lang->fail_to_delete_have_children = 'Bitte versuchen Sie es erneut nach dem Entfernen erste Antworten'; - - $lang->confirm_submit = 'Sind Sie sicher, dass zur Vorlage? '; - $lang->confirm_logout = 'Sind Sie sicher, dass nach Logout? '; - $lang->confirm_vote = 'Sind Sie sicher, dass zu empfehlen? '; - $lang->CONFIRM_DELETE = 'Sind Sie sicher, dass löschen? '; - $lang->confirm_move = 'Sind Sie sicher, dass zu bewegen? '; - $lang->confirm_reset = 'Sind Sie sicher, dass zurücksetzen? '; - $lang->confirm_leave = 'Sind Sie sicher, dass zu verlassen? '; - $lang->confirm_update = 'Are you sure to update?'; - - $lang->column_type = 'Spaltenart'; - $lang->column_type_list['text'] = 'ein Online-Text'; - $lang->column_type_list['homepage'] = 'url'; - $lang->column_type_list['email_address'] =' E-Mail '; - $lang->column_type_list['tel'] = 'Telefonnummer'; - $lang->column_type_list['textarea'] = 'Multi-line textarea'; - $lang->column_type_list['checkbox'] = 'Checkbox (multiple Auswahl)'; - $lang->column_type_list['select'] = 'select box (Einzel-Auswahl) '; - $lang->column_type_list['radio'] = 'radio button (radio)'; - $lang->column_type_list['kr_zip'] = 'Postleitzahl (Koreanisch) '; - $lang->column_type_list['date'] = 'Datum (jjjj / mm / dd)'; - // $lang->column_type_list [ 'jp_zip'] = 'Postleitzahl (Japanisch)'; - $lang->column_name = 'Spaltenname'; - $lang->column_title = 'Spaltentitel'; - $lang->default_value = 'Standardwert'; - $lang->is_active = 'Aktiv'; - $lang->is_required = 'Pflichtfeld'; - $lang->eid = '확장변수 이름'; - - // ftp 관련 - $lang->ftp_form_title = 'FTP 정보 입력'; - $lang->ftp = 'FTP'; - $lang->ftp_host = 'FTP hostname'; - $lang->ftp_port = 'FTP port'; - $lang->about_ftp_password = 'FTP password will not be stored'; - $lang->cmd_check_ftp_connect = 'FTP 접속 확인'; - $lang->about_ftp_info = " - FTP 정보는 다음의 경우에 이용될 수 있습니다.
- 1. PHP의 safe_mode=On일 경우에 FTP 정보를 이용해서 XE를 정상적으로 동작할 수 있게 합니다.
- 2. 자동 업데이트등에서 FTP 정보를 이용할 수 있습니다.
- 이 FTP정보는 files/config/ftp.config.php 파일내에 정보가 저장됩니다.
- 그리고 설치 후 관리자 페이지에서 FTP 정보를 변경하거나 제거할 수 있습니다.
- "; - - $lang->msg_safe_mode_ftp_needed = "PHP의 safe_mode가 On일 경우 FTP 정보를 꼭 입력해주셔야 XE의 설치 및 사용이 가능합니다"; - $lang->msg_ftp_not_connected = "localhost로의 FTP 접속 오류가 발생하였습니다. ftp 포트 번호를 확인해주시거나 ftp 서비스가 가능한지 확인해주세요"; - $lang->msg_ftp_invalid_auth_info = "입력하신 FTP 정보로 로그인을 하지 못했습니다. FTP정보를 확인해주세요"; - $lang->msg_ftp_mkdir_fail = "FTP를 이용한 디렉토리 생성 명령을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; - $lang->msg_ftp_chmod_fail = "FTP를 이용한 디렉토리의 속성 변경을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; - $lang->msg_ftp_connect_success = "FTP 접속 및 인증 성공하였습니다"; - - $lang->ftp_path_title = 'FTP 경로 정보 입력'; - $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; - $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; - - - // Alert Nachrichten für JavaScript unter Verwendung von XML-Filter - $lang->filter->isnull = 'Bitte geben Sie einen Wert für% s'; - $lang->filter->outofrange = 'Bitte richten Sie die Textlänge von% s'; - $lang->filter->equalto = "Der Wert von% s ist ungültig"; - $lang->filter->invalid_email = "Das Format von% s ist ungültig. ex) zbxe@zeroboard.com"; - $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "Das Format von% s ist ungültig. \ \ Nall Werte sollte aus Alphabet, Zahlen oder Unterstrich (_) und den ersten Buchstaben sollten Alphabet" ; - $lang->filter->invalid_homepage = "Das Format von% s ist ungültig. ex) http://www.zeroboard.com"; - $lang->filter->invalid_korean = "Das Format von% s ist ungültig. Koreanisch Bitte geben Sie nur"; - $lang->filter->invalid_korean_number = "Das Format von% s ist ungültig. Bitte geben Sie Ihre Koreanisch oder Zahlen"; - $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_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.
To view them, please use another non-administrator ID."; -?> +cmd_write = 'Schreiben'; + $lang->cmd_reply = 'Antworten'; + $lang->cmd_delete = 'Löschen'; + $lang->cmd_modify = 'Ändern'; + $lang->cmd_edit = 'Bearbeiten'; + $lang->cmd_view = 'Anzeigen'; + $lang->cmd_view_all = 'Alle anzeigen'; + $lang->cmd_list = 'US -'; + $lang->cmd_prev = 'Zurück'; + $lang->cmd_next = 'Nächster'; + $lang->cmd_send_trackback = 'Trackback senden'; + $lang->cmd_registration = $lang->cmd_submit = 'Übermitteln'; + $lang->cmd_comment_registration = 'Kommentar hinzufügen'; + $lang->cmd_insert = 'Legen Sie'; + $lang->cmd_save = 'sichern'; + $lang->cmd_load = 'Laden'; + $lang->cmd_input = 'Input'; + $lang->cmd_search = 'Suche'; + $lang->cmd_find = '찾기'; + $lang->cmd_replace = '바꾸기'; + $lang->cmd_confirm = '확인'; + $lang->cmd_cancel = 'Abbrechen'; + $lang->cmd_back = 'Zurück'; + $lang->cmd_vote = 'Weiterempfehlen'; + $lang->cmd_vote_down = 'Criticize'; + $lang->cmd_declare = 'accuse'; + $lang->cmd_cancel_declare = 'accuse Abbrechen'; + $lang->cmd_declared_list = 'Vorwürfe Liste'; + $lang->cmd_copy = 'Kopieren'; + $lang->cmd_move = 'Verschieben'; + $lang->cmd_move_up = 'Nach oben'; + $lang->cmd_move_down = 'Down'; + $lang->cmd_add_indent = 'Einrücken'; + $lang->cmd_remove_indent = 'Ausrücken'; + $lang->cmd_management = 'Verwaltung'; + $lang->cmd_make = 'Erstellen'; + $lang->cmd_select = 'Select'; + $lang->cmd_select_all = 'Alle auswählen'; + $lang->cmd_unselect_all = 'Alle abwählen'; + $lang->cmd_reverse_all = 'Reverse'; + $lang->cmd_close_all = 'Schließen Sie alle'; + $lang->cmd_open_all = 'Open All'; + $lang->cmd_reload = 'Reload'; + $lang->cmd_close = 'Schließen'; + $lang->cmd_open = 'Open'; + $lang->cmd_setup = 'Konfiguration'; + $lang->cmd_addition_setup = 'Zusätzliche Setup '; + $lang->cmd_option = 'Option'; + $lang->cmd_apply = 'Übernehmen'; + $lang->cmd_open_calendar = 'Wählen Sie ein Datum'; + $lang->cmd_send = 'Senden'; + $lang->cmd_print = 'Drucken'; + $lang->cmd_scrap = 'Schrott'; + $lang->cmd_preview = 'Vorschau'; + $lang->cmd_reset = 'Reset'; + $lang->cmd_remake_cache = 'Re-Cache-Datei erstellen'; + $lang->cmd_publish = 'Veröffentlichen'; + $lang->cmd_layout_setup = 'Konfiguration Layout'; + $lang->cmd_layout_edit = 'Layout bearbeiten'; + $lang->cmd_search_by_ipaddress = 'Search by IP Address'; + $lang->cmd_add_ip_to_spamfilter = 'Add IP to spamfilter'; + + $lang->enable = 'Aktivieren'; + $lang->deaktivieren = 'Deaktivieren'; + + // Essential Words + $lang->menu = 'Menu'; + $lang->no = 'Nein'; + $lang->notice = 'Hinweis'; + $lang->secret = 'Geheim'; + $lang->category = $lang->category_srl = 'Kategorie'; + $lang->none_category = '분류없음'; + $lang->none_image = '이미지 없음'; + $lang->document_srl = 'Doc. No '; + $lang->user_id = 'User-ID'; + $lang->author = 'Entwickler'; + $lang->password = 'Passwort'; + $lang->password1 = 'Passwort'; + $lang->password2 = 'Passwort bestätigen'; + $lang->admin_id = 'Admin ID'; + $lang->writer = 'Autor'; + $lang->user_name = 'Username'; + $lang->nick_name = 'Nick Name'; + $lang->email_address = 'E-Mail'; + $lang->homepage = 'Startseite'; + $lang->blog = 'Blog'; + $lang->birthday = 'Geburtstag'; + $lang->browser_title = 'Browser-Titel'; + $lang->title = 'Betreff'; + $lang->title_content = 'Betreff + Inhalt'; + $lang->topic = 'Thema'; + $lang->replies = 'Antwort'; + $lang->content = 'Inhalt'; + $lang->document = 'Artikel'; + $lang->comment = 'Kommentar'; + $lang->description = 'Beschreibung'; + $lang->trackback = 'Trackback'; + $lang->tag = 'Tag'; + $lang->allow_comment = 'Kommentare erlauben'; + $lang->lock_comment = 'Block Kommentare'; + $lang->allow_trackback = 'Allow Trackbacks'; + $lang->uploaded_file = 'Anlage'; + $lang->grant = 'Erlaubnis'; + $lang->target = 'target'; + $lang->total = 'Gesamt'; + $lang->total_count = 'count Gesamt'; + $lang->ipaddress = 'IP-Adresse'; + $lang->path = 'Pfad'; + $lang->cart = 'Ausgewählte Posten'; + $lang->friend = 'Freunde'; + $lang->notify = 'Meldung'; + $lang->order_target = 'Ausrichten Target'; + $lang->order_type = 'Sortieren Typ'; + $lang->order_asc = 'Aufstieg'; + $lang->order_desc = 'Abstieg'; + $lang->file = 'file'; + + $lang->mid = 'Module Name'; + $lang->sid = 'Site Name'; + $lang->layout = 'Layout'; + $lang->mobile_layout = 'Mobile Layout'; + $lang->widget = 'Widget'; + $lang->module = 'Modul'; + $lang->skin = 'Thema'; + $lang->mobile_skin = 'Mobile Theme'; + $lang->colorset = 'Colorset'; + $lang->extra_vars = 'Extra Vars'; + + $lang->domain = "Domain Name"; + $lang->url = "URL"; + $lang->document_url = 'Artikel-URL'; + $lang->trackback_url = 'Trackback-URL'; + $lang->blog_name = 'Blog-Titel'; + $lang->excerpt = 'Zitat'; + + $lang->document_count = 'Total Artikel'; + $lang->page_count = 'Page Count'; + $lang->list_count = 'US-Count '; + $lang->search_list_count = 'Suchen US-Count'; + $lang->readed_count = 'Views'; + $lang->voted_count = 'Stimmen'; + $lang->comment_count = 'Kommentare'; + $lang->member_count = 'Mitglied Count'; + $lang->date = 'Datum'; + $lang->regdate = 'Anmeldungsdatum Datum'; + $lang->last_update = 'Letzte Aktualisierung'; + $lang->last_post = 'Letzter Beitrag'; + $lang->signup_date = 'Join Date'; + $lang->last_login = 'Letzter Login'; + $lang->first_page = 'Erste Seite'; + $lang->last_page = 'Letzte Seite'; + $lang->search_target = 'Target für die Google-Suche'; + $lang->search_keyword = 'Stichwort'; + $lang->is_default = 'Standard'; + + $lang->no_documents = 'Keine Artikel'; + + $lang->board_manager = 'Board'; + $lang->member_manager = 'Mitglied'; + $lang->layout_manager = 'Layout-Einstellungen'; + + $lang->use = 'Use'; + $lang->notuse = 'nicht verwenden'; + $lang->not_exists = 'nicht vorhanden'; + + $lang->public = 'öffentlich'; + $lang->private = 'private'; + + $lang->unit_sec = 's'; + $lang->unit_min = 'mindestens'; + $lang->unit_hour = 'h'; + $lang->unit_day = 'th'; + $lang->unit_month = 'Monat'; + $lang->unit_year = 'Jahr'; + + $lang->unit_week = array( + 'Monday' => 'Montag', + 'Tuesday' => 'Dienstag', + 'Wednesday' => 'Mittwoch', + 'Thursday' => 'Donnerstag', + 'Friday' => 'Freitag', + 'Saturday' => 'Samstag', + 'Sunday' => 'Sonntag', + ); + + $lang->unit_meridiem = array( + 'am' => 'am', + 'pm' => 'pm', + 'AM' => 'AM', + 'PM' => 'PM', + ); + + $lang->time_gap = array( + 'min' => 'Vor %d Minute', + 'mins' => '%d Stunden', + 'hour' => '%d Tag', + 'hours' => '%d Tage', + ); + + // Beschreibungen + $lang->about_tag = 'Sie können mehrere Tags, indem Sie ein Komma (,) zwischen den einzelnen Tag'; + $lang->about_layout = 'Layouts schmücken das Aussehen Ihrer Module. Sie können sie von Layout-Menü am oberen Rand '; + + // Messages + $lang->msg_call_server = 'Anfordern an den Server, bitte warten'; + $lang->msg_db_not_setted = 'DB-Konfiguration wurde nicht festgelegt'; + $lang->msg_dbconnect_failed = "Error has occurred while connecting DB.\nPlease check DB information again"; // TODO:translation en -> ge + $lang->msg_invalid_queryid = 'spezifiziert Abfrage ID-Wert ist ungültig'; + $lang->msg_not_permitted = 'Sie haben keine Berechtigung zum Zugriff auf'; + $lang->msg_input_password = 'Bitte geben Sie das Passwort'; + $lang->msg_invalid_document = 'Ungültige Article Number'; + $lang->msg_invalid_request = 'Invalid request '; + $lang->msg_invalid_password = 'Ungültiges Passwort'; + $lang->msg_error_occured = 'Ein Fehler ist aufgetreten '; + $lang->msg_not_founded = 'Target konnte nicht gefunden werden'; + $lang->msg_no_result = 'Nichts gefunden'; + $lang->msg_fail_to_request_open = 'Fail to open your request'; + $lang->msg_invalid_format = 'Invalid Format'; + + $lang->msg_not_permitted_act = 'Sie haben keine Berechtigung zur Ausführung angeforderte Aktion'; + $lang->msg_module_is_not_exists = "요청하신 모듈을 찾을 수 없습니다.\n사이트 관리자에게 모듈 점검 요청 바랍니다"; + $lang->msg_module_is_not_standalone = 'Gewünschte Modul kann nicht ausgeführt werden unabhängig'; + $lang->msg_default_url_is_not_defined = '기본 URL이 정해지지 않아서 동작을 중지합니다'; + + $lang->success_registed = 'Anmeldungsdatum'; + $lang->success_declared = 'Accused erfolgreich'; + $lang->success_updated = 'erfolgreich aktualisiert'; + $lang->success_deleted = 'erfolgreich gelöscht'; + $lang->success_voted = 'Empfohlen'; + $lang->success_blamed = 'Schuld success_blamed'; + $lang->success_moved = 'Umzug'; + $lang->success_sended = 'Gesendet'; + $lang->success_reset = 'Reset'; + $lang->success_leaved = 'Alle Mitglieder Daten wurden komplett gestrichen. '; + $lang->success_saved = 'erfolgreich gespeichert '; + + $lang->fail_to_delete = 'konnte nicht gelöscht werden'; + $lang->fail_to_move = 'konnte nicht verschoben werden'; + + $lang->failed_voted = 'konnte nicht empfehlen'; + $lang->failed_blamed = 'Es konnte keine Schuld'; + $lang->failed_declared = 'Konnte nicht vorwerfen'; + $lang->fail_to_delete_have_children = 'Bitte versuchen Sie es erneut nach dem Entfernen erste Antworten'; + + $lang->confirm_submit = 'Sind Sie sicher, dass zur Vorlage? '; + $lang->confirm_logout = 'Sind Sie sicher, dass nach Logout? '; + $lang->confirm_vote = 'Sind Sie sicher, dass zu empfehlen? '; + $lang->CONFIRM_DELETE = 'Sind Sie sicher, dass löschen? '; + $lang->confirm_move = 'Sind Sie sicher, dass zu bewegen? '; + $lang->confirm_reset = 'Sind Sie sicher, dass zurücksetzen? '; + $lang->confirm_leave = 'Sind Sie sicher, dass zu verlassen? '; + $lang->confirm_update = 'Are you sure to update?'; + + $lang->column_type = 'Spaltenart'; + $lang->column_type_list['text'] = 'ein Online-Text'; + $lang->column_type_list['homepage'] = 'url'; + $lang->column_type_list['email_address'] =' E-Mail '; + $lang->column_type_list['tel'] = 'Telefonnummer'; + $lang->column_type_list['textarea'] = 'Multi-line textarea'; + $lang->column_type_list['checkbox'] = 'Checkbox (multiple Auswahl)'; + $lang->column_type_list['select'] = 'select box (Einzel-Auswahl) '; + $lang->column_type_list['radio'] = 'radio button (radio)'; + $lang->column_type_list['kr_zip'] = 'Postleitzahl (Koreanisch) '; + $lang->column_type_list['date'] = 'Datum (jjjj / mm / dd)'; + // $lang->column_type_list [ 'jp_zip'] = 'Postleitzahl (Japanisch)'; + $lang->column_name = 'Spaltenname'; + $lang->column_title = 'Spaltentitel'; + $lang->default_value = 'Standardwert'; + $lang->is_active = 'Aktiv'; + $lang->is_required = 'Pflichtfeld'; + $lang->eid = '확장변수 이름'; + + // ftp 관련 + $lang->ftp_form_title = 'FTP 정보 입력'; + $lang->ftp = 'FTP'; + $lang->ftp_host = 'FTP hostname'; + $lang->ftp_port = 'FTP port'; + $lang->about_ftp_password = 'FTP password will not be stored'; + $lang->cmd_check_ftp_connect = 'FTP 접속 확인'; + $lang->about_ftp_info = " + FTP 정보는 다음의 경우에 이용될 수 있습니다.
+ 1. PHP의 safe_mode=On일 경우에 FTP 정보를 이용해서 XE를 정상적으로 동작할 수 있게 합니다.
+ 2. 자동 업데이트등에서 FTP 정보를 이용할 수 있습니다.
+ 이 FTP정보는 files/config/ftp.config.php 파일내에 정보가 저장됩니다.
+ 그리고 설치 후 관리자 페이지에서 FTP 정보를 변경하거나 제거할 수 있습니다.
+ "; + + $lang->msg_safe_mode_ftp_needed = "PHP의 safe_mode가 On일 경우 FTP 정보를 꼭 입력해주셔야 XE의 설치 및 사용이 가능합니다"; + $lang->msg_ftp_not_connected = "localhost로의 FTP 접속 오류가 발생하였습니다. ftp 포트 번호를 확인해주시거나 ftp 서비스가 가능한지 확인해주세요"; + $lang->msg_ftp_invalid_auth_info = "입력하신 FTP 정보로 로그인을 하지 못했습니다. FTP정보를 확인해주세요"; + $lang->msg_ftp_mkdir_fail = "FTP를 이용한 디렉토리 생성 명령을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; + $lang->msg_ftp_chmod_fail = "FTP를 이용한 디렉토리의 속성 변경을 실패하였습니다. FTP 서버의 설정을 확인해주세요"; + $lang->msg_ftp_connect_success = "FTP 접속 및 인증 성공하였습니다"; + + $lang->ftp_path_title = 'FTP 경로 정보 입력'; + $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; + $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; + + + // Alert Nachrichten für JavaScript unter Verwendung von XML-Filter + $lang->filter->isnull = 'Bitte geben Sie einen Wert für% s'; + $lang->filter->outofrange = 'Bitte richten Sie die Textlänge von% s'; + $lang->filter->equalto = "Der Wert von% s ist ungültig"; + $lang->filter->invalid_email = "Das Format von% s ist ungültig. ex) developers@xpressengine.com"; + $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "Das Format von% s ist ungültig. \ \ Nall Werte sollte aus Alphabet, Zahlen oder Unterstrich (_) und den ersten Buchstaben sollten Alphabet" ; + $lang->filter->invalid_homepage = "Das Format von% s ist ungültig. ex) http://xpressengine.com/"; + $lang->filter->invalid_korean = "Das Format von% s ist ungültig. Koreanisch Bitte geben Sie nur"; + $lang->filter->invalid_korean_number = "Das Format von% s ist ungültig. Bitte geben Sie Ihre Koreanisch oder Zahlen"; + $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_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.
To view them, please use another non-administrator ID."; +?> diff --git a/common/lang/jp.lang.php b/common/lang/jp.lang.php index eee01c929..5505e54e4 100644 --- a/common/lang/jp.lang.php +++ b/common/lang/jp.lang.php @@ -1,324 +1,324 @@ -cmd_write = '書き込む'; - $lang->cmd_reply = '返信'; - $lang->cmd_delete = '削除'; - $lang->cmd_modify = '修正'; - $lang->cmd_edit = '編集'; - $lang->cmd_view = '表示'; - $lang->cmd_view_all = 'すべて表示'; - $lang->cmd_list = 'リスト'; - $lang->cmd_prev = '前へ'; - $lang->cmd_next = '次へ'; - $lang->cmd_send_trackback = 'トラックバック送信'; - $lang->cmd_registration = $lang->cmd_submit = '登録'; - $lang->cmd_comment_registration = 'コメント登録'; - $lang->cmd_insert = '挿入'; - $lang->cmd_save = '保存'; - $lang->cmd_load = '読み込む'; - $lang->cmd_input = '入力'; - $lang->cmd_search = '検索'; - $lang->cmd_find = '検索'; - $lang->cmd_replace = '置換'; - $lang->cmd_confirm = '確認'; - $lang->cmd_cancel = '取り消し'; - $lang->cmd_back = '戻る'; - $lang->cmd_vote = '推薦'; - $lang->cmd_vote_down = '非推薦'; - $lang->cmd_declare = '通報'; - $lang->cmd_cancel_declare = '通報取り消し'; - $lang->cmd_declared_list = '通報リスト'; - $lang->cmd_copy = 'コピー'; - $lang->cmd_move = '移動'; - $lang->cmd_move_up = '上へ'; - $lang->cmd_move_down = '下へ'; - $lang->cmd_add_indent = 'インデント'; - $lang->cmd_remove_indent = '逆インデント'; - $lang->cmd_management = '管理'; - $lang->cmd_make = '作成'; - $lang->cmd_select = '選択'; - $lang->cmd_select_all = 'すべて選択'; - $lang->cmd_unselect_all = 'すべて解除'; - $lang->cmd_reverse_all = '選択の反転'; - $lang->cmd_close_all = 'すべて閉じる'; - $lang->cmd_open_all = 'すべて開く'; - $lang->cmd_reload = 'リロード'; - $lang->cmd_close = '閉じる'; - $lang->cmd_open = '開く'; - $lang->cmd_setup = '設定'; - $lang->cmd_addition_setup = '追加設定'; - $lang->cmd_option = 'オプション'; - $lang->cmd_apply = '適用'; - $lang->cmd_open_calendar = 'カレンダーを開く'; - $lang->cmd_send = '送信'; - $lang->cmd_print = '印刷'; - $lang->cmd_scrap = 'スクラップ'; - $lang->cmd_preview = 'プレビュー'; - $lang->cmd_reset = '初期化'; - $lang->cmd_remake_cache = 'キャッシュファイル再生成'; - $lang->cmd_publish = '発行'; - $lang->cmd_layout_setup = 'レイアウト設定'; - $lang->cmd_layout_edit = 'レイアウト編集'; - $lang->cmd_search_by_ipaddress = 'IPアドレスで検索'; - $lang->cmd_add_ip_to_spamfilter = 'スパムフィルターにIPを追加'; - - $lang->enable = '可能'; - $lang->disable = '不可'; - - // 基本用語 - $lang->menu = 'メニュー'; - $lang->no = '番号'; - $lang->notice = 'お知らせ'; - $lang->secret = '非公開'; - $lang->category = $lang->category_srl = 'カテゴリ'; - $lang->none_category = 'カテゴリ無し'; - $lang->none_image = 'イメージなし'; - $lang->document_srl = '書き込み番号'; - $lang->user_id = 'ユーザーID'; - $lang->author = '作成者'; - $lang->password = 'パスワード'; - $lang->password1 = 'パスワード'; - $lang->password2 = 'パスワード確認'; - $lang->admin_id = '管理者ID'; - $lang->writer = '投稿者'; - $lang->user_name = '名前'; - $lang->nick_name = 'ニックネーム'; - $lang->email_address = 'メールアドレス'; - $lang->homepage = 'ホームページ'; - $lang->blog = 'ブログ'; - $lang->birthday = 'お誕生日'; - $lang->browser_title = 'ブラウザータイトル'; - $lang->title = 'タイトル'; - $lang->title_content = 'タイトル+内容'; - $lang->topic = 'トピック'; - $lang->replies = '返事'; - $lang->content = '内容'; - $lang->document = '書き込み'; - $lang->comment = 'コメント'; - $lang->description = '説明'; - $lang->trackback = 'トラックバック'; - $lang->tag = 'タグ'; - $lang->allow_comment = 'コメント許可'; - $lang->lock_comment = 'コメントロック'; - $lang->allow_trackback = 'トラックバック許可'; - $lang->uploaded_file = '添付'; - $lang->grant = '権限'; - $lang->target = '対象'; - $lang->total = 'すべて'; - $lang->total_count = 'トータル数'; - $lang->ipaddress = 'IPアドレス'; - $lang->path = 'パス'; - $lang->cart = '選択項目'; - $lang->friend = '友達'; - $lang->notify = 'アラート'; - $lang->order_target = 'ソート対象'; - $lang->order_type = 'ソート方法'; - $lang->order_asc = '昇る'; - $lang->order_desc = '降下'; - $lang->file = 'ファイル'; - - $lang->mid = 'モジュール名'; - $lang->sid = 'バーチャル(Virtual)サイト名'; - $lang->layout = 'レイアウト'; - $lang->mobile_layout = 'Mobile Layout'; - $lang->widget = 'ウィジェット'; - $lang->module = 'モジュール'; - $lang->skin = 'スキン'; - $lang->mobile_skin = 'Mobile Theme'; - $lang->colorset = 'カラーセット'; - $lang->extra_vars = '拡張変数'; - - $lang->domain = 'ドメイン'; - $lang->url = 'URL'; - $lang->document_url = '書き込みURL'; - $lang->trackback_url = 'トラックバックURL'; - $lang->blog_name = 'ブログ名'; - $lang->excerpt = '抜粋'; - - $lang->document_count = '書き込み数'; - $lang->page_count = 'ページ数'; - $lang->list_count = 'リスト数'; - $lang->search_list_count = '検索リスト数'; - $lang->readed_count = '閲覧数'; - $lang->voted_count = '推薦数'; - $lang->comment_count = 'コメント数'; - $lang->member_count = '会員数'; - $lang->date = '日付'; - $lang->regdate = '登録日'; - $lang->last_update = '最近修正日'; - $lang->last_post = '最近登録'; - $lang->signup_date = '登録日'; - $lang->last_login = '最近ログイン'; - $lang->first_page = '最初のページ'; - $lang->last_page = '最後のページ'; - $lang->search_target = '検索対象'; - $lang->search_keyword = 'キーワード'; - $lang->is_default = 'デフォルト'; - - $lang->no_documents = '登録された書き込みがありません。'; - - $lang->board_manager = '掲示板管理'; - $lang->member_manager = '会員管理'; - $lang->layout_manager = 'レイアウト管理'; - - $lang->use = '使用'; - $lang->notuse = '未使用'; - $lang->not_exists = 'なし'; - - $lang->public = '公開'; - $lang->private = '非公開'; - - $lang->unit_sec = '秒'; - $lang->unit_min = '分'; - $lang->unit_hour = '時'; - $lang->unit_day = '日'; - $lang->unit_month = '月'; - $lang->unit_year = '年'; - - $lang->unit_week = array( - 'Monday' => '月', - 'Tuesday' => '火', - 'Wednesday' => '水', - 'Thursday' => '木', - 'Friday' => '金', - 'Saturday' => '土', - 'Sunday' => '日', - ); - - $lang->unit_meridiem = array( - 'am' => '午前', - 'pm' => '午後', - 'AM' => '午前', - 'PM' => '午後', - ); - - $lang->time_gap = array( - 'min' => '%d 分前', - 'mins' => '%d 分前', - 'hour' => '%d 時間前', - 'hours' => '%d 時間前', - ); - - // 説明関連 - $lang->about_tag = 'タグを入力する時、「,」(半角コンマ)を使うと複数登録出来ます。'; - $lang->about_layout = 'レイアウトでモジュールの枠をデザインします。上段のレイアウトメニューで管理出来ます。'; - - // メッセージ関連 - $lang->msg_call_server = 'サーバへ問合わせ中です。しばらくお待ち下さい。'; - $lang->msg_db_not_setted = 'DBが設定されていません。'; - $lang->msg_dbconnect_failed = "データベースアクセスにエラーが発生しました。\nデータベースの情報をもう一度確認して下さい。"; - $lang->msg_invalid_queryid = 'クエリIDの値が無効です。'; - $lang->msg_not_permitted = '権限がありません。'; - $lang->msg_input_password = 'パスワードを入力して下さい。'; - $lang->msg_invalid_document = '無効な書き込み番号です。'; - $lang->msg_invalid_request = '無効なリクエストです。'; - $lang->msg_invalid_password = 'パスワードが正しくありません。'; - $lang->msg_error_occured = 'エラーが発生しました。'; - $lang->msg_not_founded = '見つかりません。'; - $lang->msg_no_result = '検索結果がありません。'; - $lang->msg_fail_to_request_open = 'リクエストのアクセスに失敗しました。'; - $lang->msg_invalid_format = '正しくないフォーマットです。'; - - $lang->msg_not_permitted_act = '現在の操作は実行する権限がありません。'; - $lang->msg_module_is_not_exists = "動作に必要なモジュールが見つかりません。\nサイト管理者へモジュールの点検をお問い合わせ下さい。"; - $lang->msg_module_is_not_standalone = 'このモジュールはスタンドアローンでは作動しません。'; - $lang->msg_default_url_is_not_defined = 'デフォルトURLが定められてないため、動作を中止します。'; - - $lang->success_registed = '登録しました。'; - $lang->success_declared = '通報しました。'; - $lang->success_updated = '修正しました。'; - $lang->success_deleted = '削除しました。'; - $lang->success_restore = '復元しました。'; - $lang->success_voted = '推薦しました。'; - $lang->success_blamed = '非推薦しました。'; - $lang->success_moved = '移動しました。'; - $lang->success_sended = '送信しました。'; - $lang->success_reset = '初期化しました。'; - $lang->success_leaved = '退会しました。'; - $lang->success_saved = '保存しました。'; - - $lang->fail_to_delete = '削除に失敗しました。'; - $lang->fail_to_move = '移動に失敗しました。'; - - $lang->failed_voted = '推薦出来ません。'; - $lang->failed_blamed = '非推薦出来ません。'; - $lang->failed_declared = '通報出来ません。'; - $lang->fail_to_delete_have_children = '返信の書き込みがあり、削除出来ません。'; - - $lang->confirm_submit = '登録しますか?'; - $lang->confirm_logout = 'ログアウトしますか?'; - $lang->confirm_vote = '推薦しますか?'; - $lang->confirm_delete = '削除しますか?'; - $lang->confirm_restore = '復元しますか?'; - $lang->confirm_move = '移動しますか?'; - $lang->confirm_reset = '初期化しますか?'; - $lang->confirm_leave = '退会しますか?'; - $lang->confirm_update = 'Are you sure to update?'; - - $lang->column_type = 'タイプ'; - $lang->column_type_list['text'] = '入力フィールド(text)'; - $lang->column_type_list['homepage'] = 'URLタイプ(url)'; - $lang->column_type_list['email_address'] = 'メールアドレスタイプ(email)'; - $lang->column_type_list['tel'] = '電話番号タイプ(phone)'; - $lang->column_type_list['textarea'] = 'テキストエリア(textarea)'; - $lang->column_type_list['checkbox'] = 'チェックボックス(checkbox)'; - $lang->column_type_list['select'] = '選択(select)'; - $lang->column_type_list['radio'] = 'ラジオボタン (radio)'; - $lang->column_type_list['kr_zip'] = '韓国住所(zip)'; - $lang->column_type_list['date'] = '日付(年月日)'; - //$lang->column_type_list['jp_zip'] = '日本住所(zip)'; - $lang->column_name = 'コラム名'; - $lang->column_title = 'コラムタイトル'; - $lang->default_value = 'デフォルト値'; - $lang->is_active = '活性化'; - $lang->is_required = '必須項目'; - $lang->eid = '拡張変数名'; - - // ftp関連 - $lang->ftp_form_title = 'サーバーのFTP情報の入力'; - $lang->ftp = 'FTP'; - $lang->ftp_host = 'FTP hostname'; - $lang->ftp_port = 'FTPポート番号(port)'; - $lang->about_ftp_password = 'FTP password will not be stored'; - $lang->cmd_check_ftp_connect = 'FTP接続をテストする'; - $lang->about_ftp_info = " - FTP情報は次の場合、利用されます。
- 1. サーバー側のPHPの設定中、「safe_mode=On」になった際、FTP情報を用いてXEが正常に働くようにします。
- 2. FTP経由でXEの自動アップデート等に使われます。
- FTP情報は「files/config/ftp.config.php」の中に保存されます。
- また、XEのインストールの後、管理者画面からFTP情報の変更・削除が可能です。(省略可能)
- "; - - $lang->msg_safe_mode_ftp_needed = 'PHPのsafe_modeがOnの場合、FTP情報を登録することで、XEのインストール及び利用が可能になります。'; - $lang->msg_ftp_not_connected = 'localhostへのFTP接続エラーが発生しました。FTPポート(port)番号をはじめ、FTPサービスが可能であるかをご確認下さい。'; - $lang->msg_ftp_invalid_auth_info = 'ログインが失敗しました。 FTPアクセス情報を再度ご確認下さい。'; - $lang->msg_ftp_mkdir_fail = 'FTPを用いたディレクトリ生成に失敗しました。FTPサーバーの設定を再度ご確認下さい。'; - $lang->msg_ftp_chmod_fail = 'FTPを用いたディレクトリパーミッション(permission)変更に失敗しました。FTPサーバーの設定を再度ご確認下さい。'; - $lang->msg_ftp_connect_success = 'FTP接続に成功しました。'; - - $lang->ftp_path_title = 'FTP 경로 정보 입력'; - $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; - $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; - - - // xml filterで用いられているjavascript用のアラートメッセージ - $lang->filter->isnull = '%sを入力して下さい。'; - $lang->filter->outofrange = '%sの文字の長さを合わせて下さい。'; - $lang->filter->equalto = '%sが正しくありません。'; - $lang->filter->invalid_email = '%sのパターンが正しくありません。 (例: zbxe@xepressengine.com)'; - $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%sの形式が正しくありません。\\n半角の英数と記号「_」を組み合わせて入力して下さい。頭字は半角英文字でなければなりません。"; - $lang->filter->invalid_homepage = '%sの形式が正しくありません。 (例: http://www.xepressengine.com)'; - $lang->filter->invalid_korean = '%sの形式が正しくありません。ハングルのみ入力して下さい。'; - $lang->filter->invalid_korean_number = '%sの形式が正しくありません。ハングルと半角数字で入力して下さい。'; - $lang->filter->invalid_alpha = '%sの形式が正しくありません。半角英文字のみ入力して下さい。'; - $lang->filter->invalid_alpha_number = '%sの形式が正しくありません。半角英数で入力して下さい。'; - $lang->filter->invalid_number = '%sの形式が正しくありません。半角数字で入力して下さい。'; - - $lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.
To view them, please use another non-administrator ID."; -?> +cmd_write = '書き込む'; + $lang->cmd_reply = '返信'; + $lang->cmd_delete = '削除'; + $lang->cmd_modify = '修正'; + $lang->cmd_edit = '編集'; + $lang->cmd_view = '表示'; + $lang->cmd_view_all = 'すべて表示'; + $lang->cmd_list = 'リスト'; + $lang->cmd_prev = '前へ'; + $lang->cmd_next = '次へ'; + $lang->cmd_send_trackback = 'トラックバック送信'; + $lang->cmd_registration = $lang->cmd_submit = '登録'; + $lang->cmd_comment_registration = 'コメント登録'; + $lang->cmd_insert = '挿入'; + $lang->cmd_save = '保存'; + $lang->cmd_load = '読み込む'; + $lang->cmd_input = '入力'; + $lang->cmd_search = '検索'; + $lang->cmd_find = '検索'; + $lang->cmd_replace = '置換'; + $lang->cmd_confirm = '確認'; + $lang->cmd_cancel = '取り消し'; + $lang->cmd_back = '戻る'; + $lang->cmd_vote = '推薦'; + $lang->cmd_vote_down = '非推薦'; + $lang->cmd_declare = '通報'; + $lang->cmd_cancel_declare = '通報取り消し'; + $lang->cmd_declared_list = '通報リスト'; + $lang->cmd_copy = 'コピー'; + $lang->cmd_move = '移動'; + $lang->cmd_move_up = '上へ'; + $lang->cmd_move_down = '下へ'; + $lang->cmd_add_indent = 'インデント'; + $lang->cmd_remove_indent = '逆インデント'; + $lang->cmd_management = '管理'; + $lang->cmd_make = '作成'; + $lang->cmd_select = '選択'; + $lang->cmd_select_all = 'すべて選択'; + $lang->cmd_unselect_all = 'すべて解除'; + $lang->cmd_reverse_all = '選択の反転'; + $lang->cmd_close_all = 'すべて閉じる'; + $lang->cmd_open_all = 'すべて開く'; + $lang->cmd_reload = 'リロード'; + $lang->cmd_close = '閉じる'; + $lang->cmd_open = '開く'; + $lang->cmd_setup = '設定'; + $lang->cmd_addition_setup = '追加設定'; + $lang->cmd_option = 'オプション'; + $lang->cmd_apply = '適用'; + $lang->cmd_open_calendar = 'カレンダーを開く'; + $lang->cmd_send = '送信'; + $lang->cmd_print = '印刷'; + $lang->cmd_scrap = 'スクラップ'; + $lang->cmd_preview = 'プレビュー'; + $lang->cmd_reset = '初期化'; + $lang->cmd_remake_cache = 'キャッシュファイル再生成'; + $lang->cmd_publish = '発行'; + $lang->cmd_layout_setup = 'レイアウト設定'; + $lang->cmd_layout_edit = 'レイアウト編集'; + $lang->cmd_search_by_ipaddress = 'IPアドレスで検索'; + $lang->cmd_add_ip_to_spamfilter = 'スパムフィルターにIPを追加'; + + $lang->enable = '可能'; + $lang->disable = '不可'; + + // 基本用語 + $lang->menu = 'メニュー'; + $lang->no = '番号'; + $lang->notice = 'お知らせ'; + $lang->secret = '非公開'; + $lang->category = $lang->category_srl = 'カテゴリ'; + $lang->none_category = 'カテゴリ無し'; + $lang->none_image = 'イメージなし'; + $lang->document_srl = '書き込み番号'; + $lang->user_id = 'ユーザーID'; + $lang->author = '作成者'; + $lang->password = 'パスワード'; + $lang->password1 = 'パスワード'; + $lang->password2 = 'パスワード確認'; + $lang->admin_id = '管理者ID'; + $lang->writer = '投稿者'; + $lang->user_name = '名前'; + $lang->nick_name = 'ニックネーム'; + $lang->email_address = 'メールアドレス'; + $lang->homepage = 'ホームページ'; + $lang->blog = 'ブログ'; + $lang->birthday = 'お誕生日'; + $lang->browser_title = 'ブラウザータイトル'; + $lang->title = 'タイトル'; + $lang->title_content = 'タイトル+内容'; + $lang->topic = 'トピック'; + $lang->replies = '返事'; + $lang->content = '内容'; + $lang->document = '書き込み'; + $lang->comment = 'コメント'; + $lang->description = '説明'; + $lang->trackback = 'トラックバック'; + $lang->tag = 'タグ'; + $lang->allow_comment = 'コメント許可'; + $lang->lock_comment = 'コメントロック'; + $lang->allow_trackback = 'トラックバック許可'; + $lang->uploaded_file = '添付'; + $lang->grant = '権限'; + $lang->target = '対象'; + $lang->total = 'すべて'; + $lang->total_count = 'トータル数'; + $lang->ipaddress = 'IPアドレス'; + $lang->path = 'パス'; + $lang->cart = '選択項目'; + $lang->friend = '友達'; + $lang->notify = 'アラート'; + $lang->order_target = 'ソート対象'; + $lang->order_type = 'ソート方法'; + $lang->order_asc = '昇る'; + $lang->order_desc = '降下'; + $lang->file = 'ファイル'; + + $lang->mid = 'モジュール名'; + $lang->sid = 'バーチャル(Virtual)サイト名'; + $lang->layout = 'レイアウト'; + $lang->mobile_layout = 'Mobile Layout'; + $lang->widget = 'ウィジェット'; + $lang->module = 'モジュール'; + $lang->skin = 'スキン'; + $lang->mobile_skin = 'Mobile Theme'; + $lang->colorset = 'カラーセット'; + $lang->extra_vars = '拡張変数'; + + $lang->domain = 'ドメイン'; + $lang->url = 'URL'; + $lang->document_url = '書き込みURL'; + $lang->trackback_url = 'トラックバックURL'; + $lang->blog_name = 'ブログ名'; + $lang->excerpt = '抜粋'; + + $lang->document_count = '書き込み数'; + $lang->page_count = 'ページ数'; + $lang->list_count = 'リスト数'; + $lang->search_list_count = '検索リスト数'; + $lang->readed_count = '閲覧数'; + $lang->voted_count = '推薦数'; + $lang->comment_count = 'コメント数'; + $lang->member_count = '会員数'; + $lang->date = '日付'; + $lang->regdate = '登録日'; + $lang->last_update = '最近修正日'; + $lang->last_post = '最近登録'; + $lang->signup_date = '登録日'; + $lang->last_login = '最近ログイン'; + $lang->first_page = '最初のページ'; + $lang->last_page = '最後のページ'; + $lang->search_target = '検索対象'; + $lang->search_keyword = 'キーワード'; + $lang->is_default = 'デフォルト'; + + $lang->no_documents = '登録された書き込みがありません。'; + + $lang->board_manager = '掲示板管理'; + $lang->member_manager = '会員管理'; + $lang->layout_manager = 'レイアウト管理'; + + $lang->use = '使用'; + $lang->notuse = '未使用'; + $lang->not_exists = 'なし'; + + $lang->public = '公開'; + $lang->private = '非公開'; + + $lang->unit_sec = '秒'; + $lang->unit_min = '分'; + $lang->unit_hour = '時'; + $lang->unit_day = '日'; + $lang->unit_month = '月'; + $lang->unit_year = '年'; + + $lang->unit_week = array( + 'Monday' => '月', + 'Tuesday' => '火', + 'Wednesday' => '水', + 'Thursday' => '木', + 'Friday' => '金', + 'Saturday' => '土', + 'Sunday' => '日', + ); + + $lang->unit_meridiem = array( + 'am' => '午前', + 'pm' => '午後', + 'AM' => '午前', + 'PM' => '午後', + ); + + $lang->time_gap = array( + 'min' => '%d 分前', + 'mins' => '%d 分前', + 'hour' => '%d 時間前', + 'hours' => '%d 時間前', + ); + + // 説明関連 + $lang->about_tag = 'タグを入力する時、「,」(半角コンマ)を使うと複数登録出来ます。'; + $lang->about_layout = 'レイアウトでモジュールの枠をデザインします。上段のレイアウトメニューで管理出来ます。'; + + // メッセージ関連 + $lang->msg_call_server = 'サーバへ問合わせ中です。しばらくお待ち下さい。'; + $lang->msg_db_not_setted = 'DBが設定されていません。'; + $lang->msg_dbconnect_failed = "データベースアクセスにエラーが発生しました。\nデータベースの情報をもう一度確認して下さい。"; + $lang->msg_invalid_queryid = 'クエリIDの値が無効です。'; + $lang->msg_not_permitted = '権限がありません。'; + $lang->msg_input_password = 'パスワードを入力して下さい。'; + $lang->msg_invalid_document = '無効な書き込み番号です。'; + $lang->msg_invalid_request = '無効なリクエストです。'; + $lang->msg_invalid_password = 'パスワードが正しくありません。'; + $lang->msg_error_occured = 'エラーが発生しました。'; + $lang->msg_not_founded = '見つかりません。'; + $lang->msg_no_result = '検索結果がありません。'; + $lang->msg_fail_to_request_open = 'リクエストのアクセスに失敗しました。'; + $lang->msg_invalid_format = '正しくないフォーマットです。'; + + $lang->msg_not_permitted_act = '現在の操作は実行する権限がありません。'; + $lang->msg_module_is_not_exists = "動作に必要なモジュールが見つかりません。\nサイト管理者へモジュールの点検をお問い合わせ下さい。"; + $lang->msg_module_is_not_standalone = 'このモジュールはスタンドアローンでは作動しません。'; + $lang->msg_default_url_is_not_defined = 'デフォルトURLが定められてないため、動作を中止します。'; + + $lang->success_registed = '登録しました。'; + $lang->success_declared = '通報しました。'; + $lang->success_updated = '修正しました。'; + $lang->success_deleted = '削除しました。'; + $lang->success_restore = '復元しました。'; + $lang->success_voted = '推薦しました。'; + $lang->success_blamed = '非推薦しました。'; + $lang->success_moved = '移動しました。'; + $lang->success_sended = '送信しました。'; + $lang->success_reset = '初期化しました。'; + $lang->success_leaved = '退会しました。'; + $lang->success_saved = '保存しました。'; + + $lang->fail_to_delete = '削除に失敗しました。'; + $lang->fail_to_move = '移動に失敗しました。'; + + $lang->failed_voted = '推薦出来ません。'; + $lang->failed_blamed = '非推薦出来ません。'; + $lang->failed_declared = '通報出来ません。'; + $lang->fail_to_delete_have_children = '返信の書き込みがあり、削除出来ません。'; + + $lang->confirm_submit = '登録しますか?'; + $lang->confirm_logout = 'ログアウトしますか?'; + $lang->confirm_vote = '推薦しますか?'; + $lang->confirm_delete = '削除しますか?'; + $lang->confirm_restore = '復元しますか?'; + $lang->confirm_move = '移動しますか?'; + $lang->confirm_reset = '初期化しますか?'; + $lang->confirm_leave = '退会しますか?'; + $lang->confirm_update = 'Are you sure to update?'; + + $lang->column_type = 'タイプ'; + $lang->column_type_list['text'] = '入力フィールド(text)'; + $lang->column_type_list['homepage'] = 'URLタイプ(url)'; + $lang->column_type_list['email_address'] = 'メールアドレスタイプ(email)'; + $lang->column_type_list['tel'] = '電話番号タイプ(phone)'; + $lang->column_type_list['textarea'] = 'テキストエリア(textarea)'; + $lang->column_type_list['checkbox'] = 'チェックボックス(checkbox)'; + $lang->column_type_list['select'] = '選択(select)'; + $lang->column_type_list['radio'] = 'ラジオボタン (radio)'; + $lang->column_type_list['kr_zip'] = '韓国住所(zip)'; + $lang->column_type_list['date'] = '日付(年月日)'; + //$lang->column_type_list['jp_zip'] = '日本住所(zip)'; + $lang->column_name = 'コラム名'; + $lang->column_title = 'コラムタイトル'; + $lang->default_value = 'デフォルト値'; + $lang->is_active = '活性化'; + $lang->is_required = '必須項目'; + $lang->eid = '拡張変数名'; + + // ftp関連 + $lang->ftp_form_title = 'サーバーのFTP情報の入力'; + $lang->ftp = 'FTP'; + $lang->ftp_host = 'FTP hostname'; + $lang->ftp_port = 'FTPポート番号(port)'; + $lang->about_ftp_password = 'FTP password will not be stored'; + $lang->cmd_check_ftp_connect = 'FTP接続をテストする'; + $lang->about_ftp_info = " + FTP情報は次の場合、利用されます。
+ 1. サーバー側のPHPの設定中、「safe_mode=On」になった際、FTP情報を用いてXEが正常に働くようにします。
+ 2. FTP経由でXEの自動アップデート等に使われます。
+ FTP情報は「files/config/ftp.config.php」の中に保存されます。
+ また、XEのインストールの後、管理者画面からFTP情報の変更・削除が可能です。(省略可能)
+ "; + + $lang->msg_safe_mode_ftp_needed = 'PHPのsafe_modeがOnの場合、FTP情報を登録することで、XEのインストール及び利用が可能になります。'; + $lang->msg_ftp_not_connected = 'localhostへのFTP接続エラーが発生しました。FTPポート(port)番号をはじめ、FTPサービスが可能であるかをご確認下さい。'; + $lang->msg_ftp_invalid_auth_info = 'ログインが失敗しました。 FTPアクセス情報を再度ご確認下さい。'; + $lang->msg_ftp_mkdir_fail = 'FTPを用いたディレクトリ生成に失敗しました。FTPサーバーの設定を再度ご確認下さい。'; + $lang->msg_ftp_chmod_fail = 'FTPを用いたディレクトリパーミッション(permission)変更に失敗しました。FTPサーバーの設定を再度ご確認下さい。'; + $lang->msg_ftp_connect_success = 'FTP接続に成功しました。'; + + $lang->ftp_path_title = 'FTP 경로 정보 입력'; + $lang->msg_ftp_installed_realpath = '설치된 XE의 절대경로'; + $lang->msg_ftp_installed_ftp_realpath = '설치된 XE의 FTP 절대경로 설정'; + + + // xml filterで用いられているjavascript用のアラートメッセージ + $lang->filter->isnull = '%sを入力して下さい。'; + $lang->filter->outofrange = '%sの文字の長さを合わせて下さい。'; + $lang->filter->equalto = '%sが正しくありません。'; + $lang->filter->invalid_email = '%sのパターンが正しくありません。 (例: zbxe@xepressengine.com)'; + $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%sの形式が正しくありません。\\n半角の英数と記号「_」を組み合わせて入力して下さい。頭字は半角英文字でなければなりません。"; + $lang->filter->invalid_homepage = '%sの形式が正しくありません。 (例: http://www.xepressengine.com)'; + $lang->filter->invalid_korean = '%sの形式が正しくありません。ハングルのみ入力して下さい。'; + $lang->filter->invalid_korean_number = '%sの形式が正しくありません。ハングルと半角数字で入力して下さい。'; + $lang->filter->invalid_alpha = '%sの形式が正しくありません。半角英文字のみ入力して下さい。'; + $lang->filter->invalid_alpha_number = '%sの形式が正しくありません。半角英数で入力して下さい。'; + $lang->filter->invalid_number = '%sの形式が正しくありません。半角数字で入力して下さい。'; + + $lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.
To view them, please use another non-administrator ID."; +?> diff --git a/common/lang/ko.lang.php b/common/lang/ko.lang.php index 55823ec65..f792baf90 100644 --- a/common/lang/ko.lang.php +++ b/common/lang/ko.lang.php @@ -1,7 +1,7 @@ cmd_write = 'Бичих'; - $lang->cmd_reply = 'Хариу'; - $lang->cmd_delete = 'Устгах'; - $lang->cmd_modify = 'Засах'; - $lang->cmd_edit = 'Өөрчлөх'; - $lang->cmd_view = 'Харах'; - $lang->cmd_view_all = 'Бүгдийг харах'; - $lang->cmd_list = 'Жагсаалт'; - $lang->cmd_prev = 'Өмнөх'; - $lang->cmd_next = 'Дараах'; - $lang->cmd_send_trackback = 'Холбоотой бичлэг илгээх'; - $lang->cmd_registration = $lang->cmd_submit = 'Оруулах'; - $lang->cmd_comment_registration = 'Коммент бичих'; - $lang->cmd_insert = 'Нэмэх'; - $lang->cmd_save = 'Хадгалах'; - $lang->cmd_load = 'Дуудах'; - $lang->cmd_input = 'Оруулах'; - $lang->cmd_search = 'Хайх'; - $lang->cmd_find = 'Хайх'; - $lang->cmd_replace = 'Солих'; - $lang->cmd_confirm = 'ОК'; - $lang->cmd_cancel = 'Устгах'; - $lang->cmd_back = 'Буцах'; - $lang->cmd_vote = 'Санал болгох'; - $lang->cmd_vote_down = 'Санал болгохгүй'; - $lang->cmd_declare = 'Мэдээлэх'; - $lang->cmd_cancel_declare = 'Мэдэгдлийг устгах'; - $lang->cmd_declared_list = 'Мэдээлсэн жагсаалт'; - $lang->cmd_copy = 'Хуулах'; - $lang->cmd_move = 'Шилжих'; - $lang->cmd_move_up = 'Дээш'; - $lang->cmd_move_down = 'Доош'; - $lang->cmd_add_indent = 'Нэмж оруулах'; - $lang->cmd_remove_indent = 'Хасах'; - $lang->cmd_management = 'Удирдах'; - $lang->cmd_make = 'Харуулах'; - $lang->cmd_select = 'Сонгох'; - $lang->cmd_select_all = 'Бүгдийг сонгох'; - $lang->cmd_unselect_all = 'Сонголтыг болих'; - $lang->cmd_reverse_all = "Дахин сонгох"; - $lang->cmd_close_all = 'Бүгдийг хаах'; - $lang->cmd_open_all = 'Бүгдийг нээх'; - $lang->cmd_reload = 'Дахин унших'; - $lang->cmd_close = 'Хаах'; - $lang->cmd_open = 'Нээх'; - $lang->cmd_setup = 'Тохируулга'; - $lang->cmd_addition_setup = 'Нэмэлт тохируулга'; - $lang->cmd_option = 'Опшион'; - $lang->cmd_apply = 'Хэрэгжүүлэх'; - $lang->cmd_open_calendar = 'Календар сонгох'; - $lang->cmd_send = 'Илгээх'; - $lang->cmd_print = 'Хэвлэх'; - $lang->cmd_scrap = 'Скрап'; - $lang->cmd_preview = 'Урьдчилан харах'; - $lang->cmd_reset = 'Дахин тохируулах'; - $lang->cmd_remake_cache = "cache файл дахин хийх"; - $lang->cmd_publish = "Олгох"; - $lang->cmd_layout_setup = 'Лэйаут тохируулах'; - $lang->cmd_layout_edit = 'Лэйаут өөрчлөх'; - $lang->cmd_search_by_ipaddress = 'IP хаягаар хайх'; - $lang->cmd_add_ip_to_spamfilter = 'Спэм филтерт IPнэмэх'; - - $lang->enable = 'Боломжтой'; - $lang->disable = 'Боломжгүй'; - - // 기본 단어 - $lang->menu = 'Menu'; - $lang->no = 'Дугаар'; - $lang->notice = 'Зарлал'; - $lang->secret = 'Нууц'; - $lang->category = $lang->category_srl = 'Категори'; - $lang->none_category = 'Категори байхгүй'; - $lang->none_image = 'No image'; - $lang->document_srl = 'Баримтын дугаар'; - $lang->user_id = 'ID'; - $lang->author = 'Бичсэн'; - $lang->password = 'Нууц дугаар'; - $lang->password1 = 'Нууц дугаар'; - $lang->password2 = 'Нууц дугаар шалгах'; - $lang->admin_id = 'Хариуцагч ID'; - // $lang->writer = 'Бичлэг оруулагч'; - $lang->writer = 'Нэр'; - $lang->user_name = 'Нэр'; - $lang->nick_name = 'Ник'; - $lang->email_address = 'Мэйл хаяг'; - $lang->homepage = 'Вебхуудас'; - $lang->blog = 'Блог'; - $lang->birthday = 'Төрсөн өдөр'; - $lang->browser_title = 'Browser гарчиг'; - $lang->title = 'Гарчиг'; - $lang->title_content = 'Гарчиг+ Агуулга'; - $lang->topic = 'Сэдэв'; - $lang->replies = 'Хариулах'; - $lang->content = 'Агуулга'; - $lang->document = 'Бичлэг'; - $lang->comment = 'Коммент'; - $lang->description = 'Тайлбар'; - $lang->trackback = 'Холбоотой бичлэг'; - $lang->tag = 'tag'; - $lang->allow_comment = 'Коммент зөвшөөрнө'; - $lang->lock_comment = 'Коммент түгжих'; - $lang->allow_trackback = 'Холбоотой бичлэг зөвшөөрнө'; - $lang->uploaded_file = 'Файл оруулах'; - $lang->grant = 'Эрх'; - $lang->target = 'Зорилго'; - $lang->total = 'Нийт'; - $lang->total_count = 'Нийт тоо'; - $lang->ipaddress = 'IP хаяг'; - $lang->path = 'Байрлал'; - $lang->cart = 'Сонгосон төрөл'; - $lang->friend = 'Найз'; - $lang->notify = 'Мэдээлэх'; - $lang->order_target = 'Цэгцлэх зорилго'; - $lang->order_type = 'Цэгцлэх арга'; - $lang->order_asc = 'Багаас ихрүү'; - $lang->order_desc = 'Ихээс бага руу'; - $lang->file = 'file'; - - - $lang->mid = 'Модиул нэр'; - $lang->sid = 'Тvр сайтын нэр'; - $lang->layout = 'Лэйаут'; - $lang->mobile_layout = 'Mobile Layout'; - $lang->widget = 'Вижет '; - $lang->module = 'Модиул'; - $lang->skin = 'Скин'; - $lang->mobile_skin = 'Mobile Theme'; - $lang->colorset = 'Өнгө тохируулах'; - $lang->extra_vars = 'Өргөжүүлэх тоо'; - $lang->domain = 'Domain'; - $lang->url = 'URL'; - $lang->document_url = 'Бичлэгийн хаяг'; - $lang->trackback_url = 'Холбоотой бичлэгний хаяг'; - $lang->blog_name = 'Блог нэр'; - $lang->excerpt = 'excerpt'; - - $lang->document_count = 'Бичлэгийн тоо'; - $lang->page_count = 'Хуудасны тоо'; - $lang->list_count = 'Жагсаалтын тоо'; - $lang->search_list_count = 'Хайлтын жагсаалт'; - $lang->readed_count = 'Уншсан'; - $lang->voted_count = 'vote'; - $lang->comment_count = 'Комментын тоо'; - $lang->member_count = 'Гишүүдийн тоо'; - $lang->date = 'Date'; - $lang->regdate = 'Оруулсан өдөр'; - $lang->last_update = 'Сүүлд засварласан өдөр'; - $lang->last_post = 'Хамгийн сүүлд оруулсан'; - $lang->signup_date = 'Бүртгүүлсэн өдөр'; - $lang->last_login = 'Хамгийн сүүлд нэвтэрсэн'; - $lang->first_page = 'Эхний хуудас'; - $lang->last_page = 'Сүүлчийн хуудас'; - $lang->search_target = 'Хайх зорилго'; - $lang->search_keyword = 'Хайх үг'; - $lang->is_default = 'Үндсэн'; - - $lang->no_documents = 'Оруулсан бичлэг байхгүй'; - - $lang->board_manager = 'Board удирдах'; - $lang->member_manager = 'Гишүүн удирдах'; - $lang->layout_manager = 'Лэйаут удирдах'; - - $lang->use = 'Хэрэглэх'; - $lang->notuse = 'Хэрэглэхгүй'; - $lang->not_exists = 'Байхгүй'; - - $lang->public = 'Нийтийн'; - $lang->private = 'Нууцлах'; - - $lang->unit_sec = 'Секунд'; - $lang->unit_min = 'Минут'; - $lang->unit_hour = 'Цаг'; - $lang->unit_day = 'Өдөр'; - $lang->unit_month = 'Сар'; - $lang->unit_year = 'Жил'; - - $lang->unit_week = array( - 'Monday' => 'Да', - 'Tuesday' => 'Мя', - 'Wednesday' => 'Лха', - 'Thursday' => 'Пv', - 'Friday' => 'Ба', - 'Saturday' => 'Бя', - 'Sunday' => 'Ня', - - ); - - $lang->unit_meridiem = array( - 'am' => 'eглee', - 'pm' => 'орой', - 'AM' => 'eглee', - 'PM' => 'орой', - ); - - - $lang->time_gap = array( - 'min' => '%d минутын eмнe', - 'mins' => '%d минутын eмнe', - 'hour' => '%d цагийн eмнe', - 'hours' => '%d цагийн eмнe', - ); - - // 설명 관련 - $lang->about_tag = 'tag оруулахдаа таслал ашиглавал давтан оруулж болно'; - $lang->about_layout = 'Лэйаут нь модиулын гадаад байдлыг чимж өгнө. Дээрх лэйаут менюнээс удирдаж болно'; - - // 메세지 관련 - $lang->msg_call_server = 'Сервер ачаалж байна. Түр хүлээнэ үү.'; - $lang->msg_db_not_setted = 'DB тохируулга хийгдээгүй байна.'; - $lang->msg_invalid_queryid = 'Query ID буруу бичигдсэн байна.'; - $lang->msg_not_permitted = 'Эрх байхгүй байна'; - $lang->msg_input_password = 'Нууц дугаараа оруулна уу'; - $lang->msg_invalid_document = 'Бичлэгийн дугаар буруу байна'; - $lang->msg_invalid_request = 'Буруу шаардлага байна'; - $lang->msg_invalid_password = 'Нууц дугаар буруу байна'; - $lang->msg_error_occured = 'Алдаа гарлаа'; - $lang->msg_not_founded = 'Зорилгыг олж чадсангүйү'; - $lang->msg_no_result = 'Хайлтын үр дүн байхгүй байна'; - $lang->msg_fail_to_request_open = 'Холболт амжилтгvй боллоо.'; - $lang->msg_invalid_format = 'Буруу хэлбэр байна.'; - - $lang->msg_not_permitted_act = 'Хүсэлт гаргасан үйлдлийг хэрэгжүүлэх эрх байхгүй.'; - $lang->msg_module_is_not_exists = 'Хүссэн модиулыг олж чадсангүй'; - $lang->msg_module_is_not_standalone = 'Хүсэлт гаргасан модиул нь бие даан хэрэгжих боломжгүй'; - - $lang->success_registed = 'Бүртгэгдсэн'; - $lang->success_declared = 'Мэдээлэгдсэн'; - $lang->success_updated = 'Засварлагдсан'; - $lang->success_deleted = 'Устгагдсан'; - $lang->success_voted = 'Санал болгогдсон'; - $lang->success_blamed = 'Санал болгогдоогүй'; - $lang->success_moved = 'Шилжсэн'; - $lang->success_sended = 'Илгээгдсэн'; - $lang->success_reset = 'Reset'; - $lang->success_leaved = 'Гишүүнээс гарсан'; - $lang->success_saved = 'Хадгалагдсан'; - - $lang->fail_to_delete = 'Устгалт амжилтгүй боллоо'; - $lang->fail_to_move = 'Шилжилт амжилтгүй боллоо'; - - $lang->failed_voted = 'Санал болгох боломжгүй'; - $lang->failed_blamed = 'Санал болгохгүй байх боломжгүй'; - $lang->failed_declared = 'Мэдээлэх боломжгүй'; - $lang->fail_to_delete_have_children = 'Хариулт бичлэг байгаа тул устгах боломжгүй'; - - $lang->confirm_submit = 'Оруулах уу?'; - $lang->confirm_logout = 'Гарах уу?'; - $lang->confirm_vote = 'Санал болгох уу?'; - $lang->confirm_delete = 'Устгах уу?'; - $lang->confirm_move = 'Шилжих үү?'; - $lang->confirm_reset = 'Reset хийх үү?'; - $lang->confirm_leave = 'Гишүүнээс гарах уу?'; - $lang->confirm_update = 'Are you sure to update?'; - - $lang->column_type = 'Хэлбэр'; - $lang->column_type_list['text'] = 'Нэг мөрөөр оруулах (text)'; - $lang->column_type_list['homepage'] = 'Веб хуудас хэлбэр (url)'; - $lang->column_type_list['email_address'] = 'Мэйл хэлбэр (email)'; - $lang->column_type_list['tel'] = 'Утасны дугаар хэлбэр (phone)'; - $lang->column_type_list['textarea'] = 'Олон мөрөөр оруулах (textarea)'; - $lang->column_type_list['checkbox'] = 'Олон сонголт хийх (checkbox)'; - $lang->column_type_list['select'] = 'Ганц сонголт хийх (select)'; - $lang->column_type_list['radio'] = 'Нэг eдeр сонгох(radio)'; - $lang->column_type_list['kr_zip'] = 'Солонгос хаяг (zip)'; - $lang->column_type_list['date'] = 'Онсар (Жил сар өдөр)'; - //$lang->column_type_list['jp_zip'] = '일본주소 (zip)'; - - $lang->column_name = 'Баганын нэр'; - $lang->column_title = 'Баганын гарчиг'; - $lang->default_value = 'Үндсэн байдал'; - $lang->is_active = 'Идэвхжүүлэх'; - $lang->is_required = 'Заавал бөглөх'; - $lang->eid = 'eгeдлийн нэр'; - - // ftp 관련 - $lang->ftp_form_title = 'FTP мэдээлэл оруулах'; - $lang->ftp = 'FTP'; - $lang->ftp_host = 'FTP hostname'; - $lang->ftp_port = 'FTP port'; - $lang->about_ftp_password = 'FTP password will not be stored'; - $lang->cmd_check_ftp_connect = 'FTP холболт шалгах'; - $lang->about_ftp_info = " - FTP мэдээлэл нь дараах тохиолдолд хэрэглэгдэх боломжтой.
- 1. PHP의 safe_mode=Onбайх тохиолдолд , FTP мэдээллийг ашиглан XE-г бvрэн ажиллуулахаар болгож болно.
- 2. Автомат опдэйт хийх зэрэгт FTP мэдээллийг ашиглаж болно.
- Тус FTP мэпээлэл нь files/config/ftp.config.php файл дотор хадгалагдна.
- Идэвхжvvлсэний дараа хариуцагчийн хуудаснаас FTP мэдээллийг eeрчлeх болон устгаж болно.
- "; - $lang->msg_safe_mode_ftp_needed = 'PHP의 safe_mode가 Onбайх тохиолдолд , FTP мэдээллийг заавал оруулснаар XE идэвжvvлэх болон хэрэглэх боломжтой болно.'; - $lang->msg_ftp_not_connected = 'localhost-ын FTP холболт амжилтгvй боллоо. FTP дугаараа шалгах буюу эсвэл FTP vйлчилгээг ашиглах боломжтой эсэхээ шалгана уу.'; - $lang->msg_ftp_invalid_auth_info = 'Таны оруулсан FTP мэдээллээр нэвтэрч чадсангvй. FTPмэдээллээ шалгана уу.'; - $lang->msg_ftp_mkdir_fail = 'FTP-г ашиглан eгсeн eгeгдлийг биелvvлж чадсангvй. FTP серверийн идэвхжvvлэлтээ шалгана уу.'; - $lang->msg_ftp_chmod_fail = 'FTP-г ашиглан eeрчлeлтийг хийж чадсангvй. FTP серверийн идэвхжvvлэлтээ шалгана уу.'; - $lang->msg_ftp_connect_success = 'FTP холболт болон баталгаажуулалт хийгдлээ.'; - - - // xml filter에서 사용되는 javascript용 alert msg - $lang->filter->isnull = '%s-ийг оруулна уу'; - $lang->filter->outofrange = '%s-ийн үсгийн тоог тааруулна уу.'; - $lang->filter->equalto = '%s-ыг буруу оруулсан байна.'; - $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_homepage = '%s-ын хэлбэр буруу байна.. (Жнь: http://www.zeroboard.com)'; - $lang->filter->invalid_korean = '%s-ын хэлбэр буруу байна. Солонгосоор оруулах ёстой'; - $lang->filter->invalid_korean_number = '%s-ын хэлбэр буруу байна. Солонгос үсэг болон тоогоор оруулах хэрэгтэй.'; - $lang->filter->invalid_alpha = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсгээр оруулах ёстой'; - $lang->filter->invalid_alpha_number = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсэг болон тоогоор л оруулах ёстой.'; - $lang->filter->invalid_number = '%s-ын хэлбэр буруу байна. Зөвхөн тоогоор оруулах ёстой.'; - - $lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.
To view them, please use another non-administrator ID."; -?> +cmd_write = 'Бичих'; + $lang->cmd_reply = 'Хариу'; + $lang->cmd_delete = 'Устгах'; + $lang->cmd_modify = 'Засах'; + $lang->cmd_edit = 'Өөрчлөх'; + $lang->cmd_view = 'Харах'; + $lang->cmd_view_all = 'Бүгдийг харах'; + $lang->cmd_list = 'Жагсаалт'; + $lang->cmd_prev = 'Өмнөх'; + $lang->cmd_next = 'Дараах'; + $lang->cmd_send_trackback = 'Холбоотой бичлэг илгээх'; + $lang->cmd_registration = $lang->cmd_submit = 'Оруулах'; + $lang->cmd_comment_registration = 'Коммент бичих'; + $lang->cmd_insert = 'Нэмэх'; + $lang->cmd_save = 'Хадгалах'; + $lang->cmd_load = 'Дуудах'; + $lang->cmd_input = 'Оруулах'; + $lang->cmd_search = 'Хайх'; + $lang->cmd_find = 'Хайх'; + $lang->cmd_replace = 'Солих'; + $lang->cmd_confirm = 'ОК'; + $lang->cmd_cancel = 'Устгах'; + $lang->cmd_back = 'Буцах'; + $lang->cmd_vote = 'Санал болгох'; + $lang->cmd_vote_down = 'Санал болгохгүй'; + $lang->cmd_declare = 'Мэдээлэх'; + $lang->cmd_cancel_declare = 'Мэдэгдлийг устгах'; + $lang->cmd_declared_list = 'Мэдээлсэн жагсаалт'; + $lang->cmd_copy = 'Хуулах'; + $lang->cmd_move = 'Шилжих'; + $lang->cmd_move_up = 'Дээш'; + $lang->cmd_move_down = 'Доош'; + $lang->cmd_add_indent = 'Нэмж оруулах'; + $lang->cmd_remove_indent = 'Хасах'; + $lang->cmd_management = 'Удирдах'; + $lang->cmd_make = 'Харуулах'; + $lang->cmd_select = 'Сонгох'; + $lang->cmd_select_all = 'Бүгдийг сонгох'; + $lang->cmd_unselect_all = 'Сонголтыг болих'; + $lang->cmd_reverse_all = "Дахин сонгох"; + $lang->cmd_close_all = 'Бүгдийг хаах'; + $lang->cmd_open_all = 'Бүгдийг нээх'; + $lang->cmd_reload = 'Дахин унших'; + $lang->cmd_close = 'Хаах'; + $lang->cmd_open = 'Нээх'; + $lang->cmd_setup = 'Тохируулга'; + $lang->cmd_addition_setup = 'Нэмэлт тохируулга'; + $lang->cmd_option = 'Опшион'; + $lang->cmd_apply = 'Хэрэгжүүлэх'; + $lang->cmd_open_calendar = 'Календар сонгох'; + $lang->cmd_send = 'Илгээх'; + $lang->cmd_print = 'Хэвлэх'; + $lang->cmd_scrap = 'Скрап'; + $lang->cmd_preview = 'Урьдчилан харах'; + $lang->cmd_reset = 'Дахин тохируулах'; + $lang->cmd_remake_cache = "cache файл дахин хийх"; + $lang->cmd_publish = "Олгох"; + $lang->cmd_layout_setup = 'Лэйаут тохируулах'; + $lang->cmd_layout_edit = 'Лэйаут өөрчлөх'; + $lang->cmd_search_by_ipaddress = 'IP хаягаар хайх'; + $lang->cmd_add_ip_to_spamfilter = 'Спэм филтерт IPнэмэх'; + + $lang->enable = 'Боломжтой'; + $lang->disable = 'Боломжгүй'; + + // 기본 단어 + $lang->menu = 'Menu'; + $lang->no = 'Дугаар'; + $lang->notice = 'Зарлал'; + $lang->secret = 'Нууц'; + $lang->category = $lang->category_srl = 'Категори'; + $lang->none_category = 'Категори байхгүй'; + $lang->none_image = 'No image'; + $lang->document_srl = 'Баримтын дугаар'; + $lang->user_id = 'ID'; + $lang->author = 'Бичсэн'; + $lang->password = 'Нууц дугаар'; + $lang->password1 = 'Нууц дугаар'; + $lang->password2 = 'Нууц дугаар шалгах'; + $lang->admin_id = 'Хариуцагч ID'; + // $lang->writer = 'Бичлэг оруулагч'; + $lang->writer = 'Нэр'; + $lang->user_name = 'Нэр'; + $lang->nick_name = 'Ник'; + $lang->email_address = 'Мэйл хаяг'; + $lang->homepage = 'Вебхуудас'; + $lang->blog = 'Блог'; + $lang->birthday = 'Төрсөн өдөр'; + $lang->browser_title = 'Browser гарчиг'; + $lang->title = 'Гарчиг'; + $lang->title_content = 'Гарчиг+ Агуулга'; + $lang->topic = 'Сэдэв'; + $lang->replies = 'Хариулах'; + $lang->content = 'Агуулга'; + $lang->document = 'Бичлэг'; + $lang->comment = 'Коммент'; + $lang->description = 'Тайлбар'; + $lang->trackback = 'Холбоотой бичлэг'; + $lang->tag = 'tag'; + $lang->allow_comment = 'Коммент зөвшөөрнө'; + $lang->lock_comment = 'Коммент түгжих'; + $lang->allow_trackback = 'Холбоотой бичлэг зөвшөөрнө'; + $lang->uploaded_file = 'Файл оруулах'; + $lang->grant = 'Эрх'; + $lang->target = 'Зорилго'; + $lang->total = 'Нийт'; + $lang->total_count = 'Нийт тоо'; + $lang->ipaddress = 'IP хаяг'; + $lang->path = 'Байрлал'; + $lang->cart = 'Сонгосон төрөл'; + $lang->friend = 'Найз'; + $lang->notify = 'Мэдээлэх'; + $lang->order_target = 'Цэгцлэх зорилго'; + $lang->order_type = 'Цэгцлэх арга'; + $lang->order_asc = 'Багаас ихрүү'; + $lang->order_desc = 'Ихээс бага руу'; + $lang->file = 'file'; + + + $lang->mid = 'Модиул нэр'; + $lang->sid = 'Тvр сайтын нэр'; + $lang->layout = 'Лэйаут'; + $lang->mobile_layout = 'Mobile Layout'; + $lang->widget = 'Вижет '; + $lang->module = 'Модиул'; + $lang->skin = 'Скин'; + $lang->mobile_skin = 'Mobile Theme'; + $lang->colorset = 'Өнгө тохируулах'; + $lang->extra_vars = 'Өргөжүүлэх тоо'; + $lang->domain = 'Domain'; + $lang->url = 'URL'; + $lang->document_url = 'Бичлэгийн хаяг'; + $lang->trackback_url = 'Холбоотой бичлэгний хаяг'; + $lang->blog_name = 'Блог нэр'; + $lang->excerpt = 'excerpt'; + + $lang->document_count = 'Бичлэгийн тоо'; + $lang->page_count = 'Хуудасны тоо'; + $lang->list_count = 'Жагсаалтын тоо'; + $lang->search_list_count = 'Хайлтын жагсаалт'; + $lang->readed_count = 'Уншсан'; + $lang->voted_count = 'vote'; + $lang->comment_count = 'Комментын тоо'; + $lang->member_count = 'Гишүүдийн тоо'; + $lang->date = 'Date'; + $lang->regdate = 'Оруулсан өдөр'; + $lang->last_update = 'Сүүлд засварласан өдөр'; + $lang->last_post = 'Хамгийн сүүлд оруулсан'; + $lang->signup_date = 'Бүртгүүлсэн өдөр'; + $lang->last_login = 'Хамгийн сүүлд нэвтэрсэн'; + $lang->first_page = 'Эхний хуудас'; + $lang->last_page = 'Сүүлчийн хуудас'; + $lang->search_target = 'Хайх зорилго'; + $lang->search_keyword = 'Хайх үг'; + $lang->is_default = 'Үндсэн'; + + $lang->no_documents = 'Оруулсан бичлэг байхгүй'; + + $lang->board_manager = 'Board удирдах'; + $lang->member_manager = 'Гишүүн удирдах'; + $lang->layout_manager = 'Лэйаут удирдах'; + + $lang->use = 'Хэрэглэх'; + $lang->notuse = 'Хэрэглэхгүй'; + $lang->not_exists = 'Байхгүй'; + + $lang->public = 'Нийтийн'; + $lang->private = 'Нууцлах'; + + $lang->unit_sec = 'Секунд'; + $lang->unit_min = 'Минут'; + $lang->unit_hour = 'Цаг'; + $lang->unit_day = 'Өдөр'; + $lang->unit_month = 'Сар'; + $lang->unit_year = 'Жил'; + + $lang->unit_week = array( + 'Monday' => 'Да', + 'Tuesday' => 'Мя', + 'Wednesday' => 'Лха', + 'Thursday' => 'Пv', + 'Friday' => 'Ба', + 'Saturday' => 'Бя', + 'Sunday' => 'Ня', + + ); + + $lang->unit_meridiem = array( + 'am' => 'eглee', + 'pm' => 'орой', + 'AM' => 'eглee', + 'PM' => 'орой', + ); + + + $lang->time_gap = array( + 'min' => '%d минутын eмнe', + 'mins' => '%d минутын eмнe', + 'hour' => '%d цагийн eмнe', + 'hours' => '%d цагийн eмнe', + ); + + // 설명 관련 + $lang->about_tag = 'tag оруулахдаа таслал ашиглавал давтан оруулж болно'; + $lang->about_layout = 'Лэйаут нь модиулын гадаад байдлыг чимж өгнө. Дээрх лэйаут менюнээс удирдаж болно'; + + // 메세지 관련 + $lang->msg_call_server = 'Сервер ачаалж байна. Түр хүлээнэ үү.'; + $lang->msg_db_not_setted = 'DB тохируулга хийгдээгүй байна.'; + $lang->msg_invalid_queryid = 'Query ID буруу бичигдсэн байна.'; + $lang->msg_not_permitted = 'Эрх байхгүй байна'; + $lang->msg_input_password = 'Нууц дугаараа оруулна уу'; + $lang->msg_invalid_document = 'Бичлэгийн дугаар буруу байна'; + $lang->msg_invalid_request = 'Буруу шаардлага байна'; + $lang->msg_invalid_password = 'Нууц дугаар буруу байна'; + $lang->msg_error_occured = 'Алдаа гарлаа'; + $lang->msg_not_founded = 'Зорилгыг олж чадсангүйү'; + $lang->msg_no_result = 'Хайлтын үр дүн байхгүй байна'; + $lang->msg_fail_to_request_open = 'Холболт амжилтгvй боллоо.'; + $lang->msg_invalid_format = 'Буруу хэлбэр байна.'; + + $lang->msg_not_permitted_act = 'Хүсэлт гаргасан үйлдлийг хэрэгжүүлэх эрх байхгүй.'; + $lang->msg_module_is_not_exists = 'Хүссэн модиулыг олж чадсангүй'; + $lang->msg_module_is_not_standalone = 'Хүсэлт гаргасан модиул нь бие даан хэрэгжих боломжгүй'; + + $lang->success_registed = 'Бүртгэгдсэн'; + $lang->success_declared = 'Мэдээлэгдсэн'; + $lang->success_updated = 'Засварлагдсан'; + $lang->success_deleted = 'Устгагдсан'; + $lang->success_voted = 'Санал болгогдсон'; + $lang->success_blamed = 'Санал болгогдоогүй'; + $lang->success_moved = 'Шилжсэн'; + $lang->success_sended = 'Илгээгдсэн'; + $lang->success_reset = 'Reset'; + $lang->success_leaved = 'Гишүүнээс гарсан'; + $lang->success_saved = 'Хадгалагдсан'; + + $lang->fail_to_delete = 'Устгалт амжилтгүй боллоо'; + $lang->fail_to_move = 'Шилжилт амжилтгүй боллоо'; + + $lang->failed_voted = 'Санал болгох боломжгүй'; + $lang->failed_blamed = 'Санал болгохгүй байх боломжгүй'; + $lang->failed_declared = 'Мэдээлэх боломжгүй'; + $lang->fail_to_delete_have_children = 'Хариулт бичлэг байгаа тул устгах боломжгүй'; + + $lang->confirm_submit = 'Оруулах уу?'; + $lang->confirm_logout = 'Гарах уу?'; + $lang->confirm_vote = 'Санал болгох уу?'; + $lang->confirm_delete = 'Устгах уу?'; + $lang->confirm_move = 'Шилжих үү?'; + $lang->confirm_reset = 'Reset хийх үү?'; + $lang->confirm_leave = 'Гишүүнээс гарах уу?'; + $lang->confirm_update = 'Are you sure to update?'; + + $lang->column_type = 'Хэлбэр'; + $lang->column_type_list['text'] = 'Нэг мөрөөр оруулах (text)'; + $lang->column_type_list['homepage'] = 'Веб хуудас хэлбэр (url)'; + $lang->column_type_list['email_address'] = 'Мэйл хэлбэр (email)'; + $lang->column_type_list['tel'] = 'Утасны дугаар хэлбэр (phone)'; + $lang->column_type_list['textarea'] = 'Олон мөрөөр оруулах (textarea)'; + $lang->column_type_list['checkbox'] = 'Олон сонголт хийх (checkbox)'; + $lang->column_type_list['select'] = 'Ганц сонголт хийх (select)'; + $lang->column_type_list['radio'] = 'Нэг eдeр сонгох(radio)'; + $lang->column_type_list['kr_zip'] = 'Солонгос хаяг (zip)'; + $lang->column_type_list['date'] = 'Онсар (Жил сар өдөр)'; + //$lang->column_type_list['jp_zip'] = '일본주소 (zip)'; + + $lang->column_name = 'Баганын нэр'; + $lang->column_title = 'Баганын гарчиг'; + $lang->default_value = 'Үндсэн байдал'; + $lang->is_active = 'Идэвхжүүлэх'; + $lang->is_required = 'Заавал бөглөх'; + $lang->eid = 'eгeдлийн нэр'; + + // ftp 관련 + $lang->ftp_form_title = 'FTP мэдээлэл оруулах'; + $lang->ftp = 'FTP'; + $lang->ftp_host = 'FTP hostname'; + $lang->ftp_port = 'FTP port'; + $lang->about_ftp_password = 'FTP password will not be stored'; + $lang->cmd_check_ftp_connect = 'FTP холболт шалгах'; + $lang->about_ftp_info = " + FTP мэдээлэл нь дараах тохиолдолд хэрэглэгдэх боломжтой.
+ 1. PHP의 safe_mode=Onбайх тохиолдолд , FTP мэдээллийг ашиглан XE-г бvрэн ажиллуулахаар болгож болно.
+ 2. Автомат опдэйт хийх зэрэгт FTP мэдээллийг ашиглаж болно.
+ Тус FTP мэпээлэл нь files/config/ftp.config.php файл дотор хадгалагдна.
+ Идэвхжvvлсэний дараа хариуцагчийн хуудаснаас FTP мэдээллийг eeрчлeх болон устгаж болно.
+ "; + $lang->msg_safe_mode_ftp_needed = 'PHP의 safe_mode가 Onбайх тохиолдолд , FTP мэдээллийг заавал оруулснаар XE идэвжvvлэх болон хэрэглэх боломжтой болно.'; + $lang->msg_ftp_not_connected = 'localhost-ын FTP холболт амжилтгvй боллоо. FTP дугаараа шалгах буюу эсвэл FTP vйлчилгээг ашиглах боломжтой эсэхээ шалгана уу.'; + $lang->msg_ftp_invalid_auth_info = 'Таны оруулсан FTP мэдээллээр нэвтэрч чадсангvй. FTPмэдээллээ шалгана уу.'; + $lang->msg_ftp_mkdir_fail = 'FTP-г ашиглан eгсeн eгeгдлийг биелvvлж чадсангvй. FTP серверийн идэвхжvvлэлтээ шалгана уу.'; + $lang->msg_ftp_chmod_fail = 'FTP-г ашиглан eeрчлeлтийг хийж чадсангvй. FTP серверийн идэвхжvvлэлтээ шалгана уу.'; + $lang->msg_ftp_connect_success = 'FTP холболт болон баталгаажуулалт хийгдлээ.'; + + + // xml filter에서 사용되는 javascript용 alert msg + $lang->filter->isnull = '%s-ийг оруулна уу'; + $lang->filter->outofrange = '%s-ийн үсгийн тоог тааруулна уу.'; + $lang->filter->equalto = '%s-ыг буруу оруулсан байна.'; + $lang->filter->invalid_email = '%s-ын хэлбэрийг буруу оруулсан байна. (Жнь: developers@xpressengine.com)'; + $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%s-ын хэлбэр буруу байна. .\\n Латин vсэг, тоо болон \'_\'-р оруулж болох бeгeeд эхлэл нь vсэг байх шаардлагатай. "; + $lang->filter->invalid_homepage = '%s-ын хэлбэр буруу байна.. (Жнь: http://xpressengine.com/)'; + $lang->filter->invalid_korean = '%s-ын хэлбэр буруу байна. Солонгосоор оруулах ёстой'; + $lang->filter->invalid_korean_number = '%s-ын хэлбэр буруу байна. Солонгос үсэг болон тоогоор оруулах хэрэгтэй.'; + $lang->filter->invalid_alpha = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсгээр оруулах ёстой'; + $lang->filter->invalid_alpha_number = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсэг болон тоогоор л оруулах ёстой.'; + $lang->filter->invalid_number = '%s-ын хэлбэр буруу байна. Зөвхөн тоогоор оруулах ёстой.'; + + $lang->security_warning_embed = "Due to security concern, administrators are not allowed to view embedded items.
To view them, please use another non-administrator ID."; +?> diff --git a/common/lang/ru.lang.php b/common/lang/ru.lang.php index cbde44274..ebef70826 100644 --- a/common/lang/ru.lang.php +++ b/common/lang/ru.lang.php @@ -1,323 +1,323 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - // Основные слова для действий - $lang->cmd_write = 'Написать'; - $lang->cmd_reply = 'Ответить'; - $lang->cmd_delete = 'Удалить'; - $lang->cmd_modify = 'Изменить'; - $lang->cmd_edit = 'Редактировать'; - $lang->cmd_view = 'Просмотреть'; - $lang->cmd_view_all = 'Просмотреть все'; - $lang->cmd_list = 'Список'; - $lang->cmd_prev = 'Предыдущее'; - $lang->cmd_next = 'Следующее'; - $lang->cmd_send_trackback = 'Отправить трекбек'; - $lang->cmd_registration = $lang->cmd_submit = 'Принять'; - $lang->cmd_comment_registration = 'Добавить запись'; - $lang->cmd_insert = 'Вставить'; - $lang->cmd_save = 'Сохранить'; - $lang->cmd_load = 'Загрузить'; - $lang->cmd_input = 'Ввести'; - $lang->cmd_search = 'Искать'; - $lang->cmd_find = 'Поиск'; - $lang->cmd_replace = 'Поменять'; - $lang->cmd_confirm = 'Подтвердить'; - $lang->cmd_cancel = 'Отменить'; - $lang->cmd_back = 'Вернуться'; - $lang->cmd_vote = 'Рекомендовать'; - $lang->cmd_vote_down = 'Критиковать'; - $lang->cmd_declare = 'Пожаловаться'; - $lang->cmd_cancel_declare = 'Отменить жалобу'; - $lang->cmd_declared_list = 'Список жалоб'; - $lang->cmd_copy = 'Копировать'; - $lang->cmd_move = 'Переместить'; - $lang->cmd_move_up = 'Вверх'; - $lang->cmd_move_down = 'Вниз'; - $lang->cmd_add_indent = 'Отступ вправо'; - $lang->cmd_remove_indent = 'Отступ влево'; - $lang->cmd_management = 'Управление'; - $lang->cmd_make = 'Создать'; - $lang->cmd_select = 'Выделить'; - $lang->cmd_select_all = 'Выделить все'; - $lang->cmd_unselect_all = 'Убрать выделение ВСЕХ'; - $lang->cmd_reverse_all = 'Перевернуть'; - $lang->cmd_close_all = 'Закрыть все'; - $lang->cmd_open_all = 'Открыть все'; - $lang->cmd_reload = 'Перегрузить'; - $lang->cmd_close = 'Закрыть'; - $lang->cmd_open = 'Открыть'; - $lang->cmd_setup = 'Конфигурация'; - $lang->cmd_addition_setup = 'Дополнительная настройка'; - $lang->cmd_option = 'Опция'; - $lang->cmd_apply = 'Применить'; - $lang->cmd_open_calendar = 'Выбрать дату'; - $lang->cmd_send = 'Отправить'; - $lang->cmd_print = 'Напечатать'; - $lang->cmd_scrap = 'В черновики'; - $lang->cmd_preview = 'Предпросмотр'; - $lang->cmd_reset = 'Сброс'; - $lang->cmd_remake_cache = "Пересоздать файл кэша"; - $lang->cmd_publish = "Опубликовать"; - $lang->cmd_layout_setup = 'Конфигурировать лейаут'; - $lang->cmd_layout_edit = 'Редактировать лейаут'; - $lang->cmd_search_by_ipaddress = 'Искать по IP адресу'; - $lang->cmd_add_ip_to_spamfilter = 'Добавить IP в спамфильтры'; - - $lang->enable = 'Включено'; - $lang->disable = 'Выключено'; - - // Основные слова - $lang->menu = 'Меню'; - $lang->no = 'No.'; - $lang->notice = 'Уведомление'; - $lang->secret = 'Секрет'; - $lang->category = $lang->category_srl = 'Категория'; - $lang->none_category = 'Без категории'; - $lang->none_image = 'Картинки нет'; - $lang->document_srl = 'No документа'; - $lang->user_id = 'ID пользователя'; - $lang->author = 'Автор'; - $lang->password = 'Пароль'; - $lang->password1 = 'Пароль'; - $lang->password2 = 'Подтверждение пароля'; - $lang->admin_id = 'ID админа'; - $lang->writer = 'Автор записи'; - $lang->user_name = 'Имя пользователя'; - $lang->nick_name = 'Ник'; - $lang->email_address = 'Email'; - $lang->homepage = 'Домашняя страница'; - $lang->blog = 'Блог'; - $lang->birthday = 'Дата рождения'; - $lang->browser_title = 'Заголовок браузера'; - $lang->title = 'Заголовок'; - $lang->title_content = 'Заголовок+Содержание'; - $lang->topic = 'Тема'; - $lang->replies = 'Ответы'; - $lang->content = 'Содержание'; - $lang->document = 'Статьи'; - $lang->comment = 'Комментарии'; - $lang->description = 'Описание'; - $lang->trackback = 'Трекбек'; - $lang->tag = 'Тег'; - $lang->allow_comment = 'Позволить комментарии'; - $lang->lock_comment = 'Заблокировать комментарии'; - $lang->allow_trackback = 'Позволить трекбек'; - $lang->uploaded_file = 'Прикрепить файл'; - $lang->grant = 'Права доступа'; - $lang->target = 'Назначение'; - $lang->total = 'Всего'; - $lang->total_count = 'Общее количество'; - $lang->ipaddress = 'IP адрес'; - $lang->path = 'Путь'; - $lang->cart = 'Выбранный объект'; - $lang->friend = 'Друзья'; - $lang->notify = 'Уведомление'; - $lang->order_target = 'Align Target'; - $lang->order_type = 'Тип сортировки'; - $lang->order_asc = 'снизу вверх'; - $lang->order_desc = 'сверху вниз'; - $lang->file = 'файл'; - - $lang->mid = 'Имя Модуля'; - $lang->sid = 'Site Name'; - $lang->layout = 'Лейаут'; - $lang->mobile_layout = 'Mobile Layout'; - $lang->widget = 'Виджет'; - $lang->module = 'Модуль'; - $lang->skin = 'Тема'; - $lang->mobile_skin = 'Mobile Theme'; - $lang->colorset = 'Цветовой набор'; - $lang->extra_vars = 'Дополнительные переменные.'; - - $lang->domain = "Доменное имя"; - $lang->url = "URL"; - $lang->document_url = 'URL записи'; - $lang->trackback_url = 'URL трекбека'; - $lang->blog_name = 'Название блога'; - $lang->excerpt = 'Цитата'; - - $lang->document_count = 'Всего записей'; - $lang->page_count = 'Количество страниц'; - $lang->list_count = 'Количество списков'; - $lang->search_list_count = 'Поиск Список кол'; - $lang->readed_count = 'Просмотры'; - $lang->voted_count = 'Голоса'; - $lang->comment_count = 'Комментарии'; - $lang->member_count = 'Количество пользователей'; - $lang->date = 'Дата'; - $lang->regdate = 'Дата регистрации'; - $lang->last_update = 'Последнее обновление'; - $lang->last_post = 'Последний комментарий'; - $lang->signup_date = 'Дата регистрации'; - $lang->last_login = 'Последний вход'; - $lang->first_page = 'Первая страница'; - $lang->last_page = 'Последняя страница'; - $lang->search_target = 'Назначение поиска'; - $lang->search_keyword = 'Ключевые слова'; - $lang->is_default = 'По умолчанию'; - - $lang->no_documents = 'Нет записей'; - - $lang->board_manager = 'Настройки форума'; - $lang->member_manager = 'Настройки пользователей'; - $lang->layout_manager = 'Настройки лейаута'; - - $lang->use = 'Использовать'; - $lang->notuse = 'Не использовать'; - $lang->not_exists = "Отсутствует"; - - $lang->public = 'Показать всем'; - $lang->private = 'Не показывать'; - - $lang->unit_sec = 'сек.'; - $lang->unit_min = 'мин.'; - $lang->unit_hour = 'ч.'; - $lang->unit_day = 'д.'; - $lang->unit_week = 'нед.'; - $lang->unit_month = 'мес.'; - $lang->unit_year = 'г.'; - - $lang->unit_week = array( - 'Monday' => 'Понедельник', - 'Tuesday' => 'Вторник', - 'Wednesday' => 'Среда', - 'Thursday' => 'Четверг', - 'Friday' => 'Пятница', - 'Saturday' => 'Суббота', - 'Sunday' => 'Воскресенье', - ); - - $lang->unit_meridiem = array( - 'am' => 'am', - 'pm' => 'pm', - 'AM' => 'AM', - 'PM' => 'PM', - ); - - $lang->time_gap = array( - 'min' => '%d минуту назад', - 'mins' => '%d минут назад', - 'hour' => '%d час назад', - 'hours' => '%d часов назад', - ); - - // Описания - $lang->about_tag = 'Вы можете применить несколько тегов, разделенных запятыми (,)'; - $lang->about_layout = 'Лейауты украшают внешний вид Ваших модулей. Вы можете сконфигурировать их с помощью меню Лейаут сверху'; - - // Сообщение - $lang->msg_call_server = 'Идет обработка. Пожалуйста, подождите...'; - $lang->msg_db_not_setted = 'Даза данных не сконфигурирована'; - $lang->msg_dbconnect_failed = "Произошла ошибка подключения к базе данных.\nПожалуйста, проверьте иформацию базы данных еще раз"; - $lang->msg_invalid_queryid = 'Указанный ID запроса неверен'; - $lang->msg_not_permitted = 'У Вас нет доступа'; - $lang->msg_input_password = 'Пожалуйста, введите пароль'; - $lang->msg_invalid_document = 'Неверный номер статьи'; - $lang->msg_invalid_request = 'Неверный запрос'; - $lang->msg_invalid_password = 'Неверный пароль'; - $lang->msg_error_occured = 'Произошла ошибка'; - $lang->msg_not_founded = 'Сообщение не найдено'; - $lang->msg_no_result = 'Ничего не найдено'; - $lang->msg_fail_to_request_open = 'Ошибка в запрашиваемом соединении'; - $lang->msg_invalid_format = 'Неверный формат'; - - $lang->msg_not_permitted_act = 'У Вас нет прав для исполнения запрошенного действия'; - $lang->msg_module_is_not_exists = "Невозможно найти запрашиваемый модуль.\nПросьба обратиться к администратору"; - $lang->msg_module_is_not_standalone = 'Запрошенный модуль не может быть исполнен независимо'; - $lang->msg_default_url_is_not_defined = 'Default URL is not define'; - - $lang->success_registed = 'Зарегистрировано успешно'; - $lang->success_declared = 'Жалоба отправлена'; - $lang->success_updated = 'Обновление успешно'; - $lang->success_deleted = 'Удалено успешно'; - $lang->success_voted = 'Рекомендовано успешно'; - $lang->success_blamed = 'Критика принята'; - $lang->success_moved = 'Перемещено успешно'; - $lang->success_sended = 'Отправлено успешно'; - $lang->success_reset = 'Сброшено успешно'; - $lang->success_leaved = 'Пользователь удален'; - $lang->success_saved = 'Сохранено успешно'; - - $lang->fail_to_delete = 'Не может быть удалено'; - $lang->fail_to_move = 'Перемещение невозможно'; - - $lang->failed_voted = 'Рекоммендовать невозможно'; - $lang->failed_blamed = 'Критиковать невозможно'; - $lang->failed_declared = 'Пожаловаться невозможно'; - $lang->fail_to_delete_have_children = 'Невозможно удаление из-за наличия ответов в записи'; - - $lang->confirm_submit = 'Вы подтверждаете запись?'; - $lang->confirm_logout = 'Вы подтверждаете выход?'; - $lang->confirm_vote = 'Рекомендовать?'; - $lang->confirm_delete = 'Удалить?'; - $lang->confirm_restore = 'Восстановить?'; - $lang->confirm_move = 'Переместить?'; - $lang->confirm_reset = 'Вы подтверждаете сброс?'; - $lang->confirm_leave = 'Вы подтверждаете удаление аккаунта?'; - $lang->confirm_update = 'Обновить?'; - - $lang->column_type = 'Тип колонки'; - $lang->column_type_list['text'] = 'Однострочное окно ввода'; - $lang->column_type_list['homepage'] = 'url'; - $lang->column_type_list['email_address'] = 'email'; - $lang->column_type_list['tel'] = 'номер телефона'; - $lang->column_type_list['textarea'] = 'Многострочное окно ввода'; - $lang->column_type_list['checkbox'] = 'Чекбокс (мульти вариант)'; - $lang->column_type_list['select'] = 'Выбор (один вариант)'; - $lang->column_type_list['radio'] = 'Кнопка радио (радио)'; - $lang->column_type_list['kr_zip'] = 'Почтовый индекс (Корейский)'; - $lang->column_type_list['date'] = 'Дата (гггг / мм / дд)'; - //$lang->column_type_list['jp_zip'] = 'почтовый индекс (японский)'; - $lang->column_name = 'Имя колонки'; - $lang->column_title = 'Заголовок колонки'; - $lang->default_value = 'Стандартное значение'; - $lang->is_active = 'Активация'; - $lang->is_required = 'Обязательные данные'; - $lang->eid = 'Имя экстра переменных'; - - // ftp 관련 - $lang->ftp_form_title = 'Введите данные FTP'; - $lang->ftp = 'FTP'; - $lang->ftp_host = 'FTP hostname'; - $lang->ftp_port = 'FTP port'; - $lang->about_ftp_password = 'FTP password will not be stored'; - $lang->cmd_check_ftp_connect = 'Check FTP Connection'; - $lang->about_ftp_info = " - FTP account information can be used in following cases.
- 1. If safe_mode setting of PHP is on, XE will be installed using FTP.
- 2. Automatic updates might use FTP information.
- This account info will be stored in files/config/ftp.config.php
- After installation, you can modify or delete the account info at the administration page.
- "; - - $lang->msg_safe_mode_ftp_needed = "If safe_mode setting of PHP is on, you should input FTP account information to install XE."; - $lang->msg_ftp_not_connected = "Connection to localhost via FTP failed. Please check the port number and if FTP service is available."; - $lang->msg_ftp_invalid_auth_info = "Authentication failed. Please check the username and password."; - $lang->msg_ftp_mkdir_fail = "Directory creation failed. Please check the permission of FTP account."; - $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->ftp_path_title = 'FTP Path Information'; - $lang->msg_ftp_installed_realpath = 'Absolute Path of XE'; - $lang->msg_ftp_installed_ftp_realpath = 'Absolute FTP Path of XE'; - - // Alert messages for Javascript using by XML filter - $lang->filter->isnull = 'Please input a value for %s'; - $lang->filter->outofrange = 'Please align the text length of %s'; - $lang->filter->equalto = "The value of %s is invalid"; - $lang->filter->invalid_email = "The format of %s is invalid. ex) zbxe@zeroboard.com"; - $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "The format of %s is invalid.\\nAll values should consist of alphabets, numbers or underscore(_) and the first letter should be alphabet"; - $lang->filter->invalid_homepage = "The format of %s is invalid. ex) http://www.zeroboard.com"; - $lang->filter->invalid_korean = "The format of %s is invalid. Please input Korean only"; - $lang->filter->invalid_korean_number = "The format of %s is invalid. Please input Korean or numbers"; - $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_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.
To view them, please use another non-administrator ID."; -?> +cmd_write = 'Написать'; + $lang->cmd_reply = 'Ответить'; + $lang->cmd_delete = 'Удалить'; + $lang->cmd_modify = 'Изменить'; + $lang->cmd_edit = 'Редактировать'; + $lang->cmd_view = 'Просмотреть'; + $lang->cmd_view_all = 'Просмотреть все'; + $lang->cmd_list = 'Список'; + $lang->cmd_prev = 'Предыдущее'; + $lang->cmd_next = 'Следующее'; + $lang->cmd_send_trackback = 'Отправить трекбек'; + $lang->cmd_registration = $lang->cmd_submit = 'Принять'; + $lang->cmd_comment_registration = 'Добавить запись'; + $lang->cmd_insert = 'Вставить'; + $lang->cmd_save = 'Сохранить'; + $lang->cmd_load = 'Загрузить'; + $lang->cmd_input = 'Ввести'; + $lang->cmd_search = 'Искать'; + $lang->cmd_find = 'Поиск'; + $lang->cmd_replace = 'Поменять'; + $lang->cmd_confirm = 'Подтвердить'; + $lang->cmd_cancel = 'Отменить'; + $lang->cmd_back = 'Вернуться'; + $lang->cmd_vote = 'Рекомендовать'; + $lang->cmd_vote_down = 'Критиковать'; + $lang->cmd_declare = 'Пожаловаться'; + $lang->cmd_cancel_declare = 'Отменить жалобу'; + $lang->cmd_declared_list = 'Список жалоб'; + $lang->cmd_copy = 'Копировать'; + $lang->cmd_move = 'Переместить'; + $lang->cmd_move_up = 'Вверх'; + $lang->cmd_move_down = 'Вниз'; + $lang->cmd_add_indent = 'Отступ вправо'; + $lang->cmd_remove_indent = 'Отступ влево'; + $lang->cmd_management = 'Управление'; + $lang->cmd_make = 'Создать'; + $lang->cmd_select = 'Выделить'; + $lang->cmd_select_all = 'Выделить все'; + $lang->cmd_unselect_all = 'Убрать выделение ВСЕХ'; + $lang->cmd_reverse_all = 'Перевернуть'; + $lang->cmd_close_all = 'Закрыть все'; + $lang->cmd_open_all = 'Открыть все'; + $lang->cmd_reload = 'Перегрузить'; + $lang->cmd_close = 'Закрыть'; + $lang->cmd_open = 'Открыть'; + $lang->cmd_setup = 'Конфигурация'; + $lang->cmd_addition_setup = 'Дополнительная настройка'; + $lang->cmd_option = 'Опция'; + $lang->cmd_apply = 'Применить'; + $lang->cmd_open_calendar = 'Выбрать дату'; + $lang->cmd_send = 'Отправить'; + $lang->cmd_print = 'Напечатать'; + $lang->cmd_scrap = 'В черновики'; + $lang->cmd_preview = 'Предпросмотр'; + $lang->cmd_reset = 'Сброс'; + $lang->cmd_remake_cache = "Пересоздать файл кэша"; + $lang->cmd_publish = "Опубликовать"; + $lang->cmd_layout_setup = 'Конфигурировать лейаут'; + $lang->cmd_layout_edit = 'Редактировать лейаут'; + $lang->cmd_search_by_ipaddress = 'Искать по IP адресу'; + $lang->cmd_add_ip_to_spamfilter = 'Добавить IP в спамфильтры'; + + $lang->enable = 'Включено'; + $lang->disable = 'Выключено'; + + // Основные слова + $lang->menu = 'Меню'; + $lang->no = 'No.'; + $lang->notice = 'Уведомление'; + $lang->secret = 'Секрет'; + $lang->category = $lang->category_srl = 'Категория'; + $lang->none_category = 'Без категории'; + $lang->none_image = 'Картинки нет'; + $lang->document_srl = 'No документа'; + $lang->user_id = 'ID пользователя'; + $lang->author = 'Автор'; + $lang->password = 'Пароль'; + $lang->password1 = 'Пароль'; + $lang->password2 = 'Подтверждение пароля'; + $lang->admin_id = 'ID админа'; + $lang->writer = 'Автор записи'; + $lang->user_name = 'Имя пользователя'; + $lang->nick_name = 'Ник'; + $lang->email_address = 'Email'; + $lang->homepage = 'Домашняя страница'; + $lang->blog = 'Блог'; + $lang->birthday = 'Дата рождения'; + $lang->browser_title = 'Заголовок браузера'; + $lang->title = 'Заголовок'; + $lang->title_content = 'Заголовок+Содержание'; + $lang->topic = 'Тема'; + $lang->replies = 'Ответы'; + $lang->content = 'Содержание'; + $lang->document = 'Статьи'; + $lang->comment = 'Комментарии'; + $lang->description = 'Описание'; + $lang->trackback = 'Трекбек'; + $lang->tag = 'Тег'; + $lang->allow_comment = 'Позволить комментарии'; + $lang->lock_comment = 'Заблокировать комментарии'; + $lang->allow_trackback = 'Позволить трекбек'; + $lang->uploaded_file = 'Прикрепить файл'; + $lang->grant = 'Права доступа'; + $lang->target = 'Назначение'; + $lang->total = 'Всего'; + $lang->total_count = 'Общее количество'; + $lang->ipaddress = 'IP адрес'; + $lang->path = 'Путь'; + $lang->cart = 'Выбранный объект'; + $lang->friend = 'Друзья'; + $lang->notify = 'Уведомление'; + $lang->order_target = 'Align Target'; + $lang->order_type = 'Тип сортировки'; + $lang->order_asc = 'снизу вверх'; + $lang->order_desc = 'сверху вниз'; + $lang->file = 'файл'; + + $lang->mid = 'Имя Модуля'; + $lang->sid = 'Site Name'; + $lang->layout = 'Лейаут'; + $lang->mobile_layout = 'Mobile Layout'; + $lang->widget = 'Виджет'; + $lang->module = 'Модуль'; + $lang->skin = 'Тема'; + $lang->mobile_skin = 'Mobile Theme'; + $lang->colorset = 'Цветовой набор'; + $lang->extra_vars = 'Дополнительные переменные.'; + + $lang->domain = "Доменное имя"; + $lang->url = "URL"; + $lang->document_url = 'URL записи'; + $lang->trackback_url = 'URL трекбека'; + $lang->blog_name = 'Название блога'; + $lang->excerpt = 'Цитата'; + + $lang->document_count = 'Всего записей'; + $lang->page_count = 'Количество страниц'; + $lang->list_count = 'Количество списков'; + $lang->search_list_count = 'Поиск Список кол'; + $lang->readed_count = 'Просмотры'; + $lang->voted_count = 'Голоса'; + $lang->comment_count = 'Комментарии'; + $lang->member_count = 'Количество пользователей'; + $lang->date = 'Дата'; + $lang->regdate = 'Дата регистрации'; + $lang->last_update = 'Последнее обновление'; + $lang->last_post = 'Последний комментарий'; + $lang->signup_date = 'Дата регистрации'; + $lang->last_login = 'Последний вход'; + $lang->first_page = 'Первая страница'; + $lang->last_page = 'Последняя страница'; + $lang->search_target = 'Назначение поиска'; + $lang->search_keyword = 'Ключевые слова'; + $lang->is_default = 'По умолчанию'; + + $lang->no_documents = 'Нет записей'; + + $lang->board_manager = 'Настройки форума'; + $lang->member_manager = 'Настройки пользователей'; + $lang->layout_manager = 'Настройки лейаута'; + + $lang->use = 'Использовать'; + $lang->notuse = 'Не использовать'; + $lang->not_exists = "Отсутствует"; + + $lang->public = 'Показать всем'; + $lang->private = 'Не показывать'; + + $lang->unit_sec = 'сек.'; + $lang->unit_min = 'мин.'; + $lang->unit_hour = 'ч.'; + $lang->unit_day = 'д.'; + $lang->unit_week = 'нед.'; + $lang->unit_month = 'мес.'; + $lang->unit_year = 'г.'; + + $lang->unit_week = array( + 'Monday' => 'Понедельник', + 'Tuesday' => 'Вторник', + 'Wednesday' => 'Среда', + 'Thursday' => 'Четверг', + 'Friday' => 'Пятница', + 'Saturday' => 'Суббота', + 'Sunday' => 'Воскресенье', + ); + + $lang->unit_meridiem = array( + 'am' => 'am', + 'pm' => 'pm', + 'AM' => 'AM', + 'PM' => 'PM', + ); + + $lang->time_gap = array( + 'min' => '%d минуту назад', + 'mins' => '%d минут назад', + 'hour' => '%d час назад', + 'hours' => '%d часов назад', + ); + + // Описания + $lang->about_tag = 'Вы можете применить несколько тегов, разделенных запятыми (,)'; + $lang->about_layout = 'Лейауты украшают внешний вид Ваших модулей. Вы можете сконфигурировать их с помощью меню Лейаут сверху'; + + // Сообщение + $lang->msg_call_server = 'Идет обработка. Пожалуйста, подождите...'; + $lang->msg_db_not_setted = 'Даза данных не сконфигурирована'; + $lang->msg_dbconnect_failed = "Произошла ошибка подключения к базе данных.\nПожалуйста, проверьте иформацию базы данных еще раз"; + $lang->msg_invalid_queryid = 'Указанный ID запроса неверен'; + $lang->msg_not_permitted = 'У Вас нет доступа'; + $lang->msg_input_password = 'Пожалуйста, введите пароль'; + $lang->msg_invalid_document = 'Неверный номер статьи'; + $lang->msg_invalid_request = 'Неверный запрос'; + $lang->msg_invalid_password = 'Неверный пароль'; + $lang->msg_error_occured = 'Произошла ошибка'; + $lang->msg_not_founded = 'Сообщение не найдено'; + $lang->msg_no_result = 'Ничего не найдено'; + $lang->msg_fail_to_request_open = 'Ошибка в запрашиваемом соединении'; + $lang->msg_invalid_format = 'Неверный формат'; + + $lang->msg_not_permitted_act = 'У Вас нет прав для исполнения запрошенного действия'; + $lang->msg_module_is_not_exists = "Невозможно найти запрашиваемый модуль.\nПросьба обратиться к администратору"; + $lang->msg_module_is_not_standalone = 'Запрошенный модуль не может быть исполнен независимо'; + $lang->msg_default_url_is_not_defined = 'Default URL is not define'; + + $lang->success_registed = 'Зарегистрировано успешно'; + $lang->success_declared = 'Жалоба отправлена'; + $lang->success_updated = 'Обновление успешно'; + $lang->success_deleted = 'Удалено успешно'; + $lang->success_voted = 'Рекомендовано успешно'; + $lang->success_blamed = 'Критика принята'; + $lang->success_moved = 'Перемещено успешно'; + $lang->success_sended = 'Отправлено успешно'; + $lang->success_reset = 'Сброшено успешно'; + $lang->success_leaved = 'Пользователь удален'; + $lang->success_saved = 'Сохранено успешно'; + + $lang->fail_to_delete = 'Не может быть удалено'; + $lang->fail_to_move = 'Перемещение невозможно'; + + $lang->failed_voted = 'Рекоммендовать невозможно'; + $lang->failed_blamed = 'Критиковать невозможно'; + $lang->failed_declared = 'Пожаловаться невозможно'; + $lang->fail_to_delete_have_children = 'Невозможно удаление из-за наличия ответов в записи'; + + $lang->confirm_submit = 'Вы подтверждаете запись?'; + $lang->confirm_logout = 'Вы подтверждаете выход?'; + $lang->confirm_vote = 'Рекомендовать?'; + $lang->confirm_delete = 'Удалить?'; + $lang->confirm_restore = 'Восстановить?'; + $lang->confirm_move = 'Переместить?'; + $lang->confirm_reset = 'Вы подтверждаете сброс?'; + $lang->confirm_leave = 'Вы подтверждаете удаление аккаунта?'; + $lang->confirm_update = 'Обновить?'; + + $lang->column_type = 'Тип колонки'; + $lang->column_type_list['text'] = 'Однострочное окно ввода'; + $lang->column_type_list['homepage'] = 'url'; + $lang->column_type_list['email_address'] = 'email'; + $lang->column_type_list['tel'] = 'номер телефона'; + $lang->column_type_list['textarea'] = 'Многострочное окно ввода'; + $lang->column_type_list['checkbox'] = 'Чекбокс (мульти вариант)'; + $lang->column_type_list['select'] = 'Выбор (один вариант)'; + $lang->column_type_list['radio'] = 'Кнопка радио (радио)'; + $lang->column_type_list['kr_zip'] = 'Почтовый индекс (Корейский)'; + $lang->column_type_list['date'] = 'Дата (гггг / мм / дд)'; + //$lang->column_type_list['jp_zip'] = 'почтовый индекс (японский)'; + $lang->column_name = 'Имя колонки'; + $lang->column_title = 'Заголовок колонки'; + $lang->default_value = 'Стандартное значение'; + $lang->is_active = 'Активация'; + $lang->is_required = 'Обязательные данные'; + $lang->eid = 'Имя экстра переменных'; + + // ftp 관련 + $lang->ftp_form_title = 'Введите данные FTP'; + $lang->ftp = 'FTP'; + $lang->ftp_host = 'FTP hostname'; + $lang->ftp_port = 'FTP port'; + $lang->about_ftp_password = 'FTP password will not be stored'; + $lang->cmd_check_ftp_connect = 'Check FTP Connection'; + $lang->about_ftp_info = " + FTP account information can be used in following cases.
+ 1. If safe_mode setting of PHP is on, XE will be installed using FTP.
+ 2. Automatic updates might use FTP information.
+ This account info will be stored in files/config/ftp.config.php
+ After installation, you can modify or delete the account info at the administration page.
+ "; + + $lang->msg_safe_mode_ftp_needed = "If safe_mode setting of PHP is on, you should input FTP account information to install XE."; + $lang->msg_ftp_not_connected = "Connection to localhost via FTP failed. Please check the port number and if FTP service is available."; + $lang->msg_ftp_invalid_auth_info = "Authentication failed. Please check the username and password."; + $lang->msg_ftp_mkdir_fail = "Directory creation failed. Please check the permission of FTP account."; + $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->ftp_path_title = 'FTP Path Information'; + $lang->msg_ftp_installed_realpath = 'Absolute Path of XE'; + $lang->msg_ftp_installed_ftp_realpath = 'Absolute FTP Path of XE'; + + // Alert messages for Javascript using by XML filter + $lang->filter->isnull = 'Please input a value for %s'; + $lang->filter->outofrange = 'Please align the text length of %s'; + $lang->filter->equalto = "The value of %s is invalid"; + $lang->filter->invalid_email = "The format of %s is invalid. ex) developers@xpressengine.com"; + $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "The format of %s is invalid.\\nAll values should consist of alphabets, numbers or underscore(_) and the first letter should be alphabet"; + $lang->filter->invalid_homepage = "The format of %s is invalid. ex) http://xpressengine.com/"; + $lang->filter->invalid_korean = "The format of %s is invalid. Please input Korean only"; + $lang->filter->invalid_korean_number = "The format of %s is invalid. Please input Korean or numbers"; + $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_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.
To view them, please use another non-administrator ID."; +?> diff --git a/common/lang/vi.lang.php b/common/lang/vi.lang.php index 461b2c9a1..f004cec73 100644 --- a/common/lang/vi.lang.php +++ b/common/lang/vi.lang.php @@ -1,7 +1,7 @@ filter->isnull = '请输入%s'; $lang->filter->outofrange = '请确认%s字数'; $lang->filter->equalto = '%s值有误。'; - $lang->filter->invalid_email = '%s格式有误。(例:zbxe@zeroboard.com)'; + $lang->filter->invalid_email = '%s格式有误。(例:developers@xpressengine.com)'; $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%s只能用英文,数字和 _,首个字符必须是英文字母。"; - $lang->filter->invalid_homepage = '%s格式有误。(例: http://www.zeroboard.com)'; + $lang->filter->invalid_homepage = '%s格式有误。(例: http://xpressengine.com/)'; $lang->filter->invalid_korean = '%s只能输入中文'; $lang->filter->invalid_korean_number = '%s只能输入中文或数字'; $lang->filter->invalid_alpha = '%s只能输入英文字母'; diff --git a/common/lang/zh-TW.lang.php b/common/lang/zh-TW.lang.php index 9c667524a..afb0060ac 100644 --- a/common/lang/zh-TW.lang.php +++ b/common/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ filter->isnull = '請輸入%s'; $lang->filter->outofrange = '請確認%s字數'; $lang->filter->equalto = '%s值有誤。'; - $lang->filter->invalid_email = '%s格式有誤。(例:zbxe@zeroboard.com)'; + $lang->filter->invalid_email = '%s格式有誤。(例:developers@xpressengine.com)'; $lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%s只允許使用英文,數字和底線,開頭必須是英文。"; - $lang->filter->invalid_homepage = '%s格式有誤。(例: http://www.zeroboard.com)'; + $lang->filter->invalid_homepage = '%s格式有誤。(例: http://xpressengine.com/)'; $lang->filter->invalid_korean = '%s只能輸入中文'; $lang->filter->invalid_korean_number = '%s只能輸入中文或數字'; $lang->filter->invalid_alpha = '%s只能輸入英文字母'; diff --git a/common/script.php b/common/script.php index 2d232dd3e..246efeabb 100644 --- a/common/script.php +++ b/common/script.php @@ -1,278 +1,278 @@ -use_template_cache){ - include _XE_PATH_ . 'classes/handler/Handler.class.php'; - include _XE_PATH_ . 'classes/cache/CacheHandler.class.php'; - $oCacheHandler = new CacheHandler('template', $db_info); - $cache_support = $oCacheHandler->isSupport(); - }else{ - $cache_support = false; - } -}else{ - $cache_support = false; -} - -//$XE_WEB_PATH = substr($XE_PATH,strlen($_SERVER['DOCUMENT_ROOT'])); -$XE_WEB_PATH_arr = explode("/", $_SERVER['REQUEST_URI']); -array_pop($XE_WEB_PATH_arr); -array_pop($XE_WEB_PATH_arr); -$XE_WEB_PATH = implode("/", $XE_WEB_PATH_arr); -if(substr($XE_WEB_PATH,-1) != "/") $XE_WEB_PATH .= "/"; -$cache_path = $XE_PATH . 'files/cache/optimized/'; -$type = $_GET['t']; -$list_file = $cache_path . $_GET['l'] .'.info.php'; - - -function getRealPath($file){ - if($file{0}=='.' && $file{1} =='/') $file = _XE_PATH_.substr($file, 2); - return $file; -} - -function getMtime($file){ - $file = getRealPath($file); - if(file_exists($file)) return filemtime($file); -} - -function getMaxMtime($list){ - $mtime = array(); - foreach($list as $file) $mtime[] = getMtime($file); - return max($mtime); -} - -// check -if($cache_support){ - $list = $oCacheHandler->get($_GET['l']); - $mtime = getMaxMtime($list); -}else{ - if(!file_exists($list_file)) exit; - $list = include($list_file); - $mtime = getMaxMtime(array_merge($list,array($list_file))); -} -if(!is_array($list)) exit; - -// set content-type -if($type == '.css'){ - $content_type = 'text/css'; -} else if($type == '.js') { - $content_type = 'text/javascript'; -} - -header("Content-Type: ".$content_type."; charset=UTF-8"); - -// return 304 -if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { - $modifiedSince = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); - if ($modifiedSince && ($modifiedSince == $mtime)) { - header('HTTP/1.1 304 Not Modified'); - header("Connection: close"); - exit; - } -} -function useContentEncoding(){ - if( (defined('__OB_GZHANDLER_ENABLE__') && __OB_GZHANDLER_ENABLE__ == 1) - && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')!==false - && function_exists('ob_gzhandler') - && extension_loaded('zlib')) { - return true; - } - return false; -} - -function getCacheKey($list){ - $key = 'optimized:' . join('',$list); - return md5($key); -} - -function printFileList($list){ - global $mtime, $cache_support, $oCacheHandler; - - $content_encoding = useContentEncoding(); - $output = null; - - if($cache_support){ - $cache_key = getCacheKey($list); - $output = $oCacheHandler->get($cache_key, $mtime); - } - - if(!$output || trim($output)==''){ - for($i=0,$c=count($list);$i<$c;$i++){ - $file = getRealPath($list[$i]); - if(file_exists($file)){ - $output .= '/* file:' . $file . " */\n"; - $output .= file_get_contents($file); - $output .= "\n"; - } - } - } - - if($cache_support) $oCacheHandler->put($cache_key, $output); - - if($content_encoding) $output = ob_gzhandler($output, 5); - $size = strlen($output); - - if($size > 0){ - header("Cache-Control: private"); - header("Pragma: cache"); - header("Connection: close"); - header("Last-Modified: " . substr(gmdate('r', $mtime), 0, -5). "GMT"); - header("ETag: \"". md5(join(' ', $list)) .'-'. dechex($mtime) .'-'.dechex($size)."\""); - } - - header("Content-Length: ". $size); - - if($content_encoding) header("Content-Encoding: gzip"); - - echo($output); -} - -function write($file_name, $buff, $mode='w'){ - $file_name = getRealPath($file_name); - if(@!$fp = fopen($file_name,$mode)) return false; - fwrite($fp, $buff); - fclose($fp); - @chmod($file_name, 0644); -} - -function read($file_name) { - $file_name = getRealPath($file_name); - - if(!file_exists($file_name)) return; - $filesize = filesize($file_name); - if($filesize<1) return; - - if(function_exists('file_get_contents')) return file_get_contents($file_name); - - $fp = fopen($file_name, "r"); - $buff = ''; - if($fp) { - while(!feof($fp) && strlen($buff)<=$filesize) { - $str = fgets($fp, 1024); - $buff .= $str; - } - fclose($fp); - } - return $buff; -} - -function makeCacheFileCSS($css_file, $cache_file, $return=false){ - $str = read($css_file); - $str = replaceCssPath($css_file, trim(convertEncodingStr($str))); - - if($return){ - return $str; - }else{ - write($cache_file, $str."\n"); - unset($str); - } -} - -function replaceCssPath($file, $str) { - global $tmp_css_path; - - // css 파일의 위치를 구함 - $tmp_css_path = preg_replace("/^\.\//is","",dirname($file))."/"; - // url() 로 되어 있는 css 파일의 경로를 변경 - $str = preg_replace_callback('/url\(([^\)]*)\)/is', '_replaceCssPath', $str); - - // charset 지정 문구를 제거 - $str = preg_replace('!@charset([^;]*?);!is','',$str); - - return $str; -} - -function _replaceCssPath($matches) { - global $tmp_css_path, $XE_WEB_PATH; - - $path = str_replace(array('"',"'"),'',$matches[1]); - if(substr($path,0,1)=='/' || strpos($path,'://')!==false || strpos($path,'.htc')!==false) return 'url('.$path.')'; - if(substr($path,0,2)=='./') $path = substr($path,2); - $target = $XE_WEB_PATH.$tmp_css_path.$path; - while(strpos($target,'/../')!==false) { - $target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target); - } - - return 'url('.$target.')'; -} - -function convertEncodingStr($str) { - if(!$str) return ''; - - $charset_list = array( - 'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932', - 'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS', - 'ISO2022-CN', 'ISO2022-CN-EXT', 'ISO2022-JP', 'ISO2022-JP-2', 'ISO2022-JP-1', - 'ISO8859-6', 'ISO8859-8', 'JOHAB', 'ISO2022-KR', 'CP1255', 'CP1256', 'CP862', - 'ASCII', 'ISO8859-1', 'ISO8850-2', 'ISO8850-3', 'ISO8850-4', 'ISO8850-5', - 'ISO8850-7', 'ISO8850-9', 'ISO8850-10', 'ISO8850-13', 'ISO8850-14', - 'ISO8850-15', 'ISO8850-16', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', - 'CP1257', 'CP850', 'CP866', - ); - - for($i=0,$c=count($charset_list);$i<$c;$i++) { - $charset = $charset_list[$i]; - if($str == iconv($charset, $charset.'//IGNORE',$str)){ - if($charset == 'UTF-8') return $str; - return iconv($charset, 'UTF-8//IGNORE', $str); - } - } - - return $str; -} -if($type == '.js'){ - printFileList($list); -}else if($type == '.css'){ - $css = array(); - - if($cache_support){ - foreach($list as $file){ - $cache_file = $cache_path . md5($file). '.cache.php'; - $css[] = getRealPath($cache_file); - } - - $cache_key = getCacheKey($css); - - $buff = $oCacheHandler->get($cache_key, $mtime); - if(!$buff){ - $buff = ''; - foreach($list as $file){ - $buff .= makeCacheFileCSS($file, '', true); - } - - $oCacheHandler->put($cache_key, $buff); - } - - }else{ - foreach($list as $file){ - $cache_file = $cache_path . md5($file). '.cache.php'; - $cache_mtime = getMtime($cache_file); - $css_mtime = getMtime($file); - - // check modified - if($css_mtime > $cache_mtime){ - makeCacheFileCSS($file, getRealPath($cache_file)); - } - $css[] = getRealPath($cache_file); - } - - } - - printFileList($css); -} -?> +use_template_cache){ + include _XE_PATH_ . 'classes/handler/Handler.class.php'; + include _XE_PATH_ . 'classes/cache/CacheHandler.class.php'; + $oCacheHandler = new CacheHandler('template', $db_info); + $cache_support = $oCacheHandler->isSupport(); + }else{ + $cache_support = false; + } +}else{ + $cache_support = false; +} + +//$XE_WEB_PATH = substr($XE_PATH,strlen($_SERVER['DOCUMENT_ROOT'])); +$XE_WEB_PATH_arr = explode("/", $_SERVER['REQUEST_URI']); +array_pop($XE_WEB_PATH_arr); +array_pop($XE_WEB_PATH_arr); +$XE_WEB_PATH = implode("/", $XE_WEB_PATH_arr); +if(substr($XE_WEB_PATH,-1) != "/") $XE_WEB_PATH .= "/"; +$cache_path = $XE_PATH . 'files/cache/optimized/'; +$type = $_GET['t']; +$list_file = $cache_path . $_GET['l'] .'.info.php'; + + +function getRealPath($file){ + if($file{0}=='.' && $file{1} =='/') $file = _XE_PATH_.substr($file, 2); + return $file; +} + +function getMtime($file){ + $file = getRealPath($file); + if(file_exists($file)) return filemtime($file); +} + +function getMaxMtime($list){ + $mtime = array(); + foreach($list as $file) $mtime[] = getMtime($file); + return max($mtime); +} + +// check +if($cache_support){ + $list = $oCacheHandler->get($_GET['l']); + $mtime = getMaxMtime($list); +}else{ + if(!file_exists($list_file)) exit; + $list = include($list_file); + $mtime = getMaxMtime(array_merge($list,array($list_file))); +} +if(!is_array($list)) exit; + +// set content-type +if($type == '.css'){ + $content_type = 'text/css'; +} else if($type == '.js') { + $content_type = 'text/javascript'; +} + +header("Content-Type: ".$content_type."; charset=UTF-8"); + +// return 304 +if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { + $modifiedSince = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); + if ($modifiedSince && ($modifiedSince == $mtime)) { + header('HTTP/1.1 304 Not Modified'); + header("Connection: close"); + exit; + } +} +function useContentEncoding(){ + if( (defined('__OB_GZHANDLER_ENABLE__') && __OB_GZHANDLER_ENABLE__ == 1) + && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')!==false + && function_exists('ob_gzhandler') + && extension_loaded('zlib')) { + return true; + } + return false; +} + +function getCacheKey($list){ + $key = 'optimized:' . join('',$list); + return md5($key); +} + +function printFileList($list){ + global $mtime, $cache_support, $oCacheHandler; + + $content_encoding = useContentEncoding(); + $output = null; + + if($cache_support){ + $cache_key = getCacheKey($list); + $output = $oCacheHandler->get($cache_key, $mtime); + } + + if(!$output || trim($output)==''){ + for($i=0,$c=count($list);$i<$c;$i++){ + $file = getRealPath($list[$i]); + if(file_exists($file)){ + $output .= '/* file:' . $file . " */\n"; + $output .= file_get_contents($file); + $output .= "\n"; + } + } + } + + if($cache_support) $oCacheHandler->put($cache_key, $output); + + if($content_encoding) $output = ob_gzhandler($output, 5); + $size = strlen($output); + + if($size > 0){ + header("Cache-Control: private"); + header("Pragma: cache"); + header("Connection: close"); + header("Last-Modified: " . substr(gmdate('r', $mtime), 0, -5). "GMT"); + header("ETag: \"". md5(join(' ', $list)) .'-'. dechex($mtime) .'-'.dechex($size)."\""); + } + + header("Content-Length: ". $size); + + if($content_encoding) header("Content-Encoding: gzip"); + + echo($output); +} + +function write($file_name, $buff, $mode='w'){ + $file_name = getRealPath($file_name); + if(@!$fp = fopen($file_name,$mode)) return false; + fwrite($fp, $buff); + fclose($fp); + @chmod($file_name, 0644); +} + +function read($file_name) { + $file_name = getRealPath($file_name); + + if(!file_exists($file_name)) return; + $filesize = filesize($file_name); + if($filesize<1) return; + + if(function_exists('file_get_contents')) return file_get_contents($file_name); + + $fp = fopen($file_name, "r"); + $buff = ''; + if($fp) { + while(!feof($fp) && strlen($buff)<=$filesize) { + $str = fgets($fp, 1024); + $buff .= $str; + } + fclose($fp); + } + return $buff; +} + +function makeCacheFileCSS($css_file, $cache_file, $return=false){ + $str = read($css_file); + $str = replaceCssPath($css_file, trim(convertEncodingStr($str))); + + if($return){ + return $str; + }else{ + write($cache_file, $str."\n"); + unset($str); + } +} + +function replaceCssPath($file, $str) { + global $tmp_css_path; + + // css 파일의 위치를 구함 + $tmp_css_path = preg_replace("/^\.\//is","",dirname($file))."/"; + // url() 로 되어 있는 css 파일의 경로를 변경 + $str = preg_replace_callback('/url\(([^\)]*)\)/is', '_replaceCssPath', $str); + + // charset 지정 문구를 제거 + $str = preg_replace('!@charset([^;]*?);!is','',$str); + + return $str; +} + +function _replaceCssPath($matches) { + global $tmp_css_path, $XE_WEB_PATH; + + $path = str_replace(array('"',"'"),'',$matches[1]); + if(substr($path,0,1)=='/' || strpos($path,'://')!==false || strpos($path,'.htc')!==false) return 'url('.$path.')'; + if(substr($path,0,2)=='./') $path = substr($path,2); + $target = $XE_WEB_PATH.$tmp_css_path.$path; + while(strpos($target,'/../')!==false) { + $target = preg_replace('/\/([^\/]+)\/\.\.\//','/',$target); + } + + return 'url('.$target.')'; +} + +function convertEncodingStr($str) { + if(!$str) return ''; + + $charset_list = array( + 'UTF-8', 'EUC-KR', 'CP949', 'ISO8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932', + 'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS', + 'ISO2022-CN', 'ISO2022-CN-EXT', 'ISO2022-JP', 'ISO2022-JP-2', 'ISO2022-JP-1', + 'ISO8859-6', 'ISO8859-8', 'JOHAB', 'ISO2022-KR', 'CP1255', 'CP1256', 'CP862', + 'ASCII', 'ISO8859-1', 'ISO8850-2', 'ISO8850-3', 'ISO8850-4', 'ISO8850-5', + 'ISO8850-7', 'ISO8850-9', 'ISO8850-10', 'ISO8850-13', 'ISO8850-14', + 'ISO8850-15', 'ISO8850-16', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254', + 'CP1257', 'CP850', 'CP866', + ); + + for($i=0,$c=count($charset_list);$i<$c;$i++) { + $charset = $charset_list[$i]; + if($str == iconv($charset, $charset.'//IGNORE',$str)){ + if($charset == 'UTF-8') return $str; + return iconv($charset, 'UTF-8//IGNORE', $str); + } + } + + return $str; +} +if($type == '.js'){ + printFileList($list); +}else if($type == '.css'){ + $css = array(); + + if($cache_support){ + foreach($list as $file){ + $cache_file = $cache_path . md5($file). '.cache.php'; + $css[] = getRealPath($cache_file); + } + + $cache_key = getCacheKey($css); + + $buff = $oCacheHandler->get($cache_key, $mtime); + if(!$buff){ + $buff = ''; + foreach($list as $file){ + $buff .= makeCacheFileCSS($file, '', true); + } + + $oCacheHandler->put($cache_key, $buff); + } + + }else{ + foreach($list as $file){ + $cache_file = $cache_path . md5($file). '.cache.php'; + $cache_mtime = getMtime($cache_file); + $css_mtime = getMtime($file); + + // check modified + if($css_mtime > $cache_mtime){ + makeCacheFileCSS($file, getRealPath($cache_file)); + } + $css[] = getRealPath($cache_file); + } + + } + + printFileList($css); +} +?> diff --git a/config/config.inc.php b/config/config.inc.php index f8c8fa08c..b462638fa 100644 --- a/config/config.inc.php +++ b/config/config.inc.php @@ -1,7 +1,7 @@ '[GMT -12:00] Baker Island Time', - '-1100' => '[GMT -11:00] Niue Time, Samoa Standard Time', - '-1000' => '[GMT -10:00] Hawaii-Aleutian Standard Time, Cook Island Time', - '-0930' => '[GMT -09:30] Marquesas Islands Time', - '-0900' => '[GMT -09:00] Alaska Standard Time, Gambier Island Time', - '-0800' => '[GMT -08:00] Pacific Standard Time', - '-0700' => '[GMT -07:00] Mountain Standard Time', - '-0600' => '[GMT -06:00] Central Standard Time', - '-0500' => '[GMT -05:00] Eastern Standard Time', - '-0400' => '[GMT -04:00] Atlantic Standard Time', - '-0330' => '[GMT -03:30] Newfoundland Standard Time', - '-0300' => '[GMT -03:00] Amazon Standard Time, Central Greenland Time', - '-0200' => '[GMT -02:00] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time', - '-0100' => '[GMT -01:00] Azores Standard Time, Cape Verde Time, Eastern Greenland Time', - '0000' => '[GMT 00:00] Western European Time, Greenwich Mean Time', - '+0100' => '[GMT +01:00] Central European Time, West African Time', - '+0200' => '[GMT +02:00] Eastern European Time, Central African Time', - '+0300' => '[GMT +03:00] Moscow Standard Time, Eastern African Time', - '+0330' => '[GMT +03:30] Iran Standard Time', - '+0400' => '[GMT +04:00] Gulf Standard Time, Samara Standard Time', - '+0430' => '[GMT +04:30] Afghanistan Time', - '+0500' => '[GMT +05:00] Pakistan Standard Time, Yekaterinburg Standard Time', - '+0530' => '[GMT +05:30] Indian Standard Time, Sri Lanka Time', - '+0545' => '[GMT +05:45] Nepal Time', - '+0600' => '[GMT +06:00] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time', - '+0630' => '[GMT +06:30] Cocos Islands Time, Myanmar Time', - '+0700' => '[GMT +07:00] Indochina Time, Krasnoyarsk Standard Time', - '+0800' => '[GMT +08:00] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time', - '+0845' => '[GMT +08:45] Southeastern Western Australia Standard Time', - '+0900' => '[GMT +09:00] Korea Standard Time, Japan Standard Time, China Standard Time', - '+0930' => '[GMT +09:30] Australian Central Standard Time', - '+1000' => '[GMT +10:00] Australian Eastern Standard Time, Vladivostok Standard Time', - '+1030' => '[GMT +10:30] Lord Howe Standard Time', - '+1100' => '[GMT +11:00] Solomon Island Time, Magadan Standard Time', - '+1130' => '[GMT +11:30] Norfolk Island Time', - '+1200' => '[GMT +12:00] New Zealand Time, Fiji Time, Kamchatka Standard Time', - '+1245' => '[GMT +12:45] Chatham Islands Time', - '+1300' => '[GMT +13:00] Tonga Time, Phoenix Islands Time', - '+1400' => '[GMT +14:00] Line Island Time' - ) ; - - /** - * @brief ModuleHandler::getModuleObject($module_name, $type)을 쓰기 쉽게 함수로 선언 - * @param module_name 모듈이름 - * @param type disp, proc, controller, class - * @param kind admin, null - * @return module instance - **/ - function &getModule($module_name, $type = 'view', $kind = '') { - return ModuleHandler::getModuleInstance($module_name, $type, $kind); - } - - /** - * @brief module의 controller 객체 생성용 - * @param module_name 모듈이름 - * @return module controller instance - **/ - function &getController($module_name) { - return getModule($module_name, 'controller'); - } - - /** - * @brief module의 admin controller 객체 생성용 - * @param module_name 모듈이름 - * @return module admin controller instance - **/ - function &getAdminController($module_name) { - return getModule($module_name, 'controller','admin'); - } - - /** - * @brief module의 view 객체 생성용 - * @param module_name 모듈이름 - * @return module view instance - **/ - function &getView($module_name) { - return getModule($module_name, 'view'); - } - - /** - * @brief module의 admin view 객체 생성용 - * @param module_name 모듈이름 - * @return module admin view instance - **/ - function &getAdminView($module_name) { - return getModule($module_name, 'view','admin'); - } - - /** - * @brief module의 model 객체 생성용 - * @param module_name 모듈이름 - * @return module model instance - **/ - function &getModel($module_name) { - return getModule($module_name, 'model'); - } - - /** - * @brief module의 admin model 객체 생성용 - * @param module_name 모듈이름 - * @return module admin model instance - **/ - function &getAdminModel($module_name) { - return getModule($module_name, 'model','admin'); - } - - /** - * @brief module의 api 객체 생성용 - * @param module_name 모듈이름 - * @return module api class instance - **/ - function &getAPI($module_name) { - return getModule($module_name, 'api'); - } - - /** - * @brief module의 wap 객체 생성용 - * @param module_name 모듈이름 - * @return module wap class instance - **/ - function &getWAP($module_name) { - return getModule($module_name, 'wap'); - } - - /** - * @brief module의 상위 class 객체 생성용 - * @param module_name 모듈이름 - * @return module class instance - **/ - function &getClass($module_name) { - return getModule($module_name, 'class'); - } - - /** - * @brief DB::executeQuery() 의 alias - * @param query_id 쿼리 ID ( 모듈명.쿼리XML파일 ) - * @param args object 변수로 선언된 인자값 - * @return 처리결과 - **/ - function executeQuery($query_id, $args = null) { - $oDB = &DB::getInstance(); - return $oDB->executeQuery($query_id, $args); - } - - /** - * @brief DB::executeQuery() 의 결과값을 무조건 배열로 처리하도록 하는 함수 - * @param query_id 쿼리 ID ( 모듈명.쿼리XML파일 ) - * @param args object 변수로 선언된 인자값 - * @return 처리결과 - **/ - function executeQueryArray($query_id, $args = null) { - $oDB = &DB::getInstance(); - $output = $oDB->executeQuery($query_id, $args); - if(!is_array($output->data) && count($output->data) > 0){ - $output->data = array($output->data); - } - return $output; - } - - /** - * @brief DB::getNextSequence() 의 alias - * @return big int - **/ - function getNextSequence() { - $oDB = &DB::getInstance(); - return $oDB->getNextSequence(); - } - - /** - * @brief Context::getUrl()를 쓰기 쉽게 함수로 선언 - * @return string - * - * getUrl()은 현재 요청된 RequestURI에 주어진 인자의 값으로 변형하여 url을 리턴한다\n - * 1. 인자는 (key, value)... 의 형식으로 주어져야 한다.\n - * ex) getUrl('key1','val1', 'key2', '') : key1, key2를 val1과 '' 로 변형\n - * 2. 아무런 인자가 없으면 argument를 제외한 url을 리턴 - * 3. 첫 인자값이 '' 이면 RequestUri에다가 추가된 args_list로 url을 만듬 - **/ - function getUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - - if(!$num_args) return Context::getRequestUri(); - - return Context::getUrl($num_args, $args_list); - } - - function getNotEncodedUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - - if(!$num_args) return Context::getRequestUri(); - - return Context::getUrl($num_args, $args_list, null, false); - } - - /** - * @brief getUrl()의 값에 request uri를 추가하여 reutrn - * full url을 얻기 위함 - **/ - function getFullUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - $request_uri = Context::getRequestUri(); - if(!$num_args) return $request_uri; - - $url = Context::getUrl($num_args, $args_list); - if(!preg_match('/^http/i',$url)){ - preg_match('/^(http|https):\/\/([^\/]+)\//',$request_uri,$match); - return substr($match[0],0,-1).$url; - } - return $url; - } - - function getNotEncodedFullUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - $request_uri = Context::getRequestUri(); - if(!$num_args) return $request_uri; - - $url = Context::getUrl($num_args, $args_list); - if(!preg_match('/^http/i',$url)){ - preg_match('/^(http|https):\/\/([^\/]+)\//',$request_uri,$match); - $url = Context::getUrl($num_args, $args_list, null, false); - return substr($match[0],0,-1).$url; - } - return $url; - } - - /** - * @brief Context::getUrl()를 쓰기 쉽게 함수로 선언 - * @return string - * - * getSiteUrl()은 지정된 도메인에 대해 주어진 인자의 값으로 변형하여 url을 리턴한다\n - * 첫 인자는 도메인(http://등이 제외된)+path 여야 함. - **/ - function getSiteUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - - if(!$num_args) return Context::getRequestUri(); - - $domain = array_shift($args_list); - $num_args = count($args_list); - - return Context::getUrl($num_args, $args_list, $domain); - } - - function getNotEncodedSiteUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - - if(!$num_args) return Context::getRequestUri(); - - $domain = array_shift($args_list); - $num_args = count($args_list); - - return Context::getUrl($num_args, $args_list, $domain, false); - } - - /** - * @brief getSiteUrl()의 값에 request uri를 추가하여 reutrn - * full url을 얻기 위함 - **/ - function getFullSiteUrl() { - $num_args = func_num_args(); - $args_list = func_get_args(); - - $request_uri = Context::getRequestUri(); - if(!$num_args) return $request_uri; - - $domain = array_shift($args_list); - $num_args = count($args_list); - - $url = Context::getUrl($num_args, $args_list, $domain); - if(!preg_match('/^http/i',$url)){ - preg_match('/^(http|https):\/\/([^\/]+)\//',$request_uri,$match); - return substr($match[0],0,-1).$url; - } - return $url; - } - - /** - * @brief 가상사이트의 Domain이 url형식인지 site id인지 return - **/ - function isSiteID($domain) { - return preg_match('/^([a-z0-9\_]+)$/i', $domain); - } - - /** - * @brief 주어진 문자를 주어진 크기로 자르고 잘라졌을 경우 주어진 꼬리를 담 - * @param string 자를 원 문자열 - * @param cut_size 주어진 원 문자열을 자를 크기 - * @param tail 잘라졌을 경우 문자열의 제일 뒤에 붙을 꼬리 - * @return string - **/ - function cut_str($string,$cut_size=0,$tail = '...') { - if($cut_size<1 || !$string) return $string; - - $chars = Array(12, 4, 3, 5, 7, 7, 11, 8, 4, 5, 5, 6, 6, 4, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 8, 6, 8, 6, 10, 8, 8, 9, 8, 8, 7, 9, 8, 3, 6, 7, 7, 11, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 8, 6, 11, 6, 6, 6, 4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 7, 3, 7, 6, 10, 6, 6, 7, 6, 6, 6, 9); - $max_width = $cut_size*$chars[0]/2; - $char_width = 0; - - $string_length = strlen($string); - $char_count = 0; - - $idx = 0; - while($idx < $string_length && $char_count < $cut_size && $char_width <= $max_width) { - $c = ord(substr($string, $idx,1)); - $char_count++; - if($c<128) { - $char_width += (int)$chars[$c-32]; - $idx++; - } - else if (191<$c && $c < 224) { - $char_width += $chars[4]; - $idx += 2; - } - else { - $char_width += $chars[0]; - $idx += 3; - } - } - $output = substr($string,0,$idx); - if(strlen($output)<$string_length) $output .= $tail; - return $output; - } - - function zgap() { - $time_zone = $GLOBALS['_time_zone']; - if($time_zone < 0) $to = -1; else $to = 1; - $t_hour = substr($time_zone, 1, 2) * $to; - $t_min = substr($time_zone, 3, 2) * $to; - - $server_time_zone = date("O"); - if($server_time_zone < 0) $so = -1; else $so = 1; - $c_hour = substr($server_time_zone, 1, 2) * $so; - $c_min = substr($server_time_zone, 3, 2) * $so; - - $g_min = $t_min - $c_min; - $g_hour = $t_hour - $c_hour; - - $gap = $g_min*60 + $g_hour*60*60; - return $gap; - } - - /** - * @brief YYYYMMDDHHIISS 형식의 시간값을 unix time으로 변경 - * @param str YYYYMMDDHHIISS 형식의 시간값 - * @return int - **/ - function ztime($str) { - if(!$str) return; - $hour = (int)substr($str,8,2); - $min = (int)substr($str,10,2); - $sec = (int)substr($str,12,2); - $year = (int)substr($str,0,4); - $month = (int)substr($str,4,2); - $day = (int)substr($str,6,2); - if(strlen($str) <= 8) { - $gap = 0; - } else { - $gap = zgap(); - } - - return mktime($hour, $min, $sec, $month?$month:1, $day?$day:1, $year)+$gap; - } - - /** - * @brief YmdHis의 시간 형식을 지금으로 부터 몇분/몇시간전, 1일 이상 차이나면 format string return - **/ - function getTimeGap($date, $format = 'Y.m.d') { - $gap = time() - ztime($date); - - $lang_time_gap = Context::getLang('time_gap'); - if($gap<60) $buff = sprintf($lang_time_gap['min'], (int)($gap / 60)+1); - elseif($gap<60*60) $buff = sprintf($lang_time_gap['mins'], (int)($gap / 60)+1); - elseif($gap<60*60*2) $buff = sprintf($lang_time_gap['hour'], (int)($gap / 60 /60)+1); - elseif($gap<60*60*24) $buff = sprintf($lang_time_gap['hours'], (int)($gap / 60 /60)+1); - else $buff = zdate($date, $format); - return $buff; - } - - /** - * @brief 월이름을 return - **/ - function getMonthName($month, $short = true) { - $short_month = array('','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); - $long_month = array('','January','February','March','April','May','June','July','August','September','October','November','December'); - return !$short?$long_month[$month]:$short_month[$month]; - } - - /** - * @brief YYYYMMDDHHIISS 형식의 시간값을 원하는 시간 포맷으로 변형 - * @param string|int str YYYYMMDDHHIISS 형식의 시간 값 - * @param string format php date()함수의 시간 포맷 - * @param bool conversion 언어에 따라 날짜 포맷의 자동변환 여부 - * @return string - **/ - function zdate($str, $format = 'Y-m-d H:i:s', $conversion=true) { - // 대상 시간이 없으면 null return - if(!$str) return; - - // 언어권에 따라서 지정된 날짜 포맷을 변경 - if($conversion == true) { - switch(Context::getLangType()) { - case 'en' : - case 'es' : - if($format == 'Y-m-d') $format = 'M d, Y'; - elseif($format == 'Y-m-d H:i:s') $format = 'M d, Y H:i:s'; - elseif($format == 'Y-m-d H:i') $format = 'M d, Y H:i'; - break; - case 'vi' : - if($format == 'Y-m-d') $format = 'd-m-Y'; - elseif($format == 'Y-m-d H:i:s') $format = 'H:i:s d-m-Y'; - elseif($format == 'Y-m-d H:i') $format = 'H:i d-m-Y'; - break; - - } - } - - // 년도가 1970년 이전이면 별도 처리 - if((int)substr($str,0,4) < 1970) { - $hour = (int)substr($str,8,2); - $min = (int)substr($str,10,2); - $sec = (int)substr($str,12,2); - $year = (int)substr($str,0,4); - $month = (int)substr($str,4,2); - $day = (int)substr($str,6,2); - $string = str_replace( - array('Y','m','d','H','h','i','s','a','M', 'F'), - array($year,$month,$day,$hour,$hour/12,$min,$sec,($hour <= 12) ? 'am' : 'pm',getMonthName($month), getMonthName($month,false)), - $format - ); - } else { - // 1970년 이후라면 ztime()함수로 unixtime을 구하고 date함수로 처리 - $string = date($format, ztime($str)); - } - - // 요일, am/pm을 각 언어에 맞게 변경 - $unit_week = Context::getLang('unit_week'); - $unit_meridiem = Context::getLang('unit_meridiem'); - $string = str_replace(array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'),$unit_week, $string); - $string = str_replace(array('am','pm','AM','PM'), $unit_meridiem, $string); - return $string; - } - - /** - * @brief prints debug messages - * @param debug_output target object to be printed - * @param display_line boolean flag whether to print seperator (default:true) - * @return none - * - * ./files/_debug_message.php 파일에 $buff 내용을 출력한다. - * tail -f ./files/_debug_message.php 하여 계속 살펴 볼 수 있다 - **/ - function debugPrint($debug_output = null, $display_option = true) { - if(!(__DEBUG__ & 1)) return; - - static $firephp; - $bt = debug_backtrace(); - if(is_array($bt)) $first = array_shift($bt); - $file_name = array_pop(explode(DIRECTORY_SEPARATOR, $first['file'])); - $line_num = $first['line']; - - if(__DEBUG_OUTPUT__ == 2 && version_compare(PHP_VERSION, '6.0.0') === -1) { - if(!isset($firephp)) $firephp = FirePHP::getInstance(true); - if(function_exists("memory_get_usage")) - { - $label = sprintf('[%s:%d] (m:%s)', $file_name, $line_num, FileHandler::filesize(memory_get_usage())); - } - else - { - $label = sprintf('[%s:%d] ', $file_name, $line_num); - } - - // FirePHP 옵션 체크 - if($display_option === 'TABLE') $label = $display_option; - - // __DEBUG_PROTECT__ 옵션으로 지정된 IP와 접근 IP가 동일한지 체크 - if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { - $debug_output = 'The IP address is not allowed. Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php'; - $label = null; - } - - $firephp->fb($debug_output, $label); - - } else { - if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { - return; - } - $debug_file = _XE_PATH_.'files/_debug_message.php'; - if(function_exists("memory_get_usage")) - { - $debug_output = sprintf("[%s %s:%d] - mem(%s)\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, FileHandler::filesize(memory_get_usage()), print_r($debug_output, true)); - } - else - { - $debug_output = sprintf("[%s %s:%d]\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, print_r($debug_output, true)); - } - - if($display_option === true) $debug_output = str_repeat('=', 40)."\n".$debug_output.str_repeat('-', 40); - $debug_output = "\n\n"; - - if(@!$fp = fopen($debug_file, 'a')) return; - fwrite($fp, $debug_output); - fclose($fp); - } - } - - - /** - * @brief microtime() return - * @return float - **/ - function getMicroTime() { - list($time1, $time2) = explode(' ', microtime()); - return (float)$time1 + (float)$time2; - } - - /** - * @brief 첫번째 인자로 오는 object var에서 2번째 object의 var들을 제거 - * @param target_obj 원 object - * @param del_obj 원 object의 vars에서 del_obj의 vars를 제거한다 - * @return object - **/ - function delObjectVars($target_obj, $del_obj) { - if(!is_object($target_obj)) return; - if(!is_object($del_obj)) return; - - $target_vars = get_object_vars($target_obj); - $del_vars = get_object_vars($del_obj); - - $target = array_keys($target_vars); - $del = array_keys($del_vars); - if(!count($target)||!count($del)) return $target_obj; - - $return_obj = NULL; - - $target_count = count($target); - for($i = 0; $i < $target_count; $i++) { - $target_key = $target[$i]; - if(!in_array($target_key, $del)) $return_obj->{$target_key} = $target_obj->{$target_key}; - } - - return $return_obj; - } - - /** - * @brief php5 이상에서 error_handing을 debugPrint로 변경 - * @param errno - * @param errstr - * @return file - * @return line - **/ - function handleError($errno, $errstr, $file, $line) { - if(!__DEBUG__) return; - $errors = array(E_USER_ERROR, E_ERROR, E_PARSE); - if(!in_array($errno, $errors)) return; - - $output = sprintf("Fatal error : %s - %d", $file, $line); - $output .= sprintf("%d - %s", $errno, $errstr); - - debugPrint($output); - } - - /** - * @brief 주어진 숫자를 주어진 크기로 recursive하게 잘라줌 - * @param no 주어진 숫자 - * @param size 잘라낼 크기 - **/ - function getNumberingPath($no, $size=3) { - $mod = pow(10, $size); - $output = sprintf('%0'.$size.'d/', $no%$mod); - if($no >= $mod) $output .= getNumberingPath((int)$no/$mod, $size); - return $output; - } - - /** - * @brief 한글이 들어간 url의 decode - **/ - function url_decode($str) { - return preg_replace('/%u([[:alnum:]]{4})/', '&#x\\1;',$str); - } - - /** - * @brief 해킹 시도로 의심되는 코드들을 미리 차단 - **/ - function removeHackTag($content) { - // 특정 태그들을 일반 문자로 변경 - $content = preg_replace('/<(\/?)(iframe|script|meta|style|applet|link|base|html|body)/is', '<$1$2', $content); - - /** - * 이미지나 동영상등의 태그에서 src에 관리자 세션을 악용하는 코드를 제거 - * - 취약점 제보 : 김상원님 - **/ - $content = preg_replace_callback("!<([a-z]+)(.*?)>!is", removeSrcHack, $content); - - return $content; - } - - - function removeSrcHack($matches) { - $tag = strtolower(trim($matches[1])); - - $buff = trim(preg_replace('/(\/>|>)/','/>',$matches[0])); - $buff = str_replace(array('&','&'),array('&','&'),$buff); - $buff = preg_replace_callback('/([^=^"^ ]*)=([^ ^>]*)/i', 'fixQuotation', $buff); - - $oXmlParser = new XmlParser(); - $xml_doc = $oXmlParser->parse($buff); - if(!$xml_doc) return sprintf("<%s>", $tag); - - // src값에 module=admin이라는 값이 입력되어 있으면 이 값을 무효화 시킴 - $src = $xml_doc->{$tag}->attrs->src; - $dynsrc = $xml_doc->{$tag}->attrs->dynsrc; - $lowsrc = $xml_doc->{$tag}->attrs->lowsrc; - $href = $xml_doc->{$tag}->attrs->href; - $data = $xml_doc->{$tag}->attrs->data; - $background = $xml_doc->{$tag}->attrs->background; - $style = $xml_doc->{$tag}->attrs->style; - if($style) { - $url = preg_match_all('/url\s*\(([^\)]+)\)/is', $style, $matches2); - if(count($matches2[0])) - { - foreach($matches2[1] as $target) - { - if(_isHackedSrc($target)) return sprintf("<%s>",$tag); - } - } - } - if(_isHackedSrc($src) || _isHackedSrc($dynsrc) || _isHackedSrc($lowsrc) || _isHackedSrc($href) || _isHackedSrc($data) || _isHackedSrc($background) || _isHackedSrcExp($style)) return sprintf("<%s>",$tag); - - return $buff; - } - - function _isHackedSrcExp($style) { - if(!$style) return false; - if(preg_match('/((\/\*)|(\*\/)|(\\n)|(expression))/i', $style)) return true; - return false; - } - - function _isHackedSrc($src) { - if(!$src) return false; - if($src) { - $target = trim($src); - if(preg_match('/(\s|(\&\#)|(script:))/i', $target)) return true; - if(preg_match('/data:/i', $target)) return true; - - $url_info = parse_url($src); - $query = $url_info['query']; - if(!trim($query)) return false; - $query = str_replace("&","&",$query); - $queries = explode('&', $query); - $cnt = count($queries); - for($i=0;$i<$cnt;$i++) { - $tmp_str = strtolower(trim($queries[$i])); - $pos = strpos($tmp_str,'='); - if($pos === false) continue; - $key = strtolower(trim(substr($tmp_str, 0, $pos))); - $val = strtolower(trim(substr($tmp_str,$pos+1))); - if( ($key=='module'&&$val=='admin') || ($key=='act'&&preg_match('/admin/i',$val)) ) return true; - } - } - return false; - } - - /** - * @brief attribute의 value를 " 로 둘러싸도록 처리하는 함수 - **/ - function fixQuotation($matches) { - $key = $matches[1]; - $val = $matches[2]; - - if(substr($val,0,1)!='"'){ - if(substr($val,-1)=='/'){ - $val = '"'.substr($val,0,-1).'" /'; - }else{ - $val = '"'.$val.'"'; - } - } - - // attribute on* remove - if(preg_match('/^on(click|load|unload|blur|dbclick|focus|resize|keypress|keyup|keydown|mouseover|mouseout|mouseup|select|change|error)/',preg_replace('/[^a-zA-Z_]/','',$key))) return ''; - - $output = sprintf('%s=%s', $key, $val); - - return $output; - } - - // hexa값을 RGB로 변환 - if(!function_exists('hexrgb')) { - function hexrgb($hexstr) { - $int = hexdec($hexstr); - - return array('red' => 0xFF & ($int >> 0x10), - 'green' => 0xFF & ($int >> 0x8), - 'blue' => 0xFF & $int); - } - - } - - /** - * @brief mysql old_password 의 php 구현 함수 - * 제로보드4나 기타 mysql4.1 이전의 old_password()함수를 쓴 데이터의 사용을 위해서 - * mysql의 password.c 소스 참조해서 구현함 - **/ - function mysql_pre4_hash_password($password) { - $nr = 1345345333; - $add = 7; - $nr2 = 0x12345671; - - settype($password, "string"); - - for ($i=0; $i>6)+192).chr(($num&63)+128); - if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128); - if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128); - return ''; - } - - - function detectUTF8($string, $return_convert = false, $urldecode = true) { - if($urldecode) $string = urldecode($string); - - $sample = iconv('utf-8', 'utf-8', $string); - $is_utf8 = (md5($sample) == md5($string)); - - if(!$urldecode) $string = urldecode($string); - - if($return_convert) return ($is_utf8) ? $string : iconv('euc-kr', 'utf-8', $string); - - return $is_utf8; - } - - - function json_encode2($data) { - switch (gettype($data)) { - case 'boolean': - return $data?'true':'false'; - case 'integer': - case 'double': - return $data; - case 'string': - return '"'.strtr($data, array('\\'=>'\\\\','"'=>'\\"')).'"'; - case 'object': - $data = get_object_vars($data); - case 'array': - $rel = false; // relative array? - $key = array_keys($data); - foreach ($key as $v) { - if (!is_int($v)) { - $rel = true; - break; - } - } - - $arr = array(); - foreach ($data as $k=>$v) { - $arr[] = ($rel?'"'.strtr($k, array('\\'=>'\\\\','"'=>'\\"')).'":':'').json_encode2($v); - } - - return $rel?'{'.join(',', $arr).'}':'['.join(',', $arr).']'; - default: - return '""'; - } - } - - - function isCrawler($agent = null) { - if(!$agent) $agent = $_SERVER['HTTP_USER_AGENT']; - $check_agent = array('bot', 'spider', 'google', 'yahoo', 'daum', 'teoma', 'fish', 'hanrss', 'facebook'); - $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; - } - - function stripEmbedTagForAdmin(&$content, $writer_member_srl) - { - if(!Context::get('is_logged')) return; - $oModuleModel = &getModel('module'); - $logged_info = Context::get('logged_info'); - - if($writer_member_srl != $logged_info->member_srl && ($logged_info->is_admin == "Y" || $oModuleModel->isSiteAdmin($logged_info)) ) - { - if($writer_member_srl) - { - $oMemberModel =& getModel('member'); - $member_info = $oMemberModel->getMemberInfoByMemberSrl($writer_member_srl); - if($member_info->is_admin == "Y") - { - return; - } - } - $security_msg = "

".Context::getLang('security_warning_embed')."

"; - $content = preg_replace('/]+>(.*?<\/object>)?/is', $security_msg, $content); - $content = preg_replace('/]+>(\s*<\/embed>)?/is', $security_msg, $content); - $content = preg_replace('/]+editor_component="multimedia_link"[^>]*>(\s*<\/img>)?/is', $security_msg, $content); - } - - return; - } - - function requirePear() - { - if(version_compare(PHP_VERSION, "5.3.0") < 0) - { - set_include_path(_XE_PATH_."libs/PEAR"); - } - else - { - set_include_path(_XE_PATH_."libs/PEAR.1.9"); - - } - } - -?> + '[GMT -12:00] Baker Island Time', + '-1100' => '[GMT -11:00] Niue Time, Samoa Standard Time', + '-1000' => '[GMT -10:00] Hawaii-Aleutian Standard Time, Cook Island Time', + '-0930' => '[GMT -09:30] Marquesas Islands Time', + '-0900' => '[GMT -09:00] Alaska Standard Time, Gambier Island Time', + '-0800' => '[GMT -08:00] Pacific Standard Time', + '-0700' => '[GMT -07:00] Mountain Standard Time', + '-0600' => '[GMT -06:00] Central Standard Time', + '-0500' => '[GMT -05:00] Eastern Standard Time', + '-0400' => '[GMT -04:00] Atlantic Standard Time', + '-0330' => '[GMT -03:30] Newfoundland Standard Time', + '-0300' => '[GMT -03:00] Amazon Standard Time, Central Greenland Time', + '-0200' => '[GMT -02:00] Fernando de Noronha Time, South Georgia & the South Sandwich Islands Time', + '-0100' => '[GMT -01:00] Azores Standard Time, Cape Verde Time, Eastern Greenland Time', + '0000' => '[GMT 00:00] Western European Time, Greenwich Mean Time', + '+0100' => '[GMT +01:00] Central European Time, West African Time', + '+0200' => '[GMT +02:00] Eastern European Time, Central African Time', + '+0300' => '[GMT +03:00] Moscow Standard Time, Eastern African Time', + '+0330' => '[GMT +03:30] Iran Standard Time', + '+0400' => '[GMT +04:00] Gulf Standard Time, Samara Standard Time', + '+0430' => '[GMT +04:30] Afghanistan Time', + '+0500' => '[GMT +05:00] Pakistan Standard Time, Yekaterinburg Standard Time', + '+0530' => '[GMT +05:30] Indian Standard Time, Sri Lanka Time', + '+0545' => '[GMT +05:45] Nepal Time', + '+0600' => '[GMT +06:00] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time', + '+0630' => '[GMT +06:30] Cocos Islands Time, Myanmar Time', + '+0700' => '[GMT +07:00] Indochina Time, Krasnoyarsk Standard Time', + '+0800' => '[GMT +08:00] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time', + '+0845' => '[GMT +08:45] Southeastern Western Australia Standard Time', + '+0900' => '[GMT +09:00] Korea Standard Time, Japan Standard Time, China Standard Time', + '+0930' => '[GMT +09:30] Australian Central Standard Time', + '+1000' => '[GMT +10:00] Australian Eastern Standard Time, Vladivostok Standard Time', + '+1030' => '[GMT +10:30] Lord Howe Standard Time', + '+1100' => '[GMT +11:00] Solomon Island Time, Magadan Standard Time', + '+1130' => '[GMT +11:30] Norfolk Island Time', + '+1200' => '[GMT +12:00] New Zealand Time, Fiji Time, Kamchatka Standard Time', + '+1245' => '[GMT +12:45] Chatham Islands Time', + '+1300' => '[GMT +13:00] Tonga Time, Phoenix Islands Time', + '+1400' => '[GMT +14:00] Line Island Time' + ) ; + + /** + * @brief ModuleHandler::getModuleObject($module_name, $type)을 쓰기 쉽게 함수로 선언 + * @param module_name 모듈이름 + * @param type disp, proc, controller, class + * @param kind admin, null + * @return module instance + **/ + function &getModule($module_name, $type = 'view', $kind = '') { + return ModuleHandler::getModuleInstance($module_name, $type, $kind); + } + + /** + * @brief module의 controller 객체 생성용 + * @param module_name 모듈이름 + * @return module controller instance + **/ + function &getController($module_name) { + return getModule($module_name, 'controller'); + } + + /** + * @brief module의 admin controller 객체 생성용 + * @param module_name 모듈이름 + * @return module admin controller instance + **/ + function &getAdminController($module_name) { + return getModule($module_name, 'controller','admin'); + } + + /** + * @brief module의 view 객체 생성용 + * @param module_name 모듈이름 + * @return module view instance + **/ + function &getView($module_name) { + return getModule($module_name, 'view'); + } + + /** + * @brief module의 admin view 객체 생성용 + * @param module_name 모듈이름 + * @return module admin view instance + **/ + function &getAdminView($module_name) { + return getModule($module_name, 'view','admin'); + } + + /** + * @brief module의 model 객체 생성용 + * @param module_name 모듈이름 + * @return module model instance + **/ + function &getModel($module_name) { + return getModule($module_name, 'model'); + } + + /** + * @brief module의 admin model 객체 생성용 + * @param module_name 모듈이름 + * @return module admin model instance + **/ + function &getAdminModel($module_name) { + return getModule($module_name, 'model','admin'); + } + + /** + * @brief module의 api 객체 생성용 + * @param module_name 모듈이름 + * @return module api class instance + **/ + function &getAPI($module_name) { + return getModule($module_name, 'api'); + } + + /** + * @brief module의 wap 객체 생성용 + * @param module_name 모듈이름 + * @return module wap class instance + **/ + function &getWAP($module_name) { + return getModule($module_name, 'wap'); + } + + /** + * @brief module의 상위 class 객체 생성용 + * @param module_name 모듈이름 + * @return module class instance + **/ + function &getClass($module_name) { + return getModule($module_name, 'class'); + } + + /** + * @brief DB::executeQuery() 의 alias + * @param query_id 쿼리 ID ( 모듈명.쿼리XML파일 ) + * @param args object 변수로 선언된 인자값 + * @return 처리결과 + **/ + function executeQuery($query_id, $args = null) { + $oDB = &DB::getInstance(); + return $oDB->executeQuery($query_id, $args); + } + + /** + * @brief DB::executeQuery() 의 결과값을 무조건 배열로 처리하도록 하는 함수 + * @param query_id 쿼리 ID ( 모듈명.쿼리XML파일 ) + * @param args object 변수로 선언된 인자값 + * @return 처리결과 + **/ + function executeQueryArray($query_id, $args = null) { + $oDB = &DB::getInstance(); + $output = $oDB->executeQuery($query_id, $args); + if(!is_array($output->data) && count($output->data) > 0){ + $output->data = array($output->data); + } + return $output; + } + + /** + * @brief DB::getNextSequence() 의 alias + * @return big int + **/ + function getNextSequence() { + $oDB = &DB::getInstance(); + return $oDB->getNextSequence(); + } + + /** + * @brief Context::getUrl()를 쓰기 쉽게 함수로 선언 + * @return string + * + * getUrl()은 현재 요청된 RequestURI에 주어진 인자의 값으로 변형하여 url을 리턴한다\n + * 1. 인자는 (key, value)... 의 형식으로 주어져야 한다.\n + * ex) getUrl('key1','val1', 'key2', '') : key1, key2를 val1과 '' 로 변형\n + * 2. 아무런 인자가 없으면 argument를 제외한 url을 리턴 + * 3. 첫 인자값이 '' 이면 RequestUri에다가 추가된 args_list로 url을 만듬 + **/ + function getUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + + if(!$num_args) return Context::getRequestUri(); + + return Context::getUrl($num_args, $args_list); + } + + function getNotEncodedUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + + if(!$num_args) return Context::getRequestUri(); + + return Context::getUrl($num_args, $args_list, null, false); + } + + /** + * @brief getUrl()의 값에 request uri를 추가하여 reutrn + * full url을 얻기 위함 + **/ + function getFullUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + $request_uri = Context::getRequestUri(); + if(!$num_args) return $request_uri; + + $url = Context::getUrl($num_args, $args_list); + if(!preg_match('/^http/i',$url)){ + preg_match('/^(http|https):\/\/([^\/]+)\//',$request_uri,$match); + return substr($match[0],0,-1).$url; + } + return $url; + } + + function getNotEncodedFullUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + $request_uri = Context::getRequestUri(); + if(!$num_args) return $request_uri; + + $url = Context::getUrl($num_args, $args_list); + if(!preg_match('/^http/i',$url)){ + preg_match('/^(http|https):\/\/([^\/]+)\//',$request_uri,$match); + $url = Context::getUrl($num_args, $args_list, null, false); + return substr($match[0],0,-1).$url; + } + return $url; + } + + /** + * @brief Context::getUrl()를 쓰기 쉽게 함수로 선언 + * @return string + * + * getSiteUrl()은 지정된 도메인에 대해 주어진 인자의 값으로 변형하여 url을 리턴한다\n + * 첫 인자는 도메인(http://등이 제외된)+path 여야 함. + **/ + function getSiteUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + + if(!$num_args) return Context::getRequestUri(); + + $domain = array_shift($args_list); + $num_args = count($args_list); + + return Context::getUrl($num_args, $args_list, $domain); + } + + function getNotEncodedSiteUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + + if(!$num_args) return Context::getRequestUri(); + + $domain = array_shift($args_list); + $num_args = count($args_list); + + return Context::getUrl($num_args, $args_list, $domain, false); + } + + /** + * @brief getSiteUrl()의 값에 request uri를 추가하여 reutrn + * full url을 얻기 위함 + **/ + function getFullSiteUrl() { + $num_args = func_num_args(); + $args_list = func_get_args(); + + $request_uri = Context::getRequestUri(); + if(!$num_args) return $request_uri; + + $domain = array_shift($args_list); + $num_args = count($args_list); + + $url = Context::getUrl($num_args, $args_list, $domain); + if(!preg_match('/^http/i',$url)){ + preg_match('/^(http|https):\/\/([^\/]+)\//',$request_uri,$match); + return substr($match[0],0,-1).$url; + } + return $url; + } + + /** + * @brief 가상사이트의 Domain이 url형식인지 site id인지 return + **/ + function isSiteID($domain) { + return preg_match('/^([a-z0-9\_]+)$/i', $domain); + } + + /** + * @brief 주어진 문자를 주어진 크기로 자르고 잘라졌을 경우 주어진 꼬리를 담 + * @param string 자를 원 문자열 + * @param cut_size 주어진 원 문자열을 자를 크기 + * @param tail 잘라졌을 경우 문자열의 제일 뒤에 붙을 꼬리 + * @return string + **/ + function cut_str($string,$cut_size=0,$tail = '...') { + if($cut_size<1 || !$string) return $string; + + $chars = Array(12, 4, 3, 5, 7, 7, 11, 8, 4, 5, 5, 6, 6, 4, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 8, 6, 8, 6, 10, 8, 8, 9, 8, 8, 7, 9, 8, 3, 6, 7, 7, 11, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 8, 6, 11, 6, 6, 6, 4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 7, 3, 7, 6, 10, 6, 6, 7, 6, 6, 6, 9); + $max_width = $cut_size*$chars[0]/2; + $char_width = 0; + + $string_length = strlen($string); + $char_count = 0; + + $idx = 0; + while($idx < $string_length && $char_count < $cut_size && $char_width <= $max_width) { + $c = ord(substr($string, $idx,1)); + $char_count++; + if($c<128) { + $char_width += (int)$chars[$c-32]; + $idx++; + } + else if (191<$c && $c < 224) { + $char_width += $chars[4]; + $idx += 2; + } + else { + $char_width += $chars[0]; + $idx += 3; + } + } + $output = substr($string,0,$idx); + if(strlen($output)<$string_length) $output .= $tail; + return $output; + } + + function zgap() { + $time_zone = $GLOBALS['_time_zone']; + if($time_zone < 0) $to = -1; else $to = 1; + $t_hour = substr($time_zone, 1, 2) * $to; + $t_min = substr($time_zone, 3, 2) * $to; + + $server_time_zone = date("O"); + if($server_time_zone < 0) $so = -1; else $so = 1; + $c_hour = substr($server_time_zone, 1, 2) * $so; + $c_min = substr($server_time_zone, 3, 2) * $so; + + $g_min = $t_min - $c_min; + $g_hour = $t_hour - $c_hour; + + $gap = $g_min*60 + $g_hour*60*60; + return $gap; + } + + /** + * @brief YYYYMMDDHHIISS 형식의 시간값을 unix time으로 변경 + * @param str YYYYMMDDHHIISS 형식의 시간값 + * @return int + **/ + function ztime($str) { + if(!$str) return; + $hour = (int)substr($str,8,2); + $min = (int)substr($str,10,2); + $sec = (int)substr($str,12,2); + $year = (int)substr($str,0,4); + $month = (int)substr($str,4,2); + $day = (int)substr($str,6,2); + if(strlen($str) <= 8) { + $gap = 0; + } else { + $gap = zgap(); + } + + return mktime($hour, $min, $sec, $month?$month:1, $day?$day:1, $year)+$gap; + } + + /** + * @brief YmdHis의 시간 형식을 지금으로 부터 몇분/몇시간전, 1일 이상 차이나면 format string return + **/ + function getTimeGap($date, $format = 'Y.m.d') { + $gap = time() - ztime($date); + + $lang_time_gap = Context::getLang('time_gap'); + if($gap<60) $buff = sprintf($lang_time_gap['min'], (int)($gap / 60)+1); + elseif($gap<60*60) $buff = sprintf($lang_time_gap['mins'], (int)($gap / 60)+1); + elseif($gap<60*60*2) $buff = sprintf($lang_time_gap['hour'], (int)($gap / 60 /60)+1); + elseif($gap<60*60*24) $buff = sprintf($lang_time_gap['hours'], (int)($gap / 60 /60)+1); + else $buff = zdate($date, $format); + return $buff; + } + + /** + * @brief 월이름을 return + **/ + function getMonthName($month, $short = true) { + $short_month = array('','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'); + $long_month = array('','January','February','March','April','May','June','July','August','September','October','November','December'); + return !$short?$long_month[$month]:$short_month[$month]; + } + + /** + * @brief YYYYMMDDHHIISS 형식의 시간값을 원하는 시간 포맷으로 변형 + * @param string|int str YYYYMMDDHHIISS 형식의 시간 값 + * @param string format php date()함수의 시간 포맷 + * @param bool conversion 언어에 따라 날짜 포맷의 자동변환 여부 + * @return string + **/ + function zdate($str, $format = 'Y-m-d H:i:s', $conversion=true) { + // 대상 시간이 없으면 null return + if(!$str) return; + + // 언어권에 따라서 지정된 날짜 포맷을 변경 + if($conversion == true) { + switch(Context::getLangType()) { + case 'en' : + case 'es' : + if($format == 'Y-m-d') $format = 'M d, Y'; + elseif($format == 'Y-m-d H:i:s') $format = 'M d, Y H:i:s'; + elseif($format == 'Y-m-d H:i') $format = 'M d, Y H:i'; + break; + case 'vi' : + if($format == 'Y-m-d') $format = 'd-m-Y'; + elseif($format == 'Y-m-d H:i:s') $format = 'H:i:s d-m-Y'; + elseif($format == 'Y-m-d H:i') $format = 'H:i d-m-Y'; + break; + + } + } + + // 년도가 1970년 이전이면 별도 처리 + if((int)substr($str,0,4) < 1970) { + $hour = (int)substr($str,8,2); + $min = (int)substr($str,10,2); + $sec = (int)substr($str,12,2); + $year = (int)substr($str,0,4); + $month = (int)substr($str,4,2); + $day = (int)substr($str,6,2); + $string = str_replace( + array('Y','m','d','H','h','i','s','a','M', 'F'), + array($year,$month,$day,$hour,$hour/12,$min,$sec,($hour <= 12) ? 'am' : 'pm',getMonthName($month), getMonthName($month,false)), + $format + ); + } else { + // 1970년 이후라면 ztime()함수로 unixtime을 구하고 date함수로 처리 + $string = date($format, ztime($str)); + } + + // 요일, am/pm을 각 언어에 맞게 변경 + $unit_week = Context::getLang('unit_week'); + $unit_meridiem = Context::getLang('unit_meridiem'); + $string = str_replace(array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'),$unit_week, $string); + $string = str_replace(array('am','pm','AM','PM'), $unit_meridiem, $string); + return $string; + } + + /** + * @brief prints debug messages + * @param debug_output target object to be printed + * @param display_line boolean flag whether to print seperator (default:true) + * @return none + * + * ./files/_debug_message.php 파일에 $buff 내용을 출력한다. + * tail -f ./files/_debug_message.php 하여 계속 살펴 볼 수 있다 + **/ + function debugPrint($debug_output = null, $display_option = true) { + if(!(__DEBUG__ & 1)) return; + + static $firephp; + $bt = debug_backtrace(); + if(is_array($bt)) $first = array_shift($bt); + $file_name = array_pop(explode(DIRECTORY_SEPARATOR, $first['file'])); + $line_num = $first['line']; + + if(__DEBUG_OUTPUT__ == 2 && version_compare(PHP_VERSION, '6.0.0') === -1) { + if(!isset($firephp)) $firephp = FirePHP::getInstance(true); + if(function_exists("memory_get_usage")) + { + $label = sprintf('[%s:%d] (m:%s)', $file_name, $line_num, FileHandler::filesize(memory_get_usage())); + } + else + { + $label = sprintf('[%s:%d] ', $file_name, $line_num); + } + + // FirePHP 옵션 체크 + if($display_option === 'TABLE') $label = $display_option; + + // __DEBUG_PROTECT__ 옵션으로 지정된 IP와 접근 IP가 동일한지 체크 + if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { + $debug_output = 'The IP address is not allowed. Change the value of __DEBUG_PROTECT_IP__ into your IP address in config/config.user.inc.php or config/config.inc.php'; + $label = null; + } + + $firephp->fb($debug_output, $label); + + } else { + if(__DEBUG_PROTECT__ === 1 && __DEBUG_PROTECT_IP__ != $_SERVER['REMOTE_ADDR']) { + return; + } + $debug_file = _XE_PATH_.'files/_debug_message.php'; + if(function_exists("memory_get_usage")) + { + $debug_output = sprintf("[%s %s:%d] - mem(%s)\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, FileHandler::filesize(memory_get_usage()), print_r($debug_output, true)); + } + else + { + $debug_output = sprintf("[%s %s:%d]\n%s\n", date('Y-m-d H:i:s'), $file_name, $line_num, print_r($debug_output, true)); + } + + if($display_option === true) $debug_output = str_repeat('=', 40)."\n".$debug_output.str_repeat('-', 40); + $debug_output = "\n\n"; + + if(@!$fp = fopen($debug_file, 'a')) return; + fwrite($fp, $debug_output); + fclose($fp); + } + } + + + /** + * @brief microtime() return + * @return float + **/ + function getMicroTime() { + list($time1, $time2) = explode(' ', microtime()); + return (float)$time1 + (float)$time2; + } + + /** + * @brief 첫번째 인자로 오는 object var에서 2번째 object의 var들을 제거 + * @param target_obj 원 object + * @param del_obj 원 object의 vars에서 del_obj의 vars를 제거한다 + * @return object + **/ + function delObjectVars($target_obj, $del_obj) { + if(!is_object($target_obj)) return; + if(!is_object($del_obj)) return; + + $target_vars = get_object_vars($target_obj); + $del_vars = get_object_vars($del_obj); + + $target = array_keys($target_vars); + $del = array_keys($del_vars); + if(!count($target)||!count($del)) return $target_obj; + + $return_obj = NULL; + + $target_count = count($target); + for($i = 0; $i < $target_count; $i++) { + $target_key = $target[$i]; + if(!in_array($target_key, $del)) $return_obj->{$target_key} = $target_obj->{$target_key}; + } + + return $return_obj; + } + + /** + * @brief php5 이상에서 error_handing을 debugPrint로 변경 + * @param errno + * @param errstr + * @return file + * @return line + **/ + function handleError($errno, $errstr, $file, $line) { + if(!__DEBUG__) return; + $errors = array(E_USER_ERROR, E_ERROR, E_PARSE); + if(!in_array($errno, $errors)) return; + + $output = sprintf("Fatal error : %s - %d", $file, $line); + $output .= sprintf("%d - %s", $errno, $errstr); + + debugPrint($output); + } + + /** + * @brief 주어진 숫자를 주어진 크기로 recursive하게 잘라줌 + * @param no 주어진 숫자 + * @param size 잘라낼 크기 + **/ + function getNumberingPath($no, $size=3) { + $mod = pow(10, $size); + $output = sprintf('%0'.$size.'d/', $no%$mod); + if($no >= $mod) $output .= getNumberingPath((int)$no/$mod, $size); + return $output; + } + + /** + * @brief 한글이 들어간 url의 decode + **/ + function url_decode($str) { + return preg_replace('/%u([[:alnum:]]{4})/', '&#x\\1;',$str); + } + + /** + * @brief 해킹 시도로 의심되는 코드들을 미리 차단 + **/ + function removeHackTag($content) { + // 특정 태그들을 일반 문자로 변경 + $content = preg_replace('/<(\/?)(iframe|script|meta|style|applet|link|base|html|body)/is', '<$1$2', $content); + + /** + * 이미지나 동영상등의 태그에서 src에 관리자 세션을 악용하는 코드를 제거 + * - 취약점 제보 : 김상원님 + **/ + $content = preg_replace_callback("!<([a-z]+)(.*?)>!is", removeSrcHack, $content); + + return $content; + } + + + function removeSrcHack($matches) { + $tag = strtolower(trim($matches[1])); + + $buff = trim(preg_replace('/(\/>|>)/','/>',$matches[0])); + $buff = str_replace(array('&','&'),array('&','&'),$buff); + $buff = preg_replace_callback('/([^=^"^ ]*)=([^ ^>]*)/i', 'fixQuotation', $buff); + + $oXmlParser = new XmlParser(); + $xml_doc = $oXmlParser->parse($buff); + if(!$xml_doc) return sprintf("<%s>", $tag); + + // src값에 module=admin이라는 값이 입력되어 있으면 이 값을 무효화 시킴 + $src = $xml_doc->{$tag}->attrs->src; + $dynsrc = $xml_doc->{$tag}->attrs->dynsrc; + $lowsrc = $xml_doc->{$tag}->attrs->lowsrc; + $href = $xml_doc->{$tag}->attrs->href; + $data = $xml_doc->{$tag}->attrs->data; + $background = $xml_doc->{$tag}->attrs->background; + $style = $xml_doc->{$tag}->attrs->style; + if($style) { + $url = preg_match_all('/url\s*\(([^\)]+)\)/is', $style, $matches2); + if(count($matches2[0])) + { + foreach($matches2[1] as $target) + { + if(_isHackedSrc($target)) return sprintf("<%s>",$tag); + } + } + } + if(_isHackedSrc($src) || _isHackedSrc($dynsrc) || _isHackedSrc($lowsrc) || _isHackedSrc($href) || _isHackedSrc($data) || _isHackedSrc($background) || _isHackedSrcExp($style)) return sprintf("<%s>",$tag); + + return $buff; + } + + function _isHackedSrcExp($style) { + if(!$style) return false; + if(preg_match('/((\/\*)|(\*\/)|(\\n)|(expression))/i', $style)) return true; + return false; + } + + function _isHackedSrc($src) { + if(!$src) return false; + if($src) { + $target = trim($src); + if(preg_match('/(\s|(\&\#)|(script:))/i', $target)) return true; + if(preg_match('/data:/i', $target)) return true; + + $url_info = parse_url($src); + $query = $url_info['query']; + if(!trim($query)) return false; + $query = str_replace("&","&",$query); + $queries = explode('&', $query); + $cnt = count($queries); + for($i=0;$i<$cnt;$i++) { + $tmp_str = strtolower(trim($queries[$i])); + $pos = strpos($tmp_str,'='); + if($pos === false) continue; + $key = strtolower(trim(substr($tmp_str, 0, $pos))); + $val = strtolower(trim(substr($tmp_str,$pos+1))); + if( ($key=='module'&&$val=='admin') || ($key=='act'&&preg_match('/admin/i',$val)) ) return true; + } + } + return false; + } + + /** + * @brief attribute의 value를 " 로 둘러싸도록 처리하는 함수 + **/ + function fixQuotation($matches) { + $key = $matches[1]; + $val = $matches[2]; + + if(substr($val,0,1)!='"'){ + if(substr($val,-1)=='/'){ + $val = '"'.substr($val,0,-1).'" /'; + }else{ + $val = '"'.$val.'"'; + } + } + + // attribute on* remove + if(preg_match('/^on(click|load|unload|blur|dbclick|focus|resize|keypress|keyup|keydown|mouseover|mouseout|mouseup|select|change|error)/',preg_replace('/[^a-zA-Z_]/','',$key))) return ''; + + $output = sprintf('%s=%s', $key, $val); + + return $output; + } + + // hexa값을 RGB로 변환 + if(!function_exists('hexrgb')) { + function hexrgb($hexstr) { + $int = hexdec($hexstr); + + return array('red' => 0xFF & ($int >> 0x10), + 'green' => 0xFF & ($int >> 0x8), + 'blue' => 0xFF & $int); + } + + } + + /** + * @brief mysql old_password 의 php 구현 함수 + * 제로보드4나 기타 mysql4.1 이전의 old_password()함수를 쓴 데이터의 사용을 위해서 + * mysql의 password.c 소스 참조해서 구현함 + **/ + function mysql_pre4_hash_password($password) { + $nr = 1345345333; + $add = 7; + $nr2 = 0x12345671; + + settype($password, "string"); + + for ($i=0; $i>6)+192).chr(($num&63)+128); + if($num<65536)return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128); + if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128); + return ''; + } + + + function detectUTF8($string, $return_convert = false, $urldecode = true) { + if($urldecode) $string = urldecode($string); + + $sample = iconv('utf-8', 'utf-8', $string); + $is_utf8 = (md5($sample) == md5($string)); + + if(!$urldecode) $string = urldecode($string); + + if($return_convert) return ($is_utf8) ? $string : iconv('euc-kr', 'utf-8', $string); + + return $is_utf8; + } + + + function json_encode2($data) { + switch (gettype($data)) { + case 'boolean': + return $data?'true':'false'; + case 'integer': + case 'double': + return $data; + case 'string': + return '"'.strtr($data, array('\\'=>'\\\\','"'=>'\\"')).'"'; + case 'object': + $data = get_object_vars($data); + case 'array': + $rel = false; // relative array? + $key = array_keys($data); + foreach ($key as $v) { + if (!is_int($v)) { + $rel = true; + break; + } + } + + $arr = array(); + foreach ($data as $k=>$v) { + $arr[] = ($rel?'"'.strtr($k, array('\\'=>'\\\\','"'=>'\\"')).'":':'').json_encode2($v); + } + + return $rel?'{'.join(',', $arr).'}':'['.join(',', $arr).']'; + default: + return '""'; + } + } + + + function isCrawler($agent = null) { + if(!$agent) $agent = $_SERVER['HTTP_USER_AGENT']; + $check_agent = array('bot', 'spider', 'google', 'yahoo', 'daum', 'teoma', 'fish', 'hanrss', 'facebook'); + $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; + } + + function stripEmbedTagForAdmin(&$content, $writer_member_srl) + { + if(!Context::get('is_logged')) return; + $oModuleModel = &getModel('module'); + $logged_info = Context::get('logged_info'); + + if($writer_member_srl != $logged_info->member_srl && ($logged_info->is_admin == "Y" || $oModuleModel->isSiteAdmin($logged_info)) ) + { + if($writer_member_srl) + { + $oMemberModel =& getModel('member'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($writer_member_srl); + if($member_info->is_admin == "Y") + { + return; + } + } + $security_msg = "

".Context::getLang('security_warning_embed')."

"; + $content = preg_replace('/]+>(.*?<\/object>)?/is', $security_msg, $content); + $content = preg_replace('/]+>(\s*<\/embed>)?/is', $security_msg, $content); + $content = preg_replace('/]+editor_component="multimedia_link"[^>]*>(\s*<\/img>)?/is', $security_msg, $content); + } + + return; + } + + function requirePear() + { + if(version_compare(PHP_VERSION, "5.3.0") < 0) + { + set_include_path(_XE_PATH_."libs/PEAR"); + } + else + { + set_include_path(_XE_PATH_."libs/PEAR.1.9"); + + } + } + +?> diff --git a/index.php b/index.php index 94bb2b26f..b25112558 100644 --- a/index.php +++ b/index.php @@ -1,61 +1,61 @@ - - * @brief 시작 페이지 - * - * Request Argument에서 mid, act로 module 객체를 찾아서 생성하고 \n - * 모듈 정보를 세팅함 - * - * @mainpage XpressEngine - * @section intro 소개 - * XE 는 오픈 프로젝트로 개발되는 오픈 소스입니다.\n - * 자세한 내용은 아래 링크를 참조하세요. - * - 공식홈페이지 : http://www.xpressengine.com - * - SVN Repository : http://svn.xpressengine.net/xe - * \n - * "XpressEngine (XE)" is free software; you can redistribute it and/or \n - * modify it under the terms of the GNU Lesser General Public \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 - * 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. - * \n - * 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 - * - **/ - - /** - * @brief 기본적인 상수 선언, 웹에서 직접 호출되는 것을 막기 위해 체크하는 상수 선언 - **/ - define('__ZBXE__', true); - - /** - * @brief 필요한 설정 파일들을 include - **/ - require('./config/config.inc.php'); - - /** - * @brief Context 객체를 생성하여 초기화 - * 모든 Request Argument/ 환경변수등을 세팅 - **/ - $oContext = &Context::getInstance(); - $oContext->init(); - - /** - * @brief default_url 이 설정되어 있고 현재 url이 default_url과 다르면 SSO인증을 위한 rediret 시도 후 모듈 동작 - **/ - if($oContext->checkSSO()) { - $oModuleHandler = new ModuleHandler(); - if($oModuleHandler->init()) { - $oModule = &$oModuleHandler->procModule(); - $oModuleHandler->displayContent($oModule); - } - } - $oContext->close(); -?> +init(); + + /** + * @brief default_url 이 설정되어 있고 현재 url이 default_url과 다르면 SSO인증을 위한 rediret 시도 후 모듈 동작 + **/ + if($oContext->checkSSO()) { + $oModuleHandler = new ModuleHandler(); + if($oModuleHandler->init()) { + $oModule = &$oModuleHandler->procModule(); + $oModuleHandler->displayContent($oModule); + } + } + $oContext->close(); +?> diff --git a/layouts/xe_official/conf/info.xml b/layouts/xe_official/conf/info.xml index de86b4e29..e6e87aaa7 100644 --- a/layouts/xe_official/conf/info.xml +++ b/layouts/xe_official/conf/info.xml @@ -11,72 +11,54 @@ Giao diện chính thức của XE XE 공식 사이트 레이아웃입니다. - 디자인 : 이소라 - 퍼블리싱 : 정찬명 - 레이아웃 제작 : zero + 제작 : NHN XEの公式サイトのレイアウトです。 - デザイン:イ ソラ - パブリシング:ジョン チャンミョン - レイアウト作成:Zero + 제작 : NHN This layout is the XE Official website layout. - Designer : So-Ra Lee - HTML/CSS : Chan-Myung Jeong - Layout producer : zero + 제작 : NHN Dieses Layout ist das XE Offizielle Website-Layout. - Designer: So-Ra Lee - HTML / CSS: Chan-Myung Jeong - Layout Hersteller: Zero + 제작 : NHN Этот формат является XE Официальный сайт компоновку. - Дизайнер: So-Ra Lee - HTML / CSS: Chan-Myung Jeong - Макет производителя: ноль + 제작 : NHN Este diseño is el diseño oficial de la página web de Zerobard XE. - Deseñador : So-Ra Lee - HTML/CSS : Chan-Myung Jeong - Productor del diseño : zero + 제작 : NHN XE官方网站布局。 - 设计 : So-Ra Lee - HTML/CSS : Chan-Myung Jeong - 布局 : zero + 제작 : NHN XE官方網站版面。 - 設計 : So-Ra Lee - HTML/CSS : Chan-Myung Jeong - 版面設計 : zero + 제작 : NHN Đây là giao diện chính thức của XE. - Thiết kế bởi: So-Ra Lee - HTML/CSS : Chan-Myung Jeong - Quản lý : zero + 제작 : NHN 0.1 2007-08-01 - http://blog.nzeo.com + http://xpressengine.com/ - - zero - zero - zero - zero - zero - zero - zero - zero - zero + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN diff --git a/layouts/xe_official/css/black.css b/layouts/xe_official/css/black.css index 8146cf5f4..32e524e3a 100644 --- a/layouts/xe_official/css/black.css +++ b/layouts/xe_official/css/black.css @@ -1,8 +1,5 @@ @charset "utf-8"; -/* -NHN UIT Lab. WebStandardization Team (http://html.nhndesign.com/) -Jeong, Chan Myeong 070601~070630 -*/ +/* NHN (developers@xpressengine.com) */ /* Black Skin - Start */ #selectLang { margin:0; padding:0; } diff --git a/layouts/xe_official/css/default.css b/layouts/xe_official/css/default.css index 11aca8a41..e7e52300a 100644 --- a/layouts/xe_official/css/default.css +++ b/layouts/xe_official/css/default.css @@ -1,8 +1,5 @@ @charset "utf-8"; -/* -NHN UIT Lab. WebStandardization Team (http://html.nhndesign.com/) -Jeong, Chan Myeong 070601~070630 -*/ +/* NHN (developers@xpressengine.com) */ /* Default Skin - Start */ #selectLang { margin:0; padding:0; } diff --git a/layouts/xe_official/css/white.css b/layouts/xe_official/css/white.css index 95071a602..1d8b11ade 100644 --- a/layouts/xe_official/css/white.css +++ b/layouts/xe_official/css/white.css @@ -1,91 +1,88 @@ -@charset "utf-8"; -/* -NHN UIT Lab. WebStandardization Team (http://html.nhndesign.com/) -Jeong, Chan Myeong 070601~070630 -*/ - -/* White Skin - Start */ -#selectLang { margin:0; padding:0; } -#gnb { margin:0; padding:0; } -#lnb { margin:0; padding:0; } -#lnb ul { margin:0; padding:0; } - -/* Site Layout - Body Wrap */ -body { background:#ffffff;} -#bodyWrap { position:relative; width:980px; margin:0 auto; padding:1.5em 0 0 0;} - -/* Site Layout - Header */ -#header { position:relative; width:978px; height:114px; border-top:6px solid #323232; border-left:1px solid #d9d9d9; border-right:1px solid #d9d9d9; background:url(../images/white/bgHeader.png) no-repeat right bottom; margin-bottom:10px; z-index:99;} -#header h1 { position:absolute; top:26px; left:25px;} -#language { position:absolute; top:12px; right:19px; z-index:100;} -#language strong { color:#5c5c5c; font:.75em Tahoma; margin-right:3px;} -#language a img { vertical-align:-5px;} -#language ul { position:absolute; top:15px; right:0px; display:none; border:1px solid #d9d9d9; background:#ffffff;} -#language ul li { list-style:none; } -#language ul li a { display:block; width:61px; padding:3px 8px; font:9px Tahoma; color:#5c5c5c; text-decoration:none;} -#language ul li a:hover { background:#f4f4f4;} - -#it_search_form { position:absolute; top:50px; right:15px;} -#it_search_form .input { border:1px solid #d9d9d9; height:17px; width:120px; color:#888888; font-size:.9em;} -#it_search_form .submit_button { width:1px; height:1px; visibility:hidden; } - -#gnb { position:absolute; top:76px; left:0; height:38px; overflow:hidden; white-space:nowrap; margin-bottom:10px;} -#gnb li { list-style:none; float:left; background:url(../images/white/bgGnbVr.gif) no-repeat left center; padding-left:2px; position:relative; left:-2px; white-space:nowrap;} -#gnb li a { display:block; float:left; padding:13px 15px 0 15px; height:25px; color:#727272; white-space:nowrap; text-decoration:none; } -#gnb li a:hover, -#gnb li a:focus { color:#000000;} -#gnb li.on a { font-weight:bold; color:#3f3f3f; background:url(../images/white/bgGnbOn.gif) no-repeat center top;} - -#isSearch { position:absolute; top:48px; right:15px; width:214px; text-align:right;} -#isSearch .searchOrder { display:none;} -#isSearch .checked { position:absolute; left:0; top:0; text-align:left; display:block; padding:5px 0 0 5px; width:64px; height:14px; background:url(../images/white/bgSearchTerm.gif) no-repeat; font:11px "돋움", Dotum, "굴림", Gulim, AppleGothic, Sans-serif; color:#5c5c5c; line-height:normal;} -#isSearch ul { display:none; position:absolute; left:0; top:18px; padding:2px 0 3px 0; text-align:left; border:1px solid #b2b2b2; background:#ffffff; overflow:hidden;} -#isSearch ul li { width:67px; height:18px; list-style:none;} -#isSearch ul li input { display:none;} -#isSearch ul li label { display:block; padding:4px 0 0 4px; width:63px; height:15px; font:11px "돋움", Dotum, "굴림", Gulim, AppleGothic, Sans-serif; color:#5c5c5c;} -#isSearch ul li label.on { background:#ededed; } -#isSearch ul li label:hover, -#isSearch ul li label:focus { background:#ededed;} -#isSearch .inputText { vertical-align:middle; position:relative; top:0; _top:-1px; left:1px; padding:3px 3px 1px 3px; width:94px; height:13px; color:#000000; border:1px solid #B0B0AF; background-color:#FFFFFF; } -#isSearch .inputText:hover, -#isSearch .inputText:focus { border:1px solid #8E8E8D; background-color:#FFFFFF; } -*:first-child+html #isSearch .inputText { position:relative; top:-1px;} -#isSearch .submit { vertical-align:middle; _position:relative; _top:-1px;} -*:first-child+html #isSearch .submit { position:relative; top:-1px;} - -/* Site Layout - Content Body */ -#contentBody { position:relative; width:980px; padding-bottom:30px; overflow:hidden; background:url(../images/white/bgContentBody.gif) repeat-y left top; border-bottom:1px solid #dddddd;} - -/* Site Layout - Column Left */ -#columnLeft { position:relative; width:201px; float:left;} -#columnLeft .mask { width:201px; height:5px; background:#ffffff; display:block;} - -#lnb { border-top:1px solid #dddddd; padding:4px 5px; width:190px;} -#lnb li { list-style:none; padding-bottom:4px;} -#lnb li a { padding:6px 5px 6px 13px; width:170px; display:block; border:1px solid #e8e8e8; background:url(../images/white/bgLnbOff.gif) repeat-x; color:#3e3e3e; position:relative; z-index:99; text-decoration:none;} -#lnb li a:hover, -#lnb li a:focus { color:#ffffff; background:#de4332; border:1px solid #de4332;} -#lnb li.on a { color:#ffffff; background:#de4332; border:1px solid #de4332;} -#lnb li.on a:hover, -#lnb li.on a:focus { font-weight:bold;} -#lnb li ul { display:block; position:relative; width:184px; padding:0 3px; position:relative; border-top:1px solid #ffffff; overflow:hidden;} -#lnb li.on ul { display:block;} -#lnb li ul li { padding:0; border-top:1px solid #f2f2f2; position:relative; top:-1px;} -#lnb li ul li a { padding:6px 5px 6px 10px; width:169px; color:#818181 !important; border:none; background:none !important; border:none !important;} -#lnb li ul li a:hover, -#lnb li ul li a:focus { font-weight:normal !important; color:#de4332 !important;} -#lnb li.on ul li.on a { color:#ff1a00 !important; font-weight:bold !important; background:url(../images/white/bulletLnb.gif) no-repeat 175px center !important;} - -/* Site Layout - Column Right */ -#columnRight { width:770px; float:right; overflow:hidden;} -#visualArea { width:770px; height:200px; background:#f5f5f5; margin-bottom:2.5em; position:relative; left:-15px; margin-right:-15px;} -#content { width:100%; overflow:hidden;} - -/* Site Layout - Footer */ -#footer { margin:0; padding:0; border-top:3px solid #f4f4f4; text-align:center; padding:2em 0 4em; clear:both;} -#footer li { display:inline; padding:0 .6em 0 1em; background:url(../images/white/vrType1.gif) no-repeat left center;} -#footer li.first-child { background:none;} -#footer li a { color:#999999; font:.9em "돋움", Dotum, "굴림", Gulim, AppleGothic, Sans-serif;} -#footer li address { display:inline; } - -/* White Skin - End */ +@charset "utf-8"; +/* NHN (developers@xpressengine.com) */ + +/* White Skin - Start */ +#selectLang { margin:0; padding:0; } +#gnb { margin:0; padding:0; } +#lnb { margin:0; padding:0; } +#lnb ul { margin:0; padding:0; } + +/* Site Layout - Body Wrap */ +body { background:#ffffff;} +#bodyWrap { position:relative; width:980px; margin:0 auto; padding:1.5em 0 0 0;} + +/* Site Layout - Header */ +#header { position:relative; width:978px; height:114px; border-top:6px solid #323232; border-left:1px solid #d9d9d9; border-right:1px solid #d9d9d9; background:url(../images/white/bgHeader.png) no-repeat right bottom; margin-bottom:10px; z-index:99;} +#header h1 { position:absolute; top:26px; left:25px;} +#language { position:absolute; top:12px; right:19px; z-index:100;} +#language strong { color:#5c5c5c; font:.75em Tahoma; margin-right:3px;} +#language a img { vertical-align:-5px;} +#language ul { position:absolute; top:15px; right:0px; display:none; border:1px solid #d9d9d9; background:#ffffff;} +#language ul li { list-style:none; } +#language ul li a { display:block; width:61px; padding:3px 8px; font:9px Tahoma; color:#5c5c5c; text-decoration:none;} +#language ul li a:hover { background:#f4f4f4;} + +#it_search_form { position:absolute; top:50px; right:15px;} +#it_search_form .input { border:1px solid #d9d9d9; height:17px; width:120px; color:#888888; font-size:.9em;} +#it_search_form .submit_button { width:1px; height:1px; visibility:hidden; } + +#gnb { position:absolute; top:76px; left:0; height:38px; overflow:hidden; white-space:nowrap; margin-bottom:10px;} +#gnb li { list-style:none; float:left; background:url(../images/white/bgGnbVr.gif) no-repeat left center; padding-left:2px; position:relative; left:-2px; white-space:nowrap;} +#gnb li a { display:block; float:left; padding:13px 15px 0 15px; height:25px; color:#727272; white-space:nowrap; text-decoration:none; } +#gnb li a:hover, +#gnb li a:focus { color:#000000;} +#gnb li.on a { font-weight:bold; color:#3f3f3f; background:url(../images/white/bgGnbOn.gif) no-repeat center top;} + +#isSearch { position:absolute; top:48px; right:15px; width:214px; text-align:right;} +#isSearch .searchOrder { display:none;} +#isSearch .checked { position:absolute; left:0; top:0; text-align:left; display:block; padding:5px 0 0 5px; width:64px; height:14px; background:url(../images/white/bgSearchTerm.gif) no-repeat; font:11px "돋움", Dotum, "굴림", Gulim, AppleGothic, Sans-serif; color:#5c5c5c; line-height:normal;} +#isSearch ul { display:none; position:absolute; left:0; top:18px; padding:2px 0 3px 0; text-align:left; border:1px solid #b2b2b2; background:#ffffff; overflow:hidden;} +#isSearch ul li { width:67px; height:18px; list-style:none;} +#isSearch ul li input { display:none;} +#isSearch ul li label { display:block; padding:4px 0 0 4px; width:63px; height:15px; font:11px "돋움", Dotum, "굴림", Gulim, AppleGothic, Sans-serif; color:#5c5c5c;} +#isSearch ul li label.on { background:#ededed; } +#isSearch ul li label:hover, +#isSearch ul li label:focus { background:#ededed;} +#isSearch .inputText { vertical-align:middle; position:relative; top:0; _top:-1px; left:1px; padding:3px 3px 1px 3px; width:94px; height:13px; color:#000000; border:1px solid #B0B0AF; background-color:#FFFFFF; } +#isSearch .inputText:hover, +#isSearch .inputText:focus { border:1px solid #8E8E8D; background-color:#FFFFFF; } +*:first-child+html #isSearch .inputText { position:relative; top:-1px;} +#isSearch .submit { vertical-align:middle; _position:relative; _top:-1px;} +*:first-child+html #isSearch .submit { position:relative; top:-1px;} + +/* Site Layout - Content Body */ +#contentBody { position:relative; width:980px; padding-bottom:30px; overflow:hidden; background:url(../images/white/bgContentBody.gif) repeat-y left top; border-bottom:1px solid #dddddd;} + +/* Site Layout - Column Left */ +#columnLeft { position:relative; width:201px; float:left;} +#columnLeft .mask { width:201px; height:5px; background:#ffffff; display:block;} + +#lnb { border-top:1px solid #dddddd; padding:4px 5px; width:190px;} +#lnb li { list-style:none; padding-bottom:4px;} +#lnb li a { padding:6px 5px 6px 13px; width:170px; display:block; border:1px solid #e8e8e8; background:url(../images/white/bgLnbOff.gif) repeat-x; color:#3e3e3e; position:relative; z-index:99; text-decoration:none;} +#lnb li a:hover, +#lnb li a:focus { color:#ffffff; background:#de4332; border:1px solid #de4332;} +#lnb li.on a { color:#ffffff; background:#de4332; border:1px solid #de4332;} +#lnb li.on a:hover, +#lnb li.on a:focus { font-weight:bold;} +#lnb li ul { display:block; position:relative; width:184px; padding:0 3px; position:relative; border-top:1px solid #ffffff; overflow:hidden;} +#lnb li.on ul { display:block;} +#lnb li ul li { padding:0; border-top:1px solid #f2f2f2; position:relative; top:-1px;} +#lnb li ul li a { padding:6px 5px 6px 10px; width:169px; color:#818181 !important; border:none; background:none !important; border:none !important;} +#lnb li ul li a:hover, +#lnb li ul li a:focus { font-weight:normal !important; color:#de4332 !important;} +#lnb li.on ul li.on a { color:#ff1a00 !important; font-weight:bold !important; background:url(../images/white/bulletLnb.gif) no-repeat 175px center !important;} + +/* Site Layout - Column Right */ +#columnRight { width:770px; float:right; overflow:hidden;} +#visualArea { width:770px; height:200px; background:#f5f5f5; margin-bottom:2.5em; position:relative; left:-15px; margin-right:-15px;} +#content { width:100%; overflow:hidden;} + +/* Site Layout - Footer */ +#footer { margin:0; padding:0; border-top:3px solid #f4f4f4; text-align:center; padding:2em 0 4em; clear:both;} +#footer li { display:inline; padding:0 .6em 0 1em; background:url(../images/white/vrType1.gif) no-repeat left center;} +#footer li.first-child { background:none;} +#footer li a { color:#999999; font:.9em "돋움", Dotum, "굴림", Gulim, AppleGothic, Sans-serif;} +#footer li address { display:inline; } + +/* White Skin - End */ diff --git a/m.layouts/default/conf/info.xml b/m.layouts/default/conf/info.xml index d71695fb2..c26ef90d4 100644 --- a/m.layouts/default/conf/info.xml +++ b/m.layouts/default/conf/info.xml @@ -6,33 +6,29 @@ XE Mobile 官方版面 XE 공식 모바일 레이아웃입니다. - 디자인, 퍼블리싱 : 전영선, 정찬명 - 레이아웃 제작 : haneul + NHN (developers@xpressengine.com) This layout is the XE Official website layout. - Design, HTML/CSS : Jeon Young-Seon, Jeong Chan-Myeong - Layout producer : haneul + NHN (developers@xpressengine.com) 官方移动版布局。 - Design, HTML/CSS : Jeon Young-Seon, Jeong Chan-Myeong - Layout producer : haneul + NHN (developers@xpressengine.com) XE Mobile 官方網站版面。 - Design, HTML/CSS : Jeon Young-Seon, Jeong Chan-Myeong - Layout producer : haneul + NHN (developers@xpressengine.com) 0.1 2010-08-20 - http://xpressengine.com + http://xpressengine.com/ - - XE - XE - XE - XE + + NHN + NHN + NHN + NHN diff --git a/m.layouts/simpleGray/conf/info.xml b/m.layouts/simpleGray/conf/info.xml index c442c1c6b..a5131bb71 100644 --- a/m.layouts/simpleGray/conf/info.xml +++ b/m.layouts/simpleGray/conf/info.xml @@ -28,11 +28,11 @@ 2010-06-10 http://xpressengine.com - - XE - XE - XE - XE + + NHN + NHN + NHN + NHN diff --git a/modules/addon/addon.admin.controller.php b/modules/addon/addon.admin.controller.php index 05196a4dd..49267b4dc 100644 --- a/modules/addon/addon.admin.controller.php +++ b/modules/addon/addon.admin.controller.php @@ -1,102 +1,102 @@ -isActivatedAddon($addon, $site_module_info->site_srl, $type)) $this->doDeactivate($addon, $site_module_info->site_srl, $type); - - // 비활성화 되어 있으면 활성화 시킴 - else $this->doActivate($addon, $site_module_info->site_srl, $type); - } - - $this->makeCacheFile($site_module_info->site_srl, $type); - } - - /** - * @brief 애드온 설정 정보 입력 - **/ - function procAddonAdminSetupAddon() { - $args = Context::getRequestVars(); - $addon_name = $args->addon_name; - unset($args->module); - unset($args->act); - unset($args->addon_name); - unset($args->body); - - $site_module_info = Context::get('site_module_info'); - - $this->doSetup($addon_name, $args, $site_module_info->site_srl); - - $this->makeCacheFile($site_module_info->site_srl, "pc"); - $this->makeCacheFile($site_module_info->site_srl, "mobile"); - } - - - - /** - * @brief 애드온 추가 - * DB에 애드온을 추가함 - **/ - function doInsert($addon, $site_srl = 0) { - $args->addon = $addon; - $args->is_used = 'N'; - if(!$site_srl) return executeQuery('addon.insertAddon', $args); - $args->site_srl = $site_srl; - return executeQuery('addon.insertSiteAddon', $args); - } - - /** - * @brief 애드온 활성화 - * addons라는 테이블에 애드온의 활성화 상태를 on 시켜줌 - **/ - function doActivate($addon, $site_srl = 0, $type = "pc") { - $args->addon = $addon; - if($type == "pc") $args->is_used = 'Y'; - else $args->is_used_m = "Y"; - if(!$site_srl) return executeQuery('addon.updateAddon', $args); - $args->site_srl = $site_srl; - return executeQuery('addon.updateSiteAddon', $args); - } - - /** - * @brief 애드온 비활성화 - * - * addons라는 테이블에 애드온의 이름을 제거하는 것으로 비활성화를 시키게 된다 - **/ - function doDeactivate($addon, $site_srl = 0, $type = "pc") { - $args->addon = $addon; - if($type == "pc") $args->is_used = 'N'; - else $args->is_used_m = 'N'; - if(!$site_srl) return executeQuery('addon.updateAddon', $args); - $args->site_srl = $site_srl; - return executeQuery('addon.updateSiteAddon', $args); - } - - - } -?> +isActivatedAddon($addon, $site_module_info->site_srl, $type)) $this->doDeactivate($addon, $site_module_info->site_srl, $type); + + // 비활성화 되어 있으면 활성화 시킴 + else $this->doActivate($addon, $site_module_info->site_srl, $type); + } + + $this->makeCacheFile($site_module_info->site_srl, $type); + } + + /** + * @brief 애드온 설정 정보 입력 + **/ + function procAddonAdminSetupAddon() { + $args = Context::getRequestVars(); + $addon_name = $args->addon_name; + unset($args->module); + unset($args->act); + unset($args->addon_name); + unset($args->body); + + $site_module_info = Context::get('site_module_info'); + + $this->doSetup($addon_name, $args, $site_module_info->site_srl); + + $this->makeCacheFile($site_module_info->site_srl, "pc"); + $this->makeCacheFile($site_module_info->site_srl, "mobile"); + } + + + + /** + * @brief 애드온 추가 + * DB에 애드온을 추가함 + **/ + function doInsert($addon, $site_srl = 0) { + $args->addon = $addon; + $args->is_used = 'N'; + if(!$site_srl) return executeQuery('addon.insertAddon', $args); + $args->site_srl = $site_srl; + return executeQuery('addon.insertSiteAddon', $args); + } + + /** + * @brief 애드온 활성화 + * addons라는 테이블에 애드온의 활성화 상태를 on 시켜줌 + **/ + function doActivate($addon, $site_srl = 0, $type = "pc") { + $args->addon = $addon; + if($type == "pc") $args->is_used = 'Y'; + else $args->is_used_m = "Y"; + if(!$site_srl) return executeQuery('addon.updateAddon', $args); + $args->site_srl = $site_srl; + return executeQuery('addon.updateSiteAddon', $args); + } + + /** + * @brief 애드온 비활성화 + * + * addons라는 테이블에 애드온의 이름을 제거하는 것으로 비활성화를 시키게 된다 + **/ + function doDeactivate($addon, $site_srl = 0, $type = "pc") { + $args->addon = $addon; + if($type == "pc") $args->is_used = 'N'; + else $args->is_used_m = 'N'; + if(!$site_srl) return executeQuery('addon.updateAddon', $args); + $args->site_srl = $site_srl; + return executeQuery('addon.updateSiteAddon', $args); + } + + + } +?> diff --git a/modules/addon/addon.admin.model.php b/modules/addon/addon.admin.model.php index 5e9d4b8e7..b6efdaa01 100644 --- a/modules/addon/addon.admin.model.php +++ b/modules/addon/addon.admin.model.php @@ -1,313 +1,313 @@ -getInsertedAddons($site_srl); - - // 다운받은 애드온과 설치된 애드온의 목록을 구함 - $searched_list = FileHandler::readDir('./addons'); - $searched_count = count($searched_list); - if(!$searched_count) return; - sort($searched_list); - - for($i=0;$i<$searched_count;$i++) { - // 애드온의 이름 - $addon_name = $searched_list[$i]; - if($addon_name == "smartphone") continue; - - // 애드온의 경로 (files/addons가 우선) - $path = $this->getAddonPath($addon_name); - - // 해당 애드온의 정보를 구함 - unset($info); - $info = $this->getAddonInfoXml($addon_name, $site_srl); - - $info->addon = $addon_name; - $info->path = $path; - $info->activated = false; - $info->mactivated = false; - - // DB에 입력되어 있는지 확인 - if(!in_array($addon_name, array_keys($inserted_addons))) { - // DB에 입력되어 있지 않으면 입력 (model에서 이런짓 하는거 싫지만 귀찮아서.. ㅡ.ㅜ) - $oAddonAdminController = &getAdminController('addon'); - $oAddonAdminController->doInsert($addon_name, $site_srl); - - // 활성화 되어 있는지 확인 - } else { - if($inserted_addons[$addon_name]->is_used=='Y') $info->activated = true; - if($inserted_addons[$addon_name]->is_used_m=='Y') $info->mactivated = true; - } - - $list[] = $info; - } - return $list; - } - - /** - * @brief 모듈의 conf/info.xml 을 읽어서 정보를 구함 - **/ - function getAddonInfoXml($addon, $site_srl = 0) { - // 요청된 모듈의 경로를 구한다. 없으면 return - $addon_path = $this->getAddonPath($addon); - if(!$addon_path) return; - - // 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음 - $xml_file = sprintf("%sconf/info.xml", $addon_path); - if(!file_exists($xml_file)) return; - - $oXmlParser = new XmlParser(); - $tmp_xml_obj = $oXmlParser->loadXmlFile($xml_file); - $xml_obj = $tmp_xml_obj->addon; - - if(!$xml_obj) return; - - - // DB에 설정된 내역을 가져온다 - $db_args->addon = $addon; - if(!$site_srl) $output = executeQuery('addon.getAddonInfo',$db_args); - else { - $db_args->site_srl = $site_srl; - $output = executeQuery('addon.getSiteAddonInfo',$db_args); - } - $extra_vals = unserialize($output->data->extra_vars); - - if($extra_vals->mid_list) { - $addon_info->mid_list = $extra_vals->mid_list; - } else { - $addon_info->mid_list = array(); - } - - - // 애드온 정보 - if($xml_obj->version && $xml_obj->attrs->version == '0.2') { - // addon format v0.2 - sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); - $addon_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - - $addon_info->addon_name = $addon; - $addon_info->title = $xml_obj->title->body; - $addon_info->description = trim($xml_obj->description->body); - $addon_info->version = $xml_obj->version->body; - $addon_info->homepage = $xml_obj->link->body; - $addon_info->license = $xml_obj->license->body; - $addon_info->license_link = $xml_obj->license->attrs->link; - - if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; - else $author_list = $xml_obj->author; - - foreach($author_list as $author) { - unset($author_obj); - $author_obj->name = $author->name->body; - $author_obj->email_address = $author->attrs->email_address; - $author_obj->homepage = $author->attrs->link; - $addon_info->author[] = $author_obj; - } - - // 확장변수를 정리 - if($xml_obj->extra_vars) { - $extra_var_groups = $xml_obj->extra_vars->group; - if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; - if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); - - foreach($extra_var_groups as $group) { - $extra_vars = $group->var; - if(!is_array($group->var)) $extra_vars = array($group->var); - - foreach($extra_vars as $key => $val) { - unset($obj); - if(!$val->attrs->type) { $val->attrs->type = 'text'; } - - $obj->group = $group->title->body; - $obj->name = $val->attrs->name; - $obj->title = $val->title->body; - $obj->type = $val->attrs->type; - $obj->description = $val->description->body; - $obj->value = $extra_vals->{$obj->name}; - if(strpos($obj->value, '|@|') != false) { $obj->value = explode('|@|', $obj->value); } - if($obj->type == 'mid_list' && !is_array($obj->value)) { $obj->value = array($obj->value); } - - // 'select'type에서 option목록을 구한다. - if(is_array($val->options)) { - $option_count = count($val->options); - - for($i = 0; $i < $option_count; $i++) { - $obj->options[$i]->title = $val->options[$i]->title->body; - $obj->options[$i]->value = $val->options[$i]->attrs->value; - } - } else { - $obj->options[0]->title = $val->options[0]->title->body; - $obj->options[0]->value = $val->options[0]->attrs->value; - } - - $addon_info->extra_vars[] = $obj; - } - } - } - - // history - if($xml_obj->history) { - if(!is_array($xml_obj->history)) $history[] = $xml_obj->history; - else $history = $xml_obj->history; - - foreach($history as $item) { - unset($obj); - - if($item->author) { - (!is_array($item->author)) ? $obj->author_list[] = $item->author : $obj->author_list = $item->author; - - foreach($obj->author_list as $author) { - unset($author_obj); - $author_obj->name = $author->name->body; - $author_obj->email_address = $author->attrs->email_address; - $author_obj->homepage = $author->attrs->link; - $obj->author[] = $author_obj; - } - } - - $obj->name = $item->name->body; - $obj->email_address = $item->attrs->email_address; - $obj->homepage = $item->attrs->link; - $obj->version = $item->attrs->version; - $obj->date = $item->attrs->date; - $obj->description = $item->description->body; - - if($item->log) { - (!is_array($item->log)) ? $obj->log[] = $item->log : $obj->log = $item->log; - - foreach($obj->log as $log) { - unset($log_obj); - $log_obj->text = $log->body; - $log_obj->link = $log->attrs->link; - $obj->logs[] = $log_obj; - } - } - - $addon_info->history[] = $obj; - } - } - - - } else { - // addon format 0.1 - $addon_info->addon_name = $addon; - $addon_info->title = $xml_obj->title->body; - $addon_info->description = trim($xml_obj->author->description->body); - $addon_info->version = $xml_obj->attrs->version; - sscanf($xml_obj->author->attrs->date, '%d. %d. %d', $date_obj->y, $date_obj->m, $date_obj->d); - $addon_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $author_obj->name = $xml_obj->author->name->body; - $author_obj->email_address = $xml_obj->author->attrs->email_address; - $author_obj->homepage = $xml_obj->author->attrs->link; - $addon_info->author[] = $author_obj; - - if($xml_obj->extra_vars) { - // 확장변수를 정리 - $extra_var_groups = $xml_obj->extra_vars->group; - if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; - if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); - foreach($extra_var_groups as $group) { - $extra_vars = $group->var; - if(!is_array($group->var)) $extra_vars = array($group->var); - - foreach($extra_vars as $key => $val) { - unset($obj); - if(!$val->type->body) { $val->type->body = 'text'; } - - $obj->group = $group->title->body; - $obj->name = $val->attrs->name; - $obj->title = $val->title->body; - $obj->type = $val->type->body; - $obj->description = $val->description->body; - $obj->value = $extra_vals->{$obj->name}; - if(strpos($obj->value, '|@|') != false) { $obj->value = explode('|@|', $obj->value); } - if($obj->type == 'mid_list' && !is_array($obj->value)) { $obj->value = array($obj->value); } - - // 'select'type에서 option목록을 구한다. - if(is_array($val->options)) { - $option_count = count($val->options); - - for($i = 0; $i < $option_count; $i++) { - $obj->options[$i]->title = $val->options[$i]->title->body; - $obj->options[$i]->value = $val->options[$i]->value->body; - } - } - - $addon_info->extra_vars[] = $obj; - } - } - } - - } - - - - return $addon_info; - } - - /** - * @brief 활성화된 애드온 목록을 구해옴 - **/ - function getInsertedAddons($site_srl = 0) { - $args->list_order = 'addon'; - if(!$site_srl) $output = executeQuery('addon.getAddons', $args); - else { - $args->site_srl = $site_srl; - $output = executeQuery('addon.getSiteAddons', $args); - } - if(!$output->data) return array(); - if(!is_array($output->data)) $output->data = array($output->data); - - $activated_count = count($output->data); - for($i=0;$i<$activated_count;$i++) { - $addon = $output->data[$i]; - $addon_list[$addon->addon] = $addon; - } - return $addon_list; - } - - /** - * @brief 애드온이 활성화 되어 있는지 체크 - **/ - function isActivatedAddon($addon, $site_srl = 0, $type = "pc") { - $args->addon = $addon; - if(!$site_srl) { - if($type == "pc") $output = executeQuery('addon.getAddonIsActivated', $args); - else $output = executeQuery('addon.getMAddonIsActivated', $args); - } - else { - $args->site_srl = $site_srl; - if($type == "pc") $output = executeQuery('addon.getSiteAddonIsActivated', $args); - else $output = executeQuery('addon.getSiteMAddonIsActivated', $args); - } - if($output->data->count>0) return true; - return false; - } - - } -?> +getInsertedAddons($site_srl); + + // 다운받은 애드온과 설치된 애드온의 목록을 구함 + $searched_list = FileHandler::readDir('./addons'); + $searched_count = count($searched_list); + if(!$searched_count) return; + sort($searched_list); + + for($i=0;$i<$searched_count;$i++) { + // 애드온의 이름 + $addon_name = $searched_list[$i]; + if($addon_name == "smartphone") continue; + + // 애드온의 경로 (files/addons가 우선) + $path = $this->getAddonPath($addon_name); + + // 해당 애드온의 정보를 구함 + unset($info); + $info = $this->getAddonInfoXml($addon_name, $site_srl); + + $info->addon = $addon_name; + $info->path = $path; + $info->activated = false; + $info->mactivated = false; + + // DB에 입력되어 있는지 확인 + if(!in_array($addon_name, array_keys($inserted_addons))) { + // DB에 입력되어 있지 않으면 입력 (model에서 이런짓 하는거 싫지만 귀찮아서.. ㅡ.ㅜ) + $oAddonAdminController = &getAdminController('addon'); + $oAddonAdminController->doInsert($addon_name, $site_srl); + + // 활성화 되어 있는지 확인 + } else { + if($inserted_addons[$addon_name]->is_used=='Y') $info->activated = true; + if($inserted_addons[$addon_name]->is_used_m=='Y') $info->mactivated = true; + } + + $list[] = $info; + } + return $list; + } + + /** + * @brief 모듈의 conf/info.xml 을 읽어서 정보를 구함 + **/ + function getAddonInfoXml($addon, $site_srl = 0) { + // 요청된 모듈의 경로를 구한다. 없으면 return + $addon_path = $this->getAddonPath($addon); + if(!$addon_path) return; + + // 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음 + $xml_file = sprintf("%sconf/info.xml", $addon_path); + if(!file_exists($xml_file)) return; + + $oXmlParser = new XmlParser(); + $tmp_xml_obj = $oXmlParser->loadXmlFile($xml_file); + $xml_obj = $tmp_xml_obj->addon; + + if(!$xml_obj) return; + + + // DB에 설정된 내역을 가져온다 + $db_args->addon = $addon; + if(!$site_srl) $output = executeQuery('addon.getAddonInfo',$db_args); + else { + $db_args->site_srl = $site_srl; + $output = executeQuery('addon.getSiteAddonInfo',$db_args); + } + $extra_vals = unserialize($output->data->extra_vars); + + if($extra_vals->mid_list) { + $addon_info->mid_list = $extra_vals->mid_list; + } else { + $addon_info->mid_list = array(); + } + + + // 애드온 정보 + if($xml_obj->version && $xml_obj->attrs->version == '0.2') { + // addon format v0.2 + sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); + $addon_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + + $addon_info->addon_name = $addon; + $addon_info->title = $xml_obj->title->body; + $addon_info->description = trim($xml_obj->description->body); + $addon_info->version = $xml_obj->version->body; + $addon_info->homepage = $xml_obj->link->body; + $addon_info->license = $xml_obj->license->body; + $addon_info->license_link = $xml_obj->license->attrs->link; + + if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; + else $author_list = $xml_obj->author; + + foreach($author_list as $author) { + unset($author_obj); + $author_obj->name = $author->name->body; + $author_obj->email_address = $author->attrs->email_address; + $author_obj->homepage = $author->attrs->link; + $addon_info->author[] = $author_obj; + } + + // 확장변수를 정리 + if($xml_obj->extra_vars) { + $extra_var_groups = $xml_obj->extra_vars->group; + if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; + if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); + + foreach($extra_var_groups as $group) { + $extra_vars = $group->var; + if(!is_array($group->var)) $extra_vars = array($group->var); + + foreach($extra_vars as $key => $val) { + unset($obj); + if(!$val->attrs->type) { $val->attrs->type = 'text'; } + + $obj->group = $group->title->body; + $obj->name = $val->attrs->name; + $obj->title = $val->title->body; + $obj->type = $val->attrs->type; + $obj->description = $val->description->body; + $obj->value = $extra_vals->{$obj->name}; + if(strpos($obj->value, '|@|') != false) { $obj->value = explode('|@|', $obj->value); } + if($obj->type == 'mid_list' && !is_array($obj->value)) { $obj->value = array($obj->value); } + + // 'select'type에서 option목록을 구한다. + if(is_array($val->options)) { + $option_count = count($val->options); + + for($i = 0; $i < $option_count; $i++) { + $obj->options[$i]->title = $val->options[$i]->title->body; + $obj->options[$i]->value = $val->options[$i]->attrs->value; + } + } else { + $obj->options[0]->title = $val->options[0]->title->body; + $obj->options[0]->value = $val->options[0]->attrs->value; + } + + $addon_info->extra_vars[] = $obj; + } + } + } + + // history + if($xml_obj->history) { + if(!is_array($xml_obj->history)) $history[] = $xml_obj->history; + else $history = $xml_obj->history; + + foreach($history as $item) { + unset($obj); + + if($item->author) { + (!is_array($item->author)) ? $obj->author_list[] = $item->author : $obj->author_list = $item->author; + + foreach($obj->author_list as $author) { + unset($author_obj); + $author_obj->name = $author->name->body; + $author_obj->email_address = $author->attrs->email_address; + $author_obj->homepage = $author->attrs->link; + $obj->author[] = $author_obj; + } + } + + $obj->name = $item->name->body; + $obj->email_address = $item->attrs->email_address; + $obj->homepage = $item->attrs->link; + $obj->version = $item->attrs->version; + $obj->date = $item->attrs->date; + $obj->description = $item->description->body; + + if($item->log) { + (!is_array($item->log)) ? $obj->log[] = $item->log : $obj->log = $item->log; + + foreach($obj->log as $log) { + unset($log_obj); + $log_obj->text = $log->body; + $log_obj->link = $log->attrs->link; + $obj->logs[] = $log_obj; + } + } + + $addon_info->history[] = $obj; + } + } + + + } else { + // addon format 0.1 + $addon_info->addon_name = $addon; + $addon_info->title = $xml_obj->title->body; + $addon_info->description = trim($xml_obj->author->description->body); + $addon_info->version = $xml_obj->attrs->version; + sscanf($xml_obj->author->attrs->date, '%d. %d. %d', $date_obj->y, $date_obj->m, $date_obj->d); + $addon_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $author_obj->name = $xml_obj->author->name->body; + $author_obj->email_address = $xml_obj->author->attrs->email_address; + $author_obj->homepage = $xml_obj->author->attrs->link; + $addon_info->author[] = $author_obj; + + if($xml_obj->extra_vars) { + // 확장변수를 정리 + $extra_var_groups = $xml_obj->extra_vars->group; + if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; + if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); + foreach($extra_var_groups as $group) { + $extra_vars = $group->var; + if(!is_array($group->var)) $extra_vars = array($group->var); + + foreach($extra_vars as $key => $val) { + unset($obj); + if(!$val->type->body) { $val->type->body = 'text'; } + + $obj->group = $group->title->body; + $obj->name = $val->attrs->name; + $obj->title = $val->title->body; + $obj->type = $val->type->body; + $obj->description = $val->description->body; + $obj->value = $extra_vals->{$obj->name}; + if(strpos($obj->value, '|@|') != false) { $obj->value = explode('|@|', $obj->value); } + if($obj->type == 'mid_list' && !is_array($obj->value)) { $obj->value = array($obj->value); } + + // 'select'type에서 option목록을 구한다. + if(is_array($val->options)) { + $option_count = count($val->options); + + for($i = 0; $i < $option_count; $i++) { + $obj->options[$i]->title = $val->options[$i]->title->body; + $obj->options[$i]->value = $val->options[$i]->value->body; + } + } + + $addon_info->extra_vars[] = $obj; + } + } + } + + } + + + + return $addon_info; + } + + /** + * @brief 활성화된 애드온 목록을 구해옴 + **/ + function getInsertedAddons($site_srl = 0) { + $args->list_order = 'addon'; + if(!$site_srl) $output = executeQuery('addon.getAddons', $args); + else { + $args->site_srl = $site_srl; + $output = executeQuery('addon.getSiteAddons', $args); + } + if(!$output->data) return array(); + if(!is_array($output->data)) $output->data = array($output->data); + + $activated_count = count($output->data); + for($i=0;$i<$activated_count;$i++) { + $addon = $output->data[$i]; + $addon_list[$addon->addon] = $addon; + } + return $addon_list; + } + + /** + * @brief 애드온이 활성화 되어 있는지 체크 + **/ + function isActivatedAddon($addon, $site_srl = 0, $type = "pc") { + $args->addon = $addon; + if(!$site_srl) { + if($type == "pc") $output = executeQuery('addon.getAddonIsActivated', $args); + else $output = executeQuery('addon.getMAddonIsActivated', $args); + } + else { + $args->site_srl = $site_srl; + if($type == "pc") $output = executeQuery('addon.getSiteAddonIsActivated', $args); + else $output = executeQuery('addon.getSiteMAddonIsActivated', $args); + } + if($output->data->count>0) return true; + return false; + } + + } +?> diff --git a/modules/addon/addon.admin.view.php b/modules/addon/addon.admin.view.php index b279390c5..ed6e3a177 100644 --- a/modules/addon/addon.admin.view.php +++ b/modules/addon/addon.admin.view.php @@ -1,98 +1,98 @@ -setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief 애드온 관리 메인 페이지 (목록 보여줌) - **/ - function dispAddonAdminIndex() { - $site_module_info = Context::get('site_module_info'); - - // 애드온 목록을 세팅 - $oAddonModel = &getAdminModel('addon'); - $addon_list = $oAddonModel->getAddonList($site_module_info->site_srl); - Context::set('addon_list', $addon_list); - - // 템플릿 패스 및 파일을 지정 - $this->setTemplateFile('addon_list'); - } - - /** - * @biref 애드온 세부 설정 팝업 출력 - **/ - function dispAddonAdminSetup() { - $site_module_info = Context::get('site_module_info'); - - // 요청된 애드온을 구함 - $selected_addon = Context::get('selected_addon'); - - // 요청된 애드온의 정보를 구함 - $oAddonModel = &getAdminModel('addon'); - $addon_info = $oAddonModel->getAddonInfoXml($selected_addon, $site_module_info->site_srl); - Context::set('addon_info', $addon_info); - - // mid 목록을 가져옴 - $oModuleModel = &getModel('module'); - $oModuleAdminModel = &getAdminModel('module'); - - if($site_module_info->site_srl) $args->site_srl = $site_module_info->site_srl; - $mid_list = $oModuleModel->getMidList($args); - - // module_category와 module의 조합 - if(!$site_module_info->site_srl) { - // 모듈 카테고리 목록을 구함 - $module_categories = $oModuleModel->getModuleCategories(); - - if($mid_list) { - foreach($mid_list as $module_srl => $module) { - $module_categories[$module->module_category_srl]->list[$module_srl] = $module; - } - } - } else { - $module_categories[0]->list = $mid_list; - } - - Context::set('mid_list',$module_categories); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 패스 및 파일을 지정 - $this->setTemplateFile('setup_addon'); - } - - /** - * @brief 애드온의 상세 정보(conf/info.xml)를 팝업 출력 - **/ - function dispAddonAdminInfo() { - $site_module_info = Context::get('site_module_info'); - - // 요청된 애드온을 구함 - $selected_addon = Context::get('selected_addon'); - - // 요청된 애드온의 정보를 구함 - $oAddonModel = &getAdminModel('addon'); - $addon_info = $oAddonModel->getAddonInfoXml($selected_addon, $site_module_info->site_srl); - Context::set('addon_info', $addon_info); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 패스 및 파일을 지정 - $this->setTemplateFile('addon_info'); - } - - } -?> +setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief 애드온 관리 메인 페이지 (목록 보여줌) + **/ + function dispAddonAdminIndex() { + $site_module_info = Context::get('site_module_info'); + + // 애드온 목록을 세팅 + $oAddonModel = &getAdminModel('addon'); + $addon_list = $oAddonModel->getAddonList($site_module_info->site_srl); + Context::set('addon_list', $addon_list); + + // 템플릿 패스 및 파일을 지정 + $this->setTemplateFile('addon_list'); + } + + /** + * @biref 애드온 세부 설정 팝업 출력 + **/ + function dispAddonAdminSetup() { + $site_module_info = Context::get('site_module_info'); + + // 요청된 애드온을 구함 + $selected_addon = Context::get('selected_addon'); + + // 요청된 애드온의 정보를 구함 + $oAddonModel = &getAdminModel('addon'); + $addon_info = $oAddonModel->getAddonInfoXml($selected_addon, $site_module_info->site_srl); + Context::set('addon_info', $addon_info); + + // mid 목록을 가져옴 + $oModuleModel = &getModel('module'); + $oModuleAdminModel = &getAdminModel('module'); + + if($site_module_info->site_srl) $args->site_srl = $site_module_info->site_srl; + $mid_list = $oModuleModel->getMidList($args); + + // module_category와 module의 조합 + if(!$site_module_info->site_srl) { + // 모듈 카테고리 목록을 구함 + $module_categories = $oModuleModel->getModuleCategories(); + + if($mid_list) { + foreach($mid_list as $module_srl => $module) { + $module_categories[$module->module_category_srl]->list[$module_srl] = $module; + } + } + } else { + $module_categories[0]->list = $mid_list; + } + + Context::set('mid_list',$module_categories); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 패스 및 파일을 지정 + $this->setTemplateFile('setup_addon'); + } + + /** + * @brief 애드온의 상세 정보(conf/info.xml)를 팝업 출력 + **/ + function dispAddonAdminInfo() { + $site_module_info = Context::get('site_module_info'); + + // 요청된 애드온을 구함 + $selected_addon = Context::get('selected_addon'); + + // 요청된 애드온의 정보를 구함 + $oAddonModel = &getAdminModel('addon'); + $addon_info = $oAddonModel->getAddonInfoXml($selected_addon, $site_module_info->site_srl); + Context::set('addon_info', $addon_info); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 패스 및 파일을 지정 + $this->setTemplateFile('addon_info'); + } + + } +?> diff --git a/modules/addon/addon.class.php b/modules/addon/addon.class.php index 4a11eff07..7472e19dd 100644 --- a/modules/addon/addon.class.php +++ b/modules/addon/addon.class.php @@ -1,71 +1,71 @@ -doInsert('autolink'); - $oAddonController->doInsert('blogapi'); - $oAddonController->doInsert('counter'); - $oAddonController->doInsert('member_communication'); - $oAddonController->doInsert('member_extra_info'); - $oAddonController->doInsert('mobile'); - $oAddonController->doInsert('referer'); - $oAddonController->doInsert('resize_image'); - $oAddonController->doInsert('openid_delegation_id'); - $oAddonController->doInsert('point_level_icon'); - - // 몇가지 애드온을 기본 활성화 상태로 변경 - $oAddonController->doActivate('autolink'); - $oAddonController->doActivate('counter'); - $oAddonController->doActivate('member_communication'); - $oAddonController->doActivate('member_extra_info'); - $oAddonController->doActivate('mobile'); - $oAddonController->doActivate('referer'); - $oAddonController->doActivate('resize_image'); - $oAddonController->makeCacheFile(0); - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB = &DB::getInstance(); - if(!$oDB->isColumnExists("addons", "is_used_m")) return true; - if(!$oDB->isColumnExists("addons_site", "is_used_m")) return true; - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - if(!$oDB->isColumnExists("addons", "is_used_m")) { - $oDB->addColumn("addons", "is_used_m", "char", 1, "N", true); - } - if(!$oDB->isColumnExists("addons_site", "is_used_m")) { - $oDB->addColumn("addons_site", "is_used_m", "char", 1, "N", true); - } - return new Object(); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - FileHandler::removeFilesInDir('./files/cache/addons'); - } - - } -?> +doInsert('autolink'); + $oAddonController->doInsert('blogapi'); + $oAddonController->doInsert('counter'); + $oAddonController->doInsert('member_communication'); + $oAddonController->doInsert('member_extra_info'); + $oAddonController->doInsert('mobile'); + $oAddonController->doInsert('referer'); + $oAddonController->doInsert('resize_image'); + $oAddonController->doInsert('openid_delegation_id'); + $oAddonController->doInsert('point_level_icon'); + + // 몇가지 애드온을 기본 활성화 상태로 변경 + $oAddonController->doActivate('autolink'); + $oAddonController->doActivate('counter'); + $oAddonController->doActivate('member_communication'); + $oAddonController->doActivate('member_extra_info'); + $oAddonController->doActivate('mobile'); + $oAddonController->doActivate('referer'); + $oAddonController->doActivate('resize_image'); + $oAddonController->makeCacheFile(0); + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB = &DB::getInstance(); + if(!$oDB->isColumnExists("addons", "is_used_m")) return true; + if(!$oDB->isColumnExists("addons_site", "is_used_m")) return true; + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + if(!$oDB->isColumnExists("addons", "is_used_m")) { + $oDB->addColumn("addons", "is_used_m", "char", 1, "N", true); + } + if(!$oDB->isColumnExists("addons_site", "is_used_m")) { + $oDB->addColumn("addons_site", "is_used_m", "char", 1, "N", true); + } + return new Object(); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + FileHandler::removeFilesInDir('./files/cache/addons'); + } + + } +?> diff --git a/modules/addon/addon.controller.php b/modules/addon/addon.controller.php index ed689ee7d..7e29d2267 100644 --- a/modules/addon/addon.controller.php +++ b/modules/addon/addon.controller.php @@ -1,7 +1,7 @@ - - 애드온 - Addon - Addon - Addon - 插件管理 - アドオン - Additions - Аддон - 附加元件 - 애드온을 등록하거나 사용/미사용을 설정하는 애드온 관리 모듈입니다. - This module is for maintaining addons which can toggle use and disuse states. - Module này dành cho việc bảo trì những Addon đang sử dụng và không sử dụng. - Este Módulo es para agregar Addons, como también el manejo de ellos. - 登录插件或设置启用/禁用插件的管理模块。 - アドオンの「登録、使用・未使用」などを設定する管理モジュールです。 - Ce module est pour les Additions de maintien qui peuvent basculer des états d'utilisation et de désuétude. - Этот модуль служит для управления аддонами, использование которых Вы можете включать и выключать. - 設定附加元件「登錄、啟用、禁用」的管理模組。 - 0.1 - 2007-02-28 - utility - - - zero - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 애드온 + Addon + Addon + Addon + 插件管理 + アドオン + Additions + Аддон + 附加元件 + 애드온을 등록하거나 사용/미사용을 설정하는 애드온 관리 모듈입니다. + This module is for maintaining addons which can toggle use and disuse states. + Module này dành cho việc bảo trì những Addon đang sử dụng và không sử dụng. + Este Módulo es para agregar Addons, como también el manejo de ellos. + 登录插件或设置启用/禁用插件的管理模块。 + アドオンの「登録、使用・未使用」などを設定する管理モジュールです。 + Ce module est pour les Additions de maintien qui peuvent basculer des états d'utilisation et de désuétude. + Этот модуль служит для управления аддонами, использование которых Вы можете включать и выключать. + 設定附加元件「登錄、啟用、禁用」的管理模組。 + 0.1 + 2007-02-28 + utility + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/addon/lang/en.lang.php b/modules/addon/lang/en.lang.php index 4029e1bcc..adb75ffd6 100644 --- a/modules/addon/lang/en.lang.php +++ b/modules/addon/lang/en.lang.php @@ -1,17 +1,17 @@ -addon = "Addon"; - - $lang->addon_info = 'Summary of this Addon'; - $lang->addon_maker = 'Author of this Addon'; - $lang->addon_license = 'License'; - $lang->addon_history = 'Addon History'; - - $lang->about_addon_mid = "Addons can select targets.
(All targets will be selected when nothing is selected)"; - $lang->about_addon = 'Addon is for controlling actions rather than displaying the HTML results.
Simply by toggling any addons you want on or off, you can use very useful functions to administer your website'; -?> +addon = "Addon"; + + $lang->addon_info = 'Summary of this Addon'; + $lang->addon_maker = 'Author of this Addon'; + $lang->addon_license = 'License'; + $lang->addon_history = 'Addon History'; + + $lang->about_addon_mid = "Addons can select targets.
(All targets will be selected when nothing is selected)"; + $lang->about_addon = 'Addon is for controlling actions rather than displaying the HTML results.
Simply by toggling any addons you want on or off, you can use very useful functions to administer your website'; +?> diff --git a/modules/addon/lang/es.lang.php b/modules/addon/lang/es.lang.php index fdc9b566b..47b52c84f 100644 --- a/modules/addon/lang/es.lang.php +++ b/modules/addon/lang/es.lang.php @@ -1,7 +1,7 @@ addon = 'アドオン'; - - $lang->addon_info = 'アドオン情報'; - $lang->addon_maker = 'アドオン制作者'; - $lang->addon_license = 'ライセンス'; - $lang->addon_history = '変更履歴'; - - $lang->about_addon_mid = 'アドオンが使われる対象を指定します。
(選択なしの場合、全てのモジュールが利用可能対象)'; - $lang->about_addon = 'アドオンは、HTMLの出力をコントロールすると言うより、動作を制御する役割をします。お好みのアドオンを「使用/未使用」に設定するだけで、サイトの運営に有用な機能が利用出来ます。'; -?> +addon = 'アドオン'; + + $lang->addon_info = 'アドオン情報'; + $lang->addon_maker = 'アドオン制作者'; + $lang->addon_license = 'ライセンス'; + $lang->addon_history = '変更履歴'; + + $lang->about_addon_mid = 'アドオンが使われる対象を指定します。
(選択なしの場合、全てのモジュールが利用可能対象)'; + $lang->about_addon = 'アドオンは、HTMLの出力をコントロールすると言うより、動作を制御する役割をします。お好みのアドオンを「使用/未使用」に設定するだけで、サイトの運営に有用な機能が利用出来ます。'; +?> diff --git a/modules/addon/lang/ko.lang.php b/modules/addon/lang/ko.lang.php index c0359aae0..39798220b 100644 --- a/modules/addon/lang/ko.lang.php +++ b/modules/addon/lang/ko.lang.php @@ -1,17 +1,17 @@ -addon = '애드온'; - - $lang->addon_info = '애드온 정보'; - $lang->addon_maker = '애드온 제작자'; - $lang->addon_license = '라이선스'; - $lang->addon_history = '변경 이력'; - - $lang->about_addon_mid = '애드온이 사용될 대상을 지정할 수 있습니다.
(모두 해제 시 모든 대상에서 사용 가능합니다.)'; - $lang->about_addon = '애드온은 HTML결과물을 출력하기보다는 동작을 제어하는 역할을 합니다.
원하시는 애드온을 ON/OFF 하시는 것만으로도 사이트 운영에 유용한 기능을 연동할 수 있습니다.'; -?> +addon = '애드온'; + + $lang->addon_info = '애드온 정보'; + $lang->addon_maker = '애드온 제작자'; + $lang->addon_license = '라이선스'; + $lang->addon_history = '변경 이력'; + + $lang->about_addon_mid = '애드온이 사용될 대상을 지정할 수 있습니다.
(모두 해제 시 모든 대상에서 사용 가능합니다.)'; + $lang->about_addon = '애드온은 HTML결과물을 출력하기보다는 동작을 제어하는 역할을 합니다.
원하시는 애드온을 ON/OFF 하시는 것만으로도 사이트 운영에 유용한 기능을 연동할 수 있습니다.'; +?> diff --git a/modules/addon/lang/ru.lang.php b/modules/addon/lang/ru.lang.php index 76e4d96e8..6e802f1dc 100644 --- a/modules/addon/lang/ru.lang.php +++ b/modules/addon/lang/ru.lang.php @@ -1,17 +1,17 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->addon = "Аддон"; - - $lang->addon_info = 'Информация об аддоне'; - $lang->addon_maker = 'Автор аддона'; - $lang->addon_license = 'License'; - $lang->addon_history = 'История аддона'; - - $lang->about_addon_mid = "애드온이 사용될 대상을 지정할 수 있습니다.
(모두 해제시 모든 대상에서 사용 가능합니다)"; - $lang->about_addon = 'Аддон служит больше для контролирования действий, чем для отображения HTML-результатов.
Простым включением/выключением любых аддонов, Вы можете использовать очень полезные функции для администрирования Вашего веб-сайта'; -?> +addon = "Аддон"; + + $lang->addon_info = 'Информация об аддоне'; + $lang->addon_maker = 'Автор аддона'; + $lang->addon_license = 'License'; + $lang->addon_history = 'История аддона'; + + $lang->about_addon_mid = "애드온이 사용될 대상을 지정할 수 있습니다.
(모두 해제시 모든 대상에서 사용 가능합니다)"; + $lang->about_addon = 'Аддон служит больше для контролирования действий, чем для отображения HTML-результатов.
Простым включением/выключением любых аддонов, Вы можете использовать очень полезные функции для администрирования Вашего веб-сайта'; +?> diff --git a/modules/addon/lang/vi.lang.php b/modules/addon/lang/vi.lang.php index 7fa716d55..e9c717b4b 100644 --- a/modules/addon/lang/vi.lang.php +++ b/modules/addon/lang/vi.lang.php @@ -1,19 +1,19 @@ -addon = "Addon"; - - $lang->addon_info = 'Thông tin về Addon'; - $lang->addon_maker = 'Tác giả của Addon'; - $lang->addon_license = 'Giấy phép'; - $lang->addon_history = 'Lịch sử'; - - $lang->about_addon_mid = "Addon có thể chọn những vị trí.
(Tất cả những vị trí mà chưa Addon nào sử dụng.)"; - $lang->about_addon = 'Addon có nhiệm vụ hiển thị và kiểm soát kết quả HTML.
Bạn có thể mở hoặc tắt bất cứ Addon nào bạn muốn.'; -?> +addon = "Addon"; + + $lang->addon_info = 'Thông tin về Addon'; + $lang->addon_maker = 'Tác giả của Addon'; + $lang->addon_license = 'Giấy phép'; + $lang->addon_history = 'Lịch sử'; + + $lang->about_addon_mid = "Addon có thể chọn những vị trí.
(Tất cả những vị trí mà chưa Addon nào sử dụng.)"; + $lang->about_addon = 'Addon có nhiệm vụ hiển thị và kiểm soát kết quả HTML.
Bạn có thể mở hoặc tắt bất cứ Addon nào bạn muốn.'; +?> diff --git a/modules/addon/lang/zh-CN.lang.php b/modules/addon/lang/zh-CN.lang.php index 76404e10c..6b8d088bb 100644 --- a/modules/addon/lang/zh-CN.lang.php +++ b/modules/addon/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ -#xeAdmin {/* background-color:#fff; */} #xeAdmin .open{ display:block !important;} #xeAdmin h1.xeAdmin { float:left; white-space:nowrap; margin:0;padding:0;} #xeAdmin caption{ text-align:left;} diff --git a/modules/admin/tpl/css/font.css b/modules/admin/tpl/css/font.css index fa704215f..4175d6a71 100755 --- a/modules/admin/tpl/css/font.css +++ b/modules/admin/tpl/css/font.css @@ -1,5 +1,5 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ #xeAdmin{ font-family:Sans-serif;} diff --git a/modules/admin/tpl/css/layout.css b/modules/admin/tpl/css/layout.css index 0b3744060..3cd75b92a 100755 --- a/modules/admin/tpl/css/layout.css +++ b/modules/admin/tpl/css/layout.css @@ -1,6 +1,7 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ + #xeAdmin .header{ position:relative; height:62px; padding:10px 15px 10px 30px; background:url(../img/bgHeader.gif) repeat-x; z-index:10;} #xeAdmin .footer{ height:26px; padding-top:10px; background:url(../img/bgFooter.gif) repeat-x; text-align:center;} #xeAdmin .gnb{ position:relative; float:right; white-space:nowrap; clear:right; margin:0; padding:0;} diff --git a/modules/admin/tpl/css/pagination.css b/modules/admin/tpl/css/pagination.css index b71173652..0ba0ff1b0 100755 --- a/modules/admin/tpl/css/pagination.css +++ b/modules/admin/tpl/css/pagination.css @@ -1,5 +1,5 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Platform Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ /* Pagination Reset */ #xeAdmin .pagination{ padding:15px 0; margin:0; text-align:center; clear:both; } diff --git a/modules/autoinstall/autoinstall.admin.controller.php b/modules/autoinstall/autoinstall.admin.controller.php index 20a3c0773..c7ce9772d 100644 --- a/modules/autoinstall/autoinstall.admin.controller.php +++ b/modules/autoinstall/autoinstall.admin.controller.php @@ -1,243 +1,243 @@ -download_path); - } - - function procAutoinstallAdminUpdateinfo() - { - $oModel = &getModel('autoinstall'); - $item = $oModel->getLatestPackage(); - if($item) - { - $params["updatedate"] = $item->updatedate; - } - - $params["act"] = "getResourceapiUpdate"; - $body = XmlGenerater::generate($params); - $buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml"); - $xml = new XmlParser(); - $xmlDoc = $xml->parse($buff); - $this->updateCategory($xmlDoc); - $this->updatePackages($xmlDoc); - $this->checkInstalled(); - - $this->setMessage("success_updated"); - } - - function checkInstalled() - { - executeQuery("autoinstall.deleteInstalledPackage"); - $oModel =& getModel('autoinstall'); - $packages = $oModel->getPackages(); - foreach($packages as $package) - { - $real_path = FileHandler::getRealPath($package->path); - if(!file_exists($real_path)) { - continue; - } - - $type = $oModel->getTypeFromPath($package->path); - if($type == "core") - { - $version = __ZBXE_VERSION__; - } - else - { - $config_file = null; - switch($type) - { - case "m.layout": - $type = "layout"; - case "module": - case "addon": - case "layout": - case "widget": - $config_file = "/conf/info.xml"; - break; - case "component": - $config_file = "/info.xml"; - break; - case "style": - case "m.skin": - $type = "skin"; - case "skin": - case "widgetstyle": - $config_file = "/skin.xml"; - break; - case "drcomponent": - $config_file = "/info.xml"; - $type = "component"; - break; - } - if(!$config_file) continue; - $xml = new XmlParser(); - $xmlDoc = $xml->loadXmlFile($real_path.$config_file); - if(!$xmlDoc) continue; - $version = $xmlDoc->{$type}->version->body; - } - - $args = null; - $args->package_srl = $package->package_srl; - $args->version = $package->version; - $args->current_version = $version; - if(version_compare($args->version, $args->current_version, ">")) - { - $args->need_update="Y"; - } - else - { - $args->need_update="N"; - } - - $output = executeQuery("autoinstall.insertInstalledPackage", $args); - } - } - - function procAutoinstallAdminPackageinstall() - { - set_time_limit(0); - $package_srls = Context::get('package_srl'); - $oModel =& getModel('autoinstall'); - $packages = explode(',', $package_srls); - $ftp_info = Context::getFTPInfo(); - if(!$_SESSION['ftp_password']) - { - $ftp_password = Context::get('ftp_password'); - } - else - { - $ftp_password = $_SESSION['ftp_password']; - } - - foreach($packages as $package_srl) - { - $package = $oModel->getPackage($package_srl); - if($ftp_info->sftp && $ftp_info->sftp == 'Y') - { - $oModuleInstaller = new SFTPModuleInstaller($package); - } - else if(function_exists(ftp_connect)) - { - $oModuleInstaller = new PHPFTPModuleInstaller($package); - } - else - { - $oModuleInstaller = new FTPModuleInstaller($package); - } - - $oModuleInstaller->setPassword($ftp_password); - $output = $oModuleInstaller->install(); - if(!$output->toBool()) return $output; - } - $this->setMessage('success_installed'); - } - - function updatePackages(&$xmlDoc) - { - $oModel =& getModel('autoinstall'); - if(!$xmlDoc->response->packages->item) return; - if(!is_array($xmlDoc->response->packages->item)) - { - $xmlDoc->response->packages->item = array($xmlDoc->response->packages->item); - } - $targets = array('package_srl', 'updatedate', 'latest_item_srl', 'path', 'version', 'category_srl'); - foreach($xmlDoc->response->packages->item as $item) - { - $args = null; - foreach($targets as $target) - { - $args->{$target} = $item->{$target}->body; - } - if($oModel->getPackage($args->package_srl)) - { - $output = executeQuery("autoinstall.updatePackage", $args); - } - else - { - $output = executeQuery("autoinstall.insertPackage", $args); - if(!$output->toBool()) - { - $output = executeQuery("autoinstall.deletePackage", $args); - $output = executeQuery("autoinstall.insertPackage", $args); - } - } - } - } - - function updateCategory(&$xmlDoc) - { - executeQuery("autoinstall.deleteCategory", $args); - $oModel =& getModel('autoinstall'); - if(!is_array($xmlDoc->response->categorylist->item)) - { - $xmlDoc->response->categorylist->item = array($xmlDoc->response->categorylist->item); - } - foreach($xmlDoc->response->categorylist->item as $item) - { - $args = null; - $args->category_srl = $item->category_srl->body; - $args->parent_srl = $item->parent_srl->body; - $args->title = $item->title->body; - executeQuery("autoinstall.insertCategory", $args); - } - } - - function procAutoinstallAdminUninstallPackage() - { - $package_srl = Context::get('package_srl'); - $oModel =& getModel('autoinstall'); - $package = $oModel->getPackage($package_srl); - $path = $package->path; - - if(!$_SESSION['ftp_password']) - { - $ftp_password = Context::get('ftp_password'); - } - else - { - $ftp_password = $_SESSION['ftp_password']; - } - $ftp_info = Context::getFTPInfo(); - - if($ftp_info->sftp && $ftp_info->sftp == 'Y') - { - $oModuleInstaller = new SFTPModuleInstaller($package); - } - else if(function_exists(ftp_connect)) - { - $oModuleInstaller = new PHPFTPModuleInstaller($package); - } - else - { - $oModuleInstaller = new FTPModuleInstaller($package); - } - - $oModuleInstaller->setPassword($ftp_password); - $output = $oModuleInstaller->uninstall(); - if(!$output->toBool()) return $output; - - $this->setMessage('success_deleted'); - } - } -?> +download_path); + } + + function procAutoinstallAdminUpdateinfo() + { + $oModel = &getModel('autoinstall'); + $item = $oModel->getLatestPackage(); + if($item) + { + $params["updatedate"] = $item->updatedate; + } + + $params["act"] = "getResourceapiUpdate"; + $body = XmlGenerater::generate($params); + $buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml"); + $xml = new XmlParser(); + $xmlDoc = $xml->parse($buff); + $this->updateCategory($xmlDoc); + $this->updatePackages($xmlDoc); + $this->checkInstalled(); + + $this->setMessage("success_updated"); + } + + function checkInstalled() + { + executeQuery("autoinstall.deleteInstalledPackage"); + $oModel =& getModel('autoinstall'); + $packages = $oModel->getPackages(); + foreach($packages as $package) + { + $real_path = FileHandler::getRealPath($package->path); + if(!file_exists($real_path)) { + continue; + } + + $type = $oModel->getTypeFromPath($package->path); + if($type == "core") + { + $version = __ZBXE_VERSION__; + } + else + { + $config_file = null; + switch($type) + { + case "m.layout": + $type = "layout"; + case "module": + case "addon": + case "layout": + case "widget": + $config_file = "/conf/info.xml"; + break; + case "component": + $config_file = "/info.xml"; + break; + case "style": + case "m.skin": + $type = "skin"; + case "skin": + case "widgetstyle": + $config_file = "/skin.xml"; + break; + case "drcomponent": + $config_file = "/info.xml"; + $type = "component"; + break; + } + if(!$config_file) continue; + $xml = new XmlParser(); + $xmlDoc = $xml->loadXmlFile($real_path.$config_file); + if(!$xmlDoc) continue; + $version = $xmlDoc->{$type}->version->body; + } + + $args = null; + $args->package_srl = $package->package_srl; + $args->version = $package->version; + $args->current_version = $version; + if(version_compare($args->version, $args->current_version, ">")) + { + $args->need_update="Y"; + } + else + { + $args->need_update="N"; + } + + $output = executeQuery("autoinstall.insertInstalledPackage", $args); + } + } + + function procAutoinstallAdminPackageinstall() + { + set_time_limit(0); + $package_srls = Context::get('package_srl'); + $oModel =& getModel('autoinstall'); + $packages = explode(',', $package_srls); + $ftp_info = Context::getFTPInfo(); + if(!$_SESSION['ftp_password']) + { + $ftp_password = Context::get('ftp_password'); + } + else + { + $ftp_password = $_SESSION['ftp_password']; + } + + foreach($packages as $package_srl) + { + $package = $oModel->getPackage($package_srl); + if($ftp_info->sftp && $ftp_info->sftp == 'Y') + { + $oModuleInstaller = new SFTPModuleInstaller($package); + } + else if(function_exists(ftp_connect)) + { + $oModuleInstaller = new PHPFTPModuleInstaller($package); + } + else + { + $oModuleInstaller = new FTPModuleInstaller($package); + } + + $oModuleInstaller->setPassword($ftp_password); + $output = $oModuleInstaller->install(); + if(!$output->toBool()) return $output; + } + $this->setMessage('success_installed'); + } + + function updatePackages(&$xmlDoc) + { + $oModel =& getModel('autoinstall'); + if(!$xmlDoc->response->packages->item) return; + if(!is_array($xmlDoc->response->packages->item)) + { + $xmlDoc->response->packages->item = array($xmlDoc->response->packages->item); + } + $targets = array('package_srl', 'updatedate', 'latest_item_srl', 'path', 'version', 'category_srl'); + foreach($xmlDoc->response->packages->item as $item) + { + $args = null; + foreach($targets as $target) + { + $args->{$target} = $item->{$target}->body; + } + if($oModel->getPackage($args->package_srl)) + { + $output = executeQuery("autoinstall.updatePackage", $args); + } + else + { + $output = executeQuery("autoinstall.insertPackage", $args); + if(!$output->toBool()) + { + $output = executeQuery("autoinstall.deletePackage", $args); + $output = executeQuery("autoinstall.insertPackage", $args); + } + } + } + } + + function updateCategory(&$xmlDoc) + { + executeQuery("autoinstall.deleteCategory", $args); + $oModel =& getModel('autoinstall'); + if(!is_array($xmlDoc->response->categorylist->item)) + { + $xmlDoc->response->categorylist->item = array($xmlDoc->response->categorylist->item); + } + foreach($xmlDoc->response->categorylist->item as $item) + { + $args = null; + $args->category_srl = $item->category_srl->body; + $args->parent_srl = $item->parent_srl->body; + $args->title = $item->title->body; + executeQuery("autoinstall.insertCategory", $args); + } + } + + function procAutoinstallAdminUninstallPackage() + { + $package_srl = Context::get('package_srl'); + $oModel =& getModel('autoinstall'); + $package = $oModel->getPackage($package_srl); + $path = $package->path; + + if(!$_SESSION['ftp_password']) + { + $ftp_password = Context::get('ftp_password'); + } + else + { + $ftp_password = $_SESSION['ftp_password']; + } + $ftp_info = Context::getFTPInfo(); + + if($ftp_info->sftp && $ftp_info->sftp == 'Y') + { + $oModuleInstaller = new SFTPModuleInstaller($package); + } + else if(function_exists(ftp_connect)) + { + $oModuleInstaller = new PHPFTPModuleInstaller($package); + } + else + { + $oModuleInstaller = new FTPModuleInstaller($package); + } + + $oModuleInstaller->setPassword($ftp_password); + $output = $oModuleInstaller->uninstall(); + if(!$output->toBool()) return $output; + + $this->setMessage('success_deleted'); + } + } +?> diff --git a/modules/autoinstall/autoinstall.admin.view.php b/modules/autoinstall/autoinstall.admin.view.php index c56322ef4..9b594c560 100644 --- a/modules/autoinstall/autoinstall.admin.view.php +++ b/modules/autoinstall/autoinstall.admin.view.php @@ -1,319 +1,319 @@ -module_path); - Context::set('original_site', $this->original_site); - Context::set('uri', $this->uri); - $this->setTemplatePath($template_path); - - $ftp_info = Context::getFTPInfo(); - if(!$ftp_info->ftp_root_path) Context::set('show_ftp_note', true); - else $this->ftp_set = true; - - - $this->dispCategory(); - $oModel = &getModel('autoinstall'); - Context::set('tCount', $oModel->getPackageCount(null)); - Context::set('iCount', $oModel->getInstalledPackageCount()); - } - - function rearrange(&$item, &$targets) - { - $ret = null; - foreach($targets as $target) - { - $ret->{$target} = $item->{$target}->body; - } - return $ret; - } - - function rearranges($items, $packages = null) - { - if(!is_array($items)) $items = array($items); - $item_list = array(); - $targets = array('category_srl', 'package_srl', 'item_screenshot_url', 'package_voted', 'package_voter', 'package_description', 'package_downloaded', 'item_regdate', 'title', 'item_version', 'package_star', 'depfrom'); - $targetpackages = array(); - foreach($items as $item) - { - $targetpackages[$item->package_srl->body] = 0; - } - $oModel = &getModel('autoinstall'); - if($package == null) - $packages = $oModel->getInstalledPackages(array_keys($targetpackages)); - $depto = array(); - foreach($items as $item) - { - $v = $this->rearrange($item, $targets); - if($packages[$v->package_srl]) - { - $v->current_version = $packages[$v->package_srl]->current_version; - $v->need_update = $packages[$v->package_srl]->need_update; - $v->type = $oModel->getTypeFromPath($packages[$v->package_srl]->path); - if($this->ftp_set && $v->depfrom) { - $depfrom = explode("," , $v->depfrom); - foreach($depfrom as $package_srl) - { - $depto[$package_srl][] = $v->package_srl; - } - } - if($v->type == "core") $v->avail_remove = false; - else if($v->type == "module") { - $v->avail_remove = $oModel->checkRemovable($packages[$v->package_srl]->path); - } - else $v->avail_remove = true; - } - $item_list[$v->package_srl] = $v; - } - - if(count($depto) > 0) - { - $installed = $oModel->getInstalledPackages(implode(",", array_keys($depto))); - foreach($installed as $key=>$val) - { - $path = $val->path; - $type = $oModel->getTypeFromPath($path); - if(!$type || $type == "core") continue; - $config_file = $oModel->getConfigFilePath($type); - if(!$config_file) continue; - - $xml = new XmlParser(); - $xmlDoc = $xml->loadXmlFile(FileHandler::getRealPath($path).$config_file); - if(!$xmlDoc) continue; - if($type == "drcomponent") $type = "component"; - if($type == "style" || $type == "m.skin") $type = "skin"; - if($type == "m.layout") $type = "layout"; - $title = $xmlDoc->{$type}->title->body; - $installed[$key]->title = $title; - } - Context::set('installed', $installed); - foreach($installed as $key=>$val) - { - foreach($depto[$key] as $package_srl) - { - $item_list[$package_srl]->avail_remove = false; - $item_list[$package_srl]->deps[] = $key; - } - } - } - - 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() { - $package_srl = Context::get('package_srl'); - if(!$package_srl) return $this->dispAutoinstallAdminIndex(); - - $params["act"] = "getResourceapiInstallInfo"; - $params["package_srl"] = $package_srl; - $xmlDoc = XmlGenerater::getXmlDoc($params); - $oModel = &getModel('autoinstall'); - - $targetpackages = array(); - if($xmlDoc) - { - $xmlPackage =& $xmlDoc->response->package; - $package->package_srl = $xmlPackage->package_srl->body; - $package->title = $xmlPackage->title->body; - $package->package_description = $xmlPackage->package_description->body; - $package->version = $xmlPackage->version->body; - $package->path = $xmlPackage->path->body; - if($xmlPackage->depends) - { - if(!is_array($xmlPackage->depends->item)) $xmlPackage->depends->item = array($xmlPackage->depends->item); - $package->depends = array(); - foreach($xmlPackage->depends->item as $item) - { - $dep_item = null; - $dep_item->package_srl = $item->package_srl->body; - $dep_item->title = $item->title->body; - $dep_item->version = $item->version->body; - $dep_item->path = $item->path->body; - $package->depends[] = $dep_item; - $targetpackages[$dep_item->package_srl] = 1; - } - $packages = $oModel->getInstalledPackages(array_keys($targetpackages)); - $package->deplist = ""; - foreach($package->depends as $key => $dep) - { - if(!$packages[$dep->package_srl]) { - $package->depends[$key]->installed = false; - $package->package_srl .= ",". $dep->package_srl; - } - else { - $package->depends[$key]->installed = true; - $package->depends[$key]->cur_version = $packages[$dep->package_srl]->current_version; - if(version_compare($dep->version, $packages[$dep->package_srl]->current_version, ">")) - { - $package->depends[$key]->need_update = true; - $package->package_srl .= ",". $dep->package_srl; - } - else - { - $package->need_update = false; - } - } - } - } - $installedPackage = $oModel->getInstalledPackage($package_srl); - if($installedPackage) { - $package->installed = true; - $package->cur_version = $installedPackage->current_version; - $package->need_update = version_compare($package->version, $installedPackage->current_version, ">"); - } - - Context::set("package", $package); - } - if(!$_SESSION['ftp_password']) - { - Context::set('need_password', true); - } - $this->setTemplateFile('install'); - } - - function dispAutoinstallAdminIndex() { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('autoinstall'); - $ftp_info = Context::getFTPInfo(); - if(!$ftp_info->ftp_root_path) Context::set('show_ftp_note', true); - - $this->setTemplateFile('index'); - - $params = array(); - $params["act"] = "getResourceapiLastupdate"; - $body = XmlGenerater::generate($params); - $buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml"); - $xml_lUpdate = new XmlParser(); - $lUpdateDoc = $xml_lUpdate->parse($buff); - $updateDate = $lUpdateDoc->response->updatedate->body; - - $oModel = &getModel('autoinstall'); - $item = $oModel->getLatestPackage(); - if(!$item || $item->updatedate < $updateDate || count($this->categories) < 1) - { - Context::set('need_update', true); - return; - } - - - $page = Context::get('page'); - if(!$page) $page = 1; - Context::set('page', $page); - - $order_type = Context::get('order_type'); - if(!in_array($order_type, array('asc', 'desc'))) $order_type = 'desc'; - Context::set('order_type', $order_type); - - $order_target = Context::get('order_target'); - if(!in_array($order_target, array('newest', 'download', 'popular'))) $order_target = 'newest'; - Context::set('order_target', $order_target); - - $search_keyword = Context::get('search_keyword'); - - $childrenList = Context::get('childrenList'); - $category_srl = Context::get('category_srl'); - if($childrenList) $params["category_srl"] = $childrenList; - else if($category_srl) $params["category_srl"] = $category_srl; - - $params["act"] = "getResourceapiPackagelist"; - $params["order_target"] = $order_target; - $params["order_type"] = $order_type; - $params["page"] = $page; - if($search_keyword) - { - $params["search_keyword"] = $search_keyword; - } - $xmlDoc = XmlGenerater::getXmlDoc($params); - if($xmlDoc && $xmlDoc->response->packagelist->item) - { - $item_list = $this->rearranges($xmlDoc->response->packagelist->item); - Context::set('item_list', $item_list); - $array = array('total_count', 'total_page', 'cur_page', 'page_count', 'first_page', 'last_page'); - $page_nav = $this->rearrange($xmlDoc->response->page_navigation, $array); - $page_navigation = new PageHandler($page_nav->total_count, $page_nav->total_page, $page_nav->cur_page, $page_nav->page_count); - Context::set('page_navigation', $page_navigation); - } - - } - - function dispCategory() - { - $oModel = &getModel('autoinstall'); - $this->categories = &$oModel->getCategoryList(); - Context::set('categories', $this->categories); - } - - function dispAutoinstallAdminUninstall() - { - $package_srl = Context::get('package_srl'); - if(!$package_srl) return $this->dispAutoinstallAdminIndex(); - $oModel =& getModel('autoinstall'); - $installedPackage = $oModel->getInstalledPackage($package_srl); - if(!$installedPackage) return $this->dispAutoinstallAdminInstalledPackages(); - - if(!$_SESSION['ftp_password']) - { - Context::set('need_password', true); - } - $installedPackage = $oModel->getPackage($package_srl); - $path = $installedPackage->path; - $type = $oModel->getTypeFromPath($path); - if(!$type || $type == "core") $this->stop("msg_invalid_request"); - $config_file = $oModel->getConfigFilePath($type); - if(!$config_file) $this->stop("msg_invalid_request"); - - $xml = new XmlParser(); - $xmlDoc = $xml->loadXmlFile(FileHandler::getRealPath($path).$config_file); - if(!$xmlDoc) $this->stop("msg_invalid_request"); - if($type == "drcomponent") $type = "component"; - if($type == "style") $type = "skin"; - $title = $xmlDoc->{$type}->title->body; - $installedPackage->title = $title; - $installedPackage->type = $type; - Context::set('package', $installedPackage); - - $this->setTemplateFile('uninstall'); - Context::addJsFilter($this->module_path.'tpl/filter', 'uninstall_package.xml'); - } - } -?> +module_path); + Context::set('original_site', $this->original_site); + Context::set('uri', $this->uri); + $this->setTemplatePath($template_path); + + $ftp_info = Context::getFTPInfo(); + if(!$ftp_info->ftp_root_path) Context::set('show_ftp_note', true); + else $this->ftp_set = true; + + + $this->dispCategory(); + $oModel = &getModel('autoinstall'); + Context::set('tCount', $oModel->getPackageCount(null)); + Context::set('iCount', $oModel->getInstalledPackageCount()); + } + + function rearrange(&$item, &$targets) + { + $ret = null; + foreach($targets as $target) + { + $ret->{$target} = $item->{$target}->body; + } + return $ret; + } + + function rearranges($items, $packages = null) + { + if(!is_array($items)) $items = array($items); + $item_list = array(); + $targets = array('category_srl', 'package_srl', 'item_screenshot_url', 'package_voted', 'package_voter', 'package_description', 'package_downloaded', 'item_regdate', 'title', 'item_version', 'package_star', 'depfrom'); + $targetpackages = array(); + foreach($items as $item) + { + $targetpackages[$item->package_srl->body] = 0; + } + $oModel = &getModel('autoinstall'); + if($package == null) + $packages = $oModel->getInstalledPackages(array_keys($targetpackages)); + $depto = array(); + foreach($items as $item) + { + $v = $this->rearrange($item, $targets); + if($packages[$v->package_srl]) + { + $v->current_version = $packages[$v->package_srl]->current_version; + $v->need_update = $packages[$v->package_srl]->need_update; + $v->type = $oModel->getTypeFromPath($packages[$v->package_srl]->path); + if($this->ftp_set && $v->depfrom) { + $depfrom = explode("," , $v->depfrom); + foreach($depfrom as $package_srl) + { + $depto[$package_srl][] = $v->package_srl; + } + } + if($v->type == "core") $v->avail_remove = false; + else if($v->type == "module") { + $v->avail_remove = $oModel->checkRemovable($packages[$v->package_srl]->path); + } + else $v->avail_remove = true; + } + $item_list[$v->package_srl] = $v; + } + + if(count($depto) > 0) + { + $installed = $oModel->getInstalledPackages(implode(",", array_keys($depto))); + foreach($installed as $key=>$val) + { + $path = $val->path; + $type = $oModel->getTypeFromPath($path); + if(!$type || $type == "core") continue; + $config_file = $oModel->getConfigFilePath($type); + if(!$config_file) continue; + + $xml = new XmlParser(); + $xmlDoc = $xml->loadXmlFile(FileHandler::getRealPath($path).$config_file); + if(!$xmlDoc) continue; + if($type == "drcomponent") $type = "component"; + if($type == "style" || $type == "m.skin") $type = "skin"; + if($type == "m.layout") $type = "layout"; + $title = $xmlDoc->{$type}->title->body; + $installed[$key]->title = $title; + } + Context::set('installed', $installed); + foreach($installed as $key=>$val) + { + foreach($depto[$key] as $package_srl) + { + $item_list[$package_srl]->avail_remove = false; + $item_list[$package_srl]->deps[] = $key; + } + } + } + + 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() { + $package_srl = Context::get('package_srl'); + if(!$package_srl) return $this->dispAutoinstallAdminIndex(); + + $params["act"] = "getResourceapiInstallInfo"; + $params["package_srl"] = $package_srl; + $xmlDoc = XmlGenerater::getXmlDoc($params); + $oModel = &getModel('autoinstall'); + + $targetpackages = array(); + if($xmlDoc) + { + $xmlPackage =& $xmlDoc->response->package; + $package->package_srl = $xmlPackage->package_srl->body; + $package->title = $xmlPackage->title->body; + $package->package_description = $xmlPackage->package_description->body; + $package->version = $xmlPackage->version->body; + $package->path = $xmlPackage->path->body; + if($xmlPackage->depends) + { + if(!is_array($xmlPackage->depends->item)) $xmlPackage->depends->item = array($xmlPackage->depends->item); + $package->depends = array(); + foreach($xmlPackage->depends->item as $item) + { + $dep_item = null; + $dep_item->package_srl = $item->package_srl->body; + $dep_item->title = $item->title->body; + $dep_item->version = $item->version->body; + $dep_item->path = $item->path->body; + $package->depends[] = $dep_item; + $targetpackages[$dep_item->package_srl] = 1; + } + $packages = $oModel->getInstalledPackages(array_keys($targetpackages)); + $package->deplist = ""; + foreach($package->depends as $key => $dep) + { + if(!$packages[$dep->package_srl]) { + $package->depends[$key]->installed = false; + $package->package_srl .= ",". $dep->package_srl; + } + else { + $package->depends[$key]->installed = true; + $package->depends[$key]->cur_version = $packages[$dep->package_srl]->current_version; + if(version_compare($dep->version, $packages[$dep->package_srl]->current_version, ">")) + { + $package->depends[$key]->need_update = true; + $package->package_srl .= ",". $dep->package_srl; + } + else + { + $package->need_update = false; + } + } + } + } + $installedPackage = $oModel->getInstalledPackage($package_srl); + if($installedPackage) { + $package->installed = true; + $package->cur_version = $installedPackage->current_version; + $package->need_update = version_compare($package->version, $installedPackage->current_version, ">"); + } + + Context::set("package", $package); + } + if(!$_SESSION['ftp_password']) + { + Context::set('need_password', true); + } + $this->setTemplateFile('install'); + } + + function dispAutoinstallAdminIndex() { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('autoinstall'); + $ftp_info = Context::getFTPInfo(); + if(!$ftp_info->ftp_root_path) Context::set('show_ftp_note', true); + + $this->setTemplateFile('index'); + + $params = array(); + $params["act"] = "getResourceapiLastupdate"; + $body = XmlGenerater::generate($params); + $buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml"); + $xml_lUpdate = new XmlParser(); + $lUpdateDoc = $xml_lUpdate->parse($buff); + $updateDate = $lUpdateDoc->response->updatedate->body; + + $oModel = &getModel('autoinstall'); + $item = $oModel->getLatestPackage(); + if(!$item || $item->updatedate < $updateDate || count($this->categories) < 1) + { + Context::set('need_update', true); + return; + } + + + $page = Context::get('page'); + if(!$page) $page = 1; + Context::set('page', $page); + + $order_type = Context::get('order_type'); + if(!in_array($order_type, array('asc', 'desc'))) $order_type = 'desc'; + Context::set('order_type', $order_type); + + $order_target = Context::get('order_target'); + if(!in_array($order_target, array('newest', 'download', 'popular'))) $order_target = 'newest'; + Context::set('order_target', $order_target); + + $search_keyword = Context::get('search_keyword'); + + $childrenList = Context::get('childrenList'); + $category_srl = Context::get('category_srl'); + if($childrenList) $params["category_srl"] = $childrenList; + else if($category_srl) $params["category_srl"] = $category_srl; + + $params["act"] = "getResourceapiPackagelist"; + $params["order_target"] = $order_target; + $params["order_type"] = $order_type; + $params["page"] = $page; + if($search_keyword) + { + $params["search_keyword"] = $search_keyword; + } + $xmlDoc = XmlGenerater::getXmlDoc($params); + if($xmlDoc && $xmlDoc->response->packagelist->item) + { + $item_list = $this->rearranges($xmlDoc->response->packagelist->item); + Context::set('item_list', $item_list); + $array = array('total_count', 'total_page', 'cur_page', 'page_count', 'first_page', 'last_page'); + $page_nav = $this->rearrange($xmlDoc->response->page_navigation, $array); + $page_navigation = new PageHandler($page_nav->total_count, $page_nav->total_page, $page_nav->cur_page, $page_nav->page_count); + Context::set('page_navigation', $page_navigation); + } + + } + + function dispCategory() + { + $oModel = &getModel('autoinstall'); + $this->categories = &$oModel->getCategoryList(); + Context::set('categories', $this->categories); + } + + function dispAutoinstallAdminUninstall() + { + $package_srl = Context::get('package_srl'); + if(!$package_srl) return $this->dispAutoinstallAdminIndex(); + $oModel =& getModel('autoinstall'); + $installedPackage = $oModel->getInstalledPackage($package_srl); + if(!$installedPackage) return $this->dispAutoinstallAdminInstalledPackages(); + + if(!$_SESSION['ftp_password']) + { + Context::set('need_password', true); + } + $installedPackage = $oModel->getPackage($package_srl); + $path = $installedPackage->path; + $type = $oModel->getTypeFromPath($path); + if(!$type || $type == "core") $this->stop("msg_invalid_request"); + $config_file = $oModel->getConfigFilePath($type); + if(!$config_file) $this->stop("msg_invalid_request"); + + $xml = new XmlParser(); + $xmlDoc = $xml->loadXmlFile(FileHandler::getRealPath($path).$config_file); + if(!$xmlDoc) $this->stop("msg_invalid_request"); + if($type == "drcomponent") $type = "component"; + if($type == "style") $type = "skin"; + $title = $xmlDoc->{$type}->title->body; + $installedPackage->title = $title; + $installedPackage->type = $type; + Context::set('package', $installedPackage); + + $this->setTemplateFile('uninstall'); + Context::addJsFilter($this->module_path.'tpl/filter', 'uninstall_package.xml'); + } + } +?> diff --git a/modules/autoinstall/autoinstall.class.php b/modules/autoinstall/autoinstall.class.php index 9db02f6d2..a253e3719 100644 --- a/modules/autoinstall/autoinstall.class.php +++ b/modules/autoinstall/autoinstall.class.php @@ -1,87 +1,87 @@ -'; - if(!is_array($params)) return null; - $params["module"] = "resourceapi"; - foreach($params as $key => $val) - { - $xmlDoc .= sprintf("<%s>", $key, $val, $key); - } - $xmlDoc .= ""; - return $xmlDoc; - } - - function getXmlDoc(&$params) - { - $body = XmlGenerater::generate($params); - $buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml"); - if(!$buff) return; - $xml = new XmlParser(); - $xmlDoc = $xml->parse($buff); - return $xmlDoc; - } - } - - class autoinstall extends ModuleObject { - var $uri = "http://download.xpressengine.com/"; - var $original_site = "http://www.xpressengine.com/"; - var $tmp_dir = './files/cache/autoinstall/'; - - /** - * @brief 설치시 추가 작업이 필요할시 구현 - **/ - function moduleInstall() { - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB =& DB::getInstance(); - if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_installed_packages.xml")) - && $oDB->isTableExists("autoinstall_installed_packages")) - { - return true; - } - if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_remote_categories.xml")) - && $oDB->isTableExists("autoinstall_remote_categories")) - { - return true; - } - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB =& DB::getInstance(); - if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_installed_packages.xml")) - && $oDB->isTableExists("autoinstall_installed_packages")) - { - $oDB->dropTable("autoinstall_installed_packages"); - } - if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_remote_categories.xml")) - && $oDB->isTableExists("autoinstall_remote_categories")) - { - $oDB->dropTable("autoinstall_remote_categories"); - } - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - } - } -?> +'; + if(!is_array($params)) return null; + $params["module"] = "resourceapi"; + foreach($params as $key => $val) + { + $xmlDoc .= sprintf("<%s>", $key, $val, $key); + } + $xmlDoc .= ""; + return $xmlDoc; + } + + function getXmlDoc(&$params) + { + $body = XmlGenerater::generate($params); + $buff = FileHandler::getRemoteResource($this->uri, $body, 3, "POST", "application/xml"); + if(!$buff) return; + $xml = new XmlParser(); + $xmlDoc = $xml->parse($buff); + return $xmlDoc; + } + } + + class autoinstall extends ModuleObject { + var $uri = "http://download.xpressengine.com/"; + var $original_site = "http://www.xpressengine.com/"; + var $tmp_dir = './files/cache/autoinstall/'; + + /** + * @brief 설치시 추가 작업이 필요할시 구현 + **/ + function moduleInstall() { + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB =& DB::getInstance(); + if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_installed_packages.xml")) + && $oDB->isTableExists("autoinstall_installed_packages")) + { + return true; + } + if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_remote_categories.xml")) + && $oDB->isTableExists("autoinstall_remote_categories")) + { + return true; + } + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB =& DB::getInstance(); + if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_installed_packages.xml")) + && $oDB->isTableExists("autoinstall_installed_packages")) + { + $oDB->dropTable("autoinstall_installed_packages"); + } + if(!file_exists(FileHandler::getRealPath("./modules/autoinstall/schemas/autoinstall_remote_categories.xml")) + && $oDB->isTableExists("autoinstall_remote_categories")) + { + $oDB->dropTable("autoinstall_remote_categories"); + } + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + } + } +?> diff --git a/modules/autoinstall/autoinstall.model.php b/modules/autoinstall/autoinstall.model.php index 5aab8ceba..3a001ca47 100644 --- a/modules/autoinstall/autoinstall.model.php +++ b/modules/autoinstall/autoinstall.model.php @@ -1,185 +1,185 @@ -category_srl = $category_srl; - $output = executeQueryArray("autoinstall.getCategory", $args); - if(!$output->data) return null; - return array_shift($output->data); - } - - function getPackages() - { - $output = executeQueryArray("autoinstall.getPackages"); - if(!$output->data) return array(); - return $output->data; - } - - function getInstalledPackage($package_srl) - { - $args->package_srl = $package_srl; - $output = executeQueryArray("autoinstall.getInstalledPackage", $args); - if(!$output->data) return null; - return array_shift($output->data); - } - - function getPackage($package_srl) - { - $args->package_srl = $package_srl; - $output = executeQueryArray("autoinstall.getPackage", $args); - if(!$output->data) return null; - return array_shift($output->data); - } - - function getCategoryList() - { - $output = executeQueryArray("autoinstall.getCategories"); - if(!$output->toBool() || !$output->data) return array(); - - $categoryList = array(); - foreach($output->data as $category) - { - $category->children = array(); - $categoryList[$category->category_srl] = $category; - } - - $depth0 = array(); - foreach($categoryList as $key => $category) - { - if($category->parent_srl) - { - $categoryList[$category->parent_srl]->children[] =& $categoryList[$key]; - } - else - { - $depth0[] = $key; - } - } - $resultList = array(); - foreach($depth0 as $category_srl) - { - $this->setDepth($categoryList[$category_srl], 0, $categoryList, $resultList); - } - return $resultList; - } - - function getPackageCount($category_srl) - { - $args->category_srl = $category_srl; - $output = executeQuery("autoinstall.getPackageCount", $args); - if(!$output->data) return 0; - 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) - { - $resultList[$item->category_srl] =& $item; - $item->depth = $depth; - $siblingList = $item->category_srl; - foreach($item->children as $child) - { - $siblingList .= ",".$this->setDepth($list[$child->category_srl], $depth+1, $list, $resultList); - } - if(count($item->children) < 1) - { - $item->nPackages = $this->getPackageCount($item->category_srl); - } - $item->childrenList = $siblingList; - return $siblingList; - } - - function getLatestPackage() { - $output = executeQueryArray("autoinstall.getLatestPackage"); - if(!$output->data) return null; - return array_shift($output->data); - } - - function getInstalledPackages($package_list) { - $args->package_list = $package_list; - $output = executeQueryArray("autoinstall.getInstalledPackages", $args); - $result = array(); - if(!$output->data) return $result; - foreach($output->data as $value) - { - $result[$value->package_srl] = $value; - } - 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; - } - - function getTypeFromPath($path) - { - if(!$path) return null; - if($path == ".") return "core"; - $path_array = explode("/", $path); - $target_name = array_pop($path_array); - $type = substr(array_pop($path_array), 0, -1); - return $type; - } - - function getConfigFilePath($type) - { - $config_file = null; - switch($type) - { - case "m.layout": - case "module": - case "addon": - case "layout": - case "widget": - $config_file = "/conf/info.xml"; - break; - case "component": - $config_file = "/info.xml"; - break; - case "m.skin": - case "skin": - case "widgetstyle": - case "style": - $config_file = "/skin.xml"; - break; - case "drcomponent": - $config_file = "/info.xml"; - break; - } - return $config_file; - } - - function checkRemovable($path) - { - $path_array = explode("/", $path); - $target_name = array_pop($path_array); - $oModule =& getModule($target_name, "class"); - if(!$oModule) return false; - if(method_exists($oModule, "moduleUninstall")) return true; - else return false; - } - - } -?> +category_srl = $category_srl; + $output = executeQueryArray("autoinstall.getCategory", $args); + if(!$output->data) return null; + return array_shift($output->data); + } + + function getPackages() + { + $output = executeQueryArray("autoinstall.getPackages"); + if(!$output->data) return array(); + return $output->data; + } + + function getInstalledPackage($package_srl) + { + $args->package_srl = $package_srl; + $output = executeQueryArray("autoinstall.getInstalledPackage", $args); + if(!$output->data) return null; + return array_shift($output->data); + } + + function getPackage($package_srl) + { + $args->package_srl = $package_srl; + $output = executeQueryArray("autoinstall.getPackage", $args); + if(!$output->data) return null; + return array_shift($output->data); + } + + function getCategoryList() + { + $output = executeQueryArray("autoinstall.getCategories"); + if(!$output->toBool() || !$output->data) return array(); + + $categoryList = array(); + foreach($output->data as $category) + { + $category->children = array(); + $categoryList[$category->category_srl] = $category; + } + + $depth0 = array(); + foreach($categoryList as $key => $category) + { + if($category->parent_srl) + { + $categoryList[$category->parent_srl]->children[] =& $categoryList[$key]; + } + else + { + $depth0[] = $key; + } + } + $resultList = array(); + foreach($depth0 as $category_srl) + { + $this->setDepth($categoryList[$category_srl], 0, $categoryList, $resultList); + } + return $resultList; + } + + function getPackageCount($category_srl) + { + $args->category_srl = $category_srl; + $output = executeQuery("autoinstall.getPackageCount", $args); + if(!$output->data) return 0; + 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) + { + $resultList[$item->category_srl] =& $item; + $item->depth = $depth; + $siblingList = $item->category_srl; + foreach($item->children as $child) + { + $siblingList .= ",".$this->setDepth($list[$child->category_srl], $depth+1, $list, $resultList); + } + if(count($item->children) < 1) + { + $item->nPackages = $this->getPackageCount($item->category_srl); + } + $item->childrenList = $siblingList; + return $siblingList; + } + + function getLatestPackage() { + $output = executeQueryArray("autoinstall.getLatestPackage"); + if(!$output->data) return null; + return array_shift($output->data); + } + + function getInstalledPackages($package_list) { + $args->package_list = $package_list; + $output = executeQueryArray("autoinstall.getInstalledPackages", $args); + $result = array(); + if(!$output->data) return $result; + foreach($output->data as $value) + { + $result[$value->package_srl] = $value; + } + 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; + } + + function getTypeFromPath($path) + { + if(!$path) return null; + if($path == ".") return "core"; + $path_array = explode("/", $path); + $target_name = array_pop($path_array); + $type = substr(array_pop($path_array), 0, -1); + return $type; + } + + function getConfigFilePath($type) + { + $config_file = null; + switch($type) + { + case "m.layout": + case "module": + case "addon": + case "layout": + case "widget": + $config_file = "/conf/info.xml"; + break; + case "component": + $config_file = "/info.xml"; + break; + case "m.skin": + case "skin": + case "widgetstyle": + case "style": + $config_file = "/skin.xml"; + break; + case "drcomponent": + $config_file = "/info.xml"; + break; + } + return $config_file; + } + + function checkRemovable($path) + { + $path_array = explode("/", $path); + $target_name = array_pop($path_array); + $oModule =& getModule($target_name, "class"); + if(!$oModule) return false; + if(method_exists($oModule, "moduleUninstall")) return true; + else return false; + } + + } +?> diff --git a/modules/autoinstall/autoinstall.view.php b/modules/autoinstall/autoinstall.view.php index 6de79151b..a925b30a8 100644 --- a/modules/autoinstall/autoinstall.view.php +++ b/modules/autoinstall/autoinstall.view.php @@ -1,26 +1,26 @@ -install($file, $checksum); - return $output; - } - } -?> +install($file, $checksum); + return $output; + } + } +?> diff --git a/modules/autoinstall/conf/info.xml b/modules/autoinstall/conf/info.xml index 0d727fc3c..c5023dfd9 100644 --- a/modules/autoinstall/conf/info.xml +++ b/modules/autoinstall/conf/info.xml @@ -1,34 +1,26 @@ - - - 쉬운 설치 - EasyInstaller - Cài đặt tự động - 自動安裝 - 安装·更新 - イージーインストール - 관리자 모드에서 클릭으로 모듈/스킨/레이아웃/위젯/위젯스타일 등을 설치하는 모듈입니다. - With this module, you can install and upgrade your programs including modules, skins, layouts, etc., from www.xpressengine.com by one-click. - 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. - 可以藉由此模組安裝、更新程式包括模組、面板、版面等。 - 很方便的在线安装/更新XE相关模块(模块/皮肤/布局/控件/控件样式等)。 - 管理者モードにてクリックだけで、モジュール/スキン/レイアウト/ウィジェット/ウィジェットスタイルのインストールを可能にするモジュールです。 - 0.3 - 2009-11-11 - system - - haneul - haneul - haneul - haneul - haneul - haneul - - - sol - sol - sol - sol - sol - sol - - + + + 쉬운 설치 + EasyInstaller + Cài đặt tự động + 自動安裝 + 安装·更新 + イージーインストール + 관리자 모드에서 클릭으로 모듈/스킨/레이아웃/위젯/위젯스타일 등을 설치하는 모듈입니다. + With this module, you can install and upgrade your programs including modules, skins, layouts, etc., from www.xpressengine.com by one-click. + 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. + 可以藉由此模組安裝、更新程式包括模組、面板、版面等。 + 很方便的在线安装/更新XE相关模块(模块/皮肤/布局/控件/控件样式等)。 + 管理者モードにてクリックだけで、モジュール/スキン/レイアウト/ウィジェット/ウィジェットスタイルのインストールを可能にするモジュールです。 + 0.3 + 2009-11-11 + system + + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/autoinstall/lang/en.lang.php b/modules/autoinstall/lang/en.lang.php index 2cf18f923..128114de0 100644 --- a/modules/autoinstall/lang/en.lang.php +++ b/modules/autoinstall/lang/en.lang.php @@ -1,7 +1,7 @@ UIT Center > Open UI Tech Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ .install{ border-top:1px solid #ddd; *zoom:1;} .install:after{ content:""; display:block; clear:both;} diff --git a/modules/comment/comment.admin.controller.php b/modules/comment/comment.admin.controller.php index 9b6e577be..31081b7b5 100644 --- a/modules/comment/comment.admin.controller.php +++ b/modules/comment/comment.admin.controller.php @@ -1,72 +1,72 @@ -stop('msg_cart_is_null'); - $comment_srl_list= explode('|@|', $cart); - $comment_count = count($comment_srl_list); - if(!$comment_count) return $this->stop('msg_cart_is_null'); - - $oCommentController = &getController('comment'); - - $deleted_count = 0; - - // 글삭제 - for($i=0;$i<$comment_count;$i++) { - $comment_srl = trim($comment_srl_list[$i]); - if(!$comment_srl) continue; - - $output = $oCommentController->deleteComment($comment_srl, true); - if(!$output->toBool()) continue; - - $deleted_count ++; - } - - $this->setMessage( sprintf(Context::getLang('msg_checked_comment_is_deleted'), $deleted_count) ); - } - - /** - * @brief 신고대상을 취소 시킴 - **/ - function procCommentAdminCancelDeclare() { - $comment_srl = trim(Context::get('comment_srl')); - - if($comment_srl) { - $args->comment_srl = $comment_srl; - $output = executeQuery('comment.deleteDeclaredComments', $args); - if(!$output->toBool()) return $output; - } - } - - /** - * @brief 특정 모듈의 모든 댓글 삭제 - **/ - function deleteModuleComments($module_srl) { - $args->module_srl = $module_srl; - $output = executeQuery('comment.deleteModuleComments', $args); - if(!$output->toBool()) return $output; - - $output = executeQuery('comment.deleteModuleCommentsList', $args); - return $output; - } - - } -?> +stop('msg_cart_is_null'); + $comment_srl_list= explode('|@|', $cart); + $comment_count = count($comment_srl_list); + if(!$comment_count) return $this->stop('msg_cart_is_null'); + + $oCommentController = &getController('comment'); + + $deleted_count = 0; + + // 글삭제 + for($i=0;$i<$comment_count;$i++) { + $comment_srl = trim($comment_srl_list[$i]); + if(!$comment_srl) continue; + + $output = $oCommentController->deleteComment($comment_srl, true); + if(!$output->toBool()) continue; + + $deleted_count ++; + } + + $this->setMessage( sprintf(Context::getLang('msg_checked_comment_is_deleted'), $deleted_count) ); + } + + /** + * @brief 신고대상을 취소 시킴 + **/ + function procCommentAdminCancelDeclare() { + $comment_srl = trim(Context::get('comment_srl')); + + if($comment_srl) { + $args->comment_srl = $comment_srl; + $output = executeQuery('comment.deleteDeclaredComments', $args); + if(!$output->toBool()) return $output; + } + } + + /** + * @brief 특정 모듈의 모든 댓글 삭제 + **/ + function deleteModuleComments($module_srl) { + $args->module_srl = $module_srl; + $output = executeQuery('comment.deleteModuleComments', $args); + if(!$output->toBool()) return $output; + + $output = executeQuery('comment.deleteModuleCommentsList', $args); + return $output; + } + + } +?> diff --git a/modules/comment/comment.admin.view.php b/modules/comment/comment.admin.view.php index d65f89429..2cb520bea 100644 --- a/modules/comment/comment.admin.view.php +++ b/modules/comment/comment.admin.view.php @@ -1,83 +1,83 @@ -page = Context::get('page'); ///< 페이지 - $args->list_count = 30; ///< 한페이지에 보여줄 글 수 - $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 - - $args->sort_index = 'list_order'; ///< 소팅 값 - - $args->module_srl = Context::get('module_srl'); - - // 목록 구함, comment->getCommentList 에서 걍 알아서 다 해버리는 구조이다... (아.. 이거 나쁜 버릇인데.. ㅡ.ㅜ 어쩔수 없다) - $oCommentModel = &getModel('comment'); - $output = $oCommentModel->getTotalCommentList($args); - - // 템플릿에 쓰기 위해서 comment_model::getTotalCommentList() 의 return object에 있는 값들을 세팅 - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('comment_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('comment_list'); - } - - /** - * @brief 관리자 페이지의 신고 목록 보기 - **/ - function dispCommentAdminDeclared() { - // 목록을 구하기 위한 옵션 - $args->page = Context::get('page'); ///< 페이지 - $args->list_count = 30; ///< 한페이지에 보여줄 글 수 - $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 - - $args->sort_index = 'comment_declared.declared_count'; ///< 소팅 값 - $args->order_type = 'desc'; ///< 소팅 정렬 값 - - // 목록을 구함 - $declared_output = executeQuery('comment.getDeclaredList', $args); - - if($declared_output->data && count($declared_output->data)) { - $comment_list = array(); - - $oCommentModel = &getModel('comment'); - foreach($declared_output->data as $key => $comment) { - $comment_list[$key] = new commentItem(); - $comment_list[$key]->setAttribute($comment); - } - $declared_output->data = $comment_list; - } - - // 템플릿에 쓰기 위해서 comment_model::getCommentList() 의 return object에 있는 값들을 세팅 - Context::set('total_count', $declared_output->total_count); - Context::set('total_page', $declared_output->total_page); - Context::set('page', $declared_output->page); - Context::set('comment_list', $declared_output->data); - Context::set('page_navigation', $declared_output->page_navigation); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('declared_list'); - } - } -?> +page = Context::get('page'); ///< 페이지 + $args->list_count = 30; ///< 한페이지에 보여줄 글 수 + $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 + + $args->sort_index = 'list_order'; ///< 소팅 값 + + $args->module_srl = Context::get('module_srl'); + + // 목록 구함, comment->getCommentList 에서 걍 알아서 다 해버리는 구조이다... (아.. 이거 나쁜 버릇인데.. ㅡ.ㅜ 어쩔수 없다) + $oCommentModel = &getModel('comment'); + $output = $oCommentModel->getTotalCommentList($args); + + // 템플릿에 쓰기 위해서 comment_model::getTotalCommentList() 의 return object에 있는 값들을 세팅 + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('comment_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('comment_list'); + } + + /** + * @brief 관리자 페이지의 신고 목록 보기 + **/ + function dispCommentAdminDeclared() { + // 목록을 구하기 위한 옵션 + $args->page = Context::get('page'); ///< 페이지 + $args->list_count = 30; ///< 한페이지에 보여줄 글 수 + $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 + + $args->sort_index = 'comment_declared.declared_count'; ///< 소팅 값 + $args->order_type = 'desc'; ///< 소팅 정렬 값 + + // 목록을 구함 + $declared_output = executeQuery('comment.getDeclaredList', $args); + + if($declared_output->data && count($declared_output->data)) { + $comment_list = array(); + + $oCommentModel = &getModel('comment'); + foreach($declared_output->data as $key => $comment) { + $comment_list[$key] = new commentItem(); + $comment_list[$key]->setAttribute($comment); + } + $declared_output->data = $comment_list; + } + + // 템플릿에 쓰기 위해서 comment_model::getCommentList() 의 return object에 있는 값들을 세팅 + Context::set('total_count', $declared_output->total_count); + Context::set('total_page', $declared_output->total_page); + Context::set('page', $declared_output->page); + Context::set('comment_list', $declared_output->data); + Context::set('page_navigation', $declared_output->page_navigation); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('declared_list'); + } + } +?> diff --git a/modules/comment/comment.class.php b/modules/comment/comment.class.php index 6d82c7c53..260d3b1a1 100644 --- a/modules/comment/comment.class.php +++ b/modules/comment/comment.class.php @@ -1,105 +1,105 @@ -insertTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after'); - - // 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가 - $oModuleController->insertTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after'); - - // 2008. 02. 22 모듈의 추가 설정에서 댓글 추가 설정 추가 - $oModuleController->insertTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before'); - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - - // 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록 - if(!$oModuleModel->getTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after')) return true; - - // 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가 - if(!$oModuleModel->getTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after')) return true; - - // 2007. 10. 23 댓글에도 추천/ 알림 기능을 위한 컬럼 추가 - if(!$oDB->isColumnExists("comments","voted_count")) return true; - if(!$oDB->isColumnExists("comments","notify_message")) return true; - - // 2008. 02. 22 모듈의 추가 설정에서 댓글 추가 설정 추가 - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before')) return true; - - // 2008. 05. 14 blamed count 컬럼 추가 - if(!$oDB->isColumnExists("comments", "blamed_count")) return true; - if(!$oDB->isColumnExists("comment_voted_log", "point")) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - - // 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록 - if(!$oModuleModel->getTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after')) - $oModuleController->insertTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after'); - - // 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가 - if(!$oModuleModel->getTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after')) - $oModuleController->insertTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after'); - - // 2007. 10. 23 댓글에도 추천/ 알림 기능을 위한 컬럼 추가 - if(!$oDB->isColumnExists("comments","voted_count")) { - $oDB->addColumn("comments","voted_count", "number","11"); - $oDB->addIndex("comments","idx_voted_count", array("voted_count")); - } - - if(!$oDB->isColumnExists("comments","notify_message")) { - $oDB->addColumn("comments","notify_message", "char","1"); - } - - // 2008. 02. 22 모듈의 추가 설정에서 댓글 추가 설정 추가 - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before')) - $oModuleController->insertTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before'); - - // 2008. 05. 14 blamed count 컬럼 추가 - if(!$oDB->isColumnExists("comments", "blamed_count")) { - $oDB->addColumn('comments', 'blamed_count', 'number', 11, 0, true); - $oDB->addIndex('comments', 'idx_blamed_count', array('blamed_count')); - } - if(!$oDB->isColumnExists("comment_voted_log", "point")) - $oDB->addColumn('comment_voted_log', 'point', 'number', 11, 0, true); - - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - } - } -?> +insertTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after'); + + // 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가 + $oModuleController->insertTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after'); + + // 2008. 02. 22 모듈의 추가 설정에서 댓글 추가 설정 추가 + $oModuleController->insertTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before'); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + + // 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록 + if(!$oModuleModel->getTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after')) return true; + + // 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가 + if(!$oModuleModel->getTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after')) return true; + + // 2007. 10. 23 댓글에도 추천/ 알림 기능을 위한 컬럼 추가 + if(!$oDB->isColumnExists("comments","voted_count")) return true; + if(!$oDB->isColumnExists("comments","notify_message")) return true; + + // 2008. 02. 22 모듈의 추가 설정에서 댓글 추가 설정 추가 + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before')) return true; + + // 2008. 05. 14 blamed count 컬럼 추가 + if(!$oDB->isColumnExists("comments", "blamed_count")) return true; + if(!$oDB->isColumnExists("comment_voted_log", "point")) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + + // 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록 + if(!$oModuleModel->getTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after')) + $oModuleController->insertTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after'); + + // 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가 + if(!$oModuleModel->getTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after')) + $oModuleController->insertTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after'); + + // 2007. 10. 23 댓글에도 추천/ 알림 기능을 위한 컬럼 추가 + if(!$oDB->isColumnExists("comments","voted_count")) { + $oDB->addColumn("comments","voted_count", "number","11"); + $oDB->addIndex("comments","idx_voted_count", array("voted_count")); + } + + if(!$oDB->isColumnExists("comments","notify_message")) { + $oDB->addColumn("comments","notify_message", "char","1"); + } + + // 2008. 02. 22 모듈의 추가 설정에서 댓글 추가 설정 추가 + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before')) + $oModuleController->insertTrigger('module.dispAdditionSetup', 'comment', 'view', 'triggerDispCommentAdditionSetup', 'before'); + + // 2008. 05. 14 blamed count 컬럼 추가 + if(!$oDB->isColumnExists("comments", "blamed_count")) { + $oDB->addColumn('comments', 'blamed_count', 'number', 11, 0, true); + $oDB->addIndex('comments', 'idx_blamed_count', array('blamed_count')); + } + if(!$oDB->isColumnExists("comment_voted_log", "point")) + $oDB->addColumn('comment_voted_log', 'point', 'number', 11, 0, true); + + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + } + } +?> diff --git a/modules/comment/comment.controller.php b/modules/comment/comment.controller.php index 50f162c54..a35b08e51 100644 --- a/modules/comment/comment.controller.php +++ b/modules/comment/comment.controller.php @@ -1,619 +1,619 @@ -updateVotedCount($comment_srl, $point); - } - - /** - * @brief 댓글의 추천을 처리하는 action (Down) - **/ - function procCommentVoteDown() { - if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); - - $comment_srl = Context::get('target_srl'); - if(!$comment_srl) return new Object(-1, 'msg_invalid_request'); - - $point = -1; - return $this->updateVotedCount($comment_srl, $point); - } - - /** - * @brief 댓글이 신고될 경우 호출되는 action - **/ - function procCommentDeclare() { - if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); - - $comment_srl = Context::get('target_srl'); - if(!$comment_srl) return new Object(-1, 'msg_invalid_request'); - - return $this->declaredComment($comment_srl); - } - - /** - * @brief document삭제시 해당 document의 댓글을 삭제하는 trigger - **/ - function triggerDeleteDocumentComments(&$obj) { - $document_srl = $obj->document_srl; - if(!$document_srl) return new Object(); - - return $this->deleteComments($document_srl, true); - } - - /** - * @brief module 삭제시 해당 댓글을 모두 삭제하는 trigger - **/ - function triggerDeleteModuleComments(&$obj) { - $module_srl = $obj->module_srl; - if(!$module_srl) return new Object(); - - $oCommentController = &getAdminController('comment'); - return $oCommentController->deleteModuleComments($module_srl); - } - - /** - * @brief 코멘트의 권한 부여 - * 세션값으로 현 접속상태에서만 사용 가능 - **/ - function addGrant($comment_srl) { - $_SESSION['own_comment'][$comment_srl] = true; - } - - /** - * @brief 댓글 입력 - **/ - function insertComment($obj, $manual_inserted = false) { - $obj->__isupdate = false; - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('comment.insertComment', 'before', $obj); - if(!$output->toBool()) return $output; - - // document_srl에 해당하는 글이 있는지 확인 - $document_srl = $obj->document_srl; - if(!$document_srl) return new Object(-1,'msg_invalid_document'); - - // document model 객체 생성 - $oDocumentModel = &getModel('document'); - - // even for manual_inserted if password exists, md5 it. - if($obj->password) $obj->password = md5($obj->password); - // 원본글을 가져옴 - if(!$manual_inserted) { - $oDocument = $oDocumentModel->getDocument($document_srl); - - if($document_srl != $oDocument->document_srl) return new Object(-1,'msg_invalid_document'); - if($oDocument->isLocked()) return new Object(-1,'msg_invalid_request'); - - if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - - // 로그인 된 회원일 경우 회원의 정보를 입력 - if(Context::get('is_logged')) { - $logged_info = Context::get('logged_info'); - $obj->member_srl = $logged_info->member_srl; - $obj->user_id = $logged_info->user_id; - $obj->user_name = $logged_info->user_name; - $obj->nick_name = $logged_info->nick_name; - $obj->email_address = $logged_info->email_address; - $obj->homepage = $logged_info->homepage; - } - } - - // 로그인정보가 없고 사용자 이름이 없으면 오류 표시 - if(!$logged_info->member_srl && !$obj->nick_name) return new Object(-1,'msg_invalid_request'); - - if(!$obj->comment_srl) $obj->comment_srl = getNextSequence(); - - // 순서를 정함 - $obj->list_order = getNextSequence() * -1; - - // 내용에서 XE만의 태그를 삭제 - $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); - if(Mobile::isFromMobilePhone()) - { - $obj->content = nl2br(htmlspecialchars($obj->content)); - } - if(!$obj->regdate) $obj->regdate = date("YmdHis"); - - // 세션에서 최고 관리자가 아니면 iframe, script 제거 - if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); - - if(!$obj->notify_message) $obj->notify_message = 'N'; - if(!$obj->is_secret) $obj->is_secret = 'N'; - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 댓글 목록 부분을 먼저 입력 - $list_args->comment_srl = $obj->comment_srl; - $list_args->document_srl = $obj->document_srl; - $list_args->module_srl = $obj->module_srl; - $list_args->regdate = $obj->regdate; - - // 부모댓글이 없으면 바로 데이터를 설정 - if(!$obj->parent_srl) { - $list_args->head = $list_args->arrange = $obj->comment_srl; - $list_args->depth = 0; - - // 부모댓글이 있으면 부모글의 정보를 구해옴 - } else { - // 부모댓글의 정보를 구함 - $parent_args->comment_srl = $obj->parent_srl; - $parent_output = executeQuery('comment.getCommentListItem', $parent_args); - - // 부모댓글이 존재하지 않으면 return - if(!$parent_output->toBool() || !$parent_output->data) return; - $parent = $parent_output->data; - - $list_args->head = $parent->head; - $list_args->depth = $parent->depth+1; - - // depth가 2단계 미만이면 별도의 update문 없이 insert만으로 쓰레드 정리 - if($list_args->depth<2) { - $list_args->arrange = $obj->comment_srl; - - // depth가 2단계 이상이면 반업데이트 실행 - } else { - // 부모 댓글과 같은 head를 가지고 depth가 같거나 작은 댓글중 제일 위 댓글을 구함 - $p_args->head = $parent->head; - $p_args->arrange = $parent->arrange; - $p_args->depth = $parent->depth; - $output = executeQuery('comment.getCommentParentNextSibling', $p_args); - - if($output->data->arrange) { - $list_args->arrange = $output->data->arrange; - $output = executeQuery('comment.updateCommentListArrange', $list_args); - } else { - $list_args->arrange = $obj->comment_srl; - } - - } - } - - $output = executeQuery('comment.insertCommentList', $list_args); - if(!$output->toBool()) return $output; - - // 댓글 본문을 입력 - $output = executeQuery('comment.insertComment', $obj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // comment model객체 생성 - $oCommentModel = &getModel('comment'); - - // 해당 글의 전체 댓글 수를 구해옴 - $comment_count = $oCommentModel->getCommentCount($document_srl); - - // document의 controller 객체 생성 - $oDocumentController = &getController('document'); - - // 해당글의 댓글 수를 업데이트 - $output = $oDocumentController->updateCommentCount($document_srl, $comment_count, $obj->nick_name, true); - - // 댓글의 권한을 부여 - $this->addGrant($obj->comment_srl); - - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('comment.insertComment', 'after', $obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - if(!$manual_inserted) { - // 원본글에 알림(notify_message)가 설정되어 있으면 메세지 보냄 - $oDocument->notify(Context::getLang('comment'), $obj->content); - - // 원본 댓글이 있고 원본 댓글에 알림(notify_message)가 있으면 메세지 보냄 - if($obj->parent_srl) { - $oParent = $oCommentModel->getComment($obj->parent_srl); - $oParent->notify(Context::getLang('comment'), $obj->content); - } - } - - - $output->add('comment_srl', $obj->comment_srl); - return $output; - } - - /** - * @brief 댓글 수정 - **/ - function updateComment($obj, $is_admin = false) { - $obj->__isupdate = true; - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('comment.updateComment', 'before', $obj); - if(!$output->toBool()) return $output; - - // comment model 객체 생성 - $oCommentModel = &getModel('comment'); - - // 원본 데이터를 가져옴 - $source_obj = $oCommentModel->getComment($obj->comment_srl); - if(!$source_obj->getMemberSrl()) { - $obj->member_srl = $source_obj->get('member_srl'); - $obj->user_name = $source_obj->get('user_name'); - $obj->nick_name = $source_obj->get('nick_name'); - $obj->email_address = $source_obj->get('email_address'); - $obj->homepage = $source_obj->get('homepage'); - } - - // 권한이 있는지 확인 - if(!$is_admin && !$source_obj->isGranted()) return new Object(-1, 'msg_not_permitted'); - - if($obj->password) $obj->password = md5($obj->password); - if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - - // 로그인 되어 있고 작성자와 수정자가 동일하면 수정자의 정보를 세팅 - if(Context::get('is_logged')) { - $logged_info = Context::get('logged_info'); - if($source_obj->member_srl == $logged_info->member_srl) { - $obj->member_srl = $logged_info->member_srl; - $obj->user_name = $logged_info->user_name; - $obj->nick_name = $logged_info->nick_name; - $obj->email_address = $logged_info->email_address; - $obj->homepage = $logged_info->homepage; - } - } - - // 로그인한 유저가 작성한 글인데 nick_name이 없을 경우 - if($source_obj->get('member_srl')&& !$obj->nick_name) { - $obj->member_srl = $source_obj->get('member_srl'); - $obj->user_name = $source_obj->get('user_name'); - $obj->nick_name = $source_obj->get('nick_name'); - $obj->email_address = $source_obj->get('email_address'); - $obj->homepage = $source_obj->get('homepage'); - } - - - if(!$obj->content) $obj->content = $source_obj->get('content'); - - // 내용에서 XE만의 태그를 삭제 - $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); - - // 세션에서 최고 관리자가 아니면 iframe, script 제거 - if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 업데이트 - $output = executeQuery('comment.updateComment', $obj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('comment.updateComment', 'after', $obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - $output->add('comment_srl', $obj->comment_srl); - return $output; - } - - /** - * @brief 댓글 삭제 - **/ - function deleteComment($comment_srl, $is_admin = false) { - - // comment model 객체 생성 - $oCommentModel = &getModel('comment'); - - // 기존 댓글이 있는지 확인 - $comment = $oCommentModel->getComment($comment_srl); - if($comment->comment_srl != $comment_srl) return new Object(-1, 'msg_invalid_request'); - $document_srl = $comment->document_srl; - - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('comment.deleteComment', 'before', $comment); - if(!$output->toBool()) return $output; - - // 해당 댓글에 child가 있는지 확인 - $child_count = $oCommentModel->getChildCommentCount($comment_srl); - if($child_count>0) return new Object(-1, 'fail_to_delete_have_children'); - - // 권한이 있는지 확인 - if(!$is_admin && !$comment->isGranted()) return new Object(-1, 'msg_not_permitted'); - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 삭제 - $args->comment_srl = $comment_srl; - $output = executeQuery('comment.deleteComment', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - $output = executeQuery('comment.deleteCommentList', $args); - - // 댓글 수를 구해서 업데이트 - $comment_count = $oCommentModel->getCommentCount($document_srl); - - // document의 controller 객체 생성 - $oDocumentController = &getController('document'); - - // 해당글의 댓글 수를 업데이트 - $output = $oDocumentController->updateCommentCount($document_srl, $comment_count, null, false); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('comment.deleteComment', 'after', $comment); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - $output->add('document_srl', $document_srl); - return $output; - } - - /** - * @brief 특정 글의 모든 댓글 삭제 - **/ - function deleteComments($document_srl) { - // document model객체 생성 - $oDocumentModel = &getModel('document'); - $oCommentModel = &getModel('comment'); - - // 권한이 있는지 확인 - $oDocument = $oDocumentModel->getDocument($document_srl); - if(!$oDocument->isExists() || !$oDocument->isGranted()) return new Object(-1, 'msg_not_permitted'); - - // 댓글 목록을 가져와서 일단 trigger만 실행 (일괄 삭제를 해야 하기에 최대한 처리 비용을 줄이기 위한 방법) - $args->document_srl = $document_srl; - $comments = executeQueryArray('comment.getAllComments',$args); - if($comments->data) { - foreach($comments->data as $key => $comment) { - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('comment.deleteComment', 'before', $comment); - if(!$output->toBool()) continue; - - // trigger 호출 (after) - $output = ModuleHandler::triggerCall('comment.deleteComment', 'after', $comment); - if(!$output->toBool()) continue; - } - } - - // 댓글 본문 삭제 - $args->document_srl = $document_srl; - $output = executeQuery('comment.deleteComments', $args); - if(!$output->toBool()) return $output; - - // 댓글 목록 삭제 - $output = executeQuery('comment.deleteCommentsList', $args); - - return $output; - } - - /** - * @brief 해당 comment의 추천수 증가 - **/ - function updateVotedCount($comment_srl, $point = 1) { - if($point > 0) $failed_voted = 'failed_voted'; - else $failed_voted = 'failed_blamed'; - - // 세션 정보에 추천 정보가 있으면 중단 - if($_SESSION['voted_comment'][$comment_srl]) return new Object(-1, 'failed_voted'); - - // 문서 원본을 가져옴 - $oCommentModel = &getModel('comment'); - $oComment = $oCommentModel->getComment($comment_srl, false, false); - - // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 - if($oComment->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { - $_SESSION['voted_comment'][$comment_srl] = true; - return new Object(-1, 'failed_voted'); - } - - // comment의 작성자가 회원일때 조사 - if($oComment->get('member_srl')) { - // member model 객체 생성 - $oMemberModel = &getModel('member'); - $member_srl = $oMemberModel->getLoggedMemberSrl(); - - // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 - if($member_srl && $member_srl == $oComment->get('member_srl')) { - $_SESSION['voted_comment'][$comment_srl] = true; - return new Object(-1, 'failed_voted'); - } - } - - // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 - if($member_srl) { - $args->member_srl = $member_srl; - } else { - $args->ipaddress = $_SERVER['REMOTE_ADDR']; - } - $args->comment_srl = $comment_srl; - $output = executeQuery('comment.getCommentVotedLogInfo', $args); - - // 로그 정보에 추천 로그가 있으면 세션 등록후 패스 - if($output->data->count) { - $_SESSION['voted_comment'][$comment_srl] = true; - return new Object(-1, 'failed_voted'); - } - - // 추천수 업데이트 - if($point < 0) - { - $args->blamed_count = $oComment->get('blamed_count') + $point; - $output = executeQuery('comment.updateBlamedCount', $args); - } - else - { - $args->voted_count = $oComment->get('voted_count') + $point; - $output = executeQuery('comment.updateVotedCount', $args); - } - - // 로그 남기기 - $args->point = $point; - $output = executeQuery('comment.insertCommentVotedLog', $args); - - // 세션 정보에 남김 - $_SESSION['voted_comment'][$comment_srl] = true; - - // 결과 리턴 - if($point > 0) - return new Object(0, 'success_voted'); - else - return new Object(0, 'success_blamed'); - } - - /** - * @brief 댓글 신고 - **/ - function declaredComment($comment_srl) { - // 세션 정보에 신고 정보가 있으면 중단 - if($_SESSION['declared_comment'][$comment_srl]) return new Object(-1, 'failed_declared'); - - // 이미 신고되었는지 검사 - $args->comment_srl = $comment_srl; - $output = executeQuery('comment.getDeclaredComment', $args); - if(!$output->toBool()) return $output; - - // 문서 원본을 가져옴 - $oCommentModel = &getModel('comment'); - $oComment = $oCommentModel->getComment($comment_srl, false, false); - - // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 - if($oComment->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { - $_SESSION['declared_comment'][$comment_srl] = true; - return new Object(-1, 'failed_declared'); - } - - // comment의 작성자가 회원일때 조사 - if($oComment->get('member_srl')) { - // member model 객체 생성 - $oMemberModel = &getModel('member'); - $member_srl = $oMemberModel->getLoggedMemberSrl(); - - // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 - if($member_srl && $member_srl == $oComment->get('member_srl')) { - $_SESSION['declared_comment'][$comment_srl] = true; - return new Object(-1, 'failed_declared'); - } - } - - // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 - if($member_srl) { - $args->member_srl = $member_srl; - } else { - $args->ipaddress = $_SERVER['REMOTE_ADDR']; - } - $args->comment_srl = $comment_srl; - $output = executeQuery('comment.getCommentDeclaredLogInfo', $args); - - // 로그 정보에 신고 로그가 있으면 세션 등록후 패스 - if($output->data->count) { - $_SESSION['declared_comment'][$comment_srl] = true; - return new Object(-1, 'failed_declared'); - } - - // 신고글 추가 - if($output->data->declared_count > 0) $output = executeQuery('comment.updateDeclaredComment', $args); - else $output = executeQuery('comment.insertDeclaredComment', $args); - if(!$output->toBool()) return $output; - - // 로그 남기기 - $output = executeQuery('comment.insertCommentDeclaredLog', $args); - - // 세션 정보에 남김 - $_SESSION['declared_comment'][$comment_srl] = true; - - $this->setMessage('success_declared'); - } - - /** - * @brief 댓글의 이 댓글을.. 클릭시 나타나는 팝업 메뉴를 추가하는 method - **/ - function addCommentPopupMenu($url, $str, $icon = '', $target = 'self') { - $comment_popup_menu_list = Context::get('comment_popup_menu_list'); - if(!is_array($comment_popup_menu_list)) $comment_popup_menu_list = array(); - - $obj->url = $url; - $obj->str = $str; - $obj->icon = $icon; - $obj->target = $target; - $comment_popup_menu_list[] = $obj; - - Context::set('comment_popup_menu_list', $comment_popup_menu_list); - } - - /** - * @brief 댓글의 모듈별 추가 확장 폼을 저장 - **/ - function procCommentInsertModuleConfig() { - $module_srl = Context::get('target_module_srl'); - if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); - else $module_srl = array($module_srl); - - $comment_count = (int)Context::get('comment_count'); - - for($i=0;$isetCommentModuleConfig($srl,$comment_count); - } - - $this->setError(-1); - $this->setMessage('success_updated'); - } - - function setCommentModuleConfig($srl, $comment_count=50){ - $comment_config->comment_count = $comment_count; - $oModuleController = &getController('module'); - $oModuleController->insertModulePartConfig('comment',$srl,$comment_config); - return new Object(); - } - } -?> +updateVotedCount($comment_srl, $point); + } + + /** + * @brief 댓글의 추천을 처리하는 action (Down) + **/ + function procCommentVoteDown() { + if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); + + $comment_srl = Context::get('target_srl'); + if(!$comment_srl) return new Object(-1, 'msg_invalid_request'); + + $point = -1; + return $this->updateVotedCount($comment_srl, $point); + } + + /** + * @brief 댓글이 신고될 경우 호출되는 action + **/ + function procCommentDeclare() { + if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); + + $comment_srl = Context::get('target_srl'); + if(!$comment_srl) return new Object(-1, 'msg_invalid_request'); + + return $this->declaredComment($comment_srl); + } + + /** + * @brief document삭제시 해당 document의 댓글을 삭제하는 trigger + **/ + function triggerDeleteDocumentComments(&$obj) { + $document_srl = $obj->document_srl; + if(!$document_srl) return new Object(); + + return $this->deleteComments($document_srl, true); + } + + /** + * @brief module 삭제시 해당 댓글을 모두 삭제하는 trigger + **/ + function triggerDeleteModuleComments(&$obj) { + $module_srl = $obj->module_srl; + if(!$module_srl) return new Object(); + + $oCommentController = &getAdminController('comment'); + return $oCommentController->deleteModuleComments($module_srl); + } + + /** + * @brief 코멘트의 권한 부여 + * 세션값으로 현 접속상태에서만 사용 가능 + **/ + function addGrant($comment_srl) { + $_SESSION['own_comment'][$comment_srl] = true; + } + + /** + * @brief 댓글 입력 + **/ + function insertComment($obj, $manual_inserted = false) { + $obj->__isupdate = false; + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('comment.insertComment', 'before', $obj); + if(!$output->toBool()) return $output; + + // document_srl에 해당하는 글이 있는지 확인 + $document_srl = $obj->document_srl; + if(!$document_srl) return new Object(-1,'msg_invalid_document'); + + // document model 객체 생성 + $oDocumentModel = &getModel('document'); + + // even for manual_inserted if password exists, md5 it. + if($obj->password) $obj->password = md5($obj->password); + // 원본글을 가져옴 + if(!$manual_inserted) { + $oDocument = $oDocumentModel->getDocument($document_srl); + + if($document_srl != $oDocument->document_srl) return new Object(-1,'msg_invalid_document'); + if($oDocument->isLocked()) return new Object(-1,'msg_invalid_request'); + + if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + + // 로그인 된 회원일 경우 회원의 정보를 입력 + if(Context::get('is_logged')) { + $logged_info = Context::get('logged_info'); + $obj->member_srl = $logged_info->member_srl; + $obj->user_id = $logged_info->user_id; + $obj->user_name = $logged_info->user_name; + $obj->nick_name = $logged_info->nick_name; + $obj->email_address = $logged_info->email_address; + $obj->homepage = $logged_info->homepage; + } + } + + // 로그인정보가 없고 사용자 이름이 없으면 오류 표시 + if(!$logged_info->member_srl && !$obj->nick_name) return new Object(-1,'msg_invalid_request'); + + if(!$obj->comment_srl) $obj->comment_srl = getNextSequence(); + + // 순서를 정함 + $obj->list_order = getNextSequence() * -1; + + // 내용에서 XE만의 태그를 삭제 + $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); + if(Mobile::isFromMobilePhone()) + { + $obj->content = nl2br(htmlspecialchars($obj->content)); + } + if(!$obj->regdate) $obj->regdate = date("YmdHis"); + + // 세션에서 최고 관리자가 아니면 iframe, script 제거 + if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); + + if(!$obj->notify_message) $obj->notify_message = 'N'; + if(!$obj->is_secret) $obj->is_secret = 'N'; + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 댓글 목록 부분을 먼저 입력 + $list_args->comment_srl = $obj->comment_srl; + $list_args->document_srl = $obj->document_srl; + $list_args->module_srl = $obj->module_srl; + $list_args->regdate = $obj->regdate; + + // 부모댓글이 없으면 바로 데이터를 설정 + if(!$obj->parent_srl) { + $list_args->head = $list_args->arrange = $obj->comment_srl; + $list_args->depth = 0; + + // 부모댓글이 있으면 부모글의 정보를 구해옴 + } else { + // 부모댓글의 정보를 구함 + $parent_args->comment_srl = $obj->parent_srl; + $parent_output = executeQuery('comment.getCommentListItem', $parent_args); + + // 부모댓글이 존재하지 않으면 return + if(!$parent_output->toBool() || !$parent_output->data) return; + $parent = $parent_output->data; + + $list_args->head = $parent->head; + $list_args->depth = $parent->depth+1; + + // depth가 2단계 미만이면 별도의 update문 없이 insert만으로 쓰레드 정리 + if($list_args->depth<2) { + $list_args->arrange = $obj->comment_srl; + + // depth가 2단계 이상이면 반업데이트 실행 + } else { + // 부모 댓글과 같은 head를 가지고 depth가 같거나 작은 댓글중 제일 위 댓글을 구함 + $p_args->head = $parent->head; + $p_args->arrange = $parent->arrange; + $p_args->depth = $parent->depth; + $output = executeQuery('comment.getCommentParentNextSibling', $p_args); + + if($output->data->arrange) { + $list_args->arrange = $output->data->arrange; + $output = executeQuery('comment.updateCommentListArrange', $list_args); + } else { + $list_args->arrange = $obj->comment_srl; + } + + } + } + + $output = executeQuery('comment.insertCommentList', $list_args); + if(!$output->toBool()) return $output; + + // 댓글 본문을 입력 + $output = executeQuery('comment.insertComment', $obj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // comment model객체 생성 + $oCommentModel = &getModel('comment'); + + // 해당 글의 전체 댓글 수를 구해옴 + $comment_count = $oCommentModel->getCommentCount($document_srl); + + // document의 controller 객체 생성 + $oDocumentController = &getController('document'); + + // 해당글의 댓글 수를 업데이트 + $output = $oDocumentController->updateCommentCount($document_srl, $comment_count, $obj->nick_name, true); + + // 댓글의 권한을 부여 + $this->addGrant($obj->comment_srl); + + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('comment.insertComment', 'after', $obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + if(!$manual_inserted) { + // 원본글에 알림(notify_message)가 설정되어 있으면 메세지 보냄 + $oDocument->notify(Context::getLang('comment'), $obj->content); + + // 원본 댓글이 있고 원본 댓글에 알림(notify_message)가 있으면 메세지 보냄 + if($obj->parent_srl) { + $oParent = $oCommentModel->getComment($obj->parent_srl); + $oParent->notify(Context::getLang('comment'), $obj->content); + } + } + + + $output->add('comment_srl', $obj->comment_srl); + return $output; + } + + /** + * @brief 댓글 수정 + **/ + function updateComment($obj, $is_admin = false) { + $obj->__isupdate = true; + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('comment.updateComment', 'before', $obj); + if(!$output->toBool()) return $output; + + // comment model 객체 생성 + $oCommentModel = &getModel('comment'); + + // 원본 데이터를 가져옴 + $source_obj = $oCommentModel->getComment($obj->comment_srl); + if(!$source_obj->getMemberSrl()) { + $obj->member_srl = $source_obj->get('member_srl'); + $obj->user_name = $source_obj->get('user_name'); + $obj->nick_name = $source_obj->get('nick_name'); + $obj->email_address = $source_obj->get('email_address'); + $obj->homepage = $source_obj->get('homepage'); + } + + // 권한이 있는지 확인 + if(!$is_admin && !$source_obj->isGranted()) return new Object(-1, 'msg_not_permitted'); + + if($obj->password) $obj->password = md5($obj->password); + if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + + // 로그인 되어 있고 작성자와 수정자가 동일하면 수정자의 정보를 세팅 + if(Context::get('is_logged')) { + $logged_info = Context::get('logged_info'); + if($source_obj->member_srl == $logged_info->member_srl) { + $obj->member_srl = $logged_info->member_srl; + $obj->user_name = $logged_info->user_name; + $obj->nick_name = $logged_info->nick_name; + $obj->email_address = $logged_info->email_address; + $obj->homepage = $logged_info->homepage; + } + } + + // 로그인한 유저가 작성한 글인데 nick_name이 없을 경우 + if($source_obj->get('member_srl')&& !$obj->nick_name) { + $obj->member_srl = $source_obj->get('member_srl'); + $obj->user_name = $source_obj->get('user_name'); + $obj->nick_name = $source_obj->get('nick_name'); + $obj->email_address = $source_obj->get('email_address'); + $obj->homepage = $source_obj->get('homepage'); + } + + + if(!$obj->content) $obj->content = $source_obj->get('content'); + + // 내용에서 XE만의 태그를 삭제 + $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); + + // 세션에서 최고 관리자가 아니면 iframe, script 제거 + if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 업데이트 + $output = executeQuery('comment.updateComment', $obj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('comment.updateComment', 'after', $obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + $output->add('comment_srl', $obj->comment_srl); + return $output; + } + + /** + * @brief 댓글 삭제 + **/ + function deleteComment($comment_srl, $is_admin = false) { + + // comment model 객체 생성 + $oCommentModel = &getModel('comment'); + + // 기존 댓글이 있는지 확인 + $comment = $oCommentModel->getComment($comment_srl); + if($comment->comment_srl != $comment_srl) return new Object(-1, 'msg_invalid_request'); + $document_srl = $comment->document_srl; + + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('comment.deleteComment', 'before', $comment); + if(!$output->toBool()) return $output; + + // 해당 댓글에 child가 있는지 확인 + $child_count = $oCommentModel->getChildCommentCount($comment_srl); + if($child_count>0) return new Object(-1, 'fail_to_delete_have_children'); + + // 권한이 있는지 확인 + if(!$is_admin && !$comment->isGranted()) return new Object(-1, 'msg_not_permitted'); + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 삭제 + $args->comment_srl = $comment_srl; + $output = executeQuery('comment.deleteComment', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + $output = executeQuery('comment.deleteCommentList', $args); + + // 댓글 수를 구해서 업데이트 + $comment_count = $oCommentModel->getCommentCount($document_srl); + + // document의 controller 객체 생성 + $oDocumentController = &getController('document'); + + // 해당글의 댓글 수를 업데이트 + $output = $oDocumentController->updateCommentCount($document_srl, $comment_count, null, false); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('comment.deleteComment', 'after', $comment); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + $output->add('document_srl', $document_srl); + return $output; + } + + /** + * @brief 특정 글의 모든 댓글 삭제 + **/ + function deleteComments($document_srl) { + // document model객체 생성 + $oDocumentModel = &getModel('document'); + $oCommentModel = &getModel('comment'); + + // 권한이 있는지 확인 + $oDocument = $oDocumentModel->getDocument($document_srl); + if(!$oDocument->isExists() || !$oDocument->isGranted()) return new Object(-1, 'msg_not_permitted'); + + // 댓글 목록을 가져와서 일단 trigger만 실행 (일괄 삭제를 해야 하기에 최대한 처리 비용을 줄이기 위한 방법) + $args->document_srl = $document_srl; + $comments = executeQueryArray('comment.getAllComments',$args); + if($comments->data) { + foreach($comments->data as $key => $comment) { + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('comment.deleteComment', 'before', $comment); + if(!$output->toBool()) continue; + + // trigger 호출 (after) + $output = ModuleHandler::triggerCall('comment.deleteComment', 'after', $comment); + if(!$output->toBool()) continue; + } + } + + // 댓글 본문 삭제 + $args->document_srl = $document_srl; + $output = executeQuery('comment.deleteComments', $args); + if(!$output->toBool()) return $output; + + // 댓글 목록 삭제 + $output = executeQuery('comment.deleteCommentsList', $args); + + return $output; + } + + /** + * @brief 해당 comment의 추천수 증가 + **/ + function updateVotedCount($comment_srl, $point = 1) { + if($point > 0) $failed_voted = 'failed_voted'; + else $failed_voted = 'failed_blamed'; + + // 세션 정보에 추천 정보가 있으면 중단 + if($_SESSION['voted_comment'][$comment_srl]) return new Object(-1, 'failed_voted'); + + // 문서 원본을 가져옴 + $oCommentModel = &getModel('comment'); + $oComment = $oCommentModel->getComment($comment_srl, false, false); + + // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 + if($oComment->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { + $_SESSION['voted_comment'][$comment_srl] = true; + return new Object(-1, 'failed_voted'); + } + + // comment의 작성자가 회원일때 조사 + if($oComment->get('member_srl')) { + // member model 객체 생성 + $oMemberModel = &getModel('member'); + $member_srl = $oMemberModel->getLoggedMemberSrl(); + + // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 + if($member_srl && $member_srl == $oComment->get('member_srl')) { + $_SESSION['voted_comment'][$comment_srl] = true; + return new Object(-1, 'failed_voted'); + } + } + + // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 + if($member_srl) { + $args->member_srl = $member_srl; + } else { + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + $args->comment_srl = $comment_srl; + $output = executeQuery('comment.getCommentVotedLogInfo', $args); + + // 로그 정보에 추천 로그가 있으면 세션 등록후 패스 + if($output->data->count) { + $_SESSION['voted_comment'][$comment_srl] = true; + return new Object(-1, 'failed_voted'); + } + + // 추천수 업데이트 + if($point < 0) + { + $args->blamed_count = $oComment->get('blamed_count') + $point; + $output = executeQuery('comment.updateBlamedCount', $args); + } + else + { + $args->voted_count = $oComment->get('voted_count') + $point; + $output = executeQuery('comment.updateVotedCount', $args); + } + + // 로그 남기기 + $args->point = $point; + $output = executeQuery('comment.insertCommentVotedLog', $args); + + // 세션 정보에 남김 + $_SESSION['voted_comment'][$comment_srl] = true; + + // 결과 리턴 + if($point > 0) + return new Object(0, 'success_voted'); + else + return new Object(0, 'success_blamed'); + } + + /** + * @brief 댓글 신고 + **/ + function declaredComment($comment_srl) { + // 세션 정보에 신고 정보가 있으면 중단 + if($_SESSION['declared_comment'][$comment_srl]) return new Object(-1, 'failed_declared'); + + // 이미 신고되었는지 검사 + $args->comment_srl = $comment_srl; + $output = executeQuery('comment.getDeclaredComment', $args); + if(!$output->toBool()) return $output; + + // 문서 원본을 가져옴 + $oCommentModel = &getModel('comment'); + $oComment = $oCommentModel->getComment($comment_srl, false, false); + + // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 + if($oComment->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { + $_SESSION['declared_comment'][$comment_srl] = true; + return new Object(-1, 'failed_declared'); + } + + // comment의 작성자가 회원일때 조사 + if($oComment->get('member_srl')) { + // member model 객체 생성 + $oMemberModel = &getModel('member'); + $member_srl = $oMemberModel->getLoggedMemberSrl(); + + // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 + if($member_srl && $member_srl == $oComment->get('member_srl')) { + $_SESSION['declared_comment'][$comment_srl] = true; + return new Object(-1, 'failed_declared'); + } + } + + // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 + if($member_srl) { + $args->member_srl = $member_srl; + } else { + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + $args->comment_srl = $comment_srl; + $output = executeQuery('comment.getCommentDeclaredLogInfo', $args); + + // 로그 정보에 신고 로그가 있으면 세션 등록후 패스 + if($output->data->count) { + $_SESSION['declared_comment'][$comment_srl] = true; + return new Object(-1, 'failed_declared'); + } + + // 신고글 추가 + if($output->data->declared_count > 0) $output = executeQuery('comment.updateDeclaredComment', $args); + else $output = executeQuery('comment.insertDeclaredComment', $args); + if(!$output->toBool()) return $output; + + // 로그 남기기 + $output = executeQuery('comment.insertCommentDeclaredLog', $args); + + // 세션 정보에 남김 + $_SESSION['declared_comment'][$comment_srl] = true; + + $this->setMessage('success_declared'); + } + + /** + * @brief 댓글의 이 댓글을.. 클릭시 나타나는 팝업 메뉴를 추가하는 method + **/ + function addCommentPopupMenu($url, $str, $icon = '', $target = 'self') { + $comment_popup_menu_list = Context::get('comment_popup_menu_list'); + if(!is_array($comment_popup_menu_list)) $comment_popup_menu_list = array(); + + $obj->url = $url; + $obj->str = $str; + $obj->icon = $icon; + $obj->target = $target; + $comment_popup_menu_list[] = $obj; + + Context::set('comment_popup_menu_list', $comment_popup_menu_list); + } + + /** + * @brief 댓글의 모듈별 추가 확장 폼을 저장 + **/ + function procCommentInsertModuleConfig() { + $module_srl = Context::get('target_module_srl'); + if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); + else $module_srl = array($module_srl); + + $comment_count = (int)Context::get('comment_count'); + + for($i=0;$isetCommentModuleConfig($srl,$comment_count); + } + + $this->setError(-1); + $this->setMessage('success_updated'); + } + + function setCommentModuleConfig($srl, $comment_count=50){ + $comment_config->comment_count = $comment_count; + $oModuleController = &getController('module'); + $oModuleController->insertModulePartConfig('comment',$srl,$comment_config); + return new Object(); + } + } +?> diff --git a/modules/comment/comment.item.php b/modules/comment/comment.item.php index c120c88af..2795ad8a4 100644 --- a/modules/comment/comment.item.php +++ b/modules/comment/comment.item.php @@ -1,7 +1,7 @@ member_srl) { - - // 추천 버튼 추가 - $url = sprintf("doCallModuleAction('comment','procCommentVoteUp','%s')", $comment_srl); - $oCommentController->addCommentPopupMenu($url,'cmd_vote','./modules/document/tpl/icons/vote_up.gif','javascript'); - - // 비추천 버튼 추가 - $url = sprintf("doCallModuleAction('comment','procCommentVoteDown','%s')", $comment_srl); - $oCommentController->addCommentPopupMenu($url,'cmd_vote_down','./modules/document/tpl/icons/vote_down.gif','javascript'); - - // 신고 기능 추가 - $url = sprintf("doCallModuleAction('comment','procCommentDeclare','%s')", $comment_srl); - $oCommentController->addCommentPopupMenu($url,'cmd_declare','./modules/document/tpl/icons/declare.gif','javascript'); - } - - // trigger 호출 (after) - ModuleHandler::triggerCall('comment.getCommentMenu', 'after', $menu_list); - - // 관리자일 경우 ip로 글 찾기 - if($logged_info->is_admin == 'Y') { - $oCommentModel = &getModel('comment'); - $oComment = $oCommentModel->getComment($comment_srl); - - if($oComment->isExists()) { - // ip주소에 해당하는 글 찾기 - $url = getUrl('','module','admin','act','dispCommentAdminList','search_target','ipaddress','search_keyword',$oComment->get('ipaddress')); - $icon_path = './modules/member/tpl/images/icon_management.gif'; - $oCommentController->addCommentPopupMenu($url,'cmd_search_by_ipaddress',$icon_path,'TraceByIpaddress'); - - $url = sprintf("var params = new Array(); params['ipaddress']='%s'; exec_xml('spamfilter', 'procSpamfilterAdminInsertDeniedIP', params, completeCallModuleAction)", $oComment-> getIpAddress()); - $oCommentController->addCommentPopupMenu($url,'cmd_add_ip_to_spamfilter','./modules/document/tpl/icons/declare.gif','javascript'); - } - } - - // 팝업메뉴의 언어 변경 - $menus = Context::get('comment_popup_menu_list'); - $menus_count = count($menus); - for($i=0;$i<$menus_count;$i++) { - $menus[$i]->str = Context::getLang($menus[$i]->str); - } - - // 최종적으로 정리된 팝업메뉴 목록을 구함 - $this->add('menus', $menus); - } - - - /** - * @brief comment_srl에 권한이 있는지 체크 - * - * 세션 정보만 이용 - **/ - function isGranted($comment_srl) { - return $_SESSION['own_comment'][$comment_srl]; - } - - /** - * @brief 자식 답글의 갯수 리턴 - **/ - function getChildCommentCount($comment_srl) { - $args->comment_srl = $comment_srl; - $output = executeQuery('comment.getChildCommentCount', $args); - return (int)$output->data->count; - } - - /** - * @brief 댓글 가져오기 - **/ - function getComment($comment_srl=0, $is_admin = false) { - $oComment = new commentItem($comment_srl); - if($is_admin) $oComment->setGrant(); - - return $oComment; - } - - /** - * @brief 여러개의 댓글들을 가져옴 (페이징 아님) - **/ - function getComments($comment_srl_list) { - if(is_array($comment_srl_list)) $comment_srls = implode(',',$comment_srl_list); - - // DB에서 가져옴 - $args->comment_srls = $comment_srls; - $output = executeQuery('comment.getComments', $args); - if(!$output->toBool()) return; - $comment_list = $output->data; - if(!$comment_list) return; - if(!is_array($comment_list)) $comment_list = array($comment_list); - - $comment_count = count($comment_list); - foreach($comment_list as $key => $attribute) { - if(!$attribute->comment_srl) continue; - $oComment = null; - $oComment = new commentItem(); - $oComment->setAttribute($attribute); - if($is_admin) $oComment->setGrant(); - - $result[$attribute->comment_srl] = $oComment; - } - return $result; - } - - /** - * @brief document_srl 에 해당하는 댓글의 전체 갯수를 가져옴 - **/ - function getCommentCount($document_srl) { - $args->document_srl = $document_srl; - $output = executeQuery('comment.getCommentCount', $args); - $total_count = $output->data->count; - return (int)$total_count; - } - - - /** - * @brief module_srl 에 해당하는 댓글의 전체 갯수를 가져옴 - **/ - function getCommentAllCount($module_srl) { - $args->module_srl = $module_srl; - $output = executeQuery('comment.getCommentCount', $args); - $total_count = $output->data->count; - - return (int)$total_count; - } - - - /** - * @brief mid 에 해당하는 댓글을 가져옴 - **/ - function getNewestCommentList($obj) { - if($obj->mid) { - $oModuleModel = &getModel('module'); - $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); - unset($obj->mid); - } - - // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 - if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); - else $args->module_srl = $obj->module_srl; - $args->list_count = $obj->list_count; - - $output = executeQuery('comment.getNewestCommentList', $args); - if(!$output->toBool()) return $output; - - $comment_list = $output->data; - if($comment_list) { - if(!is_array($comment_list)) $comment_list = array($comment_list); - $comment_count = count($comment_list); - foreach($comment_list as $key => $attribute) { - if(!$attribute->comment_srl) continue; - $oComment = null; - $oComment = new commentItem(); - $oComment->setAttribute($attribute); - - $result[$key] = $oComment; - } - $output->data = $result; - } - return $result; - } - - /** - * @brief document_srl에 해당하는 문서의 댓글 목록을 가져옴 - **/ - function getCommentList($document_srl, $page = 0, $is_admin = false, $count = 0) { - // 해당 문서의 모듈에 해당하는 댓글 수를 구함 - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); - - // 문서가 존재하지 않으면 return~ - if(!$oDocument->isExists()) return; - - // 댓글수가 없으면 return~ - if($oDocument->getCommentCount()<1) return; - - // 정해진 댓글수에 따른 댓글 목록 구함 - $module_srl = $oDocument->get('module_srl'); - - if(!$count) { - $comment_config = $this->getCommentConfig($module_srl); - $comment_count = $comment_config->comment_count; - if(!$comment_count) $comment_count = 50; - } else { - $comment_count = $count; - } - - // 페이지가 없으면 제일 뒤 페이지를 구함 - if(!$page) $page = (int)( ($oDocument->getCommentCount()-1) / $comment_count) + 1; - - // 정해진 수에 따라 목록을 구해옴 - $args->document_srl = $document_srl; - $args->list_count = $comment_count; - $args->page = $page; - $args->page_count = 10; - $output = executeQueryArray('comment.getCommentPageList', $args); - - // 쿼리 결과에서 오류가 생기면 그냥 return - if(!$output->toBool()) return; - - // 만약 구해온 결과값이 저장된 댓글수와 다르다면 기존의 데이터로 판단하고 댓글 목록 테이블에 데이터 입력 - if(!$output->data) { - $this->fixCommentList($oDocument->get('module_srl'), $document_srl); - $output = executeQueryArray('comment.getCommentPageList', $args); - if(!$output->toBool()) return; - } - - return $output; - } - - /** - * @brief document_srl에 해당하는 댓글 목록을 갱신 - * 정식버전 이전에 사용되던 데이터를 위한 처리 - **/ - function fixCommentList($module_srl, $document_srl) { - // 일괄 작업이라서 lock 파일을 생성하여 중복 작업이 되지 않도록 한다 - $lock_file = "./files/cache/tmp/lock.".$document_srl; - if(file_exists($lock_file) && filemtime($lock_file)+60*60*10document_srl = $document_srl; - $args->list_order = 'list_order'; - $output = executeQuery('comment.getCommentList', $args); - if(!$output->toBool()) return $output; - - $source_list = $output->data; - if(!is_array($source_list)) $source_list = array($source_list); - - // 댓글를 계층형 구조로 정렬 - $comment_count = count($source_list); - - $root = NULL; - $list = NULL; - $comment_list = array(); - - // 로그인 사용자의 경우 로그인 정보를 일단 구해 놓음 - $logged_info = Context::get('logged_info'); - - - // loop를 돌면서 코멘트의 계층 구조 만듬 - for($i=$comment_count-1;$i>=0;$i--) { - $comment_srl = $source_list[$i]->comment_srl; - $parent_srl = $source_list[$i]->parent_srl; - if(!$comment_srl) continue; - - // 목록을 만듬 - $list[$comment_srl] = $source_list[$i]; - - if($parent_srl) { - $list[$parent_srl]->child[] = &$list[$comment_srl]; - } else { - $root->child[] = &$list[$comment_srl]; - } - } - $this->_arrangeComment($comment_list, $root->child, 0, null); - - // 구해진 값을 db에 입력함 - if(count($comment_list)) { - foreach($comment_list as $comment_srl => $item) { - $comment_args = null; - $comment_args->comment_srl = $comment_srl; - $comment_args->document_srl = $document_srl; - $comment_args->head = $item->head; - $comment_args->arrange = $item->arrange; - $comment_args->module_srl = $module_srl; - $comment_args->regdate = $item->regdate; - $comment_args->depth = $item->depth; - - executeQuery('comment.insertCommentList', $comment_args); - } - } - - // 성공시 lock파일 제거 - FileHandler::removeFile($lock_file); - } - - /** - * @brief 댓글을 계층형으로 재배치 - **/ - function _arrangeComment(&$comment_list, $list, $depth, $parent = null) { - if(!count($list)) return; - foreach($list as $key => $val) { - - if($parent) $val->head = $parent->head; - else $val->head = $val->comment_srl; - $val->arrange = count($comment_list)+1; - - if($val->child) { - $val->depth = $depth; - $comment_list[$val->comment_srl] = $val; - $this->_arrangeComment($comment_list,$val->child,$depth+1, $val); - unset($val->child); - } else { - $val->depth = $depth; - $comment_list[$val->comment_srl] = $val; - } - } - } - - /** - * @brief 모든 댓글를 시간 역순으로 가져옴 (관리자용) - **/ - function getTotalCommentList($obj) { - $query_id = 'comment.getTotalCommentList'; - - // 변수 설정 - $args->sort_index = 'list_order'; - $args->page = $obj->page?$obj->page:1; - $args->list_count = $obj->list_count?$obj->list_count:20; - $args->page_count = $obj->page_count?$obj->page_count:10; - $args->s_module_srl = $obj->module_srl; - $args->exclude_module_srl = $obj->exclude_module_srl; - - // 검색 옵션 정리 - $search_target = $obj->search_target?$obj->search_target:trim(Context::get('search_target')); - $search_keyword = $obj->search_keyword?$obj->search_keyword:trim(Context::get('search_keyword')); - if($search_target && $search_keyword) { - switch($search_target) { - case 'content' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_content = $search_keyword; - break; - case 'user_id' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_user_id = $search_keyword; - $query_id = 'comment.getTotalCommentListWithinMember'; - $args->sort_index = 'comments.list_order'; - break; - case 'user_name' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_user_name = $search_keyword; - break; - case 'nick_name' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_nick_name = $search_keyword; - break; - case 'email_address' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_email_address = $search_keyword; - break; - case 'homepage' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_homepage = $search_keyword; - break; - case 'regdate' : - $args->s_regdate = $search_keyword; - break; - case 'last_update' : - $args->s_last_upate = $search_keyword; - break; - case 'ipaddress' : - $args->s_ipaddress= $search_keyword; - break; - case 'member_srl' : - $args->{"s_".$search_target} = (int)$search_keyword; - break; - } - } - - // comment.getTotalCommentList 쿼리 실행 - $output = executeQueryArray($query_id, $args); - - // 결과가 없거나 오류 발생시 그냥 return - if(!$output->toBool()||!count($output->data)) return $output; - foreach($output->data as $key => $val) { - unset($_oComment); - $_oComment = new CommentItem(0); - $_oComment->setAttribute($val); - $output->data[$key] = $_oComment; - } - - return $output; - } - - /** - * @brief 모듈별 댓글 설정을 return - **/ - function getCommentConfig($module_srl) { - $oModuleModel = &getModel('module'); - $comment_config = $oModuleModel->getModulePartConfig('comment', $module_srl); - if(!isset($comment_config->comment_count)) $comment_config->comment_count = 50; - return $comment_config; - } - - } -?> +member_srl) { + + // 추천 버튼 추가 + $url = sprintf("doCallModuleAction('comment','procCommentVoteUp','%s')", $comment_srl); + $oCommentController->addCommentPopupMenu($url,'cmd_vote','./modules/document/tpl/icons/vote_up.gif','javascript'); + + // 비추천 버튼 추가 + $url = sprintf("doCallModuleAction('comment','procCommentVoteDown','%s')", $comment_srl); + $oCommentController->addCommentPopupMenu($url,'cmd_vote_down','./modules/document/tpl/icons/vote_down.gif','javascript'); + + // 신고 기능 추가 + $url = sprintf("doCallModuleAction('comment','procCommentDeclare','%s')", $comment_srl); + $oCommentController->addCommentPopupMenu($url,'cmd_declare','./modules/document/tpl/icons/declare.gif','javascript'); + } + + // trigger 호출 (after) + ModuleHandler::triggerCall('comment.getCommentMenu', 'after', $menu_list); + + // 관리자일 경우 ip로 글 찾기 + if($logged_info->is_admin == 'Y') { + $oCommentModel = &getModel('comment'); + $oComment = $oCommentModel->getComment($comment_srl); + + if($oComment->isExists()) { + // ip주소에 해당하는 글 찾기 + $url = getUrl('','module','admin','act','dispCommentAdminList','search_target','ipaddress','search_keyword',$oComment->get('ipaddress')); + $icon_path = './modules/member/tpl/images/icon_management.gif'; + $oCommentController->addCommentPopupMenu($url,'cmd_search_by_ipaddress',$icon_path,'TraceByIpaddress'); + + $url = sprintf("var params = new Array(); params['ipaddress']='%s'; exec_xml('spamfilter', 'procSpamfilterAdminInsertDeniedIP', params, completeCallModuleAction)", $oComment-> getIpAddress()); + $oCommentController->addCommentPopupMenu($url,'cmd_add_ip_to_spamfilter','./modules/document/tpl/icons/declare.gif','javascript'); + } + } + + // 팝업메뉴의 언어 변경 + $menus = Context::get('comment_popup_menu_list'); + $menus_count = count($menus); + for($i=0;$i<$menus_count;$i++) { + $menus[$i]->str = Context::getLang($menus[$i]->str); + } + + // 최종적으로 정리된 팝업메뉴 목록을 구함 + $this->add('menus', $menus); + } + + + /** + * @brief comment_srl에 권한이 있는지 체크 + * + * 세션 정보만 이용 + **/ + function isGranted($comment_srl) { + return $_SESSION['own_comment'][$comment_srl]; + } + + /** + * @brief 자식 답글의 갯수 리턴 + **/ + function getChildCommentCount($comment_srl) { + $args->comment_srl = $comment_srl; + $output = executeQuery('comment.getChildCommentCount', $args); + return (int)$output->data->count; + } + + /** + * @brief 댓글 가져오기 + **/ + function getComment($comment_srl=0, $is_admin = false) { + $oComment = new commentItem($comment_srl); + if($is_admin) $oComment->setGrant(); + + return $oComment; + } + + /** + * @brief 여러개의 댓글들을 가져옴 (페이징 아님) + **/ + function getComments($comment_srl_list) { + if(is_array($comment_srl_list)) $comment_srls = implode(',',$comment_srl_list); + + // DB에서 가져옴 + $args->comment_srls = $comment_srls; + $output = executeQuery('comment.getComments', $args); + if(!$output->toBool()) return; + $comment_list = $output->data; + if(!$comment_list) return; + if(!is_array($comment_list)) $comment_list = array($comment_list); + + $comment_count = count($comment_list); + foreach($comment_list as $key => $attribute) { + if(!$attribute->comment_srl) continue; + $oComment = null; + $oComment = new commentItem(); + $oComment->setAttribute($attribute); + if($is_admin) $oComment->setGrant(); + + $result[$attribute->comment_srl] = $oComment; + } + return $result; + } + + /** + * @brief document_srl 에 해당하는 댓글의 전체 갯수를 가져옴 + **/ + function getCommentCount($document_srl) { + $args->document_srl = $document_srl; + $output = executeQuery('comment.getCommentCount', $args); + $total_count = $output->data->count; + return (int)$total_count; + } + + + /** + * @brief module_srl 에 해당하는 댓글의 전체 갯수를 가져옴 + **/ + function getCommentAllCount($module_srl) { + $args->module_srl = $module_srl; + $output = executeQuery('comment.getCommentCount', $args); + $total_count = $output->data->count; + + return (int)$total_count; + } + + + /** + * @brief mid 에 해당하는 댓글을 가져옴 + **/ + function getNewestCommentList($obj) { + if($obj->mid) { + $oModuleModel = &getModel('module'); + $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); + unset($obj->mid); + } + + // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 + if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); + else $args->module_srl = $obj->module_srl; + $args->list_count = $obj->list_count; + + $output = executeQuery('comment.getNewestCommentList', $args); + if(!$output->toBool()) return $output; + + $comment_list = $output->data; + if($comment_list) { + if(!is_array($comment_list)) $comment_list = array($comment_list); + $comment_count = count($comment_list); + foreach($comment_list as $key => $attribute) { + if(!$attribute->comment_srl) continue; + $oComment = null; + $oComment = new commentItem(); + $oComment->setAttribute($attribute); + + $result[$key] = $oComment; + } + $output->data = $result; + } + return $result; + } + + /** + * @brief document_srl에 해당하는 문서의 댓글 목록을 가져옴 + **/ + function getCommentList($document_srl, $page = 0, $is_admin = false, $count = 0) { + // 해당 문서의 모듈에 해당하는 댓글 수를 구함 + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + // 문서가 존재하지 않으면 return~ + if(!$oDocument->isExists()) return; + + // 댓글수가 없으면 return~ + if($oDocument->getCommentCount()<1) return; + + // 정해진 댓글수에 따른 댓글 목록 구함 + $module_srl = $oDocument->get('module_srl'); + + if(!$count) { + $comment_config = $this->getCommentConfig($module_srl); + $comment_count = $comment_config->comment_count; + if(!$comment_count) $comment_count = 50; + } else { + $comment_count = $count; + } + + // 페이지가 없으면 제일 뒤 페이지를 구함 + if(!$page) $page = (int)( ($oDocument->getCommentCount()-1) / $comment_count) + 1; + + // 정해진 수에 따라 목록을 구해옴 + $args->document_srl = $document_srl; + $args->list_count = $comment_count; + $args->page = $page; + $args->page_count = 10; + $output = executeQueryArray('comment.getCommentPageList', $args); + + // 쿼리 결과에서 오류가 생기면 그냥 return + if(!$output->toBool()) return; + + // 만약 구해온 결과값이 저장된 댓글수와 다르다면 기존의 데이터로 판단하고 댓글 목록 테이블에 데이터 입력 + if(!$output->data) { + $this->fixCommentList($oDocument->get('module_srl'), $document_srl); + $output = executeQueryArray('comment.getCommentPageList', $args); + if(!$output->toBool()) return; + } + + return $output; + } + + /** + * @brief document_srl에 해당하는 댓글 목록을 갱신 + * 정식버전 이전에 사용되던 데이터를 위한 처리 + **/ + function fixCommentList($module_srl, $document_srl) { + // 일괄 작업이라서 lock 파일을 생성하여 중복 작업이 되지 않도록 한다 + $lock_file = "./files/cache/tmp/lock.".$document_srl; + if(file_exists($lock_file) && filemtime($lock_file)+60*60*10document_srl = $document_srl; + $args->list_order = 'list_order'; + $output = executeQuery('comment.getCommentList', $args); + if(!$output->toBool()) return $output; + + $source_list = $output->data; + if(!is_array($source_list)) $source_list = array($source_list); + + // 댓글를 계층형 구조로 정렬 + $comment_count = count($source_list); + + $root = NULL; + $list = NULL; + $comment_list = array(); + + // 로그인 사용자의 경우 로그인 정보를 일단 구해 놓음 + $logged_info = Context::get('logged_info'); + + + // loop를 돌면서 코멘트의 계층 구조 만듬 + for($i=$comment_count-1;$i>=0;$i--) { + $comment_srl = $source_list[$i]->comment_srl; + $parent_srl = $source_list[$i]->parent_srl; + if(!$comment_srl) continue; + + // 목록을 만듬 + $list[$comment_srl] = $source_list[$i]; + + if($parent_srl) { + $list[$parent_srl]->child[] = &$list[$comment_srl]; + } else { + $root->child[] = &$list[$comment_srl]; + } + } + $this->_arrangeComment($comment_list, $root->child, 0, null); + + // 구해진 값을 db에 입력함 + if(count($comment_list)) { + foreach($comment_list as $comment_srl => $item) { + $comment_args = null; + $comment_args->comment_srl = $comment_srl; + $comment_args->document_srl = $document_srl; + $comment_args->head = $item->head; + $comment_args->arrange = $item->arrange; + $comment_args->module_srl = $module_srl; + $comment_args->regdate = $item->regdate; + $comment_args->depth = $item->depth; + + executeQuery('comment.insertCommentList', $comment_args); + } + } + + // 성공시 lock파일 제거 + FileHandler::removeFile($lock_file); + } + + /** + * @brief 댓글을 계층형으로 재배치 + **/ + function _arrangeComment(&$comment_list, $list, $depth, $parent = null) { + if(!count($list)) return; + foreach($list as $key => $val) { + + if($parent) $val->head = $parent->head; + else $val->head = $val->comment_srl; + $val->arrange = count($comment_list)+1; + + if($val->child) { + $val->depth = $depth; + $comment_list[$val->comment_srl] = $val; + $this->_arrangeComment($comment_list,$val->child,$depth+1, $val); + unset($val->child); + } else { + $val->depth = $depth; + $comment_list[$val->comment_srl] = $val; + } + } + } + + /** + * @brief 모든 댓글를 시간 역순으로 가져옴 (관리자용) + **/ + function getTotalCommentList($obj) { + $query_id = 'comment.getTotalCommentList'; + + // 변수 설정 + $args->sort_index = 'list_order'; + $args->page = $obj->page?$obj->page:1; + $args->list_count = $obj->list_count?$obj->list_count:20; + $args->page_count = $obj->page_count?$obj->page_count:10; + $args->s_module_srl = $obj->module_srl; + $args->exclude_module_srl = $obj->exclude_module_srl; + + // 검색 옵션 정리 + $search_target = $obj->search_target?$obj->search_target:trim(Context::get('search_target')); + $search_keyword = $obj->search_keyword?$obj->search_keyword:trim(Context::get('search_keyword')); + if($search_target && $search_keyword) { + switch($search_target) { + case 'content' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_content = $search_keyword; + break; + case 'user_id' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_user_id = $search_keyword; + $query_id = 'comment.getTotalCommentListWithinMember'; + $args->sort_index = 'comments.list_order'; + break; + case 'user_name' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_user_name = $search_keyword; + break; + case 'nick_name' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_nick_name = $search_keyword; + break; + case 'email_address' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_email_address = $search_keyword; + break; + case 'homepage' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_homepage = $search_keyword; + break; + case 'regdate' : + $args->s_regdate = $search_keyword; + break; + case 'last_update' : + $args->s_last_upate = $search_keyword; + break; + case 'ipaddress' : + $args->s_ipaddress= $search_keyword; + break; + case 'member_srl' : + $args->{"s_".$search_target} = (int)$search_keyword; + break; + } + } + + // comment.getTotalCommentList 쿼리 실행 + $output = executeQueryArray($query_id, $args); + + // 결과가 없거나 오류 발생시 그냥 return + if(!$output->toBool()||!count($output->data)) return $output; + foreach($output->data as $key => $val) { + unset($_oComment); + $_oComment = new CommentItem(0); + $_oComment->setAttribute($val); + $output->data[$key] = $_oComment; + } + + return $output; + } + + /** + * @brief 모듈별 댓글 설정을 return + **/ + function getCommentConfig($module_srl) { + $oModuleModel = &getModel('module'); + $comment_config = $oModuleModel->getModulePartConfig('comment', $module_srl); + if(!isset($comment_config->comment_count)) $comment_config->comment_count = 50; + return $comment_config; + } + + } +?> diff --git a/modules/comment/comment.view.php b/modules/comment/comment.view.php index a6c35f2fb..9885cbe8f 100644 --- a/modules/comment/comment.view.php +++ b/modules/comment/comment.view.php @@ -1,48 +1,48 @@ -module_srl; - if(!$current_module_srl) return new Object(); - } - - // 댓글 설정을 구함 - $oCommentModel = &getModel('comment'); - $comment_config = $oCommentModel->getCommentConfig($current_module_srl); - Context::set('comment_config', $comment_config); - - // 그룹 목록을 구함 - $oMemberModel = &getModel('member'); - $group_list = $oMemberModel->getGroups(); - Context::set('group_list', $group_list); - - // 템플릿 파일 지정 - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'comment_module_config'); - $obj .= $tpl; - - return new Object(); - } - } -?> +module_srl; + if(!$current_module_srl) return new Object(); + } + + // 댓글 설정을 구함 + $oCommentModel = &getModel('comment'); + $comment_config = $oCommentModel->getCommentConfig($current_module_srl); + Context::set('comment_config', $comment_config); + + // 그룹 목록을 구함 + $oMemberModel = &getModel('member'); + $group_list = $oMemberModel->getGroups(); + Context::set('group_list', $group_list); + + // 템플릿 파일 지정 + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'comment_module_config'); + $obj .= $tpl; + + return new Object(); + } + } +?> diff --git a/modules/comment/conf/info.xml b/modules/comment/conf/info.xml index 04da5f8b1..fd4d6efe5 100644 --- a/modules/comment/conf/info.xml +++ b/modules/comment/conf/info.xml @@ -1,33 +1,33 @@ - - - 댓글 - コメント - 评论管理 - Comment - Bình luận - Commentarios - Комментарии - 評論 - 게시판이나 블로그등의 댓글을 관리하는 모듈입니다. - 掲示板やブログなどのコメントを管理するモジュールです。 - 管理版面或博客评论的模块。 - Module for managing board/blog's comments - Module quản lý bình luận của bài viết và sổ lưu niệm - Es el módulo para manejar commentarios en blog o boletínes. - Модуль для управления комментариями форума/блога. - 管理討論板或部落格評論的模組。 - 0.1 - 2007-02-28 - content - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 댓글 + コメント + 评论管理 + Comment + Bình luận + Commentarios + Комментарии + 評論 + 게시판이나 블로그등의 댓글을 관리하는 모듈입니다. + 掲示板やブログなどのコメントを管理するモジュールです。 + 管理版面或博客评论的模块。 + Module for managing board/blog's comments + Module quản lý bình luận của bài viết và sổ lưu niệm + Es el módulo para manejar commentarios en blog o boletínes. + Модуль для управления комментариями форума/блога. + 管理討論板或部落格評論的模組。 + 0.1 + 2007-02-28 + content + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/comment/lang/en.lang.php b/modules/comment/lang/en.lang.php index 82d5344c0..8bc6908d1 100644 --- a/modules/comment/lang/en.lang.php +++ b/modules/comment/lang/en.lang.php @@ -1,31 +1,31 @@ - - * @brief comment module's basic language pack - **/ - - $lang->cmd_comment_do = 'I want to'; - - $lang->comment_list = 'Comments List'; - $lang->cmd_delete_checked_comment = 'Delete selected item'; - - $lang->comment_count = 'Number of Comments'; - $lang->about_comment_count = 'Display the comments as much as user inputs the number and it will be moved to the List if the comments are over its number.'; - - $lang->msg_cart_is_null = 'Please select an article to delete'; - $lang->msg_checked_comment_is_deleted = '%d comment(s) is(are) successfully deleted.'; - - $lang->search_target_list = array( - 'content' => 'Content', - 'user_id' => 'ID', - 'user_name' => 'Name', - 'nick_name' => 'Nickname', - 'member_srl' => 'Member Serial', - 'email_address' => 'Email', - 'homepage' => 'Homepage', - 'regdate' => 'Date', - 'last_update' => 'Last update', - 'ipaddress' => 'IP Address', - ); -?> +cmd_comment_do = 'I want to'; + + $lang->comment_list = 'Comments List'; + $lang->cmd_delete_checked_comment = 'Delete selected item'; + + $lang->comment_count = 'Number of Comments'; + $lang->about_comment_count = 'Display the comments as much as user inputs the number and it will be moved to the List if the comments are over its number.'; + + $lang->msg_cart_is_null = 'Please select an article to delete'; + $lang->msg_checked_comment_is_deleted = '%d comment(s) is(are) successfully deleted.'; + + $lang->search_target_list = array( + 'content' => 'Content', + 'user_id' => 'ID', + 'user_name' => 'Name', + 'nick_name' => 'Nickname', + 'member_srl' => 'Member Serial', + 'email_address' => 'Email', + 'homepage' => 'Homepage', + 'regdate' => 'Date', + 'last_update' => 'Last update', + 'ipaddress' => 'IP Address', + ); +?> diff --git a/modules/comment/lang/es.lang.php b/modules/comment/lang/es.lang.php index 699a80c36..d1dfd720b 100644 --- a/modules/comment/lang/es.lang.php +++ b/modules/comment/lang/es.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @sumario Paquete del idioma español para el módulo de comentarios. **/ diff --git a/modules/comment/lang/fr.lang.php b/modules/comment/lang/fr.lang.php index 7fbc3e761..aa9755333 100644 --- a/modules/comment/lang/fr.lang.php +++ b/modules/comment/lang/fr.lang.php @@ -1,32 +1,32 @@ - Traduit par Pierre Duvent - * @brief Paquet du langage en français pour le module de Commentaire - **/ - - $lang->cmd_comment_do = 'Vous voudriez...'; - - $lang->comment_list = 'Liste des Commentaires'; - $lang->cmd_toggle_checked_comment = 'Renverser les choisis'; - $lang->cmd_delete_checked_comment = 'Supprimer les choisis'; - - $lang->comment_count = 'Limite de Commentaires'; - $lang->about_comment_count = 'Quand il y a plus de commentaires, ils seront bougés sur le liste.'; - - $lang->msg_cart_is_null = 'Choisissez un article à supprimer, S.V.P.'; - $lang->msg_checked_comment_is_deleted = '%d commentaire(s) est(sont) supprimé(s) avec succés.'; - - $lang->search_target_list = array( - 'content' => 'Contenu', - 'user_id' => 'Compte', - 'user_name' => 'Nom', - 'nick_name' => 'Surnom', - 'member_srl' => 'Numéro de Série du Membre', - 'email_address' => 'Mél', - 'homepage' => 'Page d\'Accueil', - 'regdate' => 'Jour', - 'last_update' => 'Mise à Jour', - 'ipaddress' => 'Adresse IP', - ); -?> + + * @brief Paquet du langage en français pour le module de Commentaire + **/ + + $lang->cmd_comment_do = 'Vous voudriez...'; + + $lang->comment_list = 'Liste des Commentaires'; + $lang->cmd_toggle_checked_comment = 'Renverser les choisis'; + $lang->cmd_delete_checked_comment = 'Supprimer les choisis'; + + $lang->comment_count = 'Limite de Commentaires'; + $lang->about_comment_count = 'Quand il y a plus de commentaires, ils seront bougés sur le liste.'; + + $lang->msg_cart_is_null = 'Choisissez un article à supprimer, S.V.P.'; + $lang->msg_checked_comment_is_deleted = '%d commentaire(s) est(sont) supprimé(s) avec succés.'; + + $lang->search_target_list = array( + 'content' => 'Contenu', + 'user_id' => 'Compte', + 'user_name' => 'Nom', + 'nick_name' => 'Surnom', + 'member_srl' => 'Numéro de Série du Membre', + 'email_address' => 'Mél', + 'homepage' => 'Page d\'Accueil', + 'regdate' => 'Jour', + 'last_update' => 'Mise à Jour', + 'ipaddress' => 'Adresse IP', + ); +?> diff --git a/modules/comment/lang/jp.lang.php b/modules/comment/lang/jp.lang.php index 30c7d6d6b..3e31a87e1 100644 --- a/modules/comment/lang/jp.lang.php +++ b/modules/comment/lang/jp.lang.php @@ -1,32 +1,32 @@ - 翻訳:RisaPapa、ミニミ、liahona - * @brief コメント(comment) モジュールの基本言語パッケージ - **/ - - $lang->cmd_comment_do = 'このコメントを…'; - - $lang->comment_list = 'コメントリスト'; - $lang->cmd_toggle_checked_comment = '選択項目の反転'; - $lang->cmd_delete_checked_comment = '選択項目削除'; - - $lang->comment_count = 'コメント数'; - $lang->about_comment_count = 'コメントを指定した数だけ表示し、それ以上はリスト化します。'; - - $lang->msg_cart_is_null = '削除するコメントを選択して下さい。'; - $lang->msg_checked_comment_is_deleted = '%d個のコメントを削除しました。'; - - $lang->search_target_list = array( - 'content' => '内容', - 'user_id' => 'ユーザID', - 'user_name' => '名前', - 'nick_name' => 'ニックネーム', - 'member_srl' => '会員番号', - 'email_address' => 'メールアドレス', - 'homepage' => 'ホームページURL', - 'regdate' => '登録日', - 'last_update' => '最終更新日 ', - 'ipaddress' => 'IPアドレス', - ); -?> +cmd_comment_do = 'このコメントを…'; + + $lang->comment_list = 'コメントリスト'; + $lang->cmd_toggle_checked_comment = '選択項目の反転'; + $lang->cmd_delete_checked_comment = '選択項目削除'; + + $lang->comment_count = 'コメント数'; + $lang->about_comment_count = 'コメントを指定した数だけ表示し、それ以上はリスト化します。'; + + $lang->msg_cart_is_null = '削除するコメントを選択して下さい。'; + $lang->msg_checked_comment_is_deleted = '%d個のコメントを削除しました。'; + + $lang->search_target_list = array( + 'content' => '内容', + 'user_id' => 'ユーザID', + 'user_name' => '名前', + 'nick_name' => 'ニックネーム', + 'member_srl' => '会員番号', + 'email_address' => 'メールアドレス', + 'homepage' => 'ホームページURL', + 'regdate' => '登録日', + 'last_update' => '最終更新日 ', + 'ipaddress' => 'IPアドレス', + ); +?> diff --git a/modules/comment/lang/ko.lang.php b/modules/comment/lang/ko.lang.php index 2ffb11b04..589336a4c 100644 --- a/modules/comment/lang/ko.lang.php +++ b/modules/comment/lang/ko.lang.php @@ -1,32 +1,32 @@ - - * @brief 댓글(comment) 모듈의 기본 언어팩 - **/ - - $lang->cmd_comment_do = '이 댓글을...'; - - $lang->comment_list = '댓글 목록'; - $lang->cmd_toggle_checked_comment = '선택항목 반전'; - $lang->cmd_delete_checked_comment = '선택항목 삭제'; - - $lang->comment_count = '댓글 수'; - $lang->about_comment_count = '댓글을 정해진 수 만큼만 표시하고 그 이상일 경우 목록으로 이동할 수 있게 합니다.'; - - $lang->msg_cart_is_null = '삭제할 글을 선택해주세요.'; - $lang->msg_checked_comment_is_deleted = '%d개의 댓글이 삭제되었습니다.'; - - $lang->search_target_list = array( - 'content' => '내용', - 'user_id' => '아이디', - 'user_name' => '이름', - 'nick_name' => '닉네임', - 'member_srl' => '회원 번호', - 'email_address' => '이메일 주소', - 'homepage' => '홈페이지', - 'regdate' => '등록일', - 'last_update' => '최근수정일 ', - 'ipaddress' => 'IP 주소', - ); -?> +cmd_comment_do = '이 댓글을...'; + + $lang->comment_list = '댓글 목록'; + $lang->cmd_toggle_checked_comment = '선택항목 반전'; + $lang->cmd_delete_checked_comment = '선택항목 삭제'; + + $lang->comment_count = '댓글 수'; + $lang->about_comment_count = '댓글을 정해진 수 만큼만 표시하고 그 이상일 경우 목록으로 이동할 수 있게 합니다.'; + + $lang->msg_cart_is_null = '삭제할 글을 선택해주세요.'; + $lang->msg_checked_comment_is_deleted = '%d개의 댓글이 삭제되었습니다.'; + + $lang->search_target_list = array( + 'content' => '내용', + 'user_id' => '아이디', + 'user_name' => '이름', + 'nick_name' => '닉네임', + 'member_srl' => '회원 번호', + 'email_address' => '이메일 주소', + 'homepage' => '홈페이지', + 'regdate' => '등록일', + 'last_update' => '최근수정일 ', + 'ipaddress' => 'IP 주소', + ); +?> diff --git a/modules/comment/lang/ru.lang.php b/modules/comment/lang/ru.lang.php index 26fcfa204..c9151c3f3 100644 --- a/modules/comment/lang/ru.lang.php +++ b/modules/comment/lang/ru.lang.php @@ -1,32 +1,32 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->cmd_comment_do = 'Эту запись...'; - - $lang->comment_list = 'Список записей'; - $lang->cmd_toggle_checked_comment = 'Изменить выбранное'; - $lang->cmd_delete_checked_comment = 'Удалить выбранное'; - - $lang->comment_count = 'Количество ответов'; - $lang->about_comment_count = 'Отображается указанное количество ответов, после превышения этого количества производится переход к списку.'; - - $lang->msg_cart_is_null = 'Пожалуйста, выберите записи для удаления.'; - $lang->msg_checked_comment_is_deleted = '%d записьуспешно удалена'; - - $lang->search_target_list = array( - 'content' => 'Содержание', - 'user_id' => 'ID', - 'user_name' => 'Имя', - 'nick_name' => 'Ник', - 'member_srl' => 'Номер пользователя', - 'email_address' => 'Email адрес', - 'homepage' => 'Домашняя страница', - 'regdate' => 'Дата регистрации', - 'last_update' => 'Дата последнего обновления', - 'ipaddress' => 'IP-адрес', - ); -?> +cmd_comment_do = 'Эту запись...'; + + $lang->comment_list = 'Список записей'; + $lang->cmd_toggle_checked_comment = 'Изменить выбранное'; + $lang->cmd_delete_checked_comment = 'Удалить выбранное'; + + $lang->comment_count = 'Количество ответов'; + $lang->about_comment_count = 'Отображается указанное количество ответов, после превышения этого количества производится переход к списку.'; + + $lang->msg_cart_is_null = 'Пожалуйста, выберите записи для удаления.'; + $lang->msg_checked_comment_is_deleted = '%d записьуспешно удалена'; + + $lang->search_target_list = array( + 'content' => 'Содержание', + 'user_id' => 'ID', + 'user_name' => 'Имя', + 'nick_name' => 'Ник', + 'member_srl' => 'Номер пользователя', + 'email_address' => 'Email адрес', + 'homepage' => 'Домашняя страница', + 'regdate' => 'Дата регистрации', + 'last_update' => 'Дата последнего обновления', + 'ipaddress' => 'IP-адрес', + ); +?> diff --git a/modules/comment/lang/vi.lang.php b/modules/comment/lang/vi.lang.php index 4e14623c0..da0a75ca0 100644 --- a/modules/comment/lang/vi.lang.php +++ b/modules/comment/lang/vi.lang.php @@ -1,33 +1,33 @@ -cmd_comment_do = 'Bình chọn / Phê bình'; - - $lang->comment_list = 'Danh sách bình luận'; - $lang->cmd_delete_checked_comment = 'Xóa những bình luận đã chọn'; - - $lang->comment_count = 'Số bình luận'; - $lang->about_comment_count = 'Hiển thị số bình luận được gửi, và nó sẽ tạo một danh sách nếu có nhiều bình luận.'; - - $lang->msg_cart_is_null = 'Xin hãy chọn một bài viết để xóa.'; - $lang->msg_checked_comment_is_deleted = '%d bình luận đã được xóa.'; - - $lang->search_target_list = array( - 'content' => 'Nội dung', - 'user_id' => 'ID người gửi', - 'user_name' => 'Tên', - 'nick_name' => 'Nickname', - 'member_srl' => 'Mã số người gửi', - 'email_address' => 'Email', - 'homepage' => 'Trang chủ', - 'regdate' => 'Ngày', - 'last_update' => 'Cập nhật lần cuối', - 'ipaddress' => 'IP', - ); -?> +cmd_comment_do = 'Bình chọn / Phê bình'; + + $lang->comment_list = 'Danh sách bình luận'; + $lang->cmd_delete_checked_comment = 'Xóa những bình luận đã chọn'; + + $lang->comment_count = 'Số bình luận'; + $lang->about_comment_count = 'Hiển thị số bình luận được gửi, và nó sẽ tạo một danh sách nếu có nhiều bình luận.'; + + $lang->msg_cart_is_null = 'Xin hãy chọn một bài viết để xóa.'; + $lang->msg_checked_comment_is_deleted = '%d bình luận đã được xóa.'; + + $lang->search_target_list = array( + 'content' => 'Nội dung', + 'user_id' => 'ID người gửi', + 'user_name' => 'Tên', + 'nick_name' => 'Nickname', + 'member_srl' => 'Mã số người gửi', + 'email_address' => 'Email', + 'homepage' => 'Trang chủ', + 'regdate' => 'Ngày', + 'last_update' => 'Cập nhật lần cuối', + 'ipaddress' => 'IP', + ); +?> diff --git a/modules/comment/lang/zh-CN.lang.php b/modules/comment/lang/zh-CN.lang.php index cc2782b50..b0790bcbd 100644 --- a/modules/comment/lang/zh-CN.lang.php +++ b/modules/comment/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 评论(comment)模块语言包 **/ diff --git a/modules/comment/lang/zh-TW.lang.php b/modules/comment/lang/zh-TW.lang.php index 524caed1b..370d6ca5a 100644 --- a/modules/comment/lang/zh-TW.lang.php +++ b/modules/comment/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 評論(comment)模組正體中文語言 **/ diff --git a/modules/communication/communication.admin.controller.php b/modules/communication/communication.admin.controller.php index 9f89afd59..9dfdf0c11 100644 --- a/modules/communication/communication.admin.controller.php +++ b/modules/communication/communication.admin.controller.php @@ -1,7 +1,7 @@ loadSkinInfo($this->module_path, $skin); - Context::set('skin_info', $skin_info); - - $oModuleModel = &getModel('module'); - $communication_config = $oModuleModel->getModuleConfig('communication'); - if(!$communication_config->colorset) $communication_config->colorset = "white"; - Context::set('communication_config', $communication_config); - - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'colorset_list'); - } - - $this->add('tpl', $tpl); - } - - } -?> +loadSkinInfo($this->module_path, $skin); + Context::set('skin_info', $skin_info); + + $oModuleModel = &getModel('module'); + $communication_config = $oModuleModel->getModuleConfig('communication'); + if(!$communication_config->colorset) $communication_config->colorset = "white"; + Context::set('communication_config', $communication_config); + + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'colorset_list'); + } + + $this->add('tpl', $tpl); + } + + } +?> diff --git a/modules/communication/communication.admin.view.php b/modules/communication/communication.admin.view.php index 315a6efd7..5b893a025 100644 --- a/modules/communication/communication.admin.view.php +++ b/modules/communication/communication.admin.view.php @@ -1,40 +1,40 @@ -getConfig() ); - - // 에디터 스킨 목록을 구함 - Context::set('editor_skin_list', $oEditorModel->getEditorSkinList() ); - - // 커뮤니케이션 스킨 목록을 구함 - Context::set('communication_skin_list', $oModuleModel->getSkins($this->module_path) ); - - // template 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('index'); - } - - } -?> +getConfig() ); + + // 에디터 스킨 목록을 구함 + Context::set('editor_skin_list', $oEditorModel->getEditorSkinList() ); + + // 커뮤니케이션 스킨 목록을 구함 + Context::set('communication_skin_list', $oModuleModel->getSkins($this->module_path) ); + + // template 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('index'); + } + + } +?> diff --git a/modules/communication/communication.class.php b/modules/communication/communication.class.php index bcf44e2ec..caec94eb5 100644 --- a/modules/communication/communication.class.php +++ b/modules/communication/communication.class.php @@ -1,42 +1,42 @@ - + diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 6fa907465..15ebfa1af 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -1,418 +1,418 @@ -allow_message = Context::get('allow_message'); - if(!in_array($args->allow_message, array('Y','N','F'))) $args->allow_message = 'Y'; - - $logged_info = Context::get('logged_info'); - $args->member_srl = $logged_info->member_srl; - - $output = executeQuery('communication.updateAllowMessage', $args); - - return $output; - } - - /** - * @brief 쪽지 발송 - **/ - function procCommunicationSendMessage() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 검사 - $receiver_srl = Context::get('receiver_srl'); - if(!$receiver_srl) return new Object(-1, 'msg_not_exists_member'); - - $title = trim(Context::get('title')); - if(!$title) return new Object(-1, 'msg_title_is_null'); - - $content = trim(Context::get('content')); - if(!$content) return new Object(-1, 'msg_content_is_null'); - - $send_mail = Context::get('send_mail'); - if($send_mail != 'Y') $send_mail = 'N'; - - // 받을 회원이 있는지에 대한 검사 - $oMemberModel = &getModel('member'); - $oCommunicationModel = &getModel('communication'); - $receiver_member_info = $oMemberModel->getMemberInfoByMemberSrl($receiver_srl); - if($receiver_member_info->member_srl != $receiver_srl) return new Object(-1, 'msg_not_exists_member'); - - // 받을 회원의 쪽지 수신여부 검사 (최고관리자이면 패스) - if($logged_info->is_admin != 'Y') { - if($receiver_member_info->allow_message == 'F') { - if(!$oCommunicationModel->isFriend($receiver_member_info->member_srl)) return new object(-1, 'msg_allow_message_to_friend'); - } elseif($receiver_member_info->allow_messge == 'N') { - return new object(-1, 'msg_disallow_message'); - } - } - - // 쪽지 발송 - $output = $this->sendMessage($logged_info->member_srl, $receiver_srl, $title, $content); - - // 메일로도 발송 - if($output->toBool() && $send_mail == 'Y') { - $view_url = Context::getRequestUri(); - $content = sprintf("%s

From :
%s",$content, $view_url, $view_url); - $oMail = new Mail(); - $oMail->setTitle($title); - $oMail->setContent($content); - $oMail->setSender($logged_info->user_name, $logged_info->email_address); - $oMail->setReceiptor($receiver_member_info->user_name, $receiver_member_info->email_address); - $oMail->send(); - } - - return $output; - } - - function sendMessage($sender_srl, $receiver_srl, $title, $content, $sender_log = true) { - $content = removeHackTag($content); - $title = htmlspecialchars($title); - - // 보내는 사용자의 쪽지함에 넣을 쪽지 - $sender_args->sender_srl = $sender_srl; - $sender_args->receiver_srl = $receiver_srl; - $sender_args->message_type = 'S'; - $sender_args->title = $title; - $sender_args->content = $content; - $sender_args->readed = 'N'; - $sender_args->regdate = date("YmdHis"); - $sender_args->related_srl = getNextSequence(); - $sender_args->message_srl = getNextSequence(); - $sender_args->list_order = getNextSequence()*-1; - - // 받는 회원의 쪽지함에 넣을 쪽지 - $receiver_args->message_srl = $sender_args->related_srl; - $receiver_args->related_srl = 0; - $receiver_args->list_order = $sender_args->related_srl*-1; - $receiver_args->sender_srl = $sender_srl; - if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl; - $receiver_args->receiver_srl = $receiver_srl; - $receiver_args->message_type = 'R'; - $receiver_args->title = $title; - $receiver_args->content = $content; - $receiver_args->readed = 'N'; - $receiver_args->regdate = date("YmdHis"); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 발송하는 회원의 쪽지함에 넣을 쪽지 - if($sender_srl && $sender_log) { - $output = executeQuery('communication.sendMessage', $sender_args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - } - - // 받을 회원의 쪽지함에 넣을 쪽지 - $output = executeQuery('communication.sendMessage', $receiver_args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 받는 회원의 쪽지 발송 플래그 생성 (파일로 생성) - $flag_path = './files/member_extra_info/new_message_flags/'.getNumberingPath($receiver_srl); - FileHandler::makeDir($flag_path); - $flag_file = sprintf('%s%s', $flag_path, $receiver_srl); - $flag_count = FileHandler::readFile($flag_file); - FileHandler::writeFile($flag_file, ++$flag_count); - - $oDB->commit(); - - return new Object(0,'success_sended'); - } - - /** - * @brief 특정 쪽지를 보관함으로 보냄 - **/ - function procCommunicationStoreMessage() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 체크 - $message_srl = Context::get('message_srl'); - if(!$message_srl) return new Object(-1,'msg_invalid_request'); - - // 쪽지를 가져옴 - $oCommunicationModel = &getModel('communication'); - $message = $oCommunicationModel->getSelectedMessage($message_srl); - if(!$message || $message->message_type != 'R') return new Object(-1,'msg_invalid_request'); - - $args->message_srl = $message_srl; - $args->receiver_srl = $logged_info->member_srl; - $output = executeQuery('communication.setMessageStored', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_registed'); - } - - /** - * @brief 쪽지 삭제 - **/ - function procCommunicationDeleteMessage() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - // 변수 체크 - $message_srl = Context::get('message_srl'); - if(!$message_srl) return new Object(-1,'msg_invalid_request'); - - // 쪽지를 가져옴 - $oCommunicationModel = &getModel('communication'); - $message = $oCommunicationModel->getSelectedMessage($message_srl); - if(!$message) return new Object(-1,'msg_invalid_request'); - - // 발송인+type=S or 수신인+type=R 검사 - if($message->sender_srl == $member_srl && $message->message_type == 'S') { - if(!$message_srl) return new Object(-1, 'msg_invalid_request'); - } elseif($message->receiver_srl == $member_srl && $message->message_type == 'R') { - if(!$message_srl) return new Object(-1, 'msg_invalid_request'); - } - - // 삭제 - $args->message_srl = $message_srl; - $output = executeQuery('communication.deleteMessage', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_deleted'); - } - - /** - * @brief 선택된 다수의 쪽지 삭제 - **/ - function procCommunicationDeleteMessages() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - // 변수 체크 - $message_srl_list = trim(Context::get('message_srl_list')); - if(!$message_srl_list) return new Object(-1, 'msg_cart_is_null'); - - $message_srl_list = explode('|@|', $message_srl_list); - if(!count($message_srl_list)) return new Object(-1, 'msg_cart_is_null'); - - $message_type = Context::get('message_type'); - if(!$message_type || !in_array($message_type, array('R','S','T'))) return new Object(-1, 'msg_invalid_request'); - - $message_count = count($message_srl_list); - $target = array(); - for($i=0;$i<$message_count;$i++) { - $message_srl = (int)trim($message_srl_list[$i]); - if(!$message_srl) continue; - $target[] = $message_srl; - } - if(!count($target)) return new Object(-1,'msg_cart_is_null'); - - // 삭제 - $args->message_srls = implode(',',$target); - $args->message_type = $message_type; - - if($message_type == 'S') $args->sender_srl = $member_srl; - else $args->receiver_srl = $member_srl; - - $output = executeQuery('communication.deleteMessages', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_deleted'); - } - - /** - * @brief 친구 추가 - **/ - function procCommunicationAddFriend() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - $target_srl = (int)trim(Context::get('target_srl')); - if(!$target_srl) return new Object(-1,'msg_invalid_request'); - - // 변수 정리 - $args->friend_srl = getNextSequence(); - $args->list_order = $args->friend_srl * -1; - $args->friend_group_srl = Context::get('friend_group_srl'); - $args->member_srl = $logged_info->member_srl; - $args->target_srl = $target_srl; - $output = executeQuery('communication.addFriend', $args); - if(!$output->toBool()) return $output; - - $this->add('member_srl', $target_srl); - $this->setMessage('success_registed'); - } - - /** - * @brief 등록된 친구의 그룹 이동 - **/ - function procCommunicationMoveFriend() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 체크 - $friend_srl_list = trim(Context::get('friend_srl_list')); - if(!$friend_srl_list) return new Object(-1, 'msg_cart_is_null'); - - $friend_srl_list = explode('|@|', $friend_srl_list); - if(!count($friend_srl_list)) return new Object(-1, 'msg_cart_is_null'); - - $friend_count = count($friend_srl_list); - $target = array(); - for($i=0;$i<$friend_count;$i++) { - $friend_srl = (int)trim($friend_srl_list[$i]); - if(!$friend_srl) continue; - $target[] = $friend_srl; - } - if(!count($target)) return new Object(-1,'msg_cart_is_null'); - - // 변수 정리 - $args->friend_srls = implode(',',$target); - $args->member_srl = $logged_info->member_srl; - $args->friend_group_srl = Context::get('target_friend_group_srl'); - - $output = executeQuery('communication.moveFriend', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_moved'); - } - - /** - * @brief 친구 삭제 - **/ - function procCommunicationDeleteFriend() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - // 변수 체크 - $friend_srl_list = trim(Context::get('friend_srl_list')); - if(!$friend_srl_list) return new Object(-1, 'msg_cart_is_null'); - - $friend_srl_list = explode('|@|', $friend_srl_list); - if(!count($friend_srl_list)) return new Object(-1, 'msg_cart_is_null'); - - $friend_count = count($friend_srl_list); - $target = array(); - for($i=0;$i<$friend_count;$i++) { - $friend_srl = (int)trim($friend_srl_list[$i]); - if(!$friend_srl) continue; - $target[] = $friend_srl; - } - if(!count($target)) return new Object(-1,'msg_cart_is_null'); - - // 삭제 - $args->friend_srls = implode(',',$target); - $args->member_srl = $logged_info->member_srl; - $output = executeQuery('communication.deleteFriend', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_deleted'); - } - - /** - * @brief 친구 그룹 추가 - **/ - function procCommunicationAddFriendGroup() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 정리 - $args->friend_group_srl = trim(Context::get('friend_group_srl')); - $args->member_srl = $logged_info->member_srl; - $args->title = Context::get('title'); - $args->title = htmlspecialchars($args->title); - if(!$args->title) return new Object(-1, 'msg_invalid_request'); - - // friend_group_srl이 있으면 수정 - if($args->friend_group_srl) { - $output = executeQuery('communication.renameFriendGroup', $args); - $msg_code = 'success_updated'; - - // 아니면 입력 - } else { - $output = executeQuery('communication.addFriendGroup', $args); - $msg_code = 'success_registed'; - } - - if(!$output->toBool()) return $output; - - $this->setMessage($msg_code); - } - - /** - * @brief 친구 그룹 이름 변경 - **/ - function procCommunicationRenameFriendGroup() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 정리 - $args->friend_group_srl= Context::get('friend_group_srl'); - $args->member_srl = $logged_info->member_srl; - $args->title = Context::get('title'); - $args->title = htmlspecialchars($args->title); - if(!$args->title) return new Object(-1, 'msg_invalid_request'); - - $output = executeQuery('communication.renameFriendGroup', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_updated'); - } - - /** - * @brief 친구 그룹 삭제 - **/ - function procCommunicationDeleteFriendGroup() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 정리 - $args->friend_group_srl = Context::get('friend_group_srl'); - $args->member_srl = $logged_info->member_srl; - $output = executeQuery('communication.deleteFriendGroup', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_deleted'); - } - - /** - * @brief 특정 쪽지의 상태를 읽은 상태로 변경 - **/ - function setMessageReaded($message_srl) { - $args->message_srl = $message_srl; - $args->related_srl = $message_srl; - return executeQuery('communication.setMessageReaded', $args); - } - - } -?> +allow_message = Context::get('allow_message'); + if(!in_array($args->allow_message, array('Y','N','F'))) $args->allow_message = 'Y'; + + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + + $output = executeQuery('communication.updateAllowMessage', $args); + + return $output; + } + + /** + * @brief 쪽지 발송 + **/ + function procCommunicationSendMessage() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 검사 + $receiver_srl = Context::get('receiver_srl'); + if(!$receiver_srl) return new Object(-1, 'msg_not_exists_member'); + + $title = trim(Context::get('title')); + if(!$title) return new Object(-1, 'msg_title_is_null'); + + $content = trim(Context::get('content')); + if(!$content) return new Object(-1, 'msg_content_is_null'); + + $send_mail = Context::get('send_mail'); + if($send_mail != 'Y') $send_mail = 'N'; + + // 받을 회원이 있는지에 대한 검사 + $oMemberModel = &getModel('member'); + $oCommunicationModel = &getModel('communication'); + $receiver_member_info = $oMemberModel->getMemberInfoByMemberSrl($receiver_srl); + if($receiver_member_info->member_srl != $receiver_srl) return new Object(-1, 'msg_not_exists_member'); + + // 받을 회원의 쪽지 수신여부 검사 (최고관리자이면 패스) + if($logged_info->is_admin != 'Y') { + if($receiver_member_info->allow_message == 'F') { + if(!$oCommunicationModel->isFriend($receiver_member_info->member_srl)) return new object(-1, 'msg_allow_message_to_friend'); + } elseif($receiver_member_info->allow_messge == 'N') { + return new object(-1, 'msg_disallow_message'); + } + } + + // 쪽지 발송 + $output = $this->sendMessage($logged_info->member_srl, $receiver_srl, $title, $content); + + // 메일로도 발송 + if($output->toBool() && $send_mail == 'Y') { + $view_url = Context::getRequestUri(); + $content = sprintf("%s

From : %s",$content, $view_url, $view_url); + $oMail = new Mail(); + $oMail->setTitle($title); + $oMail->setContent($content); + $oMail->setSender($logged_info->user_name, $logged_info->email_address); + $oMail->setReceiptor($receiver_member_info->user_name, $receiver_member_info->email_address); + $oMail->send(); + } + + return $output; + } + + function sendMessage($sender_srl, $receiver_srl, $title, $content, $sender_log = true) { + $content = removeHackTag($content); + $title = htmlspecialchars($title); + + // 보내는 사용자의 쪽지함에 넣을 쪽지 + $sender_args->sender_srl = $sender_srl; + $sender_args->receiver_srl = $receiver_srl; + $sender_args->message_type = 'S'; + $sender_args->title = $title; + $sender_args->content = $content; + $sender_args->readed = 'N'; + $sender_args->regdate = date("YmdHis"); + $sender_args->related_srl = getNextSequence(); + $sender_args->message_srl = getNextSequence(); + $sender_args->list_order = getNextSequence()*-1; + + // 받는 회원의 쪽지함에 넣을 쪽지 + $receiver_args->message_srl = $sender_args->related_srl; + $receiver_args->related_srl = 0; + $receiver_args->list_order = $sender_args->related_srl*-1; + $receiver_args->sender_srl = $sender_srl; + if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl; + $receiver_args->receiver_srl = $receiver_srl; + $receiver_args->message_type = 'R'; + $receiver_args->title = $title; + $receiver_args->content = $content; + $receiver_args->readed = 'N'; + $receiver_args->regdate = date("YmdHis"); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 발송하는 회원의 쪽지함에 넣을 쪽지 + if($sender_srl && $sender_log) { + $output = executeQuery('communication.sendMessage', $sender_args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + } + + // 받을 회원의 쪽지함에 넣을 쪽지 + $output = executeQuery('communication.sendMessage', $receiver_args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 받는 회원의 쪽지 발송 플래그 생성 (파일로 생성) + $flag_path = './files/member_extra_info/new_message_flags/'.getNumberingPath($receiver_srl); + FileHandler::makeDir($flag_path); + $flag_file = sprintf('%s%s', $flag_path, $receiver_srl); + $flag_count = FileHandler::readFile($flag_file); + FileHandler::writeFile($flag_file, ++$flag_count); + + $oDB->commit(); + + return new Object(0,'success_sended'); + } + + /** + * @brief 특정 쪽지를 보관함으로 보냄 + **/ + function procCommunicationStoreMessage() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 체크 + $message_srl = Context::get('message_srl'); + if(!$message_srl) return new Object(-1,'msg_invalid_request'); + + // 쪽지를 가져옴 + $oCommunicationModel = &getModel('communication'); + $message = $oCommunicationModel->getSelectedMessage($message_srl); + if(!$message || $message->message_type != 'R') return new Object(-1,'msg_invalid_request'); + + $args->message_srl = $message_srl; + $args->receiver_srl = $logged_info->member_srl; + $output = executeQuery('communication.setMessageStored', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_registed'); + } + + /** + * @brief 쪽지 삭제 + **/ + function procCommunicationDeleteMessage() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + // 변수 체크 + $message_srl = Context::get('message_srl'); + if(!$message_srl) return new Object(-1,'msg_invalid_request'); + + // 쪽지를 가져옴 + $oCommunicationModel = &getModel('communication'); + $message = $oCommunicationModel->getSelectedMessage($message_srl); + if(!$message) return new Object(-1,'msg_invalid_request'); + + // 발송인+type=S or 수신인+type=R 검사 + if($message->sender_srl == $member_srl && $message->message_type == 'S') { + if(!$message_srl) return new Object(-1, 'msg_invalid_request'); + } elseif($message->receiver_srl == $member_srl && $message->message_type == 'R') { + if(!$message_srl) return new Object(-1, 'msg_invalid_request'); + } + + // 삭제 + $args->message_srl = $message_srl; + $output = executeQuery('communication.deleteMessage', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_deleted'); + } + + /** + * @brief 선택된 다수의 쪽지 삭제 + **/ + function procCommunicationDeleteMessages() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + // 변수 체크 + $message_srl_list = trim(Context::get('message_srl_list')); + if(!$message_srl_list) return new Object(-1, 'msg_cart_is_null'); + + $message_srl_list = explode('|@|', $message_srl_list); + if(!count($message_srl_list)) return new Object(-1, 'msg_cart_is_null'); + + $message_type = Context::get('message_type'); + if(!$message_type || !in_array($message_type, array('R','S','T'))) return new Object(-1, 'msg_invalid_request'); + + $message_count = count($message_srl_list); + $target = array(); + for($i=0;$i<$message_count;$i++) { + $message_srl = (int)trim($message_srl_list[$i]); + if(!$message_srl) continue; + $target[] = $message_srl; + } + if(!count($target)) return new Object(-1,'msg_cart_is_null'); + + // 삭제 + $args->message_srls = implode(',',$target); + $args->message_type = $message_type; + + if($message_type == 'S') $args->sender_srl = $member_srl; + else $args->receiver_srl = $member_srl; + + $output = executeQuery('communication.deleteMessages', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_deleted'); + } + + /** + * @brief 친구 추가 + **/ + function procCommunicationAddFriend() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + $target_srl = (int)trim(Context::get('target_srl')); + if(!$target_srl) return new Object(-1,'msg_invalid_request'); + + // 변수 정리 + $args->friend_srl = getNextSequence(); + $args->list_order = $args->friend_srl * -1; + $args->friend_group_srl = Context::get('friend_group_srl'); + $args->member_srl = $logged_info->member_srl; + $args->target_srl = $target_srl; + $output = executeQuery('communication.addFriend', $args); + if(!$output->toBool()) return $output; + + $this->add('member_srl', $target_srl); + $this->setMessage('success_registed'); + } + + /** + * @brief 등록된 친구의 그룹 이동 + **/ + function procCommunicationMoveFriend() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 체크 + $friend_srl_list = trim(Context::get('friend_srl_list')); + if(!$friend_srl_list) return new Object(-1, 'msg_cart_is_null'); + + $friend_srl_list = explode('|@|', $friend_srl_list); + if(!count($friend_srl_list)) return new Object(-1, 'msg_cart_is_null'); + + $friend_count = count($friend_srl_list); + $target = array(); + for($i=0;$i<$friend_count;$i++) { + $friend_srl = (int)trim($friend_srl_list[$i]); + if(!$friend_srl) continue; + $target[] = $friend_srl; + } + if(!count($target)) return new Object(-1,'msg_cart_is_null'); + + // 변수 정리 + $args->friend_srls = implode(',',$target); + $args->member_srl = $logged_info->member_srl; + $args->friend_group_srl = Context::get('target_friend_group_srl'); + + $output = executeQuery('communication.moveFriend', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_moved'); + } + + /** + * @brief 친구 삭제 + **/ + function procCommunicationDeleteFriend() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + // 변수 체크 + $friend_srl_list = trim(Context::get('friend_srl_list')); + if(!$friend_srl_list) return new Object(-1, 'msg_cart_is_null'); + + $friend_srl_list = explode('|@|', $friend_srl_list); + if(!count($friend_srl_list)) return new Object(-1, 'msg_cart_is_null'); + + $friend_count = count($friend_srl_list); + $target = array(); + for($i=0;$i<$friend_count;$i++) { + $friend_srl = (int)trim($friend_srl_list[$i]); + if(!$friend_srl) continue; + $target[] = $friend_srl; + } + if(!count($target)) return new Object(-1,'msg_cart_is_null'); + + // 삭제 + $args->friend_srls = implode(',',$target); + $args->member_srl = $logged_info->member_srl; + $output = executeQuery('communication.deleteFriend', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_deleted'); + } + + /** + * @brief 친구 그룹 추가 + **/ + function procCommunicationAddFriendGroup() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 정리 + $args->friend_group_srl = trim(Context::get('friend_group_srl')); + $args->member_srl = $logged_info->member_srl; + $args->title = Context::get('title'); + $args->title = htmlspecialchars($args->title); + if(!$args->title) return new Object(-1, 'msg_invalid_request'); + + // friend_group_srl이 있으면 수정 + if($args->friend_group_srl) { + $output = executeQuery('communication.renameFriendGroup', $args); + $msg_code = 'success_updated'; + + // 아니면 입력 + } else { + $output = executeQuery('communication.addFriendGroup', $args); + $msg_code = 'success_registed'; + } + + if(!$output->toBool()) return $output; + + $this->setMessage($msg_code); + } + + /** + * @brief 친구 그룹 이름 변경 + **/ + function procCommunicationRenameFriendGroup() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 정리 + $args->friend_group_srl= Context::get('friend_group_srl'); + $args->member_srl = $logged_info->member_srl; + $args->title = Context::get('title'); + $args->title = htmlspecialchars($args->title); + if(!$args->title) return new Object(-1, 'msg_invalid_request'); + + $output = executeQuery('communication.renameFriendGroup', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_updated'); + } + + /** + * @brief 친구 그룹 삭제 + **/ + function procCommunicationDeleteFriendGroup() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 정리 + $args->friend_group_srl = Context::get('friend_group_srl'); + $args->member_srl = $logged_info->member_srl; + $output = executeQuery('communication.deleteFriendGroup', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_deleted'); + } + + /** + * @brief 특정 쪽지의 상태를 읽은 상태로 변경 + **/ + function setMessageReaded($message_srl) { + $args->message_srl = $message_srl; + $args->related_srl = $message_srl; + return executeQuery('communication.setMessageReaded', $args); + } + + } +?> diff --git a/modules/communication/communication.model.php b/modules/communication/communication.model.php index f79e6b113..f24a6974b 100644 --- a/modules/communication/communication.model.php +++ b/modules/communication/communication.model.php @@ -1,189 +1,189 @@ -getModuleConfig('communication'); - - if(!$communication_config->skin) $communication_config->skin = 'default'; - if(!$communication_config->colorset) $communication_config->colorset = 'white'; - if(!$communication_config->editor_skin) $communication_config->editor_skin = 'default'; - - return $communication_config; - } - - /** - * @brief 쪽지 내용을 가져옴 - **/ - function getSelectedMessage($message_srl) { - $logged_info = Context::get('logged_info'); - - $args->message_srl = $message_srl; - $output = executeQuery('communication.getMessage',$args); - $message = $output->data; - if(!$message) return ; - - // 보낸 쪽지일 경우 받는 사람 정보를 구함 - $oMemberModel = &getModel('member'); - if($message->sender_srl == $logged_info->member_srl && $message->message_type == 'S') $member_info = $oMemberModel->getMemberInfoByMemberSrl($message->receiver_srl); - - // 보관/받은 쪽지일 경우 보낸 사람 정보를 구함 - else $member_info = $oMemberModel->getMemberInfoByMemberSrl($message->sender_srl); - - if($member_info) { - foreach($member_info as $key => $val) { - if($key != 'regdate') $message->{$key} = $val; - } - } - - // 받은 쪽지이고 아직 읽지 않았을 경우 읽은 상태로 변경 - if($message->message_type == 'R' && $message->readed != 'Y') { - $oCommunicationController = &getController('communication'); - $oCommunicationController->setMessageReaded($message_srl); - } - - - return $message; - } - - /** - * @brief 새 쪽지를 가져옴 - **/ - function getNewMessage() { - $logged_info = Context::get('logged_info'); - $args->receiver_srl = $logged_info->member_srl; - $args->readed = 'N'; - - $output = executeQuery('communication.getNewMessage', $args); - if(!count($output->data)) return; - $message = array_pop($output->data); - - $oCommunicationController = &getController('communication'); - $oCommunicationController->setMessageReaded($message->message_srl); - - return $message; - } - - /** - * @brief 쪽지 목록 가져오기 - * type = R : 받은 쪽지 - * type = S : 보낸 쪽지 - * type = T : 보관함 - **/ - function getMessages($message_type = "R") { - $logged_info = Context::get('logged_info'); - - switch($message_type) { - case 'R' : - $args->member_srl = $logged_info->member_srl; - $args->message_type = 'R'; - $query_id = 'communication.getReceivedMessages'; - break; - case 'T' : - $args->member_srl = $logged_info->member_srl; - $args->message_type = 'T'; - $query_id = 'communication.getStoredMessages'; - break; - default : - $args->member_srl = $logged_info->member_srl; - $args->message_type = 'S'; - $query_id = 'communication.getSendedMessages'; - break; - - } - - // 기타 변수들 정리 - $args->sort_index = 'message.list_order'; - $args->page = Context::get('page'); - $args->list_count = 20; - $args->page_count = 10; - return executeQuery($query_id, $args); - } - - /** - * @brief 친구 목록 가져오기 - **/ - function getFriends($friend_group_srl = 0) { - $logged_info = Context::get('logged_info'); - - $args->friend_group_srl = $friend_group_srl; - $args->member_srl = $logged_info->member_srl; - - // 기타 변수들 정리 - $args->page = Context::get('page'); - $args->sort_index = 'friend.list_order'; - $args->list_count = 10; - $args->page_count = 10; - $output = executeQuery('communication.getFriends', $args); - return $output; - } - - /** - * @brief 이미 친구로 등록되었는지 검사 - **/ - function isAddedFriend($member_srl) { - $logged_info = Context::get('logged_info'); - - $args->member_srl = $logged_info->member_srl; - $args->target_srl = $member_srl; - $output = executeQuery('communication.isAddedFriend', $args); - return $output->data->count; - } - - /** - * @brief 특정 친구 그룹 가져오기 - **/ - function getFriendGroupInfo($friend_group_srl) { - $logged_info = Context::get('logged_info'); - - $args->member_srl = $logged_info->member_srl; - $args->friend_group_srl = $friend_group_srl; - - $output = executeQuery('communication.getFriendGroup', $args); - return $output->data; - } - - /** - * @brief 그룹 목록 가져오기 - **/ - function getFriendGroups() { - $logged_info = Context::get('logged_info'); - $args->member_srl = $logged_info->member_srl; - - $output = executeQuery('communication.getFriendGroups', $args); - $group_list = $output->data; - if(!$group_list) return; - - if(!is_array($group_list)) $group_list = array($group_list); - return $group_list; - } - - /** - * @brief 특정 회원의 친구 목록에 포함되어 있는지를 확인 - **/ - function isFriend($target_srl) { - $logged_info = Context::get('logged_info'); - - $args->member_srl = $target_srl; - $args->target_srl = $logged_info->member_srl; - $output = executeQuery('communication.isAddedFriend', $args); - if($output->data->count) return true; - return false; - } - } -?> +getModuleConfig('communication'); + + if(!$communication_config->skin) $communication_config->skin = 'default'; + if(!$communication_config->colorset) $communication_config->colorset = 'white'; + if(!$communication_config->editor_skin) $communication_config->editor_skin = 'default'; + + return $communication_config; + } + + /** + * @brief 쪽지 내용을 가져옴 + **/ + function getSelectedMessage($message_srl) { + $logged_info = Context::get('logged_info'); + + $args->message_srl = $message_srl; + $output = executeQuery('communication.getMessage',$args); + $message = $output->data; + if(!$message) return ; + + // 보낸 쪽지일 경우 받는 사람 정보를 구함 + $oMemberModel = &getModel('member'); + if($message->sender_srl == $logged_info->member_srl && $message->message_type == 'S') $member_info = $oMemberModel->getMemberInfoByMemberSrl($message->receiver_srl); + + // 보관/받은 쪽지일 경우 보낸 사람 정보를 구함 + else $member_info = $oMemberModel->getMemberInfoByMemberSrl($message->sender_srl); + + if($member_info) { + foreach($member_info as $key => $val) { + if($key != 'regdate') $message->{$key} = $val; + } + } + + // 받은 쪽지이고 아직 읽지 않았을 경우 읽은 상태로 변경 + if($message->message_type == 'R' && $message->readed != 'Y') { + $oCommunicationController = &getController('communication'); + $oCommunicationController->setMessageReaded($message_srl); + } + + + return $message; + } + + /** + * @brief 새 쪽지를 가져옴 + **/ + function getNewMessage() { + $logged_info = Context::get('logged_info'); + $args->receiver_srl = $logged_info->member_srl; + $args->readed = 'N'; + + $output = executeQuery('communication.getNewMessage', $args); + if(!count($output->data)) return; + $message = array_pop($output->data); + + $oCommunicationController = &getController('communication'); + $oCommunicationController->setMessageReaded($message->message_srl); + + return $message; + } + + /** + * @brief 쪽지 목록 가져오기 + * type = R : 받은 쪽지 + * type = S : 보낸 쪽지 + * type = T : 보관함 + **/ + function getMessages($message_type = "R") { + $logged_info = Context::get('logged_info'); + + switch($message_type) { + case 'R' : + $args->member_srl = $logged_info->member_srl; + $args->message_type = 'R'; + $query_id = 'communication.getReceivedMessages'; + break; + case 'T' : + $args->member_srl = $logged_info->member_srl; + $args->message_type = 'T'; + $query_id = 'communication.getStoredMessages'; + break; + default : + $args->member_srl = $logged_info->member_srl; + $args->message_type = 'S'; + $query_id = 'communication.getSendedMessages'; + break; + + } + + // 기타 변수들 정리 + $args->sort_index = 'message.list_order'; + $args->page = Context::get('page'); + $args->list_count = 20; + $args->page_count = 10; + return executeQuery($query_id, $args); + } + + /** + * @brief 친구 목록 가져오기 + **/ + function getFriends($friend_group_srl = 0) { + $logged_info = Context::get('logged_info'); + + $args->friend_group_srl = $friend_group_srl; + $args->member_srl = $logged_info->member_srl; + + // 기타 변수들 정리 + $args->page = Context::get('page'); + $args->sort_index = 'friend.list_order'; + $args->list_count = 10; + $args->page_count = 10; + $output = executeQuery('communication.getFriends', $args); + return $output; + } + + /** + * @brief 이미 친구로 등록되었는지 검사 + **/ + function isAddedFriend($member_srl) { + $logged_info = Context::get('logged_info'); + + $args->member_srl = $logged_info->member_srl; + $args->target_srl = $member_srl; + $output = executeQuery('communication.isAddedFriend', $args); + return $output->data->count; + } + + /** + * @brief 특정 친구 그룹 가져오기 + **/ + function getFriendGroupInfo($friend_group_srl) { + $logged_info = Context::get('logged_info'); + + $args->member_srl = $logged_info->member_srl; + $args->friend_group_srl = $friend_group_srl; + + $output = executeQuery('communication.getFriendGroup', $args); + return $output->data; + } + + /** + * @brief 그룹 목록 가져오기 + **/ + function getFriendGroups() { + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + + $output = executeQuery('communication.getFriendGroups', $args); + $group_list = $output->data; + if(!$group_list) return; + + if(!is_array($group_list)) $group_list = array($group_list); + return $group_list; + } + + /** + * @brief 특정 회원의 친구 목록에 포함되어 있는지를 확인 + **/ + function isFriend($target_srl) { + $logged_info = Context::get('logged_info'); + + $args->member_srl = $target_srl; + $args->target_srl = $logged_info->member_srl; + $output = executeQuery('communication.isAddedFriend', $args); + if($output->data->count) return true; + return false; + } + } +?> diff --git a/modules/communication/communication.view.php b/modules/communication/communication.view.php index c96c193b4..58c9f17ac 100644 --- a/modules/communication/communication.view.php +++ b/modules/communication/communication.view.php @@ -1,228 +1,228 @@ -communication_config = $oCommunicationModel->getConfig(); - $skin = $this->communication_config->skin; - - Context::set('communication_config', $this->communication_config); - - $tpl_path = sprintf('%sskins/%s', $this->module_path, $skin); - $this->setTemplatePath($tpl_path); - } - - /** - * @brief 쪽지함 출력 - **/ - function dispCommunicationMessages() { - // 로그인이 되어 있지 않으면 오류 표시 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 변수 설정 - $message_srl = Context::get('message_srl'); - $message_type = Context::get('message_type'); - if(!in_array($message_type, array('R','S','T'))) { - $message_type = 'R'; - Context::set('message_type', $message_type); - } - - $oCommunicationModel = &getModel('communication'); - - // message_srl이 있으면 내용 추출 - if($message_srl) { - $message = $oCommunicationModel->getSelectedMessage($message_srl); - if($message->message_srl == $message_srl && ($message->receiver_srl == $logged_info->member_srl || $message->sender_srl == $logged_info->member_srl) ) { - stripEmbedTagForAdmin($message->content, $message->sender_srl); - Context::set('message', $message); - } - } - - // 목록 추출 - $output = $oCommunicationModel->getMessages($message_type); - - // 템플릿에 쓰기 위해서 context::set - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('message_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('messages'); - } - - /** - * @brief 새 쪽지 보여줌 - **/ - function dispCommunicationNewMessage() { - $this->setLayoutFile('popup_layout'); - - // 로그인이 되어 있지 않으면 오류 표시 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - $logged_info = Context::get('logged_info'); - - $oCommunicationModel = &getModel('communication'); - - // 새 쪽지를 가져옴 - $message = $oCommunicationModel->getNewMessage(); - if($message) { - stripEmbedTagForAdmin($message->content, $message->sender_srl); - Context::set('message', $message); - } - - // 플래그 삭제 - $flag_path = './files/communication_extra_info/new_message_flags/'.getNumberingPath($logged_info->member_srl); - $flag_file = sprintf('%s%s', $flag_path, $logged_info->member_srl); - FileHandler::removeFile($flag_file); - - $this->setTemplateFile('new_message'); - } - - /** - * @brief 쪽지 발송 출력 - **/ - function dispCommunicationSendMessage() { - $this->setLayoutFile("popup_layout"); - $oCommunicationModel = &getModel('communication'); - $oMemberModel = &getModel('member'); - - // 로그인이 되어 있지 않으면 오류 표시 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 쪽지 받을 사용자 정보 구함 - $receiver_srl = Context::get('receiver_srl'); - if(!$receiver_srl || $logged_info->member_srl == $receiver_srl) return $this->stop('msg_not_logged'); - - // 답글 쪽지일 경우 원본 메세지의 글번호를 구함 - $message_srl = Context::get('message_srl'); - if($message_srl) { - $source_message = $oCommunicationModel->getSelectedMessage($message_srl); - if($source_message->message_srl == $message_srl && $source_message->sender_srl == $receiver_srl) { - $source_message->title = "[re] ".$source_message->title; - $source_message->content = "\r\n
\r\n
".trim($source_message->content)."
"; - Context::set('source_message', $source_message); - } - } - - $receiver_info = $oMemberModel->getMemberInfoByMemberSrl($receiver_srl); - Context::set('receiver_info', $receiver_info); - - // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 - $oEditorModel = &getModel('editor'); - $option->primary_key_name = 'receiver_srl'; - $option->content_key_name = 'content'; - $option->allow_fileupload = false; - $option->enable_autosave = false; - $option->enable_default_component = true;// false; - $option->enable_component = false; - $option->resizable = false; - $option->disable_html = true; - $option->height = 300; - $option->skin = $this->communication_config->editor_skin; - $option->colorset = $this->communication_config->editor_colorset; - $editor = $oEditorModel->getEditor($logged_info->member_srl, $option); - Context::set('editor', $editor); - - $this->setTemplateFile('send_message'); - } - - /** - * @brief 친구 목록 보기 - **/ - function dispCommunicationFriend() { - // 로그인이 되어 있지 않으면 오류 표시 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - - $oCommunicationModel = &getModel('communication'); - - // 그룹 목록을 가져옴 - $tmp_group_list = $oCommunicationModel->getFriendGroups(); - $group_count = count($tmp_group_list); - for($i=0;$i<$group_count;$i++) $friend_group_list[$tmp_group_list[$i]->friend_group_srl] = $tmp_group_list[$i]; - Context::set('friend_group_list', $friend_group_list); - - // 친구 목록을 가져옴 - $friend_group_srl = Context::get('friend_group_srl'); - $output = $oCommunicationModel->getFriends($friend_group_srl); - $friend_count = count($output->data); - if($friend_count) { - foreach($output->data as $key => $val) { - $group_srl = $val->friend_group_srl; - $group_title = $friend_group_list[$group_srl]->title; - if(!$group_title) $group_title = Context::get('default_friend_group'); - $output->data[$key]->group_title = $group_title; - } - } - - // 템플릿에 쓰기 위해서 context::set - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('friend_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('friends'); - } - - /** - * @brief 친구 추가 - **/ - function dispCommunicationAddFriend() { - $this->setLayoutFile("popup_layout"); - - // 로그인이 되어 있지 않으면 오류 표시 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - $logged_info = Context::get('logged_info'); - - $target_srl = Context::get('target_srl'); - if(!$target_srl) return $this->stop('msg_invalid_request'); - - // 대상 회원의 정보를 구함 - $oMemberModel = &getModel('member'); - $oCommunicationModel = &getModel('communication'); - $communication_info = $oMemberModel->getMemberInfoByMemberSrl($target_srl); - if($communication_info->member_srl != $target_srl) return $this->stop('msg_invalid_request'); - Context::set('target_info', $communication_info); - - // 그룹의 목록을 구함 - $friend_group_list = $oCommunicationModel->getFriendGroups(); - Context::set('friend_group_list', $friend_group_list); - - $this->setTemplateFile('add_friend'); - } - - /** - * @brief 친구 그룹 추가 - **/ - function dispCommunicationAddFriendGroup() { - $this->setLayoutFile("popup_layout"); - - // 로그인이 되어 있지 않으면 오류 표시 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - $logged_info = Context::get('logged_info'); - - // 그룹 번호가 넘어오면 수정모드로.. - $friend_group_srl = Context::get('friend_group_srl'); - if($friend_group_srl) { - $oCommunicationModel = &getModel('communication'); - $friend_group = $oCommunicationModel->getFriendGroupInfo($friend_group_srl); - if($friend_group->friend_group_srl == $friend_group_srl) Context::set('friend_group', $friend_group); - } - - $this->setTemplateFile('add_friend_group'); - } - - } -?> +communication_config = $oCommunicationModel->getConfig(); + $skin = $this->communication_config->skin; + + Context::set('communication_config', $this->communication_config); + + $tpl_path = sprintf('%sskins/%s', $this->module_path, $skin); + $this->setTemplatePath($tpl_path); + } + + /** + * @brief 쪽지함 출력 + **/ + function dispCommunicationMessages() { + // 로그인이 되어 있지 않으면 오류 표시 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 변수 설정 + $message_srl = Context::get('message_srl'); + $message_type = Context::get('message_type'); + if(!in_array($message_type, array('R','S','T'))) { + $message_type = 'R'; + Context::set('message_type', $message_type); + } + + $oCommunicationModel = &getModel('communication'); + + // message_srl이 있으면 내용 추출 + if($message_srl) { + $message = $oCommunicationModel->getSelectedMessage($message_srl); + if($message->message_srl == $message_srl && ($message->receiver_srl == $logged_info->member_srl || $message->sender_srl == $logged_info->member_srl) ) { + stripEmbedTagForAdmin($message->content, $message->sender_srl); + Context::set('message', $message); + } + } + + // 목록 추출 + $output = $oCommunicationModel->getMessages($message_type); + + // 템플릿에 쓰기 위해서 context::set + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('message_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('messages'); + } + + /** + * @brief 새 쪽지 보여줌 + **/ + function dispCommunicationNewMessage() { + $this->setLayoutFile('popup_layout'); + + // 로그인이 되어 있지 않으면 오류 표시 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + $logged_info = Context::get('logged_info'); + + $oCommunicationModel = &getModel('communication'); + + // 새 쪽지를 가져옴 + $message = $oCommunicationModel->getNewMessage(); + if($message) { + stripEmbedTagForAdmin($message->content, $message->sender_srl); + Context::set('message', $message); + } + + // 플래그 삭제 + $flag_path = './files/communication_extra_info/new_message_flags/'.getNumberingPath($logged_info->member_srl); + $flag_file = sprintf('%s%s', $flag_path, $logged_info->member_srl); + FileHandler::removeFile($flag_file); + + $this->setTemplateFile('new_message'); + } + + /** + * @brief 쪽지 발송 출력 + **/ + function dispCommunicationSendMessage() { + $this->setLayoutFile("popup_layout"); + $oCommunicationModel = &getModel('communication'); + $oMemberModel = &getModel('member'); + + // 로그인이 되어 있지 않으면 오류 표시 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 쪽지 받을 사용자 정보 구함 + $receiver_srl = Context::get('receiver_srl'); + if(!$receiver_srl || $logged_info->member_srl == $receiver_srl) return $this->stop('msg_not_logged'); + + // 답글 쪽지일 경우 원본 메세지의 글번호를 구함 + $message_srl = Context::get('message_srl'); + if($message_srl) { + $source_message = $oCommunicationModel->getSelectedMessage($message_srl); + if($source_message->message_srl == $message_srl && $source_message->sender_srl == $receiver_srl) { + $source_message->title = "[re] ".$source_message->title; + $source_message->content = "\r\n
\r\n
".trim($source_message->content)."
"; + Context::set('source_message', $source_message); + } + } + + $receiver_info = $oMemberModel->getMemberInfoByMemberSrl($receiver_srl); + Context::set('receiver_info', $receiver_info); + + // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 + $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'receiver_srl'; + $option->content_key_name = 'content'; + $option->allow_fileupload = false; + $option->enable_autosave = false; + $option->enable_default_component = true;// false; + $option->enable_component = false; + $option->resizable = false; + $option->disable_html = true; + $option->height = 300; + $option->skin = $this->communication_config->editor_skin; + $option->colorset = $this->communication_config->editor_colorset; + $editor = $oEditorModel->getEditor($logged_info->member_srl, $option); + Context::set('editor', $editor); + + $this->setTemplateFile('send_message'); + } + + /** + * @brief 친구 목록 보기 + **/ + function dispCommunicationFriend() { + // 로그인이 되어 있지 않으면 오류 표시 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + + $oCommunicationModel = &getModel('communication'); + + // 그룹 목록을 가져옴 + $tmp_group_list = $oCommunicationModel->getFriendGroups(); + $group_count = count($tmp_group_list); + for($i=0;$i<$group_count;$i++) $friend_group_list[$tmp_group_list[$i]->friend_group_srl] = $tmp_group_list[$i]; + Context::set('friend_group_list', $friend_group_list); + + // 친구 목록을 가져옴 + $friend_group_srl = Context::get('friend_group_srl'); + $output = $oCommunicationModel->getFriends($friend_group_srl); + $friend_count = count($output->data); + if($friend_count) { + foreach($output->data as $key => $val) { + $group_srl = $val->friend_group_srl; + $group_title = $friend_group_list[$group_srl]->title; + if(!$group_title) $group_title = Context::get('default_friend_group'); + $output->data[$key]->group_title = $group_title; + } + } + + // 템플릿에 쓰기 위해서 context::set + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('friend_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('friends'); + } + + /** + * @brief 친구 추가 + **/ + function dispCommunicationAddFriend() { + $this->setLayoutFile("popup_layout"); + + // 로그인이 되어 있지 않으면 오류 표시 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + $logged_info = Context::get('logged_info'); + + $target_srl = Context::get('target_srl'); + if(!$target_srl) return $this->stop('msg_invalid_request'); + + // 대상 회원의 정보를 구함 + $oMemberModel = &getModel('member'); + $oCommunicationModel = &getModel('communication'); + $communication_info = $oMemberModel->getMemberInfoByMemberSrl($target_srl); + if($communication_info->member_srl != $target_srl) return $this->stop('msg_invalid_request'); + Context::set('target_info', $communication_info); + + // 그룹의 목록을 구함 + $friend_group_list = $oCommunicationModel->getFriendGroups(); + Context::set('friend_group_list', $friend_group_list); + + $this->setTemplateFile('add_friend'); + } + + /** + * @brief 친구 그룹 추가 + **/ + function dispCommunicationAddFriendGroup() { + $this->setLayoutFile("popup_layout"); + + // 로그인이 되어 있지 않으면 오류 표시 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + $logged_info = Context::get('logged_info'); + + // 그룹 번호가 넘어오면 수정모드로.. + $friend_group_srl = Context::get('friend_group_srl'); + if($friend_group_srl) { + $oCommunicationModel = &getModel('communication'); + $friend_group = $oCommunicationModel->getFriendGroupInfo($friend_group_srl); + if($friend_group->friend_group_srl == $friend_group_srl) Context::set('friend_group', $friend_group); + } + + $this->setTemplateFile('add_friend_group'); + } + + } +?> diff --git a/modules/communication/conf/info.xml b/modules/communication/conf/info.xml index cc0f564af..102851295 100644 --- a/modules/communication/conf/info.xml +++ b/modules/communication/conf/info.xml @@ -1,30 +1,30 @@ - - - 커뮤니케이션 - コミュニケーション - 会员交流 - Communication - Communication - Liên lạc - 交流 - 회원들간의 쪽지, 친구기능을 담당하는 모듈입니다. - 会員間にメッセージや友達管理などコミュニティ機能を提供します。 - 管理在线会员间短信息及好友功能的模块。 - This module is for managing message, friend functions. - Module quản lý tin nhắn và bạn bè. - This module is for managing message, friend functions. - 管理線上會員間短訊及好友功能的模組。 - 0.1 - 2008-05-30 - member - - - zero - zero - zero - zero - zero - zero - zero - - + + + 커뮤니케이션 + コミュニケーション + 会员交流 + Communication + Communication + Liên lạc + 交流 + 회원들간의 쪽지, 친구기능을 담당하는 모듈입니다. + 会員間にメッセージや友達管理などコミュニティ機能を提供します。 + 管理在线会员间短信息及好友功能的模块。 + This module is for managing message, friend functions. + Module quản lý tin nhắn và bạn bè. + This module is for managing message, friend functions. + 管理線上會員間短訊及好友功能的模組。 + 0.1 + 2008-05-30 + member + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/communication/lang/en.lang.php b/modules/communication/lang/en.lang.php index a890376e9..8ddeddf7c 100644 --- a/modules/communication/lang/en.lang.php +++ b/modules/communication/lang/en.lang.php @@ -1,48 +1,48 @@ -communication = 'Communication'; - $lang->about_communication = 'Communication module is for communications between members with messages or friends.'; - - $lang->allow_message = 'Receive Messages'; - $lang->allow_message_type = array( - 'Y' => 'Receive All', - 'N' => 'Reject All', - 'F' => 'Only Friends', - ); - - $lang->message_box = array( - 'R' => 'Received', - 'S' => 'Sent', - 'T' => 'Mailbox', - ); - $lang->readed_date = "Read Date"; - - $lang->sender = 'Sender'; - $lang->receiver = 'Receiver'; - $lang->friend_group = 'Friend Group'; - $lang->default_friend_group = 'Unassigned Group'; - - $lang->cmd_send_message = 'Send Message'; - $lang->cmd_reply_message = 'Reply Message'; - $lang->cmd_view_friend = 'Friends'; - $lang->cmd_add_friend = 'Add Friend'; - $lang->cmd_view_message_box = 'Message Box'; - $lang->cmd_store = "Save"; - $lang->cmd_add_friend_group = 'Add Friend Group'; - $lang->cmd_rename_friend_group = 'Modify Friend Group Name'; - - $lang->msg_no_message = 'There is no message'; - $lang->message_received = 'You have a new message'; - - $lang->msg_title_is_null = 'Please input the title of message'; - $lang->msg_content_is_null = 'Please input the content'; - $lang->msg_allow_message_to_friend = "Failed to send because receiver only allows friends' messages"; - $lang->msg_disallow_message = 'Failed to send because receiver rejects message reception'; - - $lang->about_allow_message = 'You can decide message reception'; -?> +communication = 'Communication'; + $lang->about_communication = 'Communication module is for communications between members with messages or friends.'; + + $lang->allow_message = 'Receive Messages'; + $lang->allow_message_type = array( + 'Y' => 'Receive All', + 'N' => 'Reject All', + 'F' => 'Only Friends', + ); + + $lang->message_box = array( + 'R' => 'Received', + 'S' => 'Sent', + 'T' => 'Mailbox', + ); + $lang->readed_date = "Read Date"; + + $lang->sender = 'Sender'; + $lang->receiver = 'Receiver'; + $lang->friend_group = 'Friend Group'; + $lang->default_friend_group = 'Unassigned Group'; + + $lang->cmd_send_message = 'Send Message'; + $lang->cmd_reply_message = 'Reply Message'; + $lang->cmd_view_friend = 'Friends'; + $lang->cmd_add_friend = 'Add Friend'; + $lang->cmd_view_message_box = 'Message Box'; + $lang->cmd_store = "Save"; + $lang->cmd_add_friend_group = 'Add Friend Group'; + $lang->cmd_rename_friend_group = 'Modify Friend Group Name'; + + $lang->msg_no_message = 'There is no message'; + $lang->message_received = 'You have a new message'; + + $lang->msg_title_is_null = 'Please input the title of message'; + $lang->msg_content_is_null = 'Please input the content'; + $lang->msg_allow_message_to_friend = "Failed to send because receiver only allows friends' messages"; + $lang->msg_disallow_message = 'Failed to send because receiver rejects message reception'; + + $lang->about_allow_message = 'You can decide message reception'; +?> diff --git a/modules/communication/lang/es.lang.php b/modules/communication/lang/es.lang.php index e67c51aa8..d70c6d4f5 100644 --- a/modules/communication/lang/es.lang.php +++ b/modules/communication/lang/es.lang.php @@ -1,49 +1,49 @@ -communication = 'Communication'; - $lang->about_communication = '회원간의 쪽지나 친구 관리등 커뮤니케이션 기능을 수행하는 모듈입니다'; - - $lang->allow_message = 'Permitir la recepción del mensaje'; - $lang->allow_message_type = array( - 'Y' => 'Recibir todo', - 'N' => 'Rechazar', - 'F' => 'Sólo amigos', - ); - - $lang->message_box = array( - 'R' => 'Recibido', - 'S' => 'Enviado', - 'T' => 'Buzon de Email', - ); - - $lang->readed_date = "Fecha Leído"; - - $lang->sender = 'Remitente'; - $lang->receiver = 'Receptor'; - $lang->friend_group = 'Grupo de amigos'; - $lang->default_friend_group = 'Grupo desasignado'; - - $lang->cmd_send_message = 'Enviar Mensaje'; - $lang->cmd_reply_message = 'Responder el mensaje'; - $lang->cmd_view_friend = 'Amigos'; - $lang->cmd_add_friend = 'Registrar como Amigo'; - $lang->cmd_view_message_box = 'Buzón de mensajes'; - $lang->cmd_store = "Guardar"; - $lang->cmd_add_friend_group = 'agregar grupo de amigos'; - $lang->cmd_rename_friend_group = 'Cambiar el nombre del grupo de amigos'; - - $lang->msg_no_message = 'No hay mensajes'; - $lang->message_received = 'Usted ha recibido un mensaje'; - - $lang->msg_title_is_null = 'Por favor ingresar el título de la nota'; - $lang->msg_content_is_null = 'Por favor ingresar el contenido'; - $lang->msg_allow_message_to_friend = "Falló el envío por permitir sólo mensajes de sus amigos"; - $lang->msg_disallow_message = 'Falló el envío por ser usuario rechazado para recibir mensajes'; - - $lang->about_allow_message = 'Usted puede decidir la recepción del mensaje'; -?> +communication = 'Communication'; + $lang->about_communication = '회원간의 쪽지나 친구 관리등 커뮤니케이션 기능을 수행하는 모듈입니다'; + + $lang->allow_message = 'Permitir la recepción del mensaje'; + $lang->allow_message_type = array( + 'Y' => 'Recibir todo', + 'N' => 'Rechazar', + 'F' => 'Sólo amigos', + ); + + $lang->message_box = array( + 'R' => 'Recibido', + 'S' => 'Enviado', + 'T' => 'Buzon de Email', + ); + + $lang->readed_date = "Fecha Leído"; + + $lang->sender = 'Remitente'; + $lang->receiver = 'Receptor'; + $lang->friend_group = 'Grupo de amigos'; + $lang->default_friend_group = 'Grupo desasignado'; + + $lang->cmd_send_message = 'Enviar Mensaje'; + $lang->cmd_reply_message = 'Responder el mensaje'; + $lang->cmd_view_friend = 'Amigos'; + $lang->cmd_add_friend = 'Registrar como Amigo'; + $lang->cmd_view_message_box = 'Buzón de mensajes'; + $lang->cmd_store = "Guardar"; + $lang->cmd_add_friend_group = 'agregar grupo de amigos'; + $lang->cmd_rename_friend_group = 'Cambiar el nombre del grupo de amigos'; + + $lang->msg_no_message = 'No hay mensajes'; + $lang->message_received = 'Usted ha recibido un mensaje'; + + $lang->msg_title_is_null = 'Por favor ingresar el título de la nota'; + $lang->msg_content_is_null = 'Por favor ingresar el contenido'; + $lang->msg_allow_message_to_friend = "Falló el envío por permitir sólo mensajes de sus amigos"; + $lang->msg_disallow_message = 'Falló el envío por ser usuario rechazado para recibir mensajes'; + + $lang->about_allow_message = 'Usted puede decidir la recepción del mensaje'; +?> diff --git a/modules/communication/lang/fr.lang.php b/modules/communication/lang/fr.lang.php index de1ca6145..c1a3b88aa 100644 --- a/modules/communication/lang/fr.lang.php +++ b/modules/communication/lang/fr.lang.php @@ -1,48 +1,48 @@ -communication = 'Communication'; - $lang->about_communication = 'Ce module exécute des fonctions communicatives comme Messages ou Amis'; - - $lang->allow_message = 'Recevoir les Messages'; - $lang->allow_message_type = array( - 'Y' => 'Recevoir tout', - 'N' => 'Refuser tout', - 'F' => 'Amis seulement', - ); - - $lang->message_box = array( - 'R' => 'Reçu', - 'S' => 'Envoyé', - 'T' => 'Boîte aux Lettres', - ); - $lang->readed_date = "Jour lu"; - - $lang->sender = 'Envoyeur'; - $lang->receiver = 'Receveur'; - $lang->friend_group = 'Groupe des Amis'; - $lang->default_friend_group = 'Groupe pas assigné '; - - $lang->cmd_send_message = 'Envoyer un Message'; - $lang->cmd_reply_message = 'Répondre à un Message'; - $lang->cmd_view_friend = 'Amis'; - $lang->cmd_add_friend = 'Inscrire des Amis'; - $lang->cmd_view_message_box = 'Lire des Messages'; - $lang->cmd_store = "Conserver"; - $lang->cmd_add_friend_group = 'Ajouter un Groupe des Amis'; - $lang->cmd_rename_friend_group = 'Modifier le Nom du Groupe des Amis'; - - $lang->msg_no_message = 'Nul Message'; - $lang->message_received = 'Nouveau message'; - - $lang->msg_title_is_null = 'Entrez le titre du message, S.V.P.'; - $lang->msg_content_is_null = 'Entrez le contenu, S.V.P.'; - $lang->msg_allow_message_to_friend = "Echoué à envoyer parce que le receveur permet seulement les messages des Amis."; - $lang->msg_disallow_message = 'Echoué à envoyer parce que le receveur refuse la réception des messages'; - - $lang->about_allow_message = 'Vous pouvez refuser la réception des messages'; -?> +communication = 'Communication'; + $lang->about_communication = 'Ce module exécute des fonctions communicatives comme Messages ou Amis'; + + $lang->allow_message = 'Recevoir les Messages'; + $lang->allow_message_type = array( + 'Y' => 'Recevoir tout', + 'N' => 'Refuser tout', + 'F' => 'Amis seulement', + ); + + $lang->message_box = array( + 'R' => 'Reçu', + 'S' => 'Envoyé', + 'T' => 'Boîte aux Lettres', + ); + $lang->readed_date = "Jour lu"; + + $lang->sender = 'Envoyeur'; + $lang->receiver = 'Receveur'; + $lang->friend_group = 'Groupe des Amis'; + $lang->default_friend_group = 'Groupe pas assigné '; + + $lang->cmd_send_message = 'Envoyer un Message'; + $lang->cmd_reply_message = 'Répondre à un Message'; + $lang->cmd_view_friend = 'Amis'; + $lang->cmd_add_friend = 'Inscrire des Amis'; + $lang->cmd_view_message_box = 'Lire des Messages'; + $lang->cmd_store = "Conserver"; + $lang->cmd_add_friend_group = 'Ajouter un Groupe des Amis'; + $lang->cmd_rename_friend_group = 'Modifier le Nom du Groupe des Amis'; + + $lang->msg_no_message = 'Nul Message'; + $lang->message_received = 'Nouveau message'; + + $lang->msg_title_is_null = 'Entrez le titre du message, S.V.P.'; + $lang->msg_content_is_null = 'Entrez le contenu, S.V.P.'; + $lang->msg_allow_message_to_friend = "Echoué à envoyer parce que le receveur permet seulement les messages des Amis."; + $lang->msg_disallow_message = 'Echoué à envoyer parce que le receveur refuse la réception des messages'; + + $lang->about_allow_message = 'Vous pouvez refuser la réception des messages'; +?> diff --git a/modules/communication/lang/jp.lang.php b/modules/communication/lang/jp.lang.php index 840101d98..be4a29728 100644 --- a/modules/communication/lang/jp.lang.php +++ b/modules/communication/lang/jp.lang.php @@ -1,48 +1,48 @@ -communication = 'コミュニケーション'; - $lang->about_communication = '会員間にメッセージや友達管理などコミュニティ機能を提供するモジュールです。'; - - $lang->allow_message = 'メッセージの受信'; - $lang->allow_message_type = array( - 'Y' => '全て受信', - 'N' => '全て受信しない', - 'F' => '友達からのみ受信する', - ); - - $lang->message_box = array( - 'R' => 'メッセージ受信箱', - 'S' => 'メッセージ送信箱', - 'T' => '保存箱', - ); - - $lang->readed_date = '開封時間'; - - $lang->sender = '送信者'; - $lang->receiver = '受信者'; - $lang->friend_group = '友達グループ'; - $lang->default_friend_group = 'グループ未指定'; - - $lang->cmd_send_message = 'メッセージ送信'; - $lang->cmd_reply_message = 'メッセージ返信'; - $lang->cmd_view_friend = '友達リスト'; - $lang->cmd_add_friend = '友達登録'; - $lang->cmd_view_message_box = 'メッセージ'; - $lang->cmd_store = '保存'; - $lang->cmd_add_friend_group = '友達グループ追加'; - $lang->cmd_rename_friend_group = '友達グループ名変更'; - - $lang->msg_no_message = 'メッセージがありません。'; - $lang->message_received = 'メッセージが届きました。'; - - $lang->msg_title_is_null = 'メッセージのタイトルを入力して下さい。'; - $lang->msg_content_is_null = '内容を入力して下さい。'; - $lang->msg_allow_message_to_friend = '友達からのみメッセージを受信出来るように設定したユーザであるため、送信出来ませんでした。'; - $lang->msg_disallow_message = 'メッセージの受信を拒否している受信者であるため、送信出来ませんでした。'; - $lang->about_allow_message = 'メッセージを受信するかを設定します。'; -?> +communication = 'コミュニケーション'; + $lang->about_communication = '会員間にメッセージや友達管理などコミュニティ機能を提供するモジュールです。'; + + $lang->allow_message = 'メッセージの受信'; + $lang->allow_message_type = array( + 'Y' => '全て受信', + 'N' => '全て受信しない', + 'F' => '友達からのみ受信する', + ); + + $lang->message_box = array( + 'R' => 'メッセージ受信箱', + 'S' => 'メッセージ送信箱', + 'T' => '保存箱', + ); + + $lang->readed_date = '開封時間'; + + $lang->sender = '送信者'; + $lang->receiver = '受信者'; + $lang->friend_group = '友達グループ'; + $lang->default_friend_group = 'グループ未指定'; + + $lang->cmd_send_message = 'メッセージ送信'; + $lang->cmd_reply_message = 'メッセージ返信'; + $lang->cmd_view_friend = '友達リスト'; + $lang->cmd_add_friend = '友達登録'; + $lang->cmd_view_message_box = 'メッセージ'; + $lang->cmd_store = '保存'; + $lang->cmd_add_friend_group = '友達グループ追加'; + $lang->cmd_rename_friend_group = '友達グループ名変更'; + + $lang->msg_no_message = 'メッセージがありません。'; + $lang->message_received = 'メッセージが届きました。'; + + $lang->msg_title_is_null = 'メッセージのタイトルを入力して下さい。'; + $lang->msg_content_is_null = '内容を入力して下さい。'; + $lang->msg_allow_message_to_friend = '友達からのみメッセージを受信出来るように設定したユーザであるため、送信出来ませんでした。'; + $lang->msg_disallow_message = 'メッセージの受信を拒否している受信者であるため、送信出来ませんでした。'; + $lang->about_allow_message = 'メッセージを受信するかを設定します。'; +?> diff --git a/modules/communication/lang/ko.lang.php b/modules/communication/lang/ko.lang.php index 75cff477d..35186374e 100644 --- a/modules/communication/lang/ko.lang.php +++ b/modules/communication/lang/ko.lang.php @@ -1,48 +1,48 @@ -communication = '커뮤니케이션'; - $lang->about_communication = '회원 간의 쪽지나 친구 관리 등 커뮤니케이션 기능을 수행하는 모듈입니다.'; - - $lang->allow_message = '쪽지 수신 허용'; - $lang->allow_message_type = array( - 'Y' => '전체 수신', - 'N' => '거부', - 'F' => '친구만 허용', - ); - - $lang->message_box = array( - 'R' => '받은 쪽지함', - 'S' => '보낸 쪽지함', - 'T' => '보관함', - ); - - $lang->readed_date = '읽은 시간'; - - $lang->sender = '보낸이'; - $lang->receiver = '받는이'; - $lang->friend_group = '친구 그룹'; - $lang->default_friend_group = '그룹 미지정'; - - $lang->cmd_send_message = '쪽지 보내기'; - $lang->cmd_reply_message = '쪽지 답장'; - $lang->cmd_view_friend = '친구 보기'; - $lang->cmd_add_friend = '친구 등록'; - $lang->cmd_view_message_box = '쪽지함 보기'; - $lang->cmd_store = '보관'; - $lang->cmd_add_friend_group = '친구 그룹 추가'; - $lang->cmd_rename_friend_group = '친구 그룹 이름 변경'; - - $lang->msg_no_message = '쪽지가 없습니다.'; - $lang->message_received = '쪽지가 왔습니다.'; - - $lang->msg_title_is_null = '쪽지 제목을 입력해주세요.'; - $lang->msg_content_is_null = '내용을 입력해주세요.'; - $lang->msg_allow_message_to_friend = '친구에게만 쪽지 발송을 허용한 사용자라서 쪽지 발송을 하지 못했습니다.'; - $lang->msg_disallow_message = '쪽지 수신을 거부한 사용자라서 쪽지 발송을 하지 못했습니다.'; - $lang->about_allow_message = '쪽지 수신 여부를 결정할 수 있습니다.'; -?> +communication = '커뮤니케이션'; + $lang->about_communication = '회원 간의 쪽지나 친구 관리 등 커뮤니케이션 기능을 수행하는 모듈입니다.'; + + $lang->allow_message = '쪽지 수신 허용'; + $lang->allow_message_type = array( + 'Y' => '전체 수신', + 'N' => '거부', + 'F' => '친구만 허용', + ); + + $lang->message_box = array( + 'R' => '받은 쪽지함', + 'S' => '보낸 쪽지함', + 'T' => '보관함', + ); + + $lang->readed_date = '읽은 시간'; + + $lang->sender = '보낸이'; + $lang->receiver = '받는이'; + $lang->friend_group = '친구 그룹'; + $lang->default_friend_group = '그룹 미지정'; + + $lang->cmd_send_message = '쪽지 보내기'; + $lang->cmd_reply_message = '쪽지 답장'; + $lang->cmd_view_friend = '친구 보기'; + $lang->cmd_add_friend = '친구 등록'; + $lang->cmd_view_message_box = '쪽지함 보기'; + $lang->cmd_store = '보관'; + $lang->cmd_add_friend_group = '친구 그룹 추가'; + $lang->cmd_rename_friend_group = '친구 그룹 이름 변경'; + + $lang->msg_no_message = '쪽지가 없습니다.'; + $lang->message_received = '쪽지가 왔습니다.'; + + $lang->msg_title_is_null = '쪽지 제목을 입력해주세요.'; + $lang->msg_content_is_null = '내용을 입력해주세요.'; + $lang->msg_allow_message_to_friend = '친구에게만 쪽지 발송을 허용한 사용자라서 쪽지 발송을 하지 못했습니다.'; + $lang->msg_disallow_message = '쪽지 수신을 거부한 사용자라서 쪽지 발송을 하지 못했습니다.'; + $lang->about_allow_message = '쪽지 수신 여부를 결정할 수 있습니다.'; +?> diff --git a/modules/communication/lang/ru.lang.php b/modules/communication/lang/ru.lang.php index 2205e9b17..e85546a84 100644 --- a/modules/communication/lang/ru.lang.php +++ b/modules/communication/lang/ru.lang.php @@ -1,49 +1,49 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->communication = 'Общение'; - $lang->about_communication = 'Модуль для общения между пользователями'; - - $lang->allow_message = 'Получать сообщения'; - $lang->allow_message_type = array( - 'Y' => 'Принимать все', - 'N' => 'Отклонять все', - 'F' => 'Принимать только от друзей', - ); - - - $lang->message_box = array( - 'R' => 'Полученные', - 'S' => 'Отправленные', - 'T' => 'Почтовый ящик', - ); - - $lang->readed_date = "Дата прочтения сообщения"; - - $lang->sender = 'Отправитель'; - $lang->receiver = 'Получатель'; - $lang->friend_group = 'Группа Друзья'; - $lang->default_friend_group = 'Незарегистрированная группа'; - - $lang->cmd_send_message = 'Отправить сообщение'; - $lang->cmd_reply_message = 'Ответить'; - $lang->cmd_view_friend = 'Друзья'; - $lang->cmd_add_friend = 'Добавить в друзья'; - $lang->cmd_view_message_box = 'Личные сообщений'; - $lang->cmd_store = "Сохранить"; - $lang->cmd_add_friend_group = 'Добавить в группу друзей'; - $lang->cmd_rename_friend_group = 'Изменить имя группы друзей'; - - $lang->msg_no_message = 'Сообщений нет'; - $lang->message_received = 'У Вас новое сообщение'; - - $lang->msg_title_is_null = 'Пожалуйста, введите тему сообщения'; - $lang->msg_content_is_null = 'Пожалуйста, введите содержание'; - $lang->msg_allow_message_to_friend = "Сообщение не отправлено, поскольку являетесь пользователем, имеющим право посылать сообщения только друзьям"; - $lang->msg_disallow_message = 'Сообщение не отправлено, поскольку получатель запретил прием сообщений'; - $lang->about_allow_message = 'Вы можете установить режим принятия сообщений'; -?> +communication = 'Общение'; + $lang->about_communication = 'Модуль для общения между пользователями'; + + $lang->allow_message = 'Получать сообщения'; + $lang->allow_message_type = array( + 'Y' => 'Принимать все', + 'N' => 'Отклонять все', + 'F' => 'Принимать только от друзей', + ); + + + $lang->message_box = array( + 'R' => 'Полученные', + 'S' => 'Отправленные', + 'T' => 'Почтовый ящик', + ); + + $lang->readed_date = "Дата прочтения сообщения"; + + $lang->sender = 'Отправитель'; + $lang->receiver = 'Получатель'; + $lang->friend_group = 'Группа Друзья'; + $lang->default_friend_group = 'Незарегистрированная группа'; + + $lang->cmd_send_message = 'Отправить сообщение'; + $lang->cmd_reply_message = 'Ответить'; + $lang->cmd_view_friend = 'Друзья'; + $lang->cmd_add_friend = 'Добавить в друзья'; + $lang->cmd_view_message_box = 'Личные сообщений'; + $lang->cmd_store = "Сохранить"; + $lang->cmd_add_friend_group = 'Добавить в группу друзей'; + $lang->cmd_rename_friend_group = 'Изменить имя группы друзей'; + + $lang->msg_no_message = 'Сообщений нет'; + $lang->message_received = 'У Вас новое сообщение'; + + $lang->msg_title_is_null = 'Пожалуйста, введите тему сообщения'; + $lang->msg_content_is_null = 'Пожалуйста, введите содержание'; + $lang->msg_allow_message_to_friend = "Сообщение не отправлено, поскольку являетесь пользователем, имеющим право посылать сообщения только друзьям"; + $lang->msg_disallow_message = 'Сообщение не отправлено, поскольку получатель запретил прием сообщений'; + $lang->about_allow_message = 'Вы можете установить режим принятия сообщений'; +?> diff --git a/modules/communication/lang/vi.lang.php b/modules/communication/lang/vi.lang.php index bdba67710..ef9514c86 100644 --- a/modules/communication/lang/vi.lang.php +++ b/modules/communication/lang/vi.lang.php @@ -1,50 +1,50 @@ -communication = 'Thông báo'; - $lang->about_communication = 'Module này thực hiện chức năng giao tiếp, tin nhắn hay bạn bè.'; - - $lang->allow_message = 'Nhận tin nhắn'; - $lang->allow_message_type = array( - 'Y' => 'Nhận tất cả', - 'N' => 'Từ chối tất cả', - 'F' => 'Chỉ bạn bè', - ); - - $lang->message_box = array( - 'R' => 'Đã nhận', - 'S' => 'Gửi', - 'T' => 'Hòm thư', - ); - $lang->readed_date = "Ngày đọc"; - - $lang->sender = 'Người gửi'; - $lang->receiver = 'Người nhận'; - $lang->friend_group = 'Nhóm bạn'; - $lang->default_friend_group = 'Nhóm mặc định'; - - $lang->cmd_send_message = 'Gửi tin nhắn'; - $lang->cmd_reply_message = 'Trả lời tin nhắn'; - $lang->cmd_view_friend = 'Bạn bè'; - $lang->cmd_add_friend = 'Thêm bạn'; - $lang->cmd_view_message_box = 'Hộp tin nhắn'; - $lang->cmd_store = "Lưu"; - $lang->cmd_add_friend_group = 'Thêm nhóm bạn'; - $lang->cmd_rename_friend_group = 'Sử tên nhóm'; - - $lang->msg_no_message = 'Không có tin nhắn nào.'; - $lang->message_received = 'Bạn có tin nhắn mới.'; - - $lang->msg_title_is_null = 'Xin vui lòng nhập tiêu đề của tin nhắn.'; - $lang->msg_content_is_null = 'Xin vui lòng nhập nội dung.'; - $lang->msg_allow_message_to_friend = "Không thể gửi vì người nhận chỉ chấp nhận những tin nhắn từ bạn bè của họ."; - $lang->msg_disallow_message = 'Không thể gửi vì người nhận đã từ chối nhận tin nhắn.'; - - $lang->about_allow_message = 'Bạn có thể đồng ý nhận tin nhắn.'; -?> +communication = 'Thông báo'; + $lang->about_communication = 'Module này thực hiện chức năng giao tiếp, tin nhắn hay bạn bè.'; + + $lang->allow_message = 'Nhận tin nhắn'; + $lang->allow_message_type = array( + 'Y' => 'Nhận tất cả', + 'N' => 'Từ chối tất cả', + 'F' => 'Chỉ bạn bè', + ); + + $lang->message_box = array( + 'R' => 'Đã nhận', + 'S' => 'Gửi', + 'T' => 'Hòm thư', + ); + $lang->readed_date = "Ngày đọc"; + + $lang->sender = 'Người gửi'; + $lang->receiver = 'Người nhận'; + $lang->friend_group = 'Nhóm bạn'; + $lang->default_friend_group = 'Nhóm mặc định'; + + $lang->cmd_send_message = 'Gửi tin nhắn'; + $lang->cmd_reply_message = 'Trả lời tin nhắn'; + $lang->cmd_view_friend = 'Bạn bè'; + $lang->cmd_add_friend = 'Thêm bạn'; + $lang->cmd_view_message_box = 'Hộp tin nhắn'; + $lang->cmd_store = "Lưu"; + $lang->cmd_add_friend_group = 'Thêm nhóm bạn'; + $lang->cmd_rename_friend_group = 'Sử tên nhóm'; + + $lang->msg_no_message = 'Không có tin nhắn nào.'; + $lang->message_received = 'Bạn có tin nhắn mới.'; + + $lang->msg_title_is_null = 'Xin vui lòng nhập tiêu đề của tin nhắn.'; + $lang->msg_content_is_null = 'Xin vui lòng nhập nội dung.'; + $lang->msg_allow_message_to_friend = "Không thể gửi vì người nhận chỉ chấp nhận những tin nhắn từ bạn bè của họ."; + $lang->msg_disallow_message = 'Không thể gửi vì người nhận đã từ chối nhận tin nhắn.'; + + $lang->about_allow_message = 'Bạn có thể đồng ý nhận tin nhắn.'; +?> diff --git a/modules/communication/lang/zh-CN.lang.php b/modules/communication/lang/zh-CN.lang.php index 0f8360d43..e587513eb 100644 --- a/modules/communication/lang/zh-CN.lang.php +++ b/modules/communication/lang/zh-CN.lang.php @@ -1,49 +1,49 @@ -communication = '会员交流'; - $lang->about_communication = '管理在线会员间短信息及好友功能的模块。'; - - $lang->allow_message = '接收短消息'; - $lang->allow_message_type = array( - 'Y' => '全部接收', - 'N' => '拒收', - 'F' => '只允许好友', - ); - - $lang->message_box = array( - 'R' => '收件箱', - 'S' => '发件箱', - 'T' => '保管箱', - ); - - $lang->readed_date = "阅读日期"; - - $lang->sender = '寄件人'; - $lang->receiver = '收件人'; - $lang->friend_group = '好友组'; - $lang->default_friend_group = '组未指定'; - - $lang->cmd_send_message = '发送短消息'; - $lang->cmd_reply_message = '回复短消息'; - $lang->cmd_view_friend = '我的好友'; - $lang->cmd_add_friend = '加为好友'; - $lang->cmd_view_message_box = '短信箱'; - $lang->cmd_store = "保管"; - $lang->cmd_add_friend_group = '添加好友组'; - $lang->cmd_rename_friend_group = '修改好友组名称'; - - $lang->msg_no_message = '没有短消息。'; - $lang->message_received = '您有新消息。'; - - $lang->msg_title_is_null = '请输入短消息标题。'; - $lang->msg_content_is_null = '请输入内容。'; - $lang->msg_allow_message_to_friend = '因其为只允许接收好友短消息的用户,所以不能发送短消息。'; - $lang->msg_disallow_message = '因其为拒绝接收短消息的用户,所以不能发送短消息。'; - - $lang->about_allow_message = '可以选择短消息接收与否。'; -?> +communication = '会员交流'; + $lang->about_communication = '管理在线会员间短信息及好友功能的模块。'; + + $lang->allow_message = '接收短消息'; + $lang->allow_message_type = array( + 'Y' => '全部接收', + 'N' => '拒收', + 'F' => '只允许好友', + ); + + $lang->message_box = array( + 'R' => '收件箱', + 'S' => '发件箱', + 'T' => '保管箱', + ); + + $lang->readed_date = "阅读日期"; + + $lang->sender = '寄件人'; + $lang->receiver = '收件人'; + $lang->friend_group = '好友组'; + $lang->default_friend_group = '组未指定'; + + $lang->cmd_send_message = '发送短消息'; + $lang->cmd_reply_message = '回复短消息'; + $lang->cmd_view_friend = '我的好友'; + $lang->cmd_add_friend = '加为好友'; + $lang->cmd_view_message_box = '短信箱'; + $lang->cmd_store = "保管"; + $lang->cmd_add_friend_group = '添加好友组'; + $lang->cmd_rename_friend_group = '修改好友组名称'; + + $lang->msg_no_message = '没有短消息。'; + $lang->message_received = '您有新消息。'; + + $lang->msg_title_is_null = '请输入短消息标题。'; + $lang->msg_content_is_null = '请输入内容。'; + $lang->msg_allow_message_to_friend = '因其为只允许接收好友短消息的用户,所以不能发送短消息。'; + $lang->msg_disallow_message = '因其为拒绝接收短消息的用户,所以不能发送短消息。'; + + $lang->about_allow_message = '可以选择短消息接收与否。'; +?> diff --git a/modules/communication/lang/zh-TW.lang.php b/modules/communication/lang/zh-TW.lang.php index 91ecc392a..2b62b46c9 100644 --- a/modules/communication/lang/zh-TW.lang.php +++ b/modules/communication/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ - - 기본 스킨 - 默认皮肤 - 基本スキン - Default Skin - Skin Mặc định - Por defecto piel - 기본 스킨 - 預設面板 - - 디자인 : 서기정 (http://blog.naver.com/addcozy) - HTML/CSS : 정찬명 (http://naradesign.net) - - - 设计 : Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - - デザイン:Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS:Chan-Myung Jeong (http://naradesign.net) - - - Design : Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - - Thiết kế: Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - - Diseño: Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML / CSS: Jeong Chan-Myung (http://naradesign.net) - - - Дизайн: Ги Чен Се (http://blog.naver.com/addcozy) - HTML / CSS: Чен-Чен Мен (http://naradesign.net) - - - 設計 : Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - 0.1 - 2008-05-28 - - - (주)NHN - (株)NHN - (株)NHN - NHN Corp - NHN Corp - NHN Corp - NHN Корп - NHN Corp - - - - - 기본 - 默认 - デフォルト - default - Mặc định - Por defecto - умолчанию - 預設 - - - 청록색 - 青緑 - 青绿色 - cyan - Cyan - Cian - бирюзовый - 青綠色 - - - 초록색 - - 绿色 - green - Green - Verde - зеленый - 綠色 - - - 빨간색 - - 红色 - red - Red - Roja - красный - 紅色 - - - 보라색 - - 紫色 - purple - Purple - Púrpura - Лиловый - 紫色 - - - 검은색 - - Black - Black - Черного - Negro - 黑色 - 黑色 - - - + + + 기본 스킨 + 默认皮肤 + 基本スキン + Default Skin + Skin Mặc định + Por defecto piel + 기본 스킨 + 預設面板 + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + + NHN (developers@xpressengine.com) + + 0.1 + 2008-05-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + + + + 기본 + 默认 + デフォルト + default + Mặc định + Por defecto + умолчанию + 預設 + + + 청록색 + 青緑 + 青绿色 + cyan + Cyan + Cian + бирюзовый + 青綠色 + + + 초록색 + + 绿色 + green + Green + Verde + зеленый + 綠色 + + + 빨간색 + + 红色 + red + Red + Roja + красный + 紅色 + + + 보라색 + + 紫色 + purple + Purple + Púrpura + Лиловый + 紫色 + + + 검은색 + + Black + Black + Черного + Negro + 黑色 + 黑色 + + + diff --git a/modules/counter/conf/info.xml b/modules/counter/conf/info.xml index 4fa33021d..680b9db36 100644 --- a/modules/counter/conf/info.xml +++ b/modules/counter/conf/info.xml @@ -1,33 +1,33 @@ - - - 접속통계 - 访问统计 - Counter - Counter - Contador - アクセスカウンター - Базовый счетчик - 基本統計 - 기본 접속 통계 프로그램입니다. - 默认访问统计程序。 - Basic connection statistics program. - Chương trình thống kê kết nối cơ bản. - Programa básico para la estadística de la conección. - デフォルトアクセス統計のプログラムです。 - Базовая программа статистики подключений. - 預設的統計程式。 - 0.1 - 2007-02-28 - statistics - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 접속통계 + 访问统计 + Counter + Counter + Contador + アクセスカウンター + Базовый счетчик + 基本統計 + 기본 접속 통계 프로그램입니다. + 默认访问统计程序。 + Basic connection statistics program. + Chương trình thống kê kết nối cơ bản. + Programa básico para la estadística de la conección. + デフォルトアクセス統計のプログラムです。 + Базовая программа статистики подключений. + 預設的統計程式。 + 0.1 + 2007-02-28 + statistics + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/counter/counter.admin.view.php b/modules/counter/counter.admin.view.php index 62c556d62..8ef40d49e 100644 --- a/modules/counter/counter.admin.view.php +++ b/modules/counter/counter.admin.view.php @@ -1,50 +1,50 @@ -setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief 관리자 페이지 초기화면 - **/ - function dispCounterAdminIndex() { - // 정해진 일자가 없으면 오늘자로 설정 - $selected_date = Context::get('selected_date'); - if(!$selected_date) $selected_date = date("Ymd"); - Context::set('selected_date', $selected_date); - - // counter model 객체 생성 - $oCounterModel = &getModel('counter'); - - // 전체 카운터 및 지정된 일자의 현황 가져오기 - $site_module_info = Context::get('site_module_info'); - $status = $oCounterModel->getStatus(array(0,$selected_date),$site_module_info->site_srl); - Context::set('total_counter', $status[0]); - Context::set('selected_day_counter', $status[$selected_date]); - - // 시간, 일, 월, 년도별로 데이터 가져오기 - $type = Context::get('type'); - if(!$type) { - $type = 'day'; - Context::set('type',$type); - } - $detail_status = $oCounterModel->getHourlyStatus($type, $selected_date, $site_module_info->site_srl); - Context::set('detail_status', $detail_status); - - // 표시 - $this->setTemplateFile('index'); - } - - } -?> +setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief 관리자 페이지 초기화면 + **/ + function dispCounterAdminIndex() { + // 정해진 일자가 없으면 오늘자로 설정 + $selected_date = Context::get('selected_date'); + if(!$selected_date) $selected_date = date("Ymd"); + Context::set('selected_date', $selected_date); + + // counter model 객체 생성 + $oCounterModel = &getModel('counter'); + + // 전체 카운터 및 지정된 일자의 현황 가져오기 + $site_module_info = Context::get('site_module_info'); + $status = $oCounterModel->getStatus(array(0,$selected_date),$site_module_info->site_srl); + Context::set('total_counter', $status[0]); + Context::set('selected_day_counter', $status[$selected_date]); + + // 시간, 일, 월, 년도별로 데이터 가져오기 + $type = Context::get('type'); + if(!$type) { + $type = 'day'; + Context::set('type',$type); + } + $detail_status = $oCounterModel->getHourlyStatus($type, $selected_date, $site_module_info->site_srl); + Context::set('detail_status', $detail_status); + + // 표시 + $this->setTemplateFile('index'); + } + + } +?> diff --git a/modules/counter/counter.class.php b/modules/counter/counter.class.php index 541c8fea2..163b56032 100644 --- a/modules/counter/counter.class.php +++ b/modules/counter/counter.class.php @@ -1,69 +1,69 @@ -insertTotalStatus(); - - // 오늘자 row입력 - //$oCounterController->insertTodayStatus(); - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $db_info = Context::getDbInfo (); - // 카운터에 site_srl추가 - $oDB = &DB::getInstance(); - if(!$oDB->isColumnExists('counter_log', 'site_srl')) return true; - if ($db_info->db_type == 'cubrid') { - if(!$oDB->isIndexExists('counter_log', $oDB->prefix.'counter_log_idx_site_counter_log')) return true; - } - else { - if(!$oDB->isIndexExists('counter_log','idx_site_counter_log')) return true; - } - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $db_info = Context::getDBInfo (); - // 카운터에 site_srl추가 - $oDB = &DB::getInstance(); - if(!$oDB->isColumnExists('counter_log', 'site_srl')) - $oDB->addColumn('counter_log','site_srl','number',11,0,true); - if ($db_info->db_type == 'cubrid') { - if(!$oDB->isIndexExists('counter_log',$oDB->prefix.'counter_log_idx_site_counter_log')) - $oDB->addIndex('counter_log',$oDB->prefix.'counter_log_idx_site_counter_log',array('site_srl','ipaddress'),false); - } - else { - if(!$oDB->isIndexExists('counter_log','idx_site_counter_log')) - $oDB->addIndex('counter_log','idx_site_counter_log',array('site_srl','ipaddress'),false); - } - - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - } - } -?> +insertTotalStatus(); + + // 오늘자 row입력 + //$oCounterController->insertTodayStatus(); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $db_info = Context::getDbInfo (); + // 카운터에 site_srl추가 + $oDB = &DB::getInstance(); + if(!$oDB->isColumnExists('counter_log', 'site_srl')) return true; + if ($db_info->db_type == 'cubrid') { + if(!$oDB->isIndexExists('counter_log', $oDB->prefix.'counter_log_idx_site_counter_log')) return true; + } + else { + if(!$oDB->isIndexExists('counter_log','idx_site_counter_log')) return true; + } + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $db_info = Context::getDBInfo (); + // 카운터에 site_srl추가 + $oDB = &DB::getInstance(); + if(!$oDB->isColumnExists('counter_log', 'site_srl')) + $oDB->addColumn('counter_log','site_srl','number',11,0,true); + if ($db_info->db_type == 'cubrid') { + if(!$oDB->isIndexExists('counter_log',$oDB->prefix.'counter_log_idx_site_counter_log')) + $oDB->addIndex('counter_log',$oDB->prefix.'counter_log_idx_site_counter_log',array('site_srl','ipaddress'),false); + } + else { + if(!$oDB->isIndexExists('counter_log','idx_site_counter_log')) + $oDB->addIndex('counter_log','idx_site_counter_log',array('site_srl','ipaddress'),false); + } + + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + } + } +?> diff --git a/modules/counter/counter.controller.php b/modules/counter/counter.controller.php index 5c085e453..19708a8a6 100644 --- a/modules/counter/counter.controller.php +++ b/modules/counter/counter.controller.php @@ -1,145 +1,145 @@ -begin(); - - $site_module_info = Context::get('site_module_info'); - $site_srl = (int)$site_module_info->site_srl; - - // 로그를 검사 - $oCounterModel = &getModel('counter'); - - // 오늘자 row가 있는지 체크하여 없으면 등록 - if(!$oCounterModel->isInsertedTodayStatus($site_srl)) { - $this->insertTodayStatus(0,$site_srl); - - // 기존 row가 있으면 사용자 체크 - } else { - - // 등록되어 있지 않은 아이피일 경우 - if(!$oCounterModel->isLogged($site_srl)) { - // 로그 등록 - $this->insertLog($site_srl); - - // unique 및 pageview 등록 - $this->insertUniqueVisitor($site_srl); - } else { - // pageview 등록 - $this->insertPageView($site_srl); - } - } - - $oDB->commit(); - } - - /** - * @brief 로그 등록 - **/ - function insertLog($site_srl=0) { - $args->regdate = date("YmdHis"); - $args->user_agent = substr ($_SERVER['HTTP_USER_AGENT'], 0, 250); - $args->site_srl = $site_srl; - return executeQuery('counter.insertCounterLog', $args); - } - - /** - * @brief unique visitor 등록 - **/ - function insertUniqueVisitor($site_srl=0) { - if($site_srl) { - $args->regdate = '0'; - $args->site_srl = $site_srl; - $output = executeQuery('counter.updateSiteCounterUnique', $args); - $args->regdate = date('Ymd'); - $output = executeQuery('counter.updateSiteCounterUnique', $args); - } else { - $args->regdate = '0'; - $output = executeQuery('counter.updateCounterUnique', $args); - $args->regdate = date('Ymd'); - $output = executeQuery('counter.updateCounterUnique', $args); - } - } - - /** - * @brief pageview 등록 - **/ - function insertPageView($site_srl=0) { - if($site_srl) { - $args->regdate = '0'; - $args->site_srl = $site_srl; - executeQuery('counter.updateSiteCounterPageview', $args); - $args->regdate = date('Ymd'); - executeQuery('counter.updateSiteCounterPageview', $args); - } else { - $args->regdate = '0'; - executeQuery('counter.updateCounterPageview', $args); - $args->regdate = date('Ymd'); - executeQuery('counter.updateCounterPageview', $args); - } - } - - /** - * @brief 전체 카운터 status 추가 - **/ - function insertTotalStatus($site_srl=0) { - $args->regdate = 0; - if($site_srl) { - $args->site_srl = $site_srl; - executeQuery('counter.insertSiteTodayStatus', $args); - } else { - executeQuery('counter.insertTodayStatus', $args); - } - } - - /** - * @brief 오늘자 카운터 status 추가 - **/ - function insertTodayStatus($regdate = 0, $site_srl=0) { - if($regdate) $args->regdate = $regdate; - else $args->regdate = date("Ymd"); - if($site_srl) { - $args->site_srl = $site_srl; - $query_id = 'counter.insertSiteTodayStatus'; - - $u_args->site_srl = $site_srl; ///< 일별 row입력시 전체 row (regdate=0)도 같이 입력 시도 - executeQuery($query_id, $u_args); - } else { - $query_id = 'counter.insertTodayStatus'; - executeQuery($query_id); ///< 일별 row입력시 전체 row (regdate=0)도 같이 입력 시도 - } - $output = executeQuery($query_id, $args); - - // 로그 등록 - $this->insertLog($site_srl); - - // unique 및 pageview 등록 - $this->insertUniqueVisitor($site_srl); - } - - /** - * @brief 특정 가상 사이트의 카운터 로그 삭제 - **/ - function deleteSiteCounterLogs($site_srl) { - $args->site_srl = $site_srl; - executeQuery('counter.deleteSiteCounter',$args); - executeQuery('counter.deleteSiteCounterLog',$args); - } - } -?> +begin(); + + $site_module_info = Context::get('site_module_info'); + $site_srl = (int)$site_module_info->site_srl; + + // 로그를 검사 + $oCounterModel = &getModel('counter'); + + // 오늘자 row가 있는지 체크하여 없으면 등록 + if(!$oCounterModel->isInsertedTodayStatus($site_srl)) { + $this->insertTodayStatus(0,$site_srl); + + // 기존 row가 있으면 사용자 체크 + } else { + + // 등록되어 있지 않은 아이피일 경우 + if(!$oCounterModel->isLogged($site_srl)) { + // 로그 등록 + $this->insertLog($site_srl); + + // unique 및 pageview 등록 + $this->insertUniqueVisitor($site_srl); + } else { + // pageview 등록 + $this->insertPageView($site_srl); + } + } + + $oDB->commit(); + } + + /** + * @brief 로그 등록 + **/ + function insertLog($site_srl=0) { + $args->regdate = date("YmdHis"); + $args->user_agent = substr ($_SERVER['HTTP_USER_AGENT'], 0, 250); + $args->site_srl = $site_srl; + return executeQuery('counter.insertCounterLog', $args); + } + + /** + * @brief unique visitor 등록 + **/ + function insertUniqueVisitor($site_srl=0) { + if($site_srl) { + $args->regdate = '0'; + $args->site_srl = $site_srl; + $output = executeQuery('counter.updateSiteCounterUnique', $args); + $args->regdate = date('Ymd'); + $output = executeQuery('counter.updateSiteCounterUnique', $args); + } else { + $args->regdate = '0'; + $output = executeQuery('counter.updateCounterUnique', $args); + $args->regdate = date('Ymd'); + $output = executeQuery('counter.updateCounterUnique', $args); + } + } + + /** + * @brief pageview 등록 + **/ + function insertPageView($site_srl=0) { + if($site_srl) { + $args->regdate = '0'; + $args->site_srl = $site_srl; + executeQuery('counter.updateSiteCounterPageview', $args); + $args->regdate = date('Ymd'); + executeQuery('counter.updateSiteCounterPageview', $args); + } else { + $args->regdate = '0'; + executeQuery('counter.updateCounterPageview', $args); + $args->regdate = date('Ymd'); + executeQuery('counter.updateCounterPageview', $args); + } + } + + /** + * @brief 전체 카운터 status 추가 + **/ + function insertTotalStatus($site_srl=0) { + $args->regdate = 0; + if($site_srl) { + $args->site_srl = $site_srl; + executeQuery('counter.insertSiteTodayStatus', $args); + } else { + executeQuery('counter.insertTodayStatus', $args); + } + } + + /** + * @brief 오늘자 카운터 status 추가 + **/ + function insertTodayStatus($regdate = 0, $site_srl=0) { + if($regdate) $args->regdate = $regdate; + else $args->regdate = date("Ymd"); + if($site_srl) { + $args->site_srl = $site_srl; + $query_id = 'counter.insertSiteTodayStatus'; + + $u_args->site_srl = $site_srl; ///< 일별 row입력시 전체 row (regdate=0)도 같이 입력 시도 + executeQuery($query_id, $u_args); + } else { + $query_id = 'counter.insertTodayStatus'; + executeQuery($query_id); ///< 일별 row입력시 전체 row (regdate=0)도 같이 입력 시도 + } + $output = executeQuery($query_id, $args); + + // 로그 등록 + $this->insertLog($site_srl); + + // unique 및 pageview 등록 + $this->insertUniqueVisitor($site_srl); + } + + /** + * @brief 특정 가상 사이트의 카운터 로그 삭제 + **/ + function deleteSiteCounterLogs($site_srl) { + $args->site_srl = $site_srl; + executeQuery('counter.deleteSiteCounter',$args); + executeQuery('counter.deleteSiteCounterLog',$args); + } + } +?> diff --git a/modules/counter/counter.model.php b/modules/counter/counter.model.php index 5c1e41096..bcdc3a7ac 100644 --- a/modules/counter/counter.model.php +++ b/modules/counter/counter.model.php @@ -1,201 +1,201 @@ -regdate = date("Ymd"); - $args->ipaddress = $_SERVER['REMOTE_ADDR']; - $args->site_srl = $site_srl; - $output = executeQuery('counter.getCounterLog', $args); - return $output->data->count?true:false; - } - - /** - * @brief 오늘자 카운터 현황 row 있는지 체크 - **/ - function isInsertedTodayStatus($site_srl=0) { - $args->regdate = date("Ymd"); - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteTodayStatus', $args); - } else { - $output = executeQuery('counter.getTodayStatus', $args); - } - return $output->data->count?true:false; - } - - /** - * @brief 특정 일의 접속 통계를 가져옴 - **/ - function getStatus($selected_date, $site_srl=0) { - // 여러개의 날짜 로그를 가져올 경우 - if(is_array($selected_date)) { - $date_count = count($selected_date); - $args->regdate = implode(',',$selected_date); - - // 단일 날짜의 로그를 가져올 경우 - } else { - if(strlen($selected_date)==8) $selected_date = $selected_date; - $args->regdate = $selected_date; - } - - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteCounterStatusDays', $args); - } else { - $output = executeQuery('counter.getCounterStatusDays', $args); - } - $status = $output->data; - - if(!is_array($selected_date)) return $status; - - if(!is_array($status)) $status = array($status); - unset($output); - - foreach($status as $key => $val) { - $output[substr($val->regdate,0,8)] = $val; - } - return $output; - } - - /** - * @brief 지정된 일자의 시간대별 로그 가져오기 - **/ - function getHourlyStatus($type='hour', $selected_date, $site_srl=0) { - $max = 0; - $sum = 0; - switch($type) { - case 'year' : - // 카운터 시작일 구함 - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteStartLogDate', $args); - } else { - $output = executeQuery('counter.getStartLogDate'); - } - $start_year = substr($output->data->regdate,0,4); - if(!$start_year) $start_year = date("Y"); - for($i=$start_year;$i<=date("Y");$i++) { - unset($args); - $args->start_date = sprintf('%04d0000', $i); - $args->end_date = sprintf('%04d1231', $i); - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteCounterStatus', $args); - } else { - $output = executeQuery('counter.getCounterStatus', $args); - } - $count = (int)$output->data->unique_visitor; - $status->list[$i] = $count; - if($count>$max) $max = $count; - $sum += $count; - } - break; - case 'week' : - $time = strtotime($selected_date); - $w = date("D"); - while(date("D",$time) != "Sun") { - $time += 60*60*24; - } - $time -= 60*60*24; - while(date("D",$time)!="Sun") { - $thisWeek[] = date("Ymd",$time); - $time -= 60*60*24; - } - $thisWeek[] = date("Ymd",$time); - asort($thisWeek); - foreach($thisWeek as $day) { - unset($args); - $args->start_date = $day; - $args->end_date = $day; - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteCounterStatus', $args); - } else { - $output = executeQuery('counter.getCounterStatus', $args); - } - $count = (int)$output->data->unique_visitor; - $status->list[$day] = (int)$count; - if($count>$max) $max = $count; - $sum += $count; - } - break; - case 'month' : - $year = substr($selected_date, 0, 4); - for($i=1;$i<=12;$i++) { - unset($args); - $args->start_date = sprintf('%04d%02d00', $year, $i); - $args->end_date = sprintf('%04d%02d31', $year, $i); - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteCounterStatus', $args); - } else { - $output = executeQuery('counter.getCounterStatus', $args); - } - $count = (int)$output->data->unique_visitor; - $status->list[$i] = (int)$count; - if($count>$max) $max = $count; - $sum += $count; - } - break; - case 'hour' : - for($i=0;$i<24;$i++) { - unset($args); - $args->start_date = sprintf('%08d%02d0000', $selected_date, $i); - $args->end_date = sprintf('%08d%02d5959', $selected_date, $i); - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteCounterLogStatus', $args); - } else { - $args->site_srl = 0; - $output = executeQuery('counter.getCounterLogStatus', $args); - } - $count = (int)$output->data->count; - $status->list[$i] = $count; - if($count>$max) $max = $count; - $sum += $count; - } - break; - default : - $year = substr($selected_date, 0, 4); - $month = substr($selected_date, 4, 2); - $end_day = date('t', mktime(0,0,0,$month,1,$year)); - for($i=1;$i<=$end_day;$i++) { - unset($args); - $args->start_date = sprintf('%04d%02d%02d', $year, $month, $i); - $args->end_date = sprintf('%04d%02d%02d', $year, $month, $i); - if($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('counter.getSiteCounterStatus', $args); - } else { - $output = executeQuery('counter.getCounterStatus', $args); - } - $count = (int)$output->data->unique_visitor; - $status->list[$i] = $count; - if($count>$max) $max = $count; - $sum += $count; - } - break; - } - - $status->max = $max; - $status->sum = $sum; - return $status; - } - - } -?> +regdate = date("Ymd"); + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + $args->site_srl = $site_srl; + $output = executeQuery('counter.getCounterLog', $args); + return $output->data->count?true:false; + } + + /** + * @brief 오늘자 카운터 현황 row 있는지 체크 + **/ + function isInsertedTodayStatus($site_srl=0) { + $args->regdate = date("Ymd"); + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteTodayStatus', $args); + } else { + $output = executeQuery('counter.getTodayStatus', $args); + } + return $output->data->count?true:false; + } + + /** + * @brief 특정 일의 접속 통계를 가져옴 + **/ + function getStatus($selected_date, $site_srl=0) { + // 여러개의 날짜 로그를 가져올 경우 + if(is_array($selected_date)) { + $date_count = count($selected_date); + $args->regdate = implode(',',$selected_date); + + // 단일 날짜의 로그를 가져올 경우 + } else { + if(strlen($selected_date)==8) $selected_date = $selected_date; + $args->regdate = $selected_date; + } + + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteCounterStatusDays', $args); + } else { + $output = executeQuery('counter.getCounterStatusDays', $args); + } + $status = $output->data; + + if(!is_array($selected_date)) return $status; + + if(!is_array($status)) $status = array($status); + unset($output); + + foreach($status as $key => $val) { + $output[substr($val->regdate,0,8)] = $val; + } + return $output; + } + + /** + * @brief 지정된 일자의 시간대별 로그 가져오기 + **/ + function getHourlyStatus($type='hour', $selected_date, $site_srl=0) { + $max = 0; + $sum = 0; + switch($type) { + case 'year' : + // 카운터 시작일 구함 + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteStartLogDate', $args); + } else { + $output = executeQuery('counter.getStartLogDate'); + } + $start_year = substr($output->data->regdate,0,4); + if(!$start_year) $start_year = date("Y"); + for($i=$start_year;$i<=date("Y");$i++) { + unset($args); + $args->start_date = sprintf('%04d0000', $i); + $args->end_date = sprintf('%04d1231', $i); + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteCounterStatus', $args); + } else { + $output = executeQuery('counter.getCounterStatus', $args); + } + $count = (int)$output->data->unique_visitor; + $status->list[$i] = $count; + if($count>$max) $max = $count; + $sum += $count; + } + break; + case 'week' : + $time = strtotime($selected_date); + $w = date("D"); + while(date("D",$time) != "Sun") { + $time += 60*60*24; + } + $time -= 60*60*24; + while(date("D",$time)!="Sun") { + $thisWeek[] = date("Ymd",$time); + $time -= 60*60*24; + } + $thisWeek[] = date("Ymd",$time); + asort($thisWeek); + foreach($thisWeek as $day) { + unset($args); + $args->start_date = $day; + $args->end_date = $day; + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteCounterStatus', $args); + } else { + $output = executeQuery('counter.getCounterStatus', $args); + } + $count = (int)$output->data->unique_visitor; + $status->list[$day] = (int)$count; + if($count>$max) $max = $count; + $sum += $count; + } + break; + case 'month' : + $year = substr($selected_date, 0, 4); + for($i=1;$i<=12;$i++) { + unset($args); + $args->start_date = sprintf('%04d%02d00', $year, $i); + $args->end_date = sprintf('%04d%02d31', $year, $i); + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteCounterStatus', $args); + } else { + $output = executeQuery('counter.getCounterStatus', $args); + } + $count = (int)$output->data->unique_visitor; + $status->list[$i] = (int)$count; + if($count>$max) $max = $count; + $sum += $count; + } + break; + case 'hour' : + for($i=0;$i<24;$i++) { + unset($args); + $args->start_date = sprintf('%08d%02d0000', $selected_date, $i); + $args->end_date = sprintf('%08d%02d5959', $selected_date, $i); + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteCounterLogStatus', $args); + } else { + $args->site_srl = 0; + $output = executeQuery('counter.getCounterLogStatus', $args); + } + $count = (int)$output->data->count; + $status->list[$i] = $count; + if($count>$max) $max = $count; + $sum += $count; + } + break; + default : + $year = substr($selected_date, 0, 4); + $month = substr($selected_date, 4, 2); + $end_day = date('t', mktime(0,0,0,$month,1,$year)); + for($i=1;$i<=$end_day;$i++) { + unset($args); + $args->start_date = sprintf('%04d%02d%02d', $year, $month, $i); + $args->end_date = sprintf('%04d%02d%02d', $year, $month, $i); + if($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('counter.getSiteCounterStatus', $args); + } else { + $output = executeQuery('counter.getCounterStatus', $args); + } + $count = (int)$output->data->unique_visitor; + $status->list[$i] = $count; + if($count>$max) $max = $count; + $sum += $count; + } + break; + } + + $status->max = $max; + $status->sum = $sum; + return $status; + } + + } +?> diff --git a/modules/counter/lang/en.lang.php b/modules/counter/lang/en.lang.php index a83ae5668..be9fe5756 100644 --- a/modules/counter/lang/en.lang.php +++ b/modules/counter/lang/en.lang.php @@ -1,25 +1,25 @@ - - * @brief English Language Pack (Only basic contents are listed) - **/ - - $lang->counter = "Counter"; - $lang->cmd_select_date = 'Select Date'; - $lang->cmd_select_counter_type = array( - 'hour' => 'By Hour', - 'day' => 'By Day', - 'month' => 'By Month', - 'year' => 'By Year', - ); - - $lang->total_counter = 'Total Status'; - $lang->selected_day_counter = 'Status of Selected Day'; - - $lang->unique_visitor = 'Visitors'; - $lang->pageview = 'Pageview'; - - $lang->today = 'today'; - $lang->yesterday = 'yesterday'; -?> +counter = "Counter"; + $lang->cmd_select_date = 'Select Date'; + $lang->cmd_select_counter_type = array( + 'hour' => 'By Hour', + 'day' => 'By Day', + 'month' => 'By Month', + 'year' => 'By Year', + ); + + $lang->total_counter = 'Total Status'; + $lang->selected_day_counter = 'Status of Selected Day'; + + $lang->unique_visitor = 'Visitors'; + $lang->pageview = 'Pageview'; + + $lang->today = 'today'; + $lang->yesterday = 'yesterday'; +?> diff --git a/modules/counter/lang/es.lang.php b/modules/counter/lang/es.lang.php index 53b551706..9e5b3df5e 100644 --- a/modules/counter/lang/es.lang.php +++ b/modules/counter/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma español para el contador. **/ diff --git a/modules/counter/lang/fr.lang.php b/modules/counter/lang/fr.lang.php index dd1f0b7e9..5aad22fa2 100644 --- a/modules/counter/lang/fr.lang.php +++ b/modules/counter/lang/fr.lang.php @@ -1,25 +1,25 @@ - Traduit par Pierre Duvent - * @brief Paquet du langage en français pour le module de Comppteur - **/ - - $lang->counter = "Coumpteur"; - $lang->cmd_select_date = 'Choisir un Jour'; - $lang->cmd_select_counter_type = array( - 'hour' => 'Par Heure', - 'day' => 'Par Jour', - 'month' => 'Par Mois', - 'year' => 'Par Année', - ); - - $lang->total_counter = 'Statut Total'; - $lang->selected_day_counter = 'Statut Journal'; - - $lang->unique_visitor = 'Visiteurs'; - $lang->pageview = 'Vues'; - - $lang->today = 'today'; - $lang->yesterday = 'yesterday'; -?> + + * @brief Paquet du langage en français pour le module de Comppteur + **/ + + $lang->counter = "Coumpteur"; + $lang->cmd_select_date = 'Choisir un Jour'; + $lang->cmd_select_counter_type = array( + 'hour' => 'Par Heure', + 'day' => 'Par Jour', + 'month' => 'Par Mois', + 'year' => 'Par Année', + ); + + $lang->total_counter = 'Statut Total'; + $lang->selected_day_counter = 'Statut Journal'; + + $lang->unique_visitor = 'Visiteurs'; + $lang->pageview = 'Vues'; + + $lang->today = 'today'; + $lang->yesterday = 'yesterday'; +?> diff --git a/modules/counter/lang/jp.lang.php b/modules/counter/lang/jp.lang.php index d722aff6d..e0e4807b7 100644 --- a/modules/counter/lang/jp.lang.php +++ b/modules/counter/lang/jp.lang.php @@ -1,25 +1,25 @@ - 翻訳:RisaPapa、ミニミ - * @brief 日本語言語パッケージ(基本的な内容のみ) - **/ - - $lang->counter = 'カウンター'; - $lang->cmd_select_date = '日付選択'; - $lang->cmd_select_counter_type = array( - 'hour' => '時間帯別', - 'day' => '日別', - 'month' => '月別', - 'year' => '年度別', - ); - - $lang->total_counter = 'トータル'; - $lang->selected_day_counter = '選択日の情報'; - - $lang->unique_visitor = '訪問者'; - $lang->pageview = 'ページビュー'; - - $lang->today = '今日'; - $lang->yesterday = '昨日'; -?> +counter = 'カウンター'; + $lang->cmd_select_date = '日付選択'; + $lang->cmd_select_counter_type = array( + 'hour' => '時間帯別', + 'day' => '日別', + 'month' => '月別', + 'year' => '年度別', + ); + + $lang->total_counter = 'トータル'; + $lang->selected_day_counter = '選択日の情報'; + + $lang->unique_visitor = '訪問者'; + $lang->pageview = 'ページビュー'; + + $lang->today = '今日'; + $lang->yesterday = '昨日'; +?> diff --git a/modules/counter/lang/ko.lang.php b/modules/counter/lang/ko.lang.php index 84db94977..b8dca9adb 100644 --- a/modules/counter/lang/ko.lang.php +++ b/modules/counter/lang/ko.lang.php @@ -1,25 +1,25 @@ - - * @brief 한국어 언어팩 (기본적인 내용만 수록) - **/ - - $lang->counter = '접속 통계'; - $lang->cmd_select_date = '날짜 선택'; - $lang->cmd_select_counter_type = array( - 'hour' => '시간대별', - 'day' => '일별', - 'month' => '월별', - 'year' => '연도별', - ); - - $lang->total_counter = '전체현황'; - $lang->selected_day_counter = '선택일 현황'; - - $lang->unique_visitor = '방문자'; - $lang->pageview = '페이지뷰'; - - $lang->today = '오늘'; - $lang->yesterday = '어제'; -?> +counter = '접속 통계'; + $lang->cmd_select_date = '날짜 선택'; + $lang->cmd_select_counter_type = array( + 'hour' => '시간대별', + 'day' => '일별', + 'month' => '월별', + 'year' => '연도별', + ); + + $lang->total_counter = '전체현황'; + $lang->selected_day_counter = '선택일 현황'; + + $lang->unique_visitor = '방문자'; + $lang->pageview = '페이지뷰'; + + $lang->today = '오늘'; + $lang->yesterday = '어제'; +?> diff --git a/modules/counter/lang/ru.lang.php b/modules/counter/lang/ru.lang.php index 90ff07baf..4bec4020b 100644 --- a/modules/counter/lang/ru.lang.php +++ b/modules/counter/lang/ru.lang.php @@ -1,25 +1,25 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->counter = "Счетчик посетителей"; - $lang->cmd_select_date = 'Выберите дату'; - $lang->cmd_select_counter_type = array( - 'hour' => 'По часам', - 'day' => 'По дням', - 'month' => 'По месяцам', - 'year' => 'По годам', - ); - - $lang->total_counter = 'Общее состояние'; - $lang->selected_day_counter = 'Состояние на выбранный день'; - - $lang->unique_visitor = 'Посетителей'; - $lang->pageview = 'Просмотров страниц'; - - $lang->today = 'Сегодня'; - $lang->yesterday = 'Вчера'; -?> +counter = "Счетчик посетителей"; + $lang->cmd_select_date = 'Выберите дату'; + $lang->cmd_select_counter_type = array( + 'hour' => 'По часам', + 'day' => 'По дням', + 'month' => 'По месяцам', + 'year' => 'По годам', + ); + + $lang->total_counter = 'Общее состояние'; + $lang->selected_day_counter = 'Состояние на выбранный день'; + + $lang->unique_visitor = 'Посетителей'; + $lang->pageview = 'Просмотров страниц'; + + $lang->today = 'Сегодня'; + $lang->yesterday = 'Вчера'; +?> diff --git a/modules/counter/lang/vi.lang.php b/modules/counter/lang/vi.lang.php index 15e73da24..aa74830fa 100644 --- a/modules/counter/lang/vi.lang.php +++ b/modules/counter/lang/vi.lang.php @@ -1,27 +1,27 @@ -counter = "Lượt truy cập"; - $lang->cmd_select_date = 'Chọn ngày'; - $lang->cmd_select_counter_type = array( - 'hour' => 'Theo giờ', - 'day' => 'Theo ngày', - 'month' => 'Theo tháng', - 'year' => 'Theo năm', - ); - - $lang->total_counter = 'Tổng số lượt truy cập'; - $lang->selected_day_counter = 'Số truy cập trong ngày'; - - $lang->unique_visitor = 'Số lượt xem'; - $lang->pageview = 'Số trang'; - - $lang->today = 'Hôm nay'; - $lang->yesterday = 'Hôm qua'; -?> +counter = "Lượt truy cập"; + $lang->cmd_select_date = 'Chọn ngày'; + $lang->cmd_select_counter_type = array( + 'hour' => 'Theo giờ', + 'day' => 'Theo ngày', + 'month' => 'Theo tháng', + 'year' => 'Theo năm', + ); + + $lang->total_counter = 'Tổng số lượt truy cập'; + $lang->selected_day_counter = 'Số truy cập trong ngày'; + + $lang->unique_visitor = 'Số lượt xem'; + $lang->pageview = 'Số trang'; + + $lang->today = 'Hôm nay'; + $lang->yesterday = 'Hôm qua'; +?> diff --git a/modules/counter/lang/zh-CN.lang.php b/modules/counter/lang/zh-CN.lang.php index 7561e8503..79459993e 100644 --- a/modules/counter/lang/zh-CN.lang.php +++ b/modules/counter/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 简体中文语言包 **/ diff --git a/modules/counter/lang/zh-TW.lang.php b/modules/counter/lang/zh-TW.lang.php index 317e79577..7b516a7a3 100644 --- a/modules/counter/lang/zh-TW.lang.php +++ b/modules/counter/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 訪問統計(counter)模組正體中文語言 **/ diff --git a/modules/document/conf/info.xml b/modules/document/conf/info.xml index 33b47e1d7..682d6f7c5 100644 --- a/modules/document/conf/info.xml +++ b/modules/document/conf/info.xml @@ -1,33 +1,33 @@ - - - 문서 - Document - Bài viết - Documento - 主题管理 - ドキュメント - Документы - 主題 - 게시판, 블로그등의 모듈에서 사용되는 문서를 관리하는 모듈입니다. - Module for managing documents used in board, blog, etc. - Module quản lý bài viết trên Board, Sổ lưu niệm và những mục khác. - Módulo para manejar los documentos en blog y en los tableros. - 管理版面,博客等处主题的模块。 - 掲示板、ブログなどのモジュールで使用されるドキュメント(書き込み)を管理します。 - Модуль для управления документами в форуме, блоге и прочее. - 管理討論板,部落格等主題的模組。 - 0.1 - 2007-02-28 - content - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 문서 + Document + Bài viết + Documento + 主题管理 + ドキュメント + Документы + 主題 + 게시판, 블로그등의 모듈에서 사용되는 문서를 관리하는 모듈입니다. + Module for managing documents used in board, blog, etc. + Module quản lý bài viết trên Board, Sổ lưu niệm và những mục khác. + Módulo para manejar los documentos en blog y en los tableros. + 管理版面,博客等处主题的模块。 + 掲示板、ブログなどのモジュールで使用されるドキュメント(書き込み)を管理します。 + Модуль для управления документами в форуме, блоге и прочее. + 管理討論板,部落格等主題的模組。 + 0.1 + 2007-02-28 + content + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/document/document.admin.controller.php b/modules/document/document.admin.controller.php index a59c71af8..f3f69cfd5 100644 --- a/modules/document/document.admin.controller.php +++ b/modules/document/document.admin.controller.php @@ -1,547 +1,547 @@ -stop('msg_cart_is_null'); - $document_srl_list= explode('|@|', $cart); - $document_count = count($document_srl_list); - if(!$document_count) return $this->stop('msg_cart_is_null'); - - // 글삭제 - $oDocumentController = &getController('document'); - for($i=0;$i<$document_count;$i++) { - $document_srl = trim($document_srl_list[$i]); - if(!$document_srl) continue; - - $oDocumentController->deleteDocument($document_srl, true); - } - - $this->setMessage( sprintf(Context::getLang('msg_checked_document_is_deleted'), $document_count) ); - } - - /** - * @brief 특정 게시물들의 소속 모듈 변경 (게시글 이동시에 사용) - **/ - function moveDocumentModule($document_srl_list, $module_srl, $category_srl) { - if(!count($document_srl_list)) return; - - $oDocumentModel = &getModel('document'); - $oDocumentController = &getController('document'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - $triggerObj->document_srls = implode(',',$document_srl_list); - $triggerObj->module_srl = $module_srl; - $triggerObj->category_srl = $category_srl; - - // Call trigger (before) - $output = ModuleHandler::triggerCall('document.moveDocumentModule', 'before', $triggerObj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - for($i=count($document_srl_list)-1;$i>=0;$i--) { - $document_srl = $document_srl_list[$i]; - $oDocument = $oDocumentModel->getDocument($document_srl); - if(!$oDocument->isExists()) continue; - - $source_category_srl = $oDocument->get('category_srl'); - - unset($obj); - $obj = $oDocument->getObjectVars(); - - // 대상 모듈이 다를 경우 첨부파일 이동 - if($module_srl != $obj->module_srl && $oDocument->hasUploadedFiles()) { - $oFileController = &getController('file'); - - $files = $oDocument->getUploadedFiles(); - foreach($files as $key => $val) { - $file_info = array(); - $file_info['tmp_name'] = $val->uploaded_filename; - $file_info['name'] = $val->source_filename; - $inserted_file = $oFileController->insertFile($file_info, $module_srl, $obj->document_srl, $val->download_count, true); - if($inserted_file && $inserted_file->toBool()) { - // 이미지/동영상등일 경우 - if($val->direct_download == 'Y') { - $source_filename = substr($val->uploaded_filename,2); - $target_filename = substr($inserted_file->get('uploaded_filename'),2); - $obj->content = str_replace($source_filename, $target_filename, $obj->content); - - // binary 파일일 경우 - } else { - $obj->content = str_replace('file_srl='.$val->file_srl, 'file_srl='.$inserted_file->get('file_srl'), $obj->content); - $obj->content = str_replace('sid='.$val->sid, 'sid='.$inserted_file->get('sid'), $obj->content); - } - } - - // 기존 파일 삭제 - $oFileController->deleteFile($val->file_srl); - } - - // 등록된 모든 파일을 유효로 변경 - $oFileController->setFilesValid($obj->document_srl); - } - - if($module_srl != $obj->module_srl) - { - $oDocumentController->deleteDocumentAliasByDocument($obj->document_srl); - } - - // 게시물의 모듈 이동 - $obj->module_srl = $module_srl; - $obj->category_srl = $category_srl; - $output = executeQuery('document.updateDocumentModule', $obj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 카테고리가 변경되었으면 검사후 없는 카테고리면 0으로 세팅 - if($source_category_srl != $category_srl) { - if($source_category_srl) $oDocumentController->updateCategoryCount($oDocument->get('module_srl'), $source_category_srl); - if($category_srl) $oDocumentController->updateCategoryCount($module_srl, $category_srl); - } - - } - - $args->document_srls = implode(',',$document_srl_list); - $args->module_srl = $module_srl; - - // 댓글의 이동 - $output = executeQuery('comment.updateCommentModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - $output = executeQuery('comment.updateCommentListModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 엮인글의 이동 - $output = executeQuery('trackback.updateTrackbackModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 태그 - $output = executeQuery('tag.updateTagModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // Call trigger (before) - $output = ModuleHandler::triggerCall('document.moveDocumentModule', 'after', $triggerObj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - $oDB->commit(); - return new Object(); - } - - /** - * @brief 게시글의 복사 - **/ - function copyDocumentModule($document_srl_list, $module_srl, $category_srl) { - if(!count($document_srl_list)) return; - - $oDocumentModel = &getModel('document'); - $oDocumentController = &getController('document'); - - $oFileModel = &getModel('file'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - for($i=count($document_srl_list)-1;$i>=0;$i--) { - $document_srl = $document_srl_list[$i]; - $oDocument = $oDocumentModel->getDocument($document_srl); - if(!$oDocument->isExists()) continue; - - $obj = null; - $obj = $oDocument->getObjectVars(); - $obj->module_srl = $module_srl; - $obj->document_srl = getNextSequence(); - $obj->category_srl = $category_srl; - $obj->password_is_hashed = true; - $obj->comment_count = 0; - $obj->trackback_count = 0; - - // 첨부파일 미리 등록 - if($oDocument->hasUploadedFiles()) { - $files = $oDocument->getUploadedFiles(); - foreach($files as $key => $val) { - $file_info = array(); - $file_info['tmp_name'] = $val->uploaded_filename; - $file_info['name'] = $val->source_filename; - $oFileController = &getController('file'); - $inserted_file = $oFileController->insertFile($file_info, $module_srl, $obj->document_srl, 0, true); - - // 이미지/동영상등일 경우 - if($val->direct_download == 'Y') { - $source_filename = substr($val->uploaded_filename,2); - $target_filename = substr($inserted_file->get('uploaded_filename'),2); - $obj->content = str_replace($source_filename, $target_filename, $obj->content); - - // binary 파일일 경우 - } else { - $obj->content = str_replace('file_srl='.$val->file_srl, 'file_srl='.$inserted_file->get('file_srl'), $obj->content); - $obj->content = str_replace('sid='.$val->sid, 'sid='.$inserted_file->get('sid'), $obj->content); - } - } - } - - // 글의 등록 - $output = $oDocumentController->insertDocument($obj, true); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 댓글 이전 - if($oDocument->getCommentCount()) { - $oCommentModel = &getModel('comment'); - $comment_output = $oCommentModel->getCommentList($document_srl, 0, true, 99999999); - $comments = $comment_output->data; - if(count($comments)) { - $oCommentController = &getController('comment'); - $success_count = 0; - $p_comment_srl = array(); - foreach($comments as $comment_obj) { - $comment_srl = getNextSequence(); - $p_comment_srl[$comment_obj->comment_srl] = $comment_srl; - - $comment_obj->module_srl = $obj->module_srl; - $comment_obj->document_srl = $obj->document_srl; - $comment_obj->comment_srl = $comment_srl; - - if($comment_obj->parent_srl) $comment_obj->parent_srl = $p_comment_srl[$comment_obj->parent_srl]; - - $output = $oCommentController->insertComment($comment_obj, true); - if($output->toBool()) $success_count ++; - } - $oDocumentController->updateCommentCount($obj->document_srl, $success_count, $comment_obj->nick_name, true); - - } - - } - - // 엮인글 이전 - if($oDocument->getTrackbackCount()) { - $oTrackbackModel = &getModel('trackback'); - $trackbacks = $oTrackbackModel->getTrackbackList($oDocument->document_srl); - if(count($trackbacks)) { - $success_count = 0; - foreach($trackbacks as $trackback_obj) { - $trackback_obj->trackback_srl = getNextSequence(); - $trackback_obj->module_srl = $obj->module_srl; - $trackback_obj->document_srl = $obj->document_srl; - $output = executeQuery('trackback.insertTrackback', $trackback_obj); - if($output->toBool()) $success_count++; - } - - // 엮인글 수 업데이트 - $oDocumentController->updateTrackbackCount($obj->document_srl, $success_count); - } - } - - $copied_srls[$document_srl] = $obj->document_srl; - } - $oDB->commit(); - - $output = new Object(); - $output->add('copied_srls', $copied_srls); - return $output; - } - - /** - * @brief 특정 모듈의 전체 문서 삭제 - **/ - function deleteModuleDocument($module_srl) { - $args->module_srl = $module_srl; - $output = executeQuery('document.deleteModuleDocument', $args); - return $output; - } - - /** - * @brief 문서 모듈의 기본설정 저장 - **/ - function procDocumentAdminInsertConfig() { - // 기본 정보를 받음 - $config = Context::gets('thumbnail_type'); - - // module Controller 객체 생성하여 입력 - $oModuleController = &getController('module'); - $output = $oModuleController->insertModuleConfig('document',$config); - return $output; - } - - /** - * @brief 선택된 글들에 대해 신고 취소 - **/ - function procDocumentAdminCancelDeclare() { - $document_srl = trim(Context::get('document_srl')); - - if($document_srl) { - $args->document_srl = $document_srl; - $output = executeQuery('document.deleteDeclaredDocuments', $args); - if(!$output->toBool()) return $output; - } - } - - /** - * @brief 모든 생성된 썸네일 삭제 - **/ - function procDocumentAdminDeleteAllThumbnail() { - - // files/attaches/images/ 디렉토리를 순환하면서 thumbnail_*.jpg 파일을 모두 삭제 (1.0.4 이전까지) - $this->deleteThumbnailFile('./files/attach/images'); - - // files/cache/thumbnails 디렉토리 자체를 삭제 (1.0.5 이후 변경된 썸네일 정책) - FileHandler::removeFilesInDir('./files/cache/thumbnails'); - - $this->setMessage('success_deleted'); - } - - function deleteThumbnailFile($path) { - $directory = dir($path); - while($entry = $directory->read()) { - if ($entry != "." && $entry != "..") { - if (is_dir($path."/".$entry)) { - $this->deleteThumbnailFile($path."/".$entry); - } else { - if(!preg_match('/^thumbnail_([^\.]*)\.jpg$/i',$entry)) continue; - FileHandler::removeFile($path.'/'.$entry); - } - } - } - $directory->close(); - } - - /** - * @brief 모듈의 확장 변수 추가 또는 수정 - **/ - function procDocumentAdminInsertExtraVar() { - $module_srl = Context::get('module_srl'); - $var_idx = Context::get('var_idx'); - $name = Context::get('name'); - $type = Context::get('type'); - $is_required = Context::get('is_required'); - $default = Context::get('default'); - $desc = Context::get('desc'); - $search = Context::get('search'); - $eid = Context::get('eid'); - - if(!$module_srl || !$name || !$eid) return new Object(-1,'msg_invalid_request'); - - // idx가 지정되어 있지 않으면 최고 값을 지정 - if(!$var_idx) { - $obj->module_srl = $module_srl; - $output = executeQuery('document.getDocumentMaxExtraKeyIdx', $obj); - $var_idx = $output->data->var_idx+1; - } - - // 이미 존재하는 모듈 이름인지 체크 - $obj->module_srl = $module_srl; - $obj->var_idx = $var_idx; - $obj->eid = $eid; - $output = executeQuery('document.isExistsExtraKey', $obj); - if(!$output->toBool() || $output->data->count) { - return new Object(-1, 'msg_extra_name_exists'); - } - - // insert or update - $oDocumentController = &getController('document'); - $output = $oDocumentController->insertDocumentExtraKey($module_srl, $var_idx, $name, $type, $is_required, $search, $default, $desc, $eid); - if(!$output->toBool()) return $output; - - $this->setMessage('success_registed'); - } - - /** - * @brief 모듈의 확장 변수 삭제 - **/ - function procDocumentAdminDeleteExtraVar() { - $module_srl = Context::get('module_srl'); - $var_idx = Context::get('var_idx'); - if(!$module_srl || !$var_idx) return new Object(-1,'msg_invalid_request'); - - $oDocumentController = &getController('document'); - $output = $oDocumentController->deleteDocumentExtraKeys($module_srl, $var_idx); - if(!$output->toBool()) return $output; - - $this->setMessage('success_deleted'); - } - - /** - * @brief 확장변수 순서 조절 - **/ - function procDocumentAdminMoveExtraVar() { - $type = Context::get('type'); - $module_srl = Context::get('module_srl'); - $var_idx = Context::get('var_idx'); - - if(!$type || !$module_srl || !$var_idx) return new Object(-1,'msg_invalid_request'); - - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - if(!$module_info->module_srl) return new Object(-1,'msg_invalid_request'); - - $oDocumentModel = &getModel('document'); - $extra_keys = $oDocumentModel->getExtraKeys($module_srl); - if(!$extra_keys[$var_idx]) return new Object(-1,'msg_invalid_request'); - - if($type == 'up') $new_idx = $var_idx-1; - else $new_idx = $var_idx+1; - if($new_idx<1) return new Object(-1,'msg_invalid_request'); - - // 바꿀 idx가 없으면 바로 업데이트 - if(!$extra_keys[$new_idx]) { - $args->module_srl = $module_srl; - $args->var_idx = $var_idx; - $args->new_idx = $new_idx; - $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); - if(!$output->toBool()) return $output; - $output = executeQuery('document.updateDocumentExtraVarIdx', $args); - if(!$output->toBool()) return $output; - // 있으면 기존의 꺼랑 교체 - } else { - $args->module_srl = $module_srl; - $args->var_idx = $new_idx; - $args->new_idx = -10000; - $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); - if(!$output->toBool()) return $output; - $output = executeQuery('document.updateDocumentExtraVarIdx', $args); - if(!$output->toBool()) return $output; - - $args->var_idx = $var_idx; - $args->new_idx = $new_idx; - $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); - if(!$output->toBool()) return $output; - $output = executeQuery('document.updateDocumentExtraVarIdx', $args); - if(!$output->toBool()) return $output; - - $args->var_idx = -10000; - $args->new_idx = $var_idx; - $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); - if(!$output->toBool()) return $output; - $output = executeQuery('document.updateDocumentExtraVarIdx', $args); - if(!$output->toBool()) return $output; - } - } - - function procDocumentAdminInsertAlias() { - $args = Context::gets('module_srl','document_srl', 'alias_title'); - $alias_srl = Context::get('alias_srl'); - if(!$alias_srl) - { - $args->alias_srl = getNextSequence(); - $query = "document.insertAlias"; - } - else - { - $args->alias_srl = $alias_srl; - $query = "document.updateAlias"; - } - $output = executeQuery($query, $args); - if(!$output->toBool()) - { - return $output; - } - } - - function procDocumentAdminDeleteAlias() { - $alias_srl = Context::get('alias_srl'); - $args->alias_srl = $alias_srl; - $output = executeQuery("document.deleteAlias", $args); - if (!$output->toBool()) - { - return $output; - } - } - - function procDocumentAdminRestoreTrash() { - $trash_srl = Context::get('trash_srl'); - $this->restoreTrash($trash_srl); - } - - function restoreTrash($trash_srl){ - $oDB = &DB::getInstance(); - $oDocumentModel = &getModel('document'); - - $trash_args->trash_srl = $trash_srl; - - $output = executeQuery('document.getTrash', $trash_args); - if (!$output->toBool()) { - return $output; - } - - $document_args->document_srl = $output->data->document_srl; - $document_args->module_srl = $output->data->module_srl; - $document_args->member_srl = $output->data->member_srl; - - $oDocument = $oDocumentModel->getDocument($document_args->document_srl); - - // begin transaction - $oDB->begin(); - - $output = executeQuery('document.updateDocument', $document_args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - $output = executeQuery('document.deleteTrash', $trash_args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 임시 저장되었던 글이 아닌 경우, 등록된 첨부파일의 상태를 유효로 지정 - if($oDocument->hasUploadedFiles() && $document_args->member_srl != $document_args->module_srl) { - $args->upload_target_srl = $oDocument->document_srl; - $args->isvalid = 'Y'; - executeQuery('file.updateFileValid', $args); - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('document.restoreTrash', 'after', $document_args); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - return $output; - } - - } -?> +stop('msg_cart_is_null'); + $document_srl_list= explode('|@|', $cart); + $document_count = count($document_srl_list); + if(!$document_count) return $this->stop('msg_cart_is_null'); + + // 글삭제 + $oDocumentController = &getController('document'); + for($i=0;$i<$document_count;$i++) { + $document_srl = trim($document_srl_list[$i]); + if(!$document_srl) continue; + + $oDocumentController->deleteDocument($document_srl, true); + } + + $this->setMessage( sprintf(Context::getLang('msg_checked_document_is_deleted'), $document_count) ); + } + + /** + * @brief 특정 게시물들의 소속 모듈 변경 (게시글 이동시에 사용) + **/ + function moveDocumentModule($document_srl_list, $module_srl, $category_srl) { + if(!count($document_srl_list)) return; + + $oDocumentModel = &getModel('document'); + $oDocumentController = &getController('document'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + $triggerObj->document_srls = implode(',',$document_srl_list); + $triggerObj->module_srl = $module_srl; + $triggerObj->category_srl = $category_srl; + + // Call trigger (before) + $output = ModuleHandler::triggerCall('document.moveDocumentModule', 'before', $triggerObj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + for($i=count($document_srl_list)-1;$i>=0;$i--) { + $document_srl = $document_srl_list[$i]; + $oDocument = $oDocumentModel->getDocument($document_srl); + if(!$oDocument->isExists()) continue; + + $source_category_srl = $oDocument->get('category_srl'); + + unset($obj); + $obj = $oDocument->getObjectVars(); + + // 대상 모듈이 다를 경우 첨부파일 이동 + if($module_srl != $obj->module_srl && $oDocument->hasUploadedFiles()) { + $oFileController = &getController('file'); + + $files = $oDocument->getUploadedFiles(); + foreach($files as $key => $val) { + $file_info = array(); + $file_info['tmp_name'] = $val->uploaded_filename; + $file_info['name'] = $val->source_filename; + $inserted_file = $oFileController->insertFile($file_info, $module_srl, $obj->document_srl, $val->download_count, true); + if($inserted_file && $inserted_file->toBool()) { + // 이미지/동영상등일 경우 + if($val->direct_download == 'Y') { + $source_filename = substr($val->uploaded_filename,2); + $target_filename = substr($inserted_file->get('uploaded_filename'),2); + $obj->content = str_replace($source_filename, $target_filename, $obj->content); + + // binary 파일일 경우 + } else { + $obj->content = str_replace('file_srl='.$val->file_srl, 'file_srl='.$inserted_file->get('file_srl'), $obj->content); + $obj->content = str_replace('sid='.$val->sid, 'sid='.$inserted_file->get('sid'), $obj->content); + } + } + + // 기존 파일 삭제 + $oFileController->deleteFile($val->file_srl); + } + + // 등록된 모든 파일을 유효로 변경 + $oFileController->setFilesValid($obj->document_srl); + } + + if($module_srl != $obj->module_srl) + { + $oDocumentController->deleteDocumentAliasByDocument($obj->document_srl); + } + + // 게시물의 모듈 이동 + $obj->module_srl = $module_srl; + $obj->category_srl = $category_srl; + $output = executeQuery('document.updateDocumentModule', $obj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 카테고리가 변경되었으면 검사후 없는 카테고리면 0으로 세팅 + if($source_category_srl != $category_srl) { + if($source_category_srl) $oDocumentController->updateCategoryCount($oDocument->get('module_srl'), $source_category_srl); + if($category_srl) $oDocumentController->updateCategoryCount($module_srl, $category_srl); + } + + } + + $args->document_srls = implode(',',$document_srl_list); + $args->module_srl = $module_srl; + + // 댓글의 이동 + $output = executeQuery('comment.updateCommentModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + $output = executeQuery('comment.updateCommentListModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 엮인글의 이동 + $output = executeQuery('trackback.updateTrackbackModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 태그 + $output = executeQuery('tag.updateTagModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // Call trigger (before) + $output = ModuleHandler::triggerCall('document.moveDocumentModule', 'after', $triggerObj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + $oDB->commit(); + return new Object(); + } + + /** + * @brief 게시글의 복사 + **/ + function copyDocumentModule($document_srl_list, $module_srl, $category_srl) { + if(!count($document_srl_list)) return; + + $oDocumentModel = &getModel('document'); + $oDocumentController = &getController('document'); + + $oFileModel = &getModel('file'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + for($i=count($document_srl_list)-1;$i>=0;$i--) { + $document_srl = $document_srl_list[$i]; + $oDocument = $oDocumentModel->getDocument($document_srl); + if(!$oDocument->isExists()) continue; + + $obj = null; + $obj = $oDocument->getObjectVars(); + $obj->module_srl = $module_srl; + $obj->document_srl = getNextSequence(); + $obj->category_srl = $category_srl; + $obj->password_is_hashed = true; + $obj->comment_count = 0; + $obj->trackback_count = 0; + + // 첨부파일 미리 등록 + if($oDocument->hasUploadedFiles()) { + $files = $oDocument->getUploadedFiles(); + foreach($files as $key => $val) { + $file_info = array(); + $file_info['tmp_name'] = $val->uploaded_filename; + $file_info['name'] = $val->source_filename; + $oFileController = &getController('file'); + $inserted_file = $oFileController->insertFile($file_info, $module_srl, $obj->document_srl, 0, true); + + // 이미지/동영상등일 경우 + if($val->direct_download == 'Y') { + $source_filename = substr($val->uploaded_filename,2); + $target_filename = substr($inserted_file->get('uploaded_filename'),2); + $obj->content = str_replace($source_filename, $target_filename, $obj->content); + + // binary 파일일 경우 + } else { + $obj->content = str_replace('file_srl='.$val->file_srl, 'file_srl='.$inserted_file->get('file_srl'), $obj->content); + $obj->content = str_replace('sid='.$val->sid, 'sid='.$inserted_file->get('sid'), $obj->content); + } + } + } + + // 글의 등록 + $output = $oDocumentController->insertDocument($obj, true); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 댓글 이전 + if($oDocument->getCommentCount()) { + $oCommentModel = &getModel('comment'); + $comment_output = $oCommentModel->getCommentList($document_srl, 0, true, 99999999); + $comments = $comment_output->data; + if(count($comments)) { + $oCommentController = &getController('comment'); + $success_count = 0; + $p_comment_srl = array(); + foreach($comments as $comment_obj) { + $comment_srl = getNextSequence(); + $p_comment_srl[$comment_obj->comment_srl] = $comment_srl; + + $comment_obj->module_srl = $obj->module_srl; + $comment_obj->document_srl = $obj->document_srl; + $comment_obj->comment_srl = $comment_srl; + + if($comment_obj->parent_srl) $comment_obj->parent_srl = $p_comment_srl[$comment_obj->parent_srl]; + + $output = $oCommentController->insertComment($comment_obj, true); + if($output->toBool()) $success_count ++; + } + $oDocumentController->updateCommentCount($obj->document_srl, $success_count, $comment_obj->nick_name, true); + + } + + } + + // 엮인글 이전 + if($oDocument->getTrackbackCount()) { + $oTrackbackModel = &getModel('trackback'); + $trackbacks = $oTrackbackModel->getTrackbackList($oDocument->document_srl); + if(count($trackbacks)) { + $success_count = 0; + foreach($trackbacks as $trackback_obj) { + $trackback_obj->trackback_srl = getNextSequence(); + $trackback_obj->module_srl = $obj->module_srl; + $trackback_obj->document_srl = $obj->document_srl; + $output = executeQuery('trackback.insertTrackback', $trackback_obj); + if($output->toBool()) $success_count++; + } + + // 엮인글 수 업데이트 + $oDocumentController->updateTrackbackCount($obj->document_srl, $success_count); + } + } + + $copied_srls[$document_srl] = $obj->document_srl; + } + $oDB->commit(); + + $output = new Object(); + $output->add('copied_srls', $copied_srls); + return $output; + } + + /** + * @brief 특정 모듈의 전체 문서 삭제 + **/ + function deleteModuleDocument($module_srl) { + $args->module_srl = $module_srl; + $output = executeQuery('document.deleteModuleDocument', $args); + return $output; + } + + /** + * @brief 문서 모듈의 기본설정 저장 + **/ + function procDocumentAdminInsertConfig() { + // 기본 정보를 받음 + $config = Context::gets('thumbnail_type'); + + // module Controller 객체 생성하여 입력 + $oModuleController = &getController('module'); + $output = $oModuleController->insertModuleConfig('document',$config); + return $output; + } + + /** + * @brief 선택된 글들에 대해 신고 취소 + **/ + function procDocumentAdminCancelDeclare() { + $document_srl = trim(Context::get('document_srl')); + + if($document_srl) { + $args->document_srl = $document_srl; + $output = executeQuery('document.deleteDeclaredDocuments', $args); + if(!$output->toBool()) return $output; + } + } + + /** + * @brief 모든 생성된 썸네일 삭제 + **/ + function procDocumentAdminDeleteAllThumbnail() { + + // files/attaches/images/ 디렉토리를 순환하면서 thumbnail_*.jpg 파일을 모두 삭제 (1.0.4 이전까지) + $this->deleteThumbnailFile('./files/attach/images'); + + // files/cache/thumbnails 디렉토리 자체를 삭제 (1.0.5 이후 변경된 썸네일 정책) + FileHandler::removeFilesInDir('./files/cache/thumbnails'); + + $this->setMessage('success_deleted'); + } + + function deleteThumbnailFile($path) { + $directory = dir($path); + while($entry = $directory->read()) { + if ($entry != "." && $entry != "..") { + if (is_dir($path."/".$entry)) { + $this->deleteThumbnailFile($path."/".$entry); + } else { + if(!preg_match('/^thumbnail_([^\.]*)\.jpg$/i',$entry)) continue; + FileHandler::removeFile($path.'/'.$entry); + } + } + } + $directory->close(); + } + + /** + * @brief 모듈의 확장 변수 추가 또는 수정 + **/ + function procDocumentAdminInsertExtraVar() { + $module_srl = Context::get('module_srl'); + $var_idx = Context::get('var_idx'); + $name = Context::get('name'); + $type = Context::get('type'); + $is_required = Context::get('is_required'); + $default = Context::get('default'); + $desc = Context::get('desc'); + $search = Context::get('search'); + $eid = Context::get('eid'); + + if(!$module_srl || !$name || !$eid) return new Object(-1,'msg_invalid_request'); + + // idx가 지정되어 있지 않으면 최고 값을 지정 + if(!$var_idx) { + $obj->module_srl = $module_srl; + $output = executeQuery('document.getDocumentMaxExtraKeyIdx', $obj); + $var_idx = $output->data->var_idx+1; + } + + // 이미 존재하는 모듈 이름인지 체크 + $obj->module_srl = $module_srl; + $obj->var_idx = $var_idx; + $obj->eid = $eid; + $output = executeQuery('document.isExistsExtraKey', $obj); + if(!$output->toBool() || $output->data->count) { + return new Object(-1, 'msg_extra_name_exists'); + } + + // insert or update + $oDocumentController = &getController('document'); + $output = $oDocumentController->insertDocumentExtraKey($module_srl, $var_idx, $name, $type, $is_required, $search, $default, $desc, $eid); + if(!$output->toBool()) return $output; + + $this->setMessage('success_registed'); + } + + /** + * @brief 모듈의 확장 변수 삭제 + **/ + function procDocumentAdminDeleteExtraVar() { + $module_srl = Context::get('module_srl'); + $var_idx = Context::get('var_idx'); + if(!$module_srl || !$var_idx) return new Object(-1,'msg_invalid_request'); + + $oDocumentController = &getController('document'); + $output = $oDocumentController->deleteDocumentExtraKeys($module_srl, $var_idx); + if(!$output->toBool()) return $output; + + $this->setMessage('success_deleted'); + } + + /** + * @brief 확장변수 순서 조절 + **/ + function procDocumentAdminMoveExtraVar() { + $type = Context::get('type'); + $module_srl = Context::get('module_srl'); + $var_idx = Context::get('var_idx'); + + if(!$type || !$module_srl || !$var_idx) return new Object(-1,'msg_invalid_request'); + + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + if(!$module_info->module_srl) return new Object(-1,'msg_invalid_request'); + + $oDocumentModel = &getModel('document'); + $extra_keys = $oDocumentModel->getExtraKeys($module_srl); + if(!$extra_keys[$var_idx]) return new Object(-1,'msg_invalid_request'); + + if($type == 'up') $new_idx = $var_idx-1; + else $new_idx = $var_idx+1; + if($new_idx<1) return new Object(-1,'msg_invalid_request'); + + // 바꿀 idx가 없으면 바로 업데이트 + if(!$extra_keys[$new_idx]) { + $args->module_srl = $module_srl; + $args->var_idx = $var_idx; + $args->new_idx = $new_idx; + $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); + if(!$output->toBool()) return $output; + $output = executeQuery('document.updateDocumentExtraVarIdx', $args); + if(!$output->toBool()) return $output; + // 있으면 기존의 꺼랑 교체 + } else { + $args->module_srl = $module_srl; + $args->var_idx = $new_idx; + $args->new_idx = -10000; + $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); + if(!$output->toBool()) return $output; + $output = executeQuery('document.updateDocumentExtraVarIdx', $args); + if(!$output->toBool()) return $output; + + $args->var_idx = $var_idx; + $args->new_idx = $new_idx; + $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); + if(!$output->toBool()) return $output; + $output = executeQuery('document.updateDocumentExtraVarIdx', $args); + if(!$output->toBool()) return $output; + + $args->var_idx = -10000; + $args->new_idx = $var_idx; + $output = executeQuery('document.updateDocumentExtraKeyIdx', $args); + if(!$output->toBool()) return $output; + $output = executeQuery('document.updateDocumentExtraVarIdx', $args); + if(!$output->toBool()) return $output; + } + } + + function procDocumentAdminInsertAlias() { + $args = Context::gets('module_srl','document_srl', 'alias_title'); + $alias_srl = Context::get('alias_srl'); + if(!$alias_srl) + { + $args->alias_srl = getNextSequence(); + $query = "document.insertAlias"; + } + else + { + $args->alias_srl = $alias_srl; + $query = "document.updateAlias"; + } + $output = executeQuery($query, $args); + if(!$output->toBool()) + { + return $output; + } + } + + function procDocumentAdminDeleteAlias() { + $alias_srl = Context::get('alias_srl'); + $args->alias_srl = $alias_srl; + $output = executeQuery("document.deleteAlias", $args); + if (!$output->toBool()) + { + return $output; + } + } + + function procDocumentAdminRestoreTrash() { + $trash_srl = Context::get('trash_srl'); + $this->restoreTrash($trash_srl); + } + + function restoreTrash($trash_srl){ + $oDB = &DB::getInstance(); + $oDocumentModel = &getModel('document'); + + $trash_args->trash_srl = $trash_srl; + + $output = executeQuery('document.getTrash', $trash_args); + if (!$output->toBool()) { + return $output; + } + + $document_args->document_srl = $output->data->document_srl; + $document_args->module_srl = $output->data->module_srl; + $document_args->member_srl = $output->data->member_srl; + + $oDocument = $oDocumentModel->getDocument($document_args->document_srl); + + // begin transaction + $oDB->begin(); + + $output = executeQuery('document.updateDocument', $document_args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + $output = executeQuery('document.deleteTrash', $trash_args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 임시 저장되었던 글이 아닌 경우, 등록된 첨부파일의 상태를 유효로 지정 + if($oDocument->hasUploadedFiles() && $document_args->member_srl != $document_args->module_srl) { + $args->upload_target_srl = $oDocument->document_srl; + $args->isvalid = 'Y'; + executeQuery('file.updateFileValid', $args); + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('document.restoreTrash', 'after', $document_args); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + return $output; + } + + } +?> diff --git a/modules/document/document.admin.model.php b/modules/document/document.admin.model.php index f7505f152..9a86e5799 100644 --- a/modules/document/document.admin.model.php +++ b/modules/document/document.admin.model.php @@ -1,87 +1,87 @@ -sort_index, array('list_order','delete_date','title'))) $obj->sort_index = 'list_order'; - if (!in_array($obj->order_type, array('desc','asc'))) $obj->order_type = 'asc'; - - // module_srl 대신 mid가 넘어왔을 경우는 직접 module_srl을 구해줌 - if ($obj->mid) { - $oModuleModel = &getModel('module'); - $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); - unset($obj->mid); - } - - // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 - if (is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); - else $args->module_srl = $obj->module_srl; - - // 변수 체크 - $args->sort_index = $obj->sort_index; - $args->order_type = $obj->order_type; - $args->page = $obj->page?$obj->page:1; - $args->list_count = $obj->list_count?$obj->list_count:20; - $args->page_count = $obj->page_count?$obj->page_count:10; - $args->member_srl = $obj->member_srl; - - // query_id 지정 - $query_id = 'document.getTrashList'; - - // query 실행 - $output = executeQueryArray($query_id, $args); - - // 결과가 없거나 오류 발생시 그냥 return - if (!$output->toBool() || !count($output->data)) return $output; - - $idx = 0; - $data = $output->data; - unset($output->data); - - $keys = array_keys($data); - $virtual_number = $keys[0]; - - foreach($data as $key => $attribute) { - $oDocument = null; - $oDocument = new documentItem(); - $oDocument->setAttribute($attribute, false); - if ($is_admin) $oDocument->setGrant(); - - $output->data[$virtual_number] = $oDocument; - $virtual_number--; - } - - return $output; - } - - /** - * @brief trash_srl값을 가지는 휴지통 문서를 가져옴 - **/ - function getDocumentTrash($trash_srl) { - $args->trash_srl = $trash_srl; - $output = executeQuery('document.getTrash', $args); - - $node = $output->data; - if (!$node) return; - - return $node; - } - - } -?> +sort_index, array('list_order','delete_date','title'))) $obj->sort_index = 'list_order'; + if (!in_array($obj->order_type, array('desc','asc'))) $obj->order_type = 'asc'; + + // module_srl 대신 mid가 넘어왔을 경우는 직접 module_srl을 구해줌 + if ($obj->mid) { + $oModuleModel = &getModel('module'); + $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); + unset($obj->mid); + } + + // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 + if (is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); + else $args->module_srl = $obj->module_srl; + + // 변수 체크 + $args->sort_index = $obj->sort_index; + $args->order_type = $obj->order_type; + $args->page = $obj->page?$obj->page:1; + $args->list_count = $obj->list_count?$obj->list_count:20; + $args->page_count = $obj->page_count?$obj->page_count:10; + $args->member_srl = $obj->member_srl; + + // query_id 지정 + $query_id = 'document.getTrashList'; + + // query 실행 + $output = executeQueryArray($query_id, $args); + + // 결과가 없거나 오류 발생시 그냥 return + if (!$output->toBool() || !count($output->data)) return $output; + + $idx = 0; + $data = $output->data; + unset($output->data); + + $keys = array_keys($data); + $virtual_number = $keys[0]; + + foreach($data as $key => $attribute) { + $oDocument = null; + $oDocument = new documentItem(); + $oDocument->setAttribute($attribute, false); + if ($is_admin) $oDocument->setGrant(); + + $output->data[$virtual_number] = $oDocument; + $virtual_number--; + } + + return $output; + } + + /** + * @brief trash_srl값을 가지는 휴지통 문서를 가져옴 + **/ + function getDocumentTrash($trash_srl) { + $args->trash_srl = $trash_srl; + $output = executeQuery('document.getTrash', $args); + + $node = $output->data; + if (!$node) return; + + return $node; + } + + } +?> diff --git a/modules/document/document.admin.view.php b/modules/document/document.admin.view.php index f9a2fbf28..7852f4951 100644 --- a/modules/document/document.admin.view.php +++ b/modules/document/document.admin.view.php @@ -1,159 +1,159 @@ -page = Context::get('page'); ///< 페이지 - $args->list_count = 30; ///< 한페이지에 보여줄 글 수 - $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 - - $args->search_target = Context::get('search_target'); ///< 검색 대상 (title, contents...) - $args->search_keyword = Context::get('search_keyword'); ///< 검색어 - - $args->sort_index = 'list_order'; ///< 소팅 값 - - $args->module_srl = Context::get('module_srl'); - - // 목록 구함, document->getDocumentList 에서 걍 알아서 다 해버리는 구조이다... (아.. 이거 나쁜 버릇인데.. ㅡ.ㅜ 어쩔수 없다) - $oDocumentModel = &getModel('document'); - $output = $oDocumentModel->getDocumentList($args); - - // 템플릿에 쓰기 위해서 document_model::getDocumentList() 의 return object에 있는 값들을 세팅 - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('document_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - // 템플릿에서 사용할 검색옵션 세팅 - $count_search_option = count($this->search_option); - for($i=0;$i<$count_search_option;$i++) { - $search_option[$this->search_option[$i]] = Context::getLang($this->search_option[$i]); - } - Context::set('search_option', $search_option); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('document_list'); - } - - /** - * @brief 문서 모듈 설정 - **/ - function dispDocumentAdminConfig() { - $oDocumentModel = &getModel('document'); - $config = $oDocumentModel->getDocumentConfig(); - Context::set('config',$config); - - // 템플릿 파일 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('document_config'); - } - - /** - * @brief 관리자 페이지의 신고 목록 보기 - **/ - function dispDocumentAdminDeclared() { - // 목록을 구하기 위한 옵션 - $args->page = Context::get('page'); ///< 페이지 - $args->list_count = 30; ///< 한페이지에 보여줄 글 수 - $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 - - $args->sort_index = 'document_declared.declared_count'; ///< 소팅 값 - $args->order_type = 'desc'; ///< 소팅 정렬 값 - - // 목록을 구함 - $declared_output = executeQuery('document.getDeclaredList', $args); - - if($declared_output->data && count($declared_output->data)) { - $document_list = array(); - - $oDocumentModel = &getModel('document'); - foreach($declared_output->data as $key => $document) { - $document_list[$key] = new documentItem(); - $document_list[$key]->setAttribute($document); - } - $declared_output->data = $document_list; - } - - // 템플릿에 쓰기 위해서 document_model::getDocumentList() 의 return object에 있는 값들을 세팅 - Context::set('total_count', $declared_output->total_count); - Context::set('total_page', $declared_output->total_page); - Context::set('page', $declared_output->page); - Context::set('document_list', $declared_output->data); - Context::set('page_navigation', $declared_output->page_navigation); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('declared_list'); - } - - function dispDocumentAdminAlias() { - $args->document_srl = Context::get('document_srl'); - if(!$args->document_srl) return $this->dispDocumentAdminList(); - - $oModel = &getModel('document'); - $oDocument = $oModel->getDocument($args->document_srl); - if(!$oDocument->isExists()) return $this->dispDocumentAdminList(); - Context::set('oDocument', $oDocument); - - $output = executeQueryArray('document.getAliases', $args); - if(!$output->data) - { - $aliases = array(); - } - else - { - $aliases = $output->data; - } - - - Context::set('aliases', $aliases); - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('document_alias'); - } - - function dispDocumentAdminTrashList() { - // 목록을 구하기 위한 옵션 - $args->page = Context::get('page'); ///< 페이지 - $args->list_count = 30; ///< 한페이지에 보여줄 글 수 - $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 - - $args->sort_index = 'list_order'; ///< 소팅 값 - $args->order_type = 'desc'; ///< 소팅 정렬 값 - - $args->module_srl = Context::get('module_srl'); - - // 목록을 구함 - $oDocumentAdminModel = &getAdminModel('document'); - $output = $oDocumentAdminModel->getDocumentTrashList($args); - - // 템플릿에 쓰기 위해서 document_admin_model::getDocumentTrashList() 의 return object에 있는 값들을 세팅 - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('document_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('document_trash_list'); - } - } -?> +page = Context::get('page'); ///< 페이지 + $args->list_count = 30; ///< 한페이지에 보여줄 글 수 + $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 + + $args->search_target = Context::get('search_target'); ///< 검색 대상 (title, contents...) + $args->search_keyword = Context::get('search_keyword'); ///< 검색어 + + $args->sort_index = 'list_order'; ///< 소팅 값 + + $args->module_srl = Context::get('module_srl'); + + // 목록 구함, document->getDocumentList 에서 걍 알아서 다 해버리는 구조이다... (아.. 이거 나쁜 버릇인데.. ㅡ.ㅜ 어쩔수 없다) + $oDocumentModel = &getModel('document'); + $output = $oDocumentModel->getDocumentList($args); + + // 템플릿에 쓰기 위해서 document_model::getDocumentList() 의 return object에 있는 값들을 세팅 + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('document_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + // 템플릿에서 사용할 검색옵션 세팅 + $count_search_option = count($this->search_option); + for($i=0;$i<$count_search_option;$i++) { + $search_option[$this->search_option[$i]] = Context::getLang($this->search_option[$i]); + } + Context::set('search_option', $search_option); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('document_list'); + } + + /** + * @brief 문서 모듈 설정 + **/ + function dispDocumentAdminConfig() { + $oDocumentModel = &getModel('document'); + $config = $oDocumentModel->getDocumentConfig(); + Context::set('config',$config); + + // 템플릿 파일 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('document_config'); + } + + /** + * @brief 관리자 페이지의 신고 목록 보기 + **/ + function dispDocumentAdminDeclared() { + // 목록을 구하기 위한 옵션 + $args->page = Context::get('page'); ///< 페이지 + $args->list_count = 30; ///< 한페이지에 보여줄 글 수 + $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 + + $args->sort_index = 'document_declared.declared_count'; ///< 소팅 값 + $args->order_type = 'desc'; ///< 소팅 정렬 값 + + // 목록을 구함 + $declared_output = executeQuery('document.getDeclaredList', $args); + + if($declared_output->data && count($declared_output->data)) { + $document_list = array(); + + $oDocumentModel = &getModel('document'); + foreach($declared_output->data as $key => $document) { + $document_list[$key] = new documentItem(); + $document_list[$key]->setAttribute($document); + } + $declared_output->data = $document_list; + } + + // 템플릿에 쓰기 위해서 document_model::getDocumentList() 의 return object에 있는 값들을 세팅 + Context::set('total_count', $declared_output->total_count); + Context::set('total_page', $declared_output->total_page); + Context::set('page', $declared_output->page); + Context::set('document_list', $declared_output->data); + Context::set('page_navigation', $declared_output->page_navigation); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('declared_list'); + } + + function dispDocumentAdminAlias() { + $args->document_srl = Context::get('document_srl'); + if(!$args->document_srl) return $this->dispDocumentAdminList(); + + $oModel = &getModel('document'); + $oDocument = $oModel->getDocument($args->document_srl); + if(!$oDocument->isExists()) return $this->dispDocumentAdminList(); + Context::set('oDocument', $oDocument); + + $output = executeQueryArray('document.getAliases', $args); + if(!$output->data) + { + $aliases = array(); + } + else + { + $aliases = $output->data; + } + + + Context::set('aliases', $aliases); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('document_alias'); + } + + function dispDocumentAdminTrashList() { + // 목록을 구하기 위한 옵션 + $args->page = Context::get('page'); ///< 페이지 + $args->list_count = 30; ///< 한페이지에 보여줄 글 수 + $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 + + $args->sort_index = 'list_order'; ///< 소팅 값 + $args->order_type = 'desc'; ///< 소팅 정렬 값 + + $args->module_srl = Context::get('module_srl'); + + // 목록을 구함 + $oDocumentAdminModel = &getAdminModel('document'); + $output = $oDocumentAdminModel->getDocumentTrashList($args); + + // 템플릿에 쓰기 위해서 document_admin_model::getDocumentTrashList() 의 return object에 있는 값들을 세팅 + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('document_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('document_trash_list'); + } + } +?> diff --git a/modules/document/document.class.php b/modules/document/document.class.php index 08c813223..23ccdda76 100644 --- a/modules/document/document.class.php +++ b/modules/document/document.class.php @@ -1,254 +1,254 @@ -addIndex("documents","idx_module_list_order", array("module_srl","list_order")); - $oDB->addIndex("documents","idx_module_update_order", array("module_srl","update_order")); - $oDB->addIndex("documents","idx_module_readed_count", array("module_srl","readed_count")); - $oDB->addIndex("documents","idx_module_voted_count", array("module_srl","voted_count")); - $oDB->addIndex("documents","idx_module_notice", array("module_srl","is_notice")); - $oDB->addIndex("documents","idx_module_document_srl", array("module_srl","document_srl")); - $oDB->addIndex("documents","idx_module_blamed_count", array("module_srl","blamed_count")); - $oDB->addIndex("document_aliases", "idx_module_title", array("module_srl","alias_title"), true); - $oDB->addIndex("document_extra_vars", "unique_extra_vars", array("module_srl","document_srl","var_idx","lang_code"), true); - - // 2007. 10. 17 모듈이 삭제될때 등록된 글도 모두 삭제하는 트리거 추가 - $oModuleController->insertTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after'); - - // 2009. 01. 29 Added a trigger for additional setup - $oModuleController->insertTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before'); - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - - /** - * 2007. 7. 25 : 알림 필드(notify_message) 추가 - **/ - if(!$oDB->isColumnExists("documents","notify_message")) return true; - - /** - * 2007. 8. 23 : document테이블에 결합 인덱스 적용 - **/ - if(!$oDB->isIndexExists("documents","idx_module_list_order")) return true; - if(!$oDB->isIndexExists("documents","idx_module_update_order")) return true; - if(!$oDB->isIndexExists("documents","idx_module_readed_count")) return true; - if(!$oDB->isIndexExists("documents","idx_module_voted_count")) return true; - - // 2007. 10. 17 모듈이 삭제될때 등록된 글도 모두 삭제하는 트리거 추가 - if(!$oModuleModel->getTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after')) return true; - - // 2007. 10. 25 문서 분류에 parent_srl, expand를 추가 - if(!$oDB->isColumnExists("document_categories","parent_srl")) return true; - if(!$oDB->isColumnExists("document_categories","expand")) return true; - if(!$oDB->isColumnExists("document_categories","group_srls")) return true; - - // 2007. 11. 20 게시글에 module_srl + is_notice 복합인덱스 만들기 - if(!$oDB->isIndexExists("documents","idx_module_notice")) return true; - - // 2008. 02. 18 게시글에 module_srl + document_srl 복합인덱스 만들기 (manian님 확인) - if(!$oDB->isIndexExists("documents","idx_module_document_srl")) return true; - - /** - * 2007. 12. 03 : 확장변수(extra_vars) 컬럼이 없을 경우 추가 - **/ - if(!$oDB->isColumnExists("documents","extra_vars")) return true; - - // 2008. 04. 23 blamed count 컬럼 추가 - if(!$oDB->isColumnExists("documents", "blamed_count")) return true; - if(!$oDB->isIndexExists("documents","idx_module_blamed_count")) return true; - if(!$oDB->isColumnExists("document_voted_log", "point")) return true; - - // 2008-12-15 문서 분류에 color를 추가 - if(!$oDB->isColumnExists("document_categories", "color")) return true; - - /** - * 2009. 01. 29 : 확장변수 값 테이블에 lang_code가 없을 경우 추가 - **/ - if(!$oDB->isColumnExists("document_extra_vars","lang_code")) return true; - - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before')) return true; - - // 2009. 03. 09 documents에 lang_code 컬럼 추가 - if(!$oDB->isColumnExists("documents","lang_code")) return true; - - // 2009. 03. 11 확장변수 값 테이블의 인덱스 점검 - if(!$oDB->isIndexExists("document_extra_vars", "unique_extra_vars")) return true; - - /** - * 2009. 03. 19 : 확장변수 값 테이블에 eid가 없을 경우 추가 - **/ - if(!$oDB->isColumnExists("document_extra_keys","eid")) return true; - if(!$oDB->isColumnExists("document_extra_vars","eid")) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - - /** - * 2007. 7. 25 : 알림 필드(notify_message) 추가 - **/ - if(!$oDB->isColumnExists("documents","notify_message")) { - $oDB->addColumn('documents',"notify_message","char",1); - } - - /** - * 2007. 8. 23 : document테이블에 결합 인덱스 적용 - **/ - if(!$oDB->isIndexExists("documents","idx_module_list_order")) { - $oDB->addIndex("documents","idx_module_list_order", array("module_srl","list_order")); - } - - if(!$oDB->isIndexExists("documents","idx_module_update_order")) { - $oDB->addIndex("documents","idx_module_update_order", array("module_srl","update_order")); - } - - if(!$oDB->isIndexExists("documents","idx_module_readed_count")) { - $oDB->addIndex("documents","idx_module_readed_count", array("module_srl","readed_count")); - } - - if(!$oDB->isIndexExists("documents","idx_module_voted_count")) { - $oDB->addIndex("documents","idx_module_voted_count", array("module_srl","voted_count")); - } - - // 2007. 10. 17 모듈이 삭제될때 등록된 글도 모두 삭제하는 트리거 추가 - if(!$oModuleModel->getTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after')) - $oModuleController->insertTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after'); - - // 2007. 10. 25 문서 분류에 parent_srl, expand를 추가 - if(!$oDB->isColumnExists("document_categories","parent_srl")) $oDB->addColumn('document_categories',"parent_srl","number",12,0); - if(!$oDB->isColumnExists("document_categories","expand")) $oDB->addColumn('document_categories',"expand","char",1,"N"); - if(!$oDB->isColumnExists("document_categories","group_srls")) $oDB->addColumn('document_categories',"group_srls","text"); - - // 2007. 11. 20 게시글에 module_srl + is_notice 복합인덱스 만들기 - if(!$oDB->isIndexExists("documents","idx_module_notice")) $oDB->addIndex("documents","idx_module_notice", array("module_srl","is_notice")); - - /** - * 2007. 12. 03 : 확장변수(extra_vars) 컬럼이 없을 경우 추가 - **/ - if(!$oDB->isColumnExists("documents","extra_vars")) $oDB->addColumn('documents','extra_vars','text'); - - /** - * 2008. 02. 18 게시글에 module_srl + document_srl 복합인덱스 만들기 (manian님 확인) - **/ - if(!$oDB->isIndexExists("documents","idx_module_document_srl")) $oDB->addIndex("documents","idx_module_document_srl", array("module_srl","document_srl")); - - // 2008. 04. 23 blamed count 컬럼 추가 - if(!$oDB->isColumnExists("documents", "blamed_count")) { - $oDB->addColumn('documents', 'blamed_count', 'number', 11, 0, true); - $oDB->addIndex('documents', 'idx_blamed_count', array('blamed_count')); - } - - if(!$oDB->isIndexExists("documents","idx_module_blamed_count")) { - $oDB->addIndex('documents', 'idx_module_blamed_count', array('module_srl', 'blamed_count')); - } - - if(!$oDB->isColumnExists("document_voted_log", "point")) - $oDB->addColumn('document_voted_log', 'point', 'number', 11, 0, true); - - - if(!$oDB->isColumnExists("document_categories","color")) $oDB->addColumn('document_categories',"color","char",7); - - /** - * 2009. 01. 29 : 확장변수 값 테이블에 lang_code가 없을 경우 추가 - **/ - if(!$oDB->isColumnExists("document_extra_vars","lang_code")) $oDB->addColumn('document_extra_vars',"lang_code","varchar",10); - - // 2009. 01. 29 Added a trigger for additional setup - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before')) - $oModuleController->insertTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before'); - - // 2009. 03. 09 documents에 lang_code 컬럼 추가 - if(!$oDB->isColumnExists("documents","lang_code")) { - $db_info = Context::getDBInfo(); - $oDB->addColumn('documents',"lang_code","varchar",10, $db_info->lang_code); - $obj->lang_code = $db_info->lang_type; - executeQuery('document.updateDocumentsLangCode', $obj); - } - - // 2009. 03. 11 확장변수 값 테이블의 인덱스 점검 - if(!$oDB->isIndexExists("document_extra_vars", "unique_extra_vars")) { - $oDB->addIndex("document_extra_vars", "unique_extra_vars", array("module_srl","document_srl","var_idx","lang_code"), true); - } - - if($oDB->isIndexExists("document_extra_vars", "unique_module_vars")) { - $oDB->dropIndex("document_extra_vars", "unique_module_vars", true); - } - - /** - * 2009. 03. 19 : 확장변수 값 테이블에 eid 없을 경우 추가 - * 2009. 04. 12 : eid를 등록할 때 다른 필드 값이 변경되는 문제 수정 #17922959 - **/ - if(!$oDB->isColumnExists("document_extra_keys","eid")) { - $oDB->addColumn("document_extra_keys","eid","varchar",40); - - $output = executeQuery('document.getGroupsExtraKeys', $obj); - if($output->toBool() && $output->data && count($output->data)) { - foreach($output->data as $extra_keys) { - $args->module_srl = $extra_keys->module_srl; - $args->var_idx = $extra_keys->idx; - $args->new_eid = "extra_vars".$extra_keys->idx; - $output = executeQuery('document.updateDocumentExtraKeyEid', $args); - } - } - } - - if(!$oDB->isColumnExists("document_extra_vars","eid")) { - $oDB->addColumn("document_extra_vars","eid","varchar",40); - $obj->var_idx = '-1,-2'; - $output = executeQuery('document.getGroupsExtraVars', $obj); - if($output->toBool() && $output->data && count($output->data)) { - foreach($output->data as $extra_vars) { - $args->module_srl = $extra_vars->module_srl; - $args->var_idx = $extra_vars->idx; - $args->new_eid = "extra_vars".$extra_vars->idx; - $output = executeQuery('document.updateDocumentExtraVarEid', $args); - } - } - } - - return new Object(0,'success_updated'); - - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - // 게시글 분류 캐시 파일 삭제 - FileHandler::removeFilesInDir(_XE_PATH_."files/cache/document_category"); - } - - } -?> +addIndex("documents","idx_module_list_order", array("module_srl","list_order")); + $oDB->addIndex("documents","idx_module_update_order", array("module_srl","update_order")); + $oDB->addIndex("documents","idx_module_readed_count", array("module_srl","readed_count")); + $oDB->addIndex("documents","idx_module_voted_count", array("module_srl","voted_count")); + $oDB->addIndex("documents","idx_module_notice", array("module_srl","is_notice")); + $oDB->addIndex("documents","idx_module_document_srl", array("module_srl","document_srl")); + $oDB->addIndex("documents","idx_module_blamed_count", array("module_srl","blamed_count")); + $oDB->addIndex("document_aliases", "idx_module_title", array("module_srl","alias_title"), true); + $oDB->addIndex("document_extra_vars", "unique_extra_vars", array("module_srl","document_srl","var_idx","lang_code"), true); + + // 2007. 10. 17 모듈이 삭제될때 등록된 글도 모두 삭제하는 트리거 추가 + $oModuleController->insertTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after'); + + // 2009. 01. 29 Added a trigger for additional setup + $oModuleController->insertTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before'); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + + /** + * 2007. 7. 25 : 알림 필드(notify_message) 추가 + **/ + if(!$oDB->isColumnExists("documents","notify_message")) return true; + + /** + * 2007. 8. 23 : document테이블에 결합 인덱스 적용 + **/ + if(!$oDB->isIndexExists("documents","idx_module_list_order")) return true; + if(!$oDB->isIndexExists("documents","idx_module_update_order")) return true; + if(!$oDB->isIndexExists("documents","idx_module_readed_count")) return true; + if(!$oDB->isIndexExists("documents","idx_module_voted_count")) return true; + + // 2007. 10. 17 모듈이 삭제될때 등록된 글도 모두 삭제하는 트리거 추가 + if(!$oModuleModel->getTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after')) return true; + + // 2007. 10. 25 문서 분류에 parent_srl, expand를 추가 + if(!$oDB->isColumnExists("document_categories","parent_srl")) return true; + if(!$oDB->isColumnExists("document_categories","expand")) return true; + if(!$oDB->isColumnExists("document_categories","group_srls")) return true; + + // 2007. 11. 20 게시글에 module_srl + is_notice 복합인덱스 만들기 + if(!$oDB->isIndexExists("documents","idx_module_notice")) return true; + + // 2008. 02. 18 게시글에 module_srl + document_srl 복합인덱스 만들기 (manian님 확인) + if(!$oDB->isIndexExists("documents","idx_module_document_srl")) return true; + + /** + * 2007. 12. 03 : 확장변수(extra_vars) 컬럼이 없을 경우 추가 + **/ + if(!$oDB->isColumnExists("documents","extra_vars")) return true; + + // 2008. 04. 23 blamed count 컬럼 추가 + if(!$oDB->isColumnExists("documents", "blamed_count")) return true; + if(!$oDB->isIndexExists("documents","idx_module_blamed_count")) return true; + if(!$oDB->isColumnExists("document_voted_log", "point")) return true; + + // 2008-12-15 문서 분류에 color를 추가 + if(!$oDB->isColumnExists("document_categories", "color")) return true; + + /** + * 2009. 01. 29 : 확장변수 값 테이블에 lang_code가 없을 경우 추가 + **/ + if(!$oDB->isColumnExists("document_extra_vars","lang_code")) return true; + + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before')) return true; + + // 2009. 03. 09 documents에 lang_code 컬럼 추가 + if(!$oDB->isColumnExists("documents","lang_code")) return true; + + // 2009. 03. 11 확장변수 값 테이블의 인덱스 점검 + if(!$oDB->isIndexExists("document_extra_vars", "unique_extra_vars")) return true; + + /** + * 2009. 03. 19 : 확장변수 값 테이블에 eid가 없을 경우 추가 + **/ + if(!$oDB->isColumnExists("document_extra_keys","eid")) return true; + if(!$oDB->isColumnExists("document_extra_vars","eid")) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + + /** + * 2007. 7. 25 : 알림 필드(notify_message) 추가 + **/ + if(!$oDB->isColumnExists("documents","notify_message")) { + $oDB->addColumn('documents',"notify_message","char",1); + } + + /** + * 2007. 8. 23 : document테이블에 결합 인덱스 적용 + **/ + if(!$oDB->isIndexExists("documents","idx_module_list_order")) { + $oDB->addIndex("documents","idx_module_list_order", array("module_srl","list_order")); + } + + if(!$oDB->isIndexExists("documents","idx_module_update_order")) { + $oDB->addIndex("documents","idx_module_update_order", array("module_srl","update_order")); + } + + if(!$oDB->isIndexExists("documents","idx_module_readed_count")) { + $oDB->addIndex("documents","idx_module_readed_count", array("module_srl","readed_count")); + } + + if(!$oDB->isIndexExists("documents","idx_module_voted_count")) { + $oDB->addIndex("documents","idx_module_voted_count", array("module_srl","voted_count")); + } + + // 2007. 10. 17 모듈이 삭제될때 등록된 글도 모두 삭제하는 트리거 추가 + if(!$oModuleModel->getTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after')) + $oModuleController->insertTrigger('module.deleteModule', 'document', 'controller', 'triggerDeleteModuleDocuments', 'after'); + + // 2007. 10. 25 문서 분류에 parent_srl, expand를 추가 + if(!$oDB->isColumnExists("document_categories","parent_srl")) $oDB->addColumn('document_categories',"parent_srl","number",12,0); + if(!$oDB->isColumnExists("document_categories","expand")) $oDB->addColumn('document_categories',"expand","char",1,"N"); + if(!$oDB->isColumnExists("document_categories","group_srls")) $oDB->addColumn('document_categories',"group_srls","text"); + + // 2007. 11. 20 게시글에 module_srl + is_notice 복합인덱스 만들기 + if(!$oDB->isIndexExists("documents","idx_module_notice")) $oDB->addIndex("documents","idx_module_notice", array("module_srl","is_notice")); + + /** + * 2007. 12. 03 : 확장변수(extra_vars) 컬럼이 없을 경우 추가 + **/ + if(!$oDB->isColumnExists("documents","extra_vars")) $oDB->addColumn('documents','extra_vars','text'); + + /** + * 2008. 02. 18 게시글에 module_srl + document_srl 복합인덱스 만들기 (manian님 확인) + **/ + if(!$oDB->isIndexExists("documents","idx_module_document_srl")) $oDB->addIndex("documents","idx_module_document_srl", array("module_srl","document_srl")); + + // 2008. 04. 23 blamed count 컬럼 추가 + if(!$oDB->isColumnExists("documents", "blamed_count")) { + $oDB->addColumn('documents', 'blamed_count', 'number', 11, 0, true); + $oDB->addIndex('documents', 'idx_blamed_count', array('blamed_count')); + } + + if(!$oDB->isIndexExists("documents","idx_module_blamed_count")) { + $oDB->addIndex('documents', 'idx_module_blamed_count', array('module_srl', 'blamed_count')); + } + + if(!$oDB->isColumnExists("document_voted_log", "point")) + $oDB->addColumn('document_voted_log', 'point', 'number', 11, 0, true); + + + if(!$oDB->isColumnExists("document_categories","color")) $oDB->addColumn('document_categories',"color","char",7); + + /** + * 2009. 01. 29 : 확장변수 값 테이블에 lang_code가 없을 경우 추가 + **/ + if(!$oDB->isColumnExists("document_extra_vars","lang_code")) $oDB->addColumn('document_extra_vars',"lang_code","varchar",10); + + // 2009. 01. 29 Added a trigger for additional setup + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before')) + $oModuleController->insertTrigger('module.dispAdditionSetup', 'document', 'view', 'triggerDispDocumentAdditionSetup', 'before'); + + // 2009. 03. 09 documents에 lang_code 컬럼 추가 + if(!$oDB->isColumnExists("documents","lang_code")) { + $db_info = Context::getDBInfo(); + $oDB->addColumn('documents',"lang_code","varchar",10, $db_info->lang_code); + $obj->lang_code = $db_info->lang_type; + executeQuery('document.updateDocumentsLangCode', $obj); + } + + // 2009. 03. 11 확장변수 값 테이블의 인덱스 점검 + if(!$oDB->isIndexExists("document_extra_vars", "unique_extra_vars")) { + $oDB->addIndex("document_extra_vars", "unique_extra_vars", array("module_srl","document_srl","var_idx","lang_code"), true); + } + + if($oDB->isIndexExists("document_extra_vars", "unique_module_vars")) { + $oDB->dropIndex("document_extra_vars", "unique_module_vars", true); + } + + /** + * 2009. 03. 19 : 확장변수 값 테이블에 eid 없을 경우 추가 + * 2009. 04. 12 : eid를 등록할 때 다른 필드 값이 변경되는 문제 수정 #17922959 + **/ + if(!$oDB->isColumnExists("document_extra_keys","eid")) { + $oDB->addColumn("document_extra_keys","eid","varchar",40); + + $output = executeQuery('document.getGroupsExtraKeys', $obj); + if($output->toBool() && $output->data && count($output->data)) { + foreach($output->data as $extra_keys) { + $args->module_srl = $extra_keys->module_srl; + $args->var_idx = $extra_keys->idx; + $args->new_eid = "extra_vars".$extra_keys->idx; + $output = executeQuery('document.updateDocumentExtraKeyEid', $args); + } + } + } + + if(!$oDB->isColumnExists("document_extra_vars","eid")) { + $oDB->addColumn("document_extra_vars","eid","varchar",40); + $obj->var_idx = '-1,-2'; + $output = executeQuery('document.getGroupsExtraVars', $obj); + if($output->toBool() && $output->data && count($output->data)) { + foreach($output->data as $extra_vars) { + $args->module_srl = $extra_vars->module_srl; + $args->var_idx = $extra_vars->idx; + $args->new_eid = "extra_vars".$extra_vars->idx; + $output = executeQuery('document.updateDocumentExtraVarEid', $args); + } + } + } + + return new Object(0,'success_updated'); + + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + // 게시글 분류 캐시 파일 삭제 + FileHandler::removeFilesInDir(_XE_PATH_."files/cache/document_category"); + } + + } +?> diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 947b5e88f..a5ba31ac8 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -1,1650 +1,1650 @@ -updateVotedCount($document_srl, $point); - } - - function insertAlias($module_srl, $document_srl, $alias_title) { - $args->alias_srl = getNextSequence(); - $args->module_srl = $module_srl; - $args->document_srl = $document_srl; - $args->alias_title = urldecode($alias_title); - $query = "document.insertAlias"; - $output = executeQuery($query, $args); - return $output; - } - - /** - * @breif 게시글의 추천을 처리하는 action (Down) - **/ - function procDocumentVoteDown() { - if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); - - $document_srl = Context::get('target_srl'); - if(!$document_srl) return new Object(-1, 'msg_invalid_request'); - - $point = -1; - return $this->updateVotedCount($document_srl, $point); - } - - /** - * @brief 게시글이 신고될 경우 호출되는 action - **/ - function procDocumentDeclare() { - if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); - - $document_srl = Context::get('target_srl'); - if(!$document_srl) return new Object(-1, 'msg_invalid_request'); - - return $this->declaredDocument($document_srl); - } - - function deleteDocumentAliasByModule($module_srl) - { - $args->module_srl = $module_srl; - executeQuery("document.deleteAlias", $args); - } - - function deleteDocumentAliasByDocument($document_srl) - { - $args->document_srl = $document_srl; - executeQuery("document.deleteAlias", $args); - } - - function deleteDocumentHistory($history_srl, $document_srl, $module_srl) - { - $args->history_srl = $history_srl; - $args->module_srl = $module_srl; - $args->document_srl = $document_srl; - if(!$args->history_srl && !$args->module_srl && !$args->document_srl) return; - executeQuery("document.deleteHistory", $args); - } - - /** - * @brief 모듈이 삭제될때 등록된 모든 글을 삭제하는 trigger - **/ - function triggerDeleteModuleDocuments(&$obj) { - $module_srl = $obj->module_srl; - if(!$module_srl) return new Object(); - - // document 삭제 - $oDocumentAdminController = &getAdminController('document'); - $output = $oDocumentAdminController->deleteModuleDocument($module_srl); - if(!$output->toBool()) return $output; - - // category 삭제 - $oDocumentController = &getController('document'); - $output = $oDocumentController->deleteModuleCategory($module_srl); - if(!$output->toBool()) return $output; - - // 확장변수 삭제 - $this->deleteDocumentExtraVars($module_srl); - - // remove aliases - $this->deleteDocumentAliasByModule($module_srl); - - // remove histories - $this->deleteDocumentHistory(null, null, $module_srl); - - return new Object(); - } - - /** - * @brief 문서의 권한 부여 - * 세션값으로 현 접속상태에서만 사용 가능 - **/ - function addGrant($document_srl) { - $_SESSION['own_document'][$document_srl] = true; - } - - /** - * @brief 문서 입력 - **/ - function insertDocument($obj, $manual_inserted = false) { - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 기본 변수들 정리 - if($obj->is_secret!='Y') $obj->is_secret = 'N'; - if($obj->allow_comment!='Y') $obj->allow_comment = 'N'; - if($obj->lock_comment!='Y') $obj->lock_comment = 'N'; - if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; - if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - if($obj->notify_message != 'Y') $obj->notify_message = 'N'; - - // $extra_vars를 serialize - $obj->extra_vars = serialize($obj->extra_vars); - - // 자동저장용 필드 제거 - unset($obj->_saved_doc_srl); - unset($obj->_saved_doc_title); - unset($obj->_saved_doc_content); - unset($obj->_saved_doc_message); - - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('document.insertDocument', 'before', $obj); - if(!$output->toBool()) return $output; - - // 주어진 문서 번호가 없으면 문서 번호 등록 - if(!$obj->document_srl) $obj->document_srl = getNextSequence(); - - $oDocumentModel = &getModel('document'); - - // 카테고리가 있나 검사하여 없는 카테고리면 0으로 세팅 - if($obj->category_srl) { - $category_list = $oDocumentModel->getCategoryList($obj->module_srl); - if(!$category_list[$obj->category_srl]) $obj->category_srl = 0; - } - - // 조회수, 등록순서 설정 - if(!$obj->readed_count) $obj->readed_count = 0; - $obj->update_order = $obj->list_order = getNextSequence() * -1; - - // 수동입력을 대비해서 비밀번호의 hash상태를 점검, 수동입력이 아니면 무조건 md5 hash - if($obj->password && !$obj->password_is_hashed) $obj->password = md5($obj->password); - - // 수동 등록이 아니고 로그인 된 회원일 경우 회원의 정보를 입력 - if(Context::get('is_logged')&&!$manual_inserted) { - $logged_info = Context::get('logged_info'); - $obj->member_srl = $logged_info->member_srl; - $obj->user_id = $logged_info->user_id; - $obj->user_name = $logged_info->user_name; - $obj->nick_name = $logged_info->nick_name; - $obj->email_address = $logged_info->email_address; - $obj->homepage = $logged_info->homepage; - } - - // 제목이 없으면 내용에서 추출 - settype($obj->title, "string"); - if($obj->title == '') $obj->title = cut_str(strip_tags($obj->content),20,'...'); - //그래도 없으면 Untitled - if($obj->title == '') $obj->title = 'Untitled'; - - // 내용에서 XE만의 태그를 삭제 - $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); - if(Mobile::isFromMobilePhone()) - { - $obj->content = nl2br(htmlspecialchars($obj->content)); - } - - // 세션에서 최고 관리자가 아니면 iframe, script 제거 - if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); - - // 로그인정보가 없고 사용자 이름이 없으면 오류 표시 - if(!$logged_info->member_srl && !$obj->nick_name) return new Object(-1,'msg_invalid_request'); - - $obj->lang_code = Context::getLangType(); - - // DB에 입력 - $output = executeQuery('document.insertDocument', $obj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 등록 성공시 확장 변수 등록 - $extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl); - if(count($extra_keys)) { - foreach($extra_keys as $idx => $extra_item) { - $value = ''; - if(isset($obj->{'extra_vars'.$idx})) $value = trim($obj->{'extra_vars'.$idx}); - elseif(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); - if(!isset($value)) continue; - $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); - } - } - - // 성공하였을 경우 category_srl이 있으면 카테고리 update - if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl); - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('document.insertDocument', 'after', $obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - // return - $this->addGrant($obj->document_srl); - $output->add('document_srl',$obj->document_srl); - $output->add('category_srl',$obj->category_srl); - return $output; - } - - /** - * @brief 문서 수정 - **/ - function updateDocument($source_obj, $obj) { - if(!$source_obj->document_srl || !$obj->document_srl) return new Object(-1,'msg_invalied_request'); - - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('document.updateDocument', 'before', $obj); - if(!$output->toBool()) return $output; - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - $oModuleModel = &getModel('module'); - if(!$obj->module_srl) $obj->module_srl = $source_obj->get('module_srl'); - $module_srl = $obj->module_srl; - $document_config = $oModuleModel->getModulePartConfig('document', $module_srl); - if(!isset($document_config->use_history)) $document_config->use_history = 'N'; - $bUseHistory = $document_config->use_history == 'Y' || $document_config->use_history == 'Trace'; - - if($bUseHistory) { - $args->history_srl = getNextSequence(); - $args->document_srl = $obj->document_srl; - $args->module_srl = $module_srl; - if($document_config->use_history == 'Y') $args->content = $source_obj->get('content'); - $args->nick_name = $source_obj->get('nick_name'); - $args->member_srl = $source_obj->get('member_srl'); - $args->regdate = $source_obj->get('last_update'); - $args->ipaddress = $source_obj->get('ipaddress'); - $output = executeQuery("document.insertHistory", $args); - } - else - { - $obj->ipaddress = $source_obj->get('ipaddress'); - } - - // 기본 변수들 정리 - if($obj->is_secret!='Y') $obj->is_secret = 'N'; - if($obj->allow_comment!='Y') $obj->allow_comment = 'N'; - if($obj->lock_comment!='Y') $obj->lock_comment = 'N'; - if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; - if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - if($obj->notify_message != 'Y') $obj->notify_message = 'N'; - - // $extra_vars를 serialize - $obj->extra_vars = serialize($obj->extra_vars); - - // 자동저장용 필드 제거 - unset($obj->_saved_doc_srl); - unset($obj->_saved_doc_title); - unset($obj->_saved_doc_content); - unset($obj->_saved_doc_message); - - $oDocumentModel = &getModel('document'); - - // 카테고리가 변경되었으면 검사후 없는 카테고리면 0으로 세팅 - if($source_obj->get('category_srl')!=$obj->category_srl) { - $category_list = $oDocumentModel->getCategoryList($obj->module_srl); - if(!$category_list[$obj->category_srl]) $obj->category_srl = 0; - } - - // 수정 순서를 조절 - $obj->update_order = getNextSequence() * -1; - - // 비밀번호가 있으면 md5 hash - if($obj->password) $obj->password = md5($obj->password); - - // 원본 작성인과 수정하려는 수정인이 동일할 시에 또는 History를 사용하면 로그인된 사용자 정보를 입력 - if(Context::get('is_logged')) { - $logged_info = Context::get('logged_info'); - if($source_obj->get('member_srl')==$logged_info->member_srl || $bUseHistory) { - $obj->member_srl = $logged_info->member_srl; - $obj->user_name = $logged_info->user_name; - $obj->nick_name = $logged_info->nick_name; - $obj->email_address = $logged_info->email_address; - $obj->homepage = $logged_info->homepage; - } - } - - // 로그인한 유저가 작성한 글인데 nick_name이 없을 경우 - if($source_obj->get('member_srl')&& !$obj->nick_name) { - $obj->member_srl = $source_obj->get('member_srl'); - $obj->user_name = $source_obj->get('user_name'); - $obj->nick_name = $source_obj->get('nick_name'); - $obj->email_address = $source_obj->get('email_address'); - $obj->homepage = $source_obj->get('homepage'); - } - - // 제목이 없으면 내용에서 추출 - settype($obj->title, "string"); - if($obj->title == '') $obj->title = cut_str(strip_tags($obj->content),20,'...'); - //그래도 없으면 Untitled - if($obj->title == '') $obj->title = 'Untitled'; - - // 내용에서 XE만의 태그를 삭제 - $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); - - // 글쓴이의 언어변수와 원문의 언어변수가 다르면 확장변수로 처리 - if($source_obj->get('lang_code') != Context::getLangType()) { - // 원문의 언어변수가 없을경우 확장변수가 아닌 원문의 언어변수를 변경 - if(!$source_obj->get('lang_code')) { - $lang_code_args->document_srl = $source_obj->get('document_srl'); - $lang_code_args->lang_code = Context::getLangType(); - $output = executeQuery('document.updateDocumentsLangCode', $lang_code_args); - } else { - $extra_content->title = $obj->title; - $extra_content->content = $obj->content; - - $document_args->document_srl = $source_obj->get('document_srl'); - $document_output = executeQuery('document.getDocument', $document_args); - $obj->title = $document_output->data->title; - $obj->content = $document_output->data->content; - } - } - - // 세션에서 최고 관리자가 아니면 iframe, script 제거 - if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); - - // DB에 입력 - $output = executeQuery('document.updateDocument', $obj); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 모든 확장 변수 삭제 - $this->deleteDocumentExtraVars($source_obj->get('module_srl'), $obj->document_srl, null, Context::getLangType()); - - // 등록 성공시 확장 변수 등록 - $extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl); - if(count($extra_keys)) { - foreach($extra_keys as $idx => $extra_item) { - $value = ''; - if(isset($obj->{'extra_vars'.$idx})) $value = trim($obj->{'extra_vars'.$idx}); - elseif(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); - if(!isset($value)) continue; - $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); - } - } - - // 제목/내용의 다국어 확장변수 등록 - if($extra_content->title) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -1, $extra_content->title, 'title_'.Context::getLangType()); - if($extra_content->content) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -2, $extra_content->content, 'content_'.Context::getLangType()); - - // 성공하였을 경우 category_srl이 있으면 카테고리 update - if($source_obj->get('category_srl') != $obj->category_srl || $source_obj->get('module_srl') == $logged_info->member_srl) { - if($source_obj->get('category_srl') != $obj->category_srl) $this->updateCategoryCount($obj->module_srl, $source_obj->get('category_srl')); - if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl); - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('document.updateDocument', 'after', $obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - // 썸네일 파일 제거 - FileHandler::removeDir(sprintf('files/cache/thumbnails/%s',getNumberingPath($obj->document_srl, 3))); - - $output->add('document_srl',$obj->document_srl); - return $output; - } - - /** - * @brief 문서 삭제 - **/ - function deleteDocument($document_srl, $is_admin = false) { - // trigger 호출 (before) - $trigger_obj->document_srl = $document_srl; - $output = ModuleHandler::triggerCall('document.deleteDocument', 'before', $trigger_obj); - if(!$output->toBool()) return $output; - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - // document의 model 객체 생성 - $oDocumentModel = &getModel('document'); - - // 기존 문서가 있는지 확인 - $oDocument = $oDocumentModel->getDocument($document_srl, $is_admin); - if(!$oDocument->isExists() || $oDocument->document_srl != $document_srl) return new Object(-1, 'msg_invalid_document'); - - // 권한이 있는지 확인 - if(!$oDocument->isGranted()) return new Object(-1, 'msg_not_permitted'); - - // 글 삭제 - $args->document_srl = $document_srl; - $output = executeQuery('document.deleteDocument', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - $this->deleteDocumentAliasByDocument($document_srl); - - $this->deleteDocumentHistory(null, $document_srl, null); - - // 카테고리가 있으면 카테고리 정보 변경 - if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl')); - - // 신고 삭제 - executeQuery('document.deleteDeclared', $args); - - // 확장 변수 삭제 - $this->deleteDocumentExtraVars($oDocument->get('module_srl'), $oDocument->document_srl); - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_obj = $oDocument->getObjectVars(); - $trigger_output = ModuleHandler::triggerCall('document.deleteDocument', 'after', $trigger_obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // 썸네일 파일 제거 - FileHandler::removeDir(sprintf('files/cache/thumbnails/%s',getNumberingPath($document_srl, 3))); - - // commit - $oDB->commit(); - - return $output; - } - - /** - * @brief 문서를 휴지통으로 옮김 - **/ - function moveDocumentToTrash($obj) { - // 주어진 trash_srl이 없으면 trash_srl 등록 - if(!$obj->trash_srl) $trash_args->trash_srl = getNextSequence(); - else $trash_args->trash_srl = $obj->trash_srl; - - // 해당 document가 속해 있는 module_srl을 구한다 - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($obj->document_srl); - - $trash_args->module_srl = $oDocument->get('module_srl'); - $obj->module_srl = $oDocument->get('module_srl'); - - // 휴지통 문서를 두번 휴지통에 버릴 수 없음. - if($trash_args->module_srl == 0) return false; - - // 데이터 설정 - $trash_args->document_srl = $obj->document_srl; - $trash_args->description = $obj->description; - - // 수동 등록이 아니고 로그인 된 회원일 경우 회원의 정보를 입력 - if(Context::get('is_logged')&&!$manual_inserted) { - $logged_info = Context::get('logged_info'); - $trash_args->member_srl = $logged_info->member_srl; - $trash_args->user_id = $logged_info->user_id; - $trash_args->user_name = $logged_info->user_name; - $trash_args->nick_name = $logged_info->nick_name; - } - - // documents update를 위한 데이터 설정 - $document_args->module_srl = 0; - $document_args->document_srl = $obj->document_srl; - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - $output = executeQuery('document.insertTrash', $trash_args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - $output = executeQuery('document.updateDocument', $document_args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // update category - if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl')); - - // remove thumbnails - FileHandler::removeDir(sprintf('files/cache/thumbnails/%s',getNumberingPath($obj->document_srl, 3))); - - // 등록된 첨부파일의 상태를 무효로 지정 - if($oDocument->hasUploadedFiles()) { - $args->upload_target_srl = $oDocument->document_srl; - $args->isvalid = 'N'; - executeQuery('file.updateFileValid', $args); - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('document.moveDocumentToTrash', 'after', $obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - return $output; - } - - /** - * @brief 해당 document의 조회수 증가 - **/ - function updateReadedCount(&$oDocument) { - $document_srl = $oDocument->document_srl; - $member_srl = $oDocument->get('member_srl'); - $logged_info = Context::get('logged_info'); - - // 조회수 업데이트가 되면 trigger 호출 (after) - $output = ModuleHandler::triggerCall('document.updateReadedCount', 'after', $oDocument); - if(!$output->toBool()) return $output; - // session에 정보로 조회수를 증가하였다고 생각하면 패스 - if($_SESSION['readed_document'][$document_srl]) return false; - - // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 - if($document->ipaddress == $_SERVER['REMOTE_ADDR']) { - $_SESSION['readed_document'][$document_srl] = true; - return false; - } - - // document의 작성자가 회원일때 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 판단후 세션 등록하고 패스 - if($member_srl && $logged_info->member_srl == $member_srl) { - $_SESSION['readed_document'][$document_srl] = true; - return false; - } - - // 조회수 업데이트 - $args->document_srl = $document_srl; - $output = executeQuery('document.updateReadedCount', $args); - - // 세션 등록 - $_SESSION['readed_document'][$document_srl] = true; - } - - /** - * @breif documents 테이블의 확장 변수 등록 - **/ - function insertDocumentExtraKey($module_srl, $var_idx, $var_name, $var_type, $var_is_required = 'N', $var_search = 'N', $var_default = '', $var_desc = '', $eid) { - if(!$module_srl || !$var_idx || !$var_name || !$var_type || !$eid) return new Object(-1,'msg_invalid_request'); - - $obj->module_srl = $module_srl; - $obj->var_idx = $var_idx; - $obj->var_name = $var_name; - $obj->var_type = $var_type; - $obj->var_is_required = $var_is_required=='Y'?'Y':'N'; - $obj->var_search = $var_search=='Y'?'Y':'N'; - $obj->var_default = $var_default; - $obj->var_desc = $var_desc; - $obj->eid = $eid; - - $output = executeQuery('document.getDocumentExtraKeys', $obj); - if(!$output->data) return executeQuery('document.insertDocumentExtraKey', $obj); - $output = executeQuery('document.updateDocumentExtraKey', $obj); - - // extra_vars에서 확장 변수 eid를 일괄 업데이트 - $output = executeQuery('document.updateDocumentExtraVar', $obj); - - return $output; - } - - /** - * @brief documents 확장변수 제거 - **/ - function deleteDocumentExtraKeys($module_srl, $var_idx = null) { - if(!$module_srl) return new Object(-1,'msg_invalid_request'); - $obj->module_srl = $module_srl; - if(!is_null($var_idx)) $obj->var_idx = $var_idx; - $output = executeQuery('document.deleteDocumentExtraKeys', $obj); - if(!$output->toBool()) return $output; - - return executeQuery('document.deleteDocumentExtraVars', $obj); - } - - /** - * @breif documents 테이블의 확장 변수 값 등록 - **/ - function insertDocumentExtraVar($module_srl, $document_srl, $var_idx, $value, $eid = null, $lang_code = '') { - if(!$module_srl || !$document_srl || !$var_idx || !isset($value)) return new Object(-1,'msg_invalid_request'); - if(!$lang_code) $lang_code = Context::getLangType(); - - $obj->module_srl = $module_srl; - $obj->document_srl = $document_srl; - $obj->var_idx = $var_idx; - $obj->value = $value; - $obj->lang_code = $lang_code; - $obj->eid = $eid; - - executeQuery('document.insertDocumentExtraVar', $obj); - } - - /** - * @brief documents 확장변수 값 제거 - **/ - function deleteDocumentExtraVars($module_srl, $document_srl = null, $var_idx = null, $lang_code = null, $eid = null) { - $obj->module_srl = $module_srl; - if(!is_null($document_srl)) $obj->document_srl = $document_srl; - if(!is_null($var_idx)) $obj->var_idx = $var_idx; - if(!is_null($lang_code)) $obj->lang_code = $lang_code; - if(!is_null($eid)) $obj->eid = $eid; - $output = executeQuery('document.deleteDocumentExtraVars', $obj); - return $output; - } - - - /** - * @brief 해당 document의 추천수 증가 - **/ - function updateVotedCount($document_srl, $point = 1) { - if($point > 0) $failed_voted = 'failed_voted'; - else $failed_voted = 'failed_blamed'; - - // 세션 정보에 추천 정보가 있으면 중단 - if($_SESSION['voted_document'][$document_srl]) return new Object(-1, $failed_voted); - - // 문서 원본을 가져옴 - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl, false, false); - - // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 - if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { - $_SESSION['voted_document'][$document_srl] = true; - return new Object(-1, $failed_voted); - } - - // document의 작성자가 회원일때 조사 - if($oDocument->get('member_srl')) { - // member model 객체 생성 - $oMemberModel = &getModel('member'); - $member_srl = $oMemberModel->getLoggedMemberSrl(); - - // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 - if($member_srl && $member_srl == $oDocument->get('member_srl')) { - $_SESSION['voted_document'][$document_srl] = true; - return new Object(-1, $failed_voted); - } - } - - // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 - if($member_srl) { - $args->member_srl = $member_srl; - } else { - $args->ipaddress = $_SERVER['REMOTE_ADDR']; - } - $args->document_srl = $document_srl; - $output = executeQuery('document.getDocumentVotedLogInfo', $args); - - // 로그 정보에 추천 로그가 있으면 세션 등록후 패스 - if($output->data->count) { - $_SESSION['voted_document'][$document_srl] = true; - return new Object(-1, $failed_voted); - } - - // 추천수 업데이트 - if($point < 0) - { - $args->blamed_count = $oDocument->get('blamed_count') + $point; - $output = executeQuery('document.updateBlamedCount', $args); - } - else - { - $args->voted_count = $oDocument->get('voted_count') + $point; - $output = executeQuery('document.updateVotedCount', $args); - } - if(!$output->toBool()) return $output; - - // 로그 남기기 - $args->point = $point; - $output = executeQuery('document.insertDocumentVotedLog', $args); - if(!$output->toBool()) return $output; - - // 세션 정보에 남김 - $_SESSION['voted_document'][$document_srl] = true; - - $obj->member_srl = $oDocument->get('member_srl'); - $obj->module_srl = $oDocument->get('module_srl'); - $obj->point = $point; - $output = ModuleHandler::triggerCall('document.updateVotedCount', 'after', $obj); - if(!$output->toBool()) return $output; - - // 결과 리턴 - if($point > 0) - return new Object(0, 'success_voted'); - else - return new Object(0, 'success_blamed'); - } - - /** - * @brief 게시글 신고 - **/ - function declaredDocument($document_srl) { - // 세션 정보에 신고 정보가 있으면 중단 - if($_SESSION['declared_document'][$document_srl]) return new Object(-1, 'failed_declared'); - - // 이미 신고되었는지 검사 - $args->document_srl = $document_srl; - $output = executeQuery('document.getDeclaredDocument', $args); - if(!$output->toBool()) return $output; - $declared_count = $output->data->declared_count; - - // 문서 원본을 가져옴 - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl, false, false); - - // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 - if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { - $_SESSION['declared_document'][$document_srl] = true; - return new Object(-1, 'failed_declared'); - } - - // document의 작성자가 회원일때 조사 - if($oDocument->get('member_srl')) { - // member model 객체 생성 - $oMemberModel = &getModel('member'); - $member_srl = $oMemberModel->getLoggedMemberSrl(); - - // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 - if($member_srl && $member_srl == $oDocument->get('member_srl')) { - $_SESSION['declared_document'][$document_srl] = true; - return new Object(-1, 'failed_declared'); - } - } - - // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 - if($member_srl) { - $args->member_srl = $member_srl; - } else { - $args->ipaddress = $_SERVER['REMOTE_ADDR']; - } - $args->document_srl = $document_srl; - $output = executeQuery('document.getDocumentDeclaredLogInfo', $args); - - // 로그 정보에 신고 로그가 있으면 세션 등록후 패스 - if($output->data->count) { - $_SESSION['declared_document'][$document_srl] = true; - return new Object(-1, 'failed_declared'); - } - - // 신고글 추가 - if($declared_count > 0) $output = executeQuery('document.updateDeclaredDocument', $args); - else $output = executeQuery('document.insertDeclaredDocument', $args); - if(!$output->toBool()) return $output; - - // 로그 남기기 - $output = executeQuery('document.insertDocumentDeclaredLog', $args); - - // 세션 정보에 남김 - $_SESSION['declared_document'][$document_srl] = true; - - $this->setMessage('success_declared'); - } - - /** - * @brief 해당 document의 댓글 수 증가 - * 댓글수를 증가시키면서 수정 순서와 수정일, 수정자를 등록 - **/ - function updateCommentCount($document_srl, $comment_count, $last_updater, $comment_inserted = false) { - $args->document_srl = $document_srl; - $args->comment_count = $comment_count; - - if($comment_inserted) { - $args->update_order = -1*getNextSequence(); - $args->last_updater = $last_updater; - } - - return executeQuery('document.updateCommentCount', $args); - } - - /** - * @brief 해당 document의 엮인글 수증가 - **/ - function updateTrackbackCount($document_srl, $trackback_count) { - $args->document_srl = $document_srl; - $args->trackback_count = $trackback_count; - - return executeQuery('document.updateTrackbackCount', $args); - } - - /** - * @brief 카테고리 추가 - **/ - function insertCategory($obj) { - // 특정 카테고리의 하단으로 추가시 정렬순서 재정렬 - if($obj->parent_srl) { - // 부모 카테고리 구함 - $oDocumentModel = &getModel('document'); - $parent_category = $oDocumentModel->getCategory($obj->parent_srl); - $obj->list_order = $parent_category->list_order; - $this->updateCategoryListOrder($parent_category->module_srl, $parent_category->list_order+1); - if(!$obj->category_srl) $obj->category_srl = getNextSequence(); - } else { - $obj->list_order = $obj->category_srl = getNextSequence(); - } - - $output = executeQuery('document.insertCategory', $obj); - if($output->toBool()) { - $output->add('category_srl', $obj->category_srl); - $this->makeCategoryFile($obj->module_srl); - } - - return $output; - } - - /** - * @brief 특정 카테고리 부터 list_count 증가 - **/ - function updateCategoryListOrder($module_srl, $list_order) { - $args->module_srl = $module_srl; - $args->list_order = $list_order; - return executeQuery('document.updateCategoryOrder', $args); - } - - /** - * @brief 카테고리에 문서의 숫자를 변경 - **/ - function updateCategoryCount($module_srl, $category_srl, $document_count = 0) { - // document model 객체 생성 - $oDocumentModel = &getModel('document'); - if(!$document_count) $document_count = $oDocumentModel->getCategoryDocumentCount($module_srl,$category_srl); - - $args->category_srl = $category_srl; - $args->document_count = $document_count; - $output = executeQuery('document.updateCategoryCount', $args); - if($output->toBool()) $this->makeCategoryFile($module_srl); - - return $output; - } - - /** - * @brief 카테고리의 정보를 수정 - **/ - function updateCategory($obj) { - $output = executeQuery('document.updateCategory', $obj); - if($output->toBool()) $this->makeCategoryFile($obj->module_srl); - return $output; - } - - /** - /** - * @brief 카테고리 삭제 - **/ - function deleteCategory($category_srl) { - $args->category_srl = $category_srl; - $oDocumentModel = &getModel('document'); - $category_info = $oDocumentModel->getCategory($category_srl); - - // 자식 카테고리가 있는지 체크하여 있으면 삭제 못한다는 에러 출력 - $output = executeQuery('document.getChildCategoryCount', $args); - if(!$output->toBool()) return $output; - if($output->data->count>0) return new Object(-1, 'msg_cannot_delete_for_child'); - - // 카테고리 정보를 삭제 - $output = executeQuery('document.deleteCategory', $args); - if(!$output->toBool()) return $output; - - $this->makeCategoryFile($category_info->module_srl); - - // 현 카테고리 값을 가지는 문서들의 category_srl을 0 으로 세팅 - unset($args); - - $args->target_category_srl = 0; - $args->source_category_srl = $category_srl; - $output = executeQuery('document.updateDocumentCategory', $args); - - return $output; - } - - /** - * @brief 특정 모듈의 카테고리를 모두 삭제 - **/ - function deleteModuleCategory($module_srl) { - $args->module_srl = $module_srl; - $output = executeQuery('document.deleteModuleCategory', $args); - return $output; - } - - /** - * @brief 카테고리를 상단으로 이동 - **/ - function moveCategoryUp($category_srl) { - $oDocumentModel = &getModel('document'); - - // 선택된 카테고리의 정보를 구한다 - $args->category_srl = $category_srl; - $output = executeQuery('document.getCategory', $args); - - $category = $output->data; - $list_order = $category->list_order; - $module_srl = $category->module_srl; - - // 전체 카테고리 목록을 구한다 - $category_list = $oDocumentModel->getCategoryList($module_srl); - $category_srl_list = array_keys($category_list); - if(count($category_srl_list)<2) return new Object(); - - $prev_category = NULL; - foreach($category_list as $key => $val) { - if($key==$category_srl) break; - $prev_category = $val; - } - - // 이전 카테고리가 없으면 그냥 return - if(!$prev_category) return new Object(-1,Context::getLang('msg_category_not_moved')); - - // 선택한 카테고리가 가장 위의 카테고리이면 그냥 return - if($category_srl_list[0]==$category_srl) return new Object(-1,Context::getLang('msg_category_not_moved')); - - // 선택한 카테고리의 정보 - $cur_args->category_srl = $category_srl; - $cur_args->list_order = $prev_category->list_order; - $cur_args->title = $category->title; - $this->updateCategory($cur_args); - - // 대상 카테고리의 정보 - $prev_args->category_srl = $prev_category->category_srl; - $prev_args->list_order = $list_order; - $prev_args->title = $prev_category->title; - $this->updateCategory($prev_args); - - return new Object(); - } - - /** - * @brief 카테고리를 아래로 이동 - **/ - function moveCategoryDown($category_srl) { - $oDocumentModel = &getModel('document'); - - // 선택된 카테고리의 정보를 구한다 - $args->category_srl = $category_srl; - $output = executeQuery('document.getCategory', $args); - - $category = $output->data; - $list_order = $category->list_order; - $module_srl = $category->module_srl; - - // 전체 카테고리 목록을 구한다 - $category_list = $oDocumentModel->getCategoryList($module_srl); - $category_srl_list = array_keys($category_list); - if(count($category_srl_list)<2) return new Object(); - - for($i=0;$icategory_srl = $category_srl; - $cur_args->list_order = $next_category->list_order; - $cur_args->title = $category->title; - $this->updateCategory($cur_args); - - // 대상 카테고리의 정보 - $next_args->category_srl = $next_category->category_srl; - $next_args->list_order = $list_order; - $next_args->title = $next_category->title; - $this->updateCategory($next_args); - - return new Object(); - } - - /** - * @brief 특정 module_srl에 해당하는 document_extra_keys type, required등의 값을 체크하여 header에 javascript 코드 추가 - **/ - function addXmlJsFilter($module_srl) { - $oDocumentModel = &getModel('document'); - $extra_keys = $oDocumentModel->getExtraKeys($module_srl); - if(!count($extra_keys)) return; - - $js_code = array(); - $js_code[] = ''; - $js_code = implode("\n", $js_code); - - Context::addHtmlHeader($js_code); - } - - /** - * @brief 카테고리 추가 - **/ - function procDocumentInsertCategory($args = null) { - // 입력할 변수 정리 - if(!$args) $args = Context::gets('module_srl','category_srl','parent_srl','title','expand','group_srls','color','mid'); - - if(!$args->module_srl && $args->mid){ - $mid = $args->mid; - unset($args->mid); - $args->module_srl = $this->module_srl; - } - - // 권한 체크 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); - $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); - if(!$grant->manager) return new Object(-1,'msg_not_permitted'); - - if($args->expand !="Y") $args->expand = "N"; - $args->group_srls = str_replace('|@|',',',$args->group_srls); - $args->parent_srl = (int)$args->parent_srl; - - $oDocumentModel = &getModel('document'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 이미 존재하는지를 확인 - if($args->category_srl) { - $category_info = $oDocumentModel->getCategory($args->category_srl); - if($category_info->category_srl != $args->category_srl) $args->category_srl = null; - } - - // 존재하게 되면 update를 해준다 - if($args->category_srl) { - $output = $this->updateCategory($args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 존재하지 않으면 insert를 해준다 - } else { - $output = $this->insertCategory($args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - } - - // XML 파일을 갱신하고 위치을 넘겨 받음 - $xml_file = $this->makeCategoryFile($args->module_srl); - - $oDB->commit(); - - $this->add('xml_file', $xml_file); - $this->add('module_srl', $args->module_srl); - $this->add('category_srl', $args->category_srl); - $this->add('parent_srl', $args->parent_srl); - } - - - function procDocumentMoveCategory() { - $source_category_srl = Context::get('source_srl'); - - // parent_srl 이 있으면 첫 자식으로 들어간다 - $parent_category_srl = Context::get('parent_srl'); - - // target_srl 이 있으면 target_srl 아래로 형제로 들어간다 - $target_category_srl = Context::get('target_srl'); - - $oDocumentModel = &getModel('document'); - $source_category = $oDocumentModel->getCategory($source_category_srl); - - // 권한 체크 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($source_category->module_srl); - $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); - if(!$grant->manager) return new Object(-1,'msg_not_permitted'); - - //parent_category_srl 의 첫 자식으로 넣자 - if($parent_category_srl > 0 || ($parent_category_srl == 0 && $target_category_srl == 0)){ - $parent_category = $oDocumentModel->getCategory($parent_category_srl); - - $args->module_srl = $source_category->module_srl; - $args->parent_srl = $parent_category_srl; - $output = executeQuery('document.getChildCategoryMinListOrder', $args); - - if(!$output->toBool()) return $output; - $args->list_order = (int)$output->data->list_order; - if(!$args->list_order) $args->list_order = 0; - $args->list_order--; - - - $source_args->category_srl = $source_category_srl; - $source_args->parent_srl = $parent_category_srl; - $source_args->list_order = $args->list_order; - $output = $this->updateCategory($source_args); - if(!$output->toBool()) return $output; - - - // $target_category_srl의 아래동생으로 - }else if($target_category_srl > 0){ - $target_category = $oDocumentModel->getCategory($target_category_srl); - - //$target_category의 아래 동생을 모두 내린다 - $output = $this->updateCategoryListOrder($target_category->module_srl, $target_category->list_order+1); - if(!$output->toBool()) return $output; - - - $source_args->category_srl = $source_category_srl; - $source_args->parent_srl = $target_category->parent_srl; - $source_args->list_order = $target_category->list_order+1; - $output = $this->updateCategory($source_args); - if(!$output->toBool()) return $output; - } - - // xml파일 재생성 - $xml_file = $this->makeCategoryFile($source_category->module_srl); - - // return 변수 설정 - $this->add('xml_file', $xml_file); - $this->add('source_category_srl', $source_category_srl); - - } - - /** - * @brief 카테고리 삭제 - **/ - function procDocumentDeleteCategory() { - // 변수 정리 - $args = Context::gets('module_srl','category_srl'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 권한 체크 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); - $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); - if(!$grant->manager) return new Object(-1,'msg_not_permitted'); - - $oDocumentModel = &getModel('document'); - - // 원정보를 가져옴 - $category_info = $oDocumentModel->getCategory($args->category_srl); - if($category_info->parent_srl) $parent_srl = $category_info->parent_srl; - - // 자식 노드가 있는지 체크하여 있으면 삭제 못한다는 에러 출력 - if($oDocumentModel->getCategoryChlidCount($args->category_srl)) return new Object(-1, 'msg_cannot_delete_for_child'); - - // DB에서 삭제 - $output = $this->deleteCategory($args->category_srl); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // XML 파일을 갱신하고 위치을 넘겨 받음 - $xml_file = $this->makeCategoryFile($args->module_srl); - - $oDB->commit(); - - $this->add('xml_file', $xml_file); - $this->add('category_srl', $parent_srl); - $this->setMessage('success_deleted'); - } - - /** - * @brief xml 파일을 갱신 - * 관리자페이지에서 메뉴 구성 후 간혹 xml파일이 재생성 안되는 경우가 있는데\n - * 이럴 경우 관리자의 수동 갱신 기능을 구현해줌\n - * 개발 중간의 문제인 것 같고 현재는 문제가 생기지 않으나 굳이 없앨 필요 없는 기능 - **/ - function procDocumentMakeXmlFile() { - // 입력값을 체크 - $module_srl = Context::get('module_srl'); - - // 권한 체크 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); - if(!$grant->manager) return new Object(-1,'msg_not_permitted'); - - $xml_file = $this->makeCategoryFile($module_srl); - - // return 값 설정 - $this->add('xml_file',$xml_file); - } - - /** - * @brief 카테고리를 캐시 파일로 저장 - **/ - function makeCategoryFile($module_srl) { - // 캐시 파일 생성시 필요한 정보가 없으면 그냥 return - if(!$module_srl) return false; - - // 모듈 정보를 가져옴 (mid를 구하기 위해) - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - $mid = $module_info->mid; - - if(!is_dir('./files/cache/document_category')) FileHandler::makeDir('./files/cache/document_category'); - - // 캐시 파일의 이름을 지정 - $xml_file = sprintf("./files/cache/document_category/%s.xml.php", $module_srl); - $php_file = sprintf("./files/cache/document_category/%s.php", $module_srl); - - // 카테고리 목록을 구함 - $args->module_srl = $module_srl; - $args->sort_index = 'list_order'; - $output = executeQuery('document.getCategoryList', $args); - - $category_list = $output->data; - - if(!$category_list) { - FileHandler::removeFile($xml_file); - FileHandler::removeFile($php_file); - return false; - } - if(!is_array($category_list)) $category_list = array($category_list); - - $category_count = count($category_list); - for($i=0;$i<$category_count;$i++) { - $category_srl = $category_list[$i]->category_srl; - if(!preg_match('/^[0-9,]+$/', $category_list[$i]->group_srls)) $category_list[$i]->group_srls = ''; - $list[$category_srl] = $category_list[$i]; - } - - // 구해온 데이터가 없다면 노드데이터가 없는 xml 파일만 생성 - if(!$list) { - $xml_buff = ""; - FileHandler::writeFile($xml_file, $xml_buff); - FileHandler::writeFile($php_file, ''); - return $xml_file; - } - - // 구해온 데이터가 하나라면 array로 바꾸어줌 - if(!is_array($list)) $list = array($list); - - // 루프를 돌면서 tree 구성 - foreach($list as $category_srl => $node) { - $node->mid = $mid; - $parent_srl = (int)$node->parent_srl; - $tree[$parent_srl][$category_srl] = $node; - } - - // 캐시 파일의 권한과 그룹 설정을 위한 공통 헤더 - $header_script = - '$lang_type = Context::getLangType(); '. - '$is_logged = Context::get(\'is_logged\'); '. - '$logged_info = Context::get(\'logged_info\'); '. - 'if($is_logged) {'. - 'if($logged_info->is_admin=="Y") $is_admin = true; '. - 'else $is_admin = false; '. - '$group_srls = array_keys($logged_info->group_list); '. - '} else { '. - '$is_admin = false; '. - '$group_srsl = array(); '. - '} '."\n"; - - // xml 캐시 파일 생성 (xml캐시는 따로 동작하기에 session 지정을 해주어야 함) - $xml_header_buff = ''; - $xml_body_buff = $this->getXmlTree($tree[0], $tree, $module_info->site_srl, $xml_header_buff); - $xml_buff = sprintf( - 'init(); '. - 'header("Content-Type: text/xml; charset=UTF-8"); '. - 'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '. - 'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '. - 'header("Cache-Control: no-store, no-cache, must-revalidate"); '. - 'header("Cache-Control: post-check=0, pre-check=0", false); '. - 'header("Pragma: no-cache"); '. - '%s'. - '%s '. - '$oContext->close();'. - '?>'. - '%s', - $header_script, - $xml_header_buff, - $xml_body_buff - ); - - // php 캐시 파일 생성 - $php_output = $this->getPhpCacheCode($tree[0], $tree, $module_info->site_srl, $php_header_buff); - $php_buff = sprintf( - 'list = array(%s); '. - '?>', - $header_script, - $php_header_buff, - $php_output['buff'] - ); - - // 파일 저장 - FileHandler::writeFile($xml_file, $xml_buff); - FileHandler::writeFile($php_file, $php_buff); - return $xml_file; - } - - /** - * @brief array로 정렬된 노드들을 parent_srl을 참조하면서 recursive하게 돌면서 xml 데이터 생성 - * 메뉴 xml파일은 node라는 tag가 중첩으로 사용되며 이 xml doc으로 관리자 페이지에서 메뉴를 구성해줌\n - * (tree_menu.js 에서 xml파일을 바로 읽고 tree menu를 구현) - **/ - function getXmlTree($source_node, $tree, $site_srl, &$xml_header_buff) { - if(!$source_node) return; - - foreach($source_node as $category_srl => $node) { - $child_buff = ""; - - // 자식 노드의 데이터 가져옴 - if($category_srl && $tree[$category_srl]) $child_buff = $this->getXmlTree($tree[$category_srl], $tree, $site_srl, $xml_header_buff); - - // 변수 정리 - $expand = $node->expand; - $group_srls = $node->group_srls; - $mid = $node->mid; - $module_srl = $node->module_srl; - $parent_srl = $node->parent_srl; - $color = $node->color; - // node->group_srls값이 있으면 - if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls); - else $group_check_code = "true"; - - $title = $node->title; - $oModuleAdminModel = &getAdminModel('module'); - $langs = $oModuleAdminModel->getLangCode($site_srl, $title); - if(count($langs)) foreach($langs as $key => $val) $xml_header_buff .= sprintf('$_titles[%d]["%s"] = "%s"; ', $category_srl, $key, str_replace('"','\\"',htmlspecialchars($val))); - - $attribute = sprintf( - 'mid="%s" module_srl="%d" node_srl="%d" parent_srl="%d" category_srl="%d" text="" url="%s" expand="%s" color="%s" document_count="%d" ', - $mid, - $module_srl, - $category_srl, - $parent_srl, - $category_srl, - $group_check_code, - $category_srl, - getUrl('','mid',$node->mid,'category',$category_srl), - $expand, - $color, - $node->document_count - ); - - if($child_buff) $buff .= sprintf('%s', $attribute, $child_buff); - else $buff .= sprintf('', $attribute); - } - return $buff; - } - - /** - * @brief array로 정렬된 노드들을 php code로 변경하여 return - * 메뉴에서 메뉴를 tpl에 사용시 xml데이터를 사용할 수도 있지만 별도의 javascript 사용이 필요하기에 - * php로 된 캐시파일을 만들어서 db이용없이 바로 메뉴 정보를 구할 수 있도록 한다 - * 이 캐시는 ModuleHandler::displayContent() 에서 include하여 Context::set() 한다 - **/ - function getPhpCacheCode($source_node, $tree, $site_srl, &$php_header_buff) { - $output = array("buff"=>"", "category_srl_list"=>array()); - if(!$source_node) return $output; - - // 루프를 돌면서 1차 배열로 정리하고 include할 수 있는 php script 코드를 생성 - foreach($source_node as $category_srl => $node) { - - // 자식 노드가 있으면 자식 노드의 데이터를 먼저 얻어옴 - if($category_srl&&$tree[$category_srl]) $child_output = $this->getPhpCacheCode($tree[$category_srl], $tree, $site_srl, $php_header_buff); - else $child_output = array("buff"=>"", "category_srl_list"=>array()); - - // 현재 노드의 url값이 공란이 아니라면 category_srl_list 배열값에 입력 - $child_output['category_srl_list'][] = $node->category_srl; - $output['category_srl_list'] = array_merge($output['category_srl_list'], $child_output['category_srl_list']); - - // node->group_srls값이 있으면 - if($node->group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls); - else $group_check_code = "true"; - - // 변수 정리 - $selected = '"'.implode('","',$child_output['category_srl_list']).'"'; - $child_buff = $child_output['buff']; - $expand = $node->expand; - - $title = $node->title; - $oModuleAdminModel = &getAdminModel('module'); - $langs = $oModuleAdminModel->getLangCode($site_srl, $title); - if(count($langs)) foreach($langs as $key => $val) $php_header_buff .= sprintf('$_titles[%d]["%s"] = "%s"; ', $category_srl, $key, str_replace('"','\\"',htmlspecialchars($val))); - - // 속성을 생성한다 ( category_srl_list를 이용해서 선택된 메뉴의 노드에 속하는지를 검사한다. 꽁수지만 빠르고 강력하다고 생각;;) - $attribute = sprintf( - '"mid" => "%s", "module_srl" => "%d","node_srl"=>"%s","category_srl"=>"%s","parent_srl"=>"%s","text"=>$_titles[%d][$lang_type],"selected"=>(in_array(Context::get("category"),array(%s))?1:0),"expand"=>"%s","color"=>"%s", "list"=>array(%s),"document_count"=>"%d","grant"=>%s?true:false', - $node->mid, - $node->module_srl, - $node->category_srl, - $node->category_srl, - $node->parent_srl, - $node->category_srl, - $selected, - $expand, - $node->color, - $child_buff, - $node->document_count, - $group_check_code - ); - - // buff 데이터를 생성한다 - $output['buff'] .= sprintf('%s=>array(%s),', $node->category_srl, $attribute); - } - return $output; - } - - /** - * @brief 게시물의 이 게시물을.. 클릭시 나타나는 팝업 메뉴를 추가하는 method - **/ - function addDocumentPopupMenu($url, $str, $icon = '', $target = 'self') { - $document_popup_menu_list = Context::get('document_popup_menu_list'); - if(!is_array($document_popup_menu_list)) $document_popup_menu_list = array(); - - $obj->url = $url; - $obj->str = $str; - $obj->icon = $icon; - $obj->target = $target; - $document_popup_menu_list[] = $obj; - - Context::set('document_popup_menu_list', $document_popup_menu_list); - } - - /** - * @brief 관리자가 글 선택시 세션에 담음 - **/ - function procDocumentAddCart() { - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_permitted'); - - // 게시글 번호 구함 - $srls = explode(',',Context::get('srls')); - for($i=0;$ilist_count = count($document_srls); - $args->document_srls = implode(',',$document_srls); - $args->order_type = 'asc'; - $output = executeQueryArray('document.getDocuments', $args); - if(!$output->data) return new Object(); - - unset($document_srls); - foreach($output->data as $key => $val) { - $document_srls[$val->module_srl][] = $val->document_srl; - } - if(!$document_srls || !count($document_srls)) return new Object(); - - // 각 문서들의 모듈 관리자 여부 확인, 최고 관리자는 모든 모듈의 문서에 수정 권한 가짐. (임시저장이나 휴지통 문서 포함.) - $oModuleModel = &getModel('module'); - $module_srls = array_keys($document_srls); - for($i=0;$igetModuleInfoByModuleSrl($module_srl); - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y') { - if(!$module_info) { - unset($document_srls[$module_srl]); - continue; - } - $grant = $oModuleModel->getGrant($module_info, $logged_info); - if(!$grant->manager) { - unset($document_srls[$module_srl]); - continue; - } - } - - } - if(!count($document_srls)) return new Object(); - - foreach($document_srls as $module_srl => $documents) { - $cnt = count($documents); - for($i=0;$i<$cnt;$i++) { - $document_srl = (int)trim($documents[$i]); - if(!$document_srls) continue; - if($_SESSION['document_management'][$document_srl]) unset($_SESSION['document_management'][$document_srl]); - else $_SESSION['document_management'][$document_srl] = true; - } - } - } - - /** - * @brief 세션에 담긴 선택글의 이동/ 삭제 - **/ - function procDocumentManageCheckedDocument() { - if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted'); - - $type = Context::get('type'); - $module_srl = Context::get('target_module'); - $category_srl = Context::get('target_category'); - $message_content = Context::get('message_content'); - if($message_content) $message_content = nl2br($message_content); - - $cart = Context::get('cart'); - if($cart) $document_srl_list = explode('|@|', $cart); - else $document_srl_list = array(); - - $document_srl_count = count($document_srl_list); - - // 쪽지 발송 - if($message_content) { - - $oCommunicationController = &getController('communication'); - $oDocumentModel = &getModel('document'); - - $logged_info = Context::get('logged_info'); - - $title = cut_str($message_content,10,'...'); - $sender_member_srl = $logged_info->member_srl; - - for($i=0;$i<$document_srl_count;$i++) { - $document_srl = $document_srl_list[$i]; - $oDocument = $oDocumentModel->getDocument($document_srl); - if(!$oDocument->get('member_srl') || $oDocument->get('member_srl')==$sender_member_srl) continue; - - if($type=='move') $purl = sprintf("%s", $oDocument->getPermanentUrl(), $oDocument->getPermanentUrl()); - else $purl = ""; - $content .= sprintf("
%s

%s
%s
%s",$message_content, $purl, $oDocument->getTitleText(), $oDocument->getContent(false, false, false)); - - $oCommunicationController->sendMessage($sender_member_srl, $oDocument->get('member_srl'), $title, $content, false); - } - } - - // 스팸 처리가 되지 않도록 스팸필터 설정 - $oSpamController = &getController('spamfilter'); - $oSpamController->setAvoidLog(); - $oDocumentAdminController = &getAdminController('document'); - - if($type == 'move') { - if(!$module_srl) return new Object(-1, 'fail_to_move'); - - $output = $oDocumentAdminController->moveDocumentModule($document_srl_list, $module_srl, $category_srl); - if(!$output->toBool()) return new Object(-1, 'fail_to_move'); - - $msg_code = 'success_moved'; - - } elseif($type == 'copy') { - if(!$module_srl) return new Object(-1, 'fail_to_move'); - - $output = $oDocumentAdminController->copyDocumentModule($document_srl_list, $module_srl, $category_srl); - if(!$output->toBool()) return new Object(-1, 'fail_to_move'); - - $msg_code = 'success_registed'; - - } elseif($type =='delete') { - $oDB = &DB::getInstance(); - $oDB->begin(); - for($i=0;$i<$document_srl_count;$i++) { - $document_srl = $document_srl_list[$i]; - $output = $this->deleteDocument($document_srl, true); - if(!$output->toBool()) return new Object(-1, 'fail_to_delete'); - } - $oDB->commit(); - $msg_code = 'success_deleted'; - } elseif($type == 'trash') { - $args->description = $message_content; - - $oDB = &DB::getInstance(); - $oDB->begin(); - for($i=0;$i<$document_srl_count;$i++) { - $args->document_srl = $document_srl_list[$i]; - $output = $this->moveDocumentToTrash($args); - if(!$output || !$output->toBool()) return new Object(-1, 'fail_to_trash'); - } - $oDB->commit(); - $msg_code = 'success_trashed'; - } - - $_SESSION['document_management'] = array(); - - $this->setMessage($msg_code); - } - - function procDocumentInsertModuleConfig() - { - $module_srl = Context::get('target_module_srl'); - if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); - else $module_srl = array($module_srl); - - $document_config = null; - $document_config->use_history = Context::get('use_history'); - if(!$document_config->use_history) $document_config->use_history = 'N'; - - $oModuleController = &getController('module'); - for($i=0;$iinsertModulePartConfig('document',$srl,$document_config); - } - $this->setError(-1); - $this->setMessage('success_updated'); - } - } -?> +updateVotedCount($document_srl, $point); + } + + function insertAlias($module_srl, $document_srl, $alias_title) { + $args->alias_srl = getNextSequence(); + $args->module_srl = $module_srl; + $args->document_srl = $document_srl; + $args->alias_title = urldecode($alias_title); + $query = "document.insertAlias"; + $output = executeQuery($query, $args); + return $output; + } + + /** + * @breif 게시글의 추천을 처리하는 action (Down) + **/ + function procDocumentVoteDown() { + if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); + + $document_srl = Context::get('target_srl'); + if(!$document_srl) return new Object(-1, 'msg_invalid_request'); + + $point = -1; + return $this->updateVotedCount($document_srl, $point); + } + + /** + * @brief 게시글이 신고될 경우 호출되는 action + **/ + function procDocumentDeclare() { + if(!Context::get('is_logged')) return new Object(-1, 'msg_invalid_request'); + + $document_srl = Context::get('target_srl'); + if(!$document_srl) return new Object(-1, 'msg_invalid_request'); + + return $this->declaredDocument($document_srl); + } + + function deleteDocumentAliasByModule($module_srl) + { + $args->module_srl = $module_srl; + executeQuery("document.deleteAlias", $args); + } + + function deleteDocumentAliasByDocument($document_srl) + { + $args->document_srl = $document_srl; + executeQuery("document.deleteAlias", $args); + } + + function deleteDocumentHistory($history_srl, $document_srl, $module_srl) + { + $args->history_srl = $history_srl; + $args->module_srl = $module_srl; + $args->document_srl = $document_srl; + if(!$args->history_srl && !$args->module_srl && !$args->document_srl) return; + executeQuery("document.deleteHistory", $args); + } + + /** + * @brief 모듈이 삭제될때 등록된 모든 글을 삭제하는 trigger + **/ + function triggerDeleteModuleDocuments(&$obj) { + $module_srl = $obj->module_srl; + if(!$module_srl) return new Object(); + + // document 삭제 + $oDocumentAdminController = &getAdminController('document'); + $output = $oDocumentAdminController->deleteModuleDocument($module_srl); + if(!$output->toBool()) return $output; + + // category 삭제 + $oDocumentController = &getController('document'); + $output = $oDocumentController->deleteModuleCategory($module_srl); + if(!$output->toBool()) return $output; + + // 확장변수 삭제 + $this->deleteDocumentExtraVars($module_srl); + + // remove aliases + $this->deleteDocumentAliasByModule($module_srl); + + // remove histories + $this->deleteDocumentHistory(null, null, $module_srl); + + return new Object(); + } + + /** + * @brief 문서의 권한 부여 + * 세션값으로 현 접속상태에서만 사용 가능 + **/ + function addGrant($document_srl) { + $_SESSION['own_document'][$document_srl] = true; + } + + /** + * @brief 문서 입력 + **/ + function insertDocument($obj, $manual_inserted = false) { + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 기본 변수들 정리 + if($obj->is_secret!='Y') $obj->is_secret = 'N'; + if($obj->allow_comment!='Y') $obj->allow_comment = 'N'; + if($obj->lock_comment!='Y') $obj->lock_comment = 'N'; + if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; + if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + if($obj->notify_message != 'Y') $obj->notify_message = 'N'; + + // $extra_vars를 serialize + $obj->extra_vars = serialize($obj->extra_vars); + + // 자동저장용 필드 제거 + unset($obj->_saved_doc_srl); + unset($obj->_saved_doc_title); + unset($obj->_saved_doc_content); + unset($obj->_saved_doc_message); + + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('document.insertDocument', 'before', $obj); + if(!$output->toBool()) return $output; + + // 주어진 문서 번호가 없으면 문서 번호 등록 + if(!$obj->document_srl) $obj->document_srl = getNextSequence(); + + $oDocumentModel = &getModel('document'); + + // 카테고리가 있나 검사하여 없는 카테고리면 0으로 세팅 + if($obj->category_srl) { + $category_list = $oDocumentModel->getCategoryList($obj->module_srl); + if(!$category_list[$obj->category_srl]) $obj->category_srl = 0; + } + + // 조회수, 등록순서 설정 + if(!$obj->readed_count) $obj->readed_count = 0; + $obj->update_order = $obj->list_order = getNextSequence() * -1; + + // 수동입력을 대비해서 비밀번호의 hash상태를 점검, 수동입력이 아니면 무조건 md5 hash + if($obj->password && !$obj->password_is_hashed) $obj->password = md5($obj->password); + + // 수동 등록이 아니고 로그인 된 회원일 경우 회원의 정보를 입력 + if(Context::get('is_logged')&&!$manual_inserted) { + $logged_info = Context::get('logged_info'); + $obj->member_srl = $logged_info->member_srl; + $obj->user_id = $logged_info->user_id; + $obj->user_name = $logged_info->user_name; + $obj->nick_name = $logged_info->nick_name; + $obj->email_address = $logged_info->email_address; + $obj->homepage = $logged_info->homepage; + } + + // 제목이 없으면 내용에서 추출 + settype($obj->title, "string"); + if($obj->title == '') $obj->title = cut_str(strip_tags($obj->content),20,'...'); + //그래도 없으면 Untitled + if($obj->title == '') $obj->title = 'Untitled'; + + // 내용에서 XE만의 태그를 삭제 + $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); + if(Mobile::isFromMobilePhone()) + { + $obj->content = nl2br(htmlspecialchars($obj->content)); + } + + // 세션에서 최고 관리자가 아니면 iframe, script 제거 + if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); + + // 로그인정보가 없고 사용자 이름이 없으면 오류 표시 + if(!$logged_info->member_srl && !$obj->nick_name) return new Object(-1,'msg_invalid_request'); + + $obj->lang_code = Context::getLangType(); + + // DB에 입력 + $output = executeQuery('document.insertDocument', $obj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 등록 성공시 확장 변수 등록 + $extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl); + if(count($extra_keys)) { + foreach($extra_keys as $idx => $extra_item) { + $value = ''; + if(isset($obj->{'extra_vars'.$idx})) $value = trim($obj->{'extra_vars'.$idx}); + elseif(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); + if(!isset($value)) continue; + $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); + } + } + + // 성공하였을 경우 category_srl이 있으면 카테고리 update + if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl); + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('document.insertDocument', 'after', $obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + // return + $this->addGrant($obj->document_srl); + $output->add('document_srl',$obj->document_srl); + $output->add('category_srl',$obj->category_srl); + return $output; + } + + /** + * @brief 문서 수정 + **/ + function updateDocument($source_obj, $obj) { + if(!$source_obj->document_srl || !$obj->document_srl) return new Object(-1,'msg_invalied_request'); + + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('document.updateDocument', 'before', $obj); + if(!$output->toBool()) return $output; + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + $oModuleModel = &getModel('module'); + if(!$obj->module_srl) $obj->module_srl = $source_obj->get('module_srl'); + $module_srl = $obj->module_srl; + $document_config = $oModuleModel->getModulePartConfig('document', $module_srl); + if(!isset($document_config->use_history)) $document_config->use_history = 'N'; + $bUseHistory = $document_config->use_history == 'Y' || $document_config->use_history == 'Trace'; + + if($bUseHistory) { + $args->history_srl = getNextSequence(); + $args->document_srl = $obj->document_srl; + $args->module_srl = $module_srl; + if($document_config->use_history == 'Y') $args->content = $source_obj->get('content'); + $args->nick_name = $source_obj->get('nick_name'); + $args->member_srl = $source_obj->get('member_srl'); + $args->regdate = $source_obj->get('last_update'); + $args->ipaddress = $source_obj->get('ipaddress'); + $output = executeQuery("document.insertHistory", $args); + } + else + { + $obj->ipaddress = $source_obj->get('ipaddress'); + } + + // 기본 변수들 정리 + if($obj->is_secret!='Y') $obj->is_secret = 'N'; + if($obj->allow_comment!='Y') $obj->allow_comment = 'N'; + if($obj->lock_comment!='Y') $obj->lock_comment = 'N'; + if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; + if($obj->homepage && !preg_match('/^[a-z]+:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + if($obj->notify_message != 'Y') $obj->notify_message = 'N'; + + // $extra_vars를 serialize + $obj->extra_vars = serialize($obj->extra_vars); + + // 자동저장용 필드 제거 + unset($obj->_saved_doc_srl); + unset($obj->_saved_doc_title); + unset($obj->_saved_doc_content); + unset($obj->_saved_doc_message); + + $oDocumentModel = &getModel('document'); + + // 카테고리가 변경되었으면 검사후 없는 카테고리면 0으로 세팅 + if($source_obj->get('category_srl')!=$obj->category_srl) { + $category_list = $oDocumentModel->getCategoryList($obj->module_srl); + if(!$category_list[$obj->category_srl]) $obj->category_srl = 0; + } + + // 수정 순서를 조절 + $obj->update_order = getNextSequence() * -1; + + // 비밀번호가 있으면 md5 hash + if($obj->password) $obj->password = md5($obj->password); + + // 원본 작성인과 수정하려는 수정인이 동일할 시에 또는 History를 사용하면 로그인된 사용자 정보를 입력 + if(Context::get('is_logged')) { + $logged_info = Context::get('logged_info'); + if($source_obj->get('member_srl')==$logged_info->member_srl || $bUseHistory) { + $obj->member_srl = $logged_info->member_srl; + $obj->user_name = $logged_info->user_name; + $obj->nick_name = $logged_info->nick_name; + $obj->email_address = $logged_info->email_address; + $obj->homepage = $logged_info->homepage; + } + } + + // 로그인한 유저가 작성한 글인데 nick_name이 없을 경우 + if($source_obj->get('member_srl')&& !$obj->nick_name) { + $obj->member_srl = $source_obj->get('member_srl'); + $obj->user_name = $source_obj->get('user_name'); + $obj->nick_name = $source_obj->get('nick_name'); + $obj->email_address = $source_obj->get('email_address'); + $obj->homepage = $source_obj->get('homepage'); + } + + // 제목이 없으면 내용에서 추출 + settype($obj->title, "string"); + if($obj->title == '') $obj->title = cut_str(strip_tags($obj->content),20,'...'); + //그래도 없으면 Untitled + if($obj->title == '') $obj->title = 'Untitled'; + + // 내용에서 XE만의 태그를 삭제 + $obj->content = preg_replace('!<\!--(Before|After)(Document|Comment)\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content); + + // 글쓴이의 언어변수와 원문의 언어변수가 다르면 확장변수로 처리 + if($source_obj->get('lang_code') != Context::getLangType()) { + // 원문의 언어변수가 없을경우 확장변수가 아닌 원문의 언어변수를 변경 + if(!$source_obj->get('lang_code')) { + $lang_code_args->document_srl = $source_obj->get('document_srl'); + $lang_code_args->lang_code = Context::getLangType(); + $output = executeQuery('document.updateDocumentsLangCode', $lang_code_args); + } else { + $extra_content->title = $obj->title; + $extra_content->content = $obj->content; + + $document_args->document_srl = $source_obj->get('document_srl'); + $document_output = executeQuery('document.getDocument', $document_args); + $obj->title = $document_output->data->title; + $obj->content = $document_output->data->content; + } + } + + // 세션에서 최고 관리자가 아니면 iframe, script 제거 + if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content); + + // DB에 입력 + $output = executeQuery('document.updateDocument', $obj); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 모든 확장 변수 삭제 + $this->deleteDocumentExtraVars($source_obj->get('module_srl'), $obj->document_srl, null, Context::getLangType()); + + // 등록 성공시 확장 변수 등록 + $extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl); + if(count($extra_keys)) { + foreach($extra_keys as $idx => $extra_item) { + $value = ''; + if(isset($obj->{'extra_vars'.$idx})) $value = trim($obj->{'extra_vars'.$idx}); + elseif(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); + if(!isset($value)) continue; + $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); + } + } + + // 제목/내용의 다국어 확장변수 등록 + if($extra_content->title) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -1, $extra_content->title, 'title_'.Context::getLangType()); + if($extra_content->content) $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, -2, $extra_content->content, 'content_'.Context::getLangType()); + + // 성공하였을 경우 category_srl이 있으면 카테고리 update + if($source_obj->get('category_srl') != $obj->category_srl || $source_obj->get('module_srl') == $logged_info->member_srl) { + if($source_obj->get('category_srl') != $obj->category_srl) $this->updateCategoryCount($obj->module_srl, $source_obj->get('category_srl')); + if($obj->category_srl) $this->updateCategoryCount($obj->module_srl, $obj->category_srl); + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('document.updateDocument', 'after', $obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + // 썸네일 파일 제거 + FileHandler::removeDir(sprintf('files/cache/thumbnails/%s',getNumberingPath($obj->document_srl, 3))); + + $output->add('document_srl',$obj->document_srl); + return $output; + } + + /** + * @brief 문서 삭제 + **/ + function deleteDocument($document_srl, $is_admin = false) { + // trigger 호출 (before) + $trigger_obj->document_srl = $document_srl; + $output = ModuleHandler::triggerCall('document.deleteDocument', 'before', $trigger_obj); + if(!$output->toBool()) return $output; + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + // document의 model 객체 생성 + $oDocumentModel = &getModel('document'); + + // 기존 문서가 있는지 확인 + $oDocument = $oDocumentModel->getDocument($document_srl, $is_admin); + if(!$oDocument->isExists() || $oDocument->document_srl != $document_srl) return new Object(-1, 'msg_invalid_document'); + + // 권한이 있는지 확인 + if(!$oDocument->isGranted()) return new Object(-1, 'msg_not_permitted'); + + // 글 삭제 + $args->document_srl = $document_srl; + $output = executeQuery('document.deleteDocument', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + $this->deleteDocumentAliasByDocument($document_srl); + + $this->deleteDocumentHistory(null, $document_srl, null); + + // 카테고리가 있으면 카테고리 정보 변경 + if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl')); + + // 신고 삭제 + executeQuery('document.deleteDeclared', $args); + + // 확장 변수 삭제 + $this->deleteDocumentExtraVars($oDocument->get('module_srl'), $oDocument->document_srl); + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_obj = $oDocument->getObjectVars(); + $trigger_output = ModuleHandler::triggerCall('document.deleteDocument', 'after', $trigger_obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // 썸네일 파일 제거 + FileHandler::removeDir(sprintf('files/cache/thumbnails/%s',getNumberingPath($document_srl, 3))); + + // commit + $oDB->commit(); + + return $output; + } + + /** + * @brief 문서를 휴지통으로 옮김 + **/ + function moveDocumentToTrash($obj) { + // 주어진 trash_srl이 없으면 trash_srl 등록 + if(!$obj->trash_srl) $trash_args->trash_srl = getNextSequence(); + else $trash_args->trash_srl = $obj->trash_srl; + + // 해당 document가 속해 있는 module_srl을 구한다 + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($obj->document_srl); + + $trash_args->module_srl = $oDocument->get('module_srl'); + $obj->module_srl = $oDocument->get('module_srl'); + + // 휴지통 문서를 두번 휴지통에 버릴 수 없음. + if($trash_args->module_srl == 0) return false; + + // 데이터 설정 + $trash_args->document_srl = $obj->document_srl; + $trash_args->description = $obj->description; + + // 수동 등록이 아니고 로그인 된 회원일 경우 회원의 정보를 입력 + if(Context::get('is_logged')&&!$manual_inserted) { + $logged_info = Context::get('logged_info'); + $trash_args->member_srl = $logged_info->member_srl; + $trash_args->user_id = $logged_info->user_id; + $trash_args->user_name = $logged_info->user_name; + $trash_args->nick_name = $logged_info->nick_name; + } + + // documents update를 위한 데이터 설정 + $document_args->module_srl = 0; + $document_args->document_srl = $obj->document_srl; + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + $output = executeQuery('document.insertTrash', $trash_args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + $output = executeQuery('document.updateDocument', $document_args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // update category + if($oDocument->get('category_srl')) $this->updateCategoryCount($oDocument->get('module_srl'),$oDocument->get('category_srl')); + + // remove thumbnails + FileHandler::removeDir(sprintf('files/cache/thumbnails/%s',getNumberingPath($obj->document_srl, 3))); + + // 등록된 첨부파일의 상태를 무효로 지정 + if($oDocument->hasUploadedFiles()) { + $args->upload_target_srl = $oDocument->document_srl; + $args->isvalid = 'N'; + executeQuery('file.updateFileValid', $args); + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('document.moveDocumentToTrash', 'after', $obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + return $output; + } + + /** + * @brief 해당 document의 조회수 증가 + **/ + function updateReadedCount(&$oDocument) { + $document_srl = $oDocument->document_srl; + $member_srl = $oDocument->get('member_srl'); + $logged_info = Context::get('logged_info'); + + // 조회수 업데이트가 되면 trigger 호출 (after) + $output = ModuleHandler::triggerCall('document.updateReadedCount', 'after', $oDocument); + if(!$output->toBool()) return $output; + // session에 정보로 조회수를 증가하였다고 생각하면 패스 + if($_SESSION['readed_document'][$document_srl]) return false; + + // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 + if($document->ipaddress == $_SERVER['REMOTE_ADDR']) { + $_SESSION['readed_document'][$document_srl] = true; + return false; + } + + // document의 작성자가 회원일때 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 판단후 세션 등록하고 패스 + if($member_srl && $logged_info->member_srl == $member_srl) { + $_SESSION['readed_document'][$document_srl] = true; + return false; + } + + // 조회수 업데이트 + $args->document_srl = $document_srl; + $output = executeQuery('document.updateReadedCount', $args); + + // 세션 등록 + $_SESSION['readed_document'][$document_srl] = true; + } + + /** + * @breif documents 테이블의 확장 변수 등록 + **/ + function insertDocumentExtraKey($module_srl, $var_idx, $var_name, $var_type, $var_is_required = 'N', $var_search = 'N', $var_default = '', $var_desc = '', $eid) { + if(!$module_srl || !$var_idx || !$var_name || !$var_type || !$eid) return new Object(-1,'msg_invalid_request'); + + $obj->module_srl = $module_srl; + $obj->var_idx = $var_idx; + $obj->var_name = $var_name; + $obj->var_type = $var_type; + $obj->var_is_required = $var_is_required=='Y'?'Y':'N'; + $obj->var_search = $var_search=='Y'?'Y':'N'; + $obj->var_default = $var_default; + $obj->var_desc = $var_desc; + $obj->eid = $eid; + + $output = executeQuery('document.getDocumentExtraKeys', $obj); + if(!$output->data) return executeQuery('document.insertDocumentExtraKey', $obj); + $output = executeQuery('document.updateDocumentExtraKey', $obj); + + // extra_vars에서 확장 변수 eid를 일괄 업데이트 + $output = executeQuery('document.updateDocumentExtraVar', $obj); + + return $output; + } + + /** + * @brief documents 확장변수 제거 + **/ + function deleteDocumentExtraKeys($module_srl, $var_idx = null) { + if(!$module_srl) return new Object(-1,'msg_invalid_request'); + $obj->module_srl = $module_srl; + if(!is_null($var_idx)) $obj->var_idx = $var_idx; + $output = executeQuery('document.deleteDocumentExtraKeys', $obj); + if(!$output->toBool()) return $output; + + return executeQuery('document.deleteDocumentExtraVars', $obj); + } + + /** + * @breif documents 테이블의 확장 변수 값 등록 + **/ + function insertDocumentExtraVar($module_srl, $document_srl, $var_idx, $value, $eid = null, $lang_code = '') { + if(!$module_srl || !$document_srl || !$var_idx || !isset($value)) return new Object(-1,'msg_invalid_request'); + if(!$lang_code) $lang_code = Context::getLangType(); + + $obj->module_srl = $module_srl; + $obj->document_srl = $document_srl; + $obj->var_idx = $var_idx; + $obj->value = $value; + $obj->lang_code = $lang_code; + $obj->eid = $eid; + + executeQuery('document.insertDocumentExtraVar', $obj); + } + + /** + * @brief documents 확장변수 값 제거 + **/ + function deleteDocumentExtraVars($module_srl, $document_srl = null, $var_idx = null, $lang_code = null, $eid = null) { + $obj->module_srl = $module_srl; + if(!is_null($document_srl)) $obj->document_srl = $document_srl; + if(!is_null($var_idx)) $obj->var_idx = $var_idx; + if(!is_null($lang_code)) $obj->lang_code = $lang_code; + if(!is_null($eid)) $obj->eid = $eid; + $output = executeQuery('document.deleteDocumentExtraVars', $obj); + return $output; + } + + + /** + * @brief 해당 document의 추천수 증가 + **/ + function updateVotedCount($document_srl, $point = 1) { + if($point > 0) $failed_voted = 'failed_voted'; + else $failed_voted = 'failed_blamed'; + + // 세션 정보에 추천 정보가 있으면 중단 + if($_SESSION['voted_document'][$document_srl]) return new Object(-1, $failed_voted); + + // 문서 원본을 가져옴 + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl, false, false); + + // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 + if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { + $_SESSION['voted_document'][$document_srl] = true; + return new Object(-1, $failed_voted); + } + + // document의 작성자가 회원일때 조사 + if($oDocument->get('member_srl')) { + // member model 객체 생성 + $oMemberModel = &getModel('member'); + $member_srl = $oMemberModel->getLoggedMemberSrl(); + + // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 + if($member_srl && $member_srl == $oDocument->get('member_srl')) { + $_SESSION['voted_document'][$document_srl] = true; + return new Object(-1, $failed_voted); + } + } + + // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 + if($member_srl) { + $args->member_srl = $member_srl; + } else { + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + $args->document_srl = $document_srl; + $output = executeQuery('document.getDocumentVotedLogInfo', $args); + + // 로그 정보에 추천 로그가 있으면 세션 등록후 패스 + if($output->data->count) { + $_SESSION['voted_document'][$document_srl] = true; + return new Object(-1, $failed_voted); + } + + // 추천수 업데이트 + if($point < 0) + { + $args->blamed_count = $oDocument->get('blamed_count') + $point; + $output = executeQuery('document.updateBlamedCount', $args); + } + else + { + $args->voted_count = $oDocument->get('voted_count') + $point; + $output = executeQuery('document.updateVotedCount', $args); + } + if(!$output->toBool()) return $output; + + // 로그 남기기 + $args->point = $point; + $output = executeQuery('document.insertDocumentVotedLog', $args); + if(!$output->toBool()) return $output; + + // 세션 정보에 남김 + $_SESSION['voted_document'][$document_srl] = true; + + $obj->member_srl = $oDocument->get('member_srl'); + $obj->module_srl = $oDocument->get('module_srl'); + $obj->point = $point; + $output = ModuleHandler::triggerCall('document.updateVotedCount', 'after', $obj); + if(!$output->toBool()) return $output; + + // 결과 리턴 + if($point > 0) + return new Object(0, 'success_voted'); + else + return new Object(0, 'success_blamed'); + } + + /** + * @brief 게시글 신고 + **/ + function declaredDocument($document_srl) { + // 세션 정보에 신고 정보가 있으면 중단 + if($_SESSION['declared_document'][$document_srl]) return new Object(-1, 'failed_declared'); + + // 이미 신고되었는지 검사 + $args->document_srl = $document_srl; + $output = executeQuery('document.getDeclaredDocument', $args); + if(!$output->toBool()) return $output; + $declared_count = $output->data->declared_count; + + // 문서 원본을 가져옴 + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl, false, false); + + // 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스 + if($oDocument->get('ipaddress') == $_SERVER['REMOTE_ADDR']) { + $_SESSION['declared_document'][$document_srl] = true; + return new Object(-1, 'failed_declared'); + } + + // document의 작성자가 회원일때 조사 + if($oDocument->get('member_srl')) { + // member model 객체 생성 + $oMemberModel = &getModel('member'); + $member_srl = $oMemberModel->getLoggedMemberSrl(); + + // 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스 + if($member_srl && $member_srl == $oDocument->get('member_srl')) { + $_SESSION['declared_document'][$document_srl] = true; + return new Object(-1, 'failed_declared'); + } + } + + // 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단 + if($member_srl) { + $args->member_srl = $member_srl; + } else { + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + $args->document_srl = $document_srl; + $output = executeQuery('document.getDocumentDeclaredLogInfo', $args); + + // 로그 정보에 신고 로그가 있으면 세션 등록후 패스 + if($output->data->count) { + $_SESSION['declared_document'][$document_srl] = true; + return new Object(-1, 'failed_declared'); + } + + // 신고글 추가 + if($declared_count > 0) $output = executeQuery('document.updateDeclaredDocument', $args); + else $output = executeQuery('document.insertDeclaredDocument', $args); + if(!$output->toBool()) return $output; + + // 로그 남기기 + $output = executeQuery('document.insertDocumentDeclaredLog', $args); + + // 세션 정보에 남김 + $_SESSION['declared_document'][$document_srl] = true; + + $this->setMessage('success_declared'); + } + + /** + * @brief 해당 document의 댓글 수 증가 + * 댓글수를 증가시키면서 수정 순서와 수정일, 수정자를 등록 + **/ + function updateCommentCount($document_srl, $comment_count, $last_updater, $comment_inserted = false) { + $args->document_srl = $document_srl; + $args->comment_count = $comment_count; + + if($comment_inserted) { + $args->update_order = -1*getNextSequence(); + $args->last_updater = $last_updater; + } + + return executeQuery('document.updateCommentCount', $args); + } + + /** + * @brief 해당 document의 엮인글 수증가 + **/ + function updateTrackbackCount($document_srl, $trackback_count) { + $args->document_srl = $document_srl; + $args->trackback_count = $trackback_count; + + return executeQuery('document.updateTrackbackCount', $args); + } + + /** + * @brief 카테고리 추가 + **/ + function insertCategory($obj) { + // 특정 카테고리의 하단으로 추가시 정렬순서 재정렬 + if($obj->parent_srl) { + // 부모 카테고리 구함 + $oDocumentModel = &getModel('document'); + $parent_category = $oDocumentModel->getCategory($obj->parent_srl); + $obj->list_order = $parent_category->list_order; + $this->updateCategoryListOrder($parent_category->module_srl, $parent_category->list_order+1); + if(!$obj->category_srl) $obj->category_srl = getNextSequence(); + } else { + $obj->list_order = $obj->category_srl = getNextSequence(); + } + + $output = executeQuery('document.insertCategory', $obj); + if($output->toBool()) { + $output->add('category_srl', $obj->category_srl); + $this->makeCategoryFile($obj->module_srl); + } + + return $output; + } + + /** + * @brief 특정 카테고리 부터 list_count 증가 + **/ + function updateCategoryListOrder($module_srl, $list_order) { + $args->module_srl = $module_srl; + $args->list_order = $list_order; + return executeQuery('document.updateCategoryOrder', $args); + } + + /** + * @brief 카테고리에 문서의 숫자를 변경 + **/ + function updateCategoryCount($module_srl, $category_srl, $document_count = 0) { + // document model 객체 생성 + $oDocumentModel = &getModel('document'); + if(!$document_count) $document_count = $oDocumentModel->getCategoryDocumentCount($module_srl,$category_srl); + + $args->category_srl = $category_srl; + $args->document_count = $document_count; + $output = executeQuery('document.updateCategoryCount', $args); + if($output->toBool()) $this->makeCategoryFile($module_srl); + + return $output; + } + + /** + * @brief 카테고리의 정보를 수정 + **/ + function updateCategory($obj) { + $output = executeQuery('document.updateCategory', $obj); + if($output->toBool()) $this->makeCategoryFile($obj->module_srl); + return $output; + } + + /** + /** + * @brief 카테고리 삭제 + **/ + function deleteCategory($category_srl) { + $args->category_srl = $category_srl; + $oDocumentModel = &getModel('document'); + $category_info = $oDocumentModel->getCategory($category_srl); + + // 자식 카테고리가 있는지 체크하여 있으면 삭제 못한다는 에러 출력 + $output = executeQuery('document.getChildCategoryCount', $args); + if(!$output->toBool()) return $output; + if($output->data->count>0) return new Object(-1, 'msg_cannot_delete_for_child'); + + // 카테고리 정보를 삭제 + $output = executeQuery('document.deleteCategory', $args); + if(!$output->toBool()) return $output; + + $this->makeCategoryFile($category_info->module_srl); + + // 현 카테고리 값을 가지는 문서들의 category_srl을 0 으로 세팅 + unset($args); + + $args->target_category_srl = 0; + $args->source_category_srl = $category_srl; + $output = executeQuery('document.updateDocumentCategory', $args); + + return $output; + } + + /** + * @brief 특정 모듈의 카테고리를 모두 삭제 + **/ + function deleteModuleCategory($module_srl) { + $args->module_srl = $module_srl; + $output = executeQuery('document.deleteModuleCategory', $args); + return $output; + } + + /** + * @brief 카테고리를 상단으로 이동 + **/ + function moveCategoryUp($category_srl) { + $oDocumentModel = &getModel('document'); + + // 선택된 카테고리의 정보를 구한다 + $args->category_srl = $category_srl; + $output = executeQuery('document.getCategory', $args); + + $category = $output->data; + $list_order = $category->list_order; + $module_srl = $category->module_srl; + + // 전체 카테고리 목록을 구한다 + $category_list = $oDocumentModel->getCategoryList($module_srl); + $category_srl_list = array_keys($category_list); + if(count($category_srl_list)<2) return new Object(); + + $prev_category = NULL; + foreach($category_list as $key => $val) { + if($key==$category_srl) break; + $prev_category = $val; + } + + // 이전 카테고리가 없으면 그냥 return + if(!$prev_category) return new Object(-1,Context::getLang('msg_category_not_moved')); + + // 선택한 카테고리가 가장 위의 카테고리이면 그냥 return + if($category_srl_list[0]==$category_srl) return new Object(-1,Context::getLang('msg_category_not_moved')); + + // 선택한 카테고리의 정보 + $cur_args->category_srl = $category_srl; + $cur_args->list_order = $prev_category->list_order; + $cur_args->title = $category->title; + $this->updateCategory($cur_args); + + // 대상 카테고리의 정보 + $prev_args->category_srl = $prev_category->category_srl; + $prev_args->list_order = $list_order; + $prev_args->title = $prev_category->title; + $this->updateCategory($prev_args); + + return new Object(); + } + + /** + * @brief 카테고리를 아래로 이동 + **/ + function moveCategoryDown($category_srl) { + $oDocumentModel = &getModel('document'); + + // 선택된 카테고리의 정보를 구한다 + $args->category_srl = $category_srl; + $output = executeQuery('document.getCategory', $args); + + $category = $output->data; + $list_order = $category->list_order; + $module_srl = $category->module_srl; + + // 전체 카테고리 목록을 구한다 + $category_list = $oDocumentModel->getCategoryList($module_srl); + $category_srl_list = array_keys($category_list); + if(count($category_srl_list)<2) return new Object(); + + for($i=0;$icategory_srl = $category_srl; + $cur_args->list_order = $next_category->list_order; + $cur_args->title = $category->title; + $this->updateCategory($cur_args); + + // 대상 카테고리의 정보 + $next_args->category_srl = $next_category->category_srl; + $next_args->list_order = $list_order; + $next_args->title = $next_category->title; + $this->updateCategory($next_args); + + return new Object(); + } + + /** + * @brief 특정 module_srl에 해당하는 document_extra_keys type, required등의 값을 체크하여 header에 javascript 코드 추가 + **/ + function addXmlJsFilter($module_srl) { + $oDocumentModel = &getModel('document'); + $extra_keys = $oDocumentModel->getExtraKeys($module_srl); + if(!count($extra_keys)) return; + + $js_code = array(); + $js_code[] = ''; + $js_code = implode("\n", $js_code); + + Context::addHtmlHeader($js_code); + } + + /** + * @brief 카테고리 추가 + **/ + function procDocumentInsertCategory($args = null) { + // 입력할 변수 정리 + if(!$args) $args = Context::gets('module_srl','category_srl','parent_srl','title','expand','group_srls','color','mid'); + + if(!$args->module_srl && $args->mid){ + $mid = $args->mid; + unset($args->mid); + $args->module_srl = $this->module_srl; + } + + // 권한 체크 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); + $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); + if(!$grant->manager) return new Object(-1,'msg_not_permitted'); + + if($args->expand !="Y") $args->expand = "N"; + $args->group_srls = str_replace('|@|',',',$args->group_srls); + $args->parent_srl = (int)$args->parent_srl; + + $oDocumentModel = &getModel('document'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 이미 존재하는지를 확인 + if($args->category_srl) { + $category_info = $oDocumentModel->getCategory($args->category_srl); + if($category_info->category_srl != $args->category_srl) $args->category_srl = null; + } + + // 존재하게 되면 update를 해준다 + if($args->category_srl) { + $output = $this->updateCategory($args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 존재하지 않으면 insert를 해준다 + } else { + $output = $this->insertCategory($args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + } + + // XML 파일을 갱신하고 위치을 넘겨 받음 + $xml_file = $this->makeCategoryFile($args->module_srl); + + $oDB->commit(); + + $this->add('xml_file', $xml_file); + $this->add('module_srl', $args->module_srl); + $this->add('category_srl', $args->category_srl); + $this->add('parent_srl', $args->parent_srl); + } + + + function procDocumentMoveCategory() { + $source_category_srl = Context::get('source_srl'); + + // parent_srl 이 있으면 첫 자식으로 들어간다 + $parent_category_srl = Context::get('parent_srl'); + + // target_srl 이 있으면 target_srl 아래로 형제로 들어간다 + $target_category_srl = Context::get('target_srl'); + + $oDocumentModel = &getModel('document'); + $source_category = $oDocumentModel->getCategory($source_category_srl); + + // 권한 체크 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($source_category->module_srl); + $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); + if(!$grant->manager) return new Object(-1,'msg_not_permitted'); + + //parent_category_srl 의 첫 자식으로 넣자 + if($parent_category_srl > 0 || ($parent_category_srl == 0 && $target_category_srl == 0)){ + $parent_category = $oDocumentModel->getCategory($parent_category_srl); + + $args->module_srl = $source_category->module_srl; + $args->parent_srl = $parent_category_srl; + $output = executeQuery('document.getChildCategoryMinListOrder', $args); + + if(!$output->toBool()) return $output; + $args->list_order = (int)$output->data->list_order; + if(!$args->list_order) $args->list_order = 0; + $args->list_order--; + + + $source_args->category_srl = $source_category_srl; + $source_args->parent_srl = $parent_category_srl; + $source_args->list_order = $args->list_order; + $output = $this->updateCategory($source_args); + if(!$output->toBool()) return $output; + + + // $target_category_srl의 아래동생으로 + }else if($target_category_srl > 0){ + $target_category = $oDocumentModel->getCategory($target_category_srl); + + //$target_category의 아래 동생을 모두 내린다 + $output = $this->updateCategoryListOrder($target_category->module_srl, $target_category->list_order+1); + if(!$output->toBool()) return $output; + + + $source_args->category_srl = $source_category_srl; + $source_args->parent_srl = $target_category->parent_srl; + $source_args->list_order = $target_category->list_order+1; + $output = $this->updateCategory($source_args); + if(!$output->toBool()) return $output; + } + + // xml파일 재생성 + $xml_file = $this->makeCategoryFile($source_category->module_srl); + + // return 변수 설정 + $this->add('xml_file', $xml_file); + $this->add('source_category_srl', $source_category_srl); + + } + + /** + * @brief 카테고리 삭제 + **/ + function procDocumentDeleteCategory() { + // 변수 정리 + $args = Context::gets('module_srl','category_srl'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 권한 체크 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); + $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); + if(!$grant->manager) return new Object(-1,'msg_not_permitted'); + + $oDocumentModel = &getModel('document'); + + // 원정보를 가져옴 + $category_info = $oDocumentModel->getCategory($args->category_srl); + if($category_info->parent_srl) $parent_srl = $category_info->parent_srl; + + // 자식 노드가 있는지 체크하여 있으면 삭제 못한다는 에러 출력 + if($oDocumentModel->getCategoryChlidCount($args->category_srl)) return new Object(-1, 'msg_cannot_delete_for_child'); + + // DB에서 삭제 + $output = $this->deleteCategory($args->category_srl); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // XML 파일을 갱신하고 위치을 넘겨 받음 + $xml_file = $this->makeCategoryFile($args->module_srl); + + $oDB->commit(); + + $this->add('xml_file', $xml_file); + $this->add('category_srl', $parent_srl); + $this->setMessage('success_deleted'); + } + + /** + * @brief xml 파일을 갱신 + * 관리자페이지에서 메뉴 구성 후 간혹 xml파일이 재생성 안되는 경우가 있는데\n + * 이럴 경우 관리자의 수동 갱신 기능을 구현해줌\n + * 개발 중간의 문제인 것 같고 현재는 문제가 생기지 않으나 굳이 없앨 필요 없는 기능 + **/ + function procDocumentMakeXmlFile() { + // 입력값을 체크 + $module_srl = Context::get('module_srl'); + + // 권한 체크 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); + if(!$grant->manager) return new Object(-1,'msg_not_permitted'); + + $xml_file = $this->makeCategoryFile($module_srl); + + // return 값 설정 + $this->add('xml_file',$xml_file); + } + + /** + * @brief 카테고리를 캐시 파일로 저장 + **/ + function makeCategoryFile($module_srl) { + // 캐시 파일 생성시 필요한 정보가 없으면 그냥 return + if(!$module_srl) return false; + + // 모듈 정보를 가져옴 (mid를 구하기 위해) + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + $mid = $module_info->mid; + + if(!is_dir('./files/cache/document_category')) FileHandler::makeDir('./files/cache/document_category'); + + // 캐시 파일의 이름을 지정 + $xml_file = sprintf("./files/cache/document_category/%s.xml.php", $module_srl); + $php_file = sprintf("./files/cache/document_category/%s.php", $module_srl); + + // 카테고리 목록을 구함 + $args->module_srl = $module_srl; + $args->sort_index = 'list_order'; + $output = executeQuery('document.getCategoryList', $args); + + $category_list = $output->data; + + if(!$category_list) { + FileHandler::removeFile($xml_file); + FileHandler::removeFile($php_file); + return false; + } + if(!is_array($category_list)) $category_list = array($category_list); + + $category_count = count($category_list); + for($i=0;$i<$category_count;$i++) { + $category_srl = $category_list[$i]->category_srl; + if(!preg_match('/^[0-9,]+$/', $category_list[$i]->group_srls)) $category_list[$i]->group_srls = ''; + $list[$category_srl] = $category_list[$i]; + } + + // 구해온 데이터가 없다면 노드데이터가 없는 xml 파일만 생성 + if(!$list) { + $xml_buff = ""; + FileHandler::writeFile($xml_file, $xml_buff); + FileHandler::writeFile($php_file, ''); + return $xml_file; + } + + // 구해온 데이터가 하나라면 array로 바꾸어줌 + if(!is_array($list)) $list = array($list); + + // 루프를 돌면서 tree 구성 + foreach($list as $category_srl => $node) { + $node->mid = $mid; + $parent_srl = (int)$node->parent_srl; + $tree[$parent_srl][$category_srl] = $node; + } + + // 캐시 파일의 권한과 그룹 설정을 위한 공통 헤더 + $header_script = + '$lang_type = Context::getLangType(); '. + '$is_logged = Context::get(\'is_logged\'); '. + '$logged_info = Context::get(\'logged_info\'); '. + 'if($is_logged) {'. + 'if($logged_info->is_admin=="Y") $is_admin = true; '. + 'else $is_admin = false; '. + '$group_srls = array_keys($logged_info->group_list); '. + '} else { '. + '$is_admin = false; '. + '$group_srsl = array(); '. + '} '."\n"; + + // xml 캐시 파일 생성 (xml캐시는 따로 동작하기에 session 지정을 해주어야 함) + $xml_header_buff = ''; + $xml_body_buff = $this->getXmlTree($tree[0], $tree, $module_info->site_srl, $xml_header_buff); + $xml_buff = sprintf( + 'init(); '. + 'header("Content-Type: text/xml; charset=UTF-8"); '. + 'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '. + 'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '. + 'header("Cache-Control: no-store, no-cache, must-revalidate"); '. + 'header("Cache-Control: post-check=0, pre-check=0", false); '. + 'header("Pragma: no-cache"); '. + '%s'. + '%s '. + '$oContext->close();'. + '?>'. + '%s', + $header_script, + $xml_header_buff, + $xml_body_buff + ); + + // php 캐시 파일 생성 + $php_output = $this->getPhpCacheCode($tree[0], $tree, $module_info->site_srl, $php_header_buff); + $php_buff = sprintf( + 'list = array(%s); '. + '?>', + $header_script, + $php_header_buff, + $php_output['buff'] + ); + + // 파일 저장 + FileHandler::writeFile($xml_file, $xml_buff); + FileHandler::writeFile($php_file, $php_buff); + return $xml_file; + } + + /** + * @brief array로 정렬된 노드들을 parent_srl을 참조하면서 recursive하게 돌면서 xml 데이터 생성 + * 메뉴 xml파일은 node라는 tag가 중첩으로 사용되며 이 xml doc으로 관리자 페이지에서 메뉴를 구성해줌\n + * (tree_menu.js 에서 xml파일을 바로 읽고 tree menu를 구현) + **/ + function getXmlTree($source_node, $tree, $site_srl, &$xml_header_buff) { + if(!$source_node) return; + + foreach($source_node as $category_srl => $node) { + $child_buff = ""; + + // 자식 노드의 데이터 가져옴 + if($category_srl && $tree[$category_srl]) $child_buff = $this->getXmlTree($tree[$category_srl], $tree, $site_srl, $xml_header_buff); + + // 변수 정리 + $expand = $node->expand; + $group_srls = $node->group_srls; + $mid = $node->mid; + $module_srl = $node->module_srl; + $parent_srl = $node->parent_srl; + $color = $node->color; + // node->group_srls값이 있으면 + if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls); + else $group_check_code = "true"; + + $title = $node->title; + $oModuleAdminModel = &getAdminModel('module'); + $langs = $oModuleAdminModel->getLangCode($site_srl, $title); + if(count($langs)) foreach($langs as $key => $val) $xml_header_buff .= sprintf('$_titles[%d]["%s"] = "%s"; ', $category_srl, $key, str_replace('"','\\"',htmlspecialchars($val))); + + $attribute = sprintf( + 'mid="%s" module_srl="%d" node_srl="%d" parent_srl="%d" category_srl="%d" text="" url="%s" expand="%s" color="%s" document_count="%d" ', + $mid, + $module_srl, + $category_srl, + $parent_srl, + $category_srl, + $group_check_code, + $category_srl, + getUrl('','mid',$node->mid,'category',$category_srl), + $expand, + $color, + $node->document_count + ); + + if($child_buff) $buff .= sprintf('%s', $attribute, $child_buff); + else $buff .= sprintf('', $attribute); + } + return $buff; + } + + /** + * @brief array로 정렬된 노드들을 php code로 변경하여 return + * 메뉴에서 메뉴를 tpl에 사용시 xml데이터를 사용할 수도 있지만 별도의 javascript 사용이 필요하기에 + * php로 된 캐시파일을 만들어서 db이용없이 바로 메뉴 정보를 구할 수 있도록 한다 + * 이 캐시는 ModuleHandler::displayContent() 에서 include하여 Context::set() 한다 + **/ + function getPhpCacheCode($source_node, $tree, $site_srl, &$php_header_buff) { + $output = array("buff"=>"", "category_srl_list"=>array()); + if(!$source_node) return $output; + + // 루프를 돌면서 1차 배열로 정리하고 include할 수 있는 php script 코드를 생성 + foreach($source_node as $category_srl => $node) { + + // 자식 노드가 있으면 자식 노드의 데이터를 먼저 얻어옴 + if($category_srl&&$tree[$category_srl]) $child_output = $this->getPhpCacheCode($tree[$category_srl], $tree, $site_srl, $php_header_buff); + else $child_output = array("buff"=>"", "category_srl_list"=>array()); + + // 현재 노드의 url값이 공란이 아니라면 category_srl_list 배열값에 입력 + $child_output['category_srl_list'][] = $node->category_srl; + $output['category_srl_list'] = array_merge($output['category_srl_list'], $child_output['category_srl_list']); + + // node->group_srls값이 있으면 + if($node->group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls); + else $group_check_code = "true"; + + // 변수 정리 + $selected = '"'.implode('","',$child_output['category_srl_list']).'"'; + $child_buff = $child_output['buff']; + $expand = $node->expand; + + $title = $node->title; + $oModuleAdminModel = &getAdminModel('module'); + $langs = $oModuleAdminModel->getLangCode($site_srl, $title); + if(count($langs)) foreach($langs as $key => $val) $php_header_buff .= sprintf('$_titles[%d]["%s"] = "%s"; ', $category_srl, $key, str_replace('"','\\"',htmlspecialchars($val))); + + // 속성을 생성한다 ( category_srl_list를 이용해서 선택된 메뉴의 노드에 속하는지를 검사한다. 꽁수지만 빠르고 강력하다고 생각;;) + $attribute = sprintf( + '"mid" => "%s", "module_srl" => "%d","node_srl"=>"%s","category_srl"=>"%s","parent_srl"=>"%s","text"=>$_titles[%d][$lang_type],"selected"=>(in_array(Context::get("category"),array(%s))?1:0),"expand"=>"%s","color"=>"%s", "list"=>array(%s),"document_count"=>"%d","grant"=>%s?true:false', + $node->mid, + $node->module_srl, + $node->category_srl, + $node->category_srl, + $node->parent_srl, + $node->category_srl, + $selected, + $expand, + $node->color, + $child_buff, + $node->document_count, + $group_check_code + ); + + // buff 데이터를 생성한다 + $output['buff'] .= sprintf('%s=>array(%s),', $node->category_srl, $attribute); + } + return $output; + } + + /** + * @brief 게시물의 이 게시물을.. 클릭시 나타나는 팝업 메뉴를 추가하는 method + **/ + function addDocumentPopupMenu($url, $str, $icon = '', $target = 'self') { + $document_popup_menu_list = Context::get('document_popup_menu_list'); + if(!is_array($document_popup_menu_list)) $document_popup_menu_list = array(); + + $obj->url = $url; + $obj->str = $str; + $obj->icon = $icon; + $obj->target = $target; + $document_popup_menu_list[] = $obj; + + Context::set('document_popup_menu_list', $document_popup_menu_list); + } + + /** + * @brief 관리자가 글 선택시 세션에 담음 + **/ + function procDocumentAddCart() { + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_permitted'); + + // 게시글 번호 구함 + $srls = explode(',',Context::get('srls')); + for($i=0;$ilist_count = count($document_srls); + $args->document_srls = implode(',',$document_srls); + $args->order_type = 'asc'; + $output = executeQueryArray('document.getDocuments', $args); + if(!$output->data) return new Object(); + + unset($document_srls); + foreach($output->data as $key => $val) { + $document_srls[$val->module_srl][] = $val->document_srl; + } + if(!$document_srls || !count($document_srls)) return new Object(); + + // 각 문서들의 모듈 관리자 여부 확인, 최고 관리자는 모든 모듈의 문서에 수정 권한 가짐. (임시저장이나 휴지통 문서 포함.) + $oModuleModel = &getModel('module'); + $module_srls = array_keys($document_srls); + for($i=0;$igetModuleInfoByModuleSrl($module_srl); + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y') { + if(!$module_info) { + unset($document_srls[$module_srl]); + continue; + } + $grant = $oModuleModel->getGrant($module_info, $logged_info); + if(!$grant->manager) { + unset($document_srls[$module_srl]); + continue; + } + } + + } + if(!count($document_srls)) return new Object(); + + foreach($document_srls as $module_srl => $documents) { + $cnt = count($documents); + for($i=0;$i<$cnt;$i++) { + $document_srl = (int)trim($documents[$i]); + if(!$document_srls) continue; + if($_SESSION['document_management'][$document_srl]) unset($_SESSION['document_management'][$document_srl]); + else $_SESSION['document_management'][$document_srl] = true; + } + } + } + + /** + * @brief 세션에 담긴 선택글의 이동/ 삭제 + **/ + function procDocumentManageCheckedDocument() { + if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted'); + + $type = Context::get('type'); + $module_srl = Context::get('target_module'); + $category_srl = Context::get('target_category'); + $message_content = Context::get('message_content'); + if($message_content) $message_content = nl2br($message_content); + + $cart = Context::get('cart'); + if($cart) $document_srl_list = explode('|@|', $cart); + else $document_srl_list = array(); + + $document_srl_count = count($document_srl_list); + + // 쪽지 발송 + if($message_content) { + + $oCommunicationController = &getController('communication'); + $oDocumentModel = &getModel('document'); + + $logged_info = Context::get('logged_info'); + + $title = cut_str($message_content,10,'...'); + $sender_member_srl = $logged_info->member_srl; + + for($i=0;$i<$document_srl_count;$i++) { + $document_srl = $document_srl_list[$i]; + $oDocument = $oDocumentModel->getDocument($document_srl); + if(!$oDocument->get('member_srl') || $oDocument->get('member_srl')==$sender_member_srl) continue; + + if($type=='move') $purl = sprintf("%s", $oDocument->getPermanentUrl(), $oDocument->getPermanentUrl()); + else $purl = ""; + $content .= sprintf("
%s

%s
%s
%s",$message_content, $purl, $oDocument->getTitleText(), $oDocument->getContent(false, false, false)); + + $oCommunicationController->sendMessage($sender_member_srl, $oDocument->get('member_srl'), $title, $content, false); + } + } + + // 스팸 처리가 되지 않도록 스팸필터 설정 + $oSpamController = &getController('spamfilter'); + $oSpamController->setAvoidLog(); + $oDocumentAdminController = &getAdminController('document'); + + if($type == 'move') { + if(!$module_srl) return new Object(-1, 'fail_to_move'); + + $output = $oDocumentAdminController->moveDocumentModule($document_srl_list, $module_srl, $category_srl); + if(!$output->toBool()) return new Object(-1, 'fail_to_move'); + + $msg_code = 'success_moved'; + + } elseif($type == 'copy') { + if(!$module_srl) return new Object(-1, 'fail_to_move'); + + $output = $oDocumentAdminController->copyDocumentModule($document_srl_list, $module_srl, $category_srl); + if(!$output->toBool()) return new Object(-1, 'fail_to_move'); + + $msg_code = 'success_registed'; + + } elseif($type =='delete') { + $oDB = &DB::getInstance(); + $oDB->begin(); + for($i=0;$i<$document_srl_count;$i++) { + $document_srl = $document_srl_list[$i]; + $output = $this->deleteDocument($document_srl, true); + if(!$output->toBool()) return new Object(-1, 'fail_to_delete'); + } + $oDB->commit(); + $msg_code = 'success_deleted'; + } elseif($type == 'trash') { + $args->description = $message_content; + + $oDB = &DB::getInstance(); + $oDB->begin(); + for($i=0;$i<$document_srl_count;$i++) { + $args->document_srl = $document_srl_list[$i]; + $output = $this->moveDocumentToTrash($args); + if(!$output || !$output->toBool()) return new Object(-1, 'fail_to_trash'); + } + $oDB->commit(); + $msg_code = 'success_trashed'; + } + + $_SESSION['document_management'] = array(); + + $this->setMessage($msg_code); + } + + function procDocumentInsertModuleConfig() + { + $module_srl = Context::get('target_module_srl'); + if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); + else $module_srl = array($module_srl); + + $document_config = null; + $document_config->use_history = Context::get('use_history'); + if(!$document_config->use_history) $document_config->use_history = 'N'; + + $oModuleController = &getController('module'); + for($i=0;$iinsertModulePartConfig('document',$srl,$document_config); + } + $this->setError(-1); + $this->setMessage('success_updated'); + } + } +?> diff --git a/modules/document/document.item.php b/modules/document/document.item.php index 5d3721f6d..269892a89 100644 --- a/modules/document/document.item.php +++ b/modules/document/document.item.php @@ -1,7 +1,7 @@ $val) { - if(!$val->document_srl || $checked_documents[$val->document_srl]) continue; - $checked_documents[$val->document_srl] = true; - $document_srls[] = $val->document_srl; - } - - // 검출된 문서 번호가 없으면 return - if(!count($document_srls)) return; - - // 확장변수 미지정된 문서에 대해서 일단 현재 접속자의 언어코드로 확장변수를 검색 - $obj->document_srl = implode(',',$document_srls); - $output = executeQueryArray('document.getDocumentExtraVars', $obj); - if($output->toBool() && $output->data) { - foreach($output->data as $key => $val) { - if(!isset($val->value)) continue; - if(!$extra_vars[$val->module_srl][$val->document_srl][$val->var_idx][0]) $extra_vars[$val->module_srl][$val->document_srl][$val->var_idx][0] = trim($val->value); - $extra_vars[$val->document_srl][$val->var_idx][$val->lang_code] = trim($val->value); - } - } - - $user_lang_code = Context::getLangType(); - for($i=0,$c=count($document_srls);$i<$c;$i++) { - $document_srl = $document_srls[$i]; - unset($vars); - - if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl] || !is_object($GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) || !$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->isExists()) continue; - - $module_srl = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->get('module_srl'); - $extra_keys = $this->getExtraKeys($module_srl); - $vars = $extra_vars[$document_srl]; - $document_lang_code = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->get('lang_code'); - - // 확장변수 처리 - if(count($extra_keys)) { - foreach($extra_keys as $idx => $key) { - $val = $vars[$idx]; - if(isset($val[$user_lang_code])) $v = $val[$user_lang_code]; - else if(isset($val[$document_lang_code])) $v = $val[$document_lang_code]; - else if(isset($val[0])) $v = $val[0]; - else $v = null; - $extra_keys[$idx]->value = $v; - } - } - - unset($evars); - $evars = new ExtraVar($module_srl); - $evars->setExtraVarKeys($extra_keys); - - // 제목 처리 - if($vars[-1][$user_lang_code]) $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->add('title',$vars[-1][$user_lang_code]); - - // 내용 처리 - if($vars[-2][$user_lang_code]) $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->add('content',$vars[-2][$user_lang_code]); - - $GLOBALS['XE_EXTRA_VARS'][$document_srl] = $evars->getExtraVars(); - } - } - - /** - * @brief 문서 가져오기 - **/ - function getDocument($document_srl=0, $is_admin = false, $load_extra_vars=true) { - if(!$document_srl) return new documentItem(); - - if(!isset($GLOBALS['XE_DOCUMENT_LIST'][$document_srl])) { - $oDocument = new documentItem($document_srl, true); - $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; - if($load_extra_vars) $this->setToAllDocumentExtraVars(); - } - if($is_admin) $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->setGrant(); - - return $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; - } - - /** - * @brief 여러개의 문서들을 가져옴 (페이징 아님) - **/ - function getDocuments($document_srls, $is_admin = false, $load_extra_vars=true) { - if(is_array($document_srls)) { - $list_count = count($document_srls); - $document_srls = implode(',',$document_srls); - } else { - $list_count = 1; - } - $args->document_srls = $document_srls; - $args->list_count = $list_count; - $args->order_type = 'asc'; - - $output = executeQuery('document.getDocuments', $args); - $document_list = $output->data; - if(!$document_list) return; - if(!is_array($document_list)) $document_list = array($document_list); - - $document_count = count($document_list); - foreach($document_list as $key => $attribute) { - $document_srl = $attribute->document_srl; - if(!$document_srl) continue; - - if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) { - $oDocument = null; - $oDocument = new documentItem(); - $oDocument->setAttribute($attribute, false); - if($is_admin) $oDocument->setGrant(); - $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; - } - - $result[$attribute->document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; - } - - if($load_extra_vars) $this->setToAllDocumentExtraVars(); - - $output = null; - if(count($result)) { - foreach($result as $document_srl => $val) { - $output[$document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; - } - } - - return $output; - } - - /** - * @brief module_srl값을 가지는 문서의 목록을 가져옴 - **/ - function getDocumentList($obj, $except_notice = false, $load_extra_vars=true) { - // 정렬 대상과 순서 체크 - if(!in_array($obj->sort_index, array('list_order','regdate','last_update','update_order','readed_count','voted_count','comment_count','trackback_count','uploaded_count','title','category_srl'))) $obj->sort_index = 'list_order'; - if(!in_array($obj->order_type, array('desc','asc'))) $obj->order_type = 'asc'; - - // module_srl 대신 mid가 넘어왔을 경우는 직접 module_srl을 구해줌 - if($obj->mid) { - $oModuleModel = &getModel('module'); - $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); - unset($obj->mid); - } - - // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 - if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); - else $args->module_srl = $obj->module_srl; - - // 제외 module_srl에 대한 검사 - if(is_array($obj->exclude_module_srl)) $args->exclude_module_srl = implode(',', $obj->exclude_module_srl); - else $args->exclude_module_srl = $obj->exclude_module_srl; - - // 변수 체크 - $args->category_srl = $obj->category_srl?$obj->category_srl:null; - $args->sort_index = $obj->sort_index; - $args->order_type = $obj->order_type; - $args->page = $obj->page?$obj->page:1; - $args->list_count = $obj->list_count?$obj->list_count:20; - $args->page_count = $obj->page_count?$obj->page_count:10; - $args->start_date = $obj->start_date?$obj->start_date:null; - $args->end_date = $obj->end_date?$obj->end_date:null; - $args->member_srl = $obj->member_srl; - - // 카테고리가 선택되어 있으면 하부 카테고리까지 모두 조건에 추가 - if($args->category_srl) { - $category_list = $this->getCategoryList($args->module_srl); - $category_info = $category_list[$args->category_srl]; - $category_info->childs[] = $args->category_srl; - $args->category_srl = implode(',',$category_info->childs); - } - - // 기본으로 사용할 query id 지정 (몇가지 검색 옵션에 따라 query id가 변경됨) - $query_id = 'document.getDocumentList'; - - // 내용검색일 경우 document division을 지정하여 검색하기 위한 처리 - $use_division = false; - - // 검색 옵션 정리 - $search_target = $obj->search_target; - $search_keyword = $obj->search_keyword; - if($search_target && $search_keyword) { - switch($search_target) { - case 'title' : - case 'content' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->{"s_".$search_target} = $search_keyword; - $use_division = true; - break; - case 'title_content' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_title = $search_keyword; - $args->s_content = $search_keyword; - $use_division = true; - break; - case 'user_id' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_user_id = $search_keyword; - $args->sort_index = 'documents.'.$args->sort_index; - break; - case 'user_name' : - case 'nick_name' : - case 'email_address' : - case 'homepage' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->{"s_".$search_target} = $search_keyword; - break; - case 'is_notice' : - case 'is_secret' : - if($search_keyword=='N') $args->{"s_".$search_target} = 'N'; - elseif($search_keyword=='Y') $args->{"s_".$search_target} = 'Y'; - else $args->{"s_".$search_target} = ''; - break; - case 'member_srl' : - case 'readed_count' : - case 'voted_count' : - case 'comment_count' : - case 'trackback_count' : - case 'uploaded_count' : - $args->{"s_".$search_target} = (int)$search_keyword; - break; - case 'regdate' : - case 'last_update' : - case 'ipaddress' : - $args->{"s_".$search_target} = $search_keyword; - break; - case 'comment' : - $args->s_comment = $search_keyword; - $query_id = 'document.getDocumentListWithinComment'; - $use_division = true; - break; - case 'tag' : - $args->s_tags = str_replace(' ','%',$search_keyword); - $query_id = 'document.getDocumentListWithinTag'; - break; - default : - if(strpos($search_target,'extra_vars')!==false) { - $args->var_idx = substr($search_target, strlen('extra_vars')); - $args->var_value = str_replace(' ','%',$search_keyword); - $args->sort_index = 'documents.'.$args->sort_index; - $query_id = 'document.getDocumentListWithExtraVars'; - } - break; - } - } - - /** - * division은 list_order의 asc 정렬일때만 사용할 수 있음 - **/ - if($args->sort_index != 'list_order' || $args->order_type != 'asc') $use_division = false; - - /** - * 만약 use_division이 true일 경우 document division을 이용하도록 변경 - **/ - if($use_division) { - // 시작 division - $division = (int)Context::get('division'); - - // division값이 없다면 제일 상위 - if(!$division) { - $division_args->module_srl = $args->module_srl; - $division_args->exclude_module_srl = $args->exclude_module_srl; - $division_args->list_count = 1; - $division_args->sort_index = $args->sort_index; - $division_args->order_type = $args->order_type; - $output = executeQuery("document.getDocumentList", $division_args); - if($output->data) { - $item = array_pop($output->data); - $division = $item->list_order; - } - $division_args = null; - } - - // 마지막 division - $last_division = (int)Context::get('last_division'); - - // 지정된 division에서부터 5000개 후의 division값을 구함 - if(!$last_division) { - $last_division_args->module_srl = $args->module_srl; - $last_division_args->exclude_module_srl = $args->exclude_module_srl; - $last_division_args->list_count = 1; - $last_division_args->sort_index = $args->sort_index; - $last_division_args->order_type = $args->order_type; - $last_division_args->list_order = $division; - $last_division_args->page = 5001; - $output = executeQuery("document.getDocumentDivision", $last_division_args); - if($output->data) { - $item = array_pop($output->data); - $last_division = $item->list_order; - } - - } - - // last_division 이후로 글이 있는지 확인 - if($last_division) { - $last_division_args = null; - $last_division_args->module_srl = $args->module_srl; - $last_division_args->exclude_module_srl = $args->exclude_module_srl; - $last_division_args->list_order = $last_division; - $output = executeQuery("document.getDocumentDivisionCount", $last_division_args); - if($output->data->count<1) $last_division = null; - } - - $args->division = $division; - $args->last_division = $last_division; - Context::set('division', $division); - Context::set('last_division', $last_division); - } - - // document.getDocumentList 쿼리 실행 - // 만약 query_id가 getDocumentListWithinComment 또는 getDocumentListWithinTag일 경우 group by 절 사용 때문에 쿼리를 한번더 수행 - if(in_array($query_id, array('document.getDocumentListWithinComment', 'document.getDocumentListWithinTag'))) { - $group_args = clone($args); - $group_args->sort_index = 'documents.'.$args->sort_index; - $output = executeQueryArray($query_id, $group_args); - if(!$output->toBool()||!count($output->data)) return $output; - - foreach($output->data as $key => $val) { - if($val->document_srl) $target_srls[] = $val->document_srl; - } - - $page_navigation = $output->page_navigation; - $keys = array_keys($output->data); - $virtual_number = $keys[0]; - - $target_args->document_srls = implode(',',$target_srls); - $target_args->list_order = $args->sort_index; - $target_args->order_type = $args->order_type; - $target_args->list_count = $args->list_count; - $target_args->page = 1; - $output = executeQueryArray('document.getDocuments', $target_args); - $output->page_navigation = $page_navigation; - $output->total_count = $page_navigation->total_count; - $output->total_page = $page_navigation->total_page; - $output->page = $page_navigation->cur_page; - } else { - $output = executeQueryArray($query_id, $args); - } - - // 결과가 없거나 오류 발생시 그냥 return - if(!$output->toBool()||!count($output->data)) return $output; - - $idx = 0; - $data = $output->data; - unset($output->data); - - if(!isset($virtual_number)) - { - $keys = array_keys($data); - $virtual_number = $keys[0]; - } - - if($except_notice) { - foreach($data as $key => $attribute) { - if($attribute->is_notice == 'Y') $virtual_number --; - } - } - - foreach($data as $key => $attribute) { - if($except_notice && $attribute->is_notice == 'Y') continue; - $document_srl = $attribute->document_srl; - if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) { - $oDocument = null; - $oDocument = new documentItem(); - $oDocument->setAttribute($attribute, false); - if($is_admin) $oDocument->setGrant(); - $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; - } - - $output->data[$virtual_number] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; - $virtual_number --; - - } - - if($load_extra_vars) $this->setToAllDocumentExtraVars(); - - if(count($output->data)) { - foreach($output->data as $number => $document) { - $output->data[$number] = $GLOBALS['XE_DOCUMENT_LIST'][$document->document_srl]; - } - } - - return $output; - } - - /** - * @brief module_srl값을 가지는 문서의 공지사항만 가져옴 - **/ - function getNoticeList($obj) { - $args->module_srl = $obj->module_srl; - $output = executeQueryArray('document.getNoticeList', $args); - if(!$output->toBool()||!$output->data) return; - - foreach($output->data as $key => $val) { - $document_srl = $val->document_srl; - if(!$document_srl) continue; - - if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) { - $oDocument = null; - $oDocument = new documentItem(); - $oDocument->setAttribute($val, false); - $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; - } - $result->data[$document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; - } - $this->setToAllDocumentExtraVars(); - - foreach($result->data as $document_srl => $val) { - $result->data[$document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; - } - - return $result; - } - - /** - * @brief document의 확장 변수 키값을 가져오는 함수 - * $form_include : 글 작성시에 필요한 확장변수의 input form 추가 여부 - **/ - function getExtraKeys($module_srl) { - if(is_null($GLOBALS['XE_EXTRA_KEYS'][$module_srl])) { - $oExtraVar = &ExtraVar::getInstance($module_srl); - $obj->module_srl = $module_srl; - $obj->sort_index = 'var_idx'; - $obj->order = 'asc'; - $output = executeQueryArray('document.getDocumentExtraKeys', $obj); - $oExtraVar->setExtraVarKeys($output->data); - $keys = $oExtraVar->getExtraVars(); - if(!$keys) $keys = array(); - $GLOBALS['XE_EXTRA_KEYS'][$module_srl] = $keys; - } - - return $GLOBALS['XE_EXTRA_KEYS'][$module_srl]; - } - - /** - * @brief 특정 document의 확장 변수 값을 가져오는 함수 - **/ - function getExtraVars($module_srl, $document_srl) { - if(!isset($GLOBALS['XE_EXTRA_VARS'][$document_srl])) { - // 확장변수 값을 추출하여 세팅 - $oDocument = $this->getDocument($document_srl, false); - $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; - $this->setToAllDocumentExtraVars(); - } - if(is_array($GLOBALS['XE_EXTRA_VARS'][$document_srl])) ksort($GLOBALS['XE_EXTRA_VARS'][$document_srl]); - return $GLOBALS['XE_EXTRA_VARS'][$document_srl]; - } - - /** - * @brief 선택된 게시물의 팝업메뉴 표시 - * - * 인쇄, 스크랩, 추천, 비추천, 신고 기능 추가 - **/ - function getDocumentMenu() { - - // 요청된 게시물 번호와 현재 로그인 정보 구함 - $document_srl = Context::get('target_srl'); - $mid = Context::get('cur_mid'); - $logged_info = Context::get('logged_info'); - $act = Context::get('cur_act'); - - // menu_list 에 "표시할글,target,url" 을 배열로 넣는다 - $menu_list = array(); - - // trigger 호출 - ModuleHandler::triggerCall('document.getDocumentMenu', 'before', $menu_list); - - $oDocumentController = &getController('document'); - - // 회원이어야만 가능한 기능 - if($logged_info->member_srl) { - - // 추천 버튼 추가 - $url = sprintf("doCallModuleAction('document','procDocumentVoteUp','%s')", $document_srl); - $oDocumentController->addDocumentPopupMenu($url,'cmd_vote','./modules/document/tpl/icons/vote_up.gif','javascript'); - - // 비추천 버튼 추가 - $url= sprintf("doCallModuleAction('document','procDocumentVoteDown','%s')", $document_srl); - $oDocumentController->addDocumentPopupMenu($url,'cmd_vote_down','./modules/document/tpl/icons/vote_down.gif','javascript'); - - // 신고 기능 추가 - $url = sprintf("doCallModuleAction('document','procDocumentDeclare','%s')", $document_srl); - $oDocumentController->addDocumentPopupMenu($url,'cmd_declare','./modules/document/tpl/icons/declare.gif','javascript'); - - // 스크랩 버튼 추가 - $url = sprintf("doCallModuleAction('member','procMemberScrapDocument','%s')", $document_srl); - $oDocumentController->addDocumentPopupMenu($url,'cmd_scrap','./modules/document/tpl/icons/scrap.gif','javascript'); - } - - // 인쇄 버튼 추가 - $url = getUrl('','module','document','act','dispDocumentPrint','document_srl',$document_srl); - $oDocumentController->addDocumentPopupMenu($url,'cmd_print','./modules/document/tpl/icons/print.gif','printDocument'); - - // trigger 호출 (after) - ModuleHandler::triggerCall('document.getDocumentMenu', 'after', $menu_list); - - // 관리자일 경우 ip로 글 찾기 - if($logged_info->is_admin == 'Y') { - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); - - if($oDocument->isExists()) { - // ip주소에 해당하는 글 찾기 - $url = getUrl('','module','admin','act','dispDocumentAdminList','search_target','ipaddress','search_keyword',$oDocument->get('ipaddress')); - $icon_path = './modules/member/tpl/images/icon_management.gif'; - $oDocumentController->addDocumentPopupMenu($url,'cmd_search_by_ipaddress',$icon_path,'TraceByIpaddress'); - - $url = sprintf("var params = new Array(); params['ipaddress']='%s'; exec_xml('spamfilter', 'procSpamfilterAdminInsertDeniedIP', params, completeCallModuleAction)", $oDocument-> getIpAddress()); - $oDocumentController->addDocumentPopupMenu($url,'cmd_add_ip_to_spamfilter','./modules/document/tpl/icons/declare.gif','javascript'); - } - } - - // 팝업메뉴의 언어 변경 - $menus = Context::get('document_popup_menu_list'); - $menus_count = count($menus); - for($i=0;$i<$menus_count;$i++) { - $menus[$i]->str = Context::getLang($menus[$i]->str); - } - - // 최종적으로 정리된 팝업메뉴 목록을 구함 - $this->add('menus', $menus); - } - - /** - * @brief module_srl에 해당하는 문서의 전체 갯수를 가져옴 - **/ - function getDocumentCount($module_srl, $search_obj = NULL) { - // 검색 옵션 추가 - $args->module_srl = $module_srl; - $args->s_title = $search_obj->s_title; - $args->s_content = $search_obj->s_content; - $args->s_user_name = $search_obj->s_user_name; - $args->s_member_srl = $search_obj->s_member_srl; - $args->s_ipaddress = $search_obj->s_ipaddress; - $args->s_regdate = $search_obj->s_regdate; - $args->category_srl = $search_obj->category_srl; - - $output = executeQuery('document.getDocumentCount', $args); - - // 전체 갯수를 return - $total_count = $output->data->count; - return (int)$total_count; - } - /** - * @brief 해당 document의 page 가져오기, module_srl이 없으면 전체에서.. - **/ - function getDocumentPage($oDocument, $opt) { - // 정렬 형식에 따라서 query args 변경 - switch($opt->sort_index) { - case 'update_order' : - if($opt->order_type == 'desc') $args->rev_update_order = $oDocument->get('update_order'); - else $args->update_order = $oDocument->get('update_order'); - break; - case 'regdate' : - if($opt->order_type == 'asc') $args->rev_regdate = $oDocument->get('regdate'); - else $args->regdate = $oDocument->get('regdate'); - break; - case 'voted_count' : - case 'readed_count' : - case 'comment_count' : - case 'title' : - return 1; - break; - default : - if($opt->order_type == 'desc') $args->rev_list_order = $oDocument->get('list_order'); - else $args->list_order = $oDocument->get('list_order'); - break; - } - $args->module_srl = $oDocument->get('module_srl'); - $args->sort_index = $opt->sort_index; - $args->order_type = $opt->order_type; - - // 전체 갯수를 구한후 해당 글의 페이지를 검색 - $output = executeQuery('document.getDocumentPage', $args); - $count = $output->data->count; - $page = (int)(($count-1)/$opt->list_count)+1; - return $page; - } - - /** - * @brief 카테고리의 정보를 가져옴 - **/ - function getCategory($category_srl) { - $args->category_srl = $category_srl; - $output = executeQuery('document.getCategory', $args); - - $node = $output->data; - if(!$node) return; - - if($node->group_srls) { - $group_srls = explode(',',$node->group_srls); - unset($node->group_srls); - $node->group_srls = $group_srls; - } else { - unset($node->group_srls); - $node->group_srls = array(); - } - return $node; - } - - /** - * @brief 특정 카테고리에 child가 있는지 체크 - **/ - function getCategoryChlidCount($category_srl) { - $args->category_srl = $category_srl; - $output = executeQuery('document.getChildCategoryCount',$args); - if($output->data->count > 0) return true; - return false; - } - - /** - * @brief 특정 모듈의 카테고리 목록을 가져옴 - * 속도나 여러가지 상황을 고려해서 카테고리 목록은 php로 생성된 script를 include하여 사용하는 것을 원칙으로 함 - **/ - function getCategoryList($module_srl) { - // 대상 모듈의 카테고리 파일을 불러옴 - $filename = sprintf("./files/cache/document_category/%s.php", $module_srl); - - // 대상 파일이 없으면 카테고리 캐시 파일을 재생성 - if(!file_exists($filename)) { - $oDocumentController = &getController('document'); - if(!$oDocumentController->makeCategoryFile($module_srl)) return array(); - } - - @include($filename); - - // 카테고리의 정리 - $document_category = array(); - $this->_arrangeCategory($document_category, $menu->list, 0); - return $document_category; - } - - /** - * @brief 카테고리를 1차 배열 형식으로 변경하는 내부 method - **/ - function _arrangeCategory(&$document_category, $list, $depth) { - if(!count($list)) return; - $idx = 0; - $list_order = array(); - foreach($list as $key => $val) { - $obj = null; - $obj->mid = $val['mid']; - $obj->module_srl = $val['module_srl']; - $obj->category_srl = $val['category_srl']; - $obj->parent_srl = $val['parent_srl']; - $obj->title = $obj->text = $val['text']; - $obj->expand = $val['expand']=='Y'?true:false; - $obj->color = $val['color']; - $obj->document_count = $val['document_count']; - $obj->depth = $depth; - $obj->child_count = 0; - $obj->childs = array(); - $obj->grant = $val['grant']; - - if(Context::get('mid') == $obj->mid && Context::get('category') == $obj->category_srl) $selected = true; - else $selected = false; - - $obj->selected = $selected; - - $list_order[$idx++] = $obj->category_srl; - - // 부모 카테고리가 있으면 자식노드들의 데이터를 적용 - if($obj->parent_srl) { - - $parent_srl = $obj->parent_srl; - $document_count = $obj->document_count; - $expand = $obj->expand; - if($selected) $expand = true; - - while($parent_srl) { - $document_category[$parent_srl]->document_count += $document_count; - $document_category[$parent_srl]->childs[] = $obj->category_srl; - $document_category[$parent_srl]->child_count = count($document_category[$parent_srl]->childs); - if($expand) $document_category[$parent_srl]->expand = $expand; - - $parent_srl = $document_category[$parent_srl]->parent_srl; - } - } - - $document_category[$key] = $obj; - - if(count($val['list'])) $this->_arrangeCategory($document_category, $val['list'], $depth+1); - } - $document_category[$list_order[0]]->first = true; - $document_category[$list_order[count($list_order)-1]]->last = true; - } - - /** - * @brief 카테고리에 속한 문서의 갯수를 구함 - **/ - function getCategoryDocumentCount($module_srl, $category_srl) { - $args->module_srl = $module_srl; - $args->category_srl = $category_srl; - $output = executeQuery('document.getCategoryDocumentCount', $args); - return (int)$output->data->count; - } - - /** - * @brief 문서 category정보의 xml 캐시 파일을 return - **/ - function getCategoryXmlFile($module_srl) { - $xml_file = sprintf('files/cache/document_category/%s.xml.php',$module_srl); - if(!file_exists($xml_file)) { - $oDocumentController = &getController('document'); - $oDocumentController->makeCategoryFile($module_srl); - } - return $xml_file; - } - - /** - * @brief 문서 category정보의 php 캐시 파일을 return - **/ - function getCategoryPhpFile($module_srl) { - $php_file = sprintf('files/cache/document_category/%s.php',$module_srl); - if(!file_exists($php_file)) { - $oDocumentController = &getController('document'); - $oDocumentController->makeCategoryFile($module_srl); - } - return $php_file; - } - - /** - * @brief 월별 글 보관현황을 가져옴 - **/ - function getMonthlyArchivedList($obj) { - if($obj->mid) { - $oModuleModel = &getModel('module'); - $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); - unset($obj->mid); - } - - // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 - if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); - else $args->module_srl = $obj->module_srl; - - $output = executeQuery('document.getMonthlyArchivedList', $args); - if(!$output->toBool()||!$output->data) return $output; - - if(!is_array($output->data)) $output->data = array($output->data); - - return $output; - } - - /** - * @brief 특정달의 일별 글 현황을 가져옴 - **/ - function getDailyArchivedList($obj) { - if($obj->mid) { - $oModuleModel = &getModel('module'); - $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); - unset($obj->mid); - } - - // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 - if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); - else $args->module_srl = $obj->module_srl; - $args->regdate = $obj->regdate; - - $output = executeQuery('document.getDailyArchivedList', $args); - if(!$output->toBool()) return $output; - - if(!is_array($output->data)) $output->data = array($output->data); - - return $output; - } - - /** - * @brief 특정 모듈의 분류를 구함 - **/ - function getDocumentCategories() { - if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted'); - $module_srl = Context::get('module_srl'); - $categories= $this->getCategoryList($module_srl); - $lang = Context::get('lang'); - - // 분류 없음 추가 - $output = "0,0,{$lang->none_category}\n"; - if($categories){ - foreach($categories as $category_srl => $category) { - $output .= sprintf("%d,%d,%s\n",$category_srl, $category->depth,$category->title); - } - } - $this->add('categories', $output); - } - - /** - * @brief 문서 설정 정보를 구함 - **/ - function getDocumentConfig() { - if(!$GLOBALS['__document_config__']) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('document'); - if(!$config->thumbnail_type) $config->thumbnail_type = 'crop'; - $GLOBALS['__document_config__'] = $config; - } - return $GLOBALS['__document_config__']; - } - - /** - * @brief 공통 :: 모듈의 확장 변수 관리 - * 모듈의 확장변수 관리는 모든 모듈에서 document module instance를 이용할때 사용할 수 있음 - **/ - function getExtraVarsHTML($module_srl) { - // 기존의 extra_keys 가져옴 - $extra_keys = $this->getExtraKeys($module_srl); - Context::set('extra_keys', $extra_keys); - - // grant 정보를 추출 - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($this->module_path.'tpl', 'extra_keys'); - } - - /** - * @brief 공통 :: 모듈의 카테고리 변수 관리 - **/ - function getCategoryHTML($module_srl) { - $category_xml_file = $this->getCategoryXmlFile($module_srl); - - Context::set('category_xml_file', $category_xml_file); - - Context::loadJavascriptPlugin('ui.tree'); - // grant 정보를 추출 - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($this->module_path.'tpl', 'category_list'); - } - - /** - * @brief 특정 카테고리의 정보를 이용하여 템플릿을 구한후 return - * 관리자 페이지에서 특정 메뉴의 정보를 추가하기 위해 서버에서 tpl을 컴파일 한후 컴파일 된 html을 직접 return - **/ - function getDocumentCategoryTplInfo() { - $oModuleModel = &getModel('module'); - $oMemberModel = &getModel('member'); - - // 해당 메뉴의 정보를 가져오기 위한 변수 설정 - $module_srl = Context::get('module_srl'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - - // 권한 체크 - $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); - if(!$grant->manager) return new Object(-1,'msg_not_permitted'); - - $category_srl = Context::get('category_srl'); - $parent_srl = Context::get('parent_srl'); - - // 회원 그룹의 목록을 가져옴 - $group_list = $oMemberModel->getGroups($module_info->site_srl); - Context::set('group_list', $group_list); - - // parent_srl이 있고 category_srl 이 없으면 하부 메뉴 추가임 - if(!$category_srl && $parent_srl) { - // 상위 메뉴의 정보를 가져옴 - $parent_info = $this->getCategory($parent_srl); - - // 추가하려는 메뉴의 기본 변수 설정 - $category_info->category_srl = getNextSequence(); - $category_info->parent_srl = $parent_srl; - $category_info->parent_category_title = $parent_info->title; - - // root에 메뉴 추가하거나 기존 메뉴의 수정일 경우 - } else { - // category_srl 이 있으면 해당 메뉴의 정보를 가져온다 - if($category_srl) $category_info = $this->getCategory($category_srl); - - // 찾아진 값이 없다면 신규 메뉴 추가로 보고 category_srl값만 구해줌 - if(!$category_info->category_srl) { - $category_info->category_srl = getNextSequence(); - } - } - - - $category_info->title = htmlspecialchars($category_info->title); - Context::set('category_info', $category_info); - - // template 파일을 직접 컴파일한후 tpl변수에 담아서 return한다. - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile('./modules/document/tpl', 'category_info'); - $tpl = str_replace("\n",'',$tpl); - - // 사용자 정의 언어 변경 - $oModuleController = &getController('module'); - $oModuleController->replaceDefinedLangCode($tpl); - - // return 할 변수 설정 - $this->add('tpl', $tpl); - } - - - function getDocumentSrlByAlias($mid, $alias) - { - if(!$mid || !$alias) return null; - $site_module_info = Context::get('site_module_info'); - $args->mid = $mid; - $args->alias_title = $alias; - $args->site_srl = $site_module_info->site_srl; - $output = executeQuery('document.getDocumentSrlByAlias', $args); - if(!$output->data) return null; - else return $output->data->document_srl; - } - - function getAlias($document_srl){ - if(!$document_srl) return null; - $args->document_srl = $document_srl; - $output = executeQueryArray('document.getAliases', $args); - - if(!$output->data) return null; - else return $output->data[0]->alias_title; - } - - function getHistories($document_srl, $list_count, $page) - { - $args->list_count = $list_count; - $args->page = $page; - $args->document_srl = $document_srl; - $output = executeQueryArray('document.getHistories', $args); - return $output; - } - - function getHistory($history_srl) - { - $args->history_srl = $history_srl; - $output = executeQuery('document.getHistory', $args); - return $output->data; - } - - /** - * @brief module_srl값을 가지는 문서의 목록을 가져옴 - **/ - function getTrashList($obj) { - - // 변수 체크 - $args->category_srl = $obj->category_srl?$obj->category_srl:null; - $args->sort_index = $obj->sort_index; - $args->order_type = $obj->order_type?$obj->order_type:'desc'; - $args->page = $obj->page?$obj->page:1; - $args->list_count = $obj->list_count?$obj->list_count:20; - $args->page_count = $obj->page_count?$obj->page_count:10; - - - // 검색 옵션 정리 - $search_target = $obj->search_target; - $search_keyword = $obj->search_keyword; - if($search_target && $search_keyword) { - switch($search_target) { - case 'title' : - case 'content' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->{"s_".$search_target} = $search_keyword; - $use_division = true; - break; - case 'title_content' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_title = $search_keyword; - $args->s_content = $search_keyword; - break; - case 'user_id' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_user_id = $search_keyword; - $args->sort_index = 'documents.'.$args->sort_index; - break; - case 'user_name' : - case 'nick_name' : - case 'email_address' : - case 'homepage' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->{"s_".$search_target} = $search_keyword; - break; - case 'is_notice' : - case 'is_secret' : - if($search_keyword=='N') $args->{"s_".$search_target} = 'N'; - elseif($search_keyword=='Y') $args->{"s_".$search_target} = 'Y'; - else $args->{"s_".$search_target} = ''; - break; - case 'member_srl' : - case 'readed_count' : - case 'voted_count' : - case 'comment_count' : - case 'trackback_count' : - case 'uploaded_count' : - $args->{"s_".$search_target} = (int)$search_keyword; - break; - case 'regdate' : - case 'last_update' : - case 'ipaddress' : - case 'tag' : - $args->{"s_".$search_target} = $search_keyword; - break; - } - } - - - $output = executeQueryArray('document.getTrashList', $args); - if($output->data){ - foreach($output->data as $key => $attribute) { - $oDocument = null; - $oDocument = new documentItem(); - $oDocument->setAttribute($attribute, false); - $attribute = $oDocument; - } - } - return $output; - } - - } -?> + $val) { + if(!$val->document_srl || $checked_documents[$val->document_srl]) continue; + $checked_documents[$val->document_srl] = true; + $document_srls[] = $val->document_srl; + } + + // 검출된 문서 번호가 없으면 return + if(!count($document_srls)) return; + + // 확장변수 미지정된 문서에 대해서 일단 현재 접속자의 언어코드로 확장변수를 검색 + $obj->document_srl = implode(',',$document_srls); + $output = executeQueryArray('document.getDocumentExtraVars', $obj); + if($output->toBool() && $output->data) { + foreach($output->data as $key => $val) { + if(!isset($val->value)) continue; + if(!$extra_vars[$val->module_srl][$val->document_srl][$val->var_idx][0]) $extra_vars[$val->module_srl][$val->document_srl][$val->var_idx][0] = trim($val->value); + $extra_vars[$val->document_srl][$val->var_idx][$val->lang_code] = trim($val->value); + } + } + + $user_lang_code = Context::getLangType(); + for($i=0,$c=count($document_srls);$i<$c;$i++) { + $document_srl = $document_srls[$i]; + unset($vars); + + if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl] || !is_object($GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) || !$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->isExists()) continue; + + $module_srl = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->get('module_srl'); + $extra_keys = $this->getExtraKeys($module_srl); + $vars = $extra_vars[$document_srl]; + $document_lang_code = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->get('lang_code'); + + // 확장변수 처리 + if(count($extra_keys)) { + foreach($extra_keys as $idx => $key) { + $val = $vars[$idx]; + if(isset($val[$user_lang_code])) $v = $val[$user_lang_code]; + else if(isset($val[$document_lang_code])) $v = $val[$document_lang_code]; + else if(isset($val[0])) $v = $val[0]; + else $v = null; + $extra_keys[$idx]->value = $v; + } + } + + unset($evars); + $evars = new ExtraVar($module_srl); + $evars->setExtraVarKeys($extra_keys); + + // 제목 처리 + if($vars[-1][$user_lang_code]) $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->add('title',$vars[-1][$user_lang_code]); + + // 내용 처리 + if($vars[-2][$user_lang_code]) $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->add('content',$vars[-2][$user_lang_code]); + + $GLOBALS['XE_EXTRA_VARS'][$document_srl] = $evars->getExtraVars(); + } + } + + /** + * @brief 문서 가져오기 + **/ + function getDocument($document_srl=0, $is_admin = false, $load_extra_vars=true) { + if(!$document_srl) return new documentItem(); + + if(!isset($GLOBALS['XE_DOCUMENT_LIST'][$document_srl])) { + $oDocument = new documentItem($document_srl, true); + $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; + if($load_extra_vars) $this->setToAllDocumentExtraVars(); + } + if($is_admin) $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]->setGrant(); + + return $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; + } + + /** + * @brief 여러개의 문서들을 가져옴 (페이징 아님) + **/ + function getDocuments($document_srls, $is_admin = false, $load_extra_vars=true) { + if(is_array($document_srls)) { + $list_count = count($document_srls); + $document_srls = implode(',',$document_srls); + } else { + $list_count = 1; + } + $args->document_srls = $document_srls; + $args->list_count = $list_count; + $args->order_type = 'asc'; + + $output = executeQuery('document.getDocuments', $args); + $document_list = $output->data; + if(!$document_list) return; + if(!is_array($document_list)) $document_list = array($document_list); + + $document_count = count($document_list); + foreach($document_list as $key => $attribute) { + $document_srl = $attribute->document_srl; + if(!$document_srl) continue; + + if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) { + $oDocument = null; + $oDocument = new documentItem(); + $oDocument->setAttribute($attribute, false); + if($is_admin) $oDocument->setGrant(); + $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; + } + + $result[$attribute->document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; + } + + if($load_extra_vars) $this->setToAllDocumentExtraVars(); + + $output = null; + if(count($result)) { + foreach($result as $document_srl => $val) { + $output[$document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; + } + } + + return $output; + } + + /** + * @brief module_srl값을 가지는 문서의 목록을 가져옴 + **/ + function getDocumentList($obj, $except_notice = false, $load_extra_vars=true) { + // 정렬 대상과 순서 체크 + if(!in_array($obj->sort_index, array('list_order','regdate','last_update','update_order','readed_count','voted_count','comment_count','trackback_count','uploaded_count','title','category_srl'))) $obj->sort_index = 'list_order'; + if(!in_array($obj->order_type, array('desc','asc'))) $obj->order_type = 'asc'; + + // module_srl 대신 mid가 넘어왔을 경우는 직접 module_srl을 구해줌 + if($obj->mid) { + $oModuleModel = &getModel('module'); + $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); + unset($obj->mid); + } + + // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 + if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); + else $args->module_srl = $obj->module_srl; + + // 제외 module_srl에 대한 검사 + if(is_array($obj->exclude_module_srl)) $args->exclude_module_srl = implode(',', $obj->exclude_module_srl); + else $args->exclude_module_srl = $obj->exclude_module_srl; + + // 변수 체크 + $args->category_srl = $obj->category_srl?$obj->category_srl:null; + $args->sort_index = $obj->sort_index; + $args->order_type = $obj->order_type; + $args->page = $obj->page?$obj->page:1; + $args->list_count = $obj->list_count?$obj->list_count:20; + $args->page_count = $obj->page_count?$obj->page_count:10; + $args->start_date = $obj->start_date?$obj->start_date:null; + $args->end_date = $obj->end_date?$obj->end_date:null; + $args->member_srl = $obj->member_srl; + + // 카테고리가 선택되어 있으면 하부 카테고리까지 모두 조건에 추가 + if($args->category_srl) { + $category_list = $this->getCategoryList($args->module_srl); + $category_info = $category_list[$args->category_srl]; + $category_info->childs[] = $args->category_srl; + $args->category_srl = implode(',',$category_info->childs); + } + + // 기본으로 사용할 query id 지정 (몇가지 검색 옵션에 따라 query id가 변경됨) + $query_id = 'document.getDocumentList'; + + // 내용검색일 경우 document division을 지정하여 검색하기 위한 처리 + $use_division = false; + + // 검색 옵션 정리 + $search_target = $obj->search_target; + $search_keyword = $obj->search_keyword; + if($search_target && $search_keyword) { + switch($search_target) { + case 'title' : + case 'content' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->{"s_".$search_target} = $search_keyword; + $use_division = true; + break; + case 'title_content' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_title = $search_keyword; + $args->s_content = $search_keyword; + $use_division = true; + break; + case 'user_id' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_user_id = $search_keyword; + $args->sort_index = 'documents.'.$args->sort_index; + break; + case 'user_name' : + case 'nick_name' : + case 'email_address' : + case 'homepage' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->{"s_".$search_target} = $search_keyword; + break; + case 'is_notice' : + case 'is_secret' : + if($search_keyword=='N') $args->{"s_".$search_target} = 'N'; + elseif($search_keyword=='Y') $args->{"s_".$search_target} = 'Y'; + else $args->{"s_".$search_target} = ''; + break; + case 'member_srl' : + case 'readed_count' : + case 'voted_count' : + case 'comment_count' : + case 'trackback_count' : + case 'uploaded_count' : + $args->{"s_".$search_target} = (int)$search_keyword; + break; + case 'regdate' : + case 'last_update' : + case 'ipaddress' : + $args->{"s_".$search_target} = $search_keyword; + break; + case 'comment' : + $args->s_comment = $search_keyword; + $query_id = 'document.getDocumentListWithinComment'; + $use_division = true; + break; + case 'tag' : + $args->s_tags = str_replace(' ','%',$search_keyword); + $query_id = 'document.getDocumentListWithinTag'; + break; + default : + if(strpos($search_target,'extra_vars')!==false) { + $args->var_idx = substr($search_target, strlen('extra_vars')); + $args->var_value = str_replace(' ','%',$search_keyword); + $args->sort_index = 'documents.'.$args->sort_index; + $query_id = 'document.getDocumentListWithExtraVars'; + } + break; + } + } + + /** + * division은 list_order의 asc 정렬일때만 사용할 수 있음 + **/ + if($args->sort_index != 'list_order' || $args->order_type != 'asc') $use_division = false; + + /** + * 만약 use_division이 true일 경우 document division을 이용하도록 변경 + **/ + if($use_division) { + // 시작 division + $division = (int)Context::get('division'); + + // division값이 없다면 제일 상위 + if(!$division) { + $division_args->module_srl = $args->module_srl; + $division_args->exclude_module_srl = $args->exclude_module_srl; + $division_args->list_count = 1; + $division_args->sort_index = $args->sort_index; + $division_args->order_type = $args->order_type; + $output = executeQuery("document.getDocumentList", $division_args); + if($output->data) { + $item = array_pop($output->data); + $division = $item->list_order; + } + $division_args = null; + } + + // 마지막 division + $last_division = (int)Context::get('last_division'); + + // 지정된 division에서부터 5000개 후의 division값을 구함 + if(!$last_division) { + $last_division_args->module_srl = $args->module_srl; + $last_division_args->exclude_module_srl = $args->exclude_module_srl; + $last_division_args->list_count = 1; + $last_division_args->sort_index = $args->sort_index; + $last_division_args->order_type = $args->order_type; + $last_division_args->list_order = $division; + $last_division_args->page = 5001; + $output = executeQuery("document.getDocumentDivision", $last_division_args); + if($output->data) { + $item = array_pop($output->data); + $last_division = $item->list_order; + } + + } + + // last_division 이후로 글이 있는지 확인 + if($last_division) { + $last_division_args = null; + $last_division_args->module_srl = $args->module_srl; + $last_division_args->exclude_module_srl = $args->exclude_module_srl; + $last_division_args->list_order = $last_division; + $output = executeQuery("document.getDocumentDivisionCount", $last_division_args); + if($output->data->count<1) $last_division = null; + } + + $args->division = $division; + $args->last_division = $last_division; + Context::set('division', $division); + Context::set('last_division', $last_division); + } + + // document.getDocumentList 쿼리 실행 + // 만약 query_id가 getDocumentListWithinComment 또는 getDocumentListWithinTag일 경우 group by 절 사용 때문에 쿼리를 한번더 수행 + if(in_array($query_id, array('document.getDocumentListWithinComment', 'document.getDocumentListWithinTag'))) { + $group_args = clone($args); + $group_args->sort_index = 'documents.'.$args->sort_index; + $output = executeQueryArray($query_id, $group_args); + if(!$output->toBool()||!count($output->data)) return $output; + + foreach($output->data as $key => $val) { + if($val->document_srl) $target_srls[] = $val->document_srl; + } + + $page_navigation = $output->page_navigation; + $keys = array_keys($output->data); + $virtual_number = $keys[0]; + + $target_args->document_srls = implode(',',$target_srls); + $target_args->list_order = $args->sort_index; + $target_args->order_type = $args->order_type; + $target_args->list_count = $args->list_count; + $target_args->page = 1; + $output = executeQueryArray('document.getDocuments', $target_args); + $output->page_navigation = $page_navigation; + $output->total_count = $page_navigation->total_count; + $output->total_page = $page_navigation->total_page; + $output->page = $page_navigation->cur_page; + } else { + $output = executeQueryArray($query_id, $args); + } + + // 결과가 없거나 오류 발생시 그냥 return + if(!$output->toBool()||!count($output->data)) return $output; + + $idx = 0; + $data = $output->data; + unset($output->data); + + if(!isset($virtual_number)) + { + $keys = array_keys($data); + $virtual_number = $keys[0]; + } + + if($except_notice) { + foreach($data as $key => $attribute) { + if($attribute->is_notice == 'Y') $virtual_number --; + } + } + + foreach($data as $key => $attribute) { + if($except_notice && $attribute->is_notice == 'Y') continue; + $document_srl = $attribute->document_srl; + if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) { + $oDocument = null; + $oDocument = new documentItem(); + $oDocument->setAttribute($attribute, false); + if($is_admin) $oDocument->setGrant(); + $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; + } + + $output->data[$virtual_number] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; + $virtual_number --; + + } + + if($load_extra_vars) $this->setToAllDocumentExtraVars(); + + if(count($output->data)) { + foreach($output->data as $number => $document) { + $output->data[$number] = $GLOBALS['XE_DOCUMENT_LIST'][$document->document_srl]; + } + } + + return $output; + } + + /** + * @brief module_srl값을 가지는 문서의 공지사항만 가져옴 + **/ + function getNoticeList($obj) { + $args->module_srl = $obj->module_srl; + $output = executeQueryArray('document.getNoticeList', $args); + if(!$output->toBool()||!$output->data) return; + + foreach($output->data as $key => $val) { + $document_srl = $val->document_srl; + if(!$document_srl) continue; + + if(!$GLOBALS['XE_DOCUMENT_LIST'][$document_srl]) { + $oDocument = null; + $oDocument = new documentItem(); + $oDocument->setAttribute($val, false); + $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; + } + $result->data[$document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; + } + $this->setToAllDocumentExtraVars(); + + foreach($result->data as $document_srl => $val) { + $result->data[$document_srl] = $GLOBALS['XE_DOCUMENT_LIST'][$document_srl]; + } + + return $result; + } + + /** + * @brief document의 확장 변수 키값을 가져오는 함수 + * $form_include : 글 작성시에 필요한 확장변수의 input form 추가 여부 + **/ + function getExtraKeys($module_srl) { + if(is_null($GLOBALS['XE_EXTRA_KEYS'][$module_srl])) { + $oExtraVar = &ExtraVar::getInstance($module_srl); + $obj->module_srl = $module_srl; + $obj->sort_index = 'var_idx'; + $obj->order = 'asc'; + $output = executeQueryArray('document.getDocumentExtraKeys', $obj); + $oExtraVar->setExtraVarKeys($output->data); + $keys = $oExtraVar->getExtraVars(); + if(!$keys) $keys = array(); + $GLOBALS['XE_EXTRA_KEYS'][$module_srl] = $keys; + } + + return $GLOBALS['XE_EXTRA_KEYS'][$module_srl]; + } + + /** + * @brief 특정 document의 확장 변수 값을 가져오는 함수 + **/ + function getExtraVars($module_srl, $document_srl) { + if(!isset($GLOBALS['XE_EXTRA_VARS'][$document_srl])) { + // 확장변수 값을 추출하여 세팅 + $oDocument = $this->getDocument($document_srl, false); + $GLOBALS['XE_DOCUMENT_LIST'][$document_srl] = $oDocument; + $this->setToAllDocumentExtraVars(); + } + if(is_array($GLOBALS['XE_EXTRA_VARS'][$document_srl])) ksort($GLOBALS['XE_EXTRA_VARS'][$document_srl]); + return $GLOBALS['XE_EXTRA_VARS'][$document_srl]; + } + + /** + * @brief 선택된 게시물의 팝업메뉴 표시 + * + * 인쇄, 스크랩, 추천, 비추천, 신고 기능 추가 + **/ + function getDocumentMenu() { + + // 요청된 게시물 번호와 현재 로그인 정보 구함 + $document_srl = Context::get('target_srl'); + $mid = Context::get('cur_mid'); + $logged_info = Context::get('logged_info'); + $act = Context::get('cur_act'); + + // menu_list 에 "표시할글,target,url" 을 배열로 넣는다 + $menu_list = array(); + + // trigger 호출 + ModuleHandler::triggerCall('document.getDocumentMenu', 'before', $menu_list); + + $oDocumentController = &getController('document'); + + // 회원이어야만 가능한 기능 + if($logged_info->member_srl) { + + // 추천 버튼 추가 + $url = sprintf("doCallModuleAction('document','procDocumentVoteUp','%s')", $document_srl); + $oDocumentController->addDocumentPopupMenu($url,'cmd_vote','./modules/document/tpl/icons/vote_up.gif','javascript'); + + // 비추천 버튼 추가 + $url= sprintf("doCallModuleAction('document','procDocumentVoteDown','%s')", $document_srl); + $oDocumentController->addDocumentPopupMenu($url,'cmd_vote_down','./modules/document/tpl/icons/vote_down.gif','javascript'); + + // 신고 기능 추가 + $url = sprintf("doCallModuleAction('document','procDocumentDeclare','%s')", $document_srl); + $oDocumentController->addDocumentPopupMenu($url,'cmd_declare','./modules/document/tpl/icons/declare.gif','javascript'); + + // 스크랩 버튼 추가 + $url = sprintf("doCallModuleAction('member','procMemberScrapDocument','%s')", $document_srl); + $oDocumentController->addDocumentPopupMenu($url,'cmd_scrap','./modules/document/tpl/icons/scrap.gif','javascript'); + } + + // 인쇄 버튼 추가 + $url = getUrl('','module','document','act','dispDocumentPrint','document_srl',$document_srl); + $oDocumentController->addDocumentPopupMenu($url,'cmd_print','./modules/document/tpl/icons/print.gif','printDocument'); + + // trigger 호출 (after) + ModuleHandler::triggerCall('document.getDocumentMenu', 'after', $menu_list); + + // 관리자일 경우 ip로 글 찾기 + if($logged_info->is_admin == 'Y') { + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + if($oDocument->isExists()) { + // ip주소에 해당하는 글 찾기 + $url = getUrl('','module','admin','act','dispDocumentAdminList','search_target','ipaddress','search_keyword',$oDocument->get('ipaddress')); + $icon_path = './modules/member/tpl/images/icon_management.gif'; + $oDocumentController->addDocumentPopupMenu($url,'cmd_search_by_ipaddress',$icon_path,'TraceByIpaddress'); + + $url = sprintf("var params = new Array(); params['ipaddress']='%s'; exec_xml('spamfilter', 'procSpamfilterAdminInsertDeniedIP', params, completeCallModuleAction)", $oDocument-> getIpAddress()); + $oDocumentController->addDocumentPopupMenu($url,'cmd_add_ip_to_spamfilter','./modules/document/tpl/icons/declare.gif','javascript'); + } + } + + // 팝업메뉴의 언어 변경 + $menus = Context::get('document_popup_menu_list'); + $menus_count = count($menus); + for($i=0;$i<$menus_count;$i++) { + $menus[$i]->str = Context::getLang($menus[$i]->str); + } + + // 최종적으로 정리된 팝업메뉴 목록을 구함 + $this->add('menus', $menus); + } + + /** + * @brief module_srl에 해당하는 문서의 전체 갯수를 가져옴 + **/ + function getDocumentCount($module_srl, $search_obj = NULL) { + // 검색 옵션 추가 + $args->module_srl = $module_srl; + $args->s_title = $search_obj->s_title; + $args->s_content = $search_obj->s_content; + $args->s_user_name = $search_obj->s_user_name; + $args->s_member_srl = $search_obj->s_member_srl; + $args->s_ipaddress = $search_obj->s_ipaddress; + $args->s_regdate = $search_obj->s_regdate; + $args->category_srl = $search_obj->category_srl; + + $output = executeQuery('document.getDocumentCount', $args); + + // 전체 갯수를 return + $total_count = $output->data->count; + return (int)$total_count; + } + /** + * @brief 해당 document의 page 가져오기, module_srl이 없으면 전체에서.. + **/ + function getDocumentPage($oDocument, $opt) { + // 정렬 형식에 따라서 query args 변경 + switch($opt->sort_index) { + case 'update_order' : + if($opt->order_type == 'desc') $args->rev_update_order = $oDocument->get('update_order'); + else $args->update_order = $oDocument->get('update_order'); + break; + case 'regdate' : + if($opt->order_type == 'asc') $args->rev_regdate = $oDocument->get('regdate'); + else $args->regdate = $oDocument->get('regdate'); + break; + case 'voted_count' : + case 'readed_count' : + case 'comment_count' : + case 'title' : + return 1; + break; + default : + if($opt->order_type == 'desc') $args->rev_list_order = $oDocument->get('list_order'); + else $args->list_order = $oDocument->get('list_order'); + break; + } + $args->module_srl = $oDocument->get('module_srl'); + $args->sort_index = $opt->sort_index; + $args->order_type = $opt->order_type; + + // 전체 갯수를 구한후 해당 글의 페이지를 검색 + $output = executeQuery('document.getDocumentPage', $args); + $count = $output->data->count; + $page = (int)(($count-1)/$opt->list_count)+1; + return $page; + } + + /** + * @brief 카테고리의 정보를 가져옴 + **/ + function getCategory($category_srl) { + $args->category_srl = $category_srl; + $output = executeQuery('document.getCategory', $args); + + $node = $output->data; + if(!$node) return; + + if($node->group_srls) { + $group_srls = explode(',',$node->group_srls); + unset($node->group_srls); + $node->group_srls = $group_srls; + } else { + unset($node->group_srls); + $node->group_srls = array(); + } + return $node; + } + + /** + * @brief 특정 카테고리에 child가 있는지 체크 + **/ + function getCategoryChlidCount($category_srl) { + $args->category_srl = $category_srl; + $output = executeQuery('document.getChildCategoryCount',$args); + if($output->data->count > 0) return true; + return false; + } + + /** + * @brief 특정 모듈의 카테고리 목록을 가져옴 + * 속도나 여러가지 상황을 고려해서 카테고리 목록은 php로 생성된 script를 include하여 사용하는 것을 원칙으로 함 + **/ + function getCategoryList($module_srl) { + // 대상 모듈의 카테고리 파일을 불러옴 + $filename = sprintf("./files/cache/document_category/%s.php", $module_srl); + + // 대상 파일이 없으면 카테고리 캐시 파일을 재생성 + if(!file_exists($filename)) { + $oDocumentController = &getController('document'); + if(!$oDocumentController->makeCategoryFile($module_srl)) return array(); + } + + @include($filename); + + // 카테고리의 정리 + $document_category = array(); + $this->_arrangeCategory($document_category, $menu->list, 0); + return $document_category; + } + + /** + * @brief 카테고리를 1차 배열 형식으로 변경하는 내부 method + **/ + function _arrangeCategory(&$document_category, $list, $depth) { + if(!count($list)) return; + $idx = 0; + $list_order = array(); + foreach($list as $key => $val) { + $obj = null; + $obj->mid = $val['mid']; + $obj->module_srl = $val['module_srl']; + $obj->category_srl = $val['category_srl']; + $obj->parent_srl = $val['parent_srl']; + $obj->title = $obj->text = $val['text']; + $obj->expand = $val['expand']=='Y'?true:false; + $obj->color = $val['color']; + $obj->document_count = $val['document_count']; + $obj->depth = $depth; + $obj->child_count = 0; + $obj->childs = array(); + $obj->grant = $val['grant']; + + if(Context::get('mid') == $obj->mid && Context::get('category') == $obj->category_srl) $selected = true; + else $selected = false; + + $obj->selected = $selected; + + $list_order[$idx++] = $obj->category_srl; + + // 부모 카테고리가 있으면 자식노드들의 데이터를 적용 + if($obj->parent_srl) { + + $parent_srl = $obj->parent_srl; + $document_count = $obj->document_count; + $expand = $obj->expand; + if($selected) $expand = true; + + while($parent_srl) { + $document_category[$parent_srl]->document_count += $document_count; + $document_category[$parent_srl]->childs[] = $obj->category_srl; + $document_category[$parent_srl]->child_count = count($document_category[$parent_srl]->childs); + if($expand) $document_category[$parent_srl]->expand = $expand; + + $parent_srl = $document_category[$parent_srl]->parent_srl; + } + } + + $document_category[$key] = $obj; + + if(count($val['list'])) $this->_arrangeCategory($document_category, $val['list'], $depth+1); + } + $document_category[$list_order[0]]->first = true; + $document_category[$list_order[count($list_order)-1]]->last = true; + } + + /** + * @brief 카테고리에 속한 문서의 갯수를 구함 + **/ + function getCategoryDocumentCount($module_srl, $category_srl) { + $args->module_srl = $module_srl; + $args->category_srl = $category_srl; + $output = executeQuery('document.getCategoryDocumentCount', $args); + return (int)$output->data->count; + } + + /** + * @brief 문서 category정보의 xml 캐시 파일을 return + **/ + function getCategoryXmlFile($module_srl) { + $xml_file = sprintf('files/cache/document_category/%s.xml.php',$module_srl); + if(!file_exists($xml_file)) { + $oDocumentController = &getController('document'); + $oDocumentController->makeCategoryFile($module_srl); + } + return $xml_file; + } + + /** + * @brief 문서 category정보의 php 캐시 파일을 return + **/ + function getCategoryPhpFile($module_srl) { + $php_file = sprintf('files/cache/document_category/%s.php',$module_srl); + if(!file_exists($php_file)) { + $oDocumentController = &getController('document'); + $oDocumentController->makeCategoryFile($module_srl); + } + return $php_file; + } + + /** + * @brief 월별 글 보관현황을 가져옴 + **/ + function getMonthlyArchivedList($obj) { + if($obj->mid) { + $oModuleModel = &getModel('module'); + $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); + unset($obj->mid); + } + + // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 + if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); + else $args->module_srl = $obj->module_srl; + + $output = executeQuery('document.getMonthlyArchivedList', $args); + if(!$output->toBool()||!$output->data) return $output; + + if(!is_array($output->data)) $output->data = array($output->data); + + return $output; + } + + /** + * @brief 특정달의 일별 글 현황을 가져옴 + **/ + function getDailyArchivedList($obj) { + if($obj->mid) { + $oModuleModel = &getModel('module'); + $obj->module_srl = $oModuleModel->getModuleSrlByMid($obj->mid); + unset($obj->mid); + } + + // 넘어온 module_srl은 array일 수도 있기에 array인지를 체크 + if(is_array($obj->module_srl)) $args->module_srl = implode(',', $obj->module_srl); + else $args->module_srl = $obj->module_srl; + $args->regdate = $obj->regdate; + + $output = executeQuery('document.getDailyArchivedList', $args); + if(!$output->toBool()) return $output; + + if(!is_array($output->data)) $output->data = array($output->data); + + return $output; + } + + /** + * @brief 특정 모듈의 분류를 구함 + **/ + function getDocumentCategories() { + if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted'); + $module_srl = Context::get('module_srl'); + $categories= $this->getCategoryList($module_srl); + $lang = Context::get('lang'); + + // 분류 없음 추가 + $output = "0,0,{$lang->none_category}\n"; + if($categories){ + foreach($categories as $category_srl => $category) { + $output .= sprintf("%d,%d,%s\n",$category_srl, $category->depth,$category->title); + } + } + $this->add('categories', $output); + } + + /** + * @brief 문서 설정 정보를 구함 + **/ + function getDocumentConfig() { + if(!$GLOBALS['__document_config__']) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('document'); + if(!$config->thumbnail_type) $config->thumbnail_type = 'crop'; + $GLOBALS['__document_config__'] = $config; + } + return $GLOBALS['__document_config__']; + } + + /** + * @brief 공통 :: 모듈의 확장 변수 관리 + * 모듈의 확장변수 관리는 모든 모듈에서 document module instance를 이용할때 사용할 수 있음 + **/ + function getExtraVarsHTML($module_srl) { + // 기존의 extra_keys 가져옴 + $extra_keys = $this->getExtraKeys($module_srl); + Context::set('extra_keys', $extra_keys); + + // grant 정보를 추출 + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($this->module_path.'tpl', 'extra_keys'); + } + + /** + * @brief 공통 :: 모듈의 카테고리 변수 관리 + **/ + function getCategoryHTML($module_srl) { + $category_xml_file = $this->getCategoryXmlFile($module_srl); + + Context::set('category_xml_file', $category_xml_file); + + Context::loadJavascriptPlugin('ui.tree'); + // grant 정보를 추출 + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($this->module_path.'tpl', 'category_list'); + } + + /** + * @brief 특정 카테고리의 정보를 이용하여 템플릿을 구한후 return + * 관리자 페이지에서 특정 메뉴의 정보를 추가하기 위해 서버에서 tpl을 컴파일 한후 컴파일 된 html을 직접 return + **/ + function getDocumentCategoryTplInfo() { + $oModuleModel = &getModel('module'); + $oMemberModel = &getModel('member'); + + // 해당 메뉴의 정보를 가져오기 위한 변수 설정 + $module_srl = Context::get('module_srl'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + + // 권한 체크 + $grant = $oModuleModel->getGrant($module_info, Context::get('logged_info')); + if(!$grant->manager) return new Object(-1,'msg_not_permitted'); + + $category_srl = Context::get('category_srl'); + $parent_srl = Context::get('parent_srl'); + + // 회원 그룹의 목록을 가져옴 + $group_list = $oMemberModel->getGroups($module_info->site_srl); + Context::set('group_list', $group_list); + + // parent_srl이 있고 category_srl 이 없으면 하부 메뉴 추가임 + if(!$category_srl && $parent_srl) { + // 상위 메뉴의 정보를 가져옴 + $parent_info = $this->getCategory($parent_srl); + + // 추가하려는 메뉴의 기본 변수 설정 + $category_info->category_srl = getNextSequence(); + $category_info->parent_srl = $parent_srl; + $category_info->parent_category_title = $parent_info->title; + + // root에 메뉴 추가하거나 기존 메뉴의 수정일 경우 + } else { + // category_srl 이 있으면 해당 메뉴의 정보를 가져온다 + if($category_srl) $category_info = $this->getCategory($category_srl); + + // 찾아진 값이 없다면 신규 메뉴 추가로 보고 category_srl값만 구해줌 + if(!$category_info->category_srl) { + $category_info->category_srl = getNextSequence(); + } + } + + + $category_info->title = htmlspecialchars($category_info->title); + Context::set('category_info', $category_info); + + // template 파일을 직접 컴파일한후 tpl변수에 담아서 return한다. + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile('./modules/document/tpl', 'category_info'); + $tpl = str_replace("\n",'',$tpl); + + // 사용자 정의 언어 변경 + $oModuleController = &getController('module'); + $oModuleController->replaceDefinedLangCode($tpl); + + // return 할 변수 설정 + $this->add('tpl', $tpl); + } + + + function getDocumentSrlByAlias($mid, $alias) + { + if(!$mid || !$alias) return null; + $site_module_info = Context::get('site_module_info'); + $args->mid = $mid; + $args->alias_title = $alias; + $args->site_srl = $site_module_info->site_srl; + $output = executeQuery('document.getDocumentSrlByAlias', $args); + if(!$output->data) return null; + else return $output->data->document_srl; + } + + function getAlias($document_srl){ + if(!$document_srl) return null; + $args->document_srl = $document_srl; + $output = executeQueryArray('document.getAliases', $args); + + if(!$output->data) return null; + else return $output->data[0]->alias_title; + } + + function getHistories($document_srl, $list_count, $page) + { + $args->list_count = $list_count; + $args->page = $page; + $args->document_srl = $document_srl; + $output = executeQueryArray('document.getHistories', $args); + return $output; + } + + function getHistory($history_srl) + { + $args->history_srl = $history_srl; + $output = executeQuery('document.getHistory', $args); + return $output->data; + } + + /** + * @brief module_srl값을 가지는 문서의 목록을 가져옴 + **/ + function getTrashList($obj) { + + // 변수 체크 + $args->category_srl = $obj->category_srl?$obj->category_srl:null; + $args->sort_index = $obj->sort_index; + $args->order_type = $obj->order_type?$obj->order_type:'desc'; + $args->page = $obj->page?$obj->page:1; + $args->list_count = $obj->list_count?$obj->list_count:20; + $args->page_count = $obj->page_count?$obj->page_count:10; + + + // 검색 옵션 정리 + $search_target = $obj->search_target; + $search_keyword = $obj->search_keyword; + if($search_target && $search_keyword) { + switch($search_target) { + case 'title' : + case 'content' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->{"s_".$search_target} = $search_keyword; + $use_division = true; + break; + case 'title_content' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_title = $search_keyword; + $args->s_content = $search_keyword; + break; + case 'user_id' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_user_id = $search_keyword; + $args->sort_index = 'documents.'.$args->sort_index; + break; + case 'user_name' : + case 'nick_name' : + case 'email_address' : + case 'homepage' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->{"s_".$search_target} = $search_keyword; + break; + case 'is_notice' : + case 'is_secret' : + if($search_keyword=='N') $args->{"s_".$search_target} = 'N'; + elseif($search_keyword=='Y') $args->{"s_".$search_target} = 'Y'; + else $args->{"s_".$search_target} = ''; + break; + case 'member_srl' : + case 'readed_count' : + case 'voted_count' : + case 'comment_count' : + case 'trackback_count' : + case 'uploaded_count' : + $args->{"s_".$search_target} = (int)$search_keyword; + break; + case 'regdate' : + case 'last_update' : + case 'ipaddress' : + case 'tag' : + $args->{"s_".$search_target} = $search_keyword; + break; + } + } + + + $output = executeQueryArray('document.getTrashList', $args); + if($output->data){ + foreach($output->data as $key => $attribute) { + $oDocument = null; + $oDocument = new documentItem(); + $oDocument->setAttribute($attribute, false); + $attribute = $oDocument; + } + } + return $output; + } + + } +?> diff --git a/modules/document/document.view.php b/modules/document/document.view.php index 4905ec9a7..4e2e3fb81 100644 --- a/modules/document/document.view.php +++ b/modules/document/document.view.php @@ -1,121 +1,121 @@ -getModuleInfoByDocumentSrl($document_srl); - - // document 객체를 생성. 기본 데이터 구조의 경우 document모듈만 쓰면 만사 해결.. -_-; - $oDocumentModel = &getModel('document'); - - // 선택된 문서 표시를 위한 객체 생성 - $oDocument = $oDocumentModel->getDocument($document_srl, $this->grant->manager); - if(!$oDocument->isExists()) return new Object(-1,'msg_invalid_request'); - - // 권한 체크 - if(!$oDocument->isAccessible()) return new Object(-1,'msg_not_permitted'); - - // 모듈 정보 세팅 - Context::set('module_info', $module_info); - - // 브라우저 타이틀 설정 - Context::setBrowserTitle($oDocument->getTitleText()); - Context::set('oDocument', $oDocument); - - Context::set('layout','none'); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('print_page'); - } - - /** - * @brief 미리 보기 - **/ - function dispDocumentPreview() { - Context::set('layout','none'); - - $content = Context::get('content'); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('preview_page'); - } - - /** - * @brief 관리자가 선택한 문서에 대한 관리 - **/ - function dispDocumentManageDocument() { - if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted'); - - // 선택한 목록을 세션에서 가져옴 - $flag_list = $_SESSION['document_management']; - if(count($flag_list)) { - foreach($flag_list as $key => $val) { - if(!is_bool($val)) continue; - $document_srl_list[] = $key; - } - } - - if(count($document_srl_list)) { - $oDocumentModel = &getModel('document'); - $document_list = $oDocumentModel->getDocuments($document_srl_list, $this->grant->is_admin); - Context::set('document_list', $document_list); - } - - $oModuleModel = &getModel('module'); - - // 모듈 카테고리 목록과 모듈 목록의 조합 - if(count($module_list)>1) Context::set('module_list', $module_categories); - - // 팝업 레이아웃 선택 - $this->setLayoutPath('./common/tpl'); - $this->setLayoutFile('popup_layout'); - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('checked_list'); - } - - function triggerDispDocumentAdditionSetup(&$obj) { - $current_module_srl = Context::get('module_srl'); - $current_module_srls = Context::get('module_srls'); - - if(!$current_module_srl && !$current_module_srls) { - // 선택된 모듈의 정보를 가져옴 - $current_module_info = Context::get('current_module_info'); - $current_module_srl = $current_module_info->module_srl; - if(!$current_module_srl) return new Object(); - } - - $oModuleModel = &getModel('module'); - if($current_module_srl) - { - $document_config = $oModuleModel->getModulePartConfig('document', $current_module_srl); - } - if(!isset($document_config->use_history)) $document_config->use_history = 'N'; - Context::set('document_config', $document_config); - - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'document_module_config'); - $obj .= $tpl; - - return new Object(); - } - - } -?> +getModuleInfoByDocumentSrl($document_srl); + + // document 객체를 생성. 기본 데이터 구조의 경우 document모듈만 쓰면 만사 해결.. -_-; + $oDocumentModel = &getModel('document'); + + // 선택된 문서 표시를 위한 객체 생성 + $oDocument = $oDocumentModel->getDocument($document_srl, $this->grant->manager); + if(!$oDocument->isExists()) return new Object(-1,'msg_invalid_request'); + + // 권한 체크 + if(!$oDocument->isAccessible()) return new Object(-1,'msg_not_permitted'); + + // 모듈 정보 세팅 + Context::set('module_info', $module_info); + + // 브라우저 타이틀 설정 + Context::setBrowserTitle($oDocument->getTitleText()); + Context::set('oDocument', $oDocument); + + Context::set('layout','none'); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('print_page'); + } + + /** + * @brief 미리 보기 + **/ + function dispDocumentPreview() { + Context::set('layout','none'); + + $content = Context::get('content'); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('preview_page'); + } + + /** + * @brief 관리자가 선택한 문서에 대한 관리 + **/ + function dispDocumentManageDocument() { + if(!Context::get('is_logged')) return new Object(-1,'msg_not_permitted'); + + // 선택한 목록을 세션에서 가져옴 + $flag_list = $_SESSION['document_management']; + if(count($flag_list)) { + foreach($flag_list as $key => $val) { + if(!is_bool($val)) continue; + $document_srl_list[] = $key; + } + } + + if(count($document_srl_list)) { + $oDocumentModel = &getModel('document'); + $document_list = $oDocumentModel->getDocuments($document_srl_list, $this->grant->is_admin); + Context::set('document_list', $document_list); + } + + $oModuleModel = &getModel('module'); + + // 모듈 카테고리 목록과 모듈 목록의 조합 + if(count($module_list)>1) Context::set('module_list', $module_categories); + + // 팝업 레이아웃 선택 + $this->setLayoutPath('./common/tpl'); + $this->setLayoutFile('popup_layout'); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('checked_list'); + } + + function triggerDispDocumentAdditionSetup(&$obj) { + $current_module_srl = Context::get('module_srl'); + $current_module_srls = Context::get('module_srls'); + + if(!$current_module_srl && !$current_module_srls) { + // 선택된 모듈의 정보를 가져옴 + $current_module_info = Context::get('current_module_info'); + $current_module_srl = $current_module_info->module_srl; + if(!$current_module_srl) return new Object(); + } + + $oModuleModel = &getModel('module'); + if($current_module_srl) + { + $document_config = $oModuleModel->getModulePartConfig('document', $current_module_srl); + } + if(!isset($document_config->use_history)) $document_config->use_history = 'N'; + Context::set('document_config', $document_config); + + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'document_module_config'); + $obj .= $tpl; + + return new Object(); + } + + } +?> diff --git a/modules/document/lang/en.lang.php b/modules/document/lang/en.lang.php index d12224008..60381ab81 100644 --- a/modules/document/lang/en.lang.php +++ b/modules/document/lang/en.lang.php @@ -1,97 +1,97 @@ - - * @brief Document module's basic language pack - **/ - - $lang->document_list = 'Documents List'; - $lang->thumbnail_type = 'Thumbnail Type'; - $lang->thumbnail_crop = 'Crop'; - $lang->thumbnail_ratio = 'Ratio'; - $lang->cmd_delete_all_thumbnail = 'Delete all thumbnails'; - $lang->move_target_module = "Target module "; - $lang->title_bold = 'Bold'; - $lang->title_color = 'Color'; - $lang->new_document_count = 'New documents'; - - $lang->parent_category_title = 'Parent Category'; - $lang->category_title = 'Category'; - $lang->category_color = 'Category Font Color'; - $lang->expand = 'Expand'; - $lang->category_group_srls = 'Accessable Group'; - - $lang->cmd_make_child = 'Add Child Category'; - $lang->cmd_enable_move_category = "Change Category Position (Drag the top menu after selection)"; - - $lang->about_category_title = 'Please input category name'; - $lang->about_expand = 'By selecting this option, it will be always expanded'; - $lang->about_category_group_srls = 'Only selected group will be able to use current category'; - $lang->about_category_color = 'You can set font color of category.'; - - $lang->cmd_search_next = 'Search Next'; - - $lang->cmd_temp_save = 'Temporary Save'; - - $lang->cmd_toggle_checked_document = 'Reverse selected items'; - $lang->cmd_delete_checked_document = 'Delete selected'; - $lang->cmd_document_do = 'I want to'; - - $lang->msg_cart_is_null = 'Please select the articles to delete'; - $lang->msg_category_not_moved = 'Could not be moved'; - $lang->msg_is_secret = 'This is a secret article'; - $lang->msg_checked_document_is_deleted = '%d article(s) was(were) deleted'; - - // Search targets in admin page - $lang->search_target_list = array( - 'title' => 'Subject', - 'content' => 'Content', - 'user_id' => 'User ID', - 'member_srl' => 'Member Serial Number', - 'user_name' => 'User Name', - 'nick_name' => 'Nickname', - 'email_address' => 'Email', - 'homepage' => 'Homepage', - 'is_notice' => 'Notice', - 'is_secret' => 'Secret', - 'tags' => 'Tag', - 'readed_count' => 'Number of Views (over)', - 'voted_count' => 'Number of Votes (over)', - 'comment_count ' => 'Number of Comments (over)', - 'trackback_count ' => 'Number of Trackbacks (over)', - 'uploaded_count ' => 'Number of Attachments (over)', - 'regdate' => 'Date', - 'last_update' => 'Last Modified Date', - 'ipaddress' => 'IP Address', - ); - - $lang->alias = "Alias"; - $lang->history = "History"; - $lang->about_use_history = "History can restore documents to previous revisions"; - $lang->trace_only = "Trace only"; - - $lang->cmd_trash = 'Trashcan'; - $lang->cmd_restore = 'Restore'; - $lang->cmd_restore_all = 'Restore All'; - - $lang->in_trash = 'Trashcan'; - $lang->trash_nick_name = 'Deleter'; - $lang->trash_date = 'Deleted date'; - $lang->trash_description = 'Description'; - - $lang->search_target_trash_list = array( - 'title' => 'Title', - 'content' => 'Content', - 'user_id' => 'User ID', - 'member_srl' => 'Member srl', - 'user_name' => 'User name', - 'nick_name' => 'Nickname', - 'trash_member_srl' => 'Deleter srl', - 'trash_user_name' => 'Deleter name', - 'trash_nick_name' => 'Deleter nickname', - 'trash_date' => 'Deleted date', - 'trash_ipaddress' => 'Deleter IP address', - ); - - $lang->success_trashed = "Successfully moved to trashcan"; -?> +document_list = 'Documents List'; + $lang->thumbnail_type = 'Thumbnail Type'; + $lang->thumbnail_crop = 'Crop'; + $lang->thumbnail_ratio = 'Ratio'; + $lang->cmd_delete_all_thumbnail = 'Delete all thumbnails'; + $lang->move_target_module = "Target module "; + $lang->title_bold = 'Bold'; + $lang->title_color = 'Color'; + $lang->new_document_count = 'New documents'; + + $lang->parent_category_title = 'Parent Category'; + $lang->category_title = 'Category'; + $lang->category_color = 'Category Font Color'; + $lang->expand = 'Expand'; + $lang->category_group_srls = 'Accessable Group'; + + $lang->cmd_make_child = 'Add Child Category'; + $lang->cmd_enable_move_category = "Change Category Position (Drag the top menu after selection)"; + + $lang->about_category_title = 'Please input category name'; + $lang->about_expand = 'By selecting this option, it will be always expanded'; + $lang->about_category_group_srls = 'Only selected group will be able to use current category'; + $lang->about_category_color = 'You can set font color of category.'; + + $lang->cmd_search_next = 'Search Next'; + + $lang->cmd_temp_save = 'Temporary Save'; + + $lang->cmd_toggle_checked_document = 'Reverse selected items'; + $lang->cmd_delete_checked_document = 'Delete selected'; + $lang->cmd_document_do = 'I want to'; + + $lang->msg_cart_is_null = 'Please select the articles to delete'; + $lang->msg_category_not_moved = 'Could not be moved'; + $lang->msg_is_secret = 'This is a secret article'; + $lang->msg_checked_document_is_deleted = '%d article(s) was(were) deleted'; + + // Search targets in admin page + $lang->search_target_list = array( + 'title' => 'Subject', + 'content' => 'Content', + 'user_id' => 'User ID', + 'member_srl' => 'Member Serial Number', + 'user_name' => 'User Name', + 'nick_name' => 'Nickname', + 'email_address' => 'Email', + 'homepage' => 'Homepage', + 'is_notice' => 'Notice', + 'is_secret' => 'Secret', + 'tags' => 'Tag', + 'readed_count' => 'Number of Views (over)', + 'voted_count' => 'Number of Votes (over)', + 'comment_count ' => 'Number of Comments (over)', + 'trackback_count ' => 'Number of Trackbacks (over)', + 'uploaded_count ' => 'Number of Attachments (over)', + 'regdate' => 'Date', + 'last_update' => 'Last Modified Date', + 'ipaddress' => 'IP Address', + ); + + $lang->alias = "Alias"; + $lang->history = "History"; + $lang->about_use_history = "History can restore documents to previous revisions"; + $lang->trace_only = "Trace only"; + + $lang->cmd_trash = 'Trashcan'; + $lang->cmd_restore = 'Restore'; + $lang->cmd_restore_all = 'Restore All'; + + $lang->in_trash = 'Trashcan'; + $lang->trash_nick_name = 'Deleter'; + $lang->trash_date = 'Deleted date'; + $lang->trash_description = 'Description'; + + $lang->search_target_trash_list = array( + 'title' => 'Title', + 'content' => 'Content', + 'user_id' => 'User ID', + 'member_srl' => 'Member srl', + 'user_name' => 'User name', + 'nick_name' => 'Nickname', + 'trash_member_srl' => 'Deleter srl', + 'trash_user_name' => 'Deleter name', + 'trash_nick_name' => 'Deleter nickname', + 'trash_date' => 'Deleted date', + 'trash_ipaddress' => 'Deleter IP address', + ); + + $lang->success_trashed = "Successfully moved to trashcan"; +?> diff --git a/modules/document/lang/es.lang.php b/modules/document/lang/es.lang.php index 94346c3ea..527e7e6cd 100644 --- a/modules/document/lang/es.lang.php +++ b/modules/document/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma español para el módulo de documentos. **/ diff --git a/modules/document/lang/fr.lang.php b/modules/document/lang/fr.lang.php index 6c18177dd..5c8d28f32 100644 --- a/modules/document/lang/fr.lang.php +++ b/modules/document/lang/fr.lang.php @@ -1,81 +1,81 @@ - Traduit par Pierre Duvent - * @brief Paquet du langage en français pour le module de Document - **/ - - $lang->document_list = 'Liste des Documents'; - $lang->thumbnail_type = 'Type de la Vignette'; - $lang->thumbnail_crop = 'Rogner'; - $lang->thumbnail_ratio = 'Proportion'; - $lang->cmd_delete_all_thumbnail = 'Supprimer toutes les vignettes'; - $lang->title_bold = 'Gras'; - $lang->title_color = 'Couleur'; - $lang->new_document_count = '새글'; - - $lang->parent_category_title = 'catégorie supérieure'; - $lang->category_title = 'Catégorie'; - $lang->category_color = '분류 폰트색깔'; - $lang->expand = 'Etendre'; - $lang->category_group_srls = 'Groupe Accessible'; - $lang->cmd_make_child = 'Ajouter une catégorie inférieure'; - $lang->cmd_enable_move_category = "Bouger la position de la catégorie (Cochez la case et puis glisser la catégorie que vous voulez déplacer)"; - $lang->about_category_title = 'Entrez le nom de la catégorie, S.V.P.'; - $lang->about_expand = 'Si vous cochez la case à cocher, ce sera toujours tendu'; - $lang->about_category_group_srls = 'Le groupe choisi seulement pourra utiliser la catégorie courante'; - $lang->about_category_color = 'You can set font color of category.'; - - $lang->cmd_search_next = 'Recherche Suivante'; - - $lang->cmd_temp_save = 'Conserver temporairement'; - - $lang->cmd_toggle_checked_document = 'Renverser les choisis'; - $lang->cmd_delete_checked_document = 'Supprimer les choisis'; - $lang->cmd_document_do = 'Vous voudriez..'; - - $lang->msg_cart_is_null = 'Choisissez les articles à supprimer, S.V.P.'; - $lang->msg_category_not_moved = 'Ne peut(peuvent) pas être bougé(s)'; - $lang->msg_is_secret = 'Cet article est secret'; - $lang->msg_checked_document_is_deleted = '%d article(s) est(sont) supprimé(s)'; - - $lang->move_target_module = "Module à déménager"; - - // Search targets in admin page - $lang->search_target_list = array( - 'title' => 'Titre', - 'content' => 'Contenu', - 'user_id' => 'Compte', - 'member_srl' => 'Numéro de Série du Membre', - 'user_name' => 'Nom', - 'nick_name' => 'Surnom', - 'email_address' => 'Mél', - 'homepage' => 'Page d\'accueil', - 'is_notice' => 'Notice', - 'is_secret' => 'Secret', - 'tags' => 'Balises', - 'readed_count' => 'Vues (surplus)', - 'voted_count' => 'Recommandés (surplus)', - 'comment_count ' => 'Commentaires (surplus)', - 'trackback_count ' => 'Rétroliens (surplus)', - 'uploaded_count ' => 'Fichiers Attachés (surplus)', - 'regdate' => 'Enrégistré', - 'last_update' => 'La Dernière Mise à Jour', - 'ipaddress' => 'Adresse IP', - ); - $lang->alias = "Alias"; - $lang->history = "히스토리"; - $lang->about_use_history = "히스토리 기능의 사용여부를 지정합니다. 히스토리 기능을 사용할 경우 문서 수정시 이전 리비전을 기록하고 복원할 수 있습니다."; - $lang->trace_only = "흔적만 남김"; - - $lang->cmd_trash = 'Trashcan'; - $lang->cmd_restore = 'Restore'; - $lang->cmd_restore_all = 'Restore All'; - - $lang->in_trash = 'Trashcan'; - $lang->trash_nick_name = 'Person who deleted'; - $lang->trash_date = 'Deleted date'; - $lang->trash_description = 'Description'; - - $lang->success_trashed = "Successfully moved to trashcan"; -?> + + * @brief Paquet du langage en français pour le module de Document + **/ + + $lang->document_list = 'Liste des Documents'; + $lang->thumbnail_type = 'Type de la Vignette'; + $lang->thumbnail_crop = 'Rogner'; + $lang->thumbnail_ratio = 'Proportion'; + $lang->cmd_delete_all_thumbnail = 'Supprimer toutes les vignettes'; + $lang->title_bold = 'Gras'; + $lang->title_color = 'Couleur'; + $lang->new_document_count = '새글'; + + $lang->parent_category_title = 'catégorie supérieure'; + $lang->category_title = 'Catégorie'; + $lang->category_color = '분류 폰트색깔'; + $lang->expand = 'Etendre'; + $lang->category_group_srls = 'Groupe Accessible'; + $lang->cmd_make_child = 'Ajouter une catégorie inférieure'; + $lang->cmd_enable_move_category = "Bouger la position de la catégorie (Cochez la case et puis glisser la catégorie que vous voulez déplacer)"; + $lang->about_category_title = 'Entrez le nom de la catégorie, S.V.P.'; + $lang->about_expand = 'Si vous cochez la case à cocher, ce sera toujours tendu'; + $lang->about_category_group_srls = 'Le groupe choisi seulement pourra utiliser la catégorie courante'; + $lang->about_category_color = 'You can set font color of category.'; + + $lang->cmd_search_next = 'Recherche Suivante'; + + $lang->cmd_temp_save = 'Conserver temporairement'; + + $lang->cmd_toggle_checked_document = 'Renverser les choisis'; + $lang->cmd_delete_checked_document = 'Supprimer les choisis'; + $lang->cmd_document_do = 'Vous voudriez..'; + + $lang->msg_cart_is_null = 'Choisissez les articles à supprimer, S.V.P.'; + $lang->msg_category_not_moved = 'Ne peut(peuvent) pas être bougé(s)'; + $lang->msg_is_secret = 'Cet article est secret'; + $lang->msg_checked_document_is_deleted = '%d article(s) est(sont) supprimé(s)'; + + $lang->move_target_module = "Module à déménager"; + + // Search targets in admin page + $lang->search_target_list = array( + 'title' => 'Titre', + 'content' => 'Contenu', + 'user_id' => 'Compte', + 'member_srl' => 'Numéro de Série du Membre', + 'user_name' => 'Nom', + 'nick_name' => 'Surnom', + 'email_address' => 'Mél', + 'homepage' => 'Page d\'accueil', + 'is_notice' => 'Notice', + 'is_secret' => 'Secret', + 'tags' => 'Balises', + 'readed_count' => 'Vues (surplus)', + 'voted_count' => 'Recommandés (surplus)', + 'comment_count ' => 'Commentaires (surplus)', + 'trackback_count ' => 'Rétroliens (surplus)', + 'uploaded_count ' => 'Fichiers Attachés (surplus)', + 'regdate' => 'Enrégistré', + 'last_update' => 'La Dernière Mise à Jour', + 'ipaddress' => 'Adresse IP', + ); + $lang->alias = "Alias"; + $lang->history = "히스토리"; + $lang->about_use_history = "히스토리 기능의 사용여부를 지정합니다. 히스토리 기능을 사용할 경우 문서 수정시 이전 리비전을 기록하고 복원할 수 있습니다."; + $lang->trace_only = "흔적만 남김"; + + $lang->cmd_trash = 'Trashcan'; + $lang->cmd_restore = 'Restore'; + $lang->cmd_restore_all = 'Restore All'; + + $lang->in_trash = 'Trashcan'; + $lang->trash_nick_name = 'Person who deleted'; + $lang->trash_date = 'Deleted date'; + $lang->trash_description = 'Description'; + + $lang->success_trashed = "Successfully moved to trashcan"; +?> diff --git a/modules/document/lang/jp.lang.php b/modules/document/lang/jp.lang.php index ea2b249ec..cd8719bf6 100644 --- a/modules/document/lang/jp.lang.php +++ b/modules/document/lang/jp.lang.php @@ -1,99 +1,99 @@ - 翻訳:RisaPapa、ミニミ - * @brief ドキュメント(document)モジュールの基本言語パッケージ - **/ - - $lang->document_list = 'ドキュメントリスト'; - $lang->thumbnail_type = 'サムネールタイプ'; - $lang->thumbnail_crop = 'トリミングする'; - $lang->thumbnail_ratio = '比率に合わせる'; - $lang->cmd_delete_all_thumbnail = 'すべてのサムネール削除'; - $lang->title_bold = 'タイトル太字'; - $lang->title_color = 'タイトルの色'; - $lang->new_document_count = '新規'; - - $lang->parent_category_title = '上位カテゴリ名'; - $lang->category_title = 'カテゴリ名'; - $lang->category_color = 'カテゴリフォント色'; - $lang->expand = '拡張表示'; - $lang->category_group_srls = 'グループ制限'; - - $lang->cmd_make_child = '下位カテゴリ追加'; - $lang->cmd_enable_move_category = 'カテゴリ位置変更(選択後上のメニューをドラッグして下さい)'; - - $lang->about_category_title = 'カテゴリ名を入力して下さい。'; - $lang->about_expand = 'チェックすると常に展開された状態になります。'; - $lang->about_category_group_srls = '選択したグループのみ、現在のカテゴリの指定が出来ます。'; - $lang->about_category_color = 'カテゴリのフォント色を設定します。'; - - $lang->cmd_search_next = '継続検索'; - - $lang->cmd_temp_save = '一時保存'; - - $lang->cmd_toggle_checked_document = '選択項目反転'; - $lang->cmd_delete_checked_document = '選択項目削除'; - $lang->cmd_document_do = 'この書き込みを..'; - - $lang->msg_cart_is_null = '削除する書き込みを選択して下さい。'; - $lang->msg_category_not_moved = '移動出来ません。'; - $lang->msg_is_secret = '非公開設定の書き込みです。'; - $lang->msg_checked_document_is_deleted = '%d個の書き込みが削除されました。'; - - $lang->move_target_module = '移動対象モジュール'; - - // 管理者ページで検索する内容 - $lang->search_target_list = array( - 'title' => 'タイトル', - 'content' => '内容', - 'user_id' => 'ユーザーID', - 'member_srl' => '会員番号', - 'user_name' => 'ユーザ名', - 'nick_name' => 'ニックネーム', - 'email_address' => 'メールアドレス', - 'homepage' => 'ホームページURL', - 'is_notice' => 'お知らせ', - 'is_secret' => '非公開書き込み', - 'tags' => 'タグ', - 'readed_count' => '閲覧数(以上)', - 'voted_count' => '推薦数(以上)', - 'comment_count ' => 'コメント数(以上)', - 'trackback_count ' => 'トラックバック数(以上)', - 'uploaded_count ' => '添付ファイル数(以上)', - 'regdate' => '登録日', - 'last_update' => '最近修正日', - 'ipaddress' => 'IPアドレス', - ); - - $lang->alias = 'アリアス(Alias)'; - $lang->history = '履歴'; - $lang->about_use_history = '履歴機能を使用するかを設定します。履歴機能を使用すると文書修正のバージョンを管理し、過去のバージョンから復元することも可能です。'; - $lang->trace_only = '記録だけ残す'; - - $lang->cmd_trash = "ごみ箱"; - $lang->cmd_restore = "差し戻し"; - $lang->cmd_restore_all = "すべて差し戻し"; - - $lang->in_trash = "ごみ箱"; - $lang->trash_nick_name = "削除者のニックネーム"; - $lang->trash_date = "削除日"; - $lang->trash_description = "理由"; - - // 管理者ページでのごみ箱の検索対象 - $lang->search_target_trash_list = array( - 'title' => 'タイトル', - 'content' => '内容', - 'user_id' => 'ユーザーID', - 'member_srl' => '会員番号', - 'user_name' => 'ユーザー名', - 'nick_name' => 'ニックネーム', - 'trash_member_srl' => '削除者会員番号', - 'trash_user_name' => '削除者ユーザー名', - 'trash_nick_name' => '削除者ニックネーム', - 'trash_date' => '削除日', - 'trash_ipaddress' => '削除者のIPアドレス', - ); - - $lang->success_trashed = "Successfully moved to trashcan"; -?> +document_list = 'ドキュメントリスト'; + $lang->thumbnail_type = 'サムネールタイプ'; + $lang->thumbnail_crop = 'トリミングする'; + $lang->thumbnail_ratio = '比率に合わせる'; + $lang->cmd_delete_all_thumbnail = 'すべてのサムネール削除'; + $lang->title_bold = 'タイトル太字'; + $lang->title_color = 'タイトルの色'; + $lang->new_document_count = '新規'; + + $lang->parent_category_title = '上位カテゴリ名'; + $lang->category_title = 'カテゴリ名'; + $lang->category_color = 'カテゴリフォント色'; + $lang->expand = '拡張表示'; + $lang->category_group_srls = 'グループ制限'; + + $lang->cmd_make_child = '下位カテゴリ追加'; + $lang->cmd_enable_move_category = 'カテゴリ位置変更(選択後上のメニューをドラッグして下さい)'; + + $lang->about_category_title = 'カテゴリ名を入力して下さい。'; + $lang->about_expand = 'チェックすると常に展開された状態になります。'; + $lang->about_category_group_srls = '選択したグループのみ、現在のカテゴリの指定が出来ます。'; + $lang->about_category_color = 'カテゴリのフォント色を設定します。'; + + $lang->cmd_search_next = '継続検索'; + + $lang->cmd_temp_save = '一時保存'; + + $lang->cmd_toggle_checked_document = '選択項目反転'; + $lang->cmd_delete_checked_document = '選択項目削除'; + $lang->cmd_document_do = 'この書き込みを..'; + + $lang->msg_cart_is_null = '削除する書き込みを選択して下さい。'; + $lang->msg_category_not_moved = '移動出来ません。'; + $lang->msg_is_secret = '非公開設定の書き込みです。'; + $lang->msg_checked_document_is_deleted = '%d個の書き込みが削除されました。'; + + $lang->move_target_module = '移動対象モジュール'; + + // 管理者ページで検索する内容 + $lang->search_target_list = array( + 'title' => 'タイトル', + 'content' => '内容', + 'user_id' => 'ユーザーID', + 'member_srl' => '会員番号', + 'user_name' => 'ユーザ名', + 'nick_name' => 'ニックネーム', + 'email_address' => 'メールアドレス', + 'homepage' => 'ホームページURL', + 'is_notice' => 'お知らせ', + 'is_secret' => '非公開書き込み', + 'tags' => 'タグ', + 'readed_count' => '閲覧数(以上)', + 'voted_count' => '推薦数(以上)', + 'comment_count ' => 'コメント数(以上)', + 'trackback_count ' => 'トラックバック数(以上)', + 'uploaded_count ' => '添付ファイル数(以上)', + 'regdate' => '登録日', + 'last_update' => '最近修正日', + 'ipaddress' => 'IPアドレス', + ); + + $lang->alias = 'アリアス(Alias)'; + $lang->history = '履歴'; + $lang->about_use_history = '履歴機能を使用するかを設定します。履歴機能を使用すると文書修正のバージョンを管理し、過去のバージョンから復元することも可能です。'; + $lang->trace_only = '記録だけ残す'; + + $lang->cmd_trash = "ごみ箱"; + $lang->cmd_restore = "差し戻し"; + $lang->cmd_restore_all = "すべて差し戻し"; + + $lang->in_trash = "ごみ箱"; + $lang->trash_nick_name = "削除者のニックネーム"; + $lang->trash_date = "削除日"; + $lang->trash_description = "理由"; + + // 管理者ページでのごみ箱の検索対象 + $lang->search_target_trash_list = array( + 'title' => 'タイトル', + 'content' => '内容', + 'user_id' => 'ユーザーID', + 'member_srl' => '会員番号', + 'user_name' => 'ユーザー名', + 'nick_name' => 'ニックネーム', + 'trash_member_srl' => '削除者会員番号', + 'trash_user_name' => '削除者ユーザー名', + 'trash_nick_name' => '削除者ニックネーム', + 'trash_date' => '削除日', + 'trash_ipaddress' => '削除者のIPアドレス', + ); + + $lang->success_trashed = "Successfully moved to trashcan"; +?> diff --git a/modules/document/lang/ko.lang.php b/modules/document/lang/ko.lang.php index b0c5ea733..5eaf3045c 100644 --- a/modules/document/lang/ko.lang.php +++ b/modules/document/lang/ko.lang.php @@ -1,100 +1,100 @@ - - * @brief 문서(document) 모듈의 기본 언어팩 - **/ - - $lang->document_list = '문서 목록'; - $lang->thumbnail_type = '썸네일 생성 방법'; - $lang->thumbnail_crop = '잘라내기 (정해진 크기에 꽉 찬 모습의 썸네일을 만듭니다.)'; - $lang->thumbnail_ratio = '비율 맞추기 (원본 이미지의 비율에 맞춥니다. 다만 정해진 크기에 여백이 생깁니다.)'; - $lang->cmd_delete_all_thumbnail = '썸네일 모두 삭제'; - $lang->title_bold = '제목 굵게'; - $lang->title_color = '제목 색깔'; - $lang->new_document_count = '새 글'; - - $lang->parent_category_title = '상위 카테고리 명'; - $lang->category_title = '분류 명'; - $lang->category_color = '분류 폰트색깔'; - $lang->expand = '펼침'; - $lang->category_group_srls = '그룹 제한'; - - $lang->cmd_make_child = '하위 카테고리 추가'; - $lang->cmd_enable_move_category = '카테고리 위치 변경 (선택 후 위 메뉴를 드래그하세요.)'; - - $lang->about_category_title = '카테고리 이름을 입력해주세요.'; - $lang->about_expand = '선택하시면 늘 펼쳐진 상태로 있게 합니다.'; - $lang->about_category_group_srls = '선택하신 그룹만 현재 카테고리를 지정할 수 있도록 합니다.'; - $lang->about_category_color = '분류 폰트색깔을 지정합니다. 예) red 또는 #ff0000'; - - $lang->cmd_search_next = '계속 검색'; - - $lang->cmd_temp_save = '임시 저장'; - - $lang->cmd_toggle_checked_document = '선택항목 반전'; - $lang->cmd_delete_checked_document = '선택항목 삭제'; - $lang->cmd_document_do = '이 게시물을...'; - - $lang->msg_cart_is_null = '삭제할 글을 선택해주세요.'; - $lang->msg_category_not_moved = '이동할 수 없습니다.'; - $lang->msg_is_secret = '비밀글 입니다.'; - $lang->msg_checked_document_is_deleted = '%d개의 글이 삭제되었습니다.'; - - $lang->move_target_module = '대상 모듈'; - - // 관리자 페이지에서 검색할 대상 - $lang->search_target_list = array( - 'title' => '제목', - 'content' => '내용', - 'user_id' => '아이디', - 'member_srl' => '회원 번호', - 'user_name' => '사용자 이름', - 'nick_name' => '닉네임', - 'email_address' => '이메일', - 'homepage' => '홈페이지', - 'is_notice' => '공지사항', - 'is_secret' => '비밀글', - 'tags' => '태그', - 'readed_count' => '조회 수 (이상)', - 'voted_count' => '추천 수 (이상)', - 'comment_count ' => '코멘트 수 (이상)', - 'trackback_count ' => '트랙백 수 (이상)', - 'uploaded_count ' => '첨부파일 수 (이상)', - 'regdate' => '등록일', - 'last_update' => '최근 수정일', - 'ipaddress' => 'IP 주소', - ); - - $lang->alias = 'Alias'; - $lang->history = '히스토리'; - $lang->about_use_history = '히스토리 기능의 사용여부를 지정합니다. 히스토리 기능을 사용할 경우, 문서 수정 후 이전 수정판으로 복원할 수 있습니다.'; - $lang->trace_only = '흔적만 남김'; - - $lang->cmd_trash = '휴지통'; - $lang->cmd_restore = '복원'; - $lang->cmd_restore_all = '모두 복원'; - - $lang->in_trash = '휴지통'; - $lang->trash_nick_name = '삭제자 닉네임'; - $lang->trash_date = '삭제 날짜'; - $lang->trash_description = '설명'; - - // 관리자 페이지에서 휴지통의 검색할 대상 - $lang->search_target_trash_list = array( - 'title' => '제목', - 'content' => '내용', - 'user_id' => '아이디', - 'member_srl' => '회원 번호', - 'user_name' => '사용자 이름', - 'nick_name' => '닉네임', - 'trash_member_srl' => '삭제자 회원 번호', - 'trash_user_name' => '삭제자 이름', - 'trash_nick_name' => '삭제자 닉네임', - 'trash_date' => '삭제일', - 'trash_ipaddress' => '삭제자 IP 주소', - ); - - $lang->success_trashed = '휴지통으로 이동되었습니다.'; - -?> +document_list = '문서 목록'; + $lang->thumbnail_type = '썸네일 생성 방법'; + $lang->thumbnail_crop = '잘라내기 (정해진 크기에 꽉 찬 모습의 썸네일을 만듭니다.)'; + $lang->thumbnail_ratio = '비율 맞추기 (원본 이미지의 비율에 맞춥니다. 다만 정해진 크기에 여백이 생깁니다.)'; + $lang->cmd_delete_all_thumbnail = '썸네일 모두 삭제'; + $lang->title_bold = '제목 굵게'; + $lang->title_color = '제목 색깔'; + $lang->new_document_count = '새 글'; + + $lang->parent_category_title = '상위 카테고리 명'; + $lang->category_title = '분류 명'; + $lang->category_color = '분류 폰트색깔'; + $lang->expand = '펼침'; + $lang->category_group_srls = '그룹 제한'; + + $lang->cmd_make_child = '하위 카테고리 추가'; + $lang->cmd_enable_move_category = '카테고리 위치 변경 (선택 후 위 메뉴를 드래그하세요.)'; + + $lang->about_category_title = '카테고리 이름을 입력해주세요.'; + $lang->about_expand = '선택하시면 늘 펼쳐진 상태로 있게 합니다.'; + $lang->about_category_group_srls = '선택하신 그룹만 현재 카테고리를 지정할 수 있도록 합니다.'; + $lang->about_category_color = '분류 폰트색깔을 지정합니다. 예) red 또는 #ff0000'; + + $lang->cmd_search_next = '계속 검색'; + + $lang->cmd_temp_save = '임시 저장'; + + $lang->cmd_toggle_checked_document = '선택항목 반전'; + $lang->cmd_delete_checked_document = '선택항목 삭제'; + $lang->cmd_document_do = '이 게시물을...'; + + $lang->msg_cart_is_null = '삭제할 글을 선택해주세요.'; + $lang->msg_category_not_moved = '이동할 수 없습니다.'; + $lang->msg_is_secret = '비밀글 입니다.'; + $lang->msg_checked_document_is_deleted = '%d개의 글이 삭제되었습니다.'; + + $lang->move_target_module = '대상 모듈'; + + // 관리자 페이지에서 검색할 대상 + $lang->search_target_list = array( + 'title' => '제목', + 'content' => '내용', + 'user_id' => '아이디', + 'member_srl' => '회원 번호', + 'user_name' => '사용자 이름', + 'nick_name' => '닉네임', + 'email_address' => '이메일', + 'homepage' => '홈페이지', + 'is_notice' => '공지사항', + 'is_secret' => '비밀글', + 'tags' => '태그', + 'readed_count' => '조회 수 (이상)', + 'voted_count' => '추천 수 (이상)', + 'comment_count ' => '코멘트 수 (이상)', + 'trackback_count ' => '트랙백 수 (이상)', + 'uploaded_count ' => '첨부파일 수 (이상)', + 'regdate' => '등록일', + 'last_update' => '최근 수정일', + 'ipaddress' => 'IP 주소', + ); + + $lang->alias = 'Alias'; + $lang->history = '히스토리'; + $lang->about_use_history = '히스토리 기능의 사용여부를 지정합니다. 히스토리 기능을 사용할 경우, 문서 수정 후 이전 수정판으로 복원할 수 있습니다.'; + $lang->trace_only = '흔적만 남김'; + + $lang->cmd_trash = '휴지통'; + $lang->cmd_restore = '복원'; + $lang->cmd_restore_all = '모두 복원'; + + $lang->in_trash = '휴지통'; + $lang->trash_nick_name = '삭제자 닉네임'; + $lang->trash_date = '삭제 날짜'; + $lang->trash_description = '설명'; + + // 관리자 페이지에서 휴지통의 검색할 대상 + $lang->search_target_trash_list = array( + 'title' => '제목', + 'content' => '내용', + 'user_id' => '아이디', + 'member_srl' => '회원 번호', + 'user_name' => '사용자 이름', + 'nick_name' => '닉네임', + 'trash_member_srl' => '삭제자 회원 번호', + 'trash_user_name' => '삭제자 이름', + 'trash_nick_name' => '삭제자 닉네임', + 'trash_date' => '삭제일', + 'trash_ipaddress' => '삭제자 IP 주소', + ); + + $lang->success_trashed = '휴지통으로 이동되었습니다.'; + +?> diff --git a/modules/document/lang/ru.lang.php b/modules/document/lang/ru.lang.php index 3d6c564ab..a897cb92b 100644 --- a/modules/document/lang/ru.lang.php +++ b/modules/document/lang/ru.lang.php @@ -1,103 +1,103 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->document_list = 'Список документов'; - $lang->thumbnail_type = 'Тип миниатюры'; - $lang->thumbnail_crop = 'Обрезать'; - $lang->thumbnail_ratio = 'Соотношение'; - $lang->cmd_delete_all_thumbnail = 'Удалить все миниарюры'; - $lang->move_target_module = "Переместить в"; - $lang->title_bold = 'Жирное название'; - $lang->title_color = 'Цвет названия'; - $lang->new_document_count = 'Новые документы'; - - $lang->parent_category_title = 'Название верхней категории'; - $lang->category_title = 'Категория'; - $lang->category_color = 'Цвет шрифта категории'; - $lang->expand = 'Развернуть'; - $lang->category_group_srls = 'Доступные группы'; - - $lang->about_category_title = 'Добавьте дочернюю категорию'; - $lang->cmd_enable_move_category = 'Изменить местоположение категории(после выделения перетащите верхнее меню)'; - - $lang->about_category_title = 'Введите название категории'; - $lang->about_expand = 'Если эта опция выбрана, расширение будут применено всегда'; - $lang->about_category_group_srls = 'Только выбранные группы можно отнести к этой категории'; - $lang->about_category_color = 'Установить цвет шрифта категории. ex) red или #ff0000'; - - $lang->cmd_search_next = 'Искать дальше'; - - $lang->about_category_color = '분류 폰트색깔을 지정합니다.'; - $lang->cmd_temp_save = 'Сохранить временно'; - - $lang->cmd_toggle_checked_document = 'Перевернуть выбранные объекты'; - $lang->cmd_delete_checked_document = 'Удалить выбранные'; - $lang->cmd_document_do = 'Эту запись...'; - - $lang->msg_cart_is_null = 'Выберите записи,которые Вы хотите удалить'; - $lang->msg_category_not_moved = 'Невозможно переместить'; - $lang->msg_is_secret = 'Секретная запись'; - $lang->msg_checked_document_is_deleted = '%d записей удалено'; - - $lang->move_target_module = 'Этот модуль'; - - // Search targets in admin page - $lang->search_target_list = array( - 'title' => 'Тема', - 'content' => 'Содержание', - 'user_id' => 'ID пользователя', - 'member_srl' => 'No. пользователя', - 'user_name' => 'Имя пользователя', - 'nick_name' => 'Ник', - 'email_address' => 'Email', - 'homepage' => 'Домашняя страница', - 'is_notice' => 'Объявления', - 'is_secret' => 'Секретная запись', - 'tags' => 'Тег', - 'readed_count' => 'Количество просмотров (свыше)', - 'voted_count' => 'Количество голосов (свыше)', - 'comment_count ' => 'Количество записей (свыше)', - 'trackback_count ' => 'Количество трекбеков (свыше)', - 'uploaded_count ' => 'Количество вложений (прикрепленных файлов) (свыше)', - 'regdate' => 'Дата регистрации', - 'last_update' => 'Дата последнего обновления', - 'ipaddress' => 'IP-Адрес', - ); - - $lang->alias = "Alias"; - $lang->history = "History"; - $lang->about_use_history = "Determine whether to enable history feature, if it is enabled, update history would be stored and possible to restore old revisions."; - $lang->trace_only = "Trace only"; - - $lang->cmd_trash = 'Корзина'; - $lang->cmd_restore = 'Восстановить'; - $lang->cmd_restore_all = 'Восстановить все'; - - $lang->in_trash = 'Корзина'; - $lang->trash_nick_name = 'Ник удалителя'; - $lang->trash_date = 'Дата удаления'; - $lang->trash_description = 'Описание'; - - // Возможен поиск на странице админа - $lang->search_target_trash_list = array( - 'title' => 'Тема', - 'content' => 'Содержание', - 'user_id' => 'ID', - 'member_srl' =>'No пользователя', - 'user_name' => 'Имя пользователя', - 'nick_name' => 'Ник', - 'trash_member_srl' => 'Номер удалителя', - 'trash_user_name' => 'Имя удалителя', - 'trash_nick_name' => 'Ник удалителя', - 'trash_date' => 'Дата удаления', - 'trash_ipaddress' => 'IP адрес удалителя', - ); - - $lang->success_trashed = 'Удалено в корзину'; - - $lang->success_trashed = "Successfully moved to trashcan"; -?> +document_list = 'Список документов'; + $lang->thumbnail_type = 'Тип миниатюры'; + $lang->thumbnail_crop = 'Обрезать'; + $lang->thumbnail_ratio = 'Соотношение'; + $lang->cmd_delete_all_thumbnail = 'Удалить все миниарюры'; + $lang->move_target_module = "Переместить в"; + $lang->title_bold = 'Жирное название'; + $lang->title_color = 'Цвет названия'; + $lang->new_document_count = 'Новые документы'; + + $lang->parent_category_title = 'Название верхней категории'; + $lang->category_title = 'Категория'; + $lang->category_color = 'Цвет шрифта категории'; + $lang->expand = 'Развернуть'; + $lang->category_group_srls = 'Доступные группы'; + + $lang->about_category_title = 'Добавьте дочернюю категорию'; + $lang->cmd_enable_move_category = 'Изменить местоположение категории(после выделения перетащите верхнее меню)'; + + $lang->about_category_title = 'Введите название категории'; + $lang->about_expand = 'Если эта опция выбрана, расширение будут применено всегда'; + $lang->about_category_group_srls = 'Только выбранные группы можно отнести к этой категории'; + $lang->about_category_color = 'Установить цвет шрифта категории. ex) red или #ff0000'; + + $lang->cmd_search_next = 'Искать дальше'; + + $lang->about_category_color = '분류 폰트색깔을 지정합니다.'; + $lang->cmd_temp_save = 'Сохранить временно'; + + $lang->cmd_toggle_checked_document = 'Перевернуть выбранные объекты'; + $lang->cmd_delete_checked_document = 'Удалить выбранные'; + $lang->cmd_document_do = 'Эту запись...'; + + $lang->msg_cart_is_null = 'Выберите записи,которые Вы хотите удалить'; + $lang->msg_category_not_moved = 'Невозможно переместить'; + $lang->msg_is_secret = 'Секретная запись'; + $lang->msg_checked_document_is_deleted = '%d записей удалено'; + + $lang->move_target_module = 'Этот модуль'; + + // Search targets in admin page + $lang->search_target_list = array( + 'title' => 'Тема', + 'content' => 'Содержание', + 'user_id' => 'ID пользователя', + 'member_srl' => 'No. пользователя', + 'user_name' => 'Имя пользователя', + 'nick_name' => 'Ник', + 'email_address' => 'Email', + 'homepage' => 'Домашняя страница', + 'is_notice' => 'Объявления', + 'is_secret' => 'Секретная запись', + 'tags' => 'Тег', + 'readed_count' => 'Количество просмотров (свыше)', + 'voted_count' => 'Количество голосов (свыше)', + 'comment_count ' => 'Количество записей (свыше)', + 'trackback_count ' => 'Количество трекбеков (свыше)', + 'uploaded_count ' => 'Количество вложений (прикрепленных файлов) (свыше)', + 'regdate' => 'Дата регистрации', + 'last_update' => 'Дата последнего обновления', + 'ipaddress' => 'IP-Адрес', + ); + + $lang->alias = "Alias"; + $lang->history = "History"; + $lang->about_use_history = "Determine whether to enable history feature, if it is enabled, update history would be stored and possible to restore old revisions."; + $lang->trace_only = "Trace only"; + + $lang->cmd_trash = 'Корзина'; + $lang->cmd_restore = 'Восстановить'; + $lang->cmd_restore_all = 'Восстановить все'; + + $lang->in_trash = 'Корзина'; + $lang->trash_nick_name = 'Ник удалителя'; + $lang->trash_date = 'Дата удаления'; + $lang->trash_description = 'Описание'; + + // Возможен поиск на странице админа + $lang->search_target_trash_list = array( + 'title' => 'Тема', + 'content' => 'Содержание', + 'user_id' => 'ID', + 'member_srl' =>'No пользователя', + 'user_name' => 'Имя пользователя', + 'nick_name' => 'Ник', + 'trash_member_srl' => 'Номер удалителя', + 'trash_user_name' => 'Имя удалителя', + 'trash_nick_name' => 'Ник удалителя', + 'trash_date' => 'Дата удаления', + 'trash_ipaddress' => 'IP адрес удалителя', + ); + + $lang->success_trashed = 'Удалено в корзину'; + + $lang->success_trashed = "Successfully moved to trashcan"; +?> diff --git a/modules/document/lang/vi.lang.php b/modules/document/lang/vi.lang.php index f7c27fc0f..71e1057a2 100644 --- a/modules/document/lang/vi.lang.php +++ b/modules/document/lang/vi.lang.php @@ -1,101 +1,101 @@ -document_list = 'Danh sách bài viết'; - $lang->thumbnail_type = 'Định dạng hình nhỏ'; - $lang->thumbnail_crop = 'Hình cắt'; - $lang->thumbnail_ratio = 'Tỉ lệ'; - $lang->cmd_delete_all_thumbnail = 'Xóa tất cả hình nhỏ'; - $lang->move_target_module = "Vị trí Module"; - $lang->title_bold = 'Chữ đậm'; - $lang->title_color = 'Màu'; - $lang->new_document_count = 'Bài viết mới'; - - $lang->parent_category_title = 'Tên thể loại chính'; - $lang->category_title = 'Tên thể loại nhỏ'; - $lang->category_color = 'Màu chữ'; - $lang->expand = 'Mở rộng'; - $lang->category_group_srls = 'Nhóm được cho phép'; - - $lang->cmd_make_child = 'Thêm thể loại nhỏ'; - $lang->cmd_enable_move_category = "Thay đổi vị trí thể loại (Kéo lên Menu trên sau khi lựa chọn)"; - - $lang->about_category_title = 'Hãy nhập tên thể loại'; - $lang->about_expand = 'Nếu sử dụng tùy chọn này, Thể loại sẽ luôn luôn được trải rộng.'; - $lang->about_category_group_srls = 'Chỉ những nhóm đã chọn mới được phép sử dụng thể loại này.'; - $lang->about_category_color = 'Bạn có thể đặt màu cho thể loại.'; - - $lang->cmd_search_next = 'Tìm tiếp'; - - $lang->cmd_temp_save = 'Lưu tạm thời'; - - $lang->cmd_toggle_checked_document = 'Khôi phục những bài đã chọn'; - $lang->cmd_delete_checked_document = 'Xóa những bài đã chọn'; - $lang->cmd_document_do = 'Bình chọn / Phê bình'; - - $lang->msg_cart_is_null = 'Xin hãy chọn bài viết để xóa.'; - $lang->msg_category_not_moved = 'Không thể di chuyển'; - $lang->msg_is_secret = 'Bài viết này đã đặt bí mật'; - $lang->msg_checked_document_is_deleted = '%d bài viết đã được xóa.'; - - // Search targets in admin page - $lang->search_target_list = array( - 'title' => 'Tiêu đề', - 'content' => 'Nội dung', - 'user_id' => 'ID sử dụng', - 'member_srl' => 'Mã thành viên', - 'user_name' => 'Tên', - 'nick_name' => 'Nickname', - 'email_address' => 'Email', - 'homepage' => 'Trang chủ', - 'is_notice' => 'Chú ý', - 'is_secret' => 'Bí mật', - 'tags' => 'Tag', - 'readed_count' => 'Lượt xem', - 'voted_count' => 'Lượt bình chọn', - 'comment_count ' => 'Số bình luận', - 'trackback_count ' => 'Số liên kết Web', - 'uploaded_count ' => 'Số đính kèm', - 'regdate' => 'Ngày gửi', - 'last_update' => 'Cập nhật lần cuối', - 'ipaddress' => 'IP', - ); - - $lang->alias = "Bí danh"; - $lang->history = "Lịch sử"; - $lang->about_use_history = "Chức năng này sẽ lưu lại những thay đổi trên bài viết. Nếu sử dụng chức năng này, bạn có thể khôi phục lại trạng thái ban đầu của bài viết."; - $lang->trace_only = "Chỉ theo dõi"; - - $lang->cmd_trash = "Thùng rác"; - $lang->cmd_restore = "Khôi phục"; - $lang->cmd_restore_all = "Khôi phục tất cả"; - - $lang->in_trash = "Thùng rác"; - $lang->trash_nick_name = "Người xóa"; - $lang->trash_date = "Ngày xóa"; - $lang->trash_description = "Mô tả"; - - // 관리자 페이지에서 휴지통의 검색할 대상 - $lang->search_target_trash_list = array( - 'title' => 'Tiêu đề', - 'content' => 'Nội dung', - 'user_id' => 'ID', - 'member_srl' => 'Mã số thành viên', - 'user_name' => 'Tên thật', - 'nick_name' => 'NickName', - 'trash_member_srl' => 'Mã số người xóa', - 'trash_user_name' => 'Tên người xóa', - 'trash_nick_name' => 'NickName người xóa', - 'trash_date' => 'Ngày xóa', - 'trash_ipaddress' => 'IP Người xóa', - ); - - $lang->success_trashed = "Đã chuyển tới thùng rác thành công."; -?> +document_list = 'Danh sách bài viết'; + $lang->thumbnail_type = 'Định dạng hình nhỏ'; + $lang->thumbnail_crop = 'Hình cắt'; + $lang->thumbnail_ratio = 'Tỉ lệ'; + $lang->cmd_delete_all_thumbnail = 'Xóa tất cả hình nhỏ'; + $lang->move_target_module = "Vị trí Module"; + $lang->title_bold = 'Chữ đậm'; + $lang->title_color = 'Màu'; + $lang->new_document_count = 'Bài viết mới'; + + $lang->parent_category_title = 'Tên thể loại chính'; + $lang->category_title = 'Tên thể loại nhỏ'; + $lang->category_color = 'Màu chữ'; + $lang->expand = 'Mở rộng'; + $lang->category_group_srls = 'Nhóm được cho phép'; + + $lang->cmd_make_child = 'Thêm thể loại nhỏ'; + $lang->cmd_enable_move_category = "Thay đổi vị trí thể loại (Kéo lên Menu trên sau khi lựa chọn)"; + + $lang->about_category_title = 'Hãy nhập tên thể loại'; + $lang->about_expand = 'Nếu sử dụng tùy chọn này, Thể loại sẽ luôn luôn được trải rộng.'; + $lang->about_category_group_srls = 'Chỉ những nhóm đã chọn mới được phép sử dụng thể loại này.'; + $lang->about_category_color = 'Bạn có thể đặt màu cho thể loại.'; + + $lang->cmd_search_next = 'Tìm tiếp'; + + $lang->cmd_temp_save = 'Lưu tạm thời'; + + $lang->cmd_toggle_checked_document = 'Khôi phục những bài đã chọn'; + $lang->cmd_delete_checked_document = 'Xóa những bài đã chọn'; + $lang->cmd_document_do = 'Bình chọn / Phê bình'; + + $lang->msg_cart_is_null = 'Xin hãy chọn bài viết để xóa.'; + $lang->msg_category_not_moved = 'Không thể di chuyển'; + $lang->msg_is_secret = 'Bài viết này đã đặt bí mật'; + $lang->msg_checked_document_is_deleted = '%d bài viết đã được xóa.'; + + // Search targets in admin page + $lang->search_target_list = array( + 'title' => 'Tiêu đề', + 'content' => 'Nội dung', + 'user_id' => 'ID sử dụng', + 'member_srl' => 'Mã thành viên', + 'user_name' => 'Tên', + 'nick_name' => 'Nickname', + 'email_address' => 'Email', + 'homepage' => 'Trang chủ', + 'is_notice' => 'Chú ý', + 'is_secret' => 'Bí mật', + 'tags' => 'Tag', + 'readed_count' => 'Lượt xem', + 'voted_count' => 'Lượt bình chọn', + 'comment_count ' => 'Số bình luận', + 'trackback_count ' => 'Số liên kết Web', + 'uploaded_count ' => 'Số đính kèm', + 'regdate' => 'Ngày gửi', + 'last_update' => 'Cập nhật lần cuối', + 'ipaddress' => 'IP', + ); + + $lang->alias = "Bí danh"; + $lang->history = "Lịch sử"; + $lang->about_use_history = "Chức năng này sẽ lưu lại những thay đổi trên bài viết. Nếu sử dụng chức năng này, bạn có thể khôi phục lại trạng thái ban đầu của bài viết."; + $lang->trace_only = "Chỉ theo dõi"; + + $lang->cmd_trash = "Thùng rác"; + $lang->cmd_restore = "Khôi phục"; + $lang->cmd_restore_all = "Khôi phục tất cả"; + + $lang->in_trash = "Thùng rác"; + $lang->trash_nick_name = "Người xóa"; + $lang->trash_date = "Ngày xóa"; + $lang->trash_description = "Mô tả"; + + // 관리자 페이지에서 휴지통의 검색할 대상 + $lang->search_target_trash_list = array( + 'title' => 'Tiêu đề', + 'content' => 'Nội dung', + 'user_id' => 'ID', + 'member_srl' => 'Mã số thành viên', + 'user_name' => 'Tên thật', + 'nick_name' => 'NickName', + 'trash_member_srl' => 'Mã số người xóa', + 'trash_user_name' => 'Tên người xóa', + 'trash_nick_name' => 'NickName người xóa', + 'trash_date' => 'Ngày xóa', + 'trash_ipaddress' => 'IP Người xóa', + ); + + $lang->success_trashed = "Đã chuyển tới thùng rác thành công."; +?> diff --git a/modules/document/lang/zh-CN.lang.php b/modules/document/lang/zh-CN.lang.php index 7c0261c3c..fd71634db 100644 --- a/modules/document/lang/zh-CN.lang.php +++ b/modules/document/lang/zh-CN.lang.php @@ -1,100 +1,100 @@ - - * @brief 文章(document)模块语言包 - **/ - - $lang->document_list = '主题列表'; - $lang->thumbnail_type = '缩略图生成方式'; - $lang->thumbnail_crop = '裁减(按指定大小裁剪图片)'; - $lang->thumbnail_ratio = '比例(按原图比例缩略处理)'; - $lang->cmd_delete_all_thumbnail = '删除全部缩略图'; - $lang->title_bold = '粗标题'; - $lang->title_color = '标题颜色'; - $lang->new_document_count = '新帖'; - - $lang->parent_category_title = '上级分类名'; - $lang->category_title = '分类名'; - $lang->category_color = '分类颜色'; - $lang->expand = '展开'; - $lang->category_group_srls = '用户组'; - - $lang->cmd_make_child = '添加下级分类'; - $lang->cmd_enable_move_category = "分类顺序(勾选后用鼠标拖动分类项)"; - - $lang->about_category_title = '请输入分类名。'; - $lang->about_expand = '选择此项将维持展开状态。'; - $lang->about_category_group_srls = '所选用户组才可以查看此分类。'; - $lang->about_category_color = '请指定分类颜色(必须带#符号)。ex)#ff0000'; - - $lang->cmd_search_next = '继续搜索'; - - $lang->cmd_temp_save = '临时保存'; - - $lang->cmd_toggle_checked_document = '反选'; - $lang->cmd_delete_checked_document = '删除所选'; - $lang->cmd_document_do = '将把此主题..'; - - $lang->msg_cart_is_null = '请选择要删除的文章。'; - $lang->msg_category_not_moved = '不能移动!'; - $lang->msg_is_secret = '这是密帖!'; - $lang->msg_checked_document_is_deleted = '删除了%d个文章。'; - - $lang->move_target_module = '目标模块'; - - // 管理页面查找的对象 - $lang->search_target_list = array( - 'title' => '标题', - 'content' => '内容', - 'user_id' => 'I D', - 'member_srl' => '会员编号', - 'user_name' => '姓名', - 'nick_name' => '昵称', - 'email_address' => '电子邮件', - 'homepage' => '主页', - 'is_notice' => '公告', - 'is_secret' => '密帖', - 'tags' => '标签', - 'readed_count' => '查看数(以上)', - 'voted_count' => '推荐数(以上)', - 'comment_count ' => '评论数(以上)', - 'trackback_count ' => '引用数(以上)', - 'uploaded_count ' => '上传附件数(以上)', - 'regdate' => '登录日期', - 'last_update' => '最近更新日期', - 'ipaddress' => 'IP 地址', - ); - - $lang->alias = "Alias"; - $lang->history = "历史版本功能"; - $lang->about_use_history = "启用历史版本功能它将记录主题修改版本,并还可以复原到之前版本。"; - $lang->trace_only = "只留痕迹"; - - $lang->cmd_trash = "回收箱"; - $lang->cmd_restore = "复原"; - $lang->cmd_restore_all = "全部复原"; - - $lang->in_trash = "回收箱"; - $lang->trash_nick_name = "操作人昵称"; - $lang->trash_date = "删除日期"; - $lang->trash_description = "说明"; - - // 管理页面回收箱搜索对象 - $lang->search_target_trash_list = array( - 'title' => '标题', - 'content' => '内容', - 'user_id' => '用户名', - 'member_srl' => '会员编号', - 'user_name' => '姓名', - 'nick_name' => '昵称', - 'trash_member_srl' => '操作人会员编号', - 'trash_user_name' => '操作人用户名', - 'trash_nick_name' => '操作人昵称', - 'trash_date' => '删除日期', - 'trash_ipaddress' => '操作人IP地址', - ); - - $lang->success_trashed = '已成功移除到回收箱。'; - -?> +document_list = '主题列表'; + $lang->thumbnail_type = '缩略图生成方式'; + $lang->thumbnail_crop = '裁减(按指定大小裁剪图片)'; + $lang->thumbnail_ratio = '比例(按原图比例缩略处理)'; + $lang->cmd_delete_all_thumbnail = '删除全部缩略图'; + $lang->title_bold = '粗标题'; + $lang->title_color = '标题颜色'; + $lang->new_document_count = '新帖'; + + $lang->parent_category_title = '上级分类名'; + $lang->category_title = '分类名'; + $lang->category_color = '分类颜色'; + $lang->expand = '展开'; + $lang->category_group_srls = '用户组'; + + $lang->cmd_make_child = '添加下级分类'; + $lang->cmd_enable_move_category = "分类顺序(勾选后用鼠标拖动分类项)"; + + $lang->about_category_title = '请输入分类名。'; + $lang->about_expand = '选择此项将维持展开状态。'; + $lang->about_category_group_srls = '所选用户组才可以查看此分类。'; + $lang->about_category_color = '请指定分类颜色(必须带#符号)。ex)#ff0000'; + + $lang->cmd_search_next = '继续搜索'; + + $lang->cmd_temp_save = '临时保存'; + + $lang->cmd_toggle_checked_document = '反选'; + $lang->cmd_delete_checked_document = '删除所选'; + $lang->cmd_document_do = '将把此主题..'; + + $lang->msg_cart_is_null = '请选择要删除的文章。'; + $lang->msg_category_not_moved = '不能移动!'; + $lang->msg_is_secret = '这是密帖!'; + $lang->msg_checked_document_is_deleted = '删除了%d个文章。'; + + $lang->move_target_module = '目标模块'; + + // 管理页面查找的对象 + $lang->search_target_list = array( + 'title' => '标题', + 'content' => '内容', + 'user_id' => 'I D', + 'member_srl' => '会员编号', + 'user_name' => '姓名', + 'nick_name' => '昵称', + 'email_address' => '电子邮件', + 'homepage' => '主页', + 'is_notice' => '公告', + 'is_secret' => '密帖', + 'tags' => '标签', + 'readed_count' => '查看数(以上)', + 'voted_count' => '推荐数(以上)', + 'comment_count ' => '评论数(以上)', + 'trackback_count ' => '引用数(以上)', + 'uploaded_count ' => '上传附件数(以上)', + 'regdate' => '登录日期', + 'last_update' => '最近更新日期', + 'ipaddress' => 'IP 地址', + ); + + $lang->alias = "Alias"; + $lang->history = "历史版本功能"; + $lang->about_use_history = "启用历史版本功能它将记录主题修改版本,并还可以复原到之前版本。"; + $lang->trace_only = "只留痕迹"; + + $lang->cmd_trash = "回收箱"; + $lang->cmd_restore = "复原"; + $lang->cmd_restore_all = "全部复原"; + + $lang->in_trash = "回收箱"; + $lang->trash_nick_name = "操作人昵称"; + $lang->trash_date = "删除日期"; + $lang->trash_description = "说明"; + + // 管理页面回收箱搜索对象 + $lang->search_target_trash_list = array( + 'title' => '标题', + 'content' => '内容', + 'user_id' => '用户名', + 'member_srl' => '会员编号', + 'user_name' => '姓名', + 'nick_name' => '昵称', + 'trash_member_srl' => '操作人会员编号', + 'trash_user_name' => '操作人用户名', + 'trash_nick_name' => '操作人昵称', + 'trash_date' => '删除日期', + 'trash_ipaddress' => '操作人IP地址', + ); + + $lang->success_trashed = '已成功移除到回收箱。'; + +?> diff --git a/modules/document/lang/zh-TW.lang.php b/modules/document/lang/zh-TW.lang.php index 853d81eb2..fbc88be4e 100644 --- a/modules/document/lang/zh-TW.lang.php +++ b/modules/document/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 文章(document)模組正體中文語言 **/ diff --git a/modules/document/tpl/js/document_category.js b/modules/document/tpl/js/document_category.js index 300eb289b..5ec3fc492 100644 --- a/modules/document/tpl/js/document_category.js +++ b/modules/document/tpl/js/document_category.js @@ -1,6 +1,6 @@ /** * @file modules/document/tpl/js/document_category.js - * @author sol (sol@ngleader.com) + * @author NHN (developers@xpressengine.com) * @brief document 모듈의 category tree javascript **/ diff --git a/modules/editor/components/emoticon/emoticon.class.php b/modules/editor/components/emoticon/emoticon.class.php index b0f252dd8..0909ee578 100644 --- a/modules/editor/components/emoticon/emoticon.class.php +++ b/modules/editor/components/emoticon/emoticon.class.php @@ -1,107 +1,107 @@ -editor_sequence = $editor_sequence; - $this->component_path = $component_path; - $this->emoticon_path = sprintf('%s%s/images',preg_replace('/^\.\//i','',$this->component_path),'tpl','images'); - } - - /** - * @brief 이모티콘 파일 목록을 리턴 - **/ - function getEmoticonList() { - $emoticon = Context::get('emoticon'); - if(!$emoticon || !preg_match("/^([a-z0-9\_]+)$/i",$emoticon)) return new Object(-1,'msg_invalid_request'); - - $list = $this->getEmoticons($emoticon); - - $this->add('emoticons', implode("\n",$list)); - } - - /** - * @brief 재귀적으로 이모티콘이 될 법한 파일들을 하위 디렉토리까지 전부 검색한다. 8,000개까지는 테스트 해봤는데 스택오버프로우를 일으킬지 어떨지는 잘 모르겠음.(2007.9.6, 베니) - **/ - function getEmoticons($path) { - $emoticon_path = sprintf("%s/%s", $this->emoticon_path, $path); - $output = array(); - - $oDir = dir($emoticon_path); - while($file = $oDir->read()) { - if(substr($file,0,1)=='.') continue; - if(preg_match('/\.(jpg|jpeg|gif|png)$/i',$file)) $output[] = sprintf("%s/%s", $path, str_replace($this->emoticon_path,'',$file)); - } - $oDir->close(); - if(count($output)) asort($output); - return $output; - } - - /** - * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 - **/ - function getPopupContent() { - // 이모티콘 디렉토리 목록을 가져옴 - $emoticon_dirs = FileHandler::readDir($this->emoticon_path); - $emoticon_list = array(); - if($emoticon_dirs) { - foreach($emoticon_dirs as $emoticon) { - if(preg_match("/^([a-z0-9\_]+)$/i", $emoticon)) $emoticon_list[] = $emoticon; - } - } - Context::set('emoticon_list', $emoticon_list); - - // 첫번째 이모티콘 디렉토리의 이미지 파일을 구함 - $emoticons = $this->getEmoticons($emoticon_list[0]); - Context::set('emoticons', $emoticons); - - // 템플릿을 미리 컴파일해서 컴파일된 소스를 return - $tpl_path = $this->component_path.'tpl'; - $tpl_file = 'popup.html'; - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($tpl_path, $tpl_file); - } - - /** - * @brief 이모티콘의 경로 문제 해결을 하기 위해 추가하였다. (2007.9.6 베니) - **/ - function transHTML($xml_obj) { - $src = $xml_obj->attrs->src; - $alt = $xml_obj->attrs->alt; - - if(!$alt) { - $tmp_arr = explode('/',$src); - $alt = array_pop($tmp_arr); - } - - $src = str_replace(array('&','"'), array('&','&qout;'), $src); - if(!$alt) $alt = $src; - - $attr_output = array(); - $attr_output = array("src=\"".$src."\""); - - if($alt) { - $attr_output[] = "alt=\"".$alt."\""; - } - if(preg_match("/\.png$/i",$src)) $attr_output[] = "class=\"iePngFix\""; - - $code = sprintf("", implode(" ",$attr_output)); - - return $code; - } - } -?> +editor_sequence = $editor_sequence; + $this->component_path = $component_path; + $this->emoticon_path = sprintf('%s%s/images',preg_replace('/^\.\//i','',$this->component_path),'tpl','images'); + } + + /** + * @brief 이모티콘 파일 목록을 리턴 + **/ + function getEmoticonList() { + $emoticon = Context::get('emoticon'); + if(!$emoticon || !preg_match("/^([a-z0-9\_]+)$/i",$emoticon)) return new Object(-1,'msg_invalid_request'); + + $list = $this->getEmoticons($emoticon); + + $this->add('emoticons', implode("\n",$list)); + } + + /** + * @brief 재귀적으로 이모티콘이 될 법한 파일들을 하위 디렉토리까지 전부 검색한다. 8,000개까지는 테스트 해봤는데 스택오버프로우를 일으킬지 어떨지는 잘 모르겠음.(2007.9.6, 베니) + **/ + function getEmoticons($path) { + $emoticon_path = sprintf("%s/%s", $this->emoticon_path, $path); + $output = array(); + + $oDir = dir($emoticon_path); + while($file = $oDir->read()) { + if(substr($file,0,1)=='.') continue; + if(preg_match('/\.(jpg|jpeg|gif|png)$/i',$file)) $output[] = sprintf("%s/%s", $path, str_replace($this->emoticon_path,'',$file)); + } + $oDir->close(); + if(count($output)) asort($output); + return $output; + } + + /** + * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 + **/ + function getPopupContent() { + // 이모티콘 디렉토리 목록을 가져옴 + $emoticon_dirs = FileHandler::readDir($this->emoticon_path); + $emoticon_list = array(); + if($emoticon_dirs) { + foreach($emoticon_dirs as $emoticon) { + if(preg_match("/^([a-z0-9\_]+)$/i", $emoticon)) $emoticon_list[] = $emoticon; + } + } + Context::set('emoticon_list', $emoticon_list); + + // 첫번째 이모티콘 디렉토리의 이미지 파일을 구함 + $emoticons = $this->getEmoticons($emoticon_list[0]); + Context::set('emoticons', $emoticons); + + // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + $tpl_path = $this->component_path.'tpl'; + $tpl_file = 'popup.html'; + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + /** + * @brief 이모티콘의 경로 문제 해결을 하기 위해 추가하였다. (2007.9.6 베니) + **/ + function transHTML($xml_obj) { + $src = $xml_obj->attrs->src; + $alt = $xml_obj->attrs->alt; + + if(!$alt) { + $tmp_arr = explode('/',$src); + $alt = array_pop($tmp_arr); + } + + $src = str_replace(array('&','"'), array('&','&qout;'), $src); + if(!$alt) $alt = $src; + + $attr_output = array(); + $attr_output = array("src=\"".$src."\""); + + if($alt) { + $attr_output[] = "alt=\"".$alt."\""; + } + if(preg_match("/\.png$/i",$src)) $attr_output[] = "class=\"iePngFix\""; + + $code = sprintf("", implode(" ",$attr_output)); + + return $code; + } + } +?> diff --git a/modules/editor/components/emoticon/info.xml b/modules/editor/components/emoticon/info.xml index 45ff46a62..afac7764d 100644 --- a/modules/editor/components/emoticon/info.xml +++ b/modules/editor/components/emoticon/info.xml @@ -1,32 +1,32 @@ - - - 이모티콘 출력 - 顔文字(イモティコン) - 表情图标 - Display Emoticons - Diễn tả cảm xúc - Mostrar iconos gestuales - Отображение смайлов - 表情符號 - 이모티콘을 에디터에 삽입할 수 있습니다. - 顔文字(イモティコン)をエディターに追加することが出来ます。 - 可以插入表情图标到编辑器。 - You may insert emoticons to editor. - Bạn có thể chèn biểu tượng cảm xúc vào bài viết. - Usted puede insertar emoticonos para el editor. - Вы можете вставить смыйлы в редактор. - 可插入表情符號到編輯器。 - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 이모티콘 출력 + 顔文字(イモティコン) + 表情图标 + Display Emoticons + Diễn tả cảm xúc + Mostrar iconos gestuales + Отображение смайлов + 表情符號 + 이모티콘을 에디터에 삽입할 수 있습니다. + 顔文字(イモティコン)をエディターに追加することが出来ます。 + 可以插入表情图标到编辑器。 + You may insert emoticons to editor. + Bạn có thể chèn biểu tượng cảm xúc vào bài viết. + Usted puede insertar emoticonos para el editor. + Вы можете вставить смыйлы в редактор. + 可插入表情符號到編輯器。 + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/components/image_gallery/image_gallery.class.php b/modules/editor/components/image_gallery/image_gallery.class.php index a686dcb39..05ecd286e 100644 --- a/modules/editor/components/image_gallery/image_gallery.class.php +++ b/modules/editor/components/image_gallery/image_gallery.class.php @@ -1,81 +1,81 @@ -editor_sequence = $editor_sequence; - $this->component_path = $component_path; - } - - /** - * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 - **/ - function getPopupContent() { - // 템플릿을 미리 컴파일해서 컴파일된 소스를 return - $tpl_path = $this->component_path.'tpl'; - $tpl_file = 'popup.html'; - - Context::set("tpl_path", $tpl_path); - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($tpl_path, $tpl_file); - } - - /** - * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method - * - * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 - * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 - **/ - function transHTML($xml_obj) { - $gallery_info->srl = rand(111111,999999); - $gallery_info->border_thickness = $xml_obj->attrs->border_thickness; - $gallery_info->gallery_style = $xml_obj->attrs->gallery_style; - $gallery_info->border_color = $xml_obj->attrs->border_color; - $gallery_info->bg_color = $xml_obj->attrs->bg_color; - $gallery_info->gallery_align = $xml_obj->attrs->gallery_align; - - $images_list = $xml_obj->attrs->images_list; - $images_list = preg_replace('/\.(gif|jpg|jpeg|png) /i',".\\1\n",$images_list); - $gallery_info->images_list = explode("\n",trim($images_list)); - - // 만약 출력설정이 XML일 경우 이미지 목록만 출력하도록 코드 생성 - if(Context::getResponseMethod() == 'XMLRPC') { - $output = ''; - for($i=0;$iimages_list);$i++) { - $output .= sprintf('
', $gallery_info->images_list[$i]); - } - return $output; - } - - // HTML 출력일 경우 템플릿 변환을 거쳐서 갤러리 출력 설정에 맞는 html코드를 생성하도록 함 - preg_match_all('/(width|height)([^[:digit:]]+)([0-9]+)/i',$xml_obj->attrs->style,$matches); - $gallery_info->width = trim($matches[3][0]); - if(!$gallery_info->width) $gallery_info->width = 400; - - Context::set('gallery_info', $gallery_info); - - $tpl_path = $this->component_path.'tpl'; - Context::set("tpl_path", $tpl_path); - - if($gallery_info->gallery_style == "list") $tpl_file = 'list_gallery.html'; - else $tpl_file = 'slide_gallery.html'; - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($tpl_path, $tpl_file); - } - - } -?> +editor_sequence = $editor_sequence; + $this->component_path = $component_path; + } + + /** + * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 + **/ + function getPopupContent() { + // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + $tpl_path = $this->component_path.'tpl'; + $tpl_file = 'popup.html'; + + Context::set("tpl_path", $tpl_path); + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + /** + * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method + * + * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 + * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 + **/ + function transHTML($xml_obj) { + $gallery_info->srl = rand(111111,999999); + $gallery_info->border_thickness = $xml_obj->attrs->border_thickness; + $gallery_info->gallery_style = $xml_obj->attrs->gallery_style; + $gallery_info->border_color = $xml_obj->attrs->border_color; + $gallery_info->bg_color = $xml_obj->attrs->bg_color; + $gallery_info->gallery_align = $xml_obj->attrs->gallery_align; + + $images_list = $xml_obj->attrs->images_list; + $images_list = preg_replace('/\.(gif|jpg|jpeg|png) /i',".\\1\n",$images_list); + $gallery_info->images_list = explode("\n",trim($images_list)); + + // 만약 출력설정이 XML일 경우 이미지 목록만 출력하도록 코드 생성 + if(Context::getResponseMethod() == 'XMLRPC') { + $output = ''; + for($i=0;$iimages_list);$i++) { + $output .= sprintf('
', $gallery_info->images_list[$i]); + } + return $output; + } + + // HTML 출력일 경우 템플릿 변환을 거쳐서 갤러리 출력 설정에 맞는 html코드를 생성하도록 함 + preg_match_all('/(width|height)([^[:digit:]]+)([0-9]+)/i',$xml_obj->attrs->style,$matches); + $gallery_info->width = trim($matches[3][0]); + if(!$gallery_info->width) $gallery_info->width = 400; + + Context::set('gallery_info', $gallery_info); + + $tpl_path = $this->component_path.'tpl'; + Context::set("tpl_path", $tpl_path); + + if($gallery_info->gallery_style == "list") $tpl_file = 'list_gallery.html'; + else $tpl_file = 'slide_gallery.html'; + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + } +?> diff --git a/modules/editor/components/image_gallery/info.xml b/modules/editor/components/image_gallery/info.xml index 8d027674e..570a4051e 100644 --- a/modules/editor/components/image_gallery/info.xml +++ b/modules/editor/components/image_gallery/info.xml @@ -1,32 +1,32 @@ - - - Slide Show - 기본 이미지 갤러리 - デフォルトイメージギャラリー - 图片相册 - Basic Image Gallery - Galería de imágenes básicos - Базовая галлерея изображений - 預設圖片相簿 - Bạn có thể tạo ra một Slide Show theo dạng danh sách hoặc Slide từ những hình ảnh đính kèm của mình. - 첨부된 이미지파일을 이용하여 슬라이드/목록형 이미지 갤러리를 만들 수 있습니다. - 添付されたイメージファイルを利用して、スライド型・リスト型のイメージギャラリーが作成できます。 - 利用上传的图片文件实现幻灯片式或目录型相册图片。 - It can create image gallery of slide/list style by using attached image file. - It can create image gallery of slide/list style by using attached image file. - Это может создать гллерею изображений в стиле слайдов/списка, используя вложенный файл изображения. - 將上傳的圖片以投影片或列表的形式實現。 - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + Slide Show + 기본 이미지 갤러리 + デフォルトイメージギャラリー + 图片相册 + Basic Image Gallery + Galería de imágenes básicos + Базовая галлерея изображений + 預設圖片相簿 + Bạn có thể tạo ra một Slide Show theo dạng danh sách hoặc Slide từ những hình ảnh đính kèm của mình. + 첨부된 이미지파일을 이용하여 슬라이드/목록형 이미지 갤러리를 만들 수 있습니다. + 添付されたイメージファイルを利用して、スライド型・リスト型のイメージギャラリーが作成できます。 + 利用上传的图片文件实现幻灯片式或目录型相册图片。 + It can create image gallery of slide/list style by using attached image file. + It can create image gallery of slide/list style by using attached image file. + Это может создать гллерею изображений в стиле слайдов/списка, используя вложенный файл изображения. + 將上傳的圖片以投影片或列表的形式實現。 + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/components/image_gallery/lang/en.lang.php b/modules/editor/components/image_gallery/lang/en.lang.php index ab8e4d901..23c267c36 100644 --- a/modules/editor/components/image_gallery/lang/en.lang.php +++ b/modules/editor/components/image_gallery/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor module > language pack of image_gallery component. **/ diff --git a/modules/editor/components/image_gallery/lang/es.lang.php b/modules/editor/components/image_gallery/lang/es.lang.php index 0c164fc38..b9355d4d7 100644 --- a/modules/editor/components/image_gallery/lang/es.lang.php +++ b/modules/editor/components/image_gallery/lang/es.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor module > language pack of image_gallery component. **/ diff --git a/modules/editor/components/image_gallery/lang/jp.lang.php b/modules/editor/components/image_gallery/lang/jp.lang.php index 1405c6c9e..8e2b37c0d 100644 --- a/modules/editor/components/image_gallery/lang/jp.lang.php +++ b/modules/editor/components/image_gallery/lang/jp.lang.php @@ -1,27 +1,27 @@ - 翻訳:RisaPapa、ミニミ - * @brief ウィジウィグエディター(editor)モジュール > イメージギャラリー(image_gallery)コンポネント言語パッケージ - **/ - - $lang->image_gallery = "イメージギャラリー作成"; - $lang->width = "横幅サイズ"; - $lang->height = "縦幅サイズ"; - $lang->image_list = "イメージリスト"; - $lang->gallery_style = "ギャラリースタイル"; - $lang->gallery_slide_style = "スライドスタイル"; - $lang->gallery_slide_align = "アライン位置"; - $lang->gallery_slide_center = "中央揃え"; - $lang->gallery_slide_left = "左揃え"; - $lang->gallery_slide_right = "右揃え"; - $lang->gallery_list_style = "展開表示(リスト)"; - $lang->gallery_border_color = "ボーダーカラー"; - $lang->gallery_border_thickness = "ボーダー"; - $lang->gallery_bg_color = "背景色"; - $lang->about_image_list = "イメージギャラリーに追加するファイルを選択して下さい。選択した後、ドラッグまたは「Shift+クリック(範囲選択)、Ctrl+クリック(個別選択)」が出来ます。"; - - $lang->cmd_gallery_prev = "前のイメージ表示"; - $lang->cmd_gallery_next = "次のイメージ表示"; - $lang->cmd_gallery_thumbnail = "サムネール表示"; -?> + イメージギャラリー(image_gallery)コンポネント言語パッケージ + **/ + + $lang->image_gallery = "イメージギャラリー作成"; + $lang->width = "横幅サイズ"; + $lang->height = "縦幅サイズ"; + $lang->image_list = "イメージリスト"; + $lang->gallery_style = "ギャラリースタイル"; + $lang->gallery_slide_style = "スライドスタイル"; + $lang->gallery_slide_align = "アライン位置"; + $lang->gallery_slide_center = "中央揃え"; + $lang->gallery_slide_left = "左揃え"; + $lang->gallery_slide_right = "右揃え"; + $lang->gallery_list_style = "展開表示(リスト)"; + $lang->gallery_border_color = "ボーダーカラー"; + $lang->gallery_border_thickness = "ボーダー"; + $lang->gallery_bg_color = "背景色"; + $lang->about_image_list = "イメージギャラリーに追加するファイルを選択して下さい。選択した後、ドラッグまたは「Shift+クリック(範囲選択)、Ctrl+クリック(個別選択)」が出来ます。"; + + $lang->cmd_gallery_prev = "前のイメージ表示"; + $lang->cmd_gallery_next = "次のイメージ表示"; + $lang->cmd_gallery_thumbnail = "サムネール表示"; +?> diff --git a/modules/editor/components/image_gallery/lang/ko.lang.php b/modules/editor/components/image_gallery/lang/ko.lang.php index 210964823..37e614c7e 100644 --- a/modules/editor/components/image_gallery/lang/ko.lang.php +++ b/modules/editor/components/image_gallery/lang/ko.lang.php @@ -1,27 +1,27 @@ - - * @brief 위지윅에디터(editor) 모듈 > 이미지갤러리(image_gallery) 컴포넌트의 언어팩 - **/ - - $lang->image_gallery = '이미지 갤러리 제작'; - $lang->width = '가로'; - $lang->height = '세로'; - $lang->image_list = '이미지 목록'; - $lang->gallery_style = '갤러리 형식 '; - $lang->gallery_slide_style = '슬라이드 형식'; - $lang->gallery_slide_align = '정렬방식'; - $lang->gallery_slide_center = '가운데'; - $lang->gallery_slide_left = '왼쪽'; - $lang->gallery_slide_right = '오른쪽'; - $lang->gallery_list_style = '모두 펼침'; - $lang->gallery_border_color = '테두리 색'; - $lang->gallery_border_thickness = '테두리 두께'; - $lang->gallery_bg_color = '배경색'; - $lang->about_image_list = '이미지 갤러리에 추가할 파일을 선택하세요. 선택 후 드래그 또는 shift+클릭(범위선택), ctrl+클릭(개별선택) 가능합니다.'; - - $lang->cmd_gallery_prev = '이전 그림 보기'; - $lang->cmd_gallery_next = '다음 그림 보기'; - $lang->cmd_gallery_thumbnail = '썸네일 보기'; -?> + 이미지갤러리(image_gallery) 컴포넌트의 언어팩 + **/ + + $lang->image_gallery = '이미지 갤러리 제작'; + $lang->width = '가로'; + $lang->height = '세로'; + $lang->image_list = '이미지 목록'; + $lang->gallery_style = '갤러리 형식 '; + $lang->gallery_slide_style = '슬라이드 형식'; + $lang->gallery_slide_align = '정렬방식'; + $lang->gallery_slide_center = '가운데'; + $lang->gallery_slide_left = '왼쪽'; + $lang->gallery_slide_right = '오른쪽'; + $lang->gallery_list_style = '모두 펼침'; + $lang->gallery_border_color = '테두리 색'; + $lang->gallery_border_thickness = '테두리 두께'; + $lang->gallery_bg_color = '배경색'; + $lang->about_image_list = '이미지 갤러리에 추가할 파일을 선택하세요. 선택 후 드래그 또는 shift+클릭(범위선택), ctrl+클릭(개별선택) 가능합니다.'; + + $lang->cmd_gallery_prev = '이전 그림 보기'; + $lang->cmd_gallery_next = '다음 그림 보기'; + $lang->cmd_gallery_thumbnail = '썸네일 보기'; +?> diff --git a/modules/editor/components/image_gallery/lang/ru.lang.php b/modules/editor/components/image_gallery/lang/ru.lang.php index 55dfb9455..e9a585eab 100644 --- a/modules/editor/components/image_gallery/lang/ru.lang.php +++ b/modules/editor/components/image_gallery/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief editor module > language pack of image_gallery component. **/ diff --git a/modules/editor/components/image_gallery/lang/vi.lang.php b/modules/editor/components/image_gallery/lang/vi.lang.php index 96637d0a4..5934406c5 100644 --- a/modules/editor/components/image_gallery/lang/vi.lang.php +++ b/modules/editor/components/image_gallery/lang/vi.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 网页编辑器(editor) 模块 > 图像(image_gallery) 组件的语言包 **/ diff --git a/modules/editor/components/image_gallery/lang/zh-TW.lang.php b/modules/editor/components/image_gallery/lang/zh-TW.lang.php index 25093e5be..430b4c80a 100644 --- a/modules/editor/components/image_gallery/lang/zh-TW.lang.php +++ b/modules/editor/components/image_gallery/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 網頁編輯器(editor) 模組 > 圖片(image_gallery) 組件的語言 **/ diff --git a/modules/editor/components/image_gallery/tpl/list_gallery.js b/modules/editor/components/image_gallery/tpl/list_gallery.js index 5b369d75d..85d7c0e4d 100644 --- a/modules/editor/components/image_gallery/tpl/list_gallery.js +++ b/modules/editor/components/image_gallery/tpl/list_gallery.js @@ -1,82 +1,82 @@ -/** - * @file list_gallery.js - * @brief 이미지 이미지갤러리 쇼 스크립트 - * @author zero (zero@nzeo.com) - **/ - -// 이미지갤러리쇼를 하기 위한 변수 -var list_gallery_images = new Array(); - -// 이미지갤러리쇼 이미지 목록에 추가 -function list_gallery_add_image(srl, image_url) { - if(!image_url) return; - if(image_url.indexOf('files')==0) image_url = request_uri+image_url; - - // 객체 생성 - var obj = {"srl":0, "image_url":null, "image":null} - - // list_gallery_images에 이미지갤러리 쇼 고유번호에 해당하는 공간을 초기화 - if(typeof(list_gallery_images[srl])=="undefined") list_gallery_images[srl] = new Array(); - - // 이미지갤러리쇼 고유번호를 세팅 - obj.srl = srl; - obj.idx = list_gallery_images[srl].length; - - // 원본 이미지를 미리 로딩 - obj.image = new Image(); - obj.image.src = image_url; - obj.image.srl = obj.srl; - obj.image.idx = obj.idx; - - // 생성된 객체를 list_gallery_images[이미지갤러리쇼 고유번호]에 추가 - list_gallery_images[srl][list_gallery_images[srl].length] = obj; -} - -// 이미지갤러리쇼 시작 -function start_list_gallery() { - - // 등록된 모든 이미지 목록을 돌면서 목록을 만들어줌 - for(var srl in list_gallery_images) { - - // 등록된 이미지가 없으면 pass~ - if(!list_gallery_images[srl].length) continue; - - // 메인이미지가 나올 곳과 썸네일이 노출될 곳의 객체를 구함 - var zone = xGetElementById('zone_list_gallery_'+srl); - - // 갤러리 외부 박스보다 이미지가 클 경우 resizing시킴 - var borderTop = parseInt(zone.style.borderTopWidth.replace(/px$/,''),10); - var borderLeft = parseInt(zone.style.borderLeftWidth.replace(/px$/,''),10); - var borderRight = parseInt(zone.style.borderRightWidth.replace(/px$/,''),10); - var borderBottom = parseInt(zone.style.borderBottomWidth.replace(/px$/,''),10); - - var zone_width = xWidth(zone)-borderLeft-borderRight; - - // 이미지 출력 - for(var i=0; i(zone_width-25)) { - resize_scale = (zone_width-25)/image_width; - image_width = parseInt(image_width*resize_scale,10); - image_height = parseInt(image_height*resize_scale,10); - } - - obj.image.style.width = image_width+"px"; - obj.image.style.height = image_height+"px"; - obj.image.style.marginLeft = "10px"; - obj.image.style.marginBottom = "10px"; - obj.image.style.display = "block"; - - // 리사이즈 되었다면 resize_image 애드온의 slideshow() 기능 사용 - if(resize_scale != 1) obj.image.rel = 'xe_gallery'; - - zone.appendChild(obj.image); - } - zone.style.paddingTop = "10px"; - } -} +/** + * @file list_gallery.js + * @brief 이미지 이미지갤러리 쇼 스크립트 + * @author NHN (developers@xpressengine.com) + **/ + +// 이미지갤러리쇼를 하기 위한 변수 +var list_gallery_images = new Array(); + +// 이미지갤러리쇼 이미지 목록에 추가 +function list_gallery_add_image(srl, image_url) { + if(!image_url) return; + if(image_url.indexOf('files')==0) image_url = request_uri+image_url; + + // 객체 생성 + var obj = {"srl":0, "image_url":null, "image":null} + + // list_gallery_images에 이미지갤러리 쇼 고유번호에 해당하는 공간을 초기화 + if(typeof(list_gallery_images[srl])=="undefined") list_gallery_images[srl] = new Array(); + + // 이미지갤러리쇼 고유번호를 세팅 + obj.srl = srl; + obj.idx = list_gallery_images[srl].length; + + // 원본 이미지를 미리 로딩 + obj.image = new Image(); + obj.image.src = image_url; + obj.image.srl = obj.srl; + obj.image.idx = obj.idx; + + // 생성된 객체를 list_gallery_images[이미지갤러리쇼 고유번호]에 추가 + list_gallery_images[srl][list_gallery_images[srl].length] = obj; +} + +// 이미지갤러리쇼 시작 +function start_list_gallery() { + + // 등록된 모든 이미지 목록을 돌면서 목록을 만들어줌 + for(var srl in list_gallery_images) { + + // 등록된 이미지가 없으면 pass~ + if(!list_gallery_images[srl].length) continue; + + // 메인이미지가 나올 곳과 썸네일이 노출될 곳의 객체를 구함 + var zone = xGetElementById('zone_list_gallery_'+srl); + + // 갤러리 외부 박스보다 이미지가 클 경우 resizing시킴 + var borderTop = parseInt(zone.style.borderTopWidth.replace(/px$/,''),10); + var borderLeft = parseInt(zone.style.borderLeftWidth.replace(/px$/,''),10); + var borderRight = parseInt(zone.style.borderRightWidth.replace(/px$/,''),10); + var borderBottom = parseInt(zone.style.borderBottomWidth.replace(/px$/,''),10); + + var zone_width = xWidth(zone)-borderLeft-borderRight; + + // 이미지 출력 + for(var i=0; i(zone_width-25)) { + resize_scale = (zone_width-25)/image_width; + image_width = parseInt(image_width*resize_scale,10); + image_height = parseInt(image_height*resize_scale,10); + } + + obj.image.style.width = image_width+"px"; + obj.image.style.height = image_height+"px"; + obj.image.style.marginLeft = "10px"; + obj.image.style.marginBottom = "10px"; + obj.image.style.display = "block"; + + // 리사이즈 되었다면 resize_image 애드온의 slideshow() 기능 사용 + if(resize_scale != 1) obj.image.rel = 'xe_gallery'; + + zone.appendChild(obj.image); + } + zone.style.paddingTop = "10px"; + } +} diff --git a/modules/editor/components/image_gallery/tpl/slide_gallery.js b/modules/editor/components/image_gallery/tpl/slide_gallery.js index 22190d208..8ecf8696a 100644 --- a/modules/editor/components/image_gallery/tpl/slide_gallery.js +++ b/modules/editor/components/image_gallery/tpl/slide_gallery.js @@ -1,196 +1,196 @@ -/** - * @file slide_gallery.js - * @brief 이미지 이미지갤러리 쇼 스크립트 - * @author zero (zero@nzeo.com) - **/ - -// 이미지갤러리쇼를 하기 위한 변수 -var slide_gallery_images = new Array(); -var thumbnail_zone_height = new Array(); - -// 이미지갤러리쇼 이미지 목록에 추가 -function slide_gallery_add_image(srl, image_url) { - if(!image_url) return; - if(image_url.indexOf('files')==0) image_url = request_uri+image_url; - - // 객체 생성 - var obj = {"srl":0, "thumbnail_url":null, "thumbnail":null, "image_url":null, "image":null} - - // slide_gallery_images에 이미지갤러리 쇼 고유번호에 해당하는 공간을 초기화 - if(typeof(slide_gallery_images[srl])=="undefined") slide_gallery_images[srl] = new Array(); - - // 이미지갤러리쇼 고유번호를 세팅 - obj.srl = srl; - obj.idx = slide_gallery_images[srl].length; - obj.image_url = image_url; - - // 원본 이미지를 미리 로딩 - obj.image = new Image(); - obj.image.src = image_url; - //if(!obj.image.width) return; - - // 썸네일 이미지를 미리 로딩 - obj.thumbnail = new Image(); - obj.thumbnail.src = image_url; - obj.thumbnail.style.cursor = "pointer"; - obj.thumbnail.style.width = "60px"; - obj.thumbnail.style.height = "60px"; - obj.thumbnail.style.margin = "5px"; - obj.thumbnail.style.opacity = 0.5; - obj.thumbnail.style.filter = "alpha(opacity=50)"; - - // 썸네일 클릭시 메인 이미지로 바꾸어줌 - xAddEventListener(obj.thumbnail, "mousedown", function() { display_gallery_image(obj) }); - - // 생성된 객체를 slide_gallery_images[이미지갤러리쇼 고유번호]에 추가 - slide_gallery_images[srl][slide_gallery_images[srl].length] = obj; -} - -// 이미지갤러리쇼 시작 -function start_slide_gallery() { - - // 등록된 모든 이미지 목록을 돌면서 thumbnail 목록을 만들어줌 - for(var srl in slide_gallery_images) { - - // 등록된 이미지가 없으면 pass~ - if(!slide_gallery_images[srl].length) continue; - - // 메인이미지가 나올 곳과 썸네일이 노출될 곳의 객체를 구함 - var zone_thumbnail = xGetElementById('zone_thumbnail_'+srl); - - // 썸네일 출력 - for(var i=0; i(zone_width-20)) { - resize_scale = (zone_width-20)/image_width; - image_width = parseInt(image_width*resize_scale,10); - image_height = parseInt(image_height*resize_scale,10); - } - var x = parseInt((zone_width - image_width)/2,10); - - // 이미지 표시 - var target_image = xGetElementById("slide_gallery_main_image_"+obj.srl); - - target_image.style.marginLeft = x+"px"; - - target_image.srl = obj.srl; - target_image.idx = obj.idx; - target_image.style.opacity = 1; - target_image.style.filter = "alpha(opacity=100)"; - target_image.start_opacity = 0; - xWidth(target_image, image_width); - xHeight(target_image, image_height); - target_image.src = obj.image.src; - - if(image_height<200) { - target_image.style.marginTop = (100-image_height/2)+"px"; - target_image.style.marginBottom = (100-image_height/2)+"px"; - } else { - target_image.style.marginTop = "10px"; - target_image.style.marginBottom = "10px"; - } - - if(typeof(showOriginalImage)=='function') { - if(resize_scale!=1) { - xAddEventListener(target_image, 'click', showOriginalImage); - target_image.style.cursor = 'pointer'; - } else { - xRemoveEventListener(target_image, 'click', showOriginalImage); - target_image.style.cursor = 'default'; - } - } - - // resize_scale이 1이 아니면, 즉 리사이즈 되었다면 해당 이미지 클릭시 원본을 새창으로 띄워줌 - var next_idx = obj.idx+1; - if(slide_gallery_images[obj.srl].length<=next_idx) next_idx = 0; - - // srl의 모든 썸네일의 투명도 조절 - for(var i=0; i"+decodeURI(filename)+""); - - // 네이게이션 영역의 숫자 변경 - var zone_navigator = xGetElementById("zone_gallery_navigator_status_"+obj.srl); - var html = (obj.idx+1) + " / " + slide_gallery_images[obj.srl].length; - xInnerHtml(zone_navigator, html); -} - -// 이전 보기 -function gallery_view_prev(srl) { - var target_image = xGetElementById("slide_gallery_main_image_"+srl); - var idx = target_image.idx; - var max_length = slide_gallery_images[srl].length; - idx--; - if(idx<0) idx = max_length-1; - display_gallery_image(slide_gallery_images[srl][idx]); -} - -// 다음 보기 -function gallery_view_next(srl) { - var target_image = xGetElementById("slide_gallery_main_image_"+srl); - var idx = target_image.idx; - var max_length = slide_gallery_images[srl].length; - idx++; - if(idx>max_length-1) idx = 0; - display_gallery_image(slide_gallery_images[srl][idx]); -} - -// 썸네일 보기 -function gallery_view_thumbnail(srl) { - var thumbnail_zone = xGetElementById("zone_thumbnail_"+srl); - if(thumbnail_zone.style.display == "none") thumbnail_zone.style.display = "block"; - else thumbnail_zone.style.display = "none"; -} - +/** + * @file slide_gallery.js + * @brief 이미지 이미지갤러리 쇼 스크립트 + * @author NHN (developers@xpressengine.com) + **/ + +// 이미지갤러리쇼를 하기 위한 변수 +var slide_gallery_images = new Array(); +var thumbnail_zone_height = new Array(); + +// 이미지갤러리쇼 이미지 목록에 추가 +function slide_gallery_add_image(srl, image_url) { + if(!image_url) return; + if(image_url.indexOf('files')==0) image_url = request_uri+image_url; + + // 객체 생성 + var obj = {"srl":0, "thumbnail_url":null, "thumbnail":null, "image_url":null, "image":null} + + // slide_gallery_images에 이미지갤러리 쇼 고유번호에 해당하는 공간을 초기화 + if(typeof(slide_gallery_images[srl])=="undefined") slide_gallery_images[srl] = new Array(); + + // 이미지갤러리쇼 고유번호를 세팅 + obj.srl = srl; + obj.idx = slide_gallery_images[srl].length; + obj.image_url = image_url; + + // 원본 이미지를 미리 로딩 + obj.image = new Image(); + obj.image.src = image_url; + //if(!obj.image.width) return; + + // 썸네일 이미지를 미리 로딩 + obj.thumbnail = new Image(); + obj.thumbnail.src = image_url; + obj.thumbnail.style.cursor = "pointer"; + obj.thumbnail.style.width = "60px"; + obj.thumbnail.style.height = "60px"; + obj.thumbnail.style.margin = "5px"; + obj.thumbnail.style.opacity = 0.5; + obj.thumbnail.style.filter = "alpha(opacity=50)"; + + // 썸네일 클릭시 메인 이미지로 바꾸어줌 + xAddEventListener(obj.thumbnail, "mousedown", function() { display_gallery_image(obj) }); + + // 생성된 객체를 slide_gallery_images[이미지갤러리쇼 고유번호]에 추가 + slide_gallery_images[srl][slide_gallery_images[srl].length] = obj; +} + +// 이미지갤러리쇼 시작 +function start_slide_gallery() { + + // 등록된 모든 이미지 목록을 돌면서 thumbnail 목록을 만들어줌 + for(var srl in slide_gallery_images) { + + // 등록된 이미지가 없으면 pass~ + if(!slide_gallery_images[srl].length) continue; + + // 메인이미지가 나올 곳과 썸네일이 노출될 곳의 객체를 구함 + var zone_thumbnail = xGetElementById('zone_thumbnail_'+srl); + + // 썸네일 출력 + for(var i=0; i(zone_width-20)) { + resize_scale = (zone_width-20)/image_width; + image_width = parseInt(image_width*resize_scale,10); + image_height = parseInt(image_height*resize_scale,10); + } + var x = parseInt((zone_width - image_width)/2,10); + + // 이미지 표시 + var target_image = xGetElementById("slide_gallery_main_image_"+obj.srl); + + target_image.style.marginLeft = x+"px"; + + target_image.srl = obj.srl; + target_image.idx = obj.idx; + target_image.style.opacity = 1; + target_image.style.filter = "alpha(opacity=100)"; + target_image.start_opacity = 0; + xWidth(target_image, image_width); + xHeight(target_image, image_height); + target_image.src = obj.image.src; + + if(image_height<200) { + target_image.style.marginTop = (100-image_height/2)+"px"; + target_image.style.marginBottom = (100-image_height/2)+"px"; + } else { + target_image.style.marginTop = "10px"; + target_image.style.marginBottom = "10px"; + } + + if(typeof(showOriginalImage)=='function') { + if(resize_scale!=1) { + xAddEventListener(target_image, 'click', showOriginalImage); + target_image.style.cursor = 'pointer'; + } else { + xRemoveEventListener(target_image, 'click', showOriginalImage); + target_image.style.cursor = 'default'; + } + } + + // resize_scale이 1이 아니면, 즉 리사이즈 되었다면 해당 이미지 클릭시 원본을 새창으로 띄워줌 + var next_idx = obj.idx+1; + if(slide_gallery_images[obj.srl].length<=next_idx) next_idx = 0; + + // srl의 모든 썸네일의 투명도 조절 + for(var i=0; i"+decodeURI(filename)+""); + + // 네이게이션 영역의 숫자 변경 + var zone_navigator = xGetElementById("zone_gallery_navigator_status_"+obj.srl); + var html = (obj.idx+1) + " / " + slide_gallery_images[obj.srl].length; + xInnerHtml(zone_navigator, html); +} + +// 이전 보기 +function gallery_view_prev(srl) { + var target_image = xGetElementById("slide_gallery_main_image_"+srl); + var idx = target_image.idx; + var max_length = slide_gallery_images[srl].length; + idx--; + if(idx<0) idx = max_length-1; + display_gallery_image(slide_gallery_images[srl][idx]); +} + +// 다음 보기 +function gallery_view_next(srl) { + var target_image = xGetElementById("slide_gallery_main_image_"+srl); + var idx = target_image.idx; + var max_length = slide_gallery_images[srl].length; + idx++; + if(idx>max_length-1) idx = 0; + display_gallery_image(slide_gallery_images[srl][idx]); +} + +// 썸네일 보기 +function gallery_view_thumbnail(srl) { + var thumbnail_zone = xGetElementById("zone_thumbnail_"+srl); + if(thumbnail_zone.style.display == "none") thumbnail_zone.style.display = "block"; + else thumbnail_zone.style.display = "none"; +} + diff --git a/modules/editor/components/image_link/image_link.class.php b/modules/editor/components/image_link/image_link.class.php index 794ccd362..a6bda7807 100644 --- a/modules/editor/components/image_link/image_link.class.php +++ b/modules/editor/components/image_link/image_link.class.php @@ -1,108 +1,108 @@ -editor_sequence = $editor_sequence; - $this->component_path = $component_path; - } - - /** - * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 - **/ - function getPopupContent() { - // 템플릿을 미리 컴파일해서 컴파일된 소스를 return - $tpl_path = $this->component_path.'tpl'; - $tpl_file = 'popup.html'; - - Context::set("tpl_path", $tpl_path); - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($tpl_path, $tpl_file); - } - - /** - * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method - * - * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 - * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 - **/ - function transHTML($xml_obj) { - $src = $xml_obj->attrs->src; - $width = $xml_obj->attrs->width; - $height = $xml_obj->attrs->height; - $align = $xml_obj->attrs->align; - $alt = $xml_obj->attrs->alt; - $border = (int)$xml_obj->attrs->border; - $link_url = $xml_obj->attrs->link_url; - $open_window = $xml_obj->attrs->open_window; - $style = $xml_obj->attrs->style; - $margin = (int)$xml_obj->attrs->margin; - - if(!$alt) { - $tmp_arr = explode('/',$src); - $alt = array_pop($tmp_arr); - } - - $src = str_replace(array('&','"'), array('&','&qout;'), $src); - $src = str_replace('&amp;', '&', $src); - - if(!$alt) $alt = $src; - // 이미지 주소를 request uri가 포함된 주소로 변환 (rss출력, 등등을 위함) - $temp_src = explode('/', $src); - if(substr($src, 0,2)=='./') $src = Context::getRequestUri().substr($src, 2); - elseif(substr($src , 0, 1)=='/') { - if($_SERVER['HTTPS']=='on') $http_src = 'https://'; - else $http_src = 'http://'; - $src = $http_src.$_SERVER['HTTP_HOST'].$src; - } - elseif(!strpos($temp_src[0],':') && $src) $src = Context::getRequestUri().$src; - - $attr_output = array(); - $attr_output = array("src=\"".$src."\""); - if($alt) { - $attr_output[] = "alt=\"".$alt."\""; - $attr_output[] = "title=\"".$alt."\""; - } - if($margin) { - $style = trim(preg_replace('/margin[a-z\-]*[ ]*:[ ]*[0-9 a-z]+(;| )/i','', $style)).';'; - $style = str_replace(';;',';',$style); - if($style == ';') $style = ''; - $style .= ' margin:'.$margin.'px;'; - } - if($align) $attr_output[] = "align=\"".$align."\""; - - if(preg_match("/\.png$/i",$src)) $attr_output[] = "class=\"iePngFix\""; - - if($width) $attr_output[] = 'width="'.$width.'"'; - if($height) $attr_output[] = 'height="'.$height.'"'; - if($border) { - $style = trim(preg_replace('/border[a-z\-]*[ ]*:[ ]*[0-9 a-z]+(;| )/i','', $style)).';'; - $style = str_replace(';;',';',$style); - if($style == ';') $style = ''; - $style .= ' border-style: solid; border-width:'.$border.'px;'; - } - - $code = sprintf("", implode(' ',$attr_output), $style); - - if($link_url) { - if($open_window =='Y') $code = sprintf('%s', $link_url, $code); - else $code = sprintf('%s', $link_url, $code); - } - return $code; - } - - } -?> +editor_sequence = $editor_sequence; + $this->component_path = $component_path; + } + + /** + * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 + **/ + function getPopupContent() { + // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + $tpl_path = $this->component_path.'tpl'; + $tpl_file = 'popup.html'; + + Context::set("tpl_path", $tpl_path); + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + /** + * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method + * + * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 + * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 + **/ + function transHTML($xml_obj) { + $src = $xml_obj->attrs->src; + $width = $xml_obj->attrs->width; + $height = $xml_obj->attrs->height; + $align = $xml_obj->attrs->align; + $alt = $xml_obj->attrs->alt; + $border = (int)$xml_obj->attrs->border; + $link_url = $xml_obj->attrs->link_url; + $open_window = $xml_obj->attrs->open_window; + $style = $xml_obj->attrs->style; + $margin = (int)$xml_obj->attrs->margin; + + if(!$alt) { + $tmp_arr = explode('/',$src); + $alt = array_pop($tmp_arr); + } + + $src = str_replace(array('&','"'), array('&','&qout;'), $src); + $src = str_replace('&amp;', '&', $src); + + if(!$alt) $alt = $src; + // 이미지 주소를 request uri가 포함된 주소로 변환 (rss출력, 등등을 위함) + $temp_src = explode('/', $src); + if(substr($src, 0,2)=='./') $src = Context::getRequestUri().substr($src, 2); + elseif(substr($src , 0, 1)=='/') { + if($_SERVER['HTTPS']=='on') $http_src = 'https://'; + else $http_src = 'http://'; + $src = $http_src.$_SERVER['HTTP_HOST'].$src; + } + elseif(!strpos($temp_src[0],':') && $src) $src = Context::getRequestUri().$src; + + $attr_output = array(); + $attr_output = array("src=\"".$src."\""); + if($alt) { + $attr_output[] = "alt=\"".$alt."\""; + $attr_output[] = "title=\"".$alt."\""; + } + if($margin) { + $style = trim(preg_replace('/margin[a-z\-]*[ ]*:[ ]*[0-9 a-z]+(;| )/i','', $style)).';'; + $style = str_replace(';;',';',$style); + if($style == ';') $style = ''; + $style .= ' margin:'.$margin.'px;'; + } + if($align) $attr_output[] = "align=\"".$align."\""; + + if(preg_match("/\.png$/i",$src)) $attr_output[] = "class=\"iePngFix\""; + + if($width) $attr_output[] = 'width="'.$width.'"'; + if($height) $attr_output[] = 'height="'.$height.'"'; + if($border) { + $style = trim(preg_replace('/border[a-z\-]*[ ]*:[ ]*[0-9 a-z]+(;| )/i','', $style)).';'; + $style = str_replace(';;',';',$style); + if($style == ';') $style = ''; + $style .= ' border-style: solid; border-width:'.$border.'px;'; + } + + $code = sprintf("", implode(' ',$attr_output), $style); + + if($link_url) { + if($open_window =='Y') $code = sprintf('%s', $link_url, $code); + else $code = sprintf('%s', $link_url, $code); + } + return $code; + } + + } +?> diff --git a/modules/editor/components/image_link/info.xml b/modules/editor/components/image_link/info.xml index e2ba8cc7d..2bd5c02f3 100644 --- a/modules/editor/components/image_link/info.xml +++ b/modules/editor/components/image_link/info.xml @@ -1,32 +1,32 @@ - - - 이미지 추가 - イメージ追加 - 插入图像 - Add Images - Thêm hình ảnh - Añadir imágenes - Добавление изображений - 圖片連結 - 에디터에 이미지를 추가하거나 속성을 변경할 수 있습니다. - エディターでイメージの追加、属性の変更が出来ます。 - 可以插入图像或编辑其相应属性。 - It can add an image to editor or change the attribution of image. - Bạn có thể thêm hình ảnh để sửa hay chia sẻ. - Se puede añadir una imagen a editor o cambiar la atribución de la imagen. - Это может добавить изображение в редактор или изменить параметры изображения. - 可以新增或編輯其相關屬性。 - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 이미지 추가 + イメージ追加 + 插入图像 + Add Images + Thêm hình ảnh + Añadir imágenes + Добавление изображений + 圖片連結 + 에디터에 이미지를 추가하거나 속성을 변경할 수 있습니다. + エディターでイメージの追加、属性の変更が出来ます。 + 可以插入图像或编辑其相应属性。 + It can add an image to editor or change the attribution of image. + Bạn có thể thêm hình ảnh để sửa hay chia sẻ. + Se puede añadir una imagen a editor o cambiar la atribución de la imagen. + Это может добавить изображение в редактор или изменить параметры изображения. + 可以新增或編輯其相關屬性。 + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/components/image_link/lang/en.lang.php b/modules/editor/components/image_link/lang/en.lang.php index 568914d1d..0f21f84d5 100644 --- a/modules/editor/components/image_link/lang/en.lang.php +++ b/modules/editor/components/image_link/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor Module > language pack of image_link component **/ diff --git a/modules/editor/components/image_link/lang/es.lang.php b/modules/editor/components/image_link/lang/es.lang.php index 221d794a0..46f63bacd 100644 --- a/modules/editor/components/image_link/lang/es.lang.php +++ b/modules/editor/components/image_link/lang/es.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor Module > language pack of image_link component **/ diff --git a/modules/editor/components/image_link/lang/jp.lang.php b/modules/editor/components/image_link/lang/jp.lang.php index 5cba9384a..d53e4cd6b 100644 --- a/modules/editor/components/image_link/lang/jp.lang.php +++ b/modules/editor/components/image_link/lang/jp.lang.php @@ -1,23 +1,23 @@ - 翻訳:RisaPapa、ミニミ - * @brief ウィジウィグエディター(editor)モジュール > イメージリンク(image_link)コンポネント言語パッケージ - **/ - - $lang->image_url = 'イメージパス'; - $lang->image_alt = '説明(Alt)入力'; - $lang->image_scale = 'イメージサイズ'; - $lang->image_align = 'アライン位置'; - $lang->image_align_normal = '一段落'; - $lang->image_align_left = '左揃え'; - $lang->image_align_middle = '中央揃え'; - $lang->image_align_right = '右揃え'; - $lang->image_border = 'ボーダー'; - $lang->image_margin = '外側の空白(Margin)'; - - $lang->urllink_open_window = '新しいウィンドウで開く'; - $lang->about_url_link_open_window = 'チェックすると、リンクをクリックする際、新しいウィンドウで開きます。'; - - $lang->cmd_get_scale = 'イメージサイズを計算'; -?> + イメージリンク(image_link)コンポネント言語パッケージ + **/ + + $lang->image_url = 'イメージパス'; + $lang->image_alt = '説明(Alt)入力'; + $lang->image_scale = 'イメージサイズ'; + $lang->image_align = 'アライン位置'; + $lang->image_align_normal = '一段落'; + $lang->image_align_left = '左揃え'; + $lang->image_align_middle = '中央揃え'; + $lang->image_align_right = '右揃え'; + $lang->image_border = 'ボーダー'; + $lang->image_margin = '外側の空白(Margin)'; + + $lang->urllink_open_window = '新しいウィンドウで開く'; + $lang->about_url_link_open_window = 'チェックすると、リンクをクリックする際、新しいウィンドウで開きます。'; + + $lang->cmd_get_scale = 'イメージサイズを計算'; +?> diff --git a/modules/editor/components/image_link/lang/ko.lang.php b/modules/editor/components/image_link/lang/ko.lang.php index 0ba78cb44..79b4bff96 100644 --- a/modules/editor/components/image_link/lang/ko.lang.php +++ b/modules/editor/components/image_link/lang/ko.lang.php @@ -1,23 +1,23 @@ - - * @brief 위지윅에디터(editor) 모듈 > 이미지링크(image_link) 컴포넌트의 언어팩 - **/ - - $lang->image_url = '이미지 경로'; - $lang->image_alt = '설명 입력'; - $lang->image_scale = '이미지 크기'; - $lang->image_align = '정렬 방법'; - $lang->image_align_normal = '한 문단을 차지'; - $lang->image_align_left = '글의 왼쪽으로'; - $lang->image_align_middle = '가운데'; - $lang->image_align_right = '글의 우측으로'; - $lang->image_border = '경계선 두께'; - $lang->image_margin = '바깥 여백'; - - $lang->urllink_open_window = '새 창 열기'; - $lang->about_url_link_open_window = '선택하시면 링크 선택 시 새 창으로 열립니다.'; - - $lang->cmd_get_scale = '가로세로 구하기'; -?> + 이미지링크(image_link) 컴포넌트의 언어팩 + **/ + + $lang->image_url = '이미지 경로'; + $lang->image_alt = '설명 입력'; + $lang->image_scale = '이미지 크기'; + $lang->image_align = '정렬 방법'; + $lang->image_align_normal = '한 문단을 차지'; + $lang->image_align_left = '글의 왼쪽으로'; + $lang->image_align_middle = '가운데'; + $lang->image_align_right = '글의 우측으로'; + $lang->image_border = '경계선 두께'; + $lang->image_margin = '바깥 여백'; + + $lang->urllink_open_window = '새 창 열기'; + $lang->about_url_link_open_window = '선택하시면 링크 선택 시 새 창으로 열립니다.'; + + $lang->cmd_get_scale = '가로세로 구하기'; +?> diff --git a/modules/editor/components/image_link/lang/ru.lang.php b/modules/editor/components/image_link/lang/ru.lang.php index 26424e0e1..27354e5ae 100644 --- a/modules/editor/components/image_link/lang/ru.lang.php +++ b/modules/editor/components/image_link/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief editor Module > language pack of image_link component **/ diff --git a/modules/editor/components/image_link/lang/vi.lang.php b/modules/editor/components/image_link/lang/vi.lang.php index 034ed9fea..df986db6e 100644 --- a/modules/editor/components/image_link/lang/vi.lang.php +++ b/modules/editor/components/image_link/lang/vi.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 网页编辑器(editor) 模块 > 图像链接(image_link) 组件的语言包 **/ diff --git a/modules/editor/components/image_link/lang/zh-TW.lang.php b/modules/editor/components/image_link/lang/zh-TW.lang.php index f3873b679..1c63b2e22 100644 --- a/modules/editor/components/image_link/lang/zh-TW.lang.php +++ b/modules/editor/components/image_link/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 網頁編輯器(editor)模組 > 圖片連結(image_link)組件語言 **/ diff --git a/modules/editor/components/multimedia_link/info.xml b/modules/editor/components/multimedia_link/info.xml index 99fbab0d3..90d465e51 100644 --- a/modules/editor/components/multimedia_link/info.xml +++ b/modules/editor/components/multimedia_link/info.xml @@ -1,32 +1,32 @@ - - - 멀티미디어 자료 관리 - マルチメディア管理 - 多媒体 - Manage Multimedia Data - Administrar datos multimedia - Управление мультимедиа данными - 多媒體管理 - Chèn Media vào bài viết - 에디터에 wmv,avi,flv등의 멀티미디어 자료를 추가하거나 속성을 수정할 수 있습니다. - エディターに拡張子が「wmv,avi,flv」などのマルチメディアコンテンツを追加、または属性の修正ができます。 - 插入wmv,avi,flv等多媒体文件或修改其相应属性 。 - It can add multimedia data like wmv,avi,flv to editor or change the attribution of multimedia data. - Se pueden agregar datos multimedia como wmv, avi, flv al editor o cambiar la atribución de datos multimedia. - Это может добавить мультимедиа данные как wmv,avi,flv в редактор или изменить параметры данных мультимедиа. - 可新增 wmv、avi、flv 等多媒體檔案或修改其相關屬性。 - Chèn Media dạng '.wmv,.avi,.flv,.mp3,.wma' vào bài viết. - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 멀티미디어 자료 관리 + マルチメディア管理 + 多媒体 + Manage Multimedia Data + Administrar datos multimedia + Управление мультимедиа данными + 多媒體管理 + Chèn Media vào bài viết + 에디터에 wmv,avi,flv등의 멀티미디어 자료를 추가하거나 속성을 수정할 수 있습니다. + エディターに拡張子が「wmv,avi,flv」などのマルチメディアコンテンツを追加、または属性の修正ができます。 + 插入wmv,avi,flv等多媒体文件或修改其相应属性 。 + It can add multimedia data like wmv,avi,flv to editor or change the attribution of multimedia data. + Se pueden agregar datos multimedia como wmv, avi, flv al editor o cambiar la atribución de datos multimedia. + Это может добавить мультимедиа данные как wmv,avi,flv в редактор или изменить параметры данных мультимедиа. + 可新增 wmv、avi、flv 等多媒體檔案或修改其相關屬性。 + Chèn Media dạng '.wmv,.avi,.flv,.mp3,.wma' vào bài viết. + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/components/multimedia_link/lang/en.lang.php b/modules/editor/components/multimedia_link/lang/en.lang.php index f6e6fd1b6..7b33ccba7 100644 --- a/modules/editor/components/multimedia_link/lang/en.lang.php +++ b/modules/editor/components/multimedia_link/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor module > language pack of multimedia_link component **/ diff --git a/modules/editor/components/multimedia_link/lang/es.lang.php b/modules/editor/components/multimedia_link/lang/es.lang.php index 6c0c53f28..bf537550c 100644 --- a/modules/editor/components/multimedia_link/lang/es.lang.php +++ b/modules/editor/components/multimedia_link/lang/es.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor module > language pack of multimedia_link component **/ diff --git a/modules/editor/components/multimedia_link/lang/jp.lang.php b/modules/editor/components/multimedia_link/lang/jp.lang.php index 6b81251a5..2e25f1659 100644 --- a/modules/editor/components/multimedia_link/lang/jp.lang.php +++ b/modules/editor/components/multimedia_link/lang/jp.lang.php @@ -1,18 +1,18 @@ - 翻訳:RisaPapa、ミニミ - * @brief ウィジウィグエディター(editor)モジュール > マルチメディアリンク((multimedia_link)コンポネント言語パッケージ - **/ - - $lang->multimedia_url = "マルチメディアのパス"; - $lang->multimedia_caption = "説明入力"; - $lang->multimedia_width = "横幅サイズ"; - $lang->multimedia_height = "縦幅サイズ"; - $lang->multimedia_auto_start = "自動再生"; - $lang->multimedia_wmode = '位置'; - - $lang->multimedia_wmode_window = '常に上へ'; - $lang->multimedia_wmode_opaque = '不透明背景'; - $lang->multimedia_wmode_transparent = '透明背景'; -?> + マルチメディアリンク((multimedia_link)コンポネント言語パッケージ + **/ + + $lang->multimedia_url = "マルチメディアのパス"; + $lang->multimedia_caption = "説明入力"; + $lang->multimedia_width = "横幅サイズ"; + $lang->multimedia_height = "縦幅サイズ"; + $lang->multimedia_auto_start = "自動再生"; + $lang->multimedia_wmode = '位置'; + + $lang->multimedia_wmode_window = '常に上へ'; + $lang->multimedia_wmode_opaque = '不透明背景'; + $lang->multimedia_wmode_transparent = '透明背景'; +?> diff --git a/modules/editor/components/multimedia_link/lang/ko.lang.php b/modules/editor/components/multimedia_link/lang/ko.lang.php index 1da590e2a..8a5adc012 100644 --- a/modules/editor/components/multimedia_link/lang/ko.lang.php +++ b/modules/editor/components/multimedia_link/lang/ko.lang.php @@ -1,18 +1,18 @@ - - * @brief 위지윅에디터(editor) 모듈 > 멀티미디어 링크 (multimedia_link) 컴포넌트의 언어팩 - **/ - - $lang->multimedia_url = '멀티미디어 경로'; - $lang->multimedia_caption = '설명 입력'; - $lang->multimedia_width = '가로'; - $lang->multimedia_height = '세로'; - $lang->multimedia_auto_start = '자동 시작'; - $lang->multimedia_wmode = '위치'; - - $lang->multimedia_wmode_window = '항상 위'; - $lang->multimedia_wmode_opaque = '배경 불투명'; - $lang->multimedia_wmode_transparent = '배경 투명'; -?> + 멀티미디어 링크 (multimedia_link) 컴포넌트의 언어팩 + **/ + + $lang->multimedia_url = '멀티미디어 경로'; + $lang->multimedia_caption = '설명 입력'; + $lang->multimedia_width = '가로'; + $lang->multimedia_height = '세로'; + $lang->multimedia_auto_start = '자동 시작'; + $lang->multimedia_wmode = '위치'; + + $lang->multimedia_wmode_window = '항상 위'; + $lang->multimedia_wmode_opaque = '배경 불투명'; + $lang->multimedia_wmode_transparent = '배경 투명'; +?> diff --git a/modules/editor/components/multimedia_link/lang/ru.lang.php b/modules/editor/components/multimedia_link/lang/ru.lang.php index 4da8224f5..7672afa58 100644 --- a/modules/editor/components/multimedia_link/lang/ru.lang.php +++ b/modules/editor/components/multimedia_link/lang/ru.lang.php @@ -1,7 +1,7 @@ > | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com)> | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief editor module > language pack of multimedia_link component **/ diff --git a/modules/editor/components/multimedia_link/lang/vi.lang.php b/modules/editor/components/multimedia_link/lang/vi.lang.php index 28d1afa46..c3afc5bce 100644 --- a/modules/editor/components/multimedia_link/lang/vi.lang.php +++ b/modules/editor/components/multimedia_link/lang/vi.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 网页编辑器(editor) 模块 > 媒体链接 (multimedia_link) 组件的语言包 **/ diff --git a/modules/editor/components/multimedia_link/lang/zh-TW.lang.php b/modules/editor/components/multimedia_link/lang/zh-TW.lang.php index 76f34f417..ca4ed9823 100644 --- a/modules/editor/components/multimedia_link/lang/zh-TW.lang.php +++ b/modules/editor/components/multimedia_link/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 網頁編輯器(editor) 模組 > 多媒體連結 (multimedia_link) 組件的語言 **/ diff --git a/modules/editor/components/multimedia_link/multimedia_link.class.php b/modules/editor/components/multimedia_link/multimedia_link.class.php index 841cc7509..efce7a308 100644 --- a/modules/editor/components/multimedia_link/multimedia_link.class.php +++ b/modules/editor/components/multimedia_link/multimedia_link.class.php @@ -1,71 +1,71 @@ -editor_sequence = $editor_sequence; - $this->component_path = $component_path; - } - - /** - * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 - **/ - function getPopupContent() { - // 템플릿을 미리 컴파일해서 컴파일된 소스를 return - $tpl_path = $this->component_path.'tpl'; - $tpl_file = 'popup.html'; - - Context::set("tpl_path", $tpl_path); - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($tpl_path, $tpl_file); - } - - /** - * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method - * - * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 - * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 - **/ - function transHTML($xml_obj) { - $src = $xml_obj->attrs->multimedia_src; - $style = $xml_obj->attrs->style; - - preg_match_all('/(width|height)([^[:digit:]]+)([0-9]+)/i',$style,$matches); - $width = trim($matches[3][0]); - $height = trim($matches[3][1]); - if(!$width) $width = 400; - if(!$height) $height = 400; - - $auto_start = $xml_obj->attrs->auto_start; - if($auto_start!="true") $auto_start = "false"; - else $auto_start = "true"; - - $wmode = $xml_obj->attrs->wmode; - if($wmode == 'window') $wmode = 'window'; - elseif($wmode == 'opaque') $wmode = 'opaque'; - else $wmode = 'transparent'; - - - $caption = $xml_obj->body; - - $src = str_replace(array('&','"'), array('&','&qout;'), $src); - $src = str_replace('&amp;', '&', $src); - - if(Context::getResponseMethod() != "XMLRPC") return sprintf("", $src, $width, $height, $auto_start, $wmode); - else return sprintf("

Attached Multimedia
", $width, $height, ($height/2-16), ($width/2-31), Context::getRequestUri().'./modules/editor/components/multimedia_link/tpl/multimedia_link_component.gif'); - } - } -?> +editor_sequence = $editor_sequence; + $this->component_path = $component_path; + } + + /** + * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 + **/ + function getPopupContent() { + // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + $tpl_path = $this->component_path.'tpl'; + $tpl_file = 'popup.html'; + + Context::set("tpl_path", $tpl_path); + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + /** + * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method + * + * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 + * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 + **/ + function transHTML($xml_obj) { + $src = $xml_obj->attrs->multimedia_src; + $style = $xml_obj->attrs->style; + + preg_match_all('/(width|height)([^[:digit:]]+)([0-9]+)/i',$style,$matches); + $width = trim($matches[3][0]); + $height = trim($matches[3][1]); + if(!$width) $width = 400; + if(!$height) $height = 400; + + $auto_start = $xml_obj->attrs->auto_start; + if($auto_start!="true") $auto_start = "false"; + else $auto_start = "true"; + + $wmode = $xml_obj->attrs->wmode; + if($wmode == 'window') $wmode = 'window'; + elseif($wmode == 'opaque') $wmode = 'opaque'; + else $wmode = 'transparent'; + + + $caption = $xml_obj->body; + + $src = str_replace(array('&','"'), array('&','&qout;'), $src); + $src = str_replace('&amp;', '&', $src); + + if(Context::getResponseMethod() != "XMLRPC") return sprintf("", $src, $width, $height, $auto_start, $wmode); + else return sprintf("

Attached Multimedia
", $width, $height, ($height/2-16), ($width/2-31), Context::getRequestUri().'./modules/editor/components/multimedia_link/tpl/multimedia_link_component.gif'); + } + } +?> diff --git a/modules/editor/components/poll_maker/info.xml b/modules/editor/components/poll_maker/info.xml index c3f2e157b..9b4b1df6d 100644 --- a/modules/editor/components/poll_maker/info.xml +++ b/modules/editor/components/poll_maker/info.xml @@ -1,32 +1,32 @@ - - - Thăm dò ý kiến - 설문조사 컴포넌트 - アンケート調査 - 投票调查 - Poll Component - Componente Poll - Компонент опросов - 投票調查 - Bạn có thể tạo một cuộc thăm dò cho chủ đề của mình. - 글 작성시에 설문조사를 첨부하실 수 있습니다. 설문조사 컴포넌트는 설문조사 모듈의 설정에 영향을 받습니다. - 書き込みの時、アンケート機能の追加ができます。アンケートモジュールの影響を受けます。 - 发表主题时可以附加投票调查。投票调查组件受投票调查模块设置的影响。 - You can attach a poll on writing articles. Poll component is affected by setting of poll module. - Puede adjuntar una encuesta sobre la redacción de artículos. Encuesta componente se ve afectada por la configuración de módulo de encuesta. - Вы можете присоединить опрос при написании статей. Компонент опросов зависит от настроек модуля отпросов. - 發表主題時可以附加投票調查。投票調查組件受投票調查模組設置的影響。 - 0.1 - 2007-02-28 - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + Thăm dò ý kiến + 설문조사 컴포넌트 + アンケート調査 + 投票调查 + Poll Component + Componente Poll + Компонент опросов + 投票調查 + Bạn có thể tạo một cuộc thăm dò cho chủ đề của mình. + 글 작성시에 설문조사를 첨부하실 수 있습니다. 설문조사 컴포넌트는 설문조사 모듈의 설정에 영향을 받습니다. + 書き込みの時、アンケート機能の追加ができます。アンケートモジュールの影響を受けます。 + 发表主题时可以附加投票调查。投票调查组件受投票调查模块设置的影响。 + You can attach a poll on writing articles. Poll component is affected by setting of poll module. + Puede adjuntar una encuesta sobre la redacción de artículos. Encuesta componente se ve afectada por la configuración de módulo de encuesta. + Вы можете присоединить опрос при написании статей. Компонент опросов зависит от настроек модуля отпросов. + 發表主題時可以附加投票調查。投票調查組件受投票調查模組設置的影響。 + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/components/poll_maker/lang/en.lang.php b/modules/editor/components/poll_maker/lang/en.lang.php index 39d0afc06..1ebc2bc55 100644 --- a/modules/editor/components/poll_maker/lang/en.lang.php +++ b/modules/editor/components/poll_maker/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor module > language pack of poll_maker component **/ diff --git a/modules/editor/components/poll_maker/lang/es.lang.php b/modules/editor/components/poll_maker/lang/es.lang.php index 72b817fef..d6bd3667a 100644 --- a/modules/editor/components/poll_maker/lang/es.lang.php +++ b/modules/editor/components/poll_maker/lang/es.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief editor module > language pack of poll_maker component **/ diff --git a/modules/editor/components/poll_maker/lang/jp.lang.php b/modules/editor/components/poll_maker/lang/jp.lang.php index 48c4ea508..c8f907f7a 100644 --- a/modules/editor/components/poll_maker/lang/jp.lang.php +++ b/modules/editor/components/poll_maker/lang/jp.lang.php @@ -1,18 +1,18 @@ - 翻訳:RisaPapa、ミニミ - * @brief ウィジウィグエディター(editor)モジュール > アンケート調査言語パッケージ - **/ - - $lang->poll_title = "タイトル"; - $lang->poll_item = "項目"; - $lang->poll_stop_date = "終了日"; - $lang->poll_chk_count = "選択項目数"; - - $lang->cmd_add_poll = "アンケート追加"; - $lang->cmd_del_poll = "アンケート削除"; - $lang->cmd_add_item = "項目追加"; - - $lang->msg_poll_cannot_modify = 'アンケートは修正出来ません。削除後、改めて新しく作成して下さい。'; -?> + アンケート調査言語パッケージ + **/ + + $lang->poll_title = "タイトル"; + $lang->poll_item = "項目"; + $lang->poll_stop_date = "終了日"; + $lang->poll_chk_count = "選択項目数"; + + $lang->cmd_add_poll = "アンケート追加"; + $lang->cmd_del_poll = "アンケート削除"; + $lang->cmd_add_item = "項目追加"; + + $lang->msg_poll_cannot_modify = 'アンケートは修正出来ません。削除後、改めて新しく作成して下さい。'; +?> diff --git a/modules/editor/components/poll_maker/lang/ko.lang.php b/modules/editor/components/poll_maker/lang/ko.lang.php index 4b03e6f05..f320afb37 100644 --- a/modules/editor/components/poll_maker/lang/ko.lang.php +++ b/modules/editor/components/poll_maker/lang/ko.lang.php @@ -1,18 +1,18 @@ - - * @brief 위지윅에디터(editor) 모듈 > 설문조사 컴포넌트의 언어팩 - **/ - - $lang->poll_title = '제목'; - $lang->poll_item = '항목'; - $lang->poll_stop_date = '종료 일자'; - $lang->poll_chk_count = '선택항목 수'; - - $lang->cmd_add_poll = '설문 추가'; - $lang->cmd_del_poll = '설문 제거'; - $lang->cmd_add_item = '항목 추가'; - - $lang->msg_poll_cannot_modify = '설문조사는 수정하실 수 없습니다. 삭제 후 다시 생성하셔야 합니다.'; -?> + 설문조사 컴포넌트의 언어팩 + **/ + + $lang->poll_title = '제목'; + $lang->poll_item = '항목'; + $lang->poll_stop_date = '종료 일자'; + $lang->poll_chk_count = '선택항목 수'; + + $lang->cmd_add_poll = '설문 추가'; + $lang->cmd_del_poll = '설문 제거'; + $lang->cmd_add_item = '항목 추가'; + + $lang->msg_poll_cannot_modify = '설문조사는 수정하실 수 없습니다. 삭제 후 다시 생성하셔야 합니다.'; +?> diff --git a/modules/editor/components/poll_maker/lang/ru.lang.php b/modules/editor/components/poll_maker/lang/ru.lang.php index d204fcbcc..4e1716d20 100644 --- a/modules/editor/components/poll_maker/lang/ru.lang.php +++ b/modules/editor/components/poll_maker/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief editor module > language pack of poll_maker component **/ diff --git a/modules/editor/components/poll_maker/lang/vi.lang.php b/modules/editor/components/poll_maker/lang/vi.lang.php index dcb86f8aa..0482e6c34 100644 --- a/modules/editor/components/poll_maker/lang/vi.lang.php +++ b/modules/editor/components/poll_maker/lang/vi.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 网页编辑器(editor) 模块 > 投票调查组件语言包 **/ diff --git a/modules/editor/components/poll_maker/lang/zh-TW.lang.php b/modules/editor/components/poll_maker/lang/zh-TW.lang.php index bd5395e81..f691de9a2 100644 --- a/modules/editor/components/poll_maker/lang/zh-TW.lang.php +++ b/modules/editor/components/poll_maker/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 網頁編輯器(editor) 模組 > 投票調查組件語言 **/ diff --git a/modules/editor/components/poll_maker/poll_maker.class.php b/modules/editor/components/poll_maker/poll_maker.class.php index f4e9d5336..96eabf422 100644 --- a/modules/editor/components/poll_maker/poll_maker.class.php +++ b/modules/editor/components/poll_maker/poll_maker.class.php @@ -1,60 +1,60 @@ -editor_sequence = $editor_sequence; - $this->component_path = $component_path; - } - - /** - * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 - **/ - function getPopupContent() { - // 설문조사 스킨을 구함 - $oModuleModel = &getModel('module'); - $skin_list = $oModuleModel->getSkins("./modules/poll/"); - Context::set('skin_list', $skin_list); - - // 템플릿을 미리 컴파일해서 컴파일된 소스를 return - $tpl_path = $this->component_path.'tpl'; - $tpl_file = 'popup.html'; - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($tpl_path, $tpl_file); - } - - /** - * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method - * - * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 - * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 - **/ - function transHTML($xml_obj) { - $poll_srl = $xml_obj->attrs->poll_srl; - $skin = $xml_obj->attrs->skin; - if(!$skin) $skin = 'default'; - - preg_match('/width([^[:digit:]]+)([0-9]+)/i',$xml_obj->attrs->style,$matches); - $width = $matches[2]; - if(!$width) $width = 400; - $style = sprintf('width:%dpx', $width); - - // poll model 객체 생성해서 html 얻어와서 return - $oPollModel = &getModel('poll'); - return $oPollModel->getPollHtml($poll_srl, $style, $skin); - } - } -?> +editor_sequence = $editor_sequence; + $this->component_path = $component_path; + } + + /** + * @brief popup window요청시 popup window에 출력할 내용을 추가하면 된다 + **/ + function getPopupContent() { + // 설문조사 스킨을 구함 + $oModuleModel = &getModel('module'); + $skin_list = $oModuleModel->getSkins("./modules/poll/"); + Context::set('skin_list', $skin_list); + + // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + $tpl_path = $this->component_path.'tpl'; + $tpl_file = 'popup.html'; + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($tpl_path, $tpl_file); + } + + /** + * @brief 에디터 컴포넌트가 별도의 고유 코드를 이용한다면 그 코드를 html로 변경하여 주는 method + * + * 이미지나 멀티미디어, 설문등 고유 코드가 필요한 에디터 컴포넌트는 고유코드를 내용에 추가하고 나서 + * DocumentModule::transContent() 에서 해당 컴포넌트의 transHtml() method를 호출하여 고유코드를 html로 변경 + **/ + function transHTML($xml_obj) { + $poll_srl = $xml_obj->attrs->poll_srl; + $skin = $xml_obj->attrs->skin; + if(!$skin) $skin = 'default'; + + preg_match('/width([^[:digit:]]+)([0-9]+)/i',$xml_obj->attrs->style,$matches); + $width = $matches[2]; + if(!$width) $width = 400; + $style = sprintf('width:%dpx', $width); + + // poll model 객체 생성해서 html 얻어와서 return + $oPollModel = &getModel('poll'); + return $oPollModel->getPollHtml($poll_srl, $style, $skin); + } + } +?> diff --git a/modules/editor/conf/info.xml b/modules/editor/conf/info.xml index fa1812ad5..b5bc798de 100644 --- a/modules/editor/conf/info.xml +++ b/modules/editor/conf/info.xml @@ -1,33 +1,33 @@ - - - WYSIWYG Editor - 위지윅 에디터 - WYSIWYG Editor - Editor WYSIWYG - 网页编辑器 - ウイジウイグエディター - WYSIWYG-редактор - 網頁編輯器 - Module hiển thị WYSIWYG Editor để quản lý những kiểu viết bài. - 위지윅 에디터를 출력하거나 에디터 컴포넌트들을 관리/중계하는 모듈입니다. - Module for displaying WYSIWYG editor and managing/relaying editor components. - Módulo para mostrar en la pantalla el editor de WYSIWYG y para el manejo/relato de los componentes del editor. - 显示网页编辑器或管理/传递编辑器组件的模块。 - ウイジウイグエディター を出力したり、エディターのコンポーネントを管理・中継するモジュールです。 - Модуль для отображения WYSIWYG-редактора и управления/смены записей редактора. - 顯示網頁編輯器或管理/傳遞編輯器組件的模組。 - 0.1 - 2007-02-28 - utility - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + WYSIWYG Editor + 위지윅 에디터 + WYSIWYG Editor + Editor WYSIWYG + 网页编辑器 + ウイジウイグエディター + WYSIWYG-редактор + 網頁編輯器 + Module hiển thị WYSIWYG Editor để quản lý những kiểu viết bài. + 위지윅 에디터를 출력하거나 에디터 컴포넌트들을 관리/중계하는 모듈입니다. + Module for displaying WYSIWYG editor and managing/relaying editor components. + Módulo para mostrar en la pantalla el editor de WYSIWYG y para el manejo/relato de los componentes del editor. + 显示网页编辑器或管理/传递编辑器组件的模块。 + ウイジウイグエディター を出力したり、エディターのコンポーネントを管理・中継するモジュールです。 + Модуль для отображения WYSIWYG-редактора и управления/смены записей редактора. + 顯示網頁編輯器或管理/傳遞編輯器組件的模組。 + 0.1 + 2007-02-28 + utility + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/editor.admin.controller.php b/modules/editor/editor.admin.controller.php index 56df8317d..f6d2bb629 100644 --- a/modules/editor/editor.admin.controller.php +++ b/modules/editor/editor.admin.controller.php @@ -1,166 +1,166 @@ -component_name = Context::get('component_name'); - $args->enabled = 'Y'; - $args->site_srl = (int)$site_module_info->site_srl; - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $args); - else $output = executeQuery('editor.updateSiteComponent', $args); - if(!$output->toBool()) return $output; - - $oEditorController = &getController('editor'); - $oEditorController->removeCache($args->site_srl); - - $this->setMessage('success_updated'); - } - - /** - * @brief 컴포넌트의 비활성화 - **/ - function procEditorAdminDisableComponent() { - $site_module_info = Context::get('site_module_info'); - - $args->component_name = Context::get('component_name'); - $args->enabled = 'N'; - $args->site_srl = (int)$site_module_info->site_srl; - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $args); - else $output = executeQuery('editor.updateSiteComponent', $args); - if(!$output->toBool()) return $output; - - $oEditorController = &getController('editor'); - $oEditorController->removeCache($args->site_srl); - - $this->setMessage('success_updated'); - } - - /** - * @brief 컴포넌트의 위치 변경 - **/ - function procEditorAdminMoveListOrder() { - $site_module_info = Context::get('site_module_info'); - $args->site_srl = (int)$site_module_info->site_srl; - $args->component_name = Context::get('component_name'); - $mode = Context::get('mode'); - - // DB에서 전체 목록 가져옴 - if(!$args->site_srl) $output = executeQuery('editor.getComponentList', $args); - else $output = executeQuery('editor.getSiteComponentList', $args); - - $db_list = $output->data; - foreach($db_list as $key => $val) { - if($val->component_name == $args->component_name) break; - } - - if($mode=="up") { - if($key == 2) return new Object(-1,'msg_component_is_first_order'); - - $prev_args->component_name = $db_list[$key-1]->component_name; - $prev_args->list_order = $db_list[$key]->list_order; - $prev_args->site_srl = $args->site_srl; - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $prev_args); - else $output = executeQuery('editor.updateSiteComponent', $prev_args); - - $cur_args->component_name = $db_list[$key]->component_name; - $cur_args->list_order = $db_list[$key-1]->list_order; - if($prev_args->list_order == $cur_args->list_order) $cur_args->list_order--; - $cur_args->site_srl = $args->site_srl; - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $cur_args); - else $output = executeQuery('editor.updateSiteComponent', $cur_args); - } else { - if($key == count($db_list)-1) return new Object(-1,'msg_component_is_last_order'); - - $next_args->component_name = $db_list[$key+1]->component_name; - $next_args->list_order = $db_list[$key]->list_order; - $next_args->site_srl = $args->site_srl; - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $next_args); - else $output = executeQuery('editor.updateSiteComponent', $next_args); - - $cur_args->component_name = $db_list[$key]->component_name; - $cur_args->list_order = $db_list[$key+1]->list_order; - $cur_args->site_srl = $args->site_srl; - if($next_args->list_order == $cur_args->list_order) $cur_args->list_order++; - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $cur_args); - else $output = executeQuery('editor.updateSiteComponent', $cur_args); - } - - $oEditorController = &getController('editor'); - $oEditorController->removeCache($args->site_srl); - - $this->setMessage('success_updated'); - } - - /** - * @brief 컴포넌트 설정 - **/ - function procEditorAdminSetupComponent() { - $site_module_info = Context::get('site_module_info'); - - $component_name = Context::get('component_name'); - $extra_vars = Context::getRequestVars(); - unset($extra_vars->component_name); - unset($extra_vars->module); - unset($extra_vars->act); - unset($extra_vars->body); - - if($extra_vars->target_group) $extra_vars->target_group = explode('|@|', $extra_vars->target_group); - if($extra_vars->mid_list) $extra_vars->mid_list = explode('|@|', $extra_vars->mid_list); - - $args->component_name = $component_name; - $args->extra_vars = serialize($extra_vars); - $args->site_srl = (int)$site_module_info->site_srl; - - if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $args); - else $output = executeQuery('editor.updateSiteComponent', $args); - if(!$output->toBool()) return $output; - - $oEditorController = &getController('editor'); - $oEditorController->removeCache($args->site_srl); - - $this->setMessage('success_updated'); - } - - /** - * @brief 컴포넌트를 DB에 추가 - **/ - function insertComponent($component_name, $enabled = false, $site_srl = 0) { - if($enabled) $enabled = 'Y'; - else $enabled = 'N'; - - $args->component_name = $component_name; - $args->enabled = $enabled; - $args->site_srl = $site_srl; - - // 컴포넌트가 있는지 확인 - if(!$site_srl) $output = executeQuery('editor.isComponentInserted', $args); - else $output = executeQuery('editor.isSiteComponentInserted', $args); - if($output->data->count) return new Object(-1, 'msg_component_is_not_founded'); - - // 입력 - $args->list_order = getNextSequence(); - if(!$site_srl) $output = executeQuery('editor.insertComponent', $args); - else $output = executeQuery('editor.insertSiteComponent', $args); - - $oEditorController = &getController('editor'); - $oEditorController->removeCache($site_srl); - return $output; - } - } -?> +component_name = Context::get('component_name'); + $args->enabled = 'Y'; + $args->site_srl = (int)$site_module_info->site_srl; + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $args); + else $output = executeQuery('editor.updateSiteComponent', $args); + if(!$output->toBool()) return $output; + + $oEditorController = &getController('editor'); + $oEditorController->removeCache($args->site_srl); + + $this->setMessage('success_updated'); + } + + /** + * @brief 컴포넌트의 비활성화 + **/ + function procEditorAdminDisableComponent() { + $site_module_info = Context::get('site_module_info'); + + $args->component_name = Context::get('component_name'); + $args->enabled = 'N'; + $args->site_srl = (int)$site_module_info->site_srl; + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $args); + else $output = executeQuery('editor.updateSiteComponent', $args); + if(!$output->toBool()) return $output; + + $oEditorController = &getController('editor'); + $oEditorController->removeCache($args->site_srl); + + $this->setMessage('success_updated'); + } + + /** + * @brief 컴포넌트의 위치 변경 + **/ + function procEditorAdminMoveListOrder() { + $site_module_info = Context::get('site_module_info'); + $args->site_srl = (int)$site_module_info->site_srl; + $args->component_name = Context::get('component_name'); + $mode = Context::get('mode'); + + // DB에서 전체 목록 가져옴 + if(!$args->site_srl) $output = executeQuery('editor.getComponentList', $args); + else $output = executeQuery('editor.getSiteComponentList', $args); + + $db_list = $output->data; + foreach($db_list as $key => $val) { + if($val->component_name == $args->component_name) break; + } + + if($mode=="up") { + if($key == 2) return new Object(-1,'msg_component_is_first_order'); + + $prev_args->component_name = $db_list[$key-1]->component_name; + $prev_args->list_order = $db_list[$key]->list_order; + $prev_args->site_srl = $args->site_srl; + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $prev_args); + else $output = executeQuery('editor.updateSiteComponent', $prev_args); + + $cur_args->component_name = $db_list[$key]->component_name; + $cur_args->list_order = $db_list[$key-1]->list_order; + if($prev_args->list_order == $cur_args->list_order) $cur_args->list_order--; + $cur_args->site_srl = $args->site_srl; + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $cur_args); + else $output = executeQuery('editor.updateSiteComponent', $cur_args); + } else { + if($key == count($db_list)-1) return new Object(-1,'msg_component_is_last_order'); + + $next_args->component_name = $db_list[$key+1]->component_name; + $next_args->list_order = $db_list[$key]->list_order; + $next_args->site_srl = $args->site_srl; + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $next_args); + else $output = executeQuery('editor.updateSiteComponent', $next_args); + + $cur_args->component_name = $db_list[$key]->component_name; + $cur_args->list_order = $db_list[$key+1]->list_order; + $cur_args->site_srl = $args->site_srl; + if($next_args->list_order == $cur_args->list_order) $cur_args->list_order++; + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $cur_args); + else $output = executeQuery('editor.updateSiteComponent', $cur_args); + } + + $oEditorController = &getController('editor'); + $oEditorController->removeCache($args->site_srl); + + $this->setMessage('success_updated'); + } + + /** + * @brief 컴포넌트 설정 + **/ + function procEditorAdminSetupComponent() { + $site_module_info = Context::get('site_module_info'); + + $component_name = Context::get('component_name'); + $extra_vars = Context::getRequestVars(); + unset($extra_vars->component_name); + unset($extra_vars->module); + unset($extra_vars->act); + unset($extra_vars->body); + + if($extra_vars->target_group) $extra_vars->target_group = explode('|@|', $extra_vars->target_group); + if($extra_vars->mid_list) $extra_vars->mid_list = explode('|@|', $extra_vars->mid_list); + + $args->component_name = $component_name; + $args->extra_vars = serialize($extra_vars); + $args->site_srl = (int)$site_module_info->site_srl; + + if(!$args->site_srl) $output = executeQuery('editor.updateComponent', $args); + else $output = executeQuery('editor.updateSiteComponent', $args); + if(!$output->toBool()) return $output; + + $oEditorController = &getController('editor'); + $oEditorController->removeCache($args->site_srl); + + $this->setMessage('success_updated'); + } + + /** + * @brief 컴포넌트를 DB에 추가 + **/ + function insertComponent($component_name, $enabled = false, $site_srl = 0) { + if($enabled) $enabled = 'Y'; + else $enabled = 'N'; + + $args->component_name = $component_name; + $args->enabled = $enabled; + $args->site_srl = $site_srl; + + // 컴포넌트가 있는지 확인 + if(!$site_srl) $output = executeQuery('editor.isComponentInserted', $args); + else $output = executeQuery('editor.isSiteComponentInserted', $args); + if($output->data->count) return new Object(-1, 'msg_component_is_not_founded'); + + // 입력 + $args->list_order = getNextSequence(); + if(!$site_srl) $output = executeQuery('editor.insertComponent', $args); + else $output = executeQuery('editor.insertSiteComponent', $args); + + $oEditorController = &getController('editor'); + $oEditorController->removeCache($site_srl); + return $output; + } + } +?> diff --git a/modules/editor/editor.admin.view.php b/modules/editor/editor.admin.view.php index 8e8beb008..745758053 100644 --- a/modules/editor/editor.admin.view.php +++ b/modules/editor/editor.admin.view.php @@ -1,80 +1,80 @@ -site_srl; - - // 컴포넌트의 종류를 구해옴 - $oEditorModel = &getModel('editor'); - $component_list = $oEditorModel->getComponentList(false, $site_srl, true); - - Context::set('component_list', $component_list); - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('admin_index'); - } - - /** - * @brief 컴퍼넌트 setup - **/ - function dispEditorAdminSetupComponent() { - $site_module_info = Context::get('site_module_info'); - $site_srl = (int)$site_module_info->site_srl; - - $component_name = Context::get('component_name'); - - // 에디터 컴포넌트의 정보를 구함 - $oEditorModel = &getModel('editor'); - $component = $oEditorModel->getComponent($component_name,$site_srl); - Context::set('component', $component); - - // 그룹 설정을 위한 그룹 목록을 구함 - $oMemberModel = &getModel('member'); - $group_list = $oMemberModel->getGroups($site_srl); - Context::set('group_list', $group_list); - - // mid 목록을 가져옴 - $oModuleModel = &getModel('module'); - - $args->site_srl = $site_srl; - $mid_list = $oModuleModel->getMidList($args); - - // module_category와 module의 조합 - if(!$args->site_srl) { - // 모듈 카테고리 목록을 구함 - $module_categories = $oModuleModel->getModuleCategories(); - - if(!is_array($mid_list)) $mid_list = array($mid_list); - foreach($mid_list as $module_srl => $module) { - if($module) $module_categories[$module->module_category_srl]->list[$module_srl] = $module; - } - } else { - $module_categories[0]->list = $mid_list; - } - - Context::set('mid_list',$module_categories); - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('setup_component'); - $this->setLayoutFile("popup_layout"); - } - - } -?> +site_srl; + + // 컴포넌트의 종류를 구해옴 + $oEditorModel = &getModel('editor'); + $component_list = $oEditorModel->getComponentList(false, $site_srl, true); + + Context::set('component_list', $component_list); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('admin_index'); + } + + /** + * @brief 컴퍼넌트 setup + **/ + function dispEditorAdminSetupComponent() { + $site_module_info = Context::get('site_module_info'); + $site_srl = (int)$site_module_info->site_srl; + + $component_name = Context::get('component_name'); + + // 에디터 컴포넌트의 정보를 구함 + $oEditorModel = &getModel('editor'); + $component = $oEditorModel->getComponent($component_name,$site_srl); + Context::set('component', $component); + + // 그룹 설정을 위한 그룹 목록을 구함 + $oMemberModel = &getModel('member'); + $group_list = $oMemberModel->getGroups($site_srl); + Context::set('group_list', $group_list); + + // mid 목록을 가져옴 + $oModuleModel = &getModel('module'); + + $args->site_srl = $site_srl; + $mid_list = $oModuleModel->getMidList($args); + + // module_category와 module의 조합 + if(!$args->site_srl) { + // 모듈 카테고리 목록을 구함 + $module_categories = $oModuleModel->getModuleCategories(); + + if(!is_array($mid_list)) $mid_list = array($mid_list); + foreach($mid_list as $module_srl => $module) { + if($module) $module_categories[$module->module_category_srl]->list[$module_srl] = $module; + } + } else { + $module_categories[0]->list = $mid_list; + } + + Context::set('mid_list',$module_categories); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('setup_component'); + $this->setLayoutFile("popup_layout"); + } + + } +?> diff --git a/modules/editor/editor.api.php b/modules/editor/editor.api.php index 8a8f8eb20..3945c9adf 100644 --- a/modules/editor/editor.api.php +++ b/modules/editor/editor.api.php @@ -1,7 +1,7 @@ insertComponent('colorpicker_text',true); - $oEditorController->insertComponent('colorpicker_bg',true); - $oEditorController->insertComponent('emoticon',true); - $oEditorController->insertComponent('url_link',true); - $oEditorController->insertComponent('image_link',true); - $oEditorController->insertComponent('multimedia_link',true); - $oEditorController->insertComponent('quotation',true); - $oEditorController->insertComponent('table_maker',true); - $oEditorController->insertComponent('poll_maker',true); - $oEditorController->insertComponent('image_gallery',true); - - // 에디터 모듈에서 사용할 디렉토리 생성 - FileHandler::makeDir('./files/cache/editor'); - - // 2007. 10. 17 글의 입력(신규 or 수정)이 일어날때마다 자동 저장된 문서를 삭제하는 trigger 추가 - $oModuleController->insertTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); - $oModuleController->insertTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); - - // 2007. 10. 23 모듈의 추가 설정에서 에디터 trigger 추가 - $oModuleController->insertTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before'); - - // 2009. 04. 14 editor component 변환 코드를 trigger로 독립 - $oModuleController->insertTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before'); - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $db_info = Context::getDBInfo (); - $oModuleModel = &getModel('module'); - - $oDB = &DB::getInstance(); - - // 2009. 06. 15 자동저장시 module_srl 을 저장 - if(!$oDB->isColumnExists("editor_autosave","module_srl")) return true; - - // 2009. 06. 15 module_srl을 인덱스로 - if ($db_info->db_type == 'cubrid') { - if(!$oDB->isIndexExists("editor_autosave",$oDB->prefix."editor_autosave_idx_module_srl")) return true; - } - else { - if(!$oDB->isIndexExists("editor_autosave","idx_module_srl")) return true; - } - - - // 2007. 10. 17 글의 입력(신규 or 수정)이 일어날때마다 자동 저장된 문서를 삭제하는 trigger 추가 - if(!$oModuleModel->getTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) return true; - if(!$oModuleModel->getTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) return true; - - // 2007. 10. 23 모듈의 추가 설정에서 에디터 trigger 추가 - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before')) return true; - - // 2009. 04. 14 editor component 변환 코드를 trigger로 독립 - if(!$oModuleModel->getTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before')) return true; - - // 2009. 06. 19 사용하지 않는 트리거 제거 - if($oModuleModel->getTrigger('file.getIsPermitted', 'editor', 'controller', 'triggerSrlSetting', 'before')) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $db_info = Context::getDBInfo (); - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - - $oDB = &DB::getInstance(); - - // 자동저장시 module_srl 을 저장 2009.6.15 - if(!$oDB->isColumnExists("editor_autosave","module_srl")) - $oDB->addColumn("editor_autosave","module_srl","number",11); - - // module_srl을 인덱스로 - if ($db_info->db_type == 'cubrid') { - if(!$oDB->isIndexExists("editor_autosave",$oDB->prefix."editor_autosave_idx_module_srl")) - $oDB->addIndex("editor_autosave",$oDB->prefix."editor_autosave_idx_module_srl", "module_srl"); - } - else { - if(!$oDB->isIndexExists("editor_autosave","idx_module_srl")) - $oDB->addIndex("editor_autosave","idx_module_srl", "module_srl"); - } - - // 2007. 10. 17 글의 입력(신규 or 수정)이 일어날때마다 자동 저장된 문서를 삭제하는 trigger 추가 - if(!$oModuleModel->getTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) - $oModuleController->insertTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); - if(!$oModuleModel->getTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) - $oModuleController->insertTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); - - // 2007. 10. 23 모듈의 추가 설정에서 에디터 trigger 추가 - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before')) - $oModuleController->insertTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before'); - - // 2009. 04. 14 editor component 변환 코드를 trigger로 독립 - if(!$oModuleModel->getTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before')) - $oModuleController->insertTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before'); - - // 2009. 06. 19 사용하지 않는 트리거 제거 - if($oModuleModel->getTrigger('file.getIsPermitted', 'editor', 'controller', 'triggerSrlSetting', 'before')) - $oModuleController->deleteTrigger('file.getIsPermitted', 'editor', 'controller', 'triggerSrlSetting', 'before'); - - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - // 에디터 컴포넌트 캐시 파일 삭제 - FileHandler::removeFilesInDir("./files/cache/editor"); - } - } -?> +insertComponent('colorpicker_text',true); + $oEditorController->insertComponent('colorpicker_bg',true); + $oEditorController->insertComponent('emoticon',true); + $oEditorController->insertComponent('url_link',true); + $oEditorController->insertComponent('image_link',true); + $oEditorController->insertComponent('multimedia_link',true); + $oEditorController->insertComponent('quotation',true); + $oEditorController->insertComponent('table_maker',true); + $oEditorController->insertComponent('poll_maker',true); + $oEditorController->insertComponent('image_gallery',true); + + // 에디터 모듈에서 사용할 디렉토리 생성 + FileHandler::makeDir('./files/cache/editor'); + + // 2007. 10. 17 글의 입력(신규 or 수정)이 일어날때마다 자동 저장된 문서를 삭제하는 trigger 추가 + $oModuleController->insertTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); + $oModuleController->insertTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); + + // 2007. 10. 23 모듈의 추가 설정에서 에디터 trigger 추가 + $oModuleController->insertTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before'); + + // 2009. 04. 14 editor component 변환 코드를 trigger로 독립 + $oModuleController->insertTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before'); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $db_info = Context::getDBInfo (); + $oModuleModel = &getModel('module'); + + $oDB = &DB::getInstance(); + + // 2009. 06. 15 자동저장시 module_srl 을 저장 + if(!$oDB->isColumnExists("editor_autosave","module_srl")) return true; + + // 2009. 06. 15 module_srl을 인덱스로 + if ($db_info->db_type == 'cubrid') { + if(!$oDB->isIndexExists("editor_autosave",$oDB->prefix."editor_autosave_idx_module_srl")) return true; + } + else { + if(!$oDB->isIndexExists("editor_autosave","idx_module_srl")) return true; + } + + + // 2007. 10. 17 글의 입력(신규 or 수정)이 일어날때마다 자동 저장된 문서를 삭제하는 trigger 추가 + if(!$oModuleModel->getTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) return true; + if(!$oModuleModel->getTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) return true; + + // 2007. 10. 23 모듈의 추가 설정에서 에디터 trigger 추가 + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before')) return true; + + // 2009. 04. 14 editor component 변환 코드를 trigger로 독립 + if(!$oModuleModel->getTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before')) return true; + + // 2009. 06. 19 사용하지 않는 트리거 제거 + if($oModuleModel->getTrigger('file.getIsPermitted', 'editor', 'controller', 'triggerSrlSetting', 'before')) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $db_info = Context::getDBInfo (); + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + + $oDB = &DB::getInstance(); + + // 자동저장시 module_srl 을 저장 2009.6.15 + if(!$oDB->isColumnExists("editor_autosave","module_srl")) + $oDB->addColumn("editor_autosave","module_srl","number",11); + + // module_srl을 인덱스로 + if ($db_info->db_type == 'cubrid') { + if(!$oDB->isIndexExists("editor_autosave",$oDB->prefix."editor_autosave_idx_module_srl")) + $oDB->addIndex("editor_autosave",$oDB->prefix."editor_autosave_idx_module_srl", "module_srl"); + } + else { + if(!$oDB->isIndexExists("editor_autosave","idx_module_srl")) + $oDB->addIndex("editor_autosave","idx_module_srl", "module_srl"); + } + + // 2007. 10. 17 글의 입력(신규 or 수정)이 일어날때마다 자동 저장된 문서를 삭제하는 trigger 추가 + if(!$oModuleModel->getTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) + $oModuleController->insertTrigger('document.insertDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); + if(!$oModuleModel->getTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after')) + $oModuleController->insertTrigger('document.updateDocument', 'editor', 'controller', 'triggerDeleteSavedDoc', 'after'); + + // 2007. 10. 23 모듈의 추가 설정에서 에디터 trigger 추가 + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before')) + $oModuleController->insertTrigger('module.dispAdditionSetup', 'editor', 'view', 'triggerDispEditorAdditionSetup', 'before'); + + // 2009. 04. 14 editor component 변환 코드를 trigger로 독립 + if(!$oModuleModel->getTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before')) + $oModuleController->insertTrigger('display', 'editor', 'controller', 'triggerEditorComponentCompile', 'before'); + + // 2009. 06. 19 사용하지 않는 트리거 제거 + if($oModuleModel->getTrigger('file.getIsPermitted', 'editor', 'controller', 'triggerSrlSetting', 'before')) + $oModuleController->deleteTrigger('file.getIsPermitted', 'editor', 'controller', 'triggerSrlSetting', 'before'); + + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + // 에디터 컴포넌트 캐시 파일 삭제 + FileHandler::removeFilesInDir("./files/cache/editor"); + } + } +?> diff --git a/modules/editor/editor.controller.php b/modules/editor/editor.controller.php index 8b4c0162a..4ebad3731 100644 --- a/modules/editor/editor.controller.php +++ b/modules/editor/editor.controller.php @@ -1,7 +1,7 @@ module_path."tpl/css/editor.css"); - - // 변수 정리 - $editor_sequence = Context::get('editor_sequence'); - $component = Context::get('component'); - - $site_module_info = Context::get('site_module_info'); - $site_srl = (int)$site_module_info->site_srl; - - // component 객체를 받음 - $oEditorModel = &getModel('editor'); - $oComponent = &$oEditorModel->getComponentObject($component, $editor_sequence, $site_srl); - if(!$oComponent->toBool()) { - Context::set('message', sprintf(Context::getLang('msg_component_is_not_founded'), $component)); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('component_not_founded'); - } else { - - // 컴포넌트의 popup url을 출력하는 method실행후 결과를 받음 - $popup_content = $oComponent->getPopupContent(); - Context::set('popup_content', $popup_content); - - // 레이아웃을 popup_layout으로 설정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('popup'); - } - } - - /** - * @brief 컴퍼넌트 정보 보기 - **/ - function dispEditorComponentInfo() { - $component_name = Context::get('component_name'); - - $site_module_info = Context::get('site_module_info'); - $site_srl = (int)$site_module_info->site_srl; - - $oEditorModel = &getModel('editor'); - $component = $oEditorModel->getComponent($component_name, $site_srl); - Context::set('component', $component); - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('view_component'); - $this->setLayoutFile("popup_layout"); - } - - /** - * @brief 모듈의 추가 설정에서 에디터 설정을 하는 form 추가 - **/ - function triggerDispEditorAdditionSetup(&$obj) { - $current_module_srl = Context::get('module_srl'); - $current_module_srls = Context::get('module_srls'); - - if(!$current_module_srl && !$current_module_srls) { - // 선택된 모듈의 정보를 가져옴 - $current_module_info = Context::get('current_module_info'); - $current_module_srl = $current_module_info->module_srl; - if(!$current_module_srl) return new Object(); - } - - // 에디터 설정을 구함 - $oEditorModel = &getModel('editor'); - $editor_config = $oEditorModel->getEditorConfig($current_module_srl); - - Context::set('editor_config', $editor_config); - - $oModuleModel = &getModel('module'); - - // 에디터 스킨 목록을 구함 - $editor_skin_list = FileHandler::readDir(_XE_PATH_.'modules/editor/skins'); - Context::set('editor_skin_list', $editor_skin_list); - - $skin_info = $oModuleModel->loadSkinInfo($this->module_path,$editor_config->editor_skin); - Context::set('editor_colorset_list', $skin_info->colorset); - $skin_info = $oModuleModel->loadSkinInfo($this->module_path,$editor_config->comment_editor_skin); - Context::set('editor_comment_colorset_list', $skin_info->colorset); - - $contents = FileHandler::readDir(_XE_PATH_.'modules/editor/styles'); - for($i=0,$c=count($contents);$i<$c;$i++) { - $style = $contents[$i]; - $info = $oModuleModel->loadSkinInfo($this->module_path,$style,'styles'); - $content_style_list[$style]->title = $info->title; - } - Context::set('content_style_list', $content_style_list); - - - // 그룹 목록을 구함 - $oMemberModel = &getModel('member'); - $site_module_info = Context::get('site_module_info'); - $group_list = $oMemberModel->getGroups($site_module_info->site_srl); - Context::set('group_list', $group_list); - - // 템플릿 파일 지정 - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'editor_module_config'); - $obj .= $tpl; - - return new Object(); - } - - - function dispEditorPreview(){ - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('preview'); - } - - function dispEditorSkinColorset(){ - $skin = Context::get('skin'); - $oModuleModel = &getModel('module'); - $skin_info = $oModuleModel->loadSkinInfo($this->module_path,$skin); - $colorset = $skin_info->colorset; - Context::set('colorset', $colorset); - } - } -?> +module_path."tpl/css/editor.css"); + + // 변수 정리 + $editor_sequence = Context::get('editor_sequence'); + $component = Context::get('component'); + + $site_module_info = Context::get('site_module_info'); + $site_srl = (int)$site_module_info->site_srl; + + // component 객체를 받음 + $oEditorModel = &getModel('editor'); + $oComponent = &$oEditorModel->getComponentObject($component, $editor_sequence, $site_srl); + if(!$oComponent->toBool()) { + Context::set('message', sprintf(Context::getLang('msg_component_is_not_founded'), $component)); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('component_not_founded'); + } else { + + // 컴포넌트의 popup url을 출력하는 method실행후 결과를 받음 + $popup_content = $oComponent->getPopupContent(); + Context::set('popup_content', $popup_content); + + // 레이아웃을 popup_layout으로 설정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('popup'); + } + } + + /** + * @brief 컴퍼넌트 정보 보기 + **/ + function dispEditorComponentInfo() { + $component_name = Context::get('component_name'); + + $site_module_info = Context::get('site_module_info'); + $site_srl = (int)$site_module_info->site_srl; + + $oEditorModel = &getModel('editor'); + $component = $oEditorModel->getComponent($component_name, $site_srl); + Context::set('component', $component); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('view_component'); + $this->setLayoutFile("popup_layout"); + } + + /** + * @brief 모듈의 추가 설정에서 에디터 설정을 하는 form 추가 + **/ + function triggerDispEditorAdditionSetup(&$obj) { + $current_module_srl = Context::get('module_srl'); + $current_module_srls = Context::get('module_srls'); + + if(!$current_module_srl && !$current_module_srls) { + // 선택된 모듈의 정보를 가져옴 + $current_module_info = Context::get('current_module_info'); + $current_module_srl = $current_module_info->module_srl; + if(!$current_module_srl) return new Object(); + } + + // 에디터 설정을 구함 + $oEditorModel = &getModel('editor'); + $editor_config = $oEditorModel->getEditorConfig($current_module_srl); + + Context::set('editor_config', $editor_config); + + $oModuleModel = &getModel('module'); + + // 에디터 스킨 목록을 구함 + $editor_skin_list = FileHandler::readDir(_XE_PATH_.'modules/editor/skins'); + Context::set('editor_skin_list', $editor_skin_list); + + $skin_info = $oModuleModel->loadSkinInfo($this->module_path,$editor_config->editor_skin); + Context::set('editor_colorset_list', $skin_info->colorset); + $skin_info = $oModuleModel->loadSkinInfo($this->module_path,$editor_config->comment_editor_skin); + Context::set('editor_comment_colorset_list', $skin_info->colorset); + + $contents = FileHandler::readDir(_XE_PATH_.'modules/editor/styles'); + for($i=0,$c=count($contents);$i<$c;$i++) { + $style = $contents[$i]; + $info = $oModuleModel->loadSkinInfo($this->module_path,$style,'styles'); + $content_style_list[$style]->title = $info->title; + } + Context::set('content_style_list', $content_style_list); + + + // 그룹 목록을 구함 + $oMemberModel = &getModel('member'); + $site_module_info = Context::get('site_module_info'); + $group_list = $oMemberModel->getGroups($site_module_info->site_srl); + Context::set('group_list', $group_list); + + // 템플릿 파일 지정 + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'editor_module_config'); + $obj .= $tpl; + + return new Object(); + } + + + function dispEditorPreview(){ + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('preview'); + } + + function dispEditorSkinColorset(){ + $skin = Context::get('skin'); + $oModuleModel = &getModel('module'); + $skin_info = $oModuleModel->loadSkinInfo($this->module_path,$skin); + $colorset = $skin_info->colorset; + Context::set('colorset', $colorset); + } + } +?> diff --git a/modules/editor/lang/en.lang.php b/modules/editor/lang/en.lang.php index a427b31d0..e093d7b15 100644 --- a/modules/editor/lang/en.lang.php +++ b/modules/editor/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief WYSIWYG Editor module's basic language pack **/ diff --git a/modules/editor/lang/es.lang.php b/modules/editor/lang/es.lang.php index 60eee307a..4c303f96a 100644 --- a/modules/editor/lang/es.lang.php +++ b/modules/editor/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma español para el editor de WYSIWYG **/ diff --git a/modules/editor/lang/fr.lang.php b/modules/editor/lang/fr.lang.php index 3935840d2..b928884f7 100644 --- a/modules/editor/lang/fr.lang.php +++ b/modules/editor/lang/fr.lang.php @@ -1,7 +1,7 @@ Traduit par Pierre Duvent + * @author NHN (developers@xpressengine.com) Traduit par Pierre Duvent * @brief Paquet du langage en français pour le module de Tel-tel Editeur **/ diff --git a/modules/editor/lang/jp.lang.php b/modules/editor/lang/jp.lang.php index 3b1cbbcfb..e834d9328 100644 --- a/modules/editor/lang/jp.lang.php +++ b/modules/editor/lang/jp.lang.php @@ -1,7 +1,7 @@ 翻訳:RisaPapa、ミニミ + * @author NHN (developers@xpressengine.com) 翻訳:RisaPapa、ミニミ * @brief ウィジウィグエディター(editor)モジュールの基本言語パッケージ **/ diff --git a/modules/editor/lang/ko.lang.php b/modules/editor/lang/ko.lang.php index 568700552..a9a52f078 100644 --- a/modules/editor/lang/ko.lang.php +++ b/modules/editor/lang/ko.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 위지윅에디터(editor) 모듈의 기본 언어팩 **/ diff --git a/modules/editor/lang/ru.lang.php b/modules/editor/lang/ru.lang.php index d4cc40e2b..809486c64 100644 --- a/modules/editor/lang/ru.lang.php +++ b/modules/editor/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief Russian basic language pack **/ diff --git a/modules/editor/lang/vi.lang.php b/modules/editor/lang/vi.lang.php index 3dd04be94..9dffea804 100644 --- a/modules/editor/lang/vi.lang.php +++ b/modules/editor/lang/vi.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 网页编辑器(editor) 模块语言包 **/ diff --git a/modules/editor/lang/zh-TW.lang.php b/modules/editor/lang/zh-TW.lang.php index 5ebeae170..e0a3a70e0 100644 --- a/modules/editor/lang/zh-TW.lang.php +++ b/modules/editor/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 網頁編輯器(editor)模組正體中文語言 **/ diff --git a/modules/editor/skins/xpresseditor/js/Xpress_Editor.js b/modules/editor/skins/xpresseditor/js/Xpress_Editor.js index 41cf1501b..5feb245b3 100644 --- a/modules/editor/skins/xpresseditor/js/Xpress_Editor.js +++ b/modules/editor/skins/xpresseditor/js/Xpress_Editor.js @@ -2986,8 +2986,7 @@ var TextRange = function(oEl) { /** * Selection for textfield - * - * @author hooriza + * @author NHN (developer@xpressengine.com) */ TextRange.prototype.getSelection = function() { var obj = this._o; @@ -5425,7 +5424,7 @@ var oMessageMap = { xe.XpressCore.oMessageMap = oMessageMap; /** * XHTML Formatter - * @author gony + * @author NHN (developer@xpressengine.com) */ var regex_meanless_css1 = /<(.*?)\s+style\s*=\s*"(.*?(?:margin|padding)\s*:\s*0(?:px)?.*?|.*?\-(?:moz|ms|webkit|opera).*?)"(.*?)>/ig, @@ -5661,7 +5660,7 @@ xe.XE_XHTMLFormatter = $.Class({ /** * Support XE extensions - * @author gony + * @author NHN (developer@xpressengine.com) */ xe.XE_Extension = $.Class({ name : "XE_Extension", @@ -5748,7 +5747,7 @@ xe.XE_Extension = $.Class({ }); /** * Auto saving - * @author gony + * @author NHN (developer@xpressengine.com) */ xe.XE_AutoSave = $.Class({ name : "XE_AutoSave", @@ -5795,7 +5794,7 @@ xe.XE_AutoSave = $.Class({ }); /** * Format Block plugin - * @author gony + * @author NHN (developer@xpressengine.com) */ xe.XE_FormatWithSelectUI = $.Class({ name : "XE_FormatWithSelectUI", @@ -5835,7 +5834,7 @@ xe.XE_FormatWithSelectUI = $.Class({ }); /** * Enhanced Table Fetures - * @author gony + * @author NHN (developer@xpressengine.com) */ // 표 편집 확장 기능 diff --git a/modules/editor/skins/xpresseditor/skin.xml b/modules/editor/skins/xpresseditor/skin.xml index 52c8d4214..95cbb0f3d 100644 --- a/modules/editor/skins/xpresseditor/skin.xml +++ b/modules/editor/skins/xpresseditor/skin.xml @@ -8,36 +8,36 @@ XpressEditor皮肤 XpressEditor面板 - XpressEditor based on SmartEditor Basic by 행복한고니 + XpressEditor based on SmartEditor Basic by NHN - XpressEditor based on SmartEditor Basic by gony + XpressEditor based on SmartEditor Basic by NHN - XpressEditor dựa trên SmartEditor cơ bản, được tạo bởi gony + XpressEditor dựa trên SmartEditor cơ bản, được tạo bởi NHN - XpressEditor based on SmartEditor Basic by gony + XpressEditor based on SmartEditor Basic by NHN - XpressEditor based on SmartEditor Basic by gony + XpressEditor based on SmartEditor Basic by NHN - XpressEditor based on SmartEditor Basic by gony + XpressEditor based on SmartEditor Basic by NHN - XpressEditor based on SmartEditor Basic by gony + XpressEditor based on SmartEditor Basic by NHN 0.3.16 2009-03-22 - - 행복한고니 - gony - gony - gony - gony - gony - gony + + NHN + NHN + NHN + NHN + NHN + NHN + NHN diff --git a/modules/editor/styles/default/editor.css b/modules/editor/styles/default/editor.css index 6353c0301..8dc9ee37d 100644 --- a/modules/editor/styles/default/editor.css +++ b/modules/editor/styles/default/editor.css @@ -1,23 +1,23 @@ -@charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ - -html, body { height:100%; background-color:transparent; padding:0; margin:0;} -.xe_content{ color:#000; font-size:12px; line-height:1.5;} - -.xe_content blockquote.q1, -.xe_content blockquote.q2, -.xe_content blockquote.q3, -.xe_content blockquote.q4, -.xe_content blockquote.q5, -.xe_content blockquote.q6, -.xe_content blockquote.q7{ padding:10px; margin:0 15px; } - -.xe_content blockquote.q1{ padding:0 10px; border-left:2px solid #ccc;} -.xe_content blockquote.q2{ padding:0 10px; background:url(./img/bg_qmark.gif) no-repeat left top;} -.xe_content blockquote.q3{ border:1px solid #d9d9d9;} -.xe_content blockquote.q4{ border:1px solid #d9d9d9; background:#fbfbfb;} -.xe_content blockquote.q5{ border:2px solid #707070;} -.xe_content blockquote.q6{ border:1px dashed #707070;} -.xe_content blockquote.q7{ border:1px dashed #707070; background:#fbfbfb;} - -.xe_content p { margin:0; padding:0; } +@charset "utf-8"; +/* NHN (developers@xpressengine.com) */ + +html, body { height:100%; background-color:transparent; padding:0; margin:0;} +.xe_content{ color:#000; font-size:12px; line-height:1.5;} + +.xe_content blockquote.q1, +.xe_content blockquote.q2, +.xe_content blockquote.q3, +.xe_content blockquote.q4, +.xe_content blockquote.q5, +.xe_content blockquote.q6, +.xe_content blockquote.q7{ padding:10px; margin:0 15px; } + +.xe_content blockquote.q1{ padding:0 10px; border-left:2px solid #ccc;} +.xe_content blockquote.q2{ padding:0 10px; background:url(./img/bg_qmark.gif) no-repeat left top;} +.xe_content blockquote.q3{ border:1px solid #d9d9d9;} +.xe_content blockquote.q4{ border:1px solid #d9d9d9; background:#fbfbfb;} +.xe_content blockquote.q5{ border:2px solid #707070;} +.xe_content blockquote.q6{ border:1px dashed #707070;} +.xe_content blockquote.q7{ border:1px dashed #707070; background:#fbfbfb;} + +.xe_content p { margin:0; padding:0; } diff --git a/modules/editor/styles/default/skin.xml b/modules/editor/styles/default/skin.xml index ca7789220..0417ea83e 100644 --- a/modules/editor/styles/default/skin.xml +++ b/modules/editor/styles/default/skin.xml @@ -1,43 +1,43 @@ - - - XE 기본 서식 - XE Default Form - XE默认样式 - XE Mặc định - XEデフォルトスタイル - XE預設樣式 - - XE 기본 문서 서식입니다. - 있는 그대로 표시가 될 뿐 편집/ 출력시 아무런 영향을 끼치지 않습니다. - - - XE default document style. - It displays as it is, and affect nothing to editing / printing. - - - XE默认样式。 - 主题显示及编辑不会受到任何影响,即原样输出。 - - - XE預設樣式。 - 主題顯示和編輯不會受到影響。 - - - XEの基本ドキュメント書式です。 - そのまま表示されるだけで、編集・出力には影響しません。 - - - Trang mẫu mặc định của XE. - Nó sẽ hiển thị trong phần sửa đổi bài viết và không ảnh hưởng đến bất cứ chức năng nào cả. - - 0.0.1 - 2009-05-23 - - 정찬명 - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong - - + + + XE 기본 서식 + XE Default Form + XE默认样式 + XE Mặc định + XEデフォルトスタイル + XE預設樣式 + + XE 기본 문서 서식입니다. + 있는 그대로 표시가 될 뿐 편집/ 출력시 아무런 영향을 끼치지 않습니다. + + + XE default document style. + It displays as it is, and affect nothing to editing / printing. + + + XE默认样式。 + 主题显示及编辑不会受到任何影响,即原样输出。 + + + XE預設樣式。 + 主題顯示和編輯不會受到影響。 + + + XEの基本ドキュメント書式です。 + そのまま表示されるだけで、編集・出力には影響しません。 + + + Trang mẫu mặc định của XE. + Nó sẽ hiển thị trong phần sửa đổi bài viết và không ảnh hưởng đến bất cứ chức năng nào cả. + + 0.0.1 + 2009-05-23 + + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/styles/default/style.css b/modules/editor/styles/default/style.css index e15d15a4d..fdb594527 100755 --- a/modules/editor/styles/default/style.css +++ b/modules/editor/styles/default/style.css @@ -1,5 +1,6 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ + /* xe_content */ .xe_content{ color:#000; font-size:12px;} diff --git a/modules/editor/styles/xeStyle/editor.css b/modules/editor/styles/xeStyle/editor.css index 6dccd1b27..d1ac2cce6 100755 --- a/modules/editor/styles/xeStyle/editor.css +++ b/modules/editor/styles/xeStyle/editor.css @@ -1,5 +1,5 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ html, body { height:100%; background-color:transparent; padding:0; margin:0;} diff --git a/modules/editor/styles/xeStyle/skin.xml b/modules/editor/styles/xeStyle/skin.xml index ef150b566..4e20af40a 100644 --- a/modules/editor/styles/xeStyle/skin.xml +++ b/modules/editor/styles/xeStyle/skin.xml @@ -1,41 +1,41 @@ - - - XE 기본 서식 (하얀 배경) - XE Default Form(white color background) - XE默认样式(白色背景) - XE預設樣式(白色背景) - XE Mặc định (Nền sáng) - XEデフォルトスタイル(白色背景) - - XE 기본 문서 서식입니다. - 문서 수정중에는 각 요소들이 구분되어 보입니다. - - - XE Default Form(white color background) - - - XE默认样式。 - 在编辑文档时,可清晰地区分各标签区域。 - - - XE編輯器預設樣式。 - 編輯檔案時,可以清楚地區分各標籤。 - - - Trang mẫu mặc định của XE. - Nó sẽ hiển thị trong phần sửa đổi bài viết. - - - XEのデフォルトドキュメントのスタイルです。 - ドキュメント編集中には、各要素が区分されて見えます。 - - 0.0.1 - 2009-04-17 - - 정찬명 - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong - - + + + XE 기본 서식 (하얀 배경) + XE Default Form(white color background) + XE默认样式(白色背景) + XE預設樣式(白色背景) + XE Mặc định (Nền sáng) + XEデフォルトスタイル(白色背景) + + XE 기본 문서 서식입니다. + 문서 수정중에는 각 요소들이 구분되어 보입니다. + + + XE Default Form(white color background) + + + XE默认样式。 + 在编辑文档时,可清晰地区分各标签区域。 + + + XE編輯器預設樣式。 + 編輯檔案時,可以清楚地區分各標籤。 + + + Trang mẫu mặc định của XE. + Nó sẽ hiển thị trong phần sửa đổi bài viết. + + + XEのデフォルトドキュメントのスタイルです。 + ドキュメント編集中には、各要素が区分されて見えます。 + + 0.0.1 + 2009-04-17 + + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/editor/styles/xeStyle/style.css b/modules/editor/styles/xeStyle/style.css index bfe49b4b8..0346feea7 100755 --- a/modules/editor/styles/xeStyle/style.css +++ b/modules/editor/styles/xeStyle/style.css @@ -1,5 +1,6 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ + /* xe_content */ .xe_content{ color:#000; font-size:12px;} diff --git a/modules/editor/styles/xeStyleBlack/editor.css b/modules/editor/styles/xeStyleBlack/editor.css index d87070418..8ef0e7cc5 100644 --- a/modules/editor/styles/xeStyleBlack/editor.css +++ b/modules/editor/styles/xeStyleBlack/editor.css @@ -1,33 +1,33 @@ -@charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ - -html, body { height:100%; background-color:transparent; padding:0; margin:0;} - -/* Editable */ -.xe_content.editable { margin-right:8px; } -.xe_content.editable h1, -.xe_content.editable h2, -.xe_content.editable h3, -.xe_content.editable h4, -.xe_content.editable h5, -.xe_content.editable h6, -.xe_content.editable p, -.xe_content.editable ul, -.xe_content.editable ol, -.xe_content.editable dl, -.xe_content.editable div, -.xe_content.editable code.block{ border:1px dotted #444;} -.xe_content.editable h1:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right top;} -.xe_content.editable h2:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -100px;} -.xe_content.editable h3:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -200px;} -.xe_content.editable h4:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -300px;} -.xe_content.editable h5:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -400px;} -.xe_content.editable h6:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -500px;} -.xe_content.editable p{ background-image:url(./img/elementP.gif); background-repeat:no-repeat; background-position:right top;} -.xe_content.editable ul{ background-image:url(./img/elementUl.gif); background-repeat:no-repeat; background-position:right top;} -.xe_content.editable ol{ background-image:url(./img/elementOl.gif); background-repeat:no-repeat; background-position:right top;} -.xe_content.editable dl{ background-image:url(./img/elementDl.gif); background-repeat:no-repeat; background-position:right top;} -.xe_content.editable div{ background-image:url(./img/elementDiv.gif); background-repeat:no-repeat; background-position:right top;} -.xe_content.editable code.block{ background-image:url(./img/elementCode.gif); background-repeat:no-repeat; background-position:right top;} - - +@charset "utf-8"; +/* NHN (developers@xpressengine.com) */ + +html, body { height:100%; background-color:transparent; padding:0; margin:0;} + +/* Editable */ +.xe_content.editable { margin-right:8px; } +.xe_content.editable h1, +.xe_content.editable h2, +.xe_content.editable h3, +.xe_content.editable h4, +.xe_content.editable h5, +.xe_content.editable h6, +.xe_content.editable p, +.xe_content.editable ul, +.xe_content.editable ol, +.xe_content.editable dl, +.xe_content.editable div, +.xe_content.editable code.block{ border:1px dotted #444;} +.xe_content.editable h1:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right top;} +.xe_content.editable h2:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -100px;} +.xe_content.editable h3:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -200px;} +.xe_content.editable h4:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -300px;} +.xe_content.editable h5:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -400px;} +.xe_content.editable h6:before{ content:""; display:block; width:100%; height:9px; margin-bottom:-9px; background-image:url(./img/elementH.gif); background-repeat:no-repeat; background-position:right -500px;} +.xe_content.editable p{ background-image:url(./img/elementP.gif); background-repeat:no-repeat; background-position:right top;} +.xe_content.editable ul{ background-image:url(./img/elementUl.gif); background-repeat:no-repeat; background-position:right top;} +.xe_content.editable ol{ background-image:url(./img/elementOl.gif); background-repeat:no-repeat; background-position:right top;} +.xe_content.editable dl{ background-image:url(./img/elementDl.gif); background-repeat:no-repeat; background-position:right top;} +.xe_content.editable div{ background-image:url(./img/elementDiv.gif); background-repeat:no-repeat; background-position:right top;} +.xe_content.editable code.block{ background-image:url(./img/elementCode.gif); background-repeat:no-repeat; background-position:right top;} + + diff --git a/modules/editor/styles/xeStyleBlack/skin.xml b/modules/editor/styles/xeStyleBlack/skin.xml index b1b016bfa..f670053cc 100644 --- a/modules/editor/styles/xeStyleBlack/skin.xml +++ b/modules/editor/styles/xeStyleBlack/skin.xml @@ -31,11 +31,11 @@ 0.0.1 2009-04-17 - - 정찬명 - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong - Chan-Myung Jeong + + NHN + NHN + NHN + NHN + NHN diff --git a/modules/editor/tpl/js/editor.js b/modules/editor/tpl/js/editor.js index 38c064521..1368d1b98 100755 --- a/modules/editor/tpl/js/editor.js +++ b/modules/editor/tpl/js/editor.js @@ -1,5 +1,5 @@ /** - * @author zero (zero@nzeo.com) + * @author NHN (developers@xpressengine.com) * @version 0.1 * @brief 에디터 관련 스크립트 */ diff --git a/modules/editor/tpl/js/editor_admin.js b/modules/editor/tpl/js/editor_admin.js index d0190cc99..50ee127c8 100644 --- a/modules/editor/tpl/js/editor_admin.js +++ b/modules/editor/tpl/js/editor_admin.js @@ -1,43 +1,43 @@ -/** - * @author zero (zero@nzeo.com) - * @version 0.1 - * @brief 에디터 관리자 페이지용 스크립트 - **/ - -function doEnableComponent(component_name) { - var params = new Array(); - params['component_name'] = component_name; - - exec_xml('editor', 'procEditorAdminEnableComponent', params, completeUpdate); -} - -function doDisableComponent(component_name) { - var params = new Array(); - params['component_name'] = component_name; - - exec_xml('editor', 'procEditorAdminDisableComponent', params, completeUpdate); -} - -function doMoveListOrder(component_name, mode) { - var params = new Array(); - params['component_name'] = component_name; - params['mode'] = mode; - - exec_xml('editor', 'procEditorAdminMoveListOrder', params, completeUpdate); -} - -function completeUpdate(ret_obj) { - location.reload(); -} - -function doSetupComponent(component_name) { - popopen(request_uri.setQuery('module','editor').setQuery('act','dispEditorAdminSetupComponent').setQuery('component_name',component_name), 'SetupComponent'); -} - -function toggleSectionCheckBox(obj, id) { - var box_list = xGetElementsByTagName('input', xGetElementById(id)); - if(typeof(box_list.length)=='undefined') return; - for(var i in box_list) { - box_list[i].checked = obj.checked; - } -} +/** + * @author NHN (developers@xpressengine.com) + * @version 0.1 + * @brief 에디터 관리자 페이지용 스크립트 + **/ + +function doEnableComponent(component_name) { + var params = new Array(); + params['component_name'] = component_name; + + exec_xml('editor', 'procEditorAdminEnableComponent', params, completeUpdate); +} + +function doDisableComponent(component_name) { + var params = new Array(); + params['component_name'] = component_name; + + exec_xml('editor', 'procEditorAdminDisableComponent', params, completeUpdate); +} + +function doMoveListOrder(component_name, mode) { + var params = new Array(); + params['component_name'] = component_name; + params['mode'] = mode; + + exec_xml('editor', 'procEditorAdminMoveListOrder', params, completeUpdate); +} + +function completeUpdate(ret_obj) { + location.reload(); +} + +function doSetupComponent(component_name) { + popopen(request_uri.setQuery('module','editor').setQuery('act','dispEditorAdminSetupComponent').setQuery('component_name',component_name), 'SetupComponent'); +} + +function toggleSectionCheckBox(obj, id) { + var box_list = xGetElementsByTagName('input', xGetElementById(id)); + if(typeof(box_list.length)=='undefined') return; + for(var i in box_list) { + box_list[i].checked = obj.checked; + } +} diff --git a/modules/editor/tpl/js/uploader.js b/modules/editor/tpl/js/uploader.js index 571a8c89d..de274f590 100755 --- a/modules/editor/tpl/js/uploader.js +++ b/modules/editor/tpl/js/uploader.js @@ -1,436 +1,436 @@ -/** - * @author zero (zero@nzeo.com) - * @version 0.1.1 - * @brief 파일 업로드 관련 - **/ -var uploadedFiles = new Array(); -var uploaderSettings = new Array(); -var loaded_images = new Array(); -var swfUploadObjs = new Array(); -var uploadSettingObj = new Array(); -var uploadAutosaveChecker = false; - -/** - * 업로드를 하기 위한 준비 시작 - * 이 함수는 editor.html 에서 파일 업로드 가능할 경우 호출됨 - **/ -// window.load 이벤트일 경우 && 문서 번호가 가상의 번호가 아니면 기존에 저장되어 있을지도 모르는 파일 목록을 가져옴 -function editorUploadInit(obj, exe) { - if(typeof(obj["editorSequence"])=="undefined") return; - if(typeof(obj["sessionName"])=="undefined") obj["sessionName"]= "PHPSESSID"; - if(typeof(obj["allowedFileSize"])=="undefined") obj["allowedFileSize"]= 2*1024*1024; - if(typeof(obj["allowedFileTypes"])=="undefined") obj["allowedFileTypes"]= "*.*"; - if(typeof(obj["allowedFileTypesDescription"])=="undefined") obj["allowedFileTypesDescription"]= "All Files"; - if(typeof(obj["replaceButtonID"])=="undefined") obj["replaceButtonID"] = "swfUploadButton"+obj["editorSequence"]; - if(typeof(obj["insertedFiles"])=="undefined") obj["insertedFiles"] = 0; - if(exe) XEUploaderStart(obj); - if(!exe) xAddEventListener(window,"load",function() { XEUploaderStart(obj) }); - uploadSettingObj[obj["editorSequence"]] = obj; -} - -// 파일 업로드를 위한 기본 준비를 함 -function XEUploaderStart(obj) { - try { document.execCommand('BackgroundImageCache',false,true); } catch(e) { } - - var btnObj = xGetElementById(obj["replaceButtonID"]); - var btnWidth = xWidth(btnObj); - var btnHeight = xHeight(btnObj); - btnObj.style.position = "relative"; - - var dummy = xCreateElement("span"); - dummy.id = "dummy"+obj["replaceButtonID"]; - btnObj.appendChild(dummy); - - var settings = { - flash_url : request_uri+"modules/editor/tpl/images/SWFUpload.swf", - upload_url: request_uri.replace(/^https/i,'http'), - post_params: { - "mid" : current_mid, - "act" : "procFileUpload", - "editor_sequence" : obj["editorSequence"], - "uploadTargetSrl" : editorRelKeys[obj["editorSequence"]]["primary"].value - }, - file_size_limit : parseInt(parseInt(obj["allowedFileSize"],10)/1024,10), - file_queue_limit : 0, - file_upload_limit : 0, - file_types : obj["allowedFileTypes"], - file_types_description : obj["allowedFileTypesDescription"], - custom_settings : { - progressTarget : null, - cancelButtonId : null - }, - debug: false, - - // Button settings - button_window_mode: 'transparent', - button_placeholder_id: dummy.id, - button_text: null, - button_image_url: "", - button_width: btnWidth, - button_height: btnHeight, - button_text_style: null, - button_text_left_padding: 0, - button_text_top_padding: 0, - button_cursor:-2, - - // The event handler functions are defined in handlers.js - file_queued_handler : fileQueued, - file_queue_error_handler : fileQueueError, - file_dialog_complete_handler : fileDialogComplete, - upload_start_handler : uploadStart, - upload_progress_handler : uploadProgress, - upload_error_handler : uploadError, - upload_success_handler : uploadSuccess, - upload_complete_handler : uploadComplete, - queue_complete_handler :queueComplete - }; - if(typeof(xeVid)!='undefined') settings["post_params"]["vid"] = xeVid; - settings["post_params"][obj["sessionName"]] = xGetCookie(obj["sessionName"]); - settings["editorSequence"] = obj["editorSequence"]; - settings["uploadTargetSrl"] = editorRelKeys[obj["editorSequence"]]["primary"].value; - settings["fileListAreaID"] = obj["fileListAreaID"]; - settings["previewAreaID"] = obj["previewAreaID"]; - settings["uploaderStatusID"] = obj["uploaderStatusID"]; - - uploaderSettings[obj["editorSequence"]] = settings; - - var swfu = new SWFUpload(settings); - var swfObj = xGetElementById(swfu.movieName); - swfUploadObjs[obj["editorSequence"]] = swfu.movieName; - if(!swfObj) return; - - swfObj.style.display = "block"; - swfObj.style.cursor = "pointer"; - swfObj.style.position = "absolute"; - swfObj.style.left = 0; - swfObj.style.top = "-3px"; - swfObj.style.width = btnWidth+"px"; - swfObj.style.height = btnHeight+"px"; - - if(obj["insertedFiles"]>0 || editorRelKeys[obj["editorSequence"]]["primary"].value > 0) reloadFileList(settings); -} - -function fileQueued(file) { -} - -function fileQueueError(file, errorCode, message) { - try { - switch(errorCode) { - case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED : - alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file."))); - break; - case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: - alert("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: - alert("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: - alert("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - default: - alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - } - } catch(ex) { - this.debug(ex); - } -} - -function fileDialogComplete(numFilesSelected, numFilesQueued) { - try { - this.startUpload(); - } catch (ex) { - this.debug(ex); - } -} - -function uploadStart(file) { - return true; -} - -function uploadProgress(file, bytesLoaded, bytesTotal) { - try { - var obj = xGetElementById(this.settings["fileListAreaID"]); - - var percent = Math.ceil((bytesLoaded / bytesTotal) * 100); - var filename = file.name; - if(filename.length>20) filename = filename.substr(0,20)+'...'; - - var text = filename + ' ('+percent+'%)'; - if(!obj.options.length || obj.options[obj.options.length-1].value != file.id) { - var opt_obj = new Option(text, file.id, true, true); - obj.options[obj.options.length] = opt_obj; - } else { - obj.options[obj.options.length-1].text = text; - } - } catch (ex) { - this.debug(ex); - } -} - -function uploadSuccess(file, serverData) { - try { - if(this.getStats().files_queued !== 0) this.startUpload(); - } catch (ex) { - this.debug(ex); - } -} - -function uploadError(file, errorCode, message) { - try { - switch (errorCode) { - case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: - alert("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: - alert("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.UPLOAD_ERROR.IO_ERROR: - alert("Error Code: IO Error, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: - alert("Error Code: Security Error, File name: " + file.name + ", Message: " + message); - break; - case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: - alert("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: - alert("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: - // If there aren't any files left (they were all cancelled) disable the cancel button - if (this.getStats().files_queued === 0) { - document.getElementById(this.customSettings.cancelButtonId).disabled = true; - } - break; - case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: - break; - default: - alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); - break; - } - } catch (ex) { - this.debug(ex); - } -} - -function uploadComplete(file) { - try { - var fileListAreaID = this.settings["fileListAreaID"]; - var uploadTargetSrl = this.settings["uploadTargetSrl"]; - reloadFileList(this.settings); - } catch(e) { - this.debug(ex); - } -} - -function queueComplete(numFilesUploaded) { -} - -function reloadFileList(settings) { - var params = new Array(); - params["file_list_area_id"] = settings["fileListAreaID"]; - params["editor_sequence"] = settings["editorSequence"]; - params["upload_target_srl"] = settings["uploadTargetSrl"]; - params["mid"] = current_mid; - var response_tags = new Array("error","message","files","upload_status","upload_target_srl","editor_sequence","left_size"); - exec_xml("file","getFileList", params, completeReloadFileList, response_tags, settings); -} - -function completeReloadFileList(ret_obj, response_tags, settings) { - var upload_target_srl = ret_obj['upload_target_srl']; - var editor_sequence = ret_obj['editor_sequence']; - var upload_status = ret_obj['upload_status']; - var files = ret_obj['files']; - var file_list_area_id = settings["fileListAreaID"]; - var listObj = xGetElementById(file_list_area_id); - var left_size = parseInt(parseInt(ret_obj["left_size"],10)/1024,10); - while(listObj.options.length) { - listObj.remove(0); - } - - if(upload_target_srl && upload_target_srl != 0) { - // 자동 저장된 문서와 target_srl이 다르게 될 경우 다시 자동 저장. - if(editorRelKeys[editor_sequence]["primary"].value != upload_target_srl) { - editorRelKeys[editor_sequence]["primary"].value = upload_target_srl; - uploadAutosaveChecker = true; - _editorAutoSave(true); - } - - editorRelKeys[editor_sequence]["primary"].value = upload_target_srl; - settings["uploadTargetSrl"] = upload_target_srl; - } - - var statusObj = xGetElementById(settings["uploaderStatusID"]); - if(statusObj) xInnerHtml(statusObj, upload_status); - - var previewObj = xGetElementById(settings["previewAreaID"]); - if(previewObj) xInnerHtml(previewObj,""); - - if(files && typeof(files['item'])!='undefined') { - var item = files['item']; - if(typeof(item.length)=='undefined' || item.length<1) item = new Array(item); - if(item.length) { - for(var i=0;i"; - xInnerHtml(previewAreaID, html); - return; - } - - var html = ""; - var uploaded_filename = file_info.download_url; - - // 플래쉬 동영상의 경우 - if(/\.flv$/i.test(uploaded_filename)) { - html = ""; - - // 플래쉬 파일의 경우 - } else if(/\.swf$/i.test(uploaded_filename)) { - html = ""; - - // wmv, avi, mpg, mpeg등의 동영상 파일의 경우 - } else if(/\.(wmv|avi|mpg|mpeg|asx|asf|mp3)$/i.test(uploaded_filename)) { - html = ""; - - // 이미지 파일의 경우 - } else if(/\.(jpg|jpeg|png|gif)$/i.test(uploaded_filename)) { - html = ""; - } else if(uploaded_filename) { - html = ""; - } - xInnerHtml(previewAreaID, html); -} - -function removeUploadedFile(editorSequence) { - var settings = uploaderSettings[editorSequence]; - var fileListAreaID = settings["fileListAreaID"]; - var fileListObj = xGetElementById(fileListAreaID); - if(!fileListObj) return; - - if(fileListObj.selectedIndex<0) return; - - var file_srls = new Array(); - for(var i=0;i"); - } - - // binary파일의 경우 url_link 컴포넌트 연결 - } else { - text.push(""+file.source_filename+"\n"); - } - } - - // html 모드 - if(editorMode[editorSequence]=='html'){ - if(text.length>0) xGetElementById('editor_textarea_'+editorSequence).value += text.join(''); - - // 위지윅 모드 - }else{ - var iframe_obj = editorGetIFrame(editorSequence); - if(!iframe_obj) return; - if(text.length>0) editorReplaceHTML(iframe_obj, text.join('')); - } -} +/** + * @author NHN (developers@xpressengine.com) + * @version 0.1.1 + * @brief 파일 업로드 관련 + **/ +var uploadedFiles = new Array(); +var uploaderSettings = new Array(); +var loaded_images = new Array(); +var swfUploadObjs = new Array(); +var uploadSettingObj = new Array(); +var uploadAutosaveChecker = false; + +/** + * 업로드를 하기 위한 준비 시작 + * 이 함수는 editor.html 에서 파일 업로드 가능할 경우 호출됨 + **/ +// window.load 이벤트일 경우 && 문서 번호가 가상의 번호가 아니면 기존에 저장되어 있을지도 모르는 파일 목록을 가져옴 +function editorUploadInit(obj, exe) { + if(typeof(obj["editorSequence"])=="undefined") return; + if(typeof(obj["sessionName"])=="undefined") obj["sessionName"]= "PHPSESSID"; + if(typeof(obj["allowedFileSize"])=="undefined") obj["allowedFileSize"]= 2*1024*1024; + if(typeof(obj["allowedFileTypes"])=="undefined") obj["allowedFileTypes"]= "*.*"; + if(typeof(obj["allowedFileTypesDescription"])=="undefined") obj["allowedFileTypesDescription"]= "All Files"; + if(typeof(obj["replaceButtonID"])=="undefined") obj["replaceButtonID"] = "swfUploadButton"+obj["editorSequence"]; + if(typeof(obj["insertedFiles"])=="undefined") obj["insertedFiles"] = 0; + if(exe) XEUploaderStart(obj); + if(!exe) xAddEventListener(window,"load",function() { XEUploaderStart(obj) }); + uploadSettingObj[obj["editorSequence"]] = obj; +} + +// 파일 업로드를 위한 기본 준비를 함 +function XEUploaderStart(obj) { + try { document.execCommand('BackgroundImageCache',false,true); } catch(e) { } + + var btnObj = xGetElementById(obj["replaceButtonID"]); + var btnWidth = xWidth(btnObj); + var btnHeight = xHeight(btnObj); + btnObj.style.position = "relative"; + + var dummy = xCreateElement("span"); + dummy.id = "dummy"+obj["replaceButtonID"]; + btnObj.appendChild(dummy); + + var settings = { + flash_url : request_uri+"modules/editor/tpl/images/SWFUpload.swf", + upload_url: request_uri.replace(/^https/i,'http'), + post_params: { + "mid" : current_mid, + "act" : "procFileUpload", + "editor_sequence" : obj["editorSequence"], + "uploadTargetSrl" : editorRelKeys[obj["editorSequence"]]["primary"].value + }, + file_size_limit : parseInt(parseInt(obj["allowedFileSize"],10)/1024,10), + file_queue_limit : 0, + file_upload_limit : 0, + file_types : obj["allowedFileTypes"], + file_types_description : obj["allowedFileTypesDescription"], + custom_settings : { + progressTarget : null, + cancelButtonId : null + }, + debug: false, + + // Button settings + button_window_mode: 'transparent', + button_placeholder_id: dummy.id, + button_text: null, + button_image_url: "", + button_width: btnWidth, + button_height: btnHeight, + button_text_style: null, + button_text_left_padding: 0, + button_text_top_padding: 0, + button_cursor:-2, + + // The event handler functions are defined in handlers.js + file_queued_handler : fileQueued, + file_queue_error_handler : fileQueueError, + file_dialog_complete_handler : fileDialogComplete, + upload_start_handler : uploadStart, + upload_progress_handler : uploadProgress, + upload_error_handler : uploadError, + upload_success_handler : uploadSuccess, + upload_complete_handler : uploadComplete, + queue_complete_handler :queueComplete + }; + if(typeof(xeVid)!='undefined') settings["post_params"]["vid"] = xeVid; + settings["post_params"][obj["sessionName"]] = xGetCookie(obj["sessionName"]); + settings["editorSequence"] = obj["editorSequence"]; + settings["uploadTargetSrl"] = editorRelKeys[obj["editorSequence"]]["primary"].value; + settings["fileListAreaID"] = obj["fileListAreaID"]; + settings["previewAreaID"] = obj["previewAreaID"]; + settings["uploaderStatusID"] = obj["uploaderStatusID"]; + + uploaderSettings[obj["editorSequence"]] = settings; + + var swfu = new SWFUpload(settings); + var swfObj = xGetElementById(swfu.movieName); + swfUploadObjs[obj["editorSequence"]] = swfu.movieName; + if(!swfObj) return; + + swfObj.style.display = "block"; + swfObj.style.cursor = "pointer"; + swfObj.style.position = "absolute"; + swfObj.style.left = 0; + swfObj.style.top = "-3px"; + swfObj.style.width = btnWidth+"px"; + swfObj.style.height = btnHeight+"px"; + + if(obj["insertedFiles"]>0 || editorRelKeys[obj["editorSequence"]]["primary"].value > 0) reloadFileList(settings); +} + +function fileQueued(file) { +} + +function fileQueueError(file, errorCode, message) { + try { + switch(errorCode) { + case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED : + alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file."))); + break; + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT: + alert("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE: + alert("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE: + alert("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + default: + alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + } + } catch(ex) { + this.debug(ex); + } +} + +function fileDialogComplete(numFilesSelected, numFilesQueued) { + try { + this.startUpload(); + } catch (ex) { + this.debug(ex); + } +} + +function uploadStart(file) { + return true; +} + +function uploadProgress(file, bytesLoaded, bytesTotal) { + try { + var obj = xGetElementById(this.settings["fileListAreaID"]); + + var percent = Math.ceil((bytesLoaded / bytesTotal) * 100); + var filename = file.name; + if(filename.length>20) filename = filename.substr(0,20)+'...'; + + var text = filename + ' ('+percent+'%)'; + if(!obj.options.length || obj.options[obj.options.length-1].value != file.id) { + var opt_obj = new Option(text, file.id, true, true); + obj.options[obj.options.length] = opt_obj; + } else { + obj.options[obj.options.length-1].text = text; + } + } catch (ex) { + this.debug(ex); + } +} + +function uploadSuccess(file, serverData) { + try { + if(this.getStats().files_queued !== 0) this.startUpload(); + } catch (ex) { + this.debug(ex); + } +} + +function uploadError(file, errorCode, message) { + try { + switch (errorCode) { + case SWFUpload.UPLOAD_ERROR.HTTP_ERROR: + alert("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED: + alert("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.IO_ERROR: + alert("Error Code: IO Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR: + alert("Error Code: Security Error, File name: " + file.name + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED: + alert("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED: + alert("Error Code: File Validation Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED: + // If there aren't any files left (they were all cancelled) disable the cancel button + if (this.getStats().files_queued === 0) { + document.getElementById(this.customSettings.cancelButtonId).disabled = true; + } + break; + case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED: + break; + default: + alert("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message); + break; + } + } catch (ex) { + this.debug(ex); + } +} + +function uploadComplete(file) { + try { + var fileListAreaID = this.settings["fileListAreaID"]; + var uploadTargetSrl = this.settings["uploadTargetSrl"]; + reloadFileList(this.settings); + } catch(e) { + this.debug(ex); + } +} + +function queueComplete(numFilesUploaded) { +} + +function reloadFileList(settings) { + var params = new Array(); + params["file_list_area_id"] = settings["fileListAreaID"]; + params["editor_sequence"] = settings["editorSequence"]; + params["upload_target_srl"] = settings["uploadTargetSrl"]; + params["mid"] = current_mid; + var response_tags = new Array("error","message","files","upload_status","upload_target_srl","editor_sequence","left_size"); + exec_xml("file","getFileList", params, completeReloadFileList, response_tags, settings); +} + +function completeReloadFileList(ret_obj, response_tags, settings) { + var upload_target_srl = ret_obj['upload_target_srl']; + var editor_sequence = ret_obj['editor_sequence']; + var upload_status = ret_obj['upload_status']; + var files = ret_obj['files']; + var file_list_area_id = settings["fileListAreaID"]; + var listObj = xGetElementById(file_list_area_id); + var left_size = parseInt(parseInt(ret_obj["left_size"],10)/1024,10); + while(listObj.options.length) { + listObj.remove(0); + } + + if(upload_target_srl && upload_target_srl != 0) { + // 자동 저장된 문서와 target_srl이 다르게 될 경우 다시 자동 저장. + if(editorRelKeys[editor_sequence]["primary"].value != upload_target_srl) { + editorRelKeys[editor_sequence]["primary"].value = upload_target_srl; + uploadAutosaveChecker = true; + _editorAutoSave(true); + } + + editorRelKeys[editor_sequence]["primary"].value = upload_target_srl; + settings["uploadTargetSrl"] = upload_target_srl; + } + + var statusObj = xGetElementById(settings["uploaderStatusID"]); + if(statusObj) xInnerHtml(statusObj, upload_status); + + var previewObj = xGetElementById(settings["previewAreaID"]); + if(previewObj) xInnerHtml(previewObj,""); + + if(files && typeof(files['item'])!='undefined') { + var item = files['item']; + if(typeof(item.length)=='undefined' || item.length<1) item = new Array(item); + if(item.length) { + for(var i=0;i"; + xInnerHtml(previewAreaID, html); + return; + } + + var html = ""; + var uploaded_filename = file_info.download_url; + + // 플래쉬 동영상의 경우 + if(/\.flv$/i.test(uploaded_filename)) { + html = ""; + + // 플래쉬 파일의 경우 + } else if(/\.swf$/i.test(uploaded_filename)) { + html = ""; + + // wmv, avi, mpg, mpeg등의 동영상 파일의 경우 + } else if(/\.(wmv|avi|mpg|mpeg|asx|asf|mp3)$/i.test(uploaded_filename)) { + html = ""; + + // 이미지 파일의 경우 + } else if(/\.(jpg|jpeg|png|gif)$/i.test(uploaded_filename)) { + html = ""; + } else if(uploaded_filename) { + html = ""; + } + xInnerHtml(previewAreaID, html); +} + +function removeUploadedFile(editorSequence) { + var settings = uploaderSettings[editorSequence]; + var fileListAreaID = settings["fileListAreaID"]; + var fileListObj = xGetElementById(fileListAreaID); + if(!fileListObj) return; + + if(fileListObj.selectedIndex<0) return; + + var file_srls = new Array(); + for(var i=0;i"); + } + + // binary파일의 경우 url_link 컴포넌트 연결 + } else { + text.push(""+file.source_filename+"\n"); + } + } + + // html 모드 + if(editorMode[editorSequence]=='html'){ + if(text.length>0) xGetElementById('editor_textarea_'+editorSequence).value += text.join(''); + + // 위지윅 모드 + }else{ + var iframe_obj = editorGetIFrame(editorSequence); + if(!iframe_obj) return; + if(text.length>0) editorReplaceHTML(iframe_obj, text.join('')); + } +} diff --git a/modules/file/conf/info.xml b/modules/file/conf/info.xml index a99e51085..ba4a9c626 100644 --- a/modules/file/conf/info.xml +++ b/modules/file/conf/info.xml @@ -1,33 +1,33 @@ - - - 첨부파일 - 附件管理 - Attachment - Đính kèm - Adjuntar archivos - 添付ファイル - Вложения - 附加檔案 - 첨부 파일 관리하는 모듈입니다. - 管理附件的模块。 - Module for managing attachments. - Module quản lý File đính kèm. - Módulo para manejar los archivos adjuntos. - 添付ファイルを管理するモジュールです。 - Модуль для управления вложениями. - 管理附加檔案的模組。 - 0.1 - 2007-02-28 - content - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 첨부파일 + 附件管理 + Attachment + Đính kèm + Adjuntar archivos + 添付ファイル + Вложения + 附加檔案 + 첨부 파일 관리하는 모듈입니다. + 管理附件的模块。 + Module for managing attachments. + Module quản lý File đính kèm. + Módulo para manejar los archivos adjuntos. + 添付ファイルを管理するモジュールです。 + Модуль для управления вложениями. + 管理附加檔案的模組。 + 0.1 + 2007-02-28 + content + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/file/file.admin.controller.php b/modules/file/file.admin.controller.php index 777e09057..6ae36fe61 100644 --- a/modules/file/file.admin.controller.php +++ b/modules/file/file.admin.controller.php @@ -1,127 +1,127 @@ -module_srl = $module_srl; - $output = executeQueryArray('file.getModuleFiles',$args); - if(!$output) return $output; - $files = $output->data; - - // DB에서 삭제 - $args->module_srl = $module_srl; - $output = executeQuery('file.deleteModuleFiles', $args); - if(!$output->toBool()) return $output; - - // 실제 파일 삭제 (일단 약속에 따라서 한번에 삭제) - FileHandler::removeDir( sprintf("./files/attach/images/%s/", $module_srl) ) ; - FileHandler::removeDir( sprintf("./files/attach/binaries/%s/", $module_srl) ); - - // DB에서 구한 파일 목록을 삭제 - $path = array(); - $cnt = count($files); - for($i=0;$i<$cnt;$i++) { - $uploaded_filename = $files[$i]->uploaded_filename; - FileHandler::removeFile($uploaded_filename); - - $path_info = pathinfo($uploaded_filename); - if(!in_array($path_info['dirname'], $path)) $path[] = $path_info['dirname']; - } - - // 해당 글의 첨부파일 디렉토리 삭제 - for($i=0;$istop('msg_cart_is_null'); - $file_srl_list= explode('|@|', $cart); - $file_count = count($file_srl_list); - if(!$file_count) return $this->stop('msg_cart_is_null'); - - $oFileController = &getController('file'); - - // 글삭제 - for($i=0;$i<$file_count;$i++) { - $file_srl = trim($file_srl_list[$i]); - if(!$file_srl) continue; - - $oFileController->deleteFile($file_srl); - } - - $this->setMessage( sprintf(Context::getLang('msg_checked_file_is_deleted'), $file_count) ); - } - - /** - * @brief 파일 기본 정보의 추가 - **/ - function procFileAdminInsertConfig() { - // 설정 정보를 받아옴 (module model 객체를 이용) - $config->allowed_filesize = Context::get('allowed_filesize'); - $config->allowed_attach_size = Context::get('allowed_attach_size'); - $config->allowed_filetypes = Context::get('allowed_filetypes'); - $config->allow_outlink = Context::get('allow_outlink'); - $config->allow_outlink_format = Context::get('allow_outlink_format'); - $config->allow_outlink_site = Context::get('allow_outlink_site'); - - // module Controller 객체 생성하여 입력 - $oModuleController = &getController('module'); - $output = $oModuleController->insertModuleConfig('file',$config); - return $output; - } - - /** - * @brief 모듈별 파일 기본 정보의 추가 - **/ - function procFileAdminInsertModuleConfig() { - // 필요한 변수를 받아옴 - $module_srl = Context::get('target_module_srl'); - - // 여러개의 모듈 일괄 설정일 경우 - if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); - else $module_srl = array($module_srl); - - $download_grant = trim(Context::get('download_grant')); - - $file_config->allow_outlink = Context::get('allow_outlink'); - $file_config->allow_outlink_format = Context::get('allow_outlink_format'); - $file_config->allow_outlink_site = Context::get('allow_outlink_site'); - $file_config->allowed_filesize = Context::get('allowed_filesize'); - $file_config->allowed_attach_size = Context::get('allowed_attach_size'); - $file_config->allowed_filetypes = Context::get('allowed_filetypes'); - if($download_grant) $file_config->download_grant = explode('|@|',$download_grant); - else $file_config->download_grant = array(); - - $oModuleController = &getController('module'); - for($i=0;$iinsertModulePartConfig('file',$srl,$file_config); - } - - $this->setError(-1); - $this->setMessage('success_updated'); - } - } -?> +module_srl = $module_srl; + $output = executeQueryArray('file.getModuleFiles',$args); + if(!$output) return $output; + $files = $output->data; + + // DB에서 삭제 + $args->module_srl = $module_srl; + $output = executeQuery('file.deleteModuleFiles', $args); + if(!$output->toBool()) return $output; + + // 실제 파일 삭제 (일단 약속에 따라서 한번에 삭제) + FileHandler::removeDir( sprintf("./files/attach/images/%s/", $module_srl) ) ; + FileHandler::removeDir( sprintf("./files/attach/binaries/%s/", $module_srl) ); + + // DB에서 구한 파일 목록을 삭제 + $path = array(); + $cnt = count($files); + for($i=0;$i<$cnt;$i++) { + $uploaded_filename = $files[$i]->uploaded_filename; + FileHandler::removeFile($uploaded_filename); + + $path_info = pathinfo($uploaded_filename); + if(!in_array($path_info['dirname'], $path)) $path[] = $path_info['dirname']; + } + + // 해당 글의 첨부파일 디렉토리 삭제 + for($i=0;$istop('msg_cart_is_null'); + $file_srl_list= explode('|@|', $cart); + $file_count = count($file_srl_list); + if(!$file_count) return $this->stop('msg_cart_is_null'); + + $oFileController = &getController('file'); + + // 글삭제 + for($i=0;$i<$file_count;$i++) { + $file_srl = trim($file_srl_list[$i]); + if(!$file_srl) continue; + + $oFileController->deleteFile($file_srl); + } + + $this->setMessage( sprintf(Context::getLang('msg_checked_file_is_deleted'), $file_count) ); + } + + /** + * @brief 파일 기본 정보의 추가 + **/ + function procFileAdminInsertConfig() { + // 설정 정보를 받아옴 (module model 객체를 이용) + $config->allowed_filesize = Context::get('allowed_filesize'); + $config->allowed_attach_size = Context::get('allowed_attach_size'); + $config->allowed_filetypes = Context::get('allowed_filetypes'); + $config->allow_outlink = Context::get('allow_outlink'); + $config->allow_outlink_format = Context::get('allow_outlink_format'); + $config->allow_outlink_site = Context::get('allow_outlink_site'); + + // module Controller 객체 생성하여 입력 + $oModuleController = &getController('module'); + $output = $oModuleController->insertModuleConfig('file',$config); + return $output; + } + + /** + * @brief 모듈별 파일 기본 정보의 추가 + **/ + function procFileAdminInsertModuleConfig() { + // 필요한 변수를 받아옴 + $module_srl = Context::get('target_module_srl'); + + // 여러개의 모듈 일괄 설정일 경우 + if(preg_match('/^([0-9,]+)$/',$module_srl)) $module_srl = explode(',',$module_srl); + else $module_srl = array($module_srl); + + $download_grant = trim(Context::get('download_grant')); + + $file_config->allow_outlink = Context::get('allow_outlink'); + $file_config->allow_outlink_format = Context::get('allow_outlink_format'); + $file_config->allow_outlink_site = Context::get('allow_outlink_site'); + $file_config->allowed_filesize = Context::get('allowed_filesize'); + $file_config->allowed_attach_size = Context::get('allowed_attach_size'); + $file_config->allowed_filetypes = Context::get('allowed_filetypes'); + if($download_grant) $file_config->download_grant = explode('|@|',$download_grant); + else $file_config->download_grant = array(); + + $oModuleController = &getController('module'); + for($i=0;$iinsertModulePartConfig('file',$srl,$file_config); + } + + $this->setError(-1); + $this->setMessage('success_updated'); + } + } +?> diff --git a/modules/file/file.admin.model.php b/modules/file/file.admin.model.php index e054df2bf..641d618e4 100644 --- a/modules/file/file.admin.model.php +++ b/modules/file/file.admin.model.php @@ -1,96 +1,96 @@ -search_target?$obj->search_target:trim(Context::get('search_target')); - $search_keyword = $obj->search_keyword?$obj->search_keyword:trim(Context::get('search_keyword')); - - if($search_target && $search_keyword) { - switch($search_target) { - case 'filename' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_filename = $search_keyword; - break; - case 'filesize_more' : - $args->s_filesize_more = (int)$search_keyword; - break; - case 'filesize_mega_more' : - $args->s_filesize_more = (int)$search_keyword * 1024 * 1024; - break; - case 'filesize_less' : - $args->s_filesize_less = (int)$search_keyword; - break; - case 'filesize_mega_less' : - $args->s_filesize_less = (int)$search_keyword * 1024 * 1024; - break; - case 'download_count' : - $args->s_download_count = (int)$search_keyword; - break; - case 'regdate' : - $args->s_regdate = $search_keyword; - break; - case 'ipaddress' : - $args->s_ipaddress = $search_keyword; - break; - case 'user_id' : - $args->s_user_id = $search_keyword; - break; - case 'user_name' : - $args->s_user_name = $search_keyword; - break; - case 'nick_name' : - $args->s_nick_name = $search_keyword; - break; - } - } - - // 유효/대기 상태 설정 - if($obj->isvalid == 'Y') $args->isvalid = 'Y'; - elseif($obj->isvalid == 'N') $args->isvalid = 'N'; - - // 멀티미디어/ 일반 상태 설정 - if($obj->direct_download == 'Y') $args->direct_download = 'Y'; - elseif($obj->direct_download == 'N') $args->direct_download= 'N'; - - // 변수 설정 - $args->sort_index = $obj->sort_index; - $args->page = $obj->page?$obj->page:1; - $args->list_count = $obj->list_count?$obj->list_count:20; - $args->page_count = $obj->page_count?$obj->page_count:10; - $args->s_module_srl = $obj->module_srl; - $args->exclude_module_srl = $obj->exclude_module_srl; - - // file.getFileList쿼리 실행 - $output = executeQuery('file.getFileList', $args); - - // 결과가 없거나 오류 발생시 그냥 return - if(!$output->toBool()||!count($output->data)) return $output; - - $oFileModel = &getModel('file'); - - foreach($output->data as $key => $file) { - $file->download_url = $oFileModel->getDownloadUrl($file->file_srl, $file->sid); - $output->data[$key] = $file; - } - - return $output; - } - - } -?> +search_target?$obj->search_target:trim(Context::get('search_target')); + $search_keyword = $obj->search_keyword?$obj->search_keyword:trim(Context::get('search_keyword')); + + if($search_target && $search_keyword) { + switch($search_target) { + case 'filename' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_filename = $search_keyword; + break; + case 'filesize_more' : + $args->s_filesize_more = (int)$search_keyword; + break; + case 'filesize_mega_more' : + $args->s_filesize_more = (int)$search_keyword * 1024 * 1024; + break; + case 'filesize_less' : + $args->s_filesize_less = (int)$search_keyword; + break; + case 'filesize_mega_less' : + $args->s_filesize_less = (int)$search_keyword * 1024 * 1024; + break; + case 'download_count' : + $args->s_download_count = (int)$search_keyword; + break; + case 'regdate' : + $args->s_regdate = $search_keyword; + break; + case 'ipaddress' : + $args->s_ipaddress = $search_keyword; + break; + case 'user_id' : + $args->s_user_id = $search_keyword; + break; + case 'user_name' : + $args->s_user_name = $search_keyword; + break; + case 'nick_name' : + $args->s_nick_name = $search_keyword; + break; + } + } + + // 유효/대기 상태 설정 + if($obj->isvalid == 'Y') $args->isvalid = 'Y'; + elseif($obj->isvalid == 'N') $args->isvalid = 'N'; + + // 멀티미디어/ 일반 상태 설정 + if($obj->direct_download == 'Y') $args->direct_download = 'Y'; + elseif($obj->direct_download == 'N') $args->direct_download= 'N'; + + // 변수 설정 + $args->sort_index = $obj->sort_index; + $args->page = $obj->page?$obj->page:1; + $args->list_count = $obj->list_count?$obj->list_count:20; + $args->page_count = $obj->page_count?$obj->page_count:10; + $args->s_module_srl = $obj->module_srl; + $args->exclude_module_srl = $obj->exclude_module_srl; + + // file.getFileList쿼리 실행 + $output = executeQuery('file.getFileList', $args); + + // 결과가 없거나 오류 발생시 그냥 return + if(!$output->toBool()||!count($output->data)) return $output; + + $oFileModel = &getModel('file'); + + foreach($output->data as $key => $file) { + $file->download_url = $oFileModel->getDownloadUrl($file->file_srl, $file->sid); + $output->data[$key] = $file; + } + + return $output; + } + + } +?> diff --git a/modules/file/file.admin.view.php b/modules/file/file.admin.view.php index adc62fa21..9a819fc20 100644 --- a/modules/file/file.admin.view.php +++ b/modules/file/file.admin.view.php @@ -1,187 +1,187 @@ -page = Context::get('page'); ///< 페이지 - $args->list_count = 30; ///< 한페이지에 보여줄 글 수 - $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 - - $args->sort_index = 'file_srl'; ///< 소팅 값 - $args->isvalid = Context::get('isvalid'); - $args->module_srl = Context::get('module_srl'); - - // 목록 구함 - $oFileModel = &getAdminModel('file'); - $output = $oFileModel->getFileList($args); - - // 목록의 loop를 돌면서 document를 구하기 - if($output->data) { - $oCommentModel = &getModel('comment'); - $oDocumentModel = &getModel('document'); - $oModuleModel = &getModel('module'); - - $file_list = array(); - $document_list = array(); - $comment_list = array(); - $module_list= array(); - - $doc_srls = array(); - $com_srls = array(); - $mod_srls= array(); - - foreach($output->data as $file) { - $file_srl = $file->file_srl; - $target_srl = $file->upload_target_srl; - $file_update_args = null; - $file_update_args->file_srl = $file_srl; - - // upload_target_type이 없으면 찾아서 업데이트 - if(!$file->upload_target_type) { - // 찾아둔게 있으면 패스 - if($document_list[$target_srl]) { - $file->upload_target_type = 'doc'; - } else if($comment_list[$target_srl]) { - $file->upload_target_type = 'com'; - } else if($module_list[$target_srl]) { - $file->upload_target_type = 'mod'; - } else { - // document - $document = $oDocumentModel->getDocument($target_srl); - if($document->isExists()) { - $file->upload_target_type = 'doc'; - $file_update_args->upload_target_type = $file->upload_target_type; - $document_list[$target_srl] = $document; - } - // comment - if(!$file->upload_target_type) { - $comment = $oCommentModel->getComment($target_srl); - if($comment->isExists()) { - $file->upload_target_type = 'com'; - $file->target_document_srl = $comment->document_srl; - $file_update_args->upload_target_type = $file->upload_target_type; - $comment_list[$target_srl] = $comment; - $doc_srls[] = $comment->document_srl; - } - } - // module (페이지인 경우) - if(!$file->upload_target_type) { - $module = $oModuleModel->getModulesInfo($target_srl); - if($module) { - $file->upload_target_type = 'mod'; - $file_update_args->upload_target_type = $file->upload_target_type; - $module_list[$module->comment_srl] = $module; - } - } - if($file_update_args->upload_target_type) { - executeQuery('file.updateFileTargetType', $file_update_args); - } - } - - // 이미 구해진 데이터가 있는 확인 - for($i = 0; $i < $com_srls_count; ++$i) { - if($comment_list[$com_srls[$i]]) delete($com_srls[$i]); - } - for($i = 0; $i < $doc_srls_count; ++$i) { - if($document_list[$doc_srls[$i]]) delete($doc_srls[$i]); - } - for($i = 0; $i < $mod_srls_count; ++$i) { - if($module_list[$mod_srls[$i]]) delete($mod_srls[$i]); - } - } - - if($file->upload_target_type) { - if(!in_array($file->upload_target_srl, ${$file->upload_target_type.'_srls'})) { - ${$file->upload_target_type.'_srls'}[] = $target_srl; - } - } - - $file_list[$file_srl] = $file; - $mod_srls[] = $file->module_srl; - } - - // 중복 제거 - $doc_srls = array_unique($doc_srls); - $com_srls = array_unique($com_srls); - $mod_srls = array_unique($mod_srls); - - // 댓글 목록 - $com_srls_count = count($com_srls); - if($com_srls_count) { - $comment_output = $oCommentModel->getComments($com_srls); - foreach($comment_output as $comment) { - $comment_list[$comment->comment_srl] = $comment; - $doc_srls[] = $comment->document_srl; - } - } - - // 문서 목록 - $doc_srls_count = count($doc_srls); - if($doc_srls_count) { - $document_output = $oDocumentModel->getDocuments($doc_srls); - foreach($document_output as $document) { - $document_list[$document->document_srl] = $document; - } - } - - // 모듈 목록 - $mod_srls_count = count($mod_srls); - if($mod_srls_count) { - $module_output = $oModuleModel->getModulesInfo($mod_srls); - if($module_output && is_array($module_output)){ - foreach($module_output as $module) { - $module_list[$module->module_srl] = $module; - } - } - } - - foreach($file_list as $srl => $file) { - if($file->upload_target_type == 'com') { - $file_list[$srl]->target_document_srl = $comment_list[$file->upload_target_srl]->document_srl; - } - } - } - Context::set('file_list', $file_list); - Context::set('document_list', $document_list); - Context::set('comment_list', $comment_list); - Context::set('module_list', $module_list); - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('page_navigation', $output->page_navigation); - - // 템플릿 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('file_list'); - } - - /** - * @brief 첨부파일 정보 설정 (관리자용) - **/ - function dispFileAdminConfig() { - $oFileModel = &getModel('file'); - $config = $oFileModel->getFileConfig(); - Context::set('config',$config); - - // 템플릿 파일 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('file_config'); - } - - } -?> +page = Context::get('page'); ///< 페이지 + $args->list_count = 30; ///< 한페이지에 보여줄 글 수 + $args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수 + + $args->sort_index = 'file_srl'; ///< 소팅 값 + $args->isvalid = Context::get('isvalid'); + $args->module_srl = Context::get('module_srl'); + + // 목록 구함 + $oFileModel = &getAdminModel('file'); + $output = $oFileModel->getFileList($args); + + // 목록의 loop를 돌면서 document를 구하기 + if($output->data) { + $oCommentModel = &getModel('comment'); + $oDocumentModel = &getModel('document'); + $oModuleModel = &getModel('module'); + + $file_list = array(); + $document_list = array(); + $comment_list = array(); + $module_list= array(); + + $doc_srls = array(); + $com_srls = array(); + $mod_srls= array(); + + foreach($output->data as $file) { + $file_srl = $file->file_srl; + $target_srl = $file->upload_target_srl; + $file_update_args = null; + $file_update_args->file_srl = $file_srl; + + // upload_target_type이 없으면 찾아서 업데이트 + if(!$file->upload_target_type) { + // 찾아둔게 있으면 패스 + if($document_list[$target_srl]) { + $file->upload_target_type = 'doc'; + } else if($comment_list[$target_srl]) { + $file->upload_target_type = 'com'; + } else if($module_list[$target_srl]) { + $file->upload_target_type = 'mod'; + } else { + // document + $document = $oDocumentModel->getDocument($target_srl); + if($document->isExists()) { + $file->upload_target_type = 'doc'; + $file_update_args->upload_target_type = $file->upload_target_type; + $document_list[$target_srl] = $document; + } + // comment + if(!$file->upload_target_type) { + $comment = $oCommentModel->getComment($target_srl); + if($comment->isExists()) { + $file->upload_target_type = 'com'; + $file->target_document_srl = $comment->document_srl; + $file_update_args->upload_target_type = $file->upload_target_type; + $comment_list[$target_srl] = $comment; + $doc_srls[] = $comment->document_srl; + } + } + // module (페이지인 경우) + if(!$file->upload_target_type) { + $module = $oModuleModel->getModulesInfo($target_srl); + if($module) { + $file->upload_target_type = 'mod'; + $file_update_args->upload_target_type = $file->upload_target_type; + $module_list[$module->comment_srl] = $module; + } + } + if($file_update_args->upload_target_type) { + executeQuery('file.updateFileTargetType', $file_update_args); + } + } + + // 이미 구해진 데이터가 있는 확인 + for($i = 0; $i < $com_srls_count; ++$i) { + if($comment_list[$com_srls[$i]]) delete($com_srls[$i]); + } + for($i = 0; $i < $doc_srls_count; ++$i) { + if($document_list[$doc_srls[$i]]) delete($doc_srls[$i]); + } + for($i = 0; $i < $mod_srls_count; ++$i) { + if($module_list[$mod_srls[$i]]) delete($mod_srls[$i]); + } + } + + if($file->upload_target_type) { + if(!in_array($file->upload_target_srl, ${$file->upload_target_type.'_srls'})) { + ${$file->upload_target_type.'_srls'}[] = $target_srl; + } + } + + $file_list[$file_srl] = $file; + $mod_srls[] = $file->module_srl; + } + + // 중복 제거 + $doc_srls = array_unique($doc_srls); + $com_srls = array_unique($com_srls); + $mod_srls = array_unique($mod_srls); + + // 댓글 목록 + $com_srls_count = count($com_srls); + if($com_srls_count) { + $comment_output = $oCommentModel->getComments($com_srls); + foreach($comment_output as $comment) { + $comment_list[$comment->comment_srl] = $comment; + $doc_srls[] = $comment->document_srl; + } + } + + // 문서 목록 + $doc_srls_count = count($doc_srls); + if($doc_srls_count) { + $document_output = $oDocumentModel->getDocuments($doc_srls); + foreach($document_output as $document) { + $document_list[$document->document_srl] = $document; + } + } + + // 모듈 목록 + $mod_srls_count = count($mod_srls); + if($mod_srls_count) { + $module_output = $oModuleModel->getModulesInfo($mod_srls); + if($module_output && is_array($module_output)){ + foreach($module_output as $module) { + $module_list[$module->module_srl] = $module; + } + } + } + + foreach($file_list as $srl => $file) { + if($file->upload_target_type == 'com') { + $file_list[$srl]->target_document_srl = $comment_list[$file->upload_target_srl]->document_srl; + } + } + } + Context::set('file_list', $file_list); + Context::set('document_list', $document_list); + Context::set('comment_list', $comment_list); + Context::set('module_list', $module_list); + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('page_navigation', $output->page_navigation); + + // 템플릿 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('file_list'); + } + + /** + * @brief 첨부파일 정보 설정 (관리자용) + **/ + function dispFileAdminConfig() { + $oFileModel = &getModel('file'); + $config = $oFileModel->getFileConfig(); + Context::set('config',$config); + + // 템플릿 파일 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('file_config'); + } + + } +?> diff --git a/modules/file/file.class.php b/modules/file/file.class.php index 575f08a21..2846f38f0 100644 --- a/modules/file/file.class.php +++ b/modules/file/file.class.php @@ -1,149 +1,149 @@ -allowed_filesize = '2'; - $config->allowed_attach_size = '2'; - $config->allowed_filetypes = '*.*'; - $oModuleController->insertModuleConfig('file', $config); - - // file 모듈에서 사용할 디렉토리 생성 - FileHandler::makeDir('./files/attach/images'); - FileHandler::makeDir('./files/attach/binaries'); - - // 2007. 10. 17 글/댓글의 입력/수정/삭제에 대한 trigger 등록 - $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); - $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); - $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); - $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); - $oModuleController->insertTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after'); - $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); - $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); - $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); - $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); - $oModuleController->insertTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after'); - - // 2009. 6. 9 자동저장문서 삭제시 첨부 파일도 같이 삭제 - $oModuleController->insertTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after'); - - // 2007. 10. 17 모듈이 삭제될때 등록된 첨부파일도 모두 삭제하는 트리거 추가 - $oModuleController->insertTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after'); - - // 2007. 10. 19 출력하기 전에 file 권한등을 세팅하는 트리거 호출 - $oModuleController->insertTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before'); - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - - // 2007. 10. 17 글/댓글의 입력/수정/삭제에 대한 trigger 등록 - if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) return true; - if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) return true; - if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) return true; - if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) return true; - if(!$oModuleModel->getTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after')) return true; - if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) return true; - if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) return true; - if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) return true; - if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) return true; - if(!$oModuleModel->getTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after')) return true; - - // 2009. 6. 9 자동저장문서 삭제시 첨부 파일도 같이 삭제 - if(!$oModuleModel->getTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after')) return true; - - // 2007. 10. 17 모듈이 삭제될때 등록된 첨부파일도 모두 삭제하는 트리거 추가 - if(!$oModuleModel->getTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after')) return true; - - // 2007. 10. 19 출력하기 전에 file 권한등을 세팅하는 트리거 호출 - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before')) return true; - - // 타겟 판별용 필드 - if(!$oDB->isColumnExists('files', 'upload_target_type')) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - - // 2007. 10. 17 글/댓글의 입력/수정/삭제에 대한 trigger 등록 - if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) - $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); - - if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) - $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); - - if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) - $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); - - if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) - $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); - - if(!$oModuleModel->getTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after')) - $oModuleController->insertTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after'); - - if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) - $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); - - if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) - $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); - - if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) - $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); - - if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) - $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); - - if(!$oModuleModel->getTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after')) - $oModuleController->insertTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after'); - - // 2009. 6. 9 자동저장문서 삭제시 첨부 파일도 같이 삭제 - if(!$oModuleModel->getTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after')) - $oModuleController->insertTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after'); - - // 2007. 10. 17 모듈이 삭제될때 등록된 첨부파일도 모두 삭제하는 트리거 추가 - if(!$oModuleModel->getTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after')) - $oModuleController->insertTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after'); - - // 2007. 10. 19 출력하기 전에 file 권한등을 세팅하는 트리거 호출 - if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before')) - $oModuleController->insertTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before'); - - // 타겟 판별용 필드 - if(!$oDB->isColumnExists('files', 'upload_target_type')) $oDB->addColumn('files', 'upload_target_type', 'char', '3'); - - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - } - - } -?> +allowed_filesize = '2'; + $config->allowed_attach_size = '2'; + $config->allowed_filetypes = '*.*'; + $oModuleController->insertModuleConfig('file', $config); + + // file 모듈에서 사용할 디렉토리 생성 + FileHandler::makeDir('./files/attach/images'); + FileHandler::makeDir('./files/attach/binaries'); + + // 2007. 10. 17 글/댓글의 입력/수정/삭제에 대한 trigger 등록 + $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); + $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); + $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); + $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); + $oModuleController->insertTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after'); + $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); + $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); + $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); + $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); + $oModuleController->insertTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after'); + + // 2009. 6. 9 자동저장문서 삭제시 첨부 파일도 같이 삭제 + $oModuleController->insertTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after'); + + // 2007. 10. 17 모듈이 삭제될때 등록된 첨부파일도 모두 삭제하는 트리거 추가 + $oModuleController->insertTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after'); + + // 2007. 10. 19 출력하기 전에 file 권한등을 세팅하는 트리거 호출 + $oModuleController->insertTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before'); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + + // 2007. 10. 17 글/댓글의 입력/수정/삭제에 대한 trigger 등록 + if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) return true; + if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) return true; + if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) return true; + if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) return true; + if(!$oModuleModel->getTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after')) return true; + if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) return true; + if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) return true; + if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) return true; + if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) return true; + if(!$oModuleModel->getTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after')) return true; + + // 2009. 6. 9 자동저장문서 삭제시 첨부 파일도 같이 삭제 + if(!$oModuleModel->getTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after')) return true; + + // 2007. 10. 17 모듈이 삭제될때 등록된 첨부파일도 모두 삭제하는 트리거 추가 + if(!$oModuleModel->getTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after')) return true; + + // 2007. 10. 19 출력하기 전에 file 권한등을 세팅하는 트리거 호출 + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before')) return true; + + // 타겟 판별용 필드 + if(!$oDB->isColumnExists('files', 'upload_target_type')) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + + // 2007. 10. 17 글/댓글의 입력/수정/삭제에 대한 trigger 등록 + if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) + $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); + + if(!$oModuleModel->getTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) + $oModuleController->insertTrigger('document.insertDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); + + if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before')) + $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerCheckAttached', 'before'); + + if(!$oModuleModel->getTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after')) + $oModuleController->insertTrigger('document.updateDocument', 'file', 'controller', 'triggerAttachFiles', 'after'); + + if(!$oModuleModel->getTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after')) + $oModuleController->insertTrigger('document.deleteDocument', 'file', 'controller', 'triggerDeleteAttached', 'after'); + + if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) + $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); + + if(!$oModuleModel->getTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) + $oModuleController->insertTrigger('comment.insertComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); + + if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before')) + $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentCheckAttached', 'before'); + + if(!$oModuleModel->getTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after')) + $oModuleController->insertTrigger('comment.updateComment', 'file', 'controller', 'triggerCommentAttachFiles', 'after'); + + if(!$oModuleModel->getTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after')) + $oModuleController->insertTrigger('comment.deleteComment', 'file', 'controller', 'triggerCommentDeleteAttached', 'after'); + + // 2009. 6. 9 자동저장문서 삭제시 첨부 파일도 같이 삭제 + if(!$oModuleModel->getTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after')) + $oModuleController->insertTrigger('editor.deleteSavedDoc', 'file', 'controller', 'triggerDeleteAttached', 'after'); + + // 2007. 10. 17 모듈이 삭제될때 등록된 첨부파일도 모두 삭제하는 트리거 추가 + if(!$oModuleModel->getTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after')) + $oModuleController->insertTrigger('module.deleteModule', 'file', 'controller', 'triggerDeleteModuleFiles', 'after'); + + // 2007. 10. 19 출력하기 전에 file 권한등을 세팅하는 트리거 호출 + if(!$oModuleModel->getTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before')) + $oModuleController->insertTrigger('module.dispAdditionSetup', 'file', 'view', 'triggerDispFileAdditionSetup', 'before'); + + // 타겟 판별용 필드 + if(!$oDB->isColumnExists('files', 'upload_target_type')) $oDB->addColumn('files', 'upload_target_type', 'char', '3'); + + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + } + + } +?> diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 7745f3801..2d17fd1f1 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -1,603 +1,603 @@ -module_srl; - - // 업로드 권한이 없거나 정보가 없을시 종료 - if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); - - // upload_target_srl 값이 명시되지 않았을 경우 세션정보에서 추출 - if(!$upload_target_srl) $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; - - // 세션정보에도 정의되지 않았다면 새로 생성 - if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence(); - - $file_info = Context::get('Filedata'); - - // 정상적으로 업로드된 파일이 아니면 오류 출력 - if(!is_uploaded_file($file_info['tmp_name'])) exit(); - - return $this->insertFile($file_info, $module_srl, $upload_target_srl); - } - - - /** - * @brief iframe 첨부파일 업로드 - **/ - function procFileIframeUpload() { - // 기본적으로 필요한 변수 설정 - $editor_sequence = Context::get('editor_sequence'); - $callback = Context::get('callback'); - $module_srl = $this->module_srl; - $upload_target_srl = intval(Context::get('uploadTargetSrl')); - - // 업로드 권한이 없거나 정보가 없을시 종료 - if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); - - // upload_target_srl 값이 명시되지 않았을 경우 세션정보에서 추출 - if(!$upload_target_srl) $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; - - // 세션정보에도 정의되지 않았다면 새로 생성 - if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence(); - - // file_srl이 요청되었을 경우 삭제 후 재업로드 시도 - $file_srl = Context::get('file_srl'); - if($file_srl) $this->deleteFile($file_srl); - - $file_info = Context::get('Filedata'); - - // 정상적으로 업로드된 파일이 아니면 오류 출력 - if(is_uploaded_file($file_info['tmp_name'])) { - $output = $this->insertFile($file_info, $module_srl, $upload_target_srl); - Context::set('uploaded_fileinfo',$output); - } - - Context::set('layout','none'); - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('iframe'); - - } - - /** - * @brief image resize - **/ - function procFileImageResize() { - $source_src = Context::get('source_src'); - $width = Context::get('width'); - $height = Context::get('height'); - $type = Context::get('type'); - $output_src = Context::get('output_src'); - - if(!$source_src || !$width) return new Object(-1,'msg_invalid_request'); - if(!$output_src){ - $output_src = $source_src . '.resized' . strrchr($source_src,'.'); - } - if(!$type) $type = 'ratio'; - if(!$height) $height = $width-1; - - if(FileHandler::createImageFile($source_src,$output_src,$width,$height,'','ratio')){ - $output->info = getimagesize($output_src); - $output->src = $output_src; - }else{ - return new Object(-1,'msg_invalid_request'); - } - - $this->add('resized_info',$output); - } - - - - /** - * @brief 첨부파일 다운로드 - * 직접 요청을 받음 - * file_srl : 파일의 sequence - * sid : db에 저장된 비교 값, 틀리면 다운로드 하지 않음 - **/ - function procFileDownload() { - $oFileModel = &getModel('file'); - - $file_srl = Context::get('file_srl'); - $sid = Context::get('sid'); - $logged_info = Context::get('logged_info'); - - // 파일의 정보를 DB에서 받아옴 - $file_obj = $oFileModel->getFile($file_srl); - - // 요청된 파일 정보가 잘못되었다면 파일을 찾을 수 없다는 오류 출력 - if($file_obj->file_srl!=$file_srl || $file_obj->sid!=$sid) return $this->stop('msg_file_not_found'); - - // 대기 상태일 경우 파일 다운로드 권한이 없음을 알림 (최고관리자는 다운 로드 허용) - if($logged_info->is_admin != 'Y' && $file_obj->isvalid!='Y') return $this->stop('msg_not_permitted_download'); - - // 파일 이름 - $filename = $file_obj->source_filename; - $file_module_config = $oFileModel->getFileModuleConfig($file_obj->module_srl); - - // 파일 외부링크 차단 - if($file_module_config->allow_outlink == 'N') { - //외부링크 허용 확장자 처리 - if($file_module_config->allow_outlink_format) { - $allow_outlink_format_array = array(); - $allow_outlink_format_array = explode(',', $file_module_config->allow_outlink_format); - if(!is_array($allow_outlink_format_array)) $allow_outlink_format_array[0] = $file_module_config->allow_outlink_format; - - foreach($allow_outlink_format_array as $val) { - $val = trim($val); - if(preg_match("/\.{$val}$/i", $filename)) { - $file_module_config->allow_outlink = 'Y'; - break; - } - } - } - //외부링크 허용 사이트 처리 - if($file_module_config->allow_outlink != 'Y') { - $referer = parse_url($_SERVER["HTTP_REFERER"]); - if($referer['host'] != $_SERVER['HTTP_HOST']) { - if($file_module_config->allow_outlink_site) { - $allow_outlink_site_array = array(); - $allow_outlink_site_array = explode("\n", $file_module_config->allow_outlink_site); - if(!is_array($allow_outlink_site_array)) $allow_outlink_site_array[0] = $file_module_config->allow_outlink_site; - - foreach($allow_outlink_site_array as $val) { - $site = parse_url(trim($val)); - if($site['host'] == $referer['host']) { - $file_module_config->allow_outlink = 'Y'; - break; - } - } - } - } - else $file_module_config->allow_outlink = 'Y'; - } - if($file_module_config->allow_outlink != 'Y') return $this->stop('msg_not_allowed_outlink'); - } - - // 파일 다운로드 권한이 있는지 확인 - if(is_array($file_module_config->download_grant) && count($file_module_config->download_grant)>0) { - if(!Context::get('is_logged')) return $this->stop('msg_not_permitted_download'); - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y') { - - $oModuleModel =& getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($file_obj->module_srl); - - if(!$oModuleModel->isSiteAdmin($logged_info, $module_info->site_srl)) - { - $oMemberModel =& getModel('member'); - $member_groups = $oMemberModel->getMemberGroups($logged_info->member_srl, $module_info->site_srl); - - $is_permitted = false; - for($i=0;$idownload_grant);$i++) { - $group_srl = $file_module_config->download_grant[$i]; - if($member_groups[$group_srl]) { - $is_permitted = true; - break; - } - } - if(!$is_permitted) return $this->stop('msg_not_permitted_download'); - } - } - } - - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('file.downloadFile', 'before', $file_obj); - if(!$output->toBool()) return $this->stop(($output->message)?$output->message:'msg_not_permitted_download'); - - // 파일 출력 - if(strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { - $filename = rawurlencode($filename); - $filename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1); - } - - $uploaded_filename = $file_obj->uploaded_filename; - if(!file_exists($uploaded_filename)) return $this->stop('msg_file_not_found'); - - $fp = fopen($uploaded_filename, 'rb'); - if(!$fp) return $this->stop('msg_file_not_found'); - - header("Cache-Control: "); - header("Pragma: "); - header("Content-Type: application/octet-stream"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); - - header("Content-Length: " .(string)($file_obj->file_size)); - header('Content-Disposition: attachment; filename="'.$filename.'"'); - header("Content-Transfer-Encoding: binary\n"); - - fpassthru($fp); - - // 이상이 없으면 download_count 증가 - $args->file_srl = $file_srl; - executeQuery('file.updateFileDownloadCount', $args); - - // trigger 호출 (after) - $output = ModuleHandler::triggerCall('file.downloadFile', 'after', $file_obj); - - Context::close(); - - exit(); - } - - /** - * @brief 에디터에서 첨부 파일 삭제 - **/ - function procFileDelete() { - // 기본적으로 필요한 변수인 upload_target_srl, module_srl을 설정 - $editor_sequence = Context::get('editor_sequence'); - $file_srl = Context::get('file_srl'); - $file_srls = Context::get('file_srls'); - if($file_srls) $file_srl = $file_srls; - - // 업로드 권한이 없거나 정보가 없을시 종료 - if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); - - $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; - if($upload_target_srl && $file_srl) $output = $this->deleteFile($file_srl); - } - - /** - * @brief 특정 upload_target_srl(document_srl)에 등록된 첨부파일의 갯수를 return하는 trigger - **/ - function triggerCheckAttached(&$obj) { - $document_srl = $obj->document_srl; - if(!$document_srl) return new Object(); - - // 첨부 파일의 갯수를 구함 - $oFileModel = &getModel('file'); - $obj->uploaded_count = $oFileModel->getFilesCount($document_srl); - - return new Object(); - } - - /** - * @brief 특정 upload_target_srl(document_srl)에 등록된 첨부파일을 연결하는 trigger - **/ - function triggerAttachFiles(&$obj) { - $document_srl = $obj->document_srl; - if(!$document_srl) return new Object(); - - $output = $this->setFilesValid($document_srl); - if(!$output->toBool()) return $output; - - return new Object(); - } - - /** - * @brief 특정 upload_target_srl(document_srl)에 등록된 첨부파일을 삭제하는 trigger - **/ - function triggerDeleteAttached(&$obj) { - $document_srl = $obj->document_srl; - if(!$document_srl) return new Object(); - - $output = $this->deleteFiles($document_srl); - return $output; - } - - /** - * @brief 특정 upload_target_srl(comment_srl)에 등록된 첨부파일의 갯수를 return하는 trigger - **/ - function triggerCommentCheckAttached(&$obj) { - $comment_srl = $obj->comment_srl; - if(!$comment_srl) return new Object(); - - // 첨부 파일의 갯수를 구함 - $oFileModel = &getModel('file'); - $obj->uploaded_count = $oFileModel->getFilesCount($comment_srl); - - return new Object(); - } - - /** - * @brief 특정 upload_target_srl(comment_srl)에 등록된 첨부파일을 연결하는 trigger - **/ - function triggerCommentAttachFiles(&$obj) { - $comment_srl = $obj->comment_srl; - $uploaded_count = $obj->uploaded_count; - if(!$comment_srl || !$uploaded_count) return new Object(); - - $output = $this->setFilesValid($comment_srl); - if(!$output->toBool()) return $output; - - return new Object(); - } - - /** - * @brief 특정 upload_target_srl(comment_srl)에 등록된 첨부파일을 삭제하는 trigger - **/ - function triggerCommentDeleteAttached(&$obj) { - $comment_srl = $obj->comment_srl; - if(!$comment_srl) return new Object(); - - $output = $this->deleteFiles($comment_srl); - return $output; - } - - /** - * @brief module 삭제시 해당 첨부파일 모두 삭제하는 trigger - **/ - function triggerDeleteModuleFiles(&$obj) { - $module_srl = $obj->module_srl; - if(!$module_srl) return new Object(); - - $oFileController = &getAdminController('file'); - return $oFileController->deleteModuleFiles($module_srl); - } - - /** - * @brief 업로드 가능하다고 세팅 - **/ - function setUploadInfo($editor_sequence, $upload_target_srl=0) { - $_SESSION['upload_info'][$editor_sequence]->enabled = true; - $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl; - } - - /** - * @brief 특정 upload_target_srl의 첨부파일들의 상태를 유효로 변경 - * 글이 등록될때 글에 첨부된 파일들의 상태를 유효상태로 변경함으로서 관리시 불필요 파일로 인식되지 않도록 함 - **/ - function setFilesValid($upload_target_srl) { - $args->upload_target_srl = $upload_target_srl; - return executeQuery('file.updateFileValid', $args); - } - - /** - * @brief 첨부파일 추가 - **/ - function insertFile($file_info, $module_srl, $upload_target_srl, $download_count = 0, $manual_insert = false) { - // trigger 호출 (before) - $trigger_obj->module_srl = $module_srl; - $trigger_obj->upload_target_srl = $upload_target_srl; - $output = ModuleHandler::triggerCall('file.insertFile', 'before', $trigger_obj); - if(!$output->toBool()) return $output; - - if(!$manual_insert) { - // 첨부파일 설정 가져옴 - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y') { - $oFileModel = &getModel('file'); - $config = $oFileModel->getFileConfig($module_srl); - $allowed_filesize = $config->allowed_filesize * 1024 * 1024; - $allowed_attach_size = $config->allowed_attach_size * 1024 * 1024; - - // 한 파일당 허용 용량 초과시 오류 출력 - if($allowed_filesize < filesize($file_info['tmp_name'])) return new Object(-1, 'msg_exceeds_limit_size'); - - - // 해당 문서에 첨부된 모든 파일의 용량을 가져옴 (DB에서 가져옴) - $size_args->upload_target_srl = $upload_target_srl; - $output = executeQuery('file.getAttachedFileSize', $size_args); - $attached_size = (int)$output->data->attached_size + filesize($file_info['tmp_name']); - if($attached_size > $allowed_attach_size) return new Object(-1, 'msg_exceeds_limit_size'); - } - } - - // 이미지인지 기타 파일인지 체크하여 upload path 지정 - if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_info['name'])) { - // direct 파일에 해킹을 의심할 수 있는 확장자가 포함되어 있으면 바로 삭제함 - $file_info['name'] = preg_replace('/\.(php|phtm|html|htm|cgi|pl|exe|jsp|asp|inc)/i', '$0-x',$file_info['name']); - $file_info['name'] = str_replace(array('<','>'),array('%3C','%3E'),$file_info['name']); - - $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3)); - $filename = $path.$file_info['name']; - $idx = 1; - while(file_exists($filename)) { - $filename = $path.preg_replace('/\.([a-z0-9]+)$/i','_'.$idx.'.$1',$file_info['name']); - $idx++; - } - $direct_download = 'Y'; - } else { - $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); - $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); - $direct_download = 'N'; - } - - // 디렉토리 생성 - if(!FileHandler::makeDir($path)) return new Object(-1,'msg_not_permitted_create'); - - // 파일 이동 - if($manual_insert) { - @copy($file_info['tmp_name'], $filename); - if(!file_exists($filename)) { - $ext = substr(strrchr($file_info['name'],'.'),1); - $filename = $path. md5(crypt(rand(1000000,900000).$file_info['name'])).'.'.$ext; - @copy($file_info['tmp_name'], $filename); - } - } else { - if(!@move_uploaded_file($file_info['tmp_name'], $filename)) { - $ext = substr(strrchr($file_info['name'],'.'),1); - $filename = $path. md5(crypt(rand(1000000,900000).$file_info['name'])).'.'.$ext; - if(!@move_uploaded_file($file_info['tmp_name'], $filename)) return new Object(-1,'msg_file_upload_error'); - } - } - - // 사용자 정보를 구함 - $oMemberModel = &getModel('member'); - $member_srl = $oMemberModel->getLoggedMemberSrl(); - - // 파일 정보를 정리 - $args->file_srl = getNextSequence(); - $args->upload_target_srl = $upload_target_srl; - $args->module_srl = $module_srl; - $args->direct_download = $direct_download; - $args->source_filename = $file_info['name']; - $args->uploaded_filename = $filename; - $args->download_count = $download_count; - $args->file_size = @filesize($filename); - $args->comment = NULL; - $args->member_srl = $member_srl; - $args->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); - - $output = executeQuery('file.insertFile', $args); - if(!$output->toBool()) return $output; - - // trigger 호출 (after) - $trigger_output = ModuleHandler::triggerCall('file.insertFile', 'after', $args); - if(!$trigger_output->toBool()) return $trigger_output; - - $output->add('file_srl', $args->file_srl); - $output->add('file_size', $args->file_size); - $output->add('sid', $args->sid); - $output->add('direct_download', $args->direct_download); - $output->add('source_filename', $args->source_filename); - $output->add('upload_target_srl', $upload_target_srl); - $output->add('uploaded_filename', $args->uploaded_filename); - return $output; - } - - /** - * @brief 첨부파일 삭제 - **/ - function deleteFile($file_srl) { - if(!$file_srl) return; - - $srls = explode(',',$file_srl); - if(!count($srls)) return; - - for($i=0;$ifile_srl = $srl; - $output = executeQuery('file.getFile', $args); - if(!$output->toBool()) continue; - - $file_info = $output->data; - if(!$file_info) continue; - - $source_filename = $output->data->source_filename; - $uploaded_filename = $output->data->uploaded_filename; - - // trigger 호출 (before) - $trigger_obj = $output->data; - $output = ModuleHandler::triggerCall('file.deleteFile', 'before', $trigger_obj); - if(!$output->toBool()) return $output; - - // DB에서 삭제 - $output = executeQuery('file.deleteFile', $args); - if(!$output->toBool()) return $output; - - // trigger 호출 (after) - $trigger_output = ModuleHandler::triggerCall('file.deleteFile', 'after', $trigger_obj); - if(!$trigger_output->toBool()) return $trigger_output; - - // 삭제 성공하면 파일 삭제 - FileHandler::removeFile($uploaded_filename); - } - - return $output; - } - - /** - * @brief 특정 문서의 첨부파일을 모두 삭제 - **/ - function deleteFiles($upload_target_srl) { - // 첨부파일 목록을 받음 - $oFileModel = &getModel('file'); - $file_list = $oFileModel->getFiles($upload_target_srl); - - // 첨부파일이 없으면 성공 return - if(!is_array($file_list)||!count($file_list)) return new Object(); - - // DB에서 삭제 - $args->upload_target_srl = $upload_target_srl; - $output = executeQuery('file.deleteFiles', $args); - if(!$output->toBool()) return $output; - - // 실제 파일 삭제 - $path = array(); - $file_count = count($file_list); - for($i=0;$i<$file_count;$i++) { - $uploaded_filename = $file_list[$i]->uploaded_filename; - FileHandler::removeFile($uploaded_filename); - $module_srl = $file_list[$i]->module_srl; - - $path_info = pathinfo($uploaded_filename); - if(!in_array($path_info['dirname'], $path)) $path[] = $path_info['dirname']; - } - - // 해당 글의 첨부파일 디렉토리 삭제 - for($i=0;$igetFiles($source_srl); - if(!$file_list) return; - - $file_count = count($file_list); - - for($i=0;$i<$file_count;$i++) { - - unset($file_info); - $file_info = $file_list[$i]; - $old_file = $file_info->uploaded_filename; - - // 이미지인지 기타 파일인지 체크하여 이동할 위치 정함 - if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_info->source_filename)) { - $path = sprintf("./files/attach/images/%s/%s/", $target_module_srl,$target_srl); - $new_file = $path.$file_info->source_filename; - } else { - $path = sprintf("./files/attach/binaries/%s/%s/", $target_module_srl, $target_srl); - $new_file = $path.md5(crypt(rand(1000000,900000), rand(0,100))); - } - - // 이전 대상이 동일하면 그냥 패스 - if($old_file == $new_file) continue; - - // 디렉토리 생성 - FileHandler::makeDir($path); - - // 파일 이동 - FileHandler::rename($old_file, $new_file); - - // DB 정보도 수정 - unset($args); - $args->file_srl = $file_info->file_srl; - $args->uploaded_filename = $new_file; - $args->module_srl = $file_info->module_srl; - $args->upload_target_srl = $target_srl; - executeQuery('file.updateFile', $args); - } - } - - /** - * @brief upload_target_srl을 키로 하는 첨부파일을 찾아서 java script 코드로 return - **/ - function printUploadedFileList($editor_sequence, $upload_target_srl) { - return; - } - } -?> +module_srl; + + // 업로드 권한이 없거나 정보가 없을시 종료 + if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); + + // upload_target_srl 값이 명시되지 않았을 경우 세션정보에서 추출 + if(!$upload_target_srl) $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; + + // 세션정보에도 정의되지 않았다면 새로 생성 + if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence(); + + $file_info = Context::get('Filedata'); + + // 정상적으로 업로드된 파일이 아니면 오류 출력 + if(!is_uploaded_file($file_info['tmp_name'])) exit(); + + return $this->insertFile($file_info, $module_srl, $upload_target_srl); + } + + + /** + * @brief iframe 첨부파일 업로드 + **/ + function procFileIframeUpload() { + // 기본적으로 필요한 변수 설정 + $editor_sequence = Context::get('editor_sequence'); + $callback = Context::get('callback'); + $module_srl = $this->module_srl; + $upload_target_srl = intval(Context::get('uploadTargetSrl')); + + // 업로드 권한이 없거나 정보가 없을시 종료 + if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); + + // upload_target_srl 값이 명시되지 않았을 경우 세션정보에서 추출 + if(!$upload_target_srl) $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; + + // 세션정보에도 정의되지 않았다면 새로 생성 + if(!$upload_target_srl) $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl = getNextSequence(); + + // file_srl이 요청되었을 경우 삭제 후 재업로드 시도 + $file_srl = Context::get('file_srl'); + if($file_srl) $this->deleteFile($file_srl); + + $file_info = Context::get('Filedata'); + + // 정상적으로 업로드된 파일이 아니면 오류 출력 + if(is_uploaded_file($file_info['tmp_name'])) { + $output = $this->insertFile($file_info, $module_srl, $upload_target_srl); + Context::set('uploaded_fileinfo',$output); + } + + Context::set('layout','none'); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('iframe'); + + } + + /** + * @brief image resize + **/ + function procFileImageResize() { + $source_src = Context::get('source_src'); + $width = Context::get('width'); + $height = Context::get('height'); + $type = Context::get('type'); + $output_src = Context::get('output_src'); + + if(!$source_src || !$width) return new Object(-1,'msg_invalid_request'); + if(!$output_src){ + $output_src = $source_src . '.resized' . strrchr($source_src,'.'); + } + if(!$type) $type = 'ratio'; + if(!$height) $height = $width-1; + + if(FileHandler::createImageFile($source_src,$output_src,$width,$height,'','ratio')){ + $output->info = getimagesize($output_src); + $output->src = $output_src; + }else{ + return new Object(-1,'msg_invalid_request'); + } + + $this->add('resized_info',$output); + } + + + + /** + * @brief 첨부파일 다운로드 + * 직접 요청을 받음 + * file_srl : 파일의 sequence + * sid : db에 저장된 비교 값, 틀리면 다운로드 하지 않음 + **/ + function procFileDownload() { + $oFileModel = &getModel('file'); + + $file_srl = Context::get('file_srl'); + $sid = Context::get('sid'); + $logged_info = Context::get('logged_info'); + + // 파일의 정보를 DB에서 받아옴 + $file_obj = $oFileModel->getFile($file_srl); + + // 요청된 파일 정보가 잘못되었다면 파일을 찾을 수 없다는 오류 출력 + if($file_obj->file_srl!=$file_srl || $file_obj->sid!=$sid) return $this->stop('msg_file_not_found'); + + // 대기 상태일 경우 파일 다운로드 권한이 없음을 알림 (최고관리자는 다운 로드 허용) + if($logged_info->is_admin != 'Y' && $file_obj->isvalid!='Y') return $this->stop('msg_not_permitted_download'); + + // 파일 이름 + $filename = $file_obj->source_filename; + $file_module_config = $oFileModel->getFileModuleConfig($file_obj->module_srl); + + // 파일 외부링크 차단 + if($file_module_config->allow_outlink == 'N') { + //외부링크 허용 확장자 처리 + if($file_module_config->allow_outlink_format) { + $allow_outlink_format_array = array(); + $allow_outlink_format_array = explode(',', $file_module_config->allow_outlink_format); + if(!is_array($allow_outlink_format_array)) $allow_outlink_format_array[0] = $file_module_config->allow_outlink_format; + + foreach($allow_outlink_format_array as $val) { + $val = trim($val); + if(preg_match("/\.{$val}$/i", $filename)) { + $file_module_config->allow_outlink = 'Y'; + break; + } + } + } + //외부링크 허용 사이트 처리 + if($file_module_config->allow_outlink != 'Y') { + $referer = parse_url($_SERVER["HTTP_REFERER"]); + if($referer['host'] != $_SERVER['HTTP_HOST']) { + if($file_module_config->allow_outlink_site) { + $allow_outlink_site_array = array(); + $allow_outlink_site_array = explode("\n", $file_module_config->allow_outlink_site); + if(!is_array($allow_outlink_site_array)) $allow_outlink_site_array[0] = $file_module_config->allow_outlink_site; + + foreach($allow_outlink_site_array as $val) { + $site = parse_url(trim($val)); + if($site['host'] == $referer['host']) { + $file_module_config->allow_outlink = 'Y'; + break; + } + } + } + } + else $file_module_config->allow_outlink = 'Y'; + } + if($file_module_config->allow_outlink != 'Y') return $this->stop('msg_not_allowed_outlink'); + } + + // 파일 다운로드 권한이 있는지 확인 + if(is_array($file_module_config->download_grant) && count($file_module_config->download_grant)>0) { + if(!Context::get('is_logged')) return $this->stop('msg_not_permitted_download'); + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y') { + + $oModuleModel =& getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($file_obj->module_srl); + + if(!$oModuleModel->isSiteAdmin($logged_info, $module_info->site_srl)) + { + $oMemberModel =& getModel('member'); + $member_groups = $oMemberModel->getMemberGroups($logged_info->member_srl, $module_info->site_srl); + + $is_permitted = false; + for($i=0;$idownload_grant);$i++) { + $group_srl = $file_module_config->download_grant[$i]; + if($member_groups[$group_srl]) { + $is_permitted = true; + break; + } + } + if(!$is_permitted) return $this->stop('msg_not_permitted_download'); + } + } + } + + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('file.downloadFile', 'before', $file_obj); + if(!$output->toBool()) return $this->stop(($output->message)?$output->message:'msg_not_permitted_download'); + + // 파일 출력 + if(strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) { + $filename = rawurlencode($filename); + $filename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1); + } + + $uploaded_filename = $file_obj->uploaded_filename; + if(!file_exists($uploaded_filename)) return $this->stop('msg_file_not_found'); + + $fp = fopen($uploaded_filename, 'rb'); + if(!$fp) return $this->stop('msg_file_not_found'); + + header("Cache-Control: "); + header("Pragma: "); + header("Content-Type: application/octet-stream"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); + + header("Content-Length: " .(string)($file_obj->file_size)); + header('Content-Disposition: attachment; filename="'.$filename.'"'); + header("Content-Transfer-Encoding: binary\n"); + + fpassthru($fp); + + // 이상이 없으면 download_count 증가 + $args->file_srl = $file_srl; + executeQuery('file.updateFileDownloadCount', $args); + + // trigger 호출 (after) + $output = ModuleHandler::triggerCall('file.downloadFile', 'after', $file_obj); + + Context::close(); + + exit(); + } + + /** + * @brief 에디터에서 첨부 파일 삭제 + **/ + function procFileDelete() { + // 기본적으로 필요한 변수인 upload_target_srl, module_srl을 설정 + $editor_sequence = Context::get('editor_sequence'); + $file_srl = Context::get('file_srl'); + $file_srls = Context::get('file_srls'); + if($file_srls) $file_srl = $file_srls; + + // 업로드 권한이 없거나 정보가 없을시 종료 + if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); + + $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; + if($upload_target_srl && $file_srl) $output = $this->deleteFile($file_srl); + } + + /** + * @brief 특정 upload_target_srl(document_srl)에 등록된 첨부파일의 갯수를 return하는 trigger + **/ + function triggerCheckAttached(&$obj) { + $document_srl = $obj->document_srl; + if(!$document_srl) return new Object(); + + // 첨부 파일의 갯수를 구함 + $oFileModel = &getModel('file'); + $obj->uploaded_count = $oFileModel->getFilesCount($document_srl); + + return new Object(); + } + + /** + * @brief 특정 upload_target_srl(document_srl)에 등록된 첨부파일을 연결하는 trigger + **/ + function triggerAttachFiles(&$obj) { + $document_srl = $obj->document_srl; + if(!$document_srl) return new Object(); + + $output = $this->setFilesValid($document_srl); + if(!$output->toBool()) return $output; + + return new Object(); + } + + /** + * @brief 특정 upload_target_srl(document_srl)에 등록된 첨부파일을 삭제하는 trigger + **/ + function triggerDeleteAttached(&$obj) { + $document_srl = $obj->document_srl; + if(!$document_srl) return new Object(); + + $output = $this->deleteFiles($document_srl); + return $output; + } + + /** + * @brief 특정 upload_target_srl(comment_srl)에 등록된 첨부파일의 갯수를 return하는 trigger + **/ + function triggerCommentCheckAttached(&$obj) { + $comment_srl = $obj->comment_srl; + if(!$comment_srl) return new Object(); + + // 첨부 파일의 갯수를 구함 + $oFileModel = &getModel('file'); + $obj->uploaded_count = $oFileModel->getFilesCount($comment_srl); + + return new Object(); + } + + /** + * @brief 특정 upload_target_srl(comment_srl)에 등록된 첨부파일을 연결하는 trigger + **/ + function triggerCommentAttachFiles(&$obj) { + $comment_srl = $obj->comment_srl; + $uploaded_count = $obj->uploaded_count; + if(!$comment_srl || !$uploaded_count) return new Object(); + + $output = $this->setFilesValid($comment_srl); + if(!$output->toBool()) return $output; + + return new Object(); + } + + /** + * @brief 특정 upload_target_srl(comment_srl)에 등록된 첨부파일을 삭제하는 trigger + **/ + function triggerCommentDeleteAttached(&$obj) { + $comment_srl = $obj->comment_srl; + if(!$comment_srl) return new Object(); + + $output = $this->deleteFiles($comment_srl); + return $output; + } + + /** + * @brief module 삭제시 해당 첨부파일 모두 삭제하는 trigger + **/ + function triggerDeleteModuleFiles(&$obj) { + $module_srl = $obj->module_srl; + if(!$module_srl) return new Object(); + + $oFileController = &getAdminController('file'); + return $oFileController->deleteModuleFiles($module_srl); + } + + /** + * @brief 업로드 가능하다고 세팅 + **/ + function setUploadInfo($editor_sequence, $upload_target_srl=0) { + $_SESSION['upload_info'][$editor_sequence]->enabled = true; + $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl; + } + + /** + * @brief 특정 upload_target_srl의 첨부파일들의 상태를 유효로 변경 + * 글이 등록될때 글에 첨부된 파일들의 상태를 유효상태로 변경함으로서 관리시 불필요 파일로 인식되지 않도록 함 + **/ + function setFilesValid($upload_target_srl) { + $args->upload_target_srl = $upload_target_srl; + return executeQuery('file.updateFileValid', $args); + } + + /** + * @brief 첨부파일 추가 + **/ + function insertFile($file_info, $module_srl, $upload_target_srl, $download_count = 0, $manual_insert = false) { + // trigger 호출 (before) + $trigger_obj->module_srl = $module_srl; + $trigger_obj->upload_target_srl = $upload_target_srl; + $output = ModuleHandler::triggerCall('file.insertFile', 'before', $trigger_obj); + if(!$output->toBool()) return $output; + + if(!$manual_insert) { + // 첨부파일 설정 가져옴 + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y') { + $oFileModel = &getModel('file'); + $config = $oFileModel->getFileConfig($module_srl); + $allowed_filesize = $config->allowed_filesize * 1024 * 1024; + $allowed_attach_size = $config->allowed_attach_size * 1024 * 1024; + + // 한 파일당 허용 용량 초과시 오류 출력 + if($allowed_filesize < filesize($file_info['tmp_name'])) return new Object(-1, 'msg_exceeds_limit_size'); + + + // 해당 문서에 첨부된 모든 파일의 용량을 가져옴 (DB에서 가져옴) + $size_args->upload_target_srl = $upload_target_srl; + $output = executeQuery('file.getAttachedFileSize', $size_args); + $attached_size = (int)$output->data->attached_size + filesize($file_info['tmp_name']); + if($attached_size > $allowed_attach_size) return new Object(-1, 'msg_exceeds_limit_size'); + } + } + + // 이미지인지 기타 파일인지 체크하여 upload path 지정 + if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_info['name'])) { + // direct 파일에 해킹을 의심할 수 있는 확장자가 포함되어 있으면 바로 삭제함 + $file_info['name'] = preg_replace('/\.(php|phtm|html|htm|cgi|pl|exe|jsp|asp|inc)/i', '$0-x',$file_info['name']); + $file_info['name'] = str_replace(array('<','>'),array('%3C','%3E'),$file_info['name']); + + $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3)); + $filename = $path.$file_info['name']; + $idx = 1; + while(file_exists($filename)) { + $filename = $path.preg_replace('/\.([a-z0-9]+)$/i','_'.$idx.'.$1',$file_info['name']); + $idx++; + } + $direct_download = 'Y'; + } else { + $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); + $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); + $direct_download = 'N'; + } + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) return new Object(-1,'msg_not_permitted_create'); + + // 파일 이동 + if($manual_insert) { + @copy($file_info['tmp_name'], $filename); + if(!file_exists($filename)) { + $ext = substr(strrchr($file_info['name'],'.'),1); + $filename = $path. md5(crypt(rand(1000000,900000).$file_info['name'])).'.'.$ext; + @copy($file_info['tmp_name'], $filename); + } + } else { + if(!@move_uploaded_file($file_info['tmp_name'], $filename)) { + $ext = substr(strrchr($file_info['name'],'.'),1); + $filename = $path. md5(crypt(rand(1000000,900000).$file_info['name'])).'.'.$ext; + if(!@move_uploaded_file($file_info['tmp_name'], $filename)) return new Object(-1,'msg_file_upload_error'); + } + } + + // 사용자 정보를 구함 + $oMemberModel = &getModel('member'); + $member_srl = $oMemberModel->getLoggedMemberSrl(); + + // 파일 정보를 정리 + $args->file_srl = getNextSequence(); + $args->upload_target_srl = $upload_target_srl; + $args->module_srl = $module_srl; + $args->direct_download = $direct_download; + $args->source_filename = $file_info['name']; + $args->uploaded_filename = $filename; + $args->download_count = $download_count; + $args->file_size = @filesize($filename); + $args->comment = NULL; + $args->member_srl = $member_srl; + $args->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); + + $output = executeQuery('file.insertFile', $args); + if(!$output->toBool()) return $output; + + // trigger 호출 (after) + $trigger_output = ModuleHandler::triggerCall('file.insertFile', 'after', $args); + if(!$trigger_output->toBool()) return $trigger_output; + + $output->add('file_srl', $args->file_srl); + $output->add('file_size', $args->file_size); + $output->add('sid', $args->sid); + $output->add('direct_download', $args->direct_download); + $output->add('source_filename', $args->source_filename); + $output->add('upload_target_srl', $upload_target_srl); + $output->add('uploaded_filename', $args->uploaded_filename); + return $output; + } + + /** + * @brief 첨부파일 삭제 + **/ + function deleteFile($file_srl) { + if(!$file_srl) return; + + $srls = explode(',',$file_srl); + if(!count($srls)) return; + + for($i=0;$ifile_srl = $srl; + $output = executeQuery('file.getFile', $args); + if(!$output->toBool()) continue; + + $file_info = $output->data; + if(!$file_info) continue; + + $source_filename = $output->data->source_filename; + $uploaded_filename = $output->data->uploaded_filename; + + // trigger 호출 (before) + $trigger_obj = $output->data; + $output = ModuleHandler::triggerCall('file.deleteFile', 'before', $trigger_obj); + if(!$output->toBool()) return $output; + + // DB에서 삭제 + $output = executeQuery('file.deleteFile', $args); + if(!$output->toBool()) return $output; + + // trigger 호출 (after) + $trigger_output = ModuleHandler::triggerCall('file.deleteFile', 'after', $trigger_obj); + if(!$trigger_output->toBool()) return $trigger_output; + + // 삭제 성공하면 파일 삭제 + FileHandler::removeFile($uploaded_filename); + } + + return $output; + } + + /** + * @brief 특정 문서의 첨부파일을 모두 삭제 + **/ + function deleteFiles($upload_target_srl) { + // 첨부파일 목록을 받음 + $oFileModel = &getModel('file'); + $file_list = $oFileModel->getFiles($upload_target_srl); + + // 첨부파일이 없으면 성공 return + if(!is_array($file_list)||!count($file_list)) return new Object(); + + // DB에서 삭제 + $args->upload_target_srl = $upload_target_srl; + $output = executeQuery('file.deleteFiles', $args); + if(!$output->toBool()) return $output; + + // 실제 파일 삭제 + $path = array(); + $file_count = count($file_list); + for($i=0;$i<$file_count;$i++) { + $uploaded_filename = $file_list[$i]->uploaded_filename; + FileHandler::removeFile($uploaded_filename); + $module_srl = $file_list[$i]->module_srl; + + $path_info = pathinfo($uploaded_filename); + if(!in_array($path_info['dirname'], $path)) $path[] = $path_info['dirname']; + } + + // 해당 글의 첨부파일 디렉토리 삭제 + for($i=0;$igetFiles($source_srl); + if(!$file_list) return; + + $file_count = count($file_list); + + for($i=0;$i<$file_count;$i++) { + + unset($file_info); + $file_info = $file_list[$i]; + $old_file = $file_info->uploaded_filename; + + // 이미지인지 기타 파일인지 체크하여 이동할 위치 정함 + if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_info->source_filename)) { + $path = sprintf("./files/attach/images/%s/%s/", $target_module_srl,$target_srl); + $new_file = $path.$file_info->source_filename; + } else { + $path = sprintf("./files/attach/binaries/%s/%s/", $target_module_srl, $target_srl); + $new_file = $path.md5(crypt(rand(1000000,900000), rand(0,100))); + } + + // 이전 대상이 동일하면 그냥 패스 + if($old_file == $new_file) continue; + + // 디렉토리 생성 + FileHandler::makeDir($path); + + // 파일 이동 + FileHandler::rename($old_file, $new_file); + + // DB 정보도 수정 + unset($args); + $args->file_srl = $file_info->file_srl; + $args->uploaded_filename = $new_file; + $args->module_srl = $file_info->module_srl; + $args->upload_target_srl = $target_srl; + executeQuery('file.updateFile', $args); + } + } + + /** + * @brief upload_target_srl을 키로 하는 첨부파일을 찾아서 java script 코드로 return + **/ + function printUploadedFileList($editor_sequence, $upload_target_srl) { + return; + } + } +?> diff --git a/modules/file/file.model.php b/modules/file/file.model.php index 669e21ccd..14ee45c30 100644 --- a/modules/file/file.model.php +++ b/modules/file/file.model.php @@ -1,213 +1,213 @@ -upload_target_srl; - - if($upload_target_srl) { - $tmp_files = $this->getFiles($upload_target_srl); - $file_count = count($tmp_files); - - for($i=0;$i<$file_count;$i++) { - $file_info = $tmp_files[$i]; - if(!$file_info->file_srl) continue; - - $obj = null; - $obj->file_srl = $file_info->file_srl; - $obj->source_filename = $file_info->source_filename; - $obj->file_size = $file_info->file_size; - $obj->disp_file_size = FileHandler::filesize($file_info->file_size); - if($file_info->direct_download=='N') $obj->download_url = $this->getDownloadUrl($file_info->file_srl, $file_info->sid); - else $obj->download_url = str_replace('./', '', $file_info->uploaded_filename); - $obj->direct_download = $file_info->direct_download; - $files[] = $obj; - $attached_size += $file_info->file_size; - } - } else { - $upload_target_srl = 0; - $attached_size = 0; - $files = array(); - } - - // 업로드 상태 표시 작성 - $upload_status = $this->getUploadStatus($attached_size); - - // 남은 용량 체크 - $config = $oModuleModel->getModuleInfoByMid($mid); - $file_config = $this->getUploadConfig(); - $left_size = $file_config->allowed_attach_size*1024*1024 - $attached_size; - - // 필요한 정보들 세팅 - $this->add("files",$files); - $this->add("editor_sequence",$editor_sequence); - $this->add("upload_target_srl",$upload_target_srl); - $this->add("upload_status",$upload_status); - $this->add("left_size",$left_size); - } - - /** - * @brief 특정 문서에 속한 첨부파일의 개수를 return - **/ - function getFilesCount($upload_target_srl) { - $args->upload_target_srl = $upload_target_srl; - $output = executeQuery('file.getFilesCount', $args); - return (int)$output->data->count; - } - - /** - * @brief 다운로드 경로를 구함 - **/ - function getDownloadUrl($file_srl, $sid) { - return sprintf('?module=%s&act=%s&file_srl=%s&sid=%s', 'file', 'procFileDownload', $file_srl, $sid); - } - - /** - * @brief 파일 설정 정보를 구함 - **/ - function getFileConfig($module_srl = null) { - // 설정 정보를 받아옴 (module model 객체를 이용) - $oModuleModel = &getModel('module'); - - $file_module_config = $oModuleModel->getModuleConfig('file'); - - if($module_srl) $file_config = $oModuleModel->getModulePartConfig('file',$module_srl); - if(!$file_config) $file_config = $file_module_config; - - if($file_config) { - $config->allowed_filesize = $file_config->allowed_filesize; - $config->allowed_attach_size = $file_config->allowed_attach_size; - $config->allowed_filetypes = $file_config->allowed_filetypes; - $config->download_grant = $file_config->download_grant; - $config->allow_outlink = $file_config->allow_outlink; - $config->allow_outlink_site = $file_config->allow_outlink_site; - $config->allow_outlink_format = $file_config->allow_outlink_format; - } - - // 전체 파일첨부 속성을 먼저 따른다 - if(!$config->allowed_filesize) $config->allowed_filesize = $file_module_config->allowed_filesize; - if(!$config->allowed_attach_size) $config->allowed_attach_size = $file_module_config->allowed_attach_size; - if(!$config->allowed_filetypes) $config->allowed_filetypes = $file_module_config->allowed_filetypes; - if(!$config->allow_outlink) $config->allow_outlink = $file_module_config->allow_outlink; - if(!$config->allow_outlink_site) $config->allow_outlink_site = $file_module_config->allow_outlink_site; - if(!$config->allow_outlink_format) $config->allow_outlink_format = $file_module_config->allow_outlink_format; - if(!$config->download_grant) $config->download_grant = $file_module_config->download_grant; - - // 그래도 없으면 default로 - if(!$config->allowed_filesize) $config->allowed_filesize = '2'; - if(!$config->allowed_attach_size) $config->allowed_attach_size = '3'; - if(!$config->allowed_filetypes) $config->allowed_filetypes = '*.*'; - if(!$config->allow_outlink) $config->allow_outlink = 'Y'; - if(!$config->download_grant) $config->download_grant = array(); - - return $config; - } - - /** - * @brief 파일 정보를 구함 - **/ - function getFile($file_srl) { - $args->file_srl = $file_srl; - $output = executeQuery('file.getFile', $args); - if(!$output->toBool()) return $output; - - $file = $output->data; - $file->download_url = $this->getDownloadUrl($file->file_srl, $file->sid); - - return $file; - } - - /** - * @brief 특정 문서에 속한 파일을 모두 return - **/ - function getFiles($upload_target_srl) { - $args->upload_target_srl = $upload_target_srl; - $args->sort_index = 'file_srl'; - $output = executeQuery('file.getFiles', $args); - if(!$output->data) return; - - $file_list = $output->data; - - if($file_list && !is_array($file_list)) $file_list = array($file_list); - - $file_count = count($file_list); - for($i=0;$i<$file_count;$i++) { - $file = $file_list[$i]; - $file->source_filename = stripslashes($file->source_filename); - $file->download_url = $this->getDownloadUrl($file->file_srl, $file->sid); - $file_list[$i] = $file; - } - - return $file_list; - } - - /** - * @brief 첨부파일에 대한 설정을 return (관리자/비관리자 자동 구분) - **/ - function getUploadConfig() { - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == 'Y') { - $file_config->allowed_filesize = preg_replace("/[a-z]/is","",ini_get('upload_max_filesize')); - $file_config->allowed_attach_size = preg_replace("/[a-z]/is","",ini_get('upload_max_filesize')); - $file_config->allowed_filetypes = '*.*'; - } else { - $module_srl = Context::get('module_srl'); - // module_srl이 없으면 현재 모듈 - if(!$module_srl) { - $current_module_info = Context::get('current_module_info'); - $module_srl = $current_module_info->module_srl; - } - $file_config = $this->getFileConfig($module_srl); - } - return $file_config; - } - - /** - * @brief 파일 업로드를 위한 관리자/비관리자에 따른 안내문구 return - **/ - function getUploadStatus($attached_size = 0) { - $file_config = $this->getUploadConfig(); - - // 업로드 상태 표시 작성 - $upload_status = sprintf( - '%s : %s/ %s
%s : %s (%s : %s)', - Context::getLang('allowed_attach_size'), - FileHandler::filesize($attached_size), - FileHandler::filesize($file_config->allowed_attach_size*1024*1024), - Context::getLang('allowed_filesize'), - FileHandler::filesize($file_config->allowed_filesize*1024*1024), - Context::getLang('allowed_filetypes'), - $file_config->allowed_filetypes - ); - return $upload_status; - } - - /** - * @brief 특정 모듈의 file 설정을 return - **/ - function getFileModuleConfig($module_srl) { - return $this->getFileConfig($module_srl); - } - } -?> +upload_target_srl; + + if($upload_target_srl) { + $tmp_files = $this->getFiles($upload_target_srl); + $file_count = count($tmp_files); + + for($i=0;$i<$file_count;$i++) { + $file_info = $tmp_files[$i]; + if(!$file_info->file_srl) continue; + + $obj = null; + $obj->file_srl = $file_info->file_srl; + $obj->source_filename = $file_info->source_filename; + $obj->file_size = $file_info->file_size; + $obj->disp_file_size = FileHandler::filesize($file_info->file_size); + if($file_info->direct_download=='N') $obj->download_url = $this->getDownloadUrl($file_info->file_srl, $file_info->sid); + else $obj->download_url = str_replace('./', '', $file_info->uploaded_filename); + $obj->direct_download = $file_info->direct_download; + $files[] = $obj; + $attached_size += $file_info->file_size; + } + } else { + $upload_target_srl = 0; + $attached_size = 0; + $files = array(); + } + + // 업로드 상태 표시 작성 + $upload_status = $this->getUploadStatus($attached_size); + + // 남은 용량 체크 + $config = $oModuleModel->getModuleInfoByMid($mid); + $file_config = $this->getUploadConfig(); + $left_size = $file_config->allowed_attach_size*1024*1024 - $attached_size; + + // 필요한 정보들 세팅 + $this->add("files",$files); + $this->add("editor_sequence",$editor_sequence); + $this->add("upload_target_srl",$upload_target_srl); + $this->add("upload_status",$upload_status); + $this->add("left_size",$left_size); + } + + /** + * @brief 특정 문서에 속한 첨부파일의 개수를 return + **/ + function getFilesCount($upload_target_srl) { + $args->upload_target_srl = $upload_target_srl; + $output = executeQuery('file.getFilesCount', $args); + return (int)$output->data->count; + } + + /** + * @brief 다운로드 경로를 구함 + **/ + function getDownloadUrl($file_srl, $sid) { + return sprintf('?module=%s&act=%s&file_srl=%s&sid=%s', 'file', 'procFileDownload', $file_srl, $sid); + } + + /** + * @brief 파일 설정 정보를 구함 + **/ + function getFileConfig($module_srl = null) { + // 설정 정보를 받아옴 (module model 객체를 이용) + $oModuleModel = &getModel('module'); + + $file_module_config = $oModuleModel->getModuleConfig('file'); + + if($module_srl) $file_config = $oModuleModel->getModulePartConfig('file',$module_srl); + if(!$file_config) $file_config = $file_module_config; + + if($file_config) { + $config->allowed_filesize = $file_config->allowed_filesize; + $config->allowed_attach_size = $file_config->allowed_attach_size; + $config->allowed_filetypes = $file_config->allowed_filetypes; + $config->download_grant = $file_config->download_grant; + $config->allow_outlink = $file_config->allow_outlink; + $config->allow_outlink_site = $file_config->allow_outlink_site; + $config->allow_outlink_format = $file_config->allow_outlink_format; + } + + // 전체 파일첨부 속성을 먼저 따른다 + if(!$config->allowed_filesize) $config->allowed_filesize = $file_module_config->allowed_filesize; + if(!$config->allowed_attach_size) $config->allowed_attach_size = $file_module_config->allowed_attach_size; + if(!$config->allowed_filetypes) $config->allowed_filetypes = $file_module_config->allowed_filetypes; + if(!$config->allow_outlink) $config->allow_outlink = $file_module_config->allow_outlink; + if(!$config->allow_outlink_site) $config->allow_outlink_site = $file_module_config->allow_outlink_site; + if(!$config->allow_outlink_format) $config->allow_outlink_format = $file_module_config->allow_outlink_format; + if(!$config->download_grant) $config->download_grant = $file_module_config->download_grant; + + // 그래도 없으면 default로 + if(!$config->allowed_filesize) $config->allowed_filesize = '2'; + if(!$config->allowed_attach_size) $config->allowed_attach_size = '3'; + if(!$config->allowed_filetypes) $config->allowed_filetypes = '*.*'; + if(!$config->allow_outlink) $config->allow_outlink = 'Y'; + if(!$config->download_grant) $config->download_grant = array(); + + return $config; + } + + /** + * @brief 파일 정보를 구함 + **/ + function getFile($file_srl) { + $args->file_srl = $file_srl; + $output = executeQuery('file.getFile', $args); + if(!$output->toBool()) return $output; + + $file = $output->data; + $file->download_url = $this->getDownloadUrl($file->file_srl, $file->sid); + + return $file; + } + + /** + * @brief 특정 문서에 속한 파일을 모두 return + **/ + function getFiles($upload_target_srl) { + $args->upload_target_srl = $upload_target_srl; + $args->sort_index = 'file_srl'; + $output = executeQuery('file.getFiles', $args); + if(!$output->data) return; + + $file_list = $output->data; + + if($file_list && !is_array($file_list)) $file_list = array($file_list); + + $file_count = count($file_list); + for($i=0;$i<$file_count;$i++) { + $file = $file_list[$i]; + $file->source_filename = stripslashes($file->source_filename); + $file->download_url = $this->getDownloadUrl($file->file_srl, $file->sid); + $file_list[$i] = $file; + } + + return $file_list; + } + + /** + * @brief 첨부파일에 대한 설정을 return (관리자/비관리자 자동 구분) + **/ + function getUploadConfig() { + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin == 'Y') { + $file_config->allowed_filesize = preg_replace("/[a-z]/is","",ini_get('upload_max_filesize')); + $file_config->allowed_attach_size = preg_replace("/[a-z]/is","",ini_get('upload_max_filesize')); + $file_config->allowed_filetypes = '*.*'; + } else { + $module_srl = Context::get('module_srl'); + // module_srl이 없으면 현재 모듈 + if(!$module_srl) { + $current_module_info = Context::get('current_module_info'); + $module_srl = $current_module_info->module_srl; + } + $file_config = $this->getFileConfig($module_srl); + } + return $file_config; + } + + /** + * @brief 파일 업로드를 위한 관리자/비관리자에 따른 안내문구 return + **/ + function getUploadStatus($attached_size = 0) { + $file_config = $this->getUploadConfig(); + + // 업로드 상태 표시 작성 + $upload_status = sprintf( + '%s : %s/ %s
%s : %s (%s : %s)', + Context::getLang('allowed_attach_size'), + FileHandler::filesize($attached_size), + FileHandler::filesize($file_config->allowed_attach_size*1024*1024), + Context::getLang('allowed_filesize'), + FileHandler::filesize($file_config->allowed_filesize*1024*1024), + Context::getLang('allowed_filetypes'), + $file_config->allowed_filetypes + ); + return $upload_status; + } + + /** + * @brief 특정 모듈의 file 설정을 return + **/ + function getFileModuleConfig($module_srl) { + return $this->getFileConfig($module_srl); + } + } +?> diff --git a/modules/file/file.view.php b/modules/file/file.view.php index a748cd4bb..6380a719f 100644 --- a/modules/file/file.view.php +++ b/modules/file/file.view.php @@ -1,53 +1,53 @@ -module_srl; - if(!$current_module_srl) return new Object(); - } - - // 선택된 모듈의 file설정을 가져옴 - $oFileModel = &getModel('file'); - $file_config = $oFileModel->getFileModuleConfig($current_module_srl); - Context::set('file_config', $file_config); - - // 그룹의 설정을 위한 권한 가져오기 - $oMemberModel = &getModel('member'); - $site_module_info = Context::get('site_module_info'); - $group_list = $oMemberModel->getGroups($site_module_info->site_srl); - Context::set('group_list', $group_list); - - // 템플릿 파일 지정 - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'file_module_config'); - $obj .= $tpl; - - return new Object(); - } - } -?> +module_srl; + if(!$current_module_srl) return new Object(); + } + + // 선택된 모듈의 file설정을 가져옴 + $oFileModel = &getModel('file'); + $file_config = $oFileModel->getFileModuleConfig($current_module_srl); + Context::set('file_config', $file_config); + + // 그룹의 설정을 위한 권한 가져오기 + $oMemberModel = &getModel('member'); + $site_module_info = Context::get('site_module_info'); + $group_list = $oMemberModel->getGroups($site_module_info->site_srl); + Context::set('group_list', $group_list); + + // 템플릿 파일 지정 + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'file_module_config'); + $obj .= $tpl; + + return new Object(); + } + } +?> diff --git a/modules/file/lang/en.lang.php b/modules/file/lang/en.lang.php index 9a9754858..7c2fcd4e5 100644 --- a/modules/file/lang/en.lang.php +++ b/modules/file/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief Attachment module's basic language pack **/ @@ -23,7 +23,7 @@ $lang->about_allow_outlink = 'You can shut external links according to referers. (except media files like *.wmv, *.mp3)'; $lang->about_allow_outlink_format = 'These formats will always be allowed. Please use comma(,) for multiple input.
eg)hwp,doc,zip,pdf'; - $lang->about_allow_outlink_site = 'These websites will alyways be allowed. Please use new line for multiple input.
ex)http://www.zeroboard.com'; + $lang->about_allow_outlink_site = 'These websites will alyways be allowed. Please use new line for multiple input.
ex)http://xpressengine.com/'; $lang->about_allowed_filesize = 'You can assign file size limit for each file. (Exclude administrators)'; $lang->about_allowed_attach_size = 'You can assign file size limit for each document. (Exclude administrators)'; $lang->about_allowed_filetypes = 'Only allowed extentsions can be attached. To allow an extension, use "*.[extention]". To allow multiple extensions, use ";" between each extension.
ex) *.* or *.jpg;*.gif;
(Exclude Administrators)'; diff --git a/modules/file/lang/es.lang.php b/modules/file/lang/es.lang.php index 52029040e..6a6fd405d 100644 --- a/modules/file/lang/es.lang.php +++ b/modules/file/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma espaA±ol para los archivos adjuntos **/ @@ -21,7 +21,7 @@ $lang->enable_download_group = 'Descargar permitió grupos'; $lang->about_allow_outlink = 'Enlaces externos a Rusia Ripper puede bloquear el archivo. (*. WMV, *. mp3, etc, excepto los archivos multimedia)'; - $lang->about_allow_outlink_site = 'Archivos, independientemente de la configuración para permitir a los enlaces externos es la dirección del sitio. Entrada múltiples gubunhaeju un cambio en la línea, por favor.
Ej.) http://www.zeroboard.com'; + $lang->about_allow_outlink_site = 'Archivos, independientemente de la configuración para permitir a los enlaces externos es la dirección del sitio. Entrada múltiples gubunhaeju un cambio en la línea, por favor.
Ej.) http://xpressengine.com/'; $lang->about_allowed_filesize = 'Puede definir el límite del tamaño del archivo adjunto. (exceptuando el administrador)'; $lang->about_allowed_attach_size = 'Puede definir el límite del tamaño total de los archivos adjuntos por documento. (exceptuando el administrador)'; $lang->about_allowed_filetypes = 'Puede definir las extensiones de los archivos permitidos. Para permitir una extensión use "*.extensión". Para permitir más de una extensión use ";".
ej) *.* o *.jpg;*.gif;etc.
(exceptuando el administrador)'; diff --git a/modules/file/lang/fr.lang.php b/modules/file/lang/fr.lang.php index 0db76d239..1bb1a9494 100644 --- a/modules/file/lang/fr.lang.php +++ b/modules/file/lang/fr.lang.php @@ -1,7 +1,7 @@ Traduit par Pierre Duvent + * @author NHN (developers@xpressengine.com) Traduit par Pierre Duvent * @brief Paquet du langage en francais pour le module d\'Annexe **/ @@ -21,7 +21,7 @@ $lang->enable_download_group = 'Groupe permis de telecharger'; $lang->about_allow_outlink = '리퍼러에 따라 파일 외부 링크를 차단할 수 있습니다.(*.wmv, *.mp3등 미디어 파일 제외)'; - $lang->about_allow_outlink_site = '파일 외부 링크 설정에 관계 없이 허용하는 사이트 주소입니다. 여러개 입력시에 줄을 바꿔서 구분해주세요.
ex)http://www.zeroboard.com'; + $lang->about_allow_outlink_site = '파일 외부 링크 설정에 관계 없이 허용하는 사이트 주소입니다. 여러개 입력시에 줄을 바꿔서 구분해주세요.
ex)http://xpressengine.com/'; $lang->about_allowed_filesize = 'Vous pouvez designer la limite de mesure pour chaque fichier. (Exclure administrateurs)'; $lang->about_allowed_attach_size = 'Vous pouvez designer la limite de mesure pour chaque document. (Exclure administrateurs)'; $lang->about_allowed_filetypes = 'Extensions consentis seulement peuvent etre attaches. Pour consentir une extension, utilisez "*.[extention]". Pour consentir plusieurs extensions, utilisez ";" entre chaque extension.
ex) *.* ou *.jpg;*.gif;
(Exclure Administrateurs)'; diff --git a/modules/file/lang/jp.lang.php b/modules/file/lang/jp.lang.php index e8b5979f3..5faa5de15 100644 --- a/modules/file/lang/jp.lang.php +++ b/modules/file/lang/jp.lang.php @@ -1,7 +1,7 @@ 翻訳:RisaPapa、ミニミ + * @author NHN (developers@xpressengine.com) 翻訳:RisaPapa、ミニミ * @brief 添付ファイル(file)モジュールの基本言語パッケージ **/ @@ -23,7 +23,7 @@ $lang->about_allow_outlink = 'リファラーによって外部からのファイルリンクを制御出来ます。(*.wmv, *.mp3などのメディアファイルは除く)'; $lang->about_allow_outlink_format = '外部からのファイルリンク設定に構わず、常に外部からのリンクを許可する拡張子です。複数登録時には、「半角コンマ(,)」区切りで記入して下さい。
eg)txt,doc,zip,pdf'; - $lang->about_allow_outlink_site = '外部からのファイルリンク設定に構わず、常に外部からのリンクを許可するURLです。複数登録時には、改行で記入して下さい。
ex)http://www.zeroboard.com'; + $lang->about_allow_outlink_site = '外部からのファイルリンク設定に構わず、常に外部からのリンクを許可するURLです。複数登録時には、改行で記入して下さい。
ex)http://xpressengine.com/'; $lang->about_allowed_filesize = '一つのファイルに対して、アップロード出来るファイルの最大サイズを指定します(管理者除外)。'; $lang->about_allowed_attach_size = '一つの書き込みに対して、管理者以外のユーザーが添付出来る最大サイズを指定します。'; $lang->about_allowed_filetypes = 'ここで指定された種類のファイルのみ添付出来ます。"*.拡張子"で指定し、 ";"で区切って任意の拡張子を追加して指定出来ます。 (管理者は制限無し)
ex) *.* or *.jpg;*.gif;
'; diff --git a/modules/file/lang/ko.lang.php b/modules/file/lang/ko.lang.php index 5a4e2b69c..27eaaadd3 100644 --- a/modules/file/lang/ko.lang.php +++ b/modules/file/lang/ko.lang.php @@ -1,57 +1,57 @@ - - * @brief 첨부 파일(file) 모듈의 기본 언어팩 - **/ - - $lang->file = '첨부 파일'; - $lang->file_name = '파일 이름'; - $lang->file_size = '파일 크기'; - $lang->download_count = '다운로드 받은 수'; - $lang->status = '상태'; - $lang->is_valid = '유효'; - $lang->is_stand_by = '대기'; - $lang->file_list = '첨부 파일 목록'; - $lang->allow_outlink = '파일 외부 링크'; - $lang->allow_outlink_site = '파일 외부 링크 허용 사이트'; - $lang->allow_outlink_format = '파일 외부 링크 허용 확장자'; - $lang->allowed_filesize = '파일 제한 크기'; - $lang->allowed_attach_size = '문서 첨부 제한'; - $lang->allowed_filetypes = '허용 확장자'; - $lang->enable_download_group = '다운로드 가능 그룹'; - - $lang->about_allow_outlink = '리퍼러에 따라 파일 외부 링크를 차단할 수 있습니다. (*.wmv, *.mp3등 미디어 파일 제외)'; - $lang->about_allow_outlink_format = '파일 외부 링크 설정에 상관없이 허용하는 파일 확장자입니다. 여러 개 입력 시에 쉼표(,)을 이용해서 구분해주세요.
예)hwp,doc,zip,pdf'; - $lang->about_allow_outlink_site = '파일 외부 링크 설정에 상관없이 허용하는 사이트 주소입니다. 여러 개 입력 시에 줄을 바꿔서 구분해주세요.
예)http://www.xpressengine.com'; - $lang->about_allowed_filesize = '하나의 파일에 대해 최고 용량을 지정할 수 있습니다. (관리자는 제외)'; - $lang->about_allowed_attach_size = '하나의 문서에 첨부할 수 있는 최고 용량을 지정할 수 있습니다. (관리자는 제외)'; - $lang->about_allowed_filetypes = '허용한 확장자만 첨부할 수 있습니다. "*.확장자"로 지정할 수 있고 ";" 으로 여러 개 지정이 가능합니다.
예) *.* or *.jpg;*.gif;
(관리자는 제외)'; - - $lang->cmd_delete_checked_file = '선택항목 삭제'; - $lang->cmd_move_to_document = '문서로 이동'; - $lang->cmd_download = '다운로드'; - - $lang->msg_not_permitted_download = '다운로드 할 수 있는 권한이 없습니다.'; - $lang->msg_cart_is_null = '삭제할 파일을 선택해주세요.'; - $lang->msg_checked_file_is_deleted = '%d개의 첨부 파일이 삭제되었습니다.'; - $lang->msg_exceeds_limit_size = '허용된 용량을 초과하여 첨부가 되지 않았습니다.'; - $lang->msg_file_not_found = '요청하신 파일을 찾을 수 없습니다.'; - - $lang->file_search_target_list = array( - 'filename' => '파일 이름', - 'filesize_more' => '파일 크기 (byte, 이상)', - 'filesize_mega_more' => '파일 크기 (MB, 이상)', - 'filesize_less' => '파일 크기 (byte, 이하)', - 'filesize_mega_less' => '파일 크기 (MB, 이하)', - 'download_count' => '다운로드 횟수 (이상)', - 'user_id' => '아이디', - 'user_name' => '이름', - 'nick_name' => '닉네임', - 'regdate' => '등록일', - 'ipaddress' => 'IP 주소', - ); - $lang->msg_not_allowed_outlink = '외부링크에서 다운로드 할 수 없습니다.'; - $lang->msg_not_permitted_create = '파일 또는 디렉토리를 생성할 수 없습니다.'; - $lang->msg_file_upload_error = '파일 업로드 중 에러가 발생하였습니다.'; -?> +file = '첨부 파일'; + $lang->file_name = '파일 이름'; + $lang->file_size = '파일 크기'; + $lang->download_count = '다운로드 받은 수'; + $lang->status = '상태'; + $lang->is_valid = '유효'; + $lang->is_stand_by = '대기'; + $lang->file_list = '첨부 파일 목록'; + $lang->allow_outlink = '파일 외부 링크'; + $lang->allow_outlink_site = '파일 외부 링크 허용 사이트'; + $lang->allow_outlink_format = '파일 외부 링크 허용 확장자'; + $lang->allowed_filesize = '파일 제한 크기'; + $lang->allowed_attach_size = '문서 첨부 제한'; + $lang->allowed_filetypes = '허용 확장자'; + $lang->enable_download_group = '다운로드 가능 그룹'; + + $lang->about_allow_outlink = '리퍼러에 따라 파일 외부 링크를 차단할 수 있습니다. (*.wmv, *.mp3등 미디어 파일 제외)'; + $lang->about_allow_outlink_format = '파일 외부 링크 설정에 상관없이 허용하는 파일 확장자입니다. 여러 개 입력 시에 쉼표(,)을 이용해서 구분해주세요.
예)hwp,doc,zip,pdf'; + $lang->about_allow_outlink_site = '파일 외부 링크 설정에 상관없이 허용하는 사이트 주소입니다. 여러 개 입력 시에 줄을 바꿔서 구분해주세요.
예)http://www.xpressengine.com'; + $lang->about_allowed_filesize = '하나의 파일에 대해 최고 용량을 지정할 수 있습니다. (관리자는 제외)'; + $lang->about_allowed_attach_size = '하나의 문서에 첨부할 수 있는 최고 용량을 지정할 수 있습니다. (관리자는 제외)'; + $lang->about_allowed_filetypes = '허용한 확장자만 첨부할 수 있습니다. "*.확장자"로 지정할 수 있고 ";" 으로 여러 개 지정이 가능합니다.
예) *.* or *.jpg;*.gif;
(관리자는 제외)'; + + $lang->cmd_delete_checked_file = '선택항목 삭제'; + $lang->cmd_move_to_document = '문서로 이동'; + $lang->cmd_download = '다운로드'; + + $lang->msg_not_permitted_download = '다운로드 할 수 있는 권한이 없습니다.'; + $lang->msg_cart_is_null = '삭제할 파일을 선택해주세요.'; + $lang->msg_checked_file_is_deleted = '%d개의 첨부 파일이 삭제되었습니다.'; + $lang->msg_exceeds_limit_size = '허용된 용량을 초과하여 첨부가 되지 않았습니다.'; + $lang->msg_file_not_found = '요청하신 파일을 찾을 수 없습니다.'; + + $lang->file_search_target_list = array( + 'filename' => '파일 이름', + 'filesize_more' => '파일 크기 (byte, 이상)', + 'filesize_mega_more' => '파일 크기 (MB, 이상)', + 'filesize_less' => '파일 크기 (byte, 이하)', + 'filesize_mega_less' => '파일 크기 (MB, 이하)', + 'download_count' => '다운로드 횟수 (이상)', + 'user_id' => '아이디', + 'user_name' => '이름', + 'nick_name' => '닉네임', + 'regdate' => '등록일', + 'ipaddress' => 'IP 주소', + ); + $lang->msg_not_allowed_outlink = '외부링크에서 다운로드 할 수 없습니다.'; + $lang->msg_not_permitted_create = '파일 또는 디렉토리를 생성할 수 없습니다.'; + $lang->msg_file_upload_error = '파일 업로드 중 에러가 발생하였습니다.'; +?> diff --git a/modules/file/lang/ru.lang.php b/modules/file/lang/ru.lang.php index b73db339e..9ed2085bc 100644 --- a/modules/file/lang/ru.lang.php +++ b/modules/file/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief Russian basic language pack **/ diff --git a/modules/file/lang/vi.lang.php b/modules/file/lang/vi.lang.php index 7d072e656..88130452d 100644 --- a/modules/file/lang/vi.lang.php +++ b/modules/file/lang/vi.lang.php @@ -1,7 +1,7 @@ about_allow_outlink = 'Những định dạng Link File từ bên ngoài được phép đính kèm.(Ngoại trừ định dạng Media *.wmv, *.mp3)'; $lang->about_allow_outlink_format = 'Những định dạng này sẽ được phép liên kết. Hãy sử dụng dấu (,) để thêm nhiều định dạng .
Ví dụ: .hwp, .doc, .zip, .pdf'; - $lang->about_allow_outlink_site = 'Những Website được phép liên kết. Hãy nhập địa chỉ của những Website được phép.
Ví dụ: http://www.zeroboard.com'; + $lang->about_allow_outlink_site = 'Những Website được phép liên kết. Hãy nhập địa chỉ của những Website được phép.
Ví dụ: http://xpressengine.com/'; $lang->about_allowed_filesize = 'Giới hạn dung lượng mỗi File đính kèm. (Ngoại trừ Administrators)'; $lang->about_allowed_attach_size = 'Giới hạn dung lượng tối đa cho tất cả các File đính kèm trong một bài viết. (Ngoại trừ Administrators)'; $lang->about_allowed_filetypes = 'Chỉ được phép đính kèm những File có đuôi được liệt kê trong danh sách.
Để thêm những dạng File được phép đính kèm, bạn sử dụng "*.[đuôi]".
Để cho phép nhiều dạng đuôi File hãy đặt dấu ";" vào giữa các dạng đuôi.
Ví dụ: *.* (Cho phép tất cả) hay *.jpg;*.gif;
(Ngoại trừ Administrators)'; diff --git a/modules/file/lang/zh-CN.lang.php b/modules/file/lang/zh-CN.lang.php index ef46c733e..1a2ca5d3d 100644 --- a/modules/file/lang/zh-CN.lang.php +++ b/modules/file/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 附件(file) 模块语言包 **/ @@ -21,7 +21,7 @@ $lang->enable_download_group = '允许下载的用户组'; $lang->about_allow_outlink = '根据反向链接防止盗链。(*.wmv, *.mp3等媒体文件除外)'; - $lang->about_allow_outlink_site = '可以设置允许外链的站点。多个站点以换行来区分,即一行一个。
ex)http://www.zeroboard.com'; + $lang->about_allow_outlink_site = '可以设置允许外链的站点。多个站点以换行来区分,即一行一个。
ex)http://xpressengine.com/'; $lang->about_allowed_filesize = '最大单个上传文件大小(管理员不受此限制)。'; $lang->about_allowed_attach_size = '每个主题最大上传文件大小(管理员不受此限制)。'; $lang->about_allowed_filetypes = '只允许上传指定的扩展名。 可以用"*.扩展名"来指定或用 ";"来 区分多个扩展名
例) *.* or *.jpg;*.gif;
(管理员不受此限制)'; diff --git a/modules/file/lang/zh-TW.lang.php b/modules/file/lang/zh-TW.lang.php index 41ddb9724..0965920e6 100644 --- a/modules/file/lang/zh-TW.lang.php +++ b/modules/file/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 附加檔案(file)模組正體中文語言 **/ @@ -23,7 +23,7 @@ $lang->about_allow_outlink = '是否允許連結外部檔案。(*.wmv, *.mp3等影音檔案除外)'; $lang->about_allow_outlink_format = '設定允許外部連結的檔案格式。可以用逗號(,)來區隔多個副檔名。
例) hwp, doc, zip, pdf'; - $lang->about_allow_outlink_site = '可設置允許外部檔案連結的網站名單。當數量太多時,可換行輸入。
例) http://www.zeroboard.com'; + $lang->about_allow_outlink_site = '可設置允許外部檔案連結的網站名單。當數量太多時,可換行輸入。
例) http://xpressengine.com/'; $lang->about_allowed_filesize = '最大單一上傳檔案大小 (管理員不受此限制)。'; $lang->about_allowed_attach_size = '每個主題最大上傳檔案大小 (管理員不受此限制)。'; $lang->about_allowed_filetypes = '設定允許上傳的檔案類型。可以用"*.副檔名"來指定或用分號";"來區隔多個副檔名。
例) *.* or *.jpg; *.gif;
(管理員不受此限制)'; diff --git a/modules/importer/conf/info.xml b/modules/importer/conf/info.xml index 2264fbeea..dec5096d6 100644 --- a/modules/importer/conf/info.xml +++ b/modules/importer/conf/info.xml @@ -1,33 +1,33 @@ - - - 데이터 이전 - Data Importer - Chuyển đổi Data - 数据导入 - データ移転 - Transferencia de los datos - Трансферинг - 資料匯入 - XML파일을 이용하여 회원정보 또는 게시판등의 데이터를 입력합니다. - This module imports data of members and articles from XML file. - Nhập thông tin thành viên hoặc Database sử dụng định dạng XML Data. - 利用XML文件导入会员信息或版面数据。 - XMLファイルを用いて会員情報または掲示板などの情報を入力します。 - Ingresa la información del usuario o los datos del tablero utilizando el archivo XML. - Запись информации пользователей или форума, используя XML-файл. - 利用 XML 檔案匯入會員或討論板資料。 - 0.2 - 2007-12-13 - migration - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 데이터 이전 + Data Importer + Chuyển đổi Data + 数据导入 + データ移転 + Transferencia de los datos + Трансферинг + 資料匯入 + XML파일을 이용하여 회원정보 또는 게시판등의 데이터를 입력합니다. + This module imports data of members and articles from XML file. + Nhập thông tin thành viên hoặc Database sử dụng định dạng XML Data. + 利用XML文件导入会员信息或版面数据。 + XMLファイルを用いて会員情報または掲示板などの情報を入力します。 + Ingresa la información del usuario o los datos del tablero utilizando el archivo XML. + Запись информации пользователей или форума, используя XML-файл. + 利用 XML 檔案匯入會員或討論板資料。 + 0.2 + 2007-12-13 + migration + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/importer/extract.class.php b/modules/importer/extract.class.php index 34647cbba..e510da8e7 100644 --- a/modules/importer/extract.class.php +++ b/modules/importer/extract.class.php @@ -1,208 +1,208 @@ -filename = $filename; - - $this->startTag = $startTag; - if($endTag) $this->endTag = $endTag; - $this->itemStartTag = $itemTag; - $this->itemEndTag = $itemEndTag; - - $this->key = md5($filename); - - $this->cache_path = './files/cache/importer/'.$this->key; - $this->cache_index_file = $this->cache_path.'/index'; - - if(!is_dir($this->cache_path)) FileHandler::makeDir($this->cache_path); - - return $this->openFile(); - } - - /** - * @brief 지정된 파일의 지시자를 염 - **/ - function openFile() { - FileHandler::removeFile($this->cache_index_file); - $this->index_fd = fopen($this->cache_index_file,"a"); - - // local 파일일 경우 - if(!preg_match('/^http:/i',$this->filename)) { - if(!file_exists($this->filename)) return new Object(-1,'msg_no_xml_file'); - $this->fd = fopen($this->filename,"r"); - - // remote 파일일 경우 - } else { - $url_info = parse_url($this->filename); - if(!$url_info['port']) $url_info['port'] = 80; - if(!$url_info['path']) $url_info['path'] = '/'; - - $this->fd = @fsockopen($url_info['host'], $url_info['port']); - if(!$this->fd) return new Object(-1,'msg_no_xml_file'); - - // 한글 파일이 있으면 한글파일 부분만 urlencode하여 처리 (iconv 필수) - $path = $url_info['path']; - if(preg_match('/[\xEA-\xED][\x80-\xFF]{2}/', $path)&&function_exists('iconv')) { - $path_list = explode('/',$path); - $cnt = count($path_list); - $filename = $path_list[$cnt-1]; - $filename = urlencode(iconv("UTF-8","EUC-KR",$filename)); - $path_list[$cnt-1] = $filename; - $path = implode('/',$path_list); - $url_info['path'] = $path; - } - - $header = sprintf("GET %s?%s HTTP/1.0\r\nHost: %s\r\nReferer: %s://%s\r\nConnection: Close\r\n\r\n", $url_info['path'], $url_info['query'], $url_info['host'], $url_info['scheme'], $url_info['host']); - @fwrite($this->fd, $header); - $buff = ''; - while(!feof($this->fd)) { - $buff .= $str = fgets($this->fd, 1024); - if(!trim($str)) break; - } - if(preg_match('/404 Not Found/i',$buff)) return new Object(-1,'msg_no_xml_file'); - } - - if($this->startTag) { - while(!feof($this->fd)) { - $str = fgets($this->fd, 1024); - $pos = strpos($str, $this->startTag); - if($pos !== false) { - $this->buff = substr($this->buff, $pos+strlen($this->startTag)); - $this->isStarted = true; - $this->isFinished = false; - break; - } - } - } else { - $this->isStarted = true; - $this->isFinished = false; - } - - return new Object(); - } - - function closeFile() { - $this->isFinished = true; - fclose($this->fd); - fclose($this->index_fd); - } - - function isFinished() { - return $this->isFinished || !$this->fd || feof($this->fd); - } - - function saveItems() { - $this->index = 0; - while(!$this->isFinished()) { - $this->getItem(); - } - } - - function mergeItems($filename) { - $this->saveItems(); - - $filename = sprintf('%s/%s', $this->cache_path, $filename); - - $index_fd = fopen($this->cache_index_file,"r"); - $fd = fopen($filename,'w'); - - fwrite($fd, ''); - while(!feof($index_fd)) { - $target_file = trim(fgets($index_fd,1024)); - if(!file_exists($target_file)) continue; - $buff = FileHandler::readFile($target_file); - fwrite($fd, FileHandler::readFile($target_file)); - - FileHandler::removeFile($target_file); - } - fwrite($fd, ''); - fclose($fd); - } - - function getItem() { - if($this->isFinished()) return; - - while(!feof($this->fd)) { - $startPos = strpos($this->buff, $this->itemStartTag); - if($startPos !== false) { - $this->buff = substr($this->buff, $startPos); - $this->buff = preg_replace("/\>/",">\r\n",$this->buff,1); - break; - } elseif($this->endTag) { - $endPos = strpos($this->buff, $this->endTag); - if($endPos !== false) { - $this->closeFile(); - return; - } - } - $this->buff .= fgets($this->fd, 1024); - } - - $startPos = strpos($this->buff, $this->itemStartTag); - if($startPos === false) { - $this->closeFile(); - return; - } - - $filename = sprintf('%s/%s.xml',$this->cache_path, $this->index++); - fwrite($this->index_fd, $filename."\r\n"); - - $fd = fopen($filename,'w'); - - while(!feof($this->fd)) { - $endPos = strpos($this->buff, $this->itemEndTag); - if($endPos !== false) { - $endPos += strlen($this->itemEndTag); - $buff = substr($this->buff, 0, $endPos); - fwrite($fd, $this->_addTagCRTail($buff)); - fclose($fd); - $this->buff = substr($this->buff, $endPos); - break; - } - - fwrite($fd, $this->_addTagCRTail($this->buff)); - $this->buff = fgets($this->fd, 1024); - } - } - - function getTotalCount() { - return $this->index; - } - - function getKey() { - return $this->key; - } - - function _addTagCRTail($str) { - $str = preg_replace('/<\/([^>]*)>\r\n<", $str); - return $str; - } - } -?> +filename = $filename; + + $this->startTag = $startTag; + if($endTag) $this->endTag = $endTag; + $this->itemStartTag = $itemTag; + $this->itemEndTag = $itemEndTag; + + $this->key = md5($filename); + + $this->cache_path = './files/cache/importer/'.$this->key; + $this->cache_index_file = $this->cache_path.'/index'; + + if(!is_dir($this->cache_path)) FileHandler::makeDir($this->cache_path); + + return $this->openFile(); + } + + /** + * @brief 지정된 파일의 지시자를 염 + **/ + function openFile() { + FileHandler::removeFile($this->cache_index_file); + $this->index_fd = fopen($this->cache_index_file,"a"); + + // local 파일일 경우 + if(!preg_match('/^http:/i',$this->filename)) { + if(!file_exists($this->filename)) return new Object(-1,'msg_no_xml_file'); + $this->fd = fopen($this->filename,"r"); + + // remote 파일일 경우 + } else { + $url_info = parse_url($this->filename); + if(!$url_info['port']) $url_info['port'] = 80; + if(!$url_info['path']) $url_info['path'] = '/'; + + $this->fd = @fsockopen($url_info['host'], $url_info['port']); + if(!$this->fd) return new Object(-1,'msg_no_xml_file'); + + // 한글 파일이 있으면 한글파일 부분만 urlencode하여 처리 (iconv 필수) + $path = $url_info['path']; + if(preg_match('/[\xEA-\xED][\x80-\xFF]{2}/', $path)&&function_exists('iconv')) { + $path_list = explode('/',$path); + $cnt = count($path_list); + $filename = $path_list[$cnt-1]; + $filename = urlencode(iconv("UTF-8","EUC-KR",$filename)); + $path_list[$cnt-1] = $filename; + $path = implode('/',$path_list); + $url_info['path'] = $path; + } + + $header = sprintf("GET %s?%s HTTP/1.0\r\nHost: %s\r\nReferer: %s://%s\r\nConnection: Close\r\n\r\n", $url_info['path'], $url_info['query'], $url_info['host'], $url_info['scheme'], $url_info['host']); + @fwrite($this->fd, $header); + $buff = ''; + while(!feof($this->fd)) { + $buff .= $str = fgets($this->fd, 1024); + if(!trim($str)) break; + } + if(preg_match('/404 Not Found/i',$buff)) return new Object(-1,'msg_no_xml_file'); + } + + if($this->startTag) { + while(!feof($this->fd)) { + $str = fgets($this->fd, 1024); + $pos = strpos($str, $this->startTag); + if($pos !== false) { + $this->buff = substr($this->buff, $pos+strlen($this->startTag)); + $this->isStarted = true; + $this->isFinished = false; + break; + } + } + } else { + $this->isStarted = true; + $this->isFinished = false; + } + + return new Object(); + } + + function closeFile() { + $this->isFinished = true; + fclose($this->fd); + fclose($this->index_fd); + } + + function isFinished() { + return $this->isFinished || !$this->fd || feof($this->fd); + } + + function saveItems() { + $this->index = 0; + while(!$this->isFinished()) { + $this->getItem(); + } + } + + function mergeItems($filename) { + $this->saveItems(); + + $filename = sprintf('%s/%s', $this->cache_path, $filename); + + $index_fd = fopen($this->cache_index_file,"r"); + $fd = fopen($filename,'w'); + + fwrite($fd, ''); + while(!feof($index_fd)) { + $target_file = trim(fgets($index_fd,1024)); + if(!file_exists($target_file)) continue; + $buff = FileHandler::readFile($target_file); + fwrite($fd, FileHandler::readFile($target_file)); + + FileHandler::removeFile($target_file); + } + fwrite($fd, ''); + fclose($fd); + } + + function getItem() { + if($this->isFinished()) return; + + while(!feof($this->fd)) { + $startPos = strpos($this->buff, $this->itemStartTag); + if($startPos !== false) { + $this->buff = substr($this->buff, $startPos); + $this->buff = preg_replace("/\>/",">\r\n",$this->buff,1); + break; + } elseif($this->endTag) { + $endPos = strpos($this->buff, $this->endTag); + if($endPos !== false) { + $this->closeFile(); + return; + } + } + $this->buff .= fgets($this->fd, 1024); + } + + $startPos = strpos($this->buff, $this->itemStartTag); + if($startPos === false) { + $this->closeFile(); + return; + } + + $filename = sprintf('%s/%s.xml',$this->cache_path, $this->index++); + fwrite($this->index_fd, $filename."\r\n"); + + $fd = fopen($filename,'w'); + + while(!feof($this->fd)) { + $endPos = strpos($this->buff, $this->itemEndTag); + if($endPos !== false) { + $endPos += strlen($this->itemEndTag); + $buff = substr($this->buff, 0, $endPos); + fwrite($fd, $this->_addTagCRTail($buff)); + fclose($fd); + $this->buff = substr($this->buff, $endPos); + break; + } + + fwrite($fd, $this->_addTagCRTail($this->buff)); + $this->buff = fgets($this->fd, 1024); + } + } + + function getTotalCount() { + return $this->index; + } + + function getKey() { + return $this->key; + } + + function _addTagCRTail($str) { + $str = preg_replace('/<\/([^>]*)>\r\n<", $str); + return $str; + } + } +?> diff --git a/modules/importer/importer.admin.controller.php b/modules/importer/importer.admin.controller.php index 7d3b109ce..e006ab05c 100644 --- a/modules/importer/importer.admin.controller.php +++ b/modules/importer/importer.admin.controller.php @@ -1,971 +1,971 @@ -setMessage('msg_sync_completed'); - } - - /** - * @brief XML파일을 미리 분석하여 개발 단위로 캐싱 - **/ - function procImporterAdminPreProcessing() { - // 이전할 대상 xml파일을 구함 - $xml_file = Context::get('xml_file'); - - // 이전할 대상의 type을 구함 - $type = Context::get('type'); - - // xml파일에서 정해진 규칙으로 캐싱 - $oExtract = new extract(); - - switch($type) { - case 'member' : - $output = $oExtract->set($xml_file,'', '', ''); - if($output->toBool()) $oExtract->saveItems(); - break; - case 'message' : - $output = $oExtract->set($xml_file,'', '',''); - if($output->toBool()) $oExtract->saveItems(); - break; - case 'ttxml' : - // 카테고리 정보를 구함 - $output = $oExtract->set($xml_file, '', '', '', ''); - if ($output->toBool()) { - // ttxml 카테고리는 별도로 구함 - $started = false; - $buff = ''; - while (!feof($oExtract->fd)) { - $str = fgets($oExtract->fd, 1024); +setMessage('msg_sync_completed'); + } + + /** + * @brief XML파일을 미리 분석하여 개발 단위로 캐싱 + **/ + function procImporterAdminPreProcessing() { + // 이전할 대상 xml파일을 구함 + $xml_file = Context::get('xml_file'); + + // 이전할 대상의 type을 구함 + $type = Context::get('type'); + + // xml파일에서 정해진 규칙으로 캐싱 + $oExtract = new extract(); + + switch($type) { + case 'member' : + $output = $oExtract->set($xml_file,'', '', ''); + if($output->toBool()) $oExtract->saveItems(); + break; + case 'message' : + $output = $oExtract->set($xml_file,'', '',''); + if($output->toBool()) $oExtract->saveItems(); + break; + case 'ttxml' : + // 카테고리 정보를 구함 + $output = $oExtract->set($xml_file, '', '', '', ''); + if ($output->toBool()) { + // ttxml 카테고리는 별도로 구함 + $started = false; + $buff = ''; + while (!feof($oExtract->fd)) { + $str = fgets($oExtract->fd, 1024); if(strstr($str, '')) { $started = true; $str = strstr($str, ''); - } - if(substr($str,0,strlen(''; - $oExtract->closeFile(); - $category_filename = sprintf('%s/%s', $oExtract->cache_path, 'category.xml'); - FileHandler::writeFile($category_filename, $buff); - - - // 방명록 정보를 구함 - $output = $oExtract->set($xml_file, '', '', '', ''); - if ($output->toBool()) { - $started = false; - $buff = ''; - while (!feof($oExtract->fd)) { - $str = fgets($oExtract->fd, 1024); + } + if(substr($str,0,strlen(''; + $oExtract->closeFile(); + $category_filename = sprintf('%s/%s', $oExtract->cache_path, 'category.xml'); + FileHandler::writeFile($category_filename, $buff); + + + // 방명록 정보를 구함 + $output = $oExtract->set($xml_file, '', '', '', ''); + if ($output->toBool()) { + $started = false; + $buff = ''; + while (!feof($oExtract->fd)) { + $str = fgets($oExtract->fd, 1024); if(strstr($str, '')) { $started = true; $str = strstr($str, ''); - } - if ($started) { - $pos = strpos($str, ''); - if ($pos !== false) { - $buff .= substr($str, 0, $pos + strlen('')); - break; - } - $buff .= $str; - } - } - $oExtract->closeFile(); - $guestbook_filename = sprintf('%s/%s', $oExtract->cache_path, 'guestbook.xml'); - FileHandler::writeFile($guestbook_filename, $buff); - - // 개별 아이템 구함 - $output = $oExtract->set($xml_file,'', ''); - if($output->toBool()) $oExtract->saveItems(); - - } - } - break; - default : - // 카테고리 정보를 먼저 구함 - $output = $oExtract->set($xml_file,'', '', ''); - if($output->toBool()) { - $oExtract->mergeItems('category.xml'); - - // 개별 아이템 구함 - $output = $oExtract->set($xml_file,'', '', ''); - if($output->toBool()) $oExtract->saveItems(); - } - break; - - } - - if(!$output->toBool()) { - $this->add('error',0); - $this->add('status',-1); - $this->setMessage($output->getMessage()); - return; - } - - // extract가 종료됨을 알림 - $this->add('type',$type); - $this->add('total',$oExtract->getTotalCount()); - $this->add('cur',0); - $this->add('key', $oExtract->getKey()); - $this->add('status',0); - } - - /** - * @brief xml파일의 내용이 extract되고 난후 차례대로 마이그레이션 - **/ - function procImporterAdminImport() { - - // 변수 설정 - $type = Context::get('type'); - $total = Context::get('total'); - $cur = Context::get('cur'); - $key = Context::get('key'); - $user_id = Context::get('user_id'); - $target_module = Context::get('target_module'); - $guestbook_target_module = Context::get('guestbook_target_module'); - $this->unit_count = Context::get('unit_count'); - - - // index파일이 있는지 확인 - $index_file = './files/cache/importer/'.$key.'/index'; - if(!file_exists($index_file)) return new Object(-1, 'msg_invalid_xml_file'); - - switch($type) { - case 'ttxml' : - if(!$target_module) return new Object(-1,'msg_invalid_request'); - - $oModuleModel = &getModel('module'); - $target_module_info = $oModuleModel->getModuleInfoByModuleSrl($target_module); - - require_once('./modules/importer/ttimport.class.php'); - $oTT = new ttimport(); - $cur = $oTT->importModule($key, $cur, $index_file, $this->unit_count, $target_module, $guestbook_target_module, $user_id, $target_module_info->module); - break; - case 'message' : - $cur = $this->importMessage($key, $cur, $index_file); - break; - case 'member' : - $cur = $this->importMember($key, $cur, $index_file); - break; - case 'module' : - // 타켓 모듈의 유무 체크 - if(!$target_module) return new Object(-1,'msg_invalid_request'); - $cur = $this->importModule($key, $cur, $index_file, $target_module); - break; - } - - // extract가 종료됨을 알림 - $this->add('type',$type); - $this->add('total',$total); - $this->add('cur',$cur); - $this->add('key', $key); - $this->add('target_module', $target_module); - - // 모두 입력시 성공 메세지 출력하고 cache 파일제거 - if($total <= $cur) { - $this->setMessage( sprintf(Context::getLang('msg_import_finished'), $cur, $total) ); - FileHandler::removeFilesInDir('./files/cache/importer/'.$key); - } else $this->setMessage( sprintf(Context::getLang('msg_importing'), $total, $cur) ); - } - - /** - * @brief 회원 정보 입력 - **/ - function importMember($key, $cur, $index_file) { - if(!$cur) $cur = 0; - - // xmlParser객체 생성 - $oXmlParser = new XmlParser(); - - // 회원 입력을 위한 기본 객체들 생성 - $this->oMemberController = &getController('member'); - $this->oMemberModel = &getModel('member'); - - // 기본 회원 그룹을 구함 - $default_group = $this->oMemberModel->getDefaultGroup(); - $default_group_srl = $default_group->group_srl; - - // index파일을 염 - $f = fopen($index_file,"r"); - - // 이미 읽혀진 것은 패스 - for($i=0;$i<$cur;$i++) fgets($f, 1024); - - // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 - for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { - if(feof($f)) break; - - // 정해진 위치를 찾음 - $target_file = trim(fgets($f, 1024)); - - // 대상 파일을 읽여서 파싱후 입력 - $xmlObj = $oXmlParser->loadXmlFile($target_file); - FileHandler::removeFile($target_file); - if(!$xmlObj) continue; - - // 객체 정리 - $obj = null; - $obj->user_id = base64_decode($xmlObj->member->user_id->body); - $obj->password = base64_decode($xmlObj->member->password->body); - $obj->user_name = base64_decode($xmlObj->member->user_name->body); - $obj->nick_name = base64_decode($xmlObj->member->nick_name->body); - if(!$obj->user_name) $obj->user_name = $obj->nick_name; - $obj->email = base64_decode($xmlObj->member->email->body); - $obj->homepage = base64_decode($xmlObj->member->homepage->body); - $obj->blog = base64_decode($xmlObj->member->blog->body); - $obj->birthday = substr(base64_decode($xmlObj->member->birthday->body),0,8); - $obj->allow_mailing = base64_decode($xmlObj->member->allow_mailing->body); - $obj->point = base64_decode($xmlObj->member->point->body); - $obj->image_nickname = base64_decode($xmlObj->member->image_nickname->buff->body); - $obj->image_mark = base64_decode($xmlObj->member->image_mark->buff->body); - $obj->profile_image = base64_decode($xmlObj->member->profile_image->buff->body); - $obj->signature = base64_decode($xmlObj->member->signature->body); - $obj->regdate = base64_decode($xmlObj->member->regdate->body); - $obj->last_login = base64_decode($xmlObj->member->last_login->body); - - if($xmlObj->member->extra_vars) { - foreach($xmlObj->member->extra_vars as $key => $val) { - if(in_array($key, array('node_name','attrs','body'))) continue; - $obj->extra_vars->{$key} = base64_decode($val->body); - } - } - - // homepage, blog의 url을 정확히 만듬 - if($obj->homepage && !preg_match("/^http:\/\//i",$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - if($obj->blog && !preg_match("/^http:\/\//i",$obj->blog)) $obj->blog = 'http://'.$obj->blog; - - // email address 필드 정리 - $obj->email_address = $obj->email; - list($obj->email_id, $obj->email_host) = explode('@', $obj->email); - - // 메일링 허용 체크 - if($obj->allow_mailing!='Y') $obj->allow_mailing = 'N'; - - // 쪽지 수신 체크 - $obj->allow_message = 'Y'; - if(!in_array($obj->allow_message, array('Y','N','F'))) $obj->allow_message= 'Y'; - - // 최종 로그인 시간이 없으면 가입일을 입력 - if(!$obj->last_login) $obj->last_login = $obj->regdate; - - // 회원 번호를 구함 - $obj->member_srl = getNextSequence(); - - // 확장변수의 정리 - $extra_vars = $obj->extra_vars; - unset($obj->extra_vars); - $obj->extra_vars = serialize($extra_vars); - - // 중복되는 nick_name 데이터가 있는지 체크 - $nick_args = null; - $nick_args->nick_name = $obj->nick_name; - $nick_output = executeQuery('member.getMemberSrl', $nick_args); - if(!$nick_output->toBool()) $obj->nick_name .= '_'.$obj->member_srl; - - // 회원 추가 - $output = executeQuery('member.insertMember', $obj); - - // 입력 성공시 그룹 가입/ 이미지이름-마크-서명등을 추가 - if($output->toBool()) { - - // 기본 그룹 가입 시킴 - $obj->group_srl = $default_group_srl; - executeQuery('member.addMemberToGroup',$obj); - - // 이미지네임 - if($obj->image_nickname) { - $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($obj->member_srl)); - $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); - FileHandler::writeFile($target_filename, $obj->image_nickname); - } - - // 이미지마크 - if($obj->image_mark && file_exists($obj->image_mark)) { - $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($obj->member_srl)); - $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); - FileHandler::writeFile($target_filename, $obj->image_mark); - } - - // 프로필 이미지 - if($obj->profile_image) { - $target_path = sprintf('files/member_extra_info/profile_image/%s/', getNumberingPath($obj->member_srl)); - $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); - FileHandler::writeFile($target_filename, $obj->profile_image); - } - - // 서명 - if($obj->signature) { - $signature = removeHackTag($obj->signature); - $signature_buff = sprintf('%s', $signature); - - $target_path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($obj->member_srl)); - if(!is_dir($target_path)) FileHandler::makeDir($target_path); - $target_filename = sprintf('%s%d.signature.php', $target_path, $obj->member_srl); - - FileHandler::writeFile($target_filename, $signature_buff); - } - } - } - - fclose($f); - - return $idx-1; - } - - /** - * @brief 주어진 xml 파일을 파싱해서 쪽지 정보 입력 - **/ - function importMessage($key, $cur, $index_file) { - if(!$cur) $cur = 0; - - // xmlParser객체 생성 - $oXmlParser = new XmlParser(); - - // index파일을 염 - $f = fopen($index_file,"r"); - - // 이미 읽혀진 것은 패스 - for($i=0;$i<$cur;$i++) fgets($f, 1024); - - // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 - for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { - if(feof($f)) break; - - // 정해진 위치를 찾음 - $target_file = trim(fgets($f, 1024)); - - // 대상 파일을 읽여서 파싱후 입력 - $xmlObj = $oXmlParser->loadXmlFile($target_file); - FileHandler::removeFile($target_file); - if(!$xmlObj) continue; - - // 객체 정리 - $obj = null; - $obj->receiver = base64_decode($xmlObj->message->receiver->body); - $obj->sender = base64_decode($xmlObj->message->sender->body); - $obj->title = base64_decode($xmlObj->message->title->body); - $obj->content = base64_decode($xmlObj->message->content->body); - $obj->readed = base64_decode($xmlObj->message->readed->body)=='Y'?'Y':'N'; - $obj->regdate = base64_decode($xmlObj->message->regdate->body); - $obj->readed_date = base64_decode($xmlObj->message->readed_date->body); - $obj->receiver = base64_decode($xmlObj->message->receiver->body); - - // 보낸이/ 받는이의 member_srl을 구함 (존재하지 않으면 그냥 pass..) - if(!$obj->sender) continue; - $sender_args->user_id = $obj->sender; - $sender_output = executeQuery('member.getMemberInfo',$sender_args); - $sender_srl = $sender_output->data->member_srl; - if(!$sender_srl) continue; - - $receiver_args->user_id = $obj->receiver; - if(!$obj->receiver) continue; - $receiver_output = executeQuery('member.getMemberInfo',$receiver_args); - $receiver_srl = $receiver_output->data->member_srl; - if(!$receiver_srl) continue; - - // 보내는 사용자의 쪽지함에 넣을 쪽지 - $sender_args->sender_srl = $sender_srl; - $sender_args->receiver_srl = $receiver_srl; - $sender_args->message_type = 'S'; - $sender_args->title = $obj->title; - $sender_args->content = $obj->content; - $sender_args->readed = $obj->readed; - $sender_args->regdate = $obj->regdate; - $sender_args->readed_date = $obj->readed_date; - $sender_args->related_srl = getNextSequence(); - $sender_args->message_srl = getNextSequence(); - $sender_args->list_order = $sender_args->message_srl * -1; - - $output = executeQuery('communication.sendMessage', $sender_args); - if($output->toBool()) { - // 받는 회원의 쪽지함에 넣을 쪽지 - $receiver_args->message_srl = $sender_args->related_srl; - $receiver_args->list_order = $sender_args->related_srl*-1; - $receiver_args->sender_srl = $sender_srl; - if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl; - $receiver_args->receiver_srl = $receiver_srl; - $receiver_args->message_type = 'R'; - $receiver_args->title = $obj->title; - $receiver_args->content = $obj->content; - $receiver_args->readed = $obj->readed; - $receiver_args->regdate = $obj->regdate; - $receiver_args->readed_date = $obj->readed_date; - $output = executeQuery('communication.sendMessage', $receiver_args); - } - } - - fclose($f); - - return $idx-1; - } - - /** - * @brief module.xml 형식의 데이터 import - **/ - function importModule($key, $cur, $index_file, $module_srl) { - // 필요한 객체 미리 생성 - $this->oXmlParser = new XmlParser(); - - // 타겟 모듈의 카테고리 정보 구함 - $oDocumentController = &getController('document'); - $oDocumentModel = &getModel('document'); - $category_list = $category_titles = array(); - $category_list = $oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - - // 먼저 카테고리 정보를 입력함 - $category_file = preg_replace('/index$/i', 'category.xml', $index_file); - if(file_exists($category_file)) { - $buff = FileHandler::readFile($category_file); - - // xmlParser객체 생성 - $xmlDoc = $this->oXmlParser->loadXmlFile($category_file); - - $categories = $xmlDoc->items->category; - if($categories) { - if(!is_array($categories)) $categories = array($categories); - $match_sequence = array(); - foreach($categories as $k => $v) { - $category = trim(base64_decode($v->body)); - if(!$category || $category_titles[$category]) continue; - - $sequence = $v->attrs->sequence; - $parent = $v->attrs->parent; - - $obj = null; - $obj->title = $category; - $obj->module_srl = $module_srl; - if($parent) $obj->parent_srl = $match_sequence[$parent]; - - $output = $oDocumentController->insertCategory($obj); - if($output->toBool()) $match_sequence[$sequence] = $output->get('category_srl'); - } - $oDocumentController = &getController('document'); - $oDocumentController->makeCategoryFile($module_srl); - } - FileHandler::removeFile($category_file); - } - - $category_list = $category_titles = array(); - $category_list = $oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - - $ek_args->module_srl = $module_srl; - $output = executeQueryArray('document.getDocumentExtraKeys', $ek_args); - if($output->data) { - foreach($output->data as $key => $val) $extra_keys[$val->eid] = true; - } - - if(!$cur) $cur = 0; - - // index파일을 염 - $f = fopen($index_file,"r"); - - // 이미 읽혀진 것은 패스 - for($i=0;$i<$cur;$i++) fgets($f, 1024); - - // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 - for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { - if(feof($f)) break; - - // 정해진 위치를 찾음 - $target_file = trim(fgets($f, 1024)); - - if(!file_exists($target_file)) continue; - - // 이제부터 데이터를 가져오면서 처리 - $fp = fopen($target_file,"r"); - if(!$fp) continue; - - $obj = null; - $obj->module_srl = $module_srl; - $obj->document_srl = getNextSequence(); - - $files = array(); - $extra_vars = array(); - - $started = false; - $buff = null; - - // 본문 데이터부터 처리 시작 - while(!feof($fp)) { - $str = fgets($fp, 1024); - - // 한 아이템 준비 시작 - if(trim($str) == '') { - $started = true; - - // 엮인글 입력 - } else if(substr($str,0,11) == 'trackback_count = $this->importTrackbacks($fp, $module_srl, $obj->document_srl); - continue; - - // 댓글 입력 - } else if(substr($str,0,9) == 'comment_count = $this->importComments($fp, $module_srl, $obj->document_srl); - continue; - - // 첨부파일 입력 - } else if(substr($str,0,9) == 'uploaded_count = $this->importAttaches($fp, $module_srl, $obj->document_srl, $files); - continue; - - // 추가 변수 시작 일 경우 - } elseif(trim($str) == '') { - $extra_vars = $this->importExtraVars($fp); - continue; - } - - if($started) $buff .= $str; - } - - $xmlDoc = $this->oXmlParser->parse($buff); - - $category = base64_decode($xmlDoc->post->category->body); - if($category_titles[$category]) $obj->category_srl = $category_titles[$category]; - - $obj->member_srl = 0; - - $obj->is_notice = base64_decode($xmlDoc->post->is_notice->body)=='Y'?'Y':'N'; - $obj->is_secret = base64_decode($xmlDoc->post->is_secret->body)=='Y'?'Y':'N'; - $obj->title = base64_decode($xmlDoc->post->title->body); - $obj->content = base64_decode($xmlDoc->post->content->body); - $obj->readed_count = base64_decode($xmlDoc->post->readed_count->body); - $obj->voted_count = base64_decode($xmlDoc->post->voted_count->body); - $obj->password = base64_decode($xmlDoc->post->password->body); - $obj->user_name = $obj->nick_name = base64_decode($xmlDoc->post->nick_name->body); - $obj->user_id = base64_decode($xmlDoc->post->user_id->body); - $obj->email_address = base64_decode($xmlDoc->post->email->body); - $obj->homepage = base64_decode($xmlDoc->post->homepage->body); - if($obj->homepage && !preg_match('/^http:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - $obj->tags = base64_decode($xmlDoc->post->tags->body); - $obj->regdate = base64_decode($xmlDoc->post->regdate->body); - $obj->last_update = base64_decode($xmlDoc->post->update->body); - if(!$obj->last_update) $obj->last_update = $obj->regdate; - $obj->ipaddress = base64_decode($xmlDoc->post->ipaddress->body); - $obj->list_order = $obj->update_order = $obj->document_srl*-1; - $obj->allow_comment = base64_decode($xmlDoc->post->allow_comment->body)!='N'?'Y':'N'; - $obj->lock_comment = base64_decode($xmlDoc->post->lock_comment->body)=='Y'?'Y':'N'; - $obj->allow_trackback = base64_decode($xmlDoc->post->allow_trackback->body)!='N'?'Y':'N'; - $obj->notify_message = base64_decode($xmlDoc->post->is_notice->body); - - // content 정보 변경 (첨부파일) - if(count($files)) { - foreach($files as $key => $val) { - $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); - $obj->content = preg_replace('/(["\']?).\/files\/(.+)\/'.preg_quote($key).'([^"\']+)(["\']?)/i','"'.$val.'"',$obj->content); - $obj->content = preg_replace('/(["\']?)files\/(.+)\/'.preg_quote($key).'([^"\']+)(["\']?)/i','"'.$val.'"',$obj->content); - } - } - - $output = executeQuery('document.insertDocument', $obj); - - if($output->toBool() && $obj->tags) { - $tag_list = explode(',',$obj->tags); - $tag_count = count($tag_list); - for($i=0;$i<$tag_count;$i++) { - $args = null; - $args->tag_srl = getNextSequence(); - $args->module_srl = $module_srl; - $args->document_srl = $obj->document_srl; - $args->tag = trim($tag_list[$i]); - $args->regdate = $obj->regdate; - if(!$args->tag) continue; - $output = executeQuery('tag.insertTag', $args); - } - - } - - // 확장변수 추가 - if(count($extra_vars)) { - foreach($extra_vars as $key => $val) { - if(!$val->value) continue; - unset($e_args); - $e_args->module_srl = $module_srl; - $e_args->document_srl = $obj->document_srl; - $e_args->var_idx = $val->var_idx; - $e_args->value = $val->value; - $e_args->lang_code = $val->lang_code; - $e_args->eid = $val->eid; - - // 등록된 확장변수 키가 없으면 생성(제목/내용 언어별 변수는 제외) - if(!preg_match('/^(title|content)_(.+)$/i',$e_args->eid) && !$extra_keys[$e_args->eid]) { - unset($ek_args); - $ek_args->module_srl = $module_srl; - $ek_args->var_idx = $val->var_idx; - $ek_args->var_name = $val->eid; - $ek_args->var_type = 'text'; - $ek_args->var_is_required = 'N'; - $ek_args->var_default = ''; - $ek_args->eid = $val->eid; - $output = executeQuery('document.insertDocumentExtraKey', $ek_args); - $extra_keys[$ek_args->eid] = true; - } - - $output = executeQuery('document.insertDocumentExtraVar', $e_args); - } - } - - fclose($fp); - FileHandler::removeFile($target_file); - } - - fclose($f); - - // 카테고리별 개수 동기화 - if(count($category_list)) foreach($category_list as $key => $val) $oDocumentController->updateCategoryCount($module_srl, $val->category_srl); - - return $idx-1; - } - - /** - * @brief 엮인글 정리 - **/ - function importTrackbacks($fp, $module_srl, $document_srl) { - $started = false; - $buff = null; - $cnt = 0; - while(!feof($fp)) { - - $str = fgets($fp, 1024); - - // 이면 중단 - if(trim($str) == '') break; - - // 면 시작 - if(trim($str) == '') $started = true; - - if($started) $buff .= $str; - - // 이면 DB에 입력 - if(trim($str) == '') { - $xmlDoc = $this->oXmlParser->parse($buff); - - $obj = null; - $obj->trackback_srl = getNextSequence(); - $obj->module_srl = $module_srl; - $obj->document_srl = $document_srl; - $obj->url = base64_decode($xmlDoc->trackback->url->body); - $obj->title = base64_decode($xmlDoc->trackback->title->body); - $obj->blog_name = base64_decode($xmlDoc->trackback->blog_name->body); - $obj->excerpt = base64_decode($xmlDoc->trackback->excerpt->body); - $obj->regdate = base64_decode($xmlDoc->trackback->regdate->body); - $obj->ipaddress = base64_decode($xmlDoc->trackback->ipaddress->body); - $obj->list_order = -1*$obj->trackback_srl; - $output = executeQuery('trackback.insertTrackback', $obj); - if($output->toBool()) $cnt++; - - $buff = null; - $started = false; - } - } - return $cnt; - } - - /** - * @brief 댓글 정리 - **/ - function importComments($fp, $module_srl, $document_srl) { - $started = false; - $buff = null; - $cnt = 0; - - $sequences = array(); - - while(!feof($fp)) { - - $str = fgets($fp, 1024); - - // 이면 중단 - if(trim($str) == '') break; - - // 면 시작 - if(trim($str) == '') { - $started = true; - $obj = null; - $obj->comment_srl = getNextSequence(); - $files = array(); - } - - // attaches로 시작하면 첨부파일 시작 - if(substr($str,0,9) == 'uploaded_count = $this->importAttaches($fp, $module_srl, $obj->comment_srl, $files); - continue; - } - - if($started) $buff .= $str; - - // 이면 DB에 입력 - if(trim($str) == '') { - $xmlDoc = $this->oXmlParser->parse($buff); - - $sequence = base64_decode($xmlDoc->comment->sequence->body); - $sequences[$sequence] = $obj->comment_srl; - $parent = base64_decode($xmlDoc->comment->parent->body); - - $obj->module_srl = $module_srl; - - if($parent) $obj->parent_srl = $sequences[$parent]; - else $obj->parent_srl = 0; - - $obj->document_srl = $document_srl; - $obj->is_secret = base64_decode($xmlDoc->comment->is_secret->body)=='Y'?'Y':'N'; - $obj->notify_message = base64_decode($xmlDoc->comment->notify_message->body)=='Y'?'Y':'N'; - $obj->content = base64_decode($xmlDoc->comment->content->body); - $obj->voted_count = base64_decode($xmlDoc->comment->voted_count->body); - $obj->password = base64_decode($xmlDoc->comment->password->body); - $obj->user_name = $obj->nick_name = base64_decode($xmlDoc->comment->nick_name->body); - $obj->user_id = base64_decode($xmlDoc->comment->user_id->body); - $obj->member_srl = 0; - $obj->email_address = base64_decode($xmlDoc->comment->email->body); - $obj->homepage = base64_decode($xmlDoc->comment->homepage->body); - $obj->regdate = base64_decode($xmlDoc->comment->regdate->body); - $obj->last_update = base64_decode($xmlDoc->comment->update->body); - if(!$obj->last_update) $obj->last_update = $obj->regdate; - $obj->ipaddress = base64_decode($xmlDoc->comment->ipaddress->body); - $obj->list_order = $obj->comment_srl*-1; - - // content 정보 변경 (첨부파일) - if(count($files)) { - foreach($files as $key => $val) { - $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); - } - } - - // 댓글 목록 부분을 먼저 입력 - $list_args = null; - $list_args->comment_srl = $obj->comment_srl; - $list_args->document_srl = $obj->document_srl; - $list_args->module_srl = $obj->module_srl; - $list_args->regdate = $obj->regdate; - - // 부모댓글이 없으면 바로 데이터를 설정 - if(!$obj->parent_srl) { - $list_args->head = $list_args->arrange = $obj->comment_srl; - $list_args->depth = 0; - - // 부모댓글이 있으면 부모글의 정보를 구해옴 - } else { - // 부모댓글의 정보를 구함 - $parent_args->comment_srl = $obj->parent_srl; - $parent_output = executeQuery('comment.getCommentListItem', $parent_args); - - // 부모댓글이 존재하지 않으면 return - if(!$parent_output->toBool() || !$parent_output->data) continue; - $parent = $parent_output->data; - - $list_args->head = $parent->head; - $list_args->depth = $parent->depth+1; - if($list_args->depth<2) $list_args->arrange = $obj->comment_srl; - else { - $list_args->arrange = $parent->arrange; - $output = executeQuery('comment.updateCommentListArrange', $list_args); - if(!$output->toBool()) return $output; - } - } - - $output = executeQuery('comment.insertCommentList', $list_args); - if($output->toBool()) { - $output = executeQuery('comment.insertComment', $obj); - if($output->toBool()) $cnt++; - } - - $buff = null; - $started = false; - } - } - return $cnt; - } - - /** - * @brief 첨부파일 정리 - **/ - function importAttaches($fp, $module_srl, $upload_target_srl, &$files) { - $uploaded_count = 0; - - $started = false; - $buff = null; - - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - - // 로 끝나면 중단 - if(trim($str) == '') break; - - // 로 시작하면 첨부파일 수집 - if(trim($str) == '') { - $file_obj = null; - $file_obj->file_srl = getNextSequence(); - $file_obj->upload_target_srl = $upload_target_srl; - $file_obj->module_srl = $module_srl; - - $started = true; - $buff = null; - // 로 시작하면 xml파일내의 첨부파일로 처리 - } else if(trim($str) == '') { - $file_obj->file = $this->saveTemporaryFile($fp); - continue; - } - - if($started) $buff .= $str; - - // 로 끝나면 첨부파일 정리 - if(trim($str) == '') { - $xmlDoc = $this->oXmlParser->parse($buff.$str); - - $file_obj->source_filename = base64_decode($xmlDoc->attach->filename->body); - $file_obj->download_count = base64_decode($xmlDoc->attach->download_count->body); - - if(!$file_obj->file) { - $url = base64_decode($xmlDoc->attach->url->body); - $path = base64_decode($xmlDoc->attach->path->body); - if($path && file_exists($path)) $file_obj->file = $path; - else { - $file_obj->file = $this->getTmpFilename(); - FileHandler::getRemoteFile($url, $file_obj->file); - } - } - - if(file_exists($file_obj->file)) { - - // 이미지인지 기타 파일인지 체크하여 upload path 지정 - if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_obj->source_filename)) { - $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3)); - $filename = $path.$file_obj->source_filename; - $file_obj->direct_download = 'Y'; - } else { - $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); - $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); - $file_obj->direct_download = 'N'; - } - - // 디렉토리 생성 - if(!FileHandler::makeDir($path)) continue; - - if(preg_match('/^\.\/files\/cache\/importer/i',$file_obj->file)) FileHandler::rename($file_obj->file, $filename); - else @copy($file_obj->file, $filename); - - // DB입력 - unset($file_obj->file); - if(file_exists($filename)) { - $file_obj->uploaded_filename = $filename; - $file_obj->file_size = filesize($filename); - $file_obj->comment = NULL; - $file_obj->member_srl = 0; - $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); - $file_obj->isvalid = 'Y'; - $output = executeQuery('file.insertFile', $file_obj); - - if($output->toBool()) { - $uploaded_count++; - $tmp_obj = null; - $tmp_obj->source_filename = $file_obj->source_filename; - if($file_obj->direct_download == 'Y') $files[$file_obj->source_filename] = $file_obj->uploaded_filename; - else $files[$file_obj->source_filename] = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid); - } - } - } - } - } - return $uploaded_count; - } - - /** - * @biref 임의로 사용할 파일이름을 return - **/ - function getTmpFilename() { - $path = "./files/cache/importer"; - if(!is_dir($path)) FileHandler::makeDir($path); - $filename = sprintf("%s/%d", $path, rand(11111111,99999999)); - if(file_exists($filename)) $filename .= rand(111,999); - return $filename; - } - - /** - * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 - **/ - function saveTemporaryFile($fp) { - $temp_filename = $this->getTmpFilename(); - $f = fopen($temp_filename, "w"); - - $buff = ''; - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - if(trim($str) == '') break; - - $buff .= $str; - - if(substr($buff,-7)=='') { - fwrite($f, base64_decode(substr($buff, 6, -7))); - $buff = ''; - } - } - fclose($f); - return $temp_filename; - } - - - /** - * @brief 게시글 추가 변수 설정 - **/ - function importExtraVars($fp) { - $buff = null; - while(!feof($fp)) { - $buff .= $str = trim(fgets($fp, 1024)); - if(trim($str) == '') break; - } - if(!$buff) return array(); - - $buff = ''.$buff; - $oXmlParser = new XmlParser(); - $xmlDoc = $this->oXmlParser->parse($buff); - if(!count($xmlDoc->extra_vars->key)) return array(); - - $index = 1; - foreach($xmlDoc->extra_vars->key as $k => $v) { - unset($vobj); - if($v->var_idx) { - $vobj->var_idx = base64_decode($v->var_idx->body); - $vobj->lang_code = base64_decode($v->lang_code->body); - $vobj->value = base64_decode($v->value->body); - $vobj->eid = base64_decode($v->eid->body); - - } else if($v->body) { - $vobj->var_idx = $index; - $vobj->lang_code = Context::getLangType(); - $vobj->value = base64_decode($v->body); - $vobj->eid = 'extra_vars'.$index; - } - $extra_vars["extra_vars".$index] = $vobj; - $index++; - } - return $extra_vars; - } - } -?> + } + if ($started) { + $pos = strpos($str, ''); + if ($pos !== false) { + $buff .= substr($str, 0, $pos + strlen('')); + break; + } + $buff .= $str; + } + } + $oExtract->closeFile(); + $guestbook_filename = sprintf('%s/%s', $oExtract->cache_path, 'guestbook.xml'); + FileHandler::writeFile($guestbook_filename, $buff); + + // 개별 아이템 구함 + $output = $oExtract->set($xml_file,'', ''); + if($output->toBool()) $oExtract->saveItems(); + + } + } + break; + default : + // 카테고리 정보를 먼저 구함 + $output = $oExtract->set($xml_file,'', '', ''); + if($output->toBool()) { + $oExtract->mergeItems('category.xml'); + + // 개별 아이템 구함 + $output = $oExtract->set($xml_file,'', '', ''); + if($output->toBool()) $oExtract->saveItems(); + } + break; + + } + + if(!$output->toBool()) { + $this->add('error',0); + $this->add('status',-1); + $this->setMessage($output->getMessage()); + return; + } + + // extract가 종료됨을 알림 + $this->add('type',$type); + $this->add('total',$oExtract->getTotalCount()); + $this->add('cur',0); + $this->add('key', $oExtract->getKey()); + $this->add('status',0); + } + + /** + * @brief xml파일의 내용이 extract되고 난후 차례대로 마이그레이션 + **/ + function procImporterAdminImport() { + + // 변수 설정 + $type = Context::get('type'); + $total = Context::get('total'); + $cur = Context::get('cur'); + $key = Context::get('key'); + $user_id = Context::get('user_id'); + $target_module = Context::get('target_module'); + $guestbook_target_module = Context::get('guestbook_target_module'); + $this->unit_count = Context::get('unit_count'); + + + // index파일이 있는지 확인 + $index_file = './files/cache/importer/'.$key.'/index'; + if(!file_exists($index_file)) return new Object(-1, 'msg_invalid_xml_file'); + + switch($type) { + case 'ttxml' : + if(!$target_module) return new Object(-1,'msg_invalid_request'); + + $oModuleModel = &getModel('module'); + $target_module_info = $oModuleModel->getModuleInfoByModuleSrl($target_module); + + require_once('./modules/importer/ttimport.class.php'); + $oTT = new ttimport(); + $cur = $oTT->importModule($key, $cur, $index_file, $this->unit_count, $target_module, $guestbook_target_module, $user_id, $target_module_info->module); + break; + case 'message' : + $cur = $this->importMessage($key, $cur, $index_file); + break; + case 'member' : + $cur = $this->importMember($key, $cur, $index_file); + break; + case 'module' : + // 타켓 모듈의 유무 체크 + if(!$target_module) return new Object(-1,'msg_invalid_request'); + $cur = $this->importModule($key, $cur, $index_file, $target_module); + break; + } + + // extract가 종료됨을 알림 + $this->add('type',$type); + $this->add('total',$total); + $this->add('cur',$cur); + $this->add('key', $key); + $this->add('target_module', $target_module); + + // 모두 입력시 성공 메세지 출력하고 cache 파일제거 + if($total <= $cur) { + $this->setMessage( sprintf(Context::getLang('msg_import_finished'), $cur, $total) ); + FileHandler::removeFilesInDir('./files/cache/importer/'.$key); + } else $this->setMessage( sprintf(Context::getLang('msg_importing'), $total, $cur) ); + } + + /** + * @brief 회원 정보 입력 + **/ + function importMember($key, $cur, $index_file) { + if(!$cur) $cur = 0; + + // xmlParser객체 생성 + $oXmlParser = new XmlParser(); + + // 회원 입력을 위한 기본 객체들 생성 + $this->oMemberController = &getController('member'); + $this->oMemberModel = &getModel('member'); + + // 기본 회원 그룹을 구함 + $default_group = $this->oMemberModel->getDefaultGroup(); + $default_group_srl = $default_group->group_srl; + + // index파일을 염 + $f = fopen($index_file,"r"); + + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); + + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { + if(feof($f)) break; + + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); + + // 대상 파일을 읽여서 파싱후 입력 + $xmlObj = $oXmlParser->loadXmlFile($target_file); + FileHandler::removeFile($target_file); + if(!$xmlObj) continue; + + // 객체 정리 + $obj = null; + $obj->user_id = base64_decode($xmlObj->member->user_id->body); + $obj->password = base64_decode($xmlObj->member->password->body); + $obj->user_name = base64_decode($xmlObj->member->user_name->body); + $obj->nick_name = base64_decode($xmlObj->member->nick_name->body); + if(!$obj->user_name) $obj->user_name = $obj->nick_name; + $obj->email = base64_decode($xmlObj->member->email->body); + $obj->homepage = base64_decode($xmlObj->member->homepage->body); + $obj->blog = base64_decode($xmlObj->member->blog->body); + $obj->birthday = substr(base64_decode($xmlObj->member->birthday->body),0,8); + $obj->allow_mailing = base64_decode($xmlObj->member->allow_mailing->body); + $obj->point = base64_decode($xmlObj->member->point->body); + $obj->image_nickname = base64_decode($xmlObj->member->image_nickname->buff->body); + $obj->image_mark = base64_decode($xmlObj->member->image_mark->buff->body); + $obj->profile_image = base64_decode($xmlObj->member->profile_image->buff->body); + $obj->signature = base64_decode($xmlObj->member->signature->body); + $obj->regdate = base64_decode($xmlObj->member->regdate->body); + $obj->last_login = base64_decode($xmlObj->member->last_login->body); + + if($xmlObj->member->extra_vars) { + foreach($xmlObj->member->extra_vars as $key => $val) { + if(in_array($key, array('node_name','attrs','body'))) continue; + $obj->extra_vars->{$key} = base64_decode($val->body); + } + } + + // homepage, blog의 url을 정확히 만듬 + if($obj->homepage && !preg_match("/^http:\/\//i",$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + if($obj->blog && !preg_match("/^http:\/\//i",$obj->blog)) $obj->blog = 'http://'.$obj->blog; + + // email address 필드 정리 + $obj->email_address = $obj->email; + list($obj->email_id, $obj->email_host) = explode('@', $obj->email); + + // 메일링 허용 체크 + if($obj->allow_mailing!='Y') $obj->allow_mailing = 'N'; + + // 쪽지 수신 체크 + $obj->allow_message = 'Y'; + if(!in_array($obj->allow_message, array('Y','N','F'))) $obj->allow_message= 'Y'; + + // 최종 로그인 시간이 없으면 가입일을 입력 + if(!$obj->last_login) $obj->last_login = $obj->regdate; + + // 회원 번호를 구함 + $obj->member_srl = getNextSequence(); + + // 확장변수의 정리 + $extra_vars = $obj->extra_vars; + unset($obj->extra_vars); + $obj->extra_vars = serialize($extra_vars); + + // 중복되는 nick_name 데이터가 있는지 체크 + $nick_args = null; + $nick_args->nick_name = $obj->nick_name; + $nick_output = executeQuery('member.getMemberSrl', $nick_args); + if(!$nick_output->toBool()) $obj->nick_name .= '_'.$obj->member_srl; + + // 회원 추가 + $output = executeQuery('member.insertMember', $obj); + + // 입력 성공시 그룹 가입/ 이미지이름-마크-서명등을 추가 + if($output->toBool()) { + + // 기본 그룹 가입 시킴 + $obj->group_srl = $default_group_srl; + executeQuery('member.addMemberToGroup',$obj); + + // 이미지네임 + if($obj->image_nickname) { + $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($obj->member_srl)); + $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); + FileHandler::writeFile($target_filename, $obj->image_nickname); + } + + // 이미지마크 + if($obj->image_mark && file_exists($obj->image_mark)) { + $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($obj->member_srl)); + $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); + FileHandler::writeFile($target_filename, $obj->image_mark); + } + + // 프로필 이미지 + if($obj->profile_image) { + $target_path = sprintf('files/member_extra_info/profile_image/%s/', getNumberingPath($obj->member_srl)); + $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); + FileHandler::writeFile($target_filename, $obj->profile_image); + } + + // 서명 + if($obj->signature) { + $signature = removeHackTag($obj->signature); + $signature_buff = sprintf('%s', $signature); + + $target_path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($obj->member_srl)); + if(!is_dir($target_path)) FileHandler::makeDir($target_path); + $target_filename = sprintf('%s%d.signature.php', $target_path, $obj->member_srl); + + FileHandler::writeFile($target_filename, $signature_buff); + } + } + } + + fclose($f); + + return $idx-1; + } + + /** + * @brief 주어진 xml 파일을 파싱해서 쪽지 정보 입력 + **/ + function importMessage($key, $cur, $index_file) { + if(!$cur) $cur = 0; + + // xmlParser객체 생성 + $oXmlParser = new XmlParser(); + + // index파일을 염 + $f = fopen($index_file,"r"); + + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); + + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { + if(feof($f)) break; + + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); + + // 대상 파일을 읽여서 파싱후 입력 + $xmlObj = $oXmlParser->loadXmlFile($target_file); + FileHandler::removeFile($target_file); + if(!$xmlObj) continue; + + // 객체 정리 + $obj = null; + $obj->receiver = base64_decode($xmlObj->message->receiver->body); + $obj->sender = base64_decode($xmlObj->message->sender->body); + $obj->title = base64_decode($xmlObj->message->title->body); + $obj->content = base64_decode($xmlObj->message->content->body); + $obj->readed = base64_decode($xmlObj->message->readed->body)=='Y'?'Y':'N'; + $obj->regdate = base64_decode($xmlObj->message->regdate->body); + $obj->readed_date = base64_decode($xmlObj->message->readed_date->body); + $obj->receiver = base64_decode($xmlObj->message->receiver->body); + + // 보낸이/ 받는이의 member_srl을 구함 (존재하지 않으면 그냥 pass..) + if(!$obj->sender) continue; + $sender_args->user_id = $obj->sender; + $sender_output = executeQuery('member.getMemberInfo',$sender_args); + $sender_srl = $sender_output->data->member_srl; + if(!$sender_srl) continue; + + $receiver_args->user_id = $obj->receiver; + if(!$obj->receiver) continue; + $receiver_output = executeQuery('member.getMemberInfo',$receiver_args); + $receiver_srl = $receiver_output->data->member_srl; + if(!$receiver_srl) continue; + + // 보내는 사용자의 쪽지함에 넣을 쪽지 + $sender_args->sender_srl = $sender_srl; + $sender_args->receiver_srl = $receiver_srl; + $sender_args->message_type = 'S'; + $sender_args->title = $obj->title; + $sender_args->content = $obj->content; + $sender_args->readed = $obj->readed; + $sender_args->regdate = $obj->regdate; + $sender_args->readed_date = $obj->readed_date; + $sender_args->related_srl = getNextSequence(); + $sender_args->message_srl = getNextSequence(); + $sender_args->list_order = $sender_args->message_srl * -1; + + $output = executeQuery('communication.sendMessage', $sender_args); + if($output->toBool()) { + // 받는 회원의 쪽지함에 넣을 쪽지 + $receiver_args->message_srl = $sender_args->related_srl; + $receiver_args->list_order = $sender_args->related_srl*-1; + $receiver_args->sender_srl = $sender_srl; + if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl; + $receiver_args->receiver_srl = $receiver_srl; + $receiver_args->message_type = 'R'; + $receiver_args->title = $obj->title; + $receiver_args->content = $obj->content; + $receiver_args->readed = $obj->readed; + $receiver_args->regdate = $obj->regdate; + $receiver_args->readed_date = $obj->readed_date; + $output = executeQuery('communication.sendMessage', $receiver_args); + } + } + + fclose($f); + + return $idx-1; + } + + /** + * @brief module.xml 형식의 데이터 import + **/ + function importModule($key, $cur, $index_file, $module_srl) { + // 필요한 객체 미리 생성 + $this->oXmlParser = new XmlParser(); + + // 타겟 모듈의 카테고리 정보 구함 + $oDocumentController = &getController('document'); + $oDocumentModel = &getModel('document'); + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + // 먼저 카테고리 정보를 입력함 + $category_file = preg_replace('/index$/i', 'category.xml', $index_file); + if(file_exists($category_file)) { + $buff = FileHandler::readFile($category_file); + + // xmlParser객체 생성 + $xmlDoc = $this->oXmlParser->loadXmlFile($category_file); + + $categories = $xmlDoc->items->category; + if($categories) { + if(!is_array($categories)) $categories = array($categories); + $match_sequence = array(); + foreach($categories as $k => $v) { + $category = trim(base64_decode($v->body)); + if(!$category || $category_titles[$category]) continue; + + $sequence = $v->attrs->sequence; + $parent = $v->attrs->parent; + + $obj = null; + $obj->title = $category; + $obj->module_srl = $module_srl; + if($parent) $obj->parent_srl = $match_sequence[$parent]; + + $output = $oDocumentController->insertCategory($obj); + if($output->toBool()) $match_sequence[$sequence] = $output->get('category_srl'); + } + $oDocumentController = &getController('document'); + $oDocumentController->makeCategoryFile($module_srl); + } + FileHandler::removeFile($category_file); + } + + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + $ek_args->module_srl = $module_srl; + $output = executeQueryArray('document.getDocumentExtraKeys', $ek_args); + if($output->data) { + foreach($output->data as $key => $val) $extra_keys[$val->eid] = true; + } + + if(!$cur) $cur = 0; + + // index파일을 염 + $f = fopen($index_file,"r"); + + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); + + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { + if(feof($f)) break; + + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); + + if(!file_exists($target_file)) continue; + + // 이제부터 데이터를 가져오면서 처리 + $fp = fopen($target_file,"r"); + if(!$fp) continue; + + $obj = null; + $obj->module_srl = $module_srl; + $obj->document_srl = getNextSequence(); + + $files = array(); + $extra_vars = array(); + + $started = false; + $buff = null; + + // 본문 데이터부터 처리 시작 + while(!feof($fp)) { + $str = fgets($fp, 1024); + + // 한 아이템 준비 시작 + if(trim($str) == '') { + $started = true; + + // 엮인글 입력 + } else if(substr($str,0,11) == 'trackback_count = $this->importTrackbacks($fp, $module_srl, $obj->document_srl); + continue; + + // 댓글 입력 + } else if(substr($str,0,9) == 'comment_count = $this->importComments($fp, $module_srl, $obj->document_srl); + continue; + + // 첨부파일 입력 + } else if(substr($str,0,9) == 'uploaded_count = $this->importAttaches($fp, $module_srl, $obj->document_srl, $files); + continue; + + // 추가 변수 시작 일 경우 + } elseif(trim($str) == '') { + $extra_vars = $this->importExtraVars($fp); + continue; + } + + if($started) $buff .= $str; + } + + $xmlDoc = $this->oXmlParser->parse($buff); + + $category = base64_decode($xmlDoc->post->category->body); + if($category_titles[$category]) $obj->category_srl = $category_titles[$category]; + + $obj->member_srl = 0; + + $obj->is_notice = base64_decode($xmlDoc->post->is_notice->body)=='Y'?'Y':'N'; + $obj->is_secret = base64_decode($xmlDoc->post->is_secret->body)=='Y'?'Y':'N'; + $obj->title = base64_decode($xmlDoc->post->title->body); + $obj->content = base64_decode($xmlDoc->post->content->body); + $obj->readed_count = base64_decode($xmlDoc->post->readed_count->body); + $obj->voted_count = base64_decode($xmlDoc->post->voted_count->body); + $obj->password = base64_decode($xmlDoc->post->password->body); + $obj->user_name = $obj->nick_name = base64_decode($xmlDoc->post->nick_name->body); + $obj->user_id = base64_decode($xmlDoc->post->user_id->body); + $obj->email_address = base64_decode($xmlDoc->post->email->body); + $obj->homepage = base64_decode($xmlDoc->post->homepage->body); + if($obj->homepage && !preg_match('/^http:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + $obj->tags = base64_decode($xmlDoc->post->tags->body); + $obj->regdate = base64_decode($xmlDoc->post->regdate->body); + $obj->last_update = base64_decode($xmlDoc->post->update->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + $obj->ipaddress = base64_decode($xmlDoc->post->ipaddress->body); + $obj->list_order = $obj->update_order = $obj->document_srl*-1; + $obj->allow_comment = base64_decode($xmlDoc->post->allow_comment->body)!='N'?'Y':'N'; + $obj->lock_comment = base64_decode($xmlDoc->post->lock_comment->body)=='Y'?'Y':'N'; + $obj->allow_trackback = base64_decode($xmlDoc->post->allow_trackback->body)!='N'?'Y':'N'; + $obj->notify_message = base64_decode($xmlDoc->post->is_notice->body); + + // content 정보 변경 (첨부파일) + if(count($files)) { + foreach($files as $key => $val) { + $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); + $obj->content = preg_replace('/(["\']?).\/files\/(.+)\/'.preg_quote($key).'([^"\']+)(["\']?)/i','"'.$val.'"',$obj->content); + $obj->content = preg_replace('/(["\']?)files\/(.+)\/'.preg_quote($key).'([^"\']+)(["\']?)/i','"'.$val.'"',$obj->content); + } + } + + $output = executeQuery('document.insertDocument', $obj); + + if($output->toBool() && $obj->tags) { + $tag_list = explode(',',$obj->tags); + $tag_count = count($tag_list); + for($i=0;$i<$tag_count;$i++) { + $args = null; + $args->tag_srl = getNextSequence(); + $args->module_srl = $module_srl; + $args->document_srl = $obj->document_srl; + $args->tag = trim($tag_list[$i]); + $args->regdate = $obj->regdate; + if(!$args->tag) continue; + $output = executeQuery('tag.insertTag', $args); + } + + } + + // 확장변수 추가 + if(count($extra_vars)) { + foreach($extra_vars as $key => $val) { + if(!$val->value) continue; + unset($e_args); + $e_args->module_srl = $module_srl; + $e_args->document_srl = $obj->document_srl; + $e_args->var_idx = $val->var_idx; + $e_args->value = $val->value; + $e_args->lang_code = $val->lang_code; + $e_args->eid = $val->eid; + + // 등록된 확장변수 키가 없으면 생성(제목/내용 언어별 변수는 제외) + if(!preg_match('/^(title|content)_(.+)$/i',$e_args->eid) && !$extra_keys[$e_args->eid]) { + unset($ek_args); + $ek_args->module_srl = $module_srl; + $ek_args->var_idx = $val->var_idx; + $ek_args->var_name = $val->eid; + $ek_args->var_type = 'text'; + $ek_args->var_is_required = 'N'; + $ek_args->var_default = ''; + $ek_args->eid = $val->eid; + $output = executeQuery('document.insertDocumentExtraKey', $ek_args); + $extra_keys[$ek_args->eid] = true; + } + + $output = executeQuery('document.insertDocumentExtraVar', $e_args); + } + } + + fclose($fp); + FileHandler::removeFile($target_file); + } + + fclose($f); + + // 카테고리별 개수 동기화 + if(count($category_list)) foreach($category_list as $key => $val) $oDocumentController->updateCategoryCount($module_srl, $val->category_srl); + + return $idx-1; + } + + /** + * @brief 엮인글 정리 + **/ + function importTrackbacks($fp, $module_srl, $document_srl) { + $started = false; + $buff = null; + $cnt = 0; + while(!feof($fp)) { + + $str = fgets($fp, 1024); + + // 이면 중단 + if(trim($str) == '') break; + + // 면 시작 + if(trim($str) == '') $started = true; + + if($started) $buff .= $str; + + // 이면 DB에 입력 + if(trim($str) == '') { + $xmlDoc = $this->oXmlParser->parse($buff); + + $obj = null; + $obj->trackback_srl = getNextSequence(); + $obj->module_srl = $module_srl; + $obj->document_srl = $document_srl; + $obj->url = base64_decode($xmlDoc->trackback->url->body); + $obj->title = base64_decode($xmlDoc->trackback->title->body); + $obj->blog_name = base64_decode($xmlDoc->trackback->blog_name->body); + $obj->excerpt = base64_decode($xmlDoc->trackback->excerpt->body); + $obj->regdate = base64_decode($xmlDoc->trackback->regdate->body); + $obj->ipaddress = base64_decode($xmlDoc->trackback->ipaddress->body); + $obj->list_order = -1*$obj->trackback_srl; + $output = executeQuery('trackback.insertTrackback', $obj); + if($output->toBool()) $cnt++; + + $buff = null; + $started = false; + } + } + return $cnt; + } + + /** + * @brief 댓글 정리 + **/ + function importComments($fp, $module_srl, $document_srl) { + $started = false; + $buff = null; + $cnt = 0; + + $sequences = array(); + + while(!feof($fp)) { + + $str = fgets($fp, 1024); + + // 이면 중단 + if(trim($str) == '') break; + + // 면 시작 + if(trim($str) == '') { + $started = true; + $obj = null; + $obj->comment_srl = getNextSequence(); + $files = array(); + } + + // attaches로 시작하면 첨부파일 시작 + if(substr($str,0,9) == 'uploaded_count = $this->importAttaches($fp, $module_srl, $obj->comment_srl, $files); + continue; + } + + if($started) $buff .= $str; + + // 이면 DB에 입력 + if(trim($str) == '') { + $xmlDoc = $this->oXmlParser->parse($buff); + + $sequence = base64_decode($xmlDoc->comment->sequence->body); + $sequences[$sequence] = $obj->comment_srl; + $parent = base64_decode($xmlDoc->comment->parent->body); + + $obj->module_srl = $module_srl; + + if($parent) $obj->parent_srl = $sequences[$parent]; + else $obj->parent_srl = 0; + + $obj->document_srl = $document_srl; + $obj->is_secret = base64_decode($xmlDoc->comment->is_secret->body)=='Y'?'Y':'N'; + $obj->notify_message = base64_decode($xmlDoc->comment->notify_message->body)=='Y'?'Y':'N'; + $obj->content = base64_decode($xmlDoc->comment->content->body); + $obj->voted_count = base64_decode($xmlDoc->comment->voted_count->body); + $obj->password = base64_decode($xmlDoc->comment->password->body); + $obj->user_name = $obj->nick_name = base64_decode($xmlDoc->comment->nick_name->body); + $obj->user_id = base64_decode($xmlDoc->comment->user_id->body); + $obj->member_srl = 0; + $obj->email_address = base64_decode($xmlDoc->comment->email->body); + $obj->homepage = base64_decode($xmlDoc->comment->homepage->body); + $obj->regdate = base64_decode($xmlDoc->comment->regdate->body); + $obj->last_update = base64_decode($xmlDoc->comment->update->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + $obj->ipaddress = base64_decode($xmlDoc->comment->ipaddress->body); + $obj->list_order = $obj->comment_srl*-1; + + // content 정보 변경 (첨부파일) + if(count($files)) { + foreach($files as $key => $val) { + $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); + } + } + + // 댓글 목록 부분을 먼저 입력 + $list_args = null; + $list_args->comment_srl = $obj->comment_srl; + $list_args->document_srl = $obj->document_srl; + $list_args->module_srl = $obj->module_srl; + $list_args->regdate = $obj->regdate; + + // 부모댓글이 없으면 바로 데이터를 설정 + if(!$obj->parent_srl) { + $list_args->head = $list_args->arrange = $obj->comment_srl; + $list_args->depth = 0; + + // 부모댓글이 있으면 부모글의 정보를 구해옴 + } else { + // 부모댓글의 정보를 구함 + $parent_args->comment_srl = $obj->parent_srl; + $parent_output = executeQuery('comment.getCommentListItem', $parent_args); + + // 부모댓글이 존재하지 않으면 return + if(!$parent_output->toBool() || !$parent_output->data) continue; + $parent = $parent_output->data; + + $list_args->head = $parent->head; + $list_args->depth = $parent->depth+1; + if($list_args->depth<2) $list_args->arrange = $obj->comment_srl; + else { + $list_args->arrange = $parent->arrange; + $output = executeQuery('comment.updateCommentListArrange', $list_args); + if(!$output->toBool()) return $output; + } + } + + $output = executeQuery('comment.insertCommentList', $list_args); + if($output->toBool()) { + $output = executeQuery('comment.insertComment', $obj); + if($output->toBool()) $cnt++; + } + + $buff = null; + $started = false; + } + } + return $cnt; + } + + /** + * @brief 첨부파일 정리 + **/ + function importAttaches($fp, $module_srl, $upload_target_srl, &$files) { + $uploaded_count = 0; + + $started = false; + $buff = null; + + while(!feof($fp)) { + $str = trim(fgets($fp, 1024)); + + // 로 끝나면 중단 + if(trim($str) == '') break; + + // 로 시작하면 첨부파일 수집 + if(trim($str) == '') { + $file_obj = null; + $file_obj->file_srl = getNextSequence(); + $file_obj->upload_target_srl = $upload_target_srl; + $file_obj->module_srl = $module_srl; + + $started = true; + $buff = null; + // 로 시작하면 xml파일내의 첨부파일로 처리 + } else if(trim($str) == '') { + $file_obj->file = $this->saveTemporaryFile($fp); + continue; + } + + if($started) $buff .= $str; + + // 로 끝나면 첨부파일 정리 + if(trim($str) == '') { + $xmlDoc = $this->oXmlParser->parse($buff.$str); + + $file_obj->source_filename = base64_decode($xmlDoc->attach->filename->body); + $file_obj->download_count = base64_decode($xmlDoc->attach->download_count->body); + + if(!$file_obj->file) { + $url = base64_decode($xmlDoc->attach->url->body); + $path = base64_decode($xmlDoc->attach->path->body); + if($path && file_exists($path)) $file_obj->file = $path; + else { + $file_obj->file = $this->getTmpFilename(); + FileHandler::getRemoteFile($url, $file_obj->file); + } + } + + if(file_exists($file_obj->file)) { + + // 이미지인지 기타 파일인지 체크하여 upload path 지정 + if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_obj->source_filename)) { + $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3)); + $filename = $path.$file_obj->source_filename; + $file_obj->direct_download = 'Y'; + } else { + $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); + $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); + $file_obj->direct_download = 'N'; + } + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) continue; + + if(preg_match('/^\.\/files\/cache\/importer/i',$file_obj->file)) FileHandler::rename($file_obj->file, $filename); + else @copy($file_obj->file, $filename); + + // DB입력 + unset($file_obj->file); + if(file_exists($filename)) { + $file_obj->uploaded_filename = $filename; + $file_obj->file_size = filesize($filename); + $file_obj->comment = NULL; + $file_obj->member_srl = 0; + $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); + $file_obj->isvalid = 'Y'; + $output = executeQuery('file.insertFile', $file_obj); + + if($output->toBool()) { + $uploaded_count++; + $tmp_obj = null; + $tmp_obj->source_filename = $file_obj->source_filename; + if($file_obj->direct_download == 'Y') $files[$file_obj->source_filename] = $file_obj->uploaded_filename; + else $files[$file_obj->source_filename] = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid); + } + } + } + } + } + return $uploaded_count; + } + + /** + * @biref 임의로 사용할 파일이름을 return + **/ + function getTmpFilename() { + $path = "./files/cache/importer"; + if(!is_dir($path)) FileHandler::makeDir($path); + $filename = sprintf("%s/%d", $path, rand(11111111,99999999)); + if(file_exists($filename)) $filename .= rand(111,999); + return $filename; + } + + /** + * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 + **/ + function saveTemporaryFile($fp) { + $temp_filename = $this->getTmpFilename(); + $f = fopen($temp_filename, "w"); + + $buff = ''; + while(!feof($fp)) { + $str = trim(fgets($fp, 1024)); + if(trim($str) == '') break; + + $buff .= $str; + + if(substr($buff,-7)=='') { + fwrite($f, base64_decode(substr($buff, 6, -7))); + $buff = ''; + } + } + fclose($f); + return $temp_filename; + } + + + /** + * @brief 게시글 추가 변수 설정 + **/ + function importExtraVars($fp) { + $buff = null; + while(!feof($fp)) { + $buff .= $str = trim(fgets($fp, 1024)); + if(trim($str) == '') break; + } + if(!$buff) return array(); + + $buff = ''.$buff; + $oXmlParser = new XmlParser(); + $xmlDoc = $this->oXmlParser->parse($buff); + if(!count($xmlDoc->extra_vars->key)) return array(); + + $index = 1; + foreach($xmlDoc->extra_vars->key as $k => $v) { + unset($vobj); + if($v->var_idx) { + $vobj->var_idx = base64_decode($v->var_idx->body); + $vobj->lang_code = base64_decode($v->lang_code->body); + $vobj->value = base64_decode($v->value->body); + $vobj->eid = base64_decode($v->eid->body); + + } else if($v->body) { + $vobj->var_idx = $index; + $vobj->lang_code = Context::getLangType(); + $vobj->value = base64_decode($v->body); + $vobj->eid = 'extra_vars'.$index; + } + $extra_vars["extra_vars".$index] = $vobj; + $index++; + } + return $extra_vars; + } + } +?> diff --git a/modules/importer/importer.admin.view.php b/modules/importer/importer.admin.view.php index f0560ff3f..b0e8a3056 100644 --- a/modules/importer/importer.admin.view.php +++ b/modules/importer/importer.admin.view.php @@ -1,58 +1,58 @@ -setTemplatePath($this->module_path.'tpl'); - - $source_type = Context::get('source_type'); - switch($source_type) { - case 'member' : - $template_filename = "member"; - break; - case 'ttxml' : - $oModuleModel = &getModel('module'); - $mid_list = $oModuleModel->getMidList(); - Context::set('mid_list', $mid_list); - - $template_filename = "ttxml"; - break; - case 'module' : - $oModuleModel = &getModel('module'); - $mid_list = $oModuleModel->getMidList(); - Context::set('mid_list', $mid_list); - - $template_filename = "module"; - break; - case 'message' : - $template_filename = "message"; - break; - case 'sync' : - $template_filename = "sync"; - break; - default : - $template_filename = "index"; - break; - } - - $this->setTemplateFile($template_filename); - } - - } -?> +setTemplatePath($this->module_path.'tpl'); + + $source_type = Context::get('source_type'); + switch($source_type) { + case 'member' : + $template_filename = "member"; + break; + case 'ttxml' : + $oModuleModel = &getModel('module'); + $mid_list = $oModuleModel->getMidList(); + Context::set('mid_list', $mid_list); + + $template_filename = "ttxml"; + break; + case 'module' : + $oModuleModel = &getModel('module'); + $mid_list = $oModuleModel->getMidList(); + Context::set('mid_list', $mid_list); + + $template_filename = "module"; + break; + case 'message' : + $template_filename = "message"; + break; + case 'sync' : + $template_filename = "sync"; + break; + default : + $template_filename = "index"; + break; + } + + $this->setTemplateFile($template_filename); + } + + } +?> diff --git a/modules/importer/importer.class.php b/modules/importer/importer.class.php index 4a7ab2d71..bb64f019e 100644 --- a/modules/importer/importer.class.php +++ b/modules/importer/importer.class.php @@ -1,37 +1,37 @@ - + diff --git a/modules/importer/lang/es.lang.php b/modules/importer/lang/es.lang.php index 40433d424..9ec4b27ad 100644 --- a/modules/importer/lang/es.lang.php +++ b/modules/importer/lang/es.lang.php @@ -1,7 +1,7 @@ about_ttxml_user_id = 'Por favor, de entrada ID de usuario establecer como autor de la transferencia de TTXML. (Identificación de usuario debe ser firmado ya en marcha)'; $lang->about_type_module = 'Seleccione esta opción si estas transfeririendo información del documento de los tableros'; $lang->about_type_syncmember = 'Seleccione esta opción cuando tenga que sincronizar la información del usuario luego de haber transferido la información del usuario y del artículo.'; - $lang->about_importer = "Es posible trasferir los datos de Zeroboard4, zb5beta o de otros programas a XE.\nPara la transferencia debe utilizar XML Exporter para transformar los datos en archivo XML, y luego subir ese archivo."; + $lang->about_importer = "Es posible trasferir los datos de Zeroboard4, zb5beta o de otros programas a XE.\nPara la transferencia debe utilizar XML Exporter para transformar los datos en archivo XML, y luego subir ese archivo."; $lang->about_target_path = "Para descargar los archivos adjuntos de ZeroBoard4, ingresa la ubicación de ZeroBoard4 instalado.\nSi esta en el mismo servidor escriba la ubicación de ZeroBoard4 como por ejemplo: /home/ID/public_html/bbs o si esta en otro servidor escriba la ubicación de ZeroBoard4 instalado como por ejemplo: http://dominio/bbs"; ?> diff --git a/modules/importer/lang/fr.lang.php b/modules/importer/lang/fr.lang.php index fc524bf94..7df2df838 100644 --- a/modules/importer/lang/fr.lang.php +++ b/modules/importer/lang/fr.lang.php @@ -1,62 +1,62 @@ - - * @brief Paquet du langage en français le module d\'Importateur - **/ - - // words for button - $lang->cmd_sync_member = 'Synchroniser'; - $lang->cmd_continue = 'Continuer'; - $lang->preprocessing = 'On est en train de préparer pour transférer les données.'; - - // items - $lang->importer = 'Transférer les Données du Zeroboard'; - $lang->source_type = 'Sorte de la Source'; - $lang->type_member = 'Données des Membres'; - $lang->type_message = 'Données des Messages'; - $lang->type_ttxml = 'TTXML'; - $lang->type_module = 'Données des Articles'; - $lang->type_syncmember = 'Synchroniser les Données des Membres'; - $lang->target_module = 'Module objectif'; - $lang->xml_file = 'Fichier en XML'; - - $lang->import_step_title = array( - 1 => 'Pas 1. Choisir l\'objet à transférer', - 12 => 'Pas 1-2. Choisir le module à transférer', - 13 => 'Pas 1-3. Choisir la catégorie à transférer', - 2 => 'Pas 2. Télécharger fichier en XML', - 3 => 'Pas 2. Synchroniser données des membres et des articles', - 99 => 'Trensférer des données', - ); - - $lang->import_step_desc = array( - 1 => 'Choisissez la sorte du fichier en XML que vous voulez transférer.', - 12 => 'Choisissez le module objectif dans lequel vous voulez tranférer les données.', - 121 => '글:', - 122 => '방명록:', - 13 => 'Choisissez la catégorie objective dans laquelle vous voulez transférer les données.', - 2 => "Entrez le chemin du fichier en XML pour transférer les données.\nS'il est localisé dans le même compte, entréz le chemin absolut ou relatif. Sinon, entrez l'URL commençant avec http://..", - 3 => 'Les données des membres et ceux des articles peuvent ne pas s\'accorder après la transfèrement. Dans ce cas, synchronisez S.V.P. Ça arrangera les données en étant basé sur le compte d\'utilisateur.', - 99 => 'En train de transférer', - ); - - // guide/alert - $lang->msg_sync_member = 'On commencera à synchroniser les données des membres et des articles quand vous cliquez le bouton de synchroniser.'; - $lang->msg_no_xml_file = 'On ne peut pas trouver le fichier de XML. Vérifiez le chemin encore une fois, S.V.P.'; - $lang->msg_invalid_xml_file = 'Ce fichier de XML est invalide.'; - $lang->msg_importing = 'On écrit %d données sur %d. (Si c\'est arrêté longtemps, cliquez le bouton "Continuer")'; - $lang->msg_import_finished = '%d/%d données sont entrées complètement. En dépendant sur la situation, il y aura quelques données qui n\'ont pas été entrées.'; - $lang->msg_sync_completed = 'On a terminé de synchroniser les données des membres, des articles et des commentaires.'; - - // blah blah.. - $lang->about_type_member = 'Choisissez cette option si vous voulez transférer les informations des membres'; - $lang->about_type_message = 'Choisissez cette option si vous voulez transférer les informations des messages'; - $lang->about_type_ttxml = 'Choisissez cette option si vous voulez transférer les informations des TTXML(textcube)'; - $lang->about_ttxml_user_id = 'Entrez le compte d\'utilisateur pour déclarer comme l\'auteur. (Le compte d\'utilisateur doit être déjà inscrit)'; - $lang->about_type_module = 'Choisissez cette option si vous voulez transférer les informations des panneaux ou des articles.'; - $lang->about_type_syncmember = 'Choisissez cette option si vous voulez synchroniser les informations des membres après le transfér des informations des membres et des articles.'; - $lang->about_importer = "Vous pouvez transférer les données de Zeroboard4, de Zeroboard5 Beta ou d\'autres logiciels aux données de XE.\nPour transférer, vous devez utiliser Exporteur de XML pour convertir les données en fichier de XML, et puis téléchargez-le."; - - $lang->about_target_path = "Pour obtenir les attachés de Zeroboard4, Entrez l\'adresse où Zeroboard4 est installé.\nSi elle se trouve dans le même serveur, entrez le chemin comme '/home/USERID/public_html/bbs'\nSi elle ne se trouve pas dans le même serveur, entrez l\'adresse où Zeroboard4 est installé comme 'http://Domain/bbs'"; -?> + + * @brief Paquet du langage en français le module d\'Importateur + **/ + + // words for button + $lang->cmd_sync_member = 'Synchroniser'; + $lang->cmd_continue = 'Continuer'; + $lang->preprocessing = 'On est en train de préparer pour transférer les données.'; + + // items + $lang->importer = 'Transférer les Données du Zeroboard'; + $lang->source_type = 'Sorte de la Source'; + $lang->type_member = 'Données des Membres'; + $lang->type_message = 'Données des Messages'; + $lang->type_ttxml = 'TTXML'; + $lang->type_module = 'Données des Articles'; + $lang->type_syncmember = 'Synchroniser les Données des Membres'; + $lang->target_module = 'Module objectif'; + $lang->xml_file = 'Fichier en XML'; + + $lang->import_step_title = array( + 1 => 'Pas 1. Choisir l\'objet à transférer', + 12 => 'Pas 1-2. Choisir le module à transférer', + 13 => 'Pas 1-3. Choisir la catégorie à transférer', + 2 => 'Pas 2. Télécharger fichier en XML', + 3 => 'Pas 2. Synchroniser données des membres et des articles', + 99 => 'Trensférer des données', + ); + + $lang->import_step_desc = array( + 1 => 'Choisissez la sorte du fichier en XML que vous voulez transférer.', + 12 => 'Choisissez le module objectif dans lequel vous voulez tranférer les données.', + 121 => '글:', + 122 => '방명록:', + 13 => 'Choisissez la catégorie objective dans laquelle vous voulez transférer les données.', + 2 => "Entrez le chemin du fichier en XML pour transférer les données.\nS'il est localisé dans le même compte, entréz le chemin absolut ou relatif. Sinon, entrez l'URL commençant avec http://..", + 3 => 'Les données des membres et ceux des articles peuvent ne pas s\'accorder après la transfèrement. Dans ce cas, synchronisez S.V.P. Ça arrangera les données en étant basé sur le compte d\'utilisateur.', + 99 => 'En train de transférer', + ); + + // guide/alert + $lang->msg_sync_member = 'On commencera à synchroniser les données des membres et des articles quand vous cliquez le bouton de synchroniser.'; + $lang->msg_no_xml_file = 'On ne peut pas trouver le fichier de XML. Vérifiez le chemin encore une fois, S.V.P.'; + $lang->msg_invalid_xml_file = 'Ce fichier de XML est invalide.'; + $lang->msg_importing = 'On écrit %d données sur %d. (Si c\'est arrêté longtemps, cliquez le bouton "Continuer")'; + $lang->msg_import_finished = '%d/%d données sont entrées complètement. En dépendant sur la situation, il y aura quelques données qui n\'ont pas été entrées.'; + $lang->msg_sync_completed = 'On a terminé de synchroniser les données des membres, des articles et des commentaires.'; + + // blah blah.. + $lang->about_type_member = 'Choisissez cette option si vous voulez transférer les informations des membres'; + $lang->about_type_message = 'Choisissez cette option si vous voulez transférer les informations des messages'; + $lang->about_type_ttxml = 'Choisissez cette option si vous voulez transférer les informations des TTXML(textcube)'; + $lang->about_ttxml_user_id = 'Entrez le compte d\'utilisateur pour déclarer comme l\'auteur. (Le compte d\'utilisateur doit être déjà inscrit)'; + $lang->about_type_module = 'Choisissez cette option si vous voulez transférer les informations des panneaux ou des articles.'; + $lang->about_type_syncmember = 'Choisissez cette option si vous voulez synchroniser les informations des membres après le transfér des informations des membres et des articles.'; + $lang->about_importer = "Vous pouvez transférer les données de Zeroboard4, de Zeroboard5 Beta ou d\'autres logiciels aux données de XE.\nPour transférer, vous devez utiliser Exporteur de XML pour convertir les données en fichier de XML, et puis téléchargez-le."; + + $lang->about_target_path = "Pour obtenir les attachés de Zeroboard4, Entrez l\'adresse où Zeroboard4 est installé.\nSi elle se trouve dans le même serveur, entrez le chemin comme '/home/USERID/public_html/bbs'\nSi elle ne se trouve pas dans le même serveur, entrez l\'adresse où Zeroboard4 est installé comme 'http://Domain/bbs'"; +?> diff --git a/modules/importer/lang/jp.lang.php b/modules/importer/lang/jp.lang.php index 139f69624..5fcad60d2 100644 --- a/modules/importer/lang/jp.lang.php +++ b/modules/importer/lang/jp.lang.php @@ -1,61 +1,61 @@ -cmd_sync_member = '同期化'; - $lang->cmd_continue = '続ける'; - $lang->preprocessing = 'データ移転のため、準備中です。'; - - // 項目 - $lang->importer = 'XEデータ変換'; - $lang->source_type = 'データ変換の対象'; - $lang->type_member = '会員情報'; - $lang->type_message = 'メッセージ情報'; - $lang->type_ttxml = 'TTXML'; - $lang->type_module = '書き込みデータ情報'; - $lang->type_syncmember = '会員情報同期化'; - $lang->target_module = '対象モジュール'; - $lang->xml_file = 'XMLファイル'; - - $lang->import_step_title = array( - 1 => 'Step 1. 移転先を選択', - 12 => 'Step 1-2. 対象モジュール選択', - 13 => 'Step 1-3. 対象カテゴリ選択', - 2 => 'Step 2. XMLファイルアップロード', - 3 => 'Step 2. 会員情報と書き込みデータの同期化', - 99 => 'データ移転', - ); - - $lang->import_step_desc = array( - 1 => '変換するXMLファイルの種類を選択して下さい。', - 12 => 'データ変換を行う対象モジュールを選択して下さい。', - 121 => '書き込み:', - 122 => 'ゲストブック:', - 13 => 'データ変換を行う対象カテゴリを選択して下さい。', - 2 => "データ変換を行うXMLファイルパスを入力して下さい。同じアカウントのサーバ上では、相対または絶対パスを、異なるサーバにアップロードされている場合は「http://アドレス..」を入力して下さい。", - 3 => '会員情報と書き込みデータの情報の変換を行った後、データが合わない場合があります。この時に同期化を行うと「user_id」をもとに正しく動作するようにします。', - 99 => 'データを移転しています。', - ); - - // 案内/警告 - $lang->msg_sync_member = '同期化ボタンをクリックすると会員情報と書き込みデータの情報の同期化が始まります。'; - $lang->msg_no_xml_file = 'XMLファイルが見つかりません。パスをもう一度確認して下さい。'; - $lang->msg_invalid_xml_file = 'XMLファイルのフォーマットが正しくありません。'; - $lang->msg_importing = '%d個のデータの内、%d個を変換中です(止まったままの場合は「続ける」ボタンをクリックして下さい)。'; - $lang->msg_import_finished = '%d/%d個のデータ変換が完了しました。場合によって変換されていないデータがあることもあります。'; - $lang->msg_sync_completed = '会員情報、書き込みデータ、コメントのデータの同期化(変換)が完了しました。'; - - // その他.. - $lang->about_type_member = 'データ変換の対象が会員情報の場合は選択して下さい。'; - $lang->about_type_message = 'データ移転対象がメッセージの場合選択して下さい。'; - $lang->about_type_ttxml = 'データ移転対象が、TTXML(textcube系列)の場合選択して下さい。'; - $lang->about_ttxml_user_id = 'TTXML移転時に投稿者として指定するユーザIDを入力して下さい(すでに加入されているIDでなければなりません)。'; - $lang->about_type_module = 'データ変換の対象が書き込みデータである場合は選択して下さい。'; - $lang->about_type_syncmember = '会員情報と書き込みデータなどの変換を行った後、会員情報を同期化する必要がある場合は、選択して下さい。'; - $lang->about_importer = "ゼロボード4、zb5betaまたは他のプログラムの書き込みデータをXEのデータに変換することが出来ます。\n変換するためには、XML Exporterを利用して変換したい書き込みデータをXMLファイルで作成してアップロードして下さい。"; - $lang->about_target_path = "添付ファイルをダウンロードするためには、ゼロボード4がインストールされた場所を入力して下さい。同じサーバ上にある場合は「/home/ID/public_html/bbs」のように入力し、他のサーバにある場合は、「http://ドメイン/bbs」のようにゼロボードがインストールされているURLを入力して下さい。"; -?> +cmd_sync_member = '同期化'; + $lang->cmd_continue = '続ける'; + $lang->preprocessing = 'データ移転のため、準備中です。'; + + // 項目 + $lang->importer = 'XEデータ変換'; + $lang->source_type = 'データ変換の対象'; + $lang->type_member = '会員情報'; + $lang->type_message = 'メッセージ情報'; + $lang->type_ttxml = 'TTXML'; + $lang->type_module = '書き込みデータ情報'; + $lang->type_syncmember = '会員情報同期化'; + $lang->target_module = '対象モジュール'; + $lang->xml_file = 'XMLファイル'; + + $lang->import_step_title = array( + 1 => 'Step 1. 移転先を選択', + 12 => 'Step 1-2. 対象モジュール選択', + 13 => 'Step 1-3. 対象カテゴリ選択', + 2 => 'Step 2. XMLファイルアップロード', + 3 => 'Step 2. 会員情報と書き込みデータの同期化', + 99 => 'データ移転', + ); + + $lang->import_step_desc = array( + 1 => '変換するXMLファイルの種類を選択して下さい。', + 12 => 'データ変換を行う対象モジュールを選択して下さい。', + 121 => '書き込み:', + 122 => 'ゲストブック:', + 13 => 'データ変換を行う対象カテゴリを選択して下さい。', + 2 => "データ変換を行うXMLファイルパスを入力して下さい。同じアカウントのサーバ上では、相対または絶対パスを、異なるサーバにアップロードされている場合は「http://アドレス..」を入力して下さい。", + 3 => '会員情報と書き込みデータの情報の変換を行った後、データが合わない場合があります。この時に同期化を行うと「user_id」をもとに正しく動作するようにします。', + 99 => 'データを移転しています。', + ); + + // 案内/警告 + $lang->msg_sync_member = '同期化ボタンをクリックすると会員情報と書き込みデータの情報の同期化が始まります。'; + $lang->msg_no_xml_file = 'XMLファイルが見つかりません。パスをもう一度確認して下さい。'; + $lang->msg_invalid_xml_file = 'XMLファイルのフォーマットが正しくありません。'; + $lang->msg_importing = '%d個のデータの内、%d個を変換中です(止まったままの場合は「続ける」ボタンをクリックして下さい)。'; + $lang->msg_import_finished = '%d/%d個のデータ変換が完了しました。場合によって変換されていないデータがあることもあります。'; + $lang->msg_sync_completed = '会員情報、書き込みデータ、コメントのデータの同期化(変換)が完了しました。'; + + // その他.. + $lang->about_type_member = 'データ変換の対象が会員情報の場合は選択して下さい。'; + $lang->about_type_message = 'データ移転対象がメッセージの場合選択して下さい。'; + $lang->about_type_ttxml = 'データ移転対象が、TTXML(textcube系列)の場合選択して下さい。'; + $lang->about_ttxml_user_id = 'TTXML移転時に投稿者として指定するユーザIDを入力して下さい(すでに加入されているIDでなければなりません)。'; + $lang->about_type_module = 'データ変換の対象が書き込みデータである場合は選択して下さい。'; + $lang->about_type_syncmember = '会員情報と書き込みデータなどの変換を行った後、会員情報を同期化する必要がある場合は、選択して下さい。'; + $lang->about_importer = "ゼロボード4、zb5betaまたは他のプログラムの書き込みデータをXEのデータに変換することが出来ます。\n変換するためには、XML Exporterを利用して変換したい書き込みデータをXMLファイルで作成してアップロードして下さい。"; + $lang->about_target_path = "添付ファイルをダウンロードするためには、ゼロボード4がインストールされた場所を入力して下さい。同じサーバ上にある場合は「/home/ID/public_html/bbs」のように入力し、他のサーバにある場合は、「http://ドメイン/bbs」のようにゼロボードがインストールされているURLを入力して下さい。"; +?> diff --git a/modules/importer/lang/ko.lang.php b/modules/importer/lang/ko.lang.php index f2ba76e0e..7270d084f 100644 --- a/modules/importer/lang/ko.lang.php +++ b/modules/importer/lang/ko.lang.php @@ -1,61 +1,61 @@ -cmd_sync_member = '동기화'; - $lang->cmd_continue = '계속 진행'; - $lang->preprocessing = '데이터 이전을 위한 사전 준비 중입니다.'; - - // 항목 - $lang->importer = 'XE 데이터 이전'; - $lang->source_type = '이전 대상'; - $lang->type_member = '회원 정보'; - $lang->type_message = '쪽지(메시지) 정보'; - $lang->type_ttxml = 'TTXML'; - $lang->type_module = '게시물 정보'; - $lang->type_syncmember = '회원정보 동기화'; - $lang->target_module = '대상 모듈'; - $lang->xml_file = 'XML 파일'; - - $lang->import_step_title = array( - 1 => 'Step 1. 이전 대상 선택', - 12 => 'Step 1-2. 대상 모듈 선택', - 13 => 'Step 1-3. 대상 분류 선택', - 2 => 'Step 2. XML파일 지정', - 3 => 'Step 2. 회원정보와 게시물의 정보 동기화', - 99 => '데이터 이전', - ); - - $lang->import_step_desc = array( - 1 => '이전하려는 XML파일의 종류를 선택해주세요.', - 12 => '데이터를 이전 받을 대상 모듈을 선택해주세요.', - 121 => '글:', - 122 => '방명록:', - 13 => '데이터 이전을 할 대상 분류를 선택해주세요.', - 2 => "이전할 데이터 XML파일의 경로를 입력해주세요.\n상대 또는 절대 경로를 입력하시면 됩니다.", - 3 => '회원정보와 게시물 정보가 이전 후에 맞지 않을 수 있습니다. 이때 동기화를 하시면 user_id를 기반으로 올바르게 동작하도록 합니다.', - 99 => '데이터 이전중입니다.', - ); - - // 안내/경고 - $lang->msg_sync_member = '동기화 버튼을 클릭하시면 회원정보와 게시물 정보의 동기화를 시작합니다.'; - $lang->msg_no_xml_file = 'XML파일을 찾을 수 없습니다. 경로를 다시 확인해주세요.'; - $lang->msg_invalid_xml_file = '잘못된 형식의 XML파일입니다.'; - $lang->msg_importing = '%d개의 데이터 중 %d개를 입력중입니다. (계속 멈추어 있으면 "계속진행" 버튼을 클릭해주세요.)'; - $lang->msg_import_finished = '%d/%d 개의 데이터 입력이 완료되었습니다. 상황에 따라 입력되지 못한 데이터가 있을 수 있습니다.'; - $lang->msg_sync_completed = '회원과 게시물, 댓글의 동기화가 완료되었습니다.'; - - // 주절주절 - $lang->about_type_member = '데이터 이전 대상이 회원정보일 경우 선택해주세요.'; - $lang->about_type_message = '데이터 이전 대상이 쪽지(메시지)일 경우 선택해주세요.'; - $lang->about_type_ttxml = '데이터 이전 대상이 TTXML(textcube계열)일 경우 선택해주세요.'; - $lang->about_ttxml_user_id = 'TTXML 이전 시에 글쓴이로 지정할 사용자 아이디를 입력해주세요. (이미 가입된 아이디여야 합니다.)'; - $lang->about_type_module = '데이터 이전 대상이 게시판 등의 게시물 정보일 경우 선택해주세요.'; - $lang->about_type_syncmember = '회원정보와 게시물정보 등을 이전 후, 회원정보를 동기화해야 할 때 선택해주세요.'; - $lang->about_importer = "제로보드4, zb5beta 또는 다른 프로그램의 데이터를 XE 데이터로 이전할 수 있습니다.\n이전을 위해서는 XML Exporter를 이용해서 원하는 데이터를 XML파일로 생성 후 업로드해주셔야 합니다."; - $lang->about_target_path = "첨부 파일을 받기 위해 제로보드4가 설치된 위치를 입력해주세요.\n같은 서버에 있을 경우 /home/아이디/public_html/bbs 등과 같이 제로보드4의 위치를 입력하시고\n다른 서버일 경우 http://도메인/bbs 처럼 제로보드4가 설치된 곳의 url을 입력해주세요."; -?> +cmd_sync_member = '동기화'; + $lang->cmd_continue = '계속 진행'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비 중입니다.'; + + // 항목 + $lang->importer = 'XE 데이터 이전'; + $lang->source_type = '이전 대상'; + $lang->type_member = '회원 정보'; + $lang->type_message = '쪽지(메시지) 정보'; + $lang->type_ttxml = 'TTXML'; + $lang->type_module = '게시물 정보'; + $lang->type_syncmember = '회원정보 동기화'; + $lang->target_module = '대상 모듈'; + $lang->xml_file = 'XML 파일'; + + $lang->import_step_title = array( + 1 => 'Step 1. 이전 대상 선택', + 12 => 'Step 1-2. 대상 모듈 선택', + 13 => 'Step 1-3. 대상 분류 선택', + 2 => 'Step 2. XML파일 지정', + 3 => 'Step 2. 회원정보와 게시물의 정보 동기화', + 99 => '데이터 이전', + ); + + $lang->import_step_desc = array( + 1 => '이전하려는 XML파일의 종류를 선택해주세요.', + 12 => '데이터를 이전 받을 대상 모듈을 선택해주세요.', + 121 => '글:', + 122 => '방명록:', + 13 => '데이터 이전을 할 대상 분류를 선택해주세요.', + 2 => "이전할 데이터 XML파일의 경로를 입력해주세요.\n상대 또는 절대 경로를 입력하시면 됩니다.", + 3 => '회원정보와 게시물 정보가 이전 후에 맞지 않을 수 있습니다. 이때 동기화를 하시면 user_id를 기반으로 올바르게 동작하도록 합니다.', + 99 => '데이터 이전중입니다.', + ); + + // 안내/경고 + $lang->msg_sync_member = '동기화 버튼을 클릭하시면 회원정보와 게시물 정보의 동기화를 시작합니다.'; + $lang->msg_no_xml_file = 'XML파일을 찾을 수 없습니다. 경로를 다시 확인해주세요.'; + $lang->msg_invalid_xml_file = '잘못된 형식의 XML파일입니다.'; + $lang->msg_importing = '%d개의 데이터 중 %d개를 입력중입니다. (계속 멈추어 있으면 "계속진행" 버튼을 클릭해주세요.)'; + $lang->msg_import_finished = '%d/%d 개의 데이터 입력이 완료되었습니다. 상황에 따라 입력되지 못한 데이터가 있을 수 있습니다.'; + $lang->msg_sync_completed = '회원과 게시물, 댓글의 동기화가 완료되었습니다.'; + + // 주절주절 + $lang->about_type_member = '데이터 이전 대상이 회원정보일 경우 선택해주세요.'; + $lang->about_type_message = '데이터 이전 대상이 쪽지(메시지)일 경우 선택해주세요.'; + $lang->about_type_ttxml = '데이터 이전 대상이 TTXML(textcube계열)일 경우 선택해주세요.'; + $lang->about_ttxml_user_id = 'TTXML 이전 시에 글쓴이로 지정할 사용자 아이디를 입력해주세요. (이미 가입된 아이디여야 합니다.)'; + $lang->about_type_module = '데이터 이전 대상이 게시판 등의 게시물 정보일 경우 선택해주세요.'; + $lang->about_type_syncmember = '회원정보와 게시물정보 등을 이전 후, 회원정보를 동기화해야 할 때 선택해주세요.'; + $lang->about_importer = "제로보드4, zb5beta 또는 다른 프로그램의 데이터를 XE 데이터로 이전할 수 있습니다.\n이전을 위해서는 XML Exporter를 이용해서 원하는 데이터를 XML파일로 생성 후 업로드해주셔야 합니다."; + $lang->about_target_path = "첨부 파일을 받기 위해 제로보드4가 설치된 위치를 입력해주세요.\n같은 서버에 있을 경우 /home/아이디/public_html/bbs 등과 같이 제로보드4의 위치를 입력하시고\n다른 서버일 경우 http://도메인/bbs 처럼 제로보드4가 설치된 곳의 url을 입력해주세요."; +?> diff --git a/modules/importer/lang/ru.lang.php b/modules/importer/lang/ru.lang.php index 8f5c35527..8c99c384e 100644 --- a/modules/importer/lang/ru.lang.php +++ b/modules/importer/lang/ru.lang.php @@ -1,62 +1,62 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - // слова для кнопок - $lang->cmd_sync_member = 'Синхронизировать'; - $lang->cmd_continue = 'Продолжить'; - $lang->preprocessing = 'Идет подготовка для импортирования данных...'; - - // объекты - $lang->importer = 'Импортировать данные zeroboard'; - $lang->source_type = 'Предыдущее назначение'; - $lang->type_member = 'Данные пользователей'; - $lang->type_message = 'Данные сообщения'; - $lang->type_ttxml = 'TTXML'; - $lang->type_module = 'Данные статьи'; - $lang->type_syncmember = 'Синхронизировать данные пользователей'; - $lang->target_module = 'Модуль назначения'; - $lang->xml_file = 'XML файл'; - - $lang->import_step_title = array( - 1 => 'Шаг 1. Выберите предыдущее назначение', - 12 => 'Шаг 1-2. Выберите модуль назначения', - 13 => 'Шаг 1-3. Выберите категорию назначения', - 2 => 'Шаг 2. Загрузить XML файл', - 3 => 'Шаг 2. Синхронизировать данные пользователей и статей', - 99 => 'Импортировать данные', - ); - - $lang->import_step_desc = array( - 1 => 'Пожалуйста, выберите тип XML файла, который Вы хотите импортировать.', - 12 => 'Пожалуйста, выберите модуль, в который Вы хотите импортировать данные.', - 121 => 'запись:', - 122 => 'посетители:', - 13 => 'Пожалуйста, выберите категорию назначения, в которую Вы хотите импортировать данные.', - 2 => "Пожайлуста, введите расположение XML файла, который Вы хотите импортировать.\nЕсли он находится в одном аккаунте, то введите абсолютный/относительный путь. Если нет, то введите URL, начинающийся с http://...", - 3 => 'Данные пользователей и статей могут быть некорректны после импорта. В таком случае, выполните синхронизацию для восстановления, основанного на user_id.', - 99 => 'Идет процесс импортирования данных', - ); - - // гид/алерт - $lang->msg_sync_member = 'Синхронизация данных пользователей и статей начнется по нажатию книпоки "Синхронизировать".'; - $lang->msg_no_xml_file = 'XML файл не найден. Пожалуйста, проверьте путь еще раз'; - $lang->msg_invalid_xml_file = 'Неверный тип XML файла.'; - $lang->msg_importing = 'Пишем %d данные %d. (Если процесс "завис", нажмите кнопку "Продолжить")'; - $lang->msg_import_finished = '%d/%d данные были поностью импортированы. В зависимости от ситуации, некоторые данные могут не быть импортированы.'; - $lang->msg_sync_completed = 'Выполнена синхронизация пользователей, статей и комментариев.'; - - // blah blah.. чепуха) - $lang->about_type_member = 'Если Вы импортируете информацию пользователей, выберите эту опцию'; - $lang->about_type_message = 'Выберите, если импортируются данные сообщения'; - $lang->about_type_ttxml = 'Выберите, если импортируются данные TTXML'; - $lang->about_ttxml_user_id = 'Введите ID указанного пользователя, сделавшего запись при импортировании данных TTXML. (Пользователь должен быть зарегистрирован)'; - $lang->about_type_module = 'Если Вы импортируете информацию форума или записей, выберите эту опцию'; - $lang->about_type_syncmember = 'Если Вы пытаетесь синхронизировать информацию пользователей после импорта информации пользователей и записей, выберите эту опцию'; - $lang->about_importer = "Вы можете импортировать данные Zeroboard4, Zeroboard5 Beta или других программ в XE.\nЧтобы импортировать, Вам следует использовать XML Экспортер (XML Exporter), чтобы конвертировать нужные данные в XML Файл и затем загрузить его."; - - $lang->about_target_path = "Чтобы получить вложения с Zeroboard4, пожалуйста, введите адрес, где установлена Zeroboard4.\nЕсли она раположена на том же сервере, введите путь к Zeroboard4 как /home/USERID/public_html/bbs\nЕсли нет, введите адрес, где Zeroboard4 установлена. Например: http://Domain/bbs"; -?> +cmd_sync_member = 'Синхронизировать'; + $lang->cmd_continue = 'Продолжить'; + $lang->preprocessing = 'Идет подготовка для импортирования данных...'; + + // объекты + $lang->importer = 'Импортировать данные zeroboard'; + $lang->source_type = 'Предыдущее назначение'; + $lang->type_member = 'Данные пользователей'; + $lang->type_message = 'Данные сообщения'; + $lang->type_ttxml = 'TTXML'; + $lang->type_module = 'Данные статьи'; + $lang->type_syncmember = 'Синхронизировать данные пользователей'; + $lang->target_module = 'Модуль назначения'; + $lang->xml_file = 'XML файл'; + + $lang->import_step_title = array( + 1 => 'Шаг 1. Выберите предыдущее назначение', + 12 => 'Шаг 1-2. Выберите модуль назначения', + 13 => 'Шаг 1-3. Выберите категорию назначения', + 2 => 'Шаг 2. Загрузить XML файл', + 3 => 'Шаг 2. Синхронизировать данные пользователей и статей', + 99 => 'Импортировать данные', + ); + + $lang->import_step_desc = array( + 1 => 'Пожалуйста, выберите тип XML файла, который Вы хотите импортировать.', + 12 => 'Пожалуйста, выберите модуль, в который Вы хотите импортировать данные.', + 121 => 'запись:', + 122 => 'посетители:', + 13 => 'Пожалуйста, выберите категорию назначения, в которую Вы хотите импортировать данные.', + 2 => "Пожайлуста, введите расположение XML файла, который Вы хотите импортировать.\nЕсли он находится в одном аккаунте, то введите абсолютный/относительный путь. Если нет, то введите URL, начинающийся с http://...", + 3 => 'Данные пользователей и статей могут быть некорректны после импорта. В таком случае, выполните синхронизацию для восстановления, основанного на user_id.', + 99 => 'Идет процесс импортирования данных', + ); + + // гид/алерт + $lang->msg_sync_member = 'Синхронизация данных пользователей и статей начнется по нажатию книпоки "Синхронизировать".'; + $lang->msg_no_xml_file = 'XML файл не найден. Пожалуйста, проверьте путь еще раз'; + $lang->msg_invalid_xml_file = 'Неверный тип XML файла.'; + $lang->msg_importing = 'Пишем %d данные %d. (Если процесс "завис", нажмите кнопку "Продолжить")'; + $lang->msg_import_finished = '%d/%d данные были поностью импортированы. В зависимости от ситуации, некоторые данные могут не быть импортированы.'; + $lang->msg_sync_completed = 'Выполнена синхронизация пользователей, статей и комментариев.'; + + // blah blah.. чепуха) + $lang->about_type_member = 'Если Вы импортируете информацию пользователей, выберите эту опцию'; + $lang->about_type_message = 'Выберите, если импортируются данные сообщения'; + $lang->about_type_ttxml = 'Выберите, если импортируются данные TTXML'; + $lang->about_ttxml_user_id = 'Введите ID указанного пользователя, сделавшего запись при импортировании данных TTXML. (Пользователь должен быть зарегистрирован)'; + $lang->about_type_module = 'Если Вы импортируете информацию форума или записей, выберите эту опцию'; + $lang->about_type_syncmember = 'Если Вы пытаетесь синхронизировать информацию пользователей после импорта информации пользователей и записей, выберите эту опцию'; + $lang->about_importer = "Вы можете импортировать данные Zeroboard4, Zeroboard5 Beta или других программ в XE.\nЧтобы импортировать, Вам следует использовать XML Экспортер (XML Exporter), чтобы конвертировать нужные данные в XML Файл и затем загрузить его."; + + $lang->about_target_path = "Чтобы получить вложения с Zeroboard4, пожалуйста, введите адрес, где установлена Zeroboard4.\nЕсли она раположена на том же сервере, введите путь к Zeroboard4 как /home/USERID/public_html/bbs\nЕсли нет, введите адрес, где Zeroboard4 установлена. Например: http://Domain/bbs"; +?> diff --git a/modules/importer/lang/vi.lang.php b/modules/importer/lang/vi.lang.php index b68008977..edc4b8788 100644 --- a/modules/importer/lang/vi.lang.php +++ b/modules/importer/lang/vi.lang.php @@ -1,64 +1,64 @@ -cmd_sync_member = 'Đồng bộ hóa'; - $lang->cmd_continue = 'Tiếp tục'; - $lang->preprocessing = 'Đang chuẩn bị cho việc chuyển dữ liệu.'; - - // items - $lang->importer = 'Chuyển Zeroboard Data'; - $lang->source_type = 'Chọn nguồn'; - $lang->type_member = 'Data Thành viên'; - $lang->type_message = 'Data Tin nhắn'; - $lang->type_ttxml = 'TTXML'; - $lang->type_module = 'Data Bài viết'; - $lang->type_syncmember = 'Đồng bộ hóa Data Thành viên'; - $lang->target_module = 'Module'; - $lang->xml_file = 'File XML'; - - $lang->import_step_title = array( - 1 => 'Bước 1. Lựa chọn đường dẫn', - 12 => 'Bước 1-2. Chọn Module', - 13 => 'Bước 1-3. Chọn chuyên đề', - 2 => 'Bước 2. Upload File XML', - 3 => 'Bước 2. Đồng bộ hóa Data thành viên và Data bài viết', - 99 => 'Đang đồng bộ hóa dữ liệu.', - ); - - $lang->import_step_desc = array( - 1 => 'Xin hãy chọn Data dưới dạng XML để đồng bộ hóa.', - 12 => 'Xin hãy chọn Module bạn muốn lưu Data.', - 121 => 'Bài viết:', - 122 => 'Sổ lưu niệm:', - 13 => 'Xin hãy chọn chuyên mục để lưu Data.', - 2 => "Xin hãy nhập File Data dưới dạng XML để bắt đầu đồng bộ hóa.\nHãy nhập đường dẫn cho File chứa Data trên Host dưới dạng http://..", - 3 => 'Đã không thể kết nối tới File Data thành viên và bài viết. Nếu đã đúng đường dẫn xin hãy kiểm tra Data với user_id.', - 99 => 'Đang đồng bộ hóa dữ liệu.', - ); - - // guide/alert - $lang->msg_sync_member = 'Data thành viên và bài viết sẽ được đồng bộ hóa sau khi bấm "Đồng bộ".'; - $lang->msg_no_xml_file = 'Không tìm yhấy File XML. Xin hãy kiểm tra lại đường dẫn!'; - $lang->msg_invalid_xml_file = 'Định dạng File XML không hợp lệ.'; - $lang->msg_importing = 'Đang gửi %d Data của %d. (Nếu việc gửi Data không tiếp tục chạy, hãy bấm "Tiếp tục")'; - $lang->msg_import_finished = '%d/%d của Data đã được đồng bộ thành công. Một số nội dung đã không thể đồng bộ.'; - $lang->msg_sync_completed = 'Đã đồng bộ Data thành công.'; - - // blah blah.. - $lang->about_type_member = 'Lựa chọn này sẽ đồng bộ Data thành viên.'; - $lang->about_type_message = 'Lựa chọn này đồng bộ Data tin nhắn.'; - $lang->about_type_ttxml = 'Lựa chọn này sẽ đồng bộ và chuyển đổi Data của Textcube.'; - $lang->about_ttxml_user_id = 'Xin hãy nhập ID sẽ hiển thị là tác giả của những bài viết sau khi Data được chuyển đổi từ TTXML. (ID này phải là thành viên đã đăng kí.)'; - $lang->about_type_module = 'Lựa chọn này sẽ đồng bộ và chuyển đổi các trang và bài viết.'; - $lang->about_type_syncmember = 'Lựa chọn này sẽ đồng bộ thông tin thành viên trước khi đồng bộ Bài viết và thành viên.'; - $lang->about_importer = "Bạn có thể chuyển Data từ Zeroboard4, Zeroboard5 Beta hay Data của những mã nguồn khác vào Data của XE.\nĐể hiểu rõ hơn công việc này, bạn có thể tham khảo cách chuyển đổi Data của bạn vào XE khi bạn đã Upload chúng tại XML Exporter."; - - $lang->about_target_path = "Để lấy cả File đính kèm tại Zeroboard4, bạn hãy nhập địa chỉ mà đã cài đặt Zeroboard4.\nNếu nó cùng nằm trên một Server, hãy nhập đầy đủ đường dẫn thư mục cài đặt của Zeroboard4. Ví dụ: /home/USERID/public_html/bbs\nNếu khác Server, hãy nhập địa chỉ của Zeroboard4 đã cài đặt. Ví dụ: http://Domain/bbs"; -?> +cmd_sync_member = 'Đồng bộ hóa'; + $lang->cmd_continue = 'Tiếp tục'; + $lang->preprocessing = 'Đang chuẩn bị cho việc chuyển dữ liệu.'; + + // items + $lang->importer = 'Chuyển Zeroboard Data'; + $lang->source_type = 'Chọn nguồn'; + $lang->type_member = 'Data Thành viên'; + $lang->type_message = 'Data Tin nhắn'; + $lang->type_ttxml = 'TTXML'; + $lang->type_module = 'Data Bài viết'; + $lang->type_syncmember = 'Đồng bộ hóa Data Thành viên'; + $lang->target_module = 'Module'; + $lang->xml_file = 'File XML'; + + $lang->import_step_title = array( + 1 => 'Bước 1. Lựa chọn đường dẫn', + 12 => 'Bước 1-2. Chọn Module', + 13 => 'Bước 1-3. Chọn chuyên đề', + 2 => 'Bước 2. Upload File XML', + 3 => 'Bước 2. Đồng bộ hóa Data thành viên và Data bài viết', + 99 => 'Đang đồng bộ hóa dữ liệu.', + ); + + $lang->import_step_desc = array( + 1 => 'Xin hãy chọn Data dưới dạng XML để đồng bộ hóa.', + 12 => 'Xin hãy chọn Module bạn muốn lưu Data.', + 121 => 'Bài viết:', + 122 => 'Sổ lưu niệm:', + 13 => 'Xin hãy chọn chuyên mục để lưu Data.', + 2 => "Xin hãy nhập File Data dưới dạng XML để bắt đầu đồng bộ hóa.\nHãy nhập đường dẫn cho File chứa Data trên Host dưới dạng http://..", + 3 => 'Đã không thể kết nối tới File Data thành viên và bài viết. Nếu đã đúng đường dẫn xin hãy kiểm tra Data với user_id.', + 99 => 'Đang đồng bộ hóa dữ liệu.', + ); + + // guide/alert + $lang->msg_sync_member = 'Data thành viên và bài viết sẽ được đồng bộ hóa sau khi bấm "Đồng bộ".'; + $lang->msg_no_xml_file = 'Không tìm yhấy File XML. Xin hãy kiểm tra lại đường dẫn!'; + $lang->msg_invalid_xml_file = 'Định dạng File XML không hợp lệ.'; + $lang->msg_importing = 'Đang gửi %d Data của %d. (Nếu việc gửi Data không tiếp tục chạy, hãy bấm "Tiếp tục")'; + $lang->msg_import_finished = '%d/%d của Data đã được đồng bộ thành công. Một số nội dung đã không thể đồng bộ.'; + $lang->msg_sync_completed = 'Đã đồng bộ Data thành công.'; + + // blah blah.. + $lang->about_type_member = 'Lựa chọn này sẽ đồng bộ Data thành viên.'; + $lang->about_type_message = 'Lựa chọn này đồng bộ Data tin nhắn.'; + $lang->about_type_ttxml = 'Lựa chọn này sẽ đồng bộ và chuyển đổi Data của Textcube.'; + $lang->about_ttxml_user_id = 'Xin hãy nhập ID sẽ hiển thị là tác giả của những bài viết sau khi Data được chuyển đổi từ TTXML. (ID này phải là thành viên đã đăng kí.)'; + $lang->about_type_module = 'Lựa chọn này sẽ đồng bộ và chuyển đổi các trang và bài viết.'; + $lang->about_type_syncmember = 'Lựa chọn này sẽ đồng bộ thông tin thành viên trước khi đồng bộ Bài viết và thành viên.'; + $lang->about_importer = "Bạn có thể chuyển Data từ Zeroboard4, Zeroboard5 Beta hay Data của những mã nguồn khác vào Data của XE.\nĐể hiểu rõ hơn công việc này, bạn có thể tham khảo cách chuyển đổi Data của bạn vào XE khi bạn đã Upload chúng tại XML Exporter."; + + $lang->about_target_path = "Để lấy cả File đính kèm tại Zeroboard4, bạn hãy nhập địa chỉ mà đã cài đặt Zeroboard4.\nNếu nó cùng nằm trên một Server, hãy nhập đầy đủ đường dẫn thư mục cài đặt của Zeroboard4. Ví dụ: /home/USERID/public_html/bbs\nNếu khác Server, hãy nhập địa chỉ của Zeroboard4 đã cài đặt. Ví dụ: http://Domain/bbs"; +?> diff --git a/modules/importer/lang/zh-CN.lang.php b/modules/importer/lang/zh-CN.lang.php index 0526b0ded..144c85b06 100644 --- a/modules/importer/lang/zh-CN.lang.php +++ b/modules/importer/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ about_ttxml_user_id = '请输入导入TTXML数据时指定为主题发布者的ID(必须是已注册会员)。'; $lang->about_type_module = '数据导入对象为版面主题时请选择此项。'; $lang->about_type_syncmember = '导入会员信息和文章信息后需要同步会员信息时请选择此项。'; - $lang->about_importer = "不仅可以导入Zeroboard 4,Zb5beta的数据,也可以把其他程序数据导入到XE当中。\n导入数据时请利用 XML Exporter生成XML文件后再上传。"; + $lang->about_importer = "不仅可以导入Zeroboard 4,Zb5beta的数据,也可以把其他程序数据导入到XE当中。\n导入数据时请利用 XML Exporter生成XML文件后再上传。"; $lang->about_target_path = "为了下载附件请输入Zeroboard 4的安装位置。\n位置在同一个服务器时,请输入如 /home/id/public_html/bbs的路径,在不同服务器时,请输入如 http://域名/bbs的url地址。"; ?> diff --git a/modules/importer/lang/zh-TW.lang.php b/modules/importer/lang/zh-TW.lang.php index 787f6ccb8..17915cb74 100644 --- a/modules/importer/lang/zh-TW.lang.php +++ b/modules/importer/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ about_ttxml_user_id = '請輸入匯入 TTXML 資料時,指定為主題發表者的 ID (必須是已註冊會員)。'; $lang->about_type_module = '資料匯入目標為討論板主題時,請選擇此項。'; $lang->about_type_syncmember = '匯入會員和文章資料後,需要同步會員資料時,請選擇此項。'; - $lang->about_importer = "不僅可以匯入 Zeroboard 4,Zb5beta 的資料,也能夠把其他程式資料匯入到 XE 當中。\n匯入資料時,請利用 XML Exporter 建立 XML 檔案後再上傳。"; + $lang->about_importer = "不僅可以匯入 Zeroboard 4,Zb5beta 的資料,也能夠把其他程式資料匯入到 XE 當中。\n匯入資料時,請利用 XML Exporter 建立 XML 檔案後再上傳。"; $lang->about_target_path = "為了下載附檔請輸入 Zeroboard 4 的安裝位置。\n位置在同一個主機時,請輸入如『/home/id/public_html/bbs』的路徑,在不同主機時,請輸入如『http://域名/bbs』的 URL 網址。"; ?> diff --git a/modules/importer/tpl/js/importer_admin.js b/modules/importer/tpl/js/importer_admin.js index 095d86ac8..7984166bd 100644 --- a/modules/importer/tpl/js/importer_admin.js +++ b/modules/importer/tpl/js/importer_admin.js @@ -1,170 +1,170 @@ -/** - * @file modules/importer/js/importer_admin.js - * @author zero (zero@nzeo.com) - * @brief importer에서 사용하는 javascript - **/ - -/** - * 회원정보와 게시글/댓글등의 동기화 요청 및 결과 처리 함수 - **/ -function doSync(fo_obj) { - exec_xml('importer','procImporterAdminSync', new Array(), completeSync); - return false; -} - -function completeSync(ret_obj) { - alert(ret_obj['message']); - location.href=location.href; -} - - -/** - * xml파일을 DB입력전에 extract를 통해 분할 캐싱을 요청하는 함수 - **/ -var prepared = false; -function doPreProcessing(fo_obj) { - var xml_file = fo_obj.xml_file.value; - if(!xml_file) return false; - - var type = fo_obj.type.value; - - jQuery('#importForm').hide(); - jQuery('#process').show(); - jQuery('#status').empty(); - prepared = false; - setTimeout(doPrepareDot, 50); - - var params = new Array(); - params['xml_file'] = xml_file; - params['type'] = type; - - var response_tags = new Array('error','message','type','total','cur','key','status'); - exec_xml('importer','procImporterAdminPreProcessing', params, completePreProcessing, response_tags); - - return false; -} - -/* 준비중일때 .(dot) 찍어주는.. */ -function doPrepareDot() { - if(prepared) return; - - var str = jQuery('#status').html(); - if(str.length < 1 || str.length - preProcessingMsg.length > 50) str = preProcessingMsg; - else str += "."; - - jQuery('#status').html(str); - setTimeout(doPrepareDot, 50); -} - -/* 준비가 끝났을때 호출되는 함수 */ -function completePreProcessing(ret_obj, response_tags) { - prepared = true; - jQuery('#status').empty(); - - var status = ret_obj['status']; - var message = ret_obj['message']; - var type = ret_obj['type']; - var total = parseInt(ret_obj['total'],10); - var cur = parseInt(ret_obj['cur'],10); - var key = ret_obj['key']; - - if(status == -1) { - xDisplay('importForm','block'); - xDisplay('process','none'); - xDisplay('btn_reload','block'); - xDisplay('btn_continue','none'); - alert(message); - return; - } - - jQuery('#btn_reload').hide(); - jQuery('#btn_continue').show(); - - var fo_obj = jQuery('#fo_process').get(0); - fo_obj.type.value = type; - fo_obj.total.value = total; - fo_obj.cur.value = cur; - fo_obj.key.value = key; - - var fo_import = jQuery('#fo_import').get(0); - if(fo_import && fo_import.target_module) fo_obj.target_module.value = fo_import.target_module.value; - if(fo_import && fo_import.guestbook_target_module) fo_obj.guestbook_target_module.value = fo_import.guestbook_target_module.value; - if(fo_import && fo_import.user_id) fo_obj.user_id.value = fo_import.user_id.value; - - fo_obj.unit_count.value = fo_import.unit_count.options[fo_import.unit_count.selectedIndex].value; - - // extract된 파일을 이용해서 import - doImport(); -} - -/* @brief 임포트 시작 */ -function doImport() { - var fo_obj = jQuery('#fo_process').get(0); - - var params = new Array(); - params['type'] = fo_obj.type.value; - params['total'] = fo_obj.total.value; - params['cur'] = fo_obj.cur.value; - params['key'] = fo_obj.key.value; - params['target_module'] = fo_obj.target_module.value; - params['guestbook_target_module'] = fo_obj.guestbook_target_module.value; - params['unit_count'] = fo_obj.unit_count.value; - params['user_id'] = fo_obj.user_id.value; - - displayProgress(params['total'], params['cur']); - - var response_tags = new Array('error','message','type','total','cur','key'); - - show_waiting_message = false; - exec_xml('importer','procImporterAdminImport', params, completeImport, response_tags); - show_waiting_message = true; - - return false; -} - - -/* import중 표시 */ -function completeImport(ret_obj, response_tags) { - var message = ret_obj['message']; - var type = ret_obj['type']; - var total = parseInt(ret_obj['total'], 10); - var cur = parseInt(ret_obj['cur'], 10); - var key = ret_obj['key']; - - displayProgress(total, cur); - - var fo_obj = jQuery('#fo_process').get(0); - fo_obj.type.value = type; - fo_obj.total.value = total; - fo_obj.cur.value = cur; - fo_obj.key.value = key; - - // extract된 파일을 이용해서 import - if(total > cur) doImport(); - else { - alert(message); - fo_obj.reset(); - jQuery('#process').hide(); - jQuery('#importForm').show(); - jQuery('#fo_import').get(0).reset(); - } -} - -/* 상태 표시 함수 */ -function displayProgress(total, cur) { - // 진행률 구함 - var per = 0; - if(total > 0) per = Math.round(cur / total * 100); - else per = 100; - if(!per) per = 1; - - var status = '
'+per+'% 
'; - status += '
'+cur+'/'+total+'
'; - status += '
'; - jQuery('#status').html(status); -} - -function insertSelectedModule(id, module_srl, mid, browser_title) { - jQuery('#' + id).val(module_srl); - jQuery('#_' + id).val(browser_title+' ('+mid+')'); -} +/** + * @file modules/importer/js/importer_admin.js + * @author NHN (developers@xpressengine.com) + * @brief importer에서 사용하는 javascript + **/ + +/** + * 회원정보와 게시글/댓글등의 동기화 요청 및 결과 처리 함수 + **/ +function doSync(fo_obj) { + exec_xml('importer','procImporterAdminSync', new Array(), completeSync); + return false; +} + +function completeSync(ret_obj) { + alert(ret_obj['message']); + location.href=location.href; +} + + +/** + * xml파일을 DB입력전에 extract를 통해 분할 캐싱을 요청하는 함수 + **/ +var prepared = false; +function doPreProcessing(fo_obj) { + var xml_file = fo_obj.xml_file.value; + if(!xml_file) return false; + + var type = fo_obj.type.value; + + jQuery('#importForm').hide(); + jQuery('#process').show(); + jQuery('#status').empty(); + prepared = false; + setTimeout(doPrepareDot, 50); + + var params = new Array(); + params['xml_file'] = xml_file; + params['type'] = type; + + var response_tags = new Array('error','message','type','total','cur','key','status'); + exec_xml('importer','procImporterAdminPreProcessing', params, completePreProcessing, response_tags); + + return false; +} + +/* 준비중일때 .(dot) 찍어주는.. */ +function doPrepareDot() { + if(prepared) return; + + var str = jQuery('#status').html(); + if(str.length < 1 || str.length - preProcessingMsg.length > 50) str = preProcessingMsg; + else str += "."; + + jQuery('#status').html(str); + setTimeout(doPrepareDot, 50); +} + +/* 준비가 끝났을때 호출되는 함수 */ +function completePreProcessing(ret_obj, response_tags) { + prepared = true; + jQuery('#status').empty(); + + var status = ret_obj['status']; + var message = ret_obj['message']; + var type = ret_obj['type']; + var total = parseInt(ret_obj['total'],10); + var cur = parseInt(ret_obj['cur'],10); + var key = ret_obj['key']; + + if(status == -1) { + xDisplay('importForm','block'); + xDisplay('process','none'); + xDisplay('btn_reload','block'); + xDisplay('btn_continue','none'); + alert(message); + return; + } + + jQuery('#btn_reload').hide(); + jQuery('#btn_continue').show(); + + var fo_obj = jQuery('#fo_process').get(0); + fo_obj.type.value = type; + fo_obj.total.value = total; + fo_obj.cur.value = cur; + fo_obj.key.value = key; + + var fo_import = jQuery('#fo_import').get(0); + if(fo_import && fo_import.target_module) fo_obj.target_module.value = fo_import.target_module.value; + if(fo_import && fo_import.guestbook_target_module) fo_obj.guestbook_target_module.value = fo_import.guestbook_target_module.value; + if(fo_import && fo_import.user_id) fo_obj.user_id.value = fo_import.user_id.value; + + fo_obj.unit_count.value = fo_import.unit_count.options[fo_import.unit_count.selectedIndex].value; + + // extract된 파일을 이용해서 import + doImport(); +} + +/* @brief 임포트 시작 */ +function doImport() { + var fo_obj = jQuery('#fo_process').get(0); + + var params = new Array(); + params['type'] = fo_obj.type.value; + params['total'] = fo_obj.total.value; + params['cur'] = fo_obj.cur.value; + params['key'] = fo_obj.key.value; + params['target_module'] = fo_obj.target_module.value; + params['guestbook_target_module'] = fo_obj.guestbook_target_module.value; + params['unit_count'] = fo_obj.unit_count.value; + params['user_id'] = fo_obj.user_id.value; + + displayProgress(params['total'], params['cur']); + + var response_tags = new Array('error','message','type','total','cur','key'); + + show_waiting_message = false; + exec_xml('importer','procImporterAdminImport', params, completeImport, response_tags); + show_waiting_message = true; + + return false; +} + + +/* import중 표시 */ +function completeImport(ret_obj, response_tags) { + var message = ret_obj['message']; + var type = ret_obj['type']; + var total = parseInt(ret_obj['total'], 10); + var cur = parseInt(ret_obj['cur'], 10); + var key = ret_obj['key']; + + displayProgress(total, cur); + + var fo_obj = jQuery('#fo_process').get(0); + fo_obj.type.value = type; + fo_obj.total.value = total; + fo_obj.cur.value = cur; + fo_obj.key.value = key; + + // extract된 파일을 이용해서 import + if(total > cur) doImport(); + else { + alert(message); + fo_obj.reset(); + jQuery('#process').hide(); + jQuery('#importForm').show(); + jQuery('#fo_import').get(0).reset(); + } +} + +/* 상태 표시 함수 */ +function displayProgress(total, cur) { + // 진행률 구함 + var per = 0; + if(total > 0) per = Math.round(cur / total * 100); + else per = 100; + if(!per) per = 1; + + var status = '
'+per+'% 
'; + status += '
'+cur+'/'+total+'
'; + status += '
'; + jQuery('#status').html(status); +} + +function insertSelectedModule(id, module_srl, mid, browser_title) { + jQuery('#' + id).val(module_srl); + jQuery('#_' + id).val(browser_title+' ('+mid+')'); +} diff --git a/modules/importer/ttimport.class.php b/modules/importer/ttimport.class.php index 2304ce4f5..7793dba01 100644 --- a/modules/importer/ttimport.class.php +++ b/modules/importer/ttimport.class.php @@ -1,638 +1,638 @@ -oXmlParser = new XmlParser(); - - // 타겟 모듈의 카테고리 정보 구함 - $oDocumentController = &getController('document'); - $oDocumentModel = &getModel('document'); - $category_list = $category_titles = array(); - $category_list = $oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - - // 먼저 카테고리 정보를 입력함 - $category_file = preg_replace('/index$/i', 'category.xml', $index_file); - if(file_exists($category_file)) { - // xmlParser객체 생성 - $xmlDoc = $this->oXmlParser->loadXmlFile($category_file); - - // 카테고리 정보를 정리 - if($xmlDoc->categories->category) { - $categories = array(); - $idx = 0; - $this->arrangeCategory($xmlDoc->categories, $categories, $idx, 0); - - $match_sequence = array(); - foreach($categories as $k => $v) { - $category = $v->name; - if(!$category || $category_titles[$category]) continue; - - $obj = null; - $obj->title = $category; - $obj->module_srl = $module_srl; - if($v->parent) $obj->parent_srl = $match_sequence[$v->parent]; - $output = $oDocumentController->insertCategory($obj); - - if($output->toBool()) $match_sequence[$v->sequence] = $category_titles[$category] = $output->get('category_srl'); - } - $oDocumentController->makeCategoryFile($module_srl); - } - FileHandler::removeFile($category_file); - } - $category_list = $category_titles = array(); - $category_list = $oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - - // 관리자 정보를 구함 - $oMemberModel = &getModel('member'); - $member_info = $oMemberModel->getMemberInfoByUserID($user_id); - $author_xml_id = 0; - - if(!$cur) $cur = 0; - - // index파일을 염 - $f = fopen($index_file,"r"); - - // 이미 읽혀진 것은 패스 - for($i=0;$i<$cur;$i++) fgets($f, 1024); - - // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$unit_count개보다 작으면 중지 - for($idx=$cur;$idx<$cur+$unit_count;$idx++) { - if(feof($f)) break; - - // 정해진 위치를 찾음 - $target_file = trim(fgets($f, 1024)); - - if(!file_exists($target_file)) continue; - - // 이제부터 데이터를 가져오면서 처리 - $fp = fopen($target_file,"r"); - if(!$fp) continue; - - $obj = null; - $obj->module_srl = $module_srl; - $obj->document_srl = getNextSequence(); - $obj->uploaded_count = 0; - - $files = array(); - - $started = false; - $buff = null; - - // 본문 데이터부터 처리 시작 - while(!feof($fp)) { - $str = fgets($fp, 1024); - - // 한 아이템 준비 시작 - if(substr($str,0,5) == 'importAttaches($fp, $module_srl, $obj->document_srl, $files, $str)) $obj->uploaded_count++; - continue; - } - - if($started) $buff .= $str; - } - - $xmlDoc = $this->oXmlParser->parse(''.$buff); - - $author_xml_id = $xmlDoc->post->author->body; - - - if($xmlDoc->post->category->body) { - $tmp_arr = explode('/',$xmlDoc->post->category->body); - $category = trim($tmp_arr[count($tmp_arr)-1]); - if($category_titles[$category]) $obj->category_srl = $category_titles[$category]; - } - - $obj->is_notice = 'N'; - $obj->is_secret = in_array($xmlDoc->post->visibility->body, array('public','syndicated'))?'N':'Y'; - $obj->title = $xmlDoc->post->title->body; - $obj->content = $xmlDoc->post->content->body; - $obj->password = md5($xmlDoc->post->password->body); - $obj->allow_comment = $xmlDoc->post->acceptcomment->body=='1'?'Y':'N'; - $obj->allow_trackback = $xmlDoc->post->accepttrackback->body=='1'?'Y':'N'; - //$obj->allow_comment = $xmlDoc->post->acceptComment->body=='1'?'Y':'N'; - //$obj->allow_trackback = $xmlDoc->post->acceptTrackback->body=='1'?'Y':'N'; - $obj->regdate = date("YmdHis",$xmlDoc->post->published->body); - $obj->last_update = date("YmdHis", $xmlDoc->post->modified->body); - if(!$obj->last_update) $obj->last_update = $obj->regdate; - - $tag = null; - $tmp_tags = null; - $tag = $xmlDoc->post->tag; - if($tag) { - if(!is_array($tag)) $tag = array($tag); - foreach($tag as $key => $val) $tmp_tags[] = $val->body; - $obj->tags = implode(',',$tmp_tags); - } - - $obj->readed_count = 0; - $obj->voted_count = 0; - $obj->nick_name = $member_info->nick_name; - $obj->user_name = $member_info->user_name; - $obj->user_id = $member_info->user_id; - $obj->member_srl = $member_info->member_srl; - $obj->email_address = $member_info->email_address; - $obj->homepage = $member_info->homepage; - $obj->ipaddress = $_REMOTE['SERVER_ADDR']; - $obj->list_order = $obj->update_order = $obj->document_srl*-1; - $obj->lock_comment = 'N'; - $obj->notify_message = 'N'; - - // content 정보 변경 (첨부파일) - $obj->content = str_replace('[##_ATTACH_PATH_##]/','',$obj->content); - if(count($files)) { - foreach($files as $key => $val) { - $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val->url.'"',$obj->content); - } - } - - $obj->content = preg_replace_callback('!\[##_Movie\|([^\|]*)\|(.*?)_##\]!is', array($this, '_replaceTTMovie'), $obj->content); - - if(count($files)) { - $this->files = $files; - $obj->content = preg_replace_callback('!\[##_([a-z0-9]+)\|([^\|]*)\|([^\|]*)\|(.*?)_##\]!is', array($this, '_replaceTTAttach'), $obj->content); - } - - // 역인글 입력 - $obj->trackback_count = 0; - if($xmlDoc->post->trackback) { - $trackbacks = $xmlDoc->post->trackback; - if(!is_array($trackbacks)) $trackbacks = array($trackbacks); - if(count($trackbacks)) { - foreach($trackbacks as $key => $val) { - $tobj = null; - $tobj->trackback_srl = getNextSequence(); - $tobj->module_srl = $module_srl; - $tobj->document_srl = $obj->document_srl; - $tobj->url = $val->url->body; - $tobj->title = $val->title->body; - $tobj->blog_name = $val->site->body; - $tobj->excerpt = $val->excerpt->body; - $tobj->regdate = date("YmdHis",$val->received->body); - $tobj->ipaddress = $val->ip->body; - $tobj->list_order = -1*$tobj->trackback_srl; - $output = executeQuery('trackback.insertTrackback', $tobj); - if($output->toBool()) $obj->trackback_count++; - } - } - } - - // 댓글입력 - $obj->comment_count = 0; - if($xmlDoc->post->comment) { - $comment = $xmlDoc->post->comment; - if(!is_array($comment)) $comment = array($comment); - foreach($comment as $key => $val) { - $parent_srl = $this->insertComment($val, $module_srl, $obj->document_srl, $member_info, 0, $author_xml_id); - if($parent_srl === false) continue; - - $obj->comment_count++; - if($val->comment) { - $child_comment = $val->comment; - if(!is_array($child_comment)) $child_comment = array($child_comment); - foreach($child_comment as $k => $v) { - $result = $this->insertComment($v, $module_srl, $obj->document_srl, $member_info, $parent_srl, $author_xml_id); - if($result !== false) $obj->comment_count++; - } - } - } - } - - if($module_name == 'textyle') { - $args->document_srl = $obj->document_srl; - $args->module_srl = $obj->module_srl; - $args->logs = serialize(null); - $output = executeQuery('textyle.insertPublishLog', $args); - - // 발행 상태의 visibility 값 - $status_published = array('public', 'syndicated'); - // 발행이 아닌 것들은 저장상태로 - if(!in_array($xmlDoc->post->visibility->body, $status_published)) { - $obj->module_srl = $member_info->member_srl; - } - } - - // 문서 입력 - $output = executeQuery('document.insertDocument', $obj); - - if($output->toBool()) { - // 태그 입력 - if($obj->tags) { - $tag_list = explode(',',$obj->tags); - $tag_count = count($tag_list); - for($i=0;$i<$tag_count;$i++) { - $args = null; - $args->tag_srl = getNextSequence(); - $args->module_srl = $module_srl; - $args->document_srl = $obj->document_srl; - $args->tag = trim($tag_list[$i]); - $args->regdate = $obj->regdate; - if(!$args->tag) continue; - $output = executeQuery('tag.insertTag', $args); - } - } - } - - fclose($fp); - FileHandler::removeFile($target_file); - } - - fclose($f); - - if(count($category_list)) foreach($category_list as $key => $val) $oDocumentController->updateCategoryCount($module_srl, $val->category_srl); - - - // 방명록 정보를 입력함 - $guestbook_file = preg_replace('/index$/i', 'guestbook.xml', $index_file); - if (file_exists($guestbook_file)) { - // xmlParser객체 생성 - $xmlDoc = $this->oXmlParser->loadXmlFile($guestbook_file); - - // 방명록 정보를 처리 - if($guestbook_module_srl && $xmlDoc->guestbook->comment) { - $comment = $xmlDoc->guestbook->comment; - if(!is_array($comment)) $comment = array($comment); - - if($module_name =='textyle'){ - foreach($comment as $key => $val) { - $textyle_guestbook_srl = getNextSequence(); - - if($val->comment) { - $child_comment = $val->comment; - if(!is_array($child_comment)) $child_comment = array($child_comment); - foreach($child_comment as $k => $v) { - $result = $this->insertTextyleGuestbookItem($v, $module_srl, $member_info,0,$textyle_guestbook_srl,$author_xml_id); - } - } - - $result = $this->insertTextyleGuestbookItem($val, $module_srl, $member_info,$textyle_guestbook_srl,0,$author_xml_id); - } - }else{ - foreach($comment as $key => $val) { - $obj = null; - $obj->module_srl = $guestbook_module_srl; - $obj->document_srl = getNextSequence(); - $obj->uploaded_count = 0; - $obj->is_notice = 'N'; - $obj->is_secret = $val->secret->body=='1'?'Y':'N'; - $obj->content = nl2br($val->content->body); - - // 본문에서 제목 추출 - $obj->title = cut_str(strip_tags($obj->content),20,'...'); - if ($obj->title == '') $obj->title = 'Untitled'; - - $obj->allow_comment = 'Y'; - $obj->allow_trackback = 'N'; - $obj->regdate = date("YmdHis",$val->written->body); - $obj->last_update = date("YmdHis", $val->written->body); - if(!$obj->last_update) $obj->last_update = $obj->regdate; - $obj->tags = ''; - $obj->readed_count = 0; - $obj->voted_count = 0; - if ($author_xml_id && $val->commenter->attrs->id == $author_xml_id) { - $obj->password = ''; - $obj->nick_name = $member_info->nick_name; - $obj->user_name = $member_info->user_name; - $obj->user_id = $member_info->user_id; - $obj->member_srl = $member_info->member_srl; - $obj->email_address = $member_info->email_address; - $obj->homepage = $member_info->homepage; - } - else { - $obj->password = $val->password->body; - $obj->nick_name = $val->commenter->name->body; - $obj->member_srl = 0; - $homepage = $val->commenter->homepage->body; - } - $obj->ipaddress = $val->commenter->ip->body; - $obj->list_order = $obj->update_order = $obj->document_srl*-1; - $obj->lock_comment = 'N'; - $obj->notify_message = 'N'; - $obj->trackback_count = 0; - - $obj->comment_count = 0; - if($val->comment) { - $child_comment = $val->comment; - if(!is_array($child_comment)) $child_comment = array($child_comment); - foreach($child_comment as $k => $v) { - $result = $this->insertComment($v, $module_srl, $obj->document_srl, $member_info, 0,$author_xml_id); - if($result !== false) $obj->comment_count++; - } - } - - // 문서 입력 - $output = executeQuery('document.insertDocument', $obj); - } - } - } - FileHandler::removeFile($guestbook_file); - } - - return $idx-1; - } - - - function insertTextyleGuestbookItem($val, $module_srl, $member_info, $textyle_guestbook_srl,$parent_srl = 0, $author_xml_id=null) { - $tobj = null; - if($textyle_guestbook_srl>0){ - $tobj->textyle_guestbook_srl = $textyle_guestbook_srl; - }else{ - $tobj->textyle_guestbook_srl = getNextSequence(); - } - $tobj->module_srl = $module_srl; - $tobj->is_secret = $val->secret->body=='1'?1:-1; - $tobj->content = nl2br($val->content->body); - if($author_xml_id && $val->commenter->attrs->id == $author_xml_id) { - $tobj->password = ''; - $tobj->nick_name = $member_info->nick_name; - $tobj->user_name = $member_info->user_name; - $tobj->user_id = $member_info->user_id; - $tobj->member_srl = $member_info->member_srl; - $tobj->homepage = $member_info->homepage; - $tobj->email_address = $member_info->email_address; - } else { - $tobj->password = $val->password->body; - $tobj->nick_name = $val->commenter->name->body; - $tobj->homepage = $val->commenter->homepage->body; - $tobj->member_srl = 0; - } - $tobj->last_update = $tobj->regdate = date("YmdHis",$val->written->body); - $tobj->ipaddress = $val->commenter->ip->body; - - if($parent_srl>0){ - $tobj->parent_srl = $parent_srl; - $tobj->list_order = $tobj->parent_srl * -1; - }else{ - $tobj->list_order = $tobj->textyle_guestbook_srl*-1; - } - - $output = executeQuery('textyle.insertTextyleGuestbook', $tobj); - - if($output->toBool()) return $tobj->textyle_guestbook_srl; - return false; - } - - - /** - * @brief 첨부파일 정리 - **/ - function importAttaches($fp, $module_srl, $upload_target_srl, &$files, $buff) { - $uploaded_count = 0; - - $file_obj = null; - $file_obj->file_srl = getNextSequence(); - $file_obj->upload_target_srl = $upload_target_srl; - $file_obj->module_srl = $module_srl; - - while(!feof($fp)) { - $str = fgets($fp, 1024); - - // 로 끝나면 중단 - if(trim($str) == '') break; - - // 로 시작하면 xml파일내의 첨부파일로 처리 - if(substr($str, 0, 9)=='') { - $file_obj->file = $this->saveTemporaryFile($fp, $str); - continue; - } - - $buff .= $str; - } - if(!file_exists($file_obj->file)) return false; - - $buff .= ''; - - $xmlDoc = $this->oXmlParser->parse($buff); - - $file_obj->source_filename = $xmlDoc->attachment->label->body; - $file_obj->download_count = $xmlDoc->attachment->downloads->body; - $name = $xmlDoc->attachment->name->body; - - // 이미지인지 기타 파일인지 체크하여 upload path 지정 - if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_obj->source_filename)) { - $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3)); - $filename = $path.$file_obj->source_filename; - $file_obj->direct_download = 'Y'; - } else { - $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); - $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); - $file_obj->direct_download = 'N'; - } - - // 디렉토리 생성 - if(!FileHandler::makeDir($path)) return; - - FileHandler::rename($file_obj->file, $filename); - - // DB입력 - unset($file_obj->file); - $file_obj->uploaded_filename = $filename; - $file_obj->file_size = filesize($filename); - $file_obj->comment = NULL; - $file_obj->member_srl = 0; - $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); - $file_obj->isvalid = 'Y'; - $output = executeQuery('file.insertFile', $file_obj); - - if($output->toBool()) { - $uploaded_count++; - $tmp_obj = null; - if($file_obj->direct_download == 'Y') $files[$name]->url = $file_obj->uploaded_filename; - else $files[$name]->url = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid); - $files[$name]->direct_download = $file_obj->direct_download; - $files[$name]->source_filename = $file_obj->source_filename; - return true; - } - - return false; - } - - /** - * @biref 임의로 사용할 파일이름을 return - **/ - function getTmpFilename() { - $path = "./files/cache/importer"; - if(!is_dir($path)) FileHandler::makeDir($path); - $filename = sprintf("%s/%d", $path, rand(11111111,99999999)); - if(file_exists($filename)) $filename .= rand(111,999); - return $filename; - } - - /** - * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 - **/ - function saveTemporaryFile($fp, $buff) { - $temp_filename = $this->getTmpFilename(); - $buff = substr($buff, 9); - - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - $buff .= $str; - if(substr($str, -10) == '') break; - } - - $buff = substr($buff, 0, -10); - - $f = fopen($temp_filename, "w"); - fwrite($f, base64_decode($buff)); - fclose($f); - return $temp_filename; - } - - /** - * @brief ttxml의 자체 img 태그를 치환 - **/ - function _replaceTTAttach($matches) { - $name = $matches[2]; - if(!$name) return $matches[0]; - - $obj = $this->files[$name]; - - // 멀티미디어성 파일의 경우 - if($obj->direct_download == 'Y') { - // 이미지의 경우 - if(preg_match('/\.(jpg|gif|jpeg|png)$/i', $obj->source_filename)) { - return sprintf('%s', $obj->url, str_replace('"','\\"',$matches[4])); - // 이미지 외의 멀티미디어성 파일의 경우 - } else { - return sprintf('', $obj->url); - } - - // binary파일일 경우 - } else { - return sprintf('%s', $obj->url, $obj->source_filename); - } - } - - /** - * @brief ttxml의 동영상 변환 - **/ - function _replaceTTMovie($matches) { - $key = $matches[1]; - if(!$key) return $matches[0]; - - return - ''. - ''. - ''. - ''. - ''. - ''. - ''; - } - - /** - * @brief 댓글 입력 - **/ - function insertComment($val, $module_srl, $document_srl, $member_info, $parent_srl = 0, $author_xml_id) { - $tobj = null; - $tobj->comment_srl = getNextSequence(); - $tobj->module_srl = $module_srl; - $tobj->document_srl = $document_srl; - $tobj->is_secret = $val->secret->body=='1'?'Y':'N'; - $tobj->notify_message = 'N'; - $tobj->content = nl2br($val->content->body); - $tobj->voted_count = 0; - if ($author_xml_id && $val->commenter->attrs->id == $author_xml_id) { - $tobj->password = ''; - $tobj->nick_name = $member_info->nick_name; - $tobj->user_name = $member_info->user_name; - $tobj->user_id = $member_info->user_id; - $tobj->member_srl = $member_info->member_srl; - $tobj->homepage = $member_info->homepage; - $tobj->email_address = $member_info->email_address; - } else { - $tobj->password = $val->password->body; - $tobj->nick_name = $val->commenter->name->body; - $tobj->homepage = $val->commenter->homepage->body; - $tobj->member_srl = 0; - } - $tobj->last_update = $tobj->regdate = date("YmdHis",$val->written->body); - $tobj->ipaddress = $val->commenter->ip->body; - $tobj->list_order = $tobj->comment_srl*-1; - $tobj->sequence = $sequence; - $tobj->parent_srl = $parent_srl; - - // 댓글 목록 부분을 먼저 입력 - $list_args = null; - $list_args->comment_srl = $tobj->comment_srl; - $list_args->document_srl = $tobj->document_srl; - $list_args->module_srl = $tobj->module_srl; - $list_args->regdate = $tobj->regdate; - - // 부모댓글이 없으면 바로 데이터를 설정 - if(!$tobj->parent_srl) { - $list_args->head = $list_args->arrange = $tobj->comment_srl; - $list_args->depth = 0; - - // 부모댓글이 있으면 부모글의 정보를 구해옴 - } else { - // 부모댓글의 정보를 구함 - $parent_args->comment_srl = $tobj->parent_srl; - $parent_output = executeQuery('comment.getCommentListItem', $parent_args); - - // 부모댓글이 존재하지 않으면 return - if(!$parent_output->toBool() || !$parent_output->data) return false; - $parent = $parent_output->data; - - $list_args->head = $parent->head; - $list_args->depth = $parent->depth+1; - if($list_args->depth<2) $list_args->arrange = $tobj->comment_srl; - else { - $list_args->arrange = $parent->arrange; - $output = executeQuery('comment.updateCommentListArrange', $list_args); - if(!$output->toBool()) return $output; - } - } - - $output = executeQuery('comment.insertCommentList', $list_args); - if($output->toBool()) { - $output = executeQuery('comment.insertComment', $tobj); - if($output->toBool()) return $tobj->comment_srl; - } - return false; - } - - // 카테고리 정리 - function arrangeCategory($obj, &$category, &$idx, $parent = 0) { - if(!$obj->category) return; - if(!is_array($obj->category)) $c = array($obj->category); - else $c = $obj->category; - foreach($c as $val) { - $idx++; - $priority = $val->priority->body; - $name = $val->name->body; - $obj = null; - $obj->priority = $priority; - $obj->name = $name; - $obj->sequence = $idx; - $obj->parent = $parent; - - $category[$idx] = $obj; - - $this->arrangeCategory($val, $category, $idx, $idx); - } - } - } -?> +oXmlParser = new XmlParser(); + + // 타겟 모듈의 카테고리 정보 구함 + $oDocumentController = &getController('document'); + $oDocumentModel = &getModel('document'); + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + // 먼저 카테고리 정보를 입력함 + $category_file = preg_replace('/index$/i', 'category.xml', $index_file); + if(file_exists($category_file)) { + // xmlParser객체 생성 + $xmlDoc = $this->oXmlParser->loadXmlFile($category_file); + + // 카테고리 정보를 정리 + if($xmlDoc->categories->category) { + $categories = array(); + $idx = 0; + $this->arrangeCategory($xmlDoc->categories, $categories, $idx, 0); + + $match_sequence = array(); + foreach($categories as $k => $v) { + $category = $v->name; + if(!$category || $category_titles[$category]) continue; + + $obj = null; + $obj->title = $category; + $obj->module_srl = $module_srl; + if($v->parent) $obj->parent_srl = $match_sequence[$v->parent]; + $output = $oDocumentController->insertCategory($obj); + + if($output->toBool()) $match_sequence[$v->sequence] = $category_titles[$category] = $output->get('category_srl'); + } + $oDocumentController->makeCategoryFile($module_srl); + } + FileHandler::removeFile($category_file); + } + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + // 관리자 정보를 구함 + $oMemberModel = &getModel('member'); + $member_info = $oMemberModel->getMemberInfoByUserID($user_id); + $author_xml_id = 0; + + if(!$cur) $cur = 0; + + // index파일을 염 + $f = fopen($index_file,"r"); + + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); + + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$unit_count;$idx++) { + if(feof($f)) break; + + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); + + if(!file_exists($target_file)) continue; + + // 이제부터 데이터를 가져오면서 처리 + $fp = fopen($target_file,"r"); + if(!$fp) continue; + + $obj = null; + $obj->module_srl = $module_srl; + $obj->document_srl = getNextSequence(); + $obj->uploaded_count = 0; + + $files = array(); + + $started = false; + $buff = null; + + // 본문 데이터부터 처리 시작 + while(!feof($fp)) { + $str = fgets($fp, 1024); + + // 한 아이템 준비 시작 + if(substr($str,0,5) == 'importAttaches($fp, $module_srl, $obj->document_srl, $files, $str)) $obj->uploaded_count++; + continue; + } + + if($started) $buff .= $str; + } + + $xmlDoc = $this->oXmlParser->parse(''.$buff); + + $author_xml_id = $xmlDoc->post->author->body; + + + if($xmlDoc->post->category->body) { + $tmp_arr = explode('/',$xmlDoc->post->category->body); + $category = trim($tmp_arr[count($tmp_arr)-1]); + if($category_titles[$category]) $obj->category_srl = $category_titles[$category]; + } + + $obj->is_notice = 'N'; + $obj->is_secret = in_array($xmlDoc->post->visibility->body, array('public','syndicated'))?'N':'Y'; + $obj->title = $xmlDoc->post->title->body; + $obj->content = $xmlDoc->post->content->body; + $obj->password = md5($xmlDoc->post->password->body); + $obj->allow_comment = $xmlDoc->post->acceptcomment->body=='1'?'Y':'N'; + $obj->allow_trackback = $xmlDoc->post->accepttrackback->body=='1'?'Y':'N'; + //$obj->allow_comment = $xmlDoc->post->acceptComment->body=='1'?'Y':'N'; + //$obj->allow_trackback = $xmlDoc->post->acceptTrackback->body=='1'?'Y':'N'; + $obj->regdate = date("YmdHis",$xmlDoc->post->published->body); + $obj->last_update = date("YmdHis", $xmlDoc->post->modified->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + + $tag = null; + $tmp_tags = null; + $tag = $xmlDoc->post->tag; + if($tag) { + if(!is_array($tag)) $tag = array($tag); + foreach($tag as $key => $val) $tmp_tags[] = $val->body; + $obj->tags = implode(',',$tmp_tags); + } + + $obj->readed_count = 0; + $obj->voted_count = 0; + $obj->nick_name = $member_info->nick_name; + $obj->user_name = $member_info->user_name; + $obj->user_id = $member_info->user_id; + $obj->member_srl = $member_info->member_srl; + $obj->email_address = $member_info->email_address; + $obj->homepage = $member_info->homepage; + $obj->ipaddress = $_REMOTE['SERVER_ADDR']; + $obj->list_order = $obj->update_order = $obj->document_srl*-1; + $obj->lock_comment = 'N'; + $obj->notify_message = 'N'; + + // content 정보 변경 (첨부파일) + $obj->content = str_replace('[##_ATTACH_PATH_##]/','',$obj->content); + if(count($files)) { + foreach($files as $key => $val) { + $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val->url.'"',$obj->content); + } + } + + $obj->content = preg_replace_callback('!\[##_Movie\|([^\|]*)\|(.*?)_##\]!is', array($this, '_replaceTTMovie'), $obj->content); + + if(count($files)) { + $this->files = $files; + $obj->content = preg_replace_callback('!\[##_([a-z0-9]+)\|([^\|]*)\|([^\|]*)\|(.*?)_##\]!is', array($this, '_replaceTTAttach'), $obj->content); + } + + // 역인글 입력 + $obj->trackback_count = 0; + if($xmlDoc->post->trackback) { + $trackbacks = $xmlDoc->post->trackback; + if(!is_array($trackbacks)) $trackbacks = array($trackbacks); + if(count($trackbacks)) { + foreach($trackbacks as $key => $val) { + $tobj = null; + $tobj->trackback_srl = getNextSequence(); + $tobj->module_srl = $module_srl; + $tobj->document_srl = $obj->document_srl; + $tobj->url = $val->url->body; + $tobj->title = $val->title->body; + $tobj->blog_name = $val->site->body; + $tobj->excerpt = $val->excerpt->body; + $tobj->regdate = date("YmdHis",$val->received->body); + $tobj->ipaddress = $val->ip->body; + $tobj->list_order = -1*$tobj->trackback_srl; + $output = executeQuery('trackback.insertTrackback', $tobj); + if($output->toBool()) $obj->trackback_count++; + } + } + } + + // 댓글입력 + $obj->comment_count = 0; + if($xmlDoc->post->comment) { + $comment = $xmlDoc->post->comment; + if(!is_array($comment)) $comment = array($comment); + foreach($comment as $key => $val) { + $parent_srl = $this->insertComment($val, $module_srl, $obj->document_srl, $member_info, 0, $author_xml_id); + if($parent_srl === false) continue; + + $obj->comment_count++; + if($val->comment) { + $child_comment = $val->comment; + if(!is_array($child_comment)) $child_comment = array($child_comment); + foreach($child_comment as $k => $v) { + $result = $this->insertComment($v, $module_srl, $obj->document_srl, $member_info, $parent_srl, $author_xml_id); + if($result !== false) $obj->comment_count++; + } + } + } + } + + if($module_name == 'textyle') { + $args->document_srl = $obj->document_srl; + $args->module_srl = $obj->module_srl; + $args->logs = serialize(null); + $output = executeQuery('textyle.insertPublishLog', $args); + + // 발행 상태의 visibility 값 + $status_published = array('public', 'syndicated'); + // 발행이 아닌 것들은 저장상태로 + if(!in_array($xmlDoc->post->visibility->body, $status_published)) { + $obj->module_srl = $member_info->member_srl; + } + } + + // 문서 입력 + $output = executeQuery('document.insertDocument', $obj); + + if($output->toBool()) { + // 태그 입력 + if($obj->tags) { + $tag_list = explode(',',$obj->tags); + $tag_count = count($tag_list); + for($i=0;$i<$tag_count;$i++) { + $args = null; + $args->tag_srl = getNextSequence(); + $args->module_srl = $module_srl; + $args->document_srl = $obj->document_srl; + $args->tag = trim($tag_list[$i]); + $args->regdate = $obj->regdate; + if(!$args->tag) continue; + $output = executeQuery('tag.insertTag', $args); + } + } + } + + fclose($fp); + FileHandler::removeFile($target_file); + } + + fclose($f); + + if(count($category_list)) foreach($category_list as $key => $val) $oDocumentController->updateCategoryCount($module_srl, $val->category_srl); + + + // 방명록 정보를 입력함 + $guestbook_file = preg_replace('/index$/i', 'guestbook.xml', $index_file); + if (file_exists($guestbook_file)) { + // xmlParser객체 생성 + $xmlDoc = $this->oXmlParser->loadXmlFile($guestbook_file); + + // 방명록 정보를 처리 + if($guestbook_module_srl && $xmlDoc->guestbook->comment) { + $comment = $xmlDoc->guestbook->comment; + if(!is_array($comment)) $comment = array($comment); + + if($module_name =='textyle'){ + foreach($comment as $key => $val) { + $textyle_guestbook_srl = getNextSequence(); + + if($val->comment) { + $child_comment = $val->comment; + if(!is_array($child_comment)) $child_comment = array($child_comment); + foreach($child_comment as $k => $v) { + $result = $this->insertTextyleGuestbookItem($v, $module_srl, $member_info,0,$textyle_guestbook_srl,$author_xml_id); + } + } + + $result = $this->insertTextyleGuestbookItem($val, $module_srl, $member_info,$textyle_guestbook_srl,0,$author_xml_id); + } + }else{ + foreach($comment as $key => $val) { + $obj = null; + $obj->module_srl = $guestbook_module_srl; + $obj->document_srl = getNextSequence(); + $obj->uploaded_count = 0; + $obj->is_notice = 'N'; + $obj->is_secret = $val->secret->body=='1'?'Y':'N'; + $obj->content = nl2br($val->content->body); + + // 본문에서 제목 추출 + $obj->title = cut_str(strip_tags($obj->content),20,'...'); + if ($obj->title == '') $obj->title = 'Untitled'; + + $obj->allow_comment = 'Y'; + $obj->allow_trackback = 'N'; + $obj->regdate = date("YmdHis",$val->written->body); + $obj->last_update = date("YmdHis", $val->written->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + $obj->tags = ''; + $obj->readed_count = 0; + $obj->voted_count = 0; + if ($author_xml_id && $val->commenter->attrs->id == $author_xml_id) { + $obj->password = ''; + $obj->nick_name = $member_info->nick_name; + $obj->user_name = $member_info->user_name; + $obj->user_id = $member_info->user_id; + $obj->member_srl = $member_info->member_srl; + $obj->email_address = $member_info->email_address; + $obj->homepage = $member_info->homepage; + } + else { + $obj->password = $val->password->body; + $obj->nick_name = $val->commenter->name->body; + $obj->member_srl = 0; + $homepage = $val->commenter->homepage->body; + } + $obj->ipaddress = $val->commenter->ip->body; + $obj->list_order = $obj->update_order = $obj->document_srl*-1; + $obj->lock_comment = 'N'; + $obj->notify_message = 'N'; + $obj->trackback_count = 0; + + $obj->comment_count = 0; + if($val->comment) { + $child_comment = $val->comment; + if(!is_array($child_comment)) $child_comment = array($child_comment); + foreach($child_comment as $k => $v) { + $result = $this->insertComment($v, $module_srl, $obj->document_srl, $member_info, 0,$author_xml_id); + if($result !== false) $obj->comment_count++; + } + } + + // 문서 입력 + $output = executeQuery('document.insertDocument', $obj); + } + } + } + FileHandler::removeFile($guestbook_file); + } + + return $idx-1; + } + + + function insertTextyleGuestbookItem($val, $module_srl, $member_info, $textyle_guestbook_srl,$parent_srl = 0, $author_xml_id=null) { + $tobj = null; + if($textyle_guestbook_srl>0){ + $tobj->textyle_guestbook_srl = $textyle_guestbook_srl; + }else{ + $tobj->textyle_guestbook_srl = getNextSequence(); + } + $tobj->module_srl = $module_srl; + $tobj->is_secret = $val->secret->body=='1'?1:-1; + $tobj->content = nl2br($val->content->body); + if($author_xml_id && $val->commenter->attrs->id == $author_xml_id) { + $tobj->password = ''; + $tobj->nick_name = $member_info->nick_name; + $tobj->user_name = $member_info->user_name; + $tobj->user_id = $member_info->user_id; + $tobj->member_srl = $member_info->member_srl; + $tobj->homepage = $member_info->homepage; + $tobj->email_address = $member_info->email_address; + } else { + $tobj->password = $val->password->body; + $tobj->nick_name = $val->commenter->name->body; + $tobj->homepage = $val->commenter->homepage->body; + $tobj->member_srl = 0; + } + $tobj->last_update = $tobj->regdate = date("YmdHis",$val->written->body); + $tobj->ipaddress = $val->commenter->ip->body; + + if($parent_srl>0){ + $tobj->parent_srl = $parent_srl; + $tobj->list_order = $tobj->parent_srl * -1; + }else{ + $tobj->list_order = $tobj->textyle_guestbook_srl*-1; + } + + $output = executeQuery('textyle.insertTextyleGuestbook', $tobj); + + if($output->toBool()) return $tobj->textyle_guestbook_srl; + return false; + } + + + /** + * @brief 첨부파일 정리 + **/ + function importAttaches($fp, $module_srl, $upload_target_srl, &$files, $buff) { + $uploaded_count = 0; + + $file_obj = null; + $file_obj->file_srl = getNextSequence(); + $file_obj->upload_target_srl = $upload_target_srl; + $file_obj->module_srl = $module_srl; + + while(!feof($fp)) { + $str = fgets($fp, 1024); + + // 로 끝나면 중단 + if(trim($str) == '') break; + + // 로 시작하면 xml파일내의 첨부파일로 처리 + if(substr($str, 0, 9)=='') { + $file_obj->file = $this->saveTemporaryFile($fp, $str); + continue; + } + + $buff .= $str; + } + if(!file_exists($file_obj->file)) return false; + + $buff .= ''; + + $xmlDoc = $this->oXmlParser->parse($buff); + + $file_obj->source_filename = $xmlDoc->attachment->label->body; + $file_obj->download_count = $xmlDoc->attachment->downloads->body; + $name = $xmlDoc->attachment->name->body; + + // 이미지인지 기타 파일인지 체크하여 upload path 지정 + if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp1|mp2|mp3|mp4|asf|wav|asx|mid|midi|asf|mov|moov|qt|rm|ram|ra|rmm|m4v)$/i", $file_obj->source_filename)) { + $path = sprintf("./files/attach/images/%s/%s", $module_srl,getNumberingPath($upload_target_srl,3)); + $filename = $path.$file_obj->source_filename; + $file_obj->direct_download = 'Y'; + } else { + $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); + $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); + $file_obj->direct_download = 'N'; + } + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) return; + + FileHandler::rename($file_obj->file, $filename); + + // DB입력 + unset($file_obj->file); + $file_obj->uploaded_filename = $filename; + $file_obj->file_size = filesize($filename); + $file_obj->comment = NULL; + $file_obj->member_srl = 0; + $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); + $file_obj->isvalid = 'Y'; + $output = executeQuery('file.insertFile', $file_obj); + + if($output->toBool()) { + $uploaded_count++; + $tmp_obj = null; + if($file_obj->direct_download == 'Y') $files[$name]->url = $file_obj->uploaded_filename; + else $files[$name]->url = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid); + $files[$name]->direct_download = $file_obj->direct_download; + $files[$name]->source_filename = $file_obj->source_filename; + return true; + } + + return false; + } + + /** + * @biref 임의로 사용할 파일이름을 return + **/ + function getTmpFilename() { + $path = "./files/cache/importer"; + if(!is_dir($path)) FileHandler::makeDir($path); + $filename = sprintf("%s/%d", $path, rand(11111111,99999999)); + if(file_exists($filename)) $filename .= rand(111,999); + return $filename; + } + + /** + * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 + **/ + function saveTemporaryFile($fp, $buff) { + $temp_filename = $this->getTmpFilename(); + $buff = substr($buff, 9); + + while(!feof($fp)) { + $str = trim(fgets($fp, 1024)); + $buff .= $str; + if(substr($str, -10) == '') break; + } + + $buff = substr($buff, 0, -10); + + $f = fopen($temp_filename, "w"); + fwrite($f, base64_decode($buff)); + fclose($f); + return $temp_filename; + } + + /** + * @brief ttxml의 자체 img 태그를 치환 + **/ + function _replaceTTAttach($matches) { + $name = $matches[2]; + if(!$name) return $matches[0]; + + $obj = $this->files[$name]; + + // 멀티미디어성 파일의 경우 + if($obj->direct_download == 'Y') { + // 이미지의 경우 + if(preg_match('/\.(jpg|gif|jpeg|png)$/i', $obj->source_filename)) { + return sprintf('%s', $obj->url, str_replace('"','\\"',$matches[4])); + // 이미지 외의 멀티미디어성 파일의 경우 + } else { + return sprintf('', $obj->url); + } + + // binary파일일 경우 + } else { + return sprintf('%s', $obj->url, $obj->source_filename); + } + } + + /** + * @brief ttxml의 동영상 변환 + **/ + function _replaceTTMovie($matches) { + $key = $matches[1]; + if(!$key) return $matches[0]; + + return + ''. + ''. + ''. + ''. + ''. + ''. + ''; + } + + /** + * @brief 댓글 입력 + **/ + function insertComment($val, $module_srl, $document_srl, $member_info, $parent_srl = 0, $author_xml_id) { + $tobj = null; + $tobj->comment_srl = getNextSequence(); + $tobj->module_srl = $module_srl; + $tobj->document_srl = $document_srl; + $tobj->is_secret = $val->secret->body=='1'?'Y':'N'; + $tobj->notify_message = 'N'; + $tobj->content = nl2br($val->content->body); + $tobj->voted_count = 0; + if ($author_xml_id && $val->commenter->attrs->id == $author_xml_id) { + $tobj->password = ''; + $tobj->nick_name = $member_info->nick_name; + $tobj->user_name = $member_info->user_name; + $tobj->user_id = $member_info->user_id; + $tobj->member_srl = $member_info->member_srl; + $tobj->homepage = $member_info->homepage; + $tobj->email_address = $member_info->email_address; + } else { + $tobj->password = $val->password->body; + $tobj->nick_name = $val->commenter->name->body; + $tobj->homepage = $val->commenter->homepage->body; + $tobj->member_srl = 0; + } + $tobj->last_update = $tobj->regdate = date("YmdHis",$val->written->body); + $tobj->ipaddress = $val->commenter->ip->body; + $tobj->list_order = $tobj->comment_srl*-1; + $tobj->sequence = $sequence; + $tobj->parent_srl = $parent_srl; + + // 댓글 목록 부분을 먼저 입력 + $list_args = null; + $list_args->comment_srl = $tobj->comment_srl; + $list_args->document_srl = $tobj->document_srl; + $list_args->module_srl = $tobj->module_srl; + $list_args->regdate = $tobj->regdate; + + // 부모댓글이 없으면 바로 데이터를 설정 + if(!$tobj->parent_srl) { + $list_args->head = $list_args->arrange = $tobj->comment_srl; + $list_args->depth = 0; + + // 부모댓글이 있으면 부모글의 정보를 구해옴 + } else { + // 부모댓글의 정보를 구함 + $parent_args->comment_srl = $tobj->parent_srl; + $parent_output = executeQuery('comment.getCommentListItem', $parent_args); + + // 부모댓글이 존재하지 않으면 return + if(!$parent_output->toBool() || !$parent_output->data) return false; + $parent = $parent_output->data; + + $list_args->head = $parent->head; + $list_args->depth = $parent->depth+1; + if($list_args->depth<2) $list_args->arrange = $tobj->comment_srl; + else { + $list_args->arrange = $parent->arrange; + $output = executeQuery('comment.updateCommentListArrange', $list_args); + if(!$output->toBool()) return $output; + } + } + + $output = executeQuery('comment.insertCommentList', $list_args); + if($output->toBool()) { + $output = executeQuery('comment.insertComment', $tobj); + if($output->toBool()) return $tobj->comment_srl; + } + return false; + } + + // 카테고리 정리 + function arrangeCategory($obj, &$category, &$idx, $parent = 0) { + if(!$obj->category) return; + if(!is_array($obj->category)) $c = array($obj->category); + else $c = $obj->category; + foreach($c as $val) { + $idx++; + $priority = $val->priority->body; + $name = $val->name->body; + $obj = null; + $obj->priority = $priority; + $obj->name = $name; + $obj->sequence = $idx; + $obj->parent = $parent; + + $category[$idx] = $obj; + + $this->arrangeCategory($val, $category, $idx, $idx); + } + } + } +?> diff --git a/modules/install/conf/info.xml b/modules/install/conf/info.xml index 0a1ebb56b..a15f2c176 100644 --- a/modules/install/conf/info.xml +++ b/modules/install/conf/info.xml @@ -1,33 +1,33 @@ - - - 설치관리 - Manage installation - Quản lý cài đặt - 安装管理 - インストール管理 - Manajo de la Instalación - Управление установкой - 安裝管理 - 설치 관리 모듈 - Module for managing installation - Module quản lý cài đặt - 安装管理模块。 - インストール管理モジュール - Módulo para el manejo de la instalación - Модуль для управления установкой - 安裝管理模組 - 0.1 - 2007-02-28 - system - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 설치관리 + Manage installation + Quản lý cài đặt + 安装管理 + インストール管理 + Manajo de la Instalación + Управление установкой + 安裝管理 + 설치 관리 모듈 + Module for managing installation + Module quản lý cài đặt + 安装管理模块。 + インストール管理モジュール + Módulo para el manejo de la instalación + Модуль для управления установкой + 安裝管理模組 + 0.1 + 2007-02-28 + system + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/install/install.admin.controller.php b/modules/install/install.admin.controller.php index b3164967f..6ab6bd66c 100644 --- a/modules/install/install.admin.controller.php +++ b/modules/install/install.admin.controller.php @@ -1,155 +1,155 @@ -installModule($module_name, './modules/'.$module_name); - - $this->setMessage('success_installed'); - } - - /** - * @brief 모듈 업데이트 - **/ - function procInstallAdminUpdate() { - $module_name = Context::get('module_name'); - if(!$module_name) return new object(-1, 'invalid_request'); - - $oModule = &getModule($module_name, 'class'); - if($oModule) $output = $oModule->moduleUpdate(); - else $output = new Object(-1, 'invalid_request'); - - return $output; - } - - /** - * @brief 설정 변경 - **/ - function procInstallAdminSaveTimeZone() { - $use_rewrite = Context::get('use_rewrite'); - if($use_rewrite!='Y') $use_rewrite = 'N'; - - $use_optimizer = Context::get('use_optimizer'); - if($use_optimizer!='Y') $use_optimizer = 'N'; - - $time_zone = Context::get('time_zone'); - - $qmail_compatibility = Context::get('qmail_compatibility'); - if($qmail_compatibility!='Y') $qmail_compatibility = 'N'; - - $use_db_session = Context::get('use_db_session'); - if($use_db_session!='Y') $use_db_session = 'N'; - - $use_ssl = Context::get('use_ssl'); - if(!$use_ssl) $use_ssl = 'none'; - - $http_port = Context::get('http_port'); - $https_port = Context::get('https_port'); - - $use_mobile_view = Context::get('use_mobile_view'); - if($use_mobile_view!='Y') $use_mobile_view = 'N'; - - $db_info = Context::getDBInfo(); - $db_info->default_url = Context::get('default_url'); - if($db_info->default_url && !preg_match('/^(http|https):\/\//i', $db_info->default_url)) $db_info->default_url = 'http://'.$db_info->default_url; - $db_info->time_zone = $time_zone; - $db_info->qmail_compatibility = $qmail_compatibility; - $db_info->use_db_session = $use_db_session; - $db_info->use_rewrite = $use_rewrite; - $db_info->use_optimizer = $use_optimizer; - $db_info->use_ssl = $use_ssl; - $db_info->use_mobile_view = $use_mobile_view; - if($http_port) $db_info->http_port = (int) $http_port; - else if($db_info->http_port) unset($db_info->http_port); - - if($https_port) $db_info->https_port = (int) $https_port; - else if($db_info->https_port) unset($db_info->https_port); - - unset($db_info->lang_type); - Context::setDBInfo($db_info); - - $oInstallController = &getController('install'); - $oInstallController->makeConfigFile(); - - $site_args->site_srl = 0; - $site_args->index_module_srl = Context::get('index_module_srl'); - $site_args->default_language = Context::get('change_lang_type'); - $site_args->domain = $db_info->default_url; - $oModuleController = &getController('module'); - $oModuleController->updateSite($site_args); - - $this->setMessage('success_updated'); - } - - /** - * @brief 지원 언어 선택 - **/ - function procInstallAdminSaveLangSelected() { - $selected_lang = trim(Context::get('selected_lang')); - if(!$selected_lang) return new Object(-1,'msg_invalid_request'); - $langs = explode('|@|', $selected_lang); - - $lang_supported = Context::loadLangSupported(); - $buff = null; - for($i=0;$isetMessage('success_updated'); - } - - function procInstallAdminRemoveFTPInfo() { - $ftp_config_file = Context::getFTPConfigFile(); - if(file_exists($ftp_config_file)) unlink($ftp_config_file); - if($_SESSION['ftp_password']) unset($_SESSION['ftp_password']); - $this->setMessage('success_deleted'); - } - - function procInstallAdminSaveFTPInfo() { - $ftp_info = Context::getFTPInfo(); - $ftp_info->ftp_user = Context::get('ftp_user'); - $ftp_info->ftp_port = Context::get('ftp_port'); - $ftp_info->ftp_host = Context::get('ftp_host'); - $ftp_info->ftp_pasv = Context::get('ftp_pasv'); - if(!$ftp_info->ftp_pasv) $ftp_info->ftp_pasv = "N"; - $ftp_info->sftp = Context::get('sftp'); - $ftp_info->ftp_root_path = Context::get('ftp_root_path'); - if(ini_get('safe_mode')) { - $ftp_info->ftp_password = Context::get('ftp_password'); - } - - $buff = ' $val) { - if(!$val) continue; - $buff .= sprintf("\$ftp_info->%s = '%s';\n", $key, str_replace("'","\\'",$val)); - } - $buff .= "?>"; - $config_file = Context::getFTPConfigFile(); - FileHandler::WriteFile($config_file, $buff); - if($_SESSION['ftp_password']) unset($_SESSION['ftp_password']); - $this->setMessage('success_updated'); - } - - } -?> +installModule($module_name, './modules/'.$module_name); + + $this->setMessage('success_installed'); + } + + /** + * @brief 모듈 업데이트 + **/ + function procInstallAdminUpdate() { + $module_name = Context::get('module_name'); + if(!$module_name) return new object(-1, 'invalid_request'); + + $oModule = &getModule($module_name, 'class'); + if($oModule) $output = $oModule->moduleUpdate(); + else $output = new Object(-1, 'invalid_request'); + + return $output; + } + + /** + * @brief 설정 변경 + **/ + function procInstallAdminSaveTimeZone() { + $use_rewrite = Context::get('use_rewrite'); + if($use_rewrite!='Y') $use_rewrite = 'N'; + + $use_optimizer = Context::get('use_optimizer'); + if($use_optimizer!='Y') $use_optimizer = 'N'; + + $time_zone = Context::get('time_zone'); + + $qmail_compatibility = Context::get('qmail_compatibility'); + if($qmail_compatibility!='Y') $qmail_compatibility = 'N'; + + $use_db_session = Context::get('use_db_session'); + if($use_db_session!='Y') $use_db_session = 'N'; + + $use_ssl = Context::get('use_ssl'); + if(!$use_ssl) $use_ssl = 'none'; + + $http_port = Context::get('http_port'); + $https_port = Context::get('https_port'); + + $use_mobile_view = Context::get('use_mobile_view'); + if($use_mobile_view!='Y') $use_mobile_view = 'N'; + + $db_info = Context::getDBInfo(); + $db_info->default_url = Context::get('default_url'); + if($db_info->default_url && !preg_match('/^(http|https):\/\//i', $db_info->default_url)) $db_info->default_url = 'http://'.$db_info->default_url; + $db_info->time_zone = $time_zone; + $db_info->qmail_compatibility = $qmail_compatibility; + $db_info->use_db_session = $use_db_session; + $db_info->use_rewrite = $use_rewrite; + $db_info->use_optimizer = $use_optimizer; + $db_info->use_ssl = $use_ssl; + $db_info->use_mobile_view = $use_mobile_view; + if($http_port) $db_info->http_port = (int) $http_port; + else if($db_info->http_port) unset($db_info->http_port); + + if($https_port) $db_info->https_port = (int) $https_port; + else if($db_info->https_port) unset($db_info->https_port); + + unset($db_info->lang_type); + Context::setDBInfo($db_info); + + $oInstallController = &getController('install'); + $oInstallController->makeConfigFile(); + + $site_args->site_srl = 0; + $site_args->index_module_srl = Context::get('index_module_srl'); + $site_args->default_language = Context::get('change_lang_type'); + $site_args->domain = $db_info->default_url; + $oModuleController = &getController('module'); + $oModuleController->updateSite($site_args); + + $this->setMessage('success_updated'); + } + + /** + * @brief 지원 언어 선택 + **/ + function procInstallAdminSaveLangSelected() { + $selected_lang = trim(Context::get('selected_lang')); + if(!$selected_lang) return new Object(-1,'msg_invalid_request'); + $langs = explode('|@|', $selected_lang); + + $lang_supported = Context::loadLangSupported(); + $buff = null; + for($i=0;$isetMessage('success_updated'); + } + + function procInstallAdminRemoveFTPInfo() { + $ftp_config_file = Context::getFTPConfigFile(); + if(file_exists($ftp_config_file)) unlink($ftp_config_file); + if($_SESSION['ftp_password']) unset($_SESSION['ftp_password']); + $this->setMessage('success_deleted'); + } + + function procInstallAdminSaveFTPInfo() { + $ftp_info = Context::getFTPInfo(); + $ftp_info->ftp_user = Context::get('ftp_user'); + $ftp_info->ftp_port = Context::get('ftp_port'); + $ftp_info->ftp_host = Context::get('ftp_host'); + $ftp_info->ftp_pasv = Context::get('ftp_pasv'); + if(!$ftp_info->ftp_pasv) $ftp_info->ftp_pasv = "N"; + $ftp_info->sftp = Context::get('sftp'); + $ftp_info->ftp_root_path = Context::get('ftp_root_path'); + if(ini_get('safe_mode')) { + $ftp_info->ftp_password = Context::get('ftp_password'); + } + + $buff = ' $val) { + if(!$val) continue; + $buff .= sprintf("\$ftp_info->%s = '%s';\n", $key, str_replace("'","\\'",$val)); + } + $buff .= "?>"; + $config_file = Context::getFTPConfigFile(); + FileHandler::WriteFile($config_file, $buff); + if($_SESSION['ftp_password']) unset($_SESSION['ftp_password']); + $this->setMessage('success_updated'); + } + + } +?> diff --git a/modules/install/install.class.php b/modules/install/install.class.php index c9fffeb66..b71c79123 100644 --- a/modules/install/install.class.php +++ b/modules/install/install.class.php @@ -1,37 +1,37 @@ - + diff --git a/modules/install/install.controller.php b/modules/install/install.controller.php index 2f6f64568..98f5abd22 100644 --- a/modules/install/install.controller.php +++ b/modules/install/install.controller.php @@ -1,360 +1,360 @@ -is_admin = 'Y'; - $_SESSION['logged_info'] = $logged_info; - Context::set('logged_info', $logged_info); - - // DB와 관련된 변수를 받음 - $db_info = Context::gets('db_type','db_port','db_hostname','db_userid','db_password','db_database','db_table_prefix','time_zone','use_rewrite'); - if($db_info->use_rewrite!='Y') $db_info->use_rewrite = 'N'; - if(!$db_info->default_url) $db_info->default_url = Context::getRequestUri(); - $db_info->lang_type = Context::getLangType(); - - // DB의 타입과 정보를 등록 - Context::setDBInfo($db_info); - - // DB Instance 생성 - $oDB = &DB::getInstance(); - - // DB접속이 가능한지 체크 - $output = $oDB->getError(); - if(!$oDB->isConnected()) return $oDB->getError(); - - // firebird는 설치시에 트랜젝션을 사용하지 않음 - if($db_info->db_type != "firebird") $oDB->begin(); - - // 모든 모듈의 설치 - $this->installDownloadedModule(); - - if($db_info->db_type != "firebird") $oDB->commit(); - - // config 파일 생성 - if(!$this->makeConfigFile()) return new Object(-1, 'msg_install_failed'); - - // load script - $scripts = FileHandler::readDir('./modules/install/script','/(\.php)$/'); - if(count($scripts)>0){ - sort($scripts); - foreach($scripts as $script){ - $output = include(FileHandler::getRealPath('./modules/install/script/'.$script)); - } - } - - // 설치 완료 메세지 출력 - $this->setMessage('msg_install_completed'); - } - - /** - * @brief FTP 정보 등록 - **/ - function procInstallFTP() { - if(Context::isInstalled()) return new Object(-1, 'msg_already_installed'); - $ftp_info = Context::gets('ftp_host', 'ftp_user','ftp_password','ftp_port','ftp_root_path'); - $ftp_info->ftp_port = (int)$ftp_info->ftp_port; - if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21; - if(!$ftp_info->ftp_host) $ftp_info->ftp_host = '127.0.0.1'; - if(!$ftp_info->ftp_root_path) $ftp_info->ftp_root_path = '/'; - - $buff = ' $val) { - $buff .= sprintf("\$ftp_info->%s = '%s';\n", $key, str_replace("'","\\'",$val)); - } - $buff .= "?>"; - - // safe_mode 일 경우 - if(ini_get('safe_mode')) { - if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed'); - - require_once(_XE_PATH_.'libs/ftp.class.php'); - $oFtp = new ftp(); - if(!$oFtp->ftp_connect($ftp_info->ftp_host, $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'); - } - - if(!is_dir(_XE_PATH_.'files') && !$oFtp->ftp_mkdir($ftp_info->ftp_root_path.'files')) { - $oFtp->ftp_quit(); - return new Object(-1,'msg_ftp_mkdir_fail'); - } - - if(!$oFtp->ftp_site("CHMOD 777 ".$ftp_info->ftp_root_path.'files')) { - $oFtp->ftp_quit(); - return new Object(-1,'msg_ftp_chmod_fail'); - } - - if(!is_dir(_XE_PATH_.'files/config') && !$oFtp->ftp_mkdir($ftp_info->ftp_root_path.'files/config')) { - $oFtp->ftp_quit(); - return new Object(-1,'msg_ftp_mkdir_fail'); - } - - if(!$oFtp->ftp_site("CHMOD 777 ".$ftp_info->ftp_root_path.'files/config')) { - $oFtp->ftp_quit(); - return new Object(-1,'msg_ftp_chmod_fail'); - } - - $oFtp->ftp_quit(); - } - - $config_file = Context::getFTPConfigFile(); - FileHandler::WriteFile($config_file, $buff); - } - - function procInstallCheckFtp() { - $ftp_info = Context::gets('ftp_user','ftp_password','ftp_port','sftp'); - $ftp_info->ftp_port = (int)$ftp_info->ftp_port; - if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21; - if(!$ftp_info->sftp) $ftp_info->sftp = 'N'; - - if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed'); - - if($ftp_info->sftp == 'Y') - { - $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'); - } - } - else - { - 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'); - } - - $oFtp->ftp_quit(); - } - - $this->setMessage('msg_ftp_connect_success'); - } - - /** - * @brief 인스톨 환경을 체크하여 결과 return - **/ - function checkInstallEnv() { - // 각 필요한 항목 체크 - $checklist = array(); - - // 0. php 버전 체크 (5.2.2는 설치 불가) - if(phpversion()=='5.2.2') $checklist['php_version'] = false; - else $checklist['php_version'] = true; - - // 1. permission 체크 - if(is_writable('./')||is_writable('./files')) $checklist['permission'] = true; - else $checklist['permission'] = false; - - // 2. xml_parser_create함수 유무 체크 - if(function_exists('xml_parser_create')) $checklist['xml'] = true; - else $checklist['xml'] = false; - - // 3. ini_get(session.auto_start)==1 체크 - if(ini_get(session.auto_start)!=1) $checklist['session'] = true; - else $checklist['session'] = false; - - // 4. iconv 체크 - if(function_exists('iconv')) $checklist['iconv'] = true; - else $checklist['iconv'] = false; - - // 5. gd 체크 (imagecreatefromgif함수) - if(function_exists('imagecreatefromgif')) $checklist['gd'] = true; - else $checklist['gd'] = false; - - if(!$checklist['php_version'] || !$checklist['permission'] || !$checklist['xml'] || !$checklist['session']) $install_enable = false; - else $install_enable = true; - - // 체크 결과를 Context에 저장 - Context::set('checklist', $checklist); - Context::set('install_enable', $install_enable); - - return $install_enable; - } - - /** - * @brief files 및 하위 디렉토리 생성 - * DB 정보를 바탕으로 실제 install하기 전에 로컬 환경 설저d - **/ - function makeDefaultDirectory() { - $directory_list = array( - './files/config', - './files/cache/queries', - './files/cache/js_filter_compiled', - './files/cache/template_compiled', - ); - - foreach($directory_list as $dir) { - FileHandler::makeDir($dir); - } - } - - /** - * @brief 모든 모듈의 설치 - * - * 모든 module의 schemas 디렉토리를 확인하여 schema xml을 이용, 테이블 생성 - **/ - function installDownloadedModule() { - $oModuleModel = &getModel('module'); - - // 각 모듈의 schemas/*.xml 파일을 모두 찾아서 table 생성 - $module_list = FileHandler::readDir('./modules/', NULL, false, true); - foreach($module_list as $module_path) { - // 모듈 이름을 구함 - $tmp_arr = explode('/',$module_path); - $module = $tmp_arr[count($tmp_arr)-1]; - - $xml_info = $oModuleModel->getModuleInfoXml($module); - if(!$xml_info) continue; - $modules[$xml_info->category][] = $module; - } - - // module 모듈은 미리 설치 - $this->installModule('module','./modules/module'); - $oModule = &getClass('module'); - if($oModule->checkUpdate()) $oModule->moduleUpdate(); - - // 모듈을 category에 의거 설치 순서를 정함 - $install_step = array('system','content','member'); - // 나머지 모든 모듈 설치 - foreach($install_step as $category) { - if(count($modules[$category])) { - foreach($modules[$category] as $module) { - if($module == 'module') continue; - $this->installModule($module, sprintf('./modules/%s', $module)); - - $oModule = &getClass($module); - if($oModule->checkUpdate()) $oModule->moduleUpdate(); - } - unset($modules[$category]); - } - } - - // 나머지 모든 모듈 설치 - if(count($modules)) { - foreach($modules as $category => $module_list) { - if(count($module_list)) { - foreach($module_list as $module) { - if($module == 'module') continue; - $this->installModule($module, sprintf('./modules/%s', $module)); - - $oModule = &getClass($module); - if($oModule->checkUpdate()) $oModule->moduleUpdate(); - } - } - } - } - - return new Object(); - } - - /** - * @brief 개별 모듈의 설치 - **/ - function installModule($module, $module_path) { - // db instance생성 - $oDB = &DB::getInstance(); - - // 해당 모듈의 schemas 디렉토리를 검사하여 schema xml파일이 있으면 생성 - $schema_dir = sprintf('%s/schemas/', $module_path); - $schema_files = FileHandler::readDir($schema_dir, NULL, false, true); - - $file_cnt = count($schema_files); - for($i=0;$i<$file_cnt;$i++) { - $file = trim($schema_files[$i]); - if(!$file || substr($file,-4)!='.xml') continue; - $output = $oDB->createTableByXmlFile($file); - } - - // 테이블 설치후 module instance를 만들고 install() method를 실행 - unset($oModule); - $oModule = &getClass($module); - if(method_exists($oModule, 'moduleInstall')) $oModule->moduleInstall(); - - return new Object(); - } - - /** - * @brief config 파일을 생성 - * 모든 설정이 이상없이 끝난 후에 config파일 생성 - **/ - function makeConfigFile() { - $config_file = Context::getConfigFile(); - //if(file_exists($config_file)) return; - - $db_info = Context::getDbInfo(); - if(!$db_info) return; - - $buff = ' $val) { - $buff .= sprintf("\$db_info->%s = '%s';\n", $key, str_replace("'","\\'",$val)); - } - $buff .= "?>"; - - FileHandler::writeFile($config_file, $buff); - - if(@file_exists($config_file)) return true; - return false; - } - - function installByConfig($install_config_file){ - include $install_config_file; - if(!is_array($auto_config)) return false; - - $auto_config['module'] = 'install'; - $auto_config['act'] = 'procInstall'; - - $fstr = "<%s>\r\n"; - $fheader = "POST %s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/xml\r\nContent-Length: %s\r\n\r\n%s\r\n"; - $body = "\r\n\r\n\r\n"; - foreach($auto_config as $k => $v){ - if(!in_array($k,array('host','port','path'))) $body .= sprintf($fstr,$k,$v,$k); - } - $body .= "\r\n"; - - $header = sprintf($fheader,$auto_config['path'],$auto_config['host'],strlen($body),$body); - $fp = @fsockopen($auto_config['host'], $auto_config['port'], $errno, $errstr, 5); - if($fp){ - fputs($fp, $header); - while(!feof($fp)) { - $line = trim(fgets($fp, 4096)); - if(preg_match("/^/i",$line)){ - fclose($fp); - return false; - } - } - fclose($fp); - } - return true; - - } - } -?> +is_admin = 'Y'; + $_SESSION['logged_info'] = $logged_info; + Context::set('logged_info', $logged_info); + + // DB와 관련된 변수를 받음 + $db_info = Context::gets('db_type','db_port','db_hostname','db_userid','db_password','db_database','db_table_prefix','time_zone','use_rewrite'); + if($db_info->use_rewrite!='Y') $db_info->use_rewrite = 'N'; + if(!$db_info->default_url) $db_info->default_url = Context::getRequestUri(); + $db_info->lang_type = Context::getLangType(); + + // DB의 타입과 정보를 등록 + Context::setDBInfo($db_info); + + // DB Instance 생성 + $oDB = &DB::getInstance(); + + // DB접속이 가능한지 체크 + $output = $oDB->getError(); + if(!$oDB->isConnected()) return $oDB->getError(); + + // firebird는 설치시에 트랜젝션을 사용하지 않음 + if($db_info->db_type != "firebird") $oDB->begin(); + + // 모든 모듈의 설치 + $this->installDownloadedModule(); + + if($db_info->db_type != "firebird") $oDB->commit(); + + // config 파일 생성 + if(!$this->makeConfigFile()) return new Object(-1, 'msg_install_failed'); + + // load script + $scripts = FileHandler::readDir('./modules/install/script','/(\.php)$/'); + if(count($scripts)>0){ + sort($scripts); + foreach($scripts as $script){ + $output = include(FileHandler::getRealPath('./modules/install/script/'.$script)); + } + } + + // 설치 완료 메세지 출력 + $this->setMessage('msg_install_completed'); + } + + /** + * @brief FTP 정보 등록 + **/ + function procInstallFTP() { + if(Context::isInstalled()) return new Object(-1, 'msg_already_installed'); + $ftp_info = Context::gets('ftp_host', 'ftp_user','ftp_password','ftp_port','ftp_root_path'); + $ftp_info->ftp_port = (int)$ftp_info->ftp_port; + if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21; + if(!$ftp_info->ftp_host) $ftp_info->ftp_host = '127.0.0.1'; + if(!$ftp_info->ftp_root_path) $ftp_info->ftp_root_path = '/'; + + $buff = ' $val) { + $buff .= sprintf("\$ftp_info->%s = '%s';\n", $key, str_replace("'","\\'",$val)); + } + $buff .= "?>"; + + // safe_mode 일 경우 + if(ini_get('safe_mode')) { + if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed'); + + require_once(_XE_PATH_.'libs/ftp.class.php'); + $oFtp = new ftp(); + if(!$oFtp->ftp_connect($ftp_info->ftp_host, $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'); + } + + if(!is_dir(_XE_PATH_.'files') && !$oFtp->ftp_mkdir($ftp_info->ftp_root_path.'files')) { + $oFtp->ftp_quit(); + return new Object(-1,'msg_ftp_mkdir_fail'); + } + + if(!$oFtp->ftp_site("CHMOD 777 ".$ftp_info->ftp_root_path.'files')) { + $oFtp->ftp_quit(); + return new Object(-1,'msg_ftp_chmod_fail'); + } + + if(!is_dir(_XE_PATH_.'files/config') && !$oFtp->ftp_mkdir($ftp_info->ftp_root_path.'files/config')) { + $oFtp->ftp_quit(); + return new Object(-1,'msg_ftp_mkdir_fail'); + } + + if(!$oFtp->ftp_site("CHMOD 777 ".$ftp_info->ftp_root_path.'files/config')) { + $oFtp->ftp_quit(); + return new Object(-1,'msg_ftp_chmod_fail'); + } + + $oFtp->ftp_quit(); + } + + $config_file = Context::getFTPConfigFile(); + FileHandler::WriteFile($config_file, $buff); + } + + function procInstallCheckFtp() { + $ftp_info = Context::gets('ftp_user','ftp_password','ftp_port','sftp'); + $ftp_info->ftp_port = (int)$ftp_info->ftp_port; + if(!$ftp_info->ftp_port) $ftp_info->ftp_port = 21; + if(!$ftp_info->sftp) $ftp_info->sftp = 'N'; + + if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed'); + + if($ftp_info->sftp == 'Y') + { + $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'); + } + } + else + { + 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'); + } + + $oFtp->ftp_quit(); + } + + $this->setMessage('msg_ftp_connect_success'); + } + + /** + * @brief 인스톨 환경을 체크하여 결과 return + **/ + function checkInstallEnv() { + // 각 필요한 항목 체크 + $checklist = array(); + + // 0. php 버전 체크 (5.2.2는 설치 불가) + if(phpversion()=='5.2.2') $checklist['php_version'] = false; + else $checklist['php_version'] = true; + + // 1. permission 체크 + if(is_writable('./')||is_writable('./files')) $checklist['permission'] = true; + else $checklist['permission'] = false; + + // 2. xml_parser_create함수 유무 체크 + if(function_exists('xml_parser_create')) $checklist['xml'] = true; + else $checklist['xml'] = false; + + // 3. ini_get(session.auto_start)==1 체크 + if(ini_get(session.auto_start)!=1) $checklist['session'] = true; + else $checklist['session'] = false; + + // 4. iconv 체크 + if(function_exists('iconv')) $checklist['iconv'] = true; + else $checklist['iconv'] = false; + + // 5. gd 체크 (imagecreatefromgif함수) + if(function_exists('imagecreatefromgif')) $checklist['gd'] = true; + else $checklist['gd'] = false; + + if(!$checklist['php_version'] || !$checklist['permission'] || !$checklist['xml'] || !$checklist['session']) $install_enable = false; + else $install_enable = true; + + // 체크 결과를 Context에 저장 + Context::set('checklist', $checklist); + Context::set('install_enable', $install_enable); + + return $install_enable; + } + + /** + * @brief files 및 하위 디렉토리 생성 + * DB 정보를 바탕으로 실제 install하기 전에 로컬 환경 설저d + **/ + function makeDefaultDirectory() { + $directory_list = array( + './files/config', + './files/cache/queries', + './files/cache/js_filter_compiled', + './files/cache/template_compiled', + ); + + foreach($directory_list as $dir) { + FileHandler::makeDir($dir); + } + } + + /** + * @brief 모든 모듈의 설치 + * + * 모든 module의 schemas 디렉토리를 확인하여 schema xml을 이용, 테이블 생성 + **/ + function installDownloadedModule() { + $oModuleModel = &getModel('module'); + + // 각 모듈의 schemas/*.xml 파일을 모두 찾아서 table 생성 + $module_list = FileHandler::readDir('./modules/', NULL, false, true); + foreach($module_list as $module_path) { + // 모듈 이름을 구함 + $tmp_arr = explode('/',$module_path); + $module = $tmp_arr[count($tmp_arr)-1]; + + $xml_info = $oModuleModel->getModuleInfoXml($module); + if(!$xml_info) continue; + $modules[$xml_info->category][] = $module; + } + + // module 모듈은 미리 설치 + $this->installModule('module','./modules/module'); + $oModule = &getClass('module'); + if($oModule->checkUpdate()) $oModule->moduleUpdate(); + + // 모듈을 category에 의거 설치 순서를 정함 + $install_step = array('system','content','member'); + // 나머지 모든 모듈 설치 + foreach($install_step as $category) { + if(count($modules[$category])) { + foreach($modules[$category] as $module) { + if($module == 'module') continue; + $this->installModule($module, sprintf('./modules/%s', $module)); + + $oModule = &getClass($module); + if($oModule->checkUpdate()) $oModule->moduleUpdate(); + } + unset($modules[$category]); + } + } + + // 나머지 모든 모듈 설치 + if(count($modules)) { + foreach($modules as $category => $module_list) { + if(count($module_list)) { + foreach($module_list as $module) { + if($module == 'module') continue; + $this->installModule($module, sprintf('./modules/%s', $module)); + + $oModule = &getClass($module); + if($oModule->checkUpdate()) $oModule->moduleUpdate(); + } + } + } + } + + return new Object(); + } + + /** + * @brief 개별 모듈의 설치 + **/ + function installModule($module, $module_path) { + // db instance생성 + $oDB = &DB::getInstance(); + + // 해당 모듈의 schemas 디렉토리를 검사하여 schema xml파일이 있으면 생성 + $schema_dir = sprintf('%s/schemas/', $module_path); + $schema_files = FileHandler::readDir($schema_dir, NULL, false, true); + + $file_cnt = count($schema_files); + for($i=0;$i<$file_cnt;$i++) { + $file = trim($schema_files[$i]); + if(!$file || substr($file,-4)!='.xml') continue; + $output = $oDB->createTableByXmlFile($file); + } + + // 테이블 설치후 module instance를 만들고 install() method를 실행 + unset($oModule); + $oModule = &getClass($module); + if(method_exists($oModule, 'moduleInstall')) $oModule->moduleInstall(); + + return new Object(); + } + + /** + * @brief config 파일을 생성 + * 모든 설정이 이상없이 끝난 후에 config파일 생성 + **/ + function makeConfigFile() { + $config_file = Context::getConfigFile(); + //if(file_exists($config_file)) return; + + $db_info = Context::getDbInfo(); + if(!$db_info) return; + + $buff = ' $val) { + $buff .= sprintf("\$db_info->%s = '%s';\n", $key, str_replace("'","\\'",$val)); + } + $buff .= "?>"; + + FileHandler::writeFile($config_file, $buff); + + if(@file_exists($config_file)) return true; + return false; + } + + function installByConfig($install_config_file){ + include $install_config_file; + if(!is_array($auto_config)) return false; + + $auto_config['module'] = 'install'; + $auto_config['act'] = 'procInstall'; + + $fstr = "<%s>\r\n"; + $fheader = "POST %s HTTP/1.1\r\nHost: %s\r\nContent-Type: application/xml\r\nContent-Length: %s\r\n\r\n%s\r\n"; + $body = "\r\n\r\n\r\n"; + foreach($auto_config as $k => $v){ + if(!in_array($k,array('host','port','path'))) $body .= sprintf($fstr,$k,$v,$k); + } + $body .= "\r\n"; + + $header = sprintf($fheader,$auto_config['path'],$auto_config['host'],strlen($body),$body); + $fp = @fsockopen($auto_config['host'], $auto_config['port'], $errno, $errstr, 5); + if($fp){ + fputs($fp, $header); + while(!feof($fp)) { + $line = trim(fgets($fp, 4096)); + if(preg_match("/^/i",$line)){ + fclose($fp); + return false; + } + } + fclose($fp); + } + return true; + + } + } +?> diff --git a/modules/install/install.view.php b/modules/install/install.view.php index 63dffe292..6acfd63ef 100644 --- a/modules/install/install.view.php +++ b/modules/install/install.view.php @@ -1,91 +1,91 @@ -setTemplatePath($this->module_path.'tpl'); - - // 설치가 되어 있으면 오류 - if(Context::isInstalled()) return $this->stop('msg_already_installed'); - - // 컨트롤러 생성 - $oInstallController = &getController('install'); - $this->install_enable = $oInstallController->checkInstallEnv(); - - // 설치 가능한 환경이라면 installController::makeDefaultDirectory() 실행 - if($this->install_enable) $oInstallController->makeDefaultDirectory(); - } - - /** - * @brief license 메세지 노출 - **/ - function dispInstallIntroduce() { - $install_config_file = FileHandler::getRealPath('./config/install.config.php'); - if(file_exists($install_config_file)){ - include $install_config_file; - if(is_array($install_config)){ - foreach($install_config as $k => $v) Context::set($k,$v,true); - unset($GLOBALS['__DB__']); - $oInstallController = &getController('install'); - $oInstallController->procInstall(); - header("location: ./"); - exit; - } - } - - $this->setTemplateFile('introduce'); - } - - /** - * @brief 설치 환경에 대한 메세지 보여줌 - **/ - function dispInstallCheckEnv() { - $this->setTemplateFile('check_env'); - } - - - /** - * @brief DB 선택 화면 - **/ - function dispInstallSelectDB() { - // 설치 불가능하다면 check_env를 출력 - if(!$this->install_enable) return $this->dispInstallCheckEnv(); - - // ftp 정보 입력 - if(ini_get('safe_mode') && !Context::isFTPRegisted()) { - $this->setTemplateFile('ftp'); - } else { - $this->setTemplateFile('select_db'); - } - } - - /** - * @brief DB 정보/ 최고 관리자 정보 입력 화면을 보여줌 - **/ - function dispInstallForm() { - // 설치 불가능하다면 check_env를 출력 - if(!$this->install_enable) return $this->dispInstallCheckEnv(); - - // db_type이 지정되지 않았다면 다시 초기화면 출력 - if(!Context::get('db_type')) return $this->dispInstallSelectDB(); - - Context::set('time_zone', $GLOBALS['time_zone']); - - // disp_db_info_form.html 파일 출력 - $tpl_filename = sprintf('form.%s', Context::get('db_type')); - $this->setTemplateFile($tpl_filename); - } - - } -?> +setTemplatePath($this->module_path.'tpl'); + + // 설치가 되어 있으면 오류 + if(Context::isInstalled()) return $this->stop('msg_already_installed'); + + // 컨트롤러 생성 + $oInstallController = &getController('install'); + $this->install_enable = $oInstallController->checkInstallEnv(); + + // 설치 가능한 환경이라면 installController::makeDefaultDirectory() 실행 + if($this->install_enable) $oInstallController->makeDefaultDirectory(); + } + + /** + * @brief license 메세지 노출 + **/ + function dispInstallIntroduce() { + $install_config_file = FileHandler::getRealPath('./config/install.config.php'); + if(file_exists($install_config_file)){ + include $install_config_file; + if(is_array($install_config)){ + foreach($install_config as $k => $v) Context::set($k,$v,true); + unset($GLOBALS['__DB__']); + $oInstallController = &getController('install'); + $oInstallController->procInstall(); + header("location: ./"); + exit; + } + } + + $this->setTemplateFile('introduce'); + } + + /** + * @brief 설치 환경에 대한 메세지 보여줌 + **/ + function dispInstallCheckEnv() { + $this->setTemplateFile('check_env'); + } + + + /** + * @brief DB 선택 화면 + **/ + function dispInstallSelectDB() { + // 설치 불가능하다면 check_env를 출력 + if(!$this->install_enable) return $this->dispInstallCheckEnv(); + + // ftp 정보 입력 + if(ini_get('safe_mode') && !Context::isFTPRegisted()) { + $this->setTemplateFile('ftp'); + } else { + $this->setTemplateFile('select_db'); + } + } + + /** + * @brief DB 정보/ 최고 관리자 정보 입력 화면을 보여줌 + **/ + function dispInstallForm() { + // 설치 불가능하다면 check_env를 출력 + if(!$this->install_enable) return $this->dispInstallCheckEnv(); + + // db_type이 지정되지 않았다면 다시 초기화면 출력 + if(!Context::get('db_type')) return $this->dispInstallSelectDB(); + + Context::set('time_zone', $GLOBALS['time_zone']); + + // disp_db_info_form.html 파일 출력 + $tpl_filename = sprintf('form.%s', Context::get('db_type')); + $this->setTemplateFile($tpl_filename); + } + + } +?> diff --git a/modules/install/lang/en.lang.php b/modules/install/lang/en.lang.php index 587aaeb20..37fb9d5e6 100644 --- a/modules/install/lang/en.lang.php +++ b/modules/install/lang/en.lang.php @@ -1,553 +1,553 @@ -introduce_title = 'XE Installation'; - $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE
- Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - 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 - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -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 -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -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 a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -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. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -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 -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -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 - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - 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 -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -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 Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 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 -above, provided that you also meet all of these conditions: - - 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. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - 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 -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -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 -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -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 -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -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 -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -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. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - 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 -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -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 -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -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 -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -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 - -EndOfLicense; - - $lang->install_condition_title = "Please check the installation requirement."; - - $lang->install_checklist_title = array( - 'php_version' => 'PHP Version', - 'permission' => 'Permission', - 'xml' => 'XML Library', - 'iconv' => 'ICONV Library', - 'gd' => 'GD Library', - 'session' => 'Session.auto_start setting', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '[Required] If PHP version is 5.2.2, XE will not be installed because of bug', - 'permission' => '[Required] XE installation path or ./files directory\'s permission must be 707', - 'xml' => '[Required] XML Library is needed for XML communication', - 'session' => '[Required] PHP setting file\'s (php.ini) \'Session.auto_start\' must equal to zero in order for XE to use the session', - 'iconv' => 'Iconv should be installed in order to convert UTF-8 and other language set', - 'gd' => 'GD Library should be installed in order to use image convert function', - ); - - $lang->install_checklist_xml = 'Install XML Library'; - $lang->install_without_xml = 'XML Library is not installed'; - $lang->install_checklist_gd = 'Install GD Library'; - $lang->install_without_gd = 'GD Library is not installed for image convertion'; - $lang->install_checklist_gd = 'Intall GD Library'; - $lang->install_without_iconv = 'Iconv Library is not installed for processing characters'; - $lang->install_session_auto_start = 'Possible problems might occur due to the php setting. session.auto_start is equal to 1'; - $lang->install_permission_denied = 'Installation path\'s permission doesn\'t equal to 707'; - - $lang->cmd_agree_license = 'I agree with the license'; - $lang->cmd_install_fix_checklist = 'I have fixed the required conditions.'; - $lang->cmd_install_next = 'Continue installation'; - $lang->cmd_ignore = 'Ignore'; - - $lang->db_desc = array( - 'mysql' => 'Using mysql*() function to use mysql DB.
Transaction is disabled because DB file is created by myisam.', - 'mysqli' => 'Using mysqli*() function to use mysql DB.', - 'mysql_innodb' => 'Using innodb to use mysql DB.
Transaction is enabled for innodb', - 'sqlite2' => 'Supporting sqlite2 which saves the data into the file.
When installing, DB file should be created at unreachable place from web.
(Never got tested on stabilization)', - 'sqlite3_pdo' => 'Suppots sqlite3 by PHP\'s PDO.
When installing, DB file should be created at unreachable place from web.', - 'cubrid' => 'Use CUBRID DB. manual', - 'mssql' => 'Use MSSQL DB', - 'postgresql' => 'Use PostgreSql DB.', - 'firebird' => 'Use firebird DB.', - ); - - $lang->form_title = 'Please input DB & Admin information'; - $lang->db_title = 'Please input DB information'; - $lang->db_type = 'DB Type'; - $lang->select_db_type = 'Please select the DB you want to use.'; - $lang->db_hostname = 'DB Hostname'; - $lang->db_port = 'DB Port'; - $lang->db_userid = 'DB ID'; - $lang->db_password = 'DB Password'; - $lang->db_database = 'DB Database'; - $lang->db_database_file = 'DB Database file'; - $lang->db_table_prefix = 'Table header'; - - $lang->admin_title = 'Administrator Info'; - - $lang->env_title = 'Configuration'; - $lang->use_optimizer = 'Enable Optimizer'; - $lang->about_optimizer = 'If optimizer is enabled, users can quickly access to this site, since multiple CSS / JS files are put together and compressed before transmission.
Nevertheless, this optimization might be problematic according to CSS or JS. If you disable it, it would work properly though it would work slower.'; - $lang->use_rewrite = 'Rewrite Mod'; - $lang->about_rewrite = "If web server provides rewrite mod, long URL such as http://blah/?document_srl=123 can be shortened like http://blah/123"; - $lang->time_zone = 'Time Zone'; - $lang->about_time_zone = "If the server time and the time on your location don't accord each other, you can set the time as same as your location by using time zone "; - $lang->qmail_compatibility = 'Enable Qmail'; - $lang->about_qmail_compatibility = 'It will enable sending mails from MTA which cannot distinguish CRLF like Qmail.'; - - $lang->about_database_file = 'Sqlite saves data in the file. Location of the database file should be unreachable by web
Data file should be inside the permission of 707.'; - - $lang->success_installed = 'Installation has been completed'; - - $lang->msg_cannot_proc = 'Installation environment is not proper to proceed.'; - $lang->msg_already_installed = 'XE is already installed'; - $lang->msg_dbconnect_failed = "Error has occurred while connecting DB.\nPlease check DB information again"; - $lang->msg_table_is_exists = "Table is already created in the DB.\nConfig file is recreated"; - $lang->msg_install_completed = "Installation has been completed.\nThank you for choosing XE"; - $lang->msg_install_failed = "An error has occurred while creating installation file."; - - $lang->ftp_get_list = "Get List"; -?> +introduce_title = 'XE Installation'; + $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + 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 + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +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 +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +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 a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +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. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +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 +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +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 + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + 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 +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +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 Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 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 +above, provided that you also meet all of these conditions: + + 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. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + 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 +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +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 +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +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 +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +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 +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +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. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + 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 +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +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 +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +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 +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +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 + +EndOfLicense; + + $lang->install_condition_title = "Please check the installation requirement."; + + $lang->install_checklist_title = array( + 'php_version' => 'PHP Version', + 'permission' => 'Permission', + 'xml' => 'XML Library', + 'iconv' => 'ICONV Library', + 'gd' => 'GD Library', + 'session' => 'Session.auto_start setting', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '[Required] If PHP version is 5.2.2, XE will not be installed because of bug', + 'permission' => '[Required] XE installation path or ./files directory\'s permission must be 707', + 'xml' => '[Required] XML Library is needed for XML communication', + 'session' => '[Required] PHP setting file\'s (php.ini) \'Session.auto_start\' must equal to zero in order for XE to use the session', + 'iconv' => 'Iconv should be installed in order to convert UTF-8 and other language set', + 'gd' => 'GD Library should be installed in order to use image convert function', + ); + + $lang->install_checklist_xml = 'Install XML Library'; + $lang->install_without_xml = 'XML Library is not installed'; + $lang->install_checklist_gd = 'Install GD Library'; + $lang->install_without_gd = 'GD Library is not installed for image convertion'; + $lang->install_checklist_gd = 'Intall GD Library'; + $lang->install_without_iconv = 'Iconv Library is not installed for processing characters'; + $lang->install_session_auto_start = 'Possible problems might occur due to the php setting. session.auto_start is equal to 1'; + $lang->install_permission_denied = 'Installation path\'s permission doesn\'t equal to 707'; + + $lang->cmd_agree_license = 'I agree with the license'; + $lang->cmd_install_fix_checklist = 'I have fixed the required conditions.'; + $lang->cmd_install_next = 'Continue installation'; + $lang->cmd_ignore = 'Ignore'; + + $lang->db_desc = array( + 'mysql' => 'Using mysql*() function to use mysql DB.
Transaction is disabled because DB file is created by myisam.', + 'mysqli' => 'Using mysqli*() function to use mysql DB.', + 'mysql_innodb' => 'Using innodb to use mysql DB.
Transaction is enabled for innodb', + 'sqlite2' => 'Supporting sqlite2 which saves the data into the file.
When installing, DB file should be created at unreachable place from web.
(Never got tested on stabilization)', + 'sqlite3_pdo' => 'Suppots sqlite3 by PHP\'s PDO.
When installing, DB file should be created at unreachable place from web.', + 'cubrid' => 'Use CUBRID DB. manual', + 'mssql' => 'Use MSSQL DB', + 'postgresql' => 'Use PostgreSql DB.', + 'firebird' => 'Use firebird DB.', + ); + + $lang->form_title = 'Please input DB & Admin information'; + $lang->db_title = 'Please input DB information'; + $lang->db_type = 'DB Type'; + $lang->select_db_type = 'Please select the DB you want to use.'; + $lang->db_hostname = 'DB Hostname'; + $lang->db_port = 'DB Port'; + $lang->db_userid = 'DB ID'; + $lang->db_password = 'DB Password'; + $lang->db_database = 'DB Database'; + $lang->db_database_file = 'DB Database file'; + $lang->db_table_prefix = 'Table header'; + + $lang->admin_title = 'Administrator Info'; + + $lang->env_title = 'Configuration'; + $lang->use_optimizer = 'Enable Optimizer'; + $lang->about_optimizer = 'If optimizer is enabled, users can quickly access to this site, since multiple CSS / JS files are put together and compressed before transmission.
Nevertheless, this optimization might be problematic according to CSS or JS. If you disable it, it would work properly though it would work slower.'; + $lang->use_rewrite = 'Rewrite Mod'; + $lang->about_rewrite = "If web server provides rewrite mod, long URL such as http://blah/?document_srl=123 can be shortened like http://blah/123"; + $lang->time_zone = 'Time Zone'; + $lang->about_time_zone = "If the server time and the time on your location don't accord each other, you can set the time as same as your location by using time zone "; + $lang->qmail_compatibility = 'Enable Qmail'; + $lang->about_qmail_compatibility = 'It will enable sending mails from MTA which cannot distinguish CRLF like Qmail.'; + + $lang->about_database_file = 'Sqlite saves data in the file. Location of the database file should be unreachable by web
Data file should be inside the permission of 707.'; + + $lang->success_installed = 'Installation has been completed'; + + $lang->msg_cannot_proc = 'Installation environment is not proper to proceed.'; + $lang->msg_already_installed = 'XE is already installed'; + $lang->msg_dbconnect_failed = "Error has occurred while connecting DB.\nPlease check DB information again"; + $lang->msg_table_is_exists = "Table is already created in the DB.\nConfig file is recreated"; + $lang->msg_install_completed = "Installation has been completed.\nThank you for choosing XE"; + $lang->msg_install_failed = "An error has occurred while creating installation file."; + + $lang->ftp_get_list = "Get List"; +?> diff --git a/modules/install/lang/es.lang.php b/modules/install/lang/es.lang.php index 1251db718..8764f5c87 100644 --- a/modules/install/lang/es.lang.php +++ b/modules/install/lang/es.lang.php @@ -1,7 +1,7 @@ introduce_title = 'Installation du XE '; - $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - 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 - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -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 -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -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 a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -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. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -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 -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -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 - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - 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 -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -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 Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 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 -above, provided that you also meet all of these conditions: - - 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. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - 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 -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -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 -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -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 -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -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 -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -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. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - 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 -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -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 -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -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 -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -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 - - - - -EndOfLicense; - - $lang->install_condition_title = "Vérifiez les conditions obligatoires pour l'installation, S.V.P."; - - $lang->install_checklist_title = array( - 'php_version' => 'Version de PHP', - 'permission' => 'Autorisation', - 'xml' => 'Bibliothèque de XML', - 'iconv' => 'Bibliothèque de ICONV', - 'gd' => 'Bibliothèque de GD', - 'session' => 'Configuration de Session.auto_start', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '[Obligatoire] Si la version de PHP est 5.2.2, XE ne sera pas installé à cause du bogue', - 'permission' => '[Obligatoire] Chemin de l\'installation de XE ou la permission de répertoire de ./files doit être 707', - 'xml' => '[Obligatoire] La bibliothèque de XML est nécessaire pour la communication de XML', - 'session' => '[Obligatoire] \'Session.auto_start\' dans le fichier de configuration pour PHP (php.ini) doit être égal à zéro car XE utilise la session', - 'iconv' => 'Iconv doit être installé afin de convertir UTF-8 et des autres assortiments des langues', - 'gd' => 'La bibliothèque de GD doit être installé afin d\'utiliser la fonction à convertir des images', - ); - - $lang->install_checklist_xml = 'Installation la bibliothèque de XML'; - $lang->install_without_xml = 'La bibliothèque de XML n\'est pas installée'; - $lang->install_checklist_gd = 'Installation la bibliothèque de GD'; - $lang->install_without_gd = 'La bibliothèque de GD pour convertir des images n\'est pas installée'; - $lang->install_checklist_iconv = 'Installation la bibliothèque d\'Iconv'; - $lang->install_without_iconv = 'La bibliothèque d\'Iconv pour traiter les caractères n\'est pas installée'; - $lang->install_session_auto_start = 'Des problèmes possibles peuvent avoir lieu car session.auto_start==1 dans la configuration de PHP'; - $lang->install_permission_denied = 'La permission du chemin d\'installation n\'est pas égale à 707'; - - $lang->cmd_agree_license = 'Je suis d\'accord avec la licence'; - $lang->cmd_install_fix_checklist = 'J\'ai corrigé les conditions obligatoires.'; - $lang->cmd_install_next = 'Continuer à installer'; - $lang->cmd_ignore = 'Ignore'; - - $lang->db_desc = array( - 'mysql' => 'Utilisera fonction mysql*() pour utiliser la base de données de mysql.
La transaction sera invalidé parce que le fichier de Base de Données est créé par myisam.', - 'mysqli' => 'Utilisera fonction mysqli*() pour utiliser la base de données de mysql.
La transaction sera invalidé parce que le fichier de Base de Données est créé par myisam.', - 'mysql_innodb' => 'Utilisera innodb pour utiliser Base de Données de mysql.
La transaction sera validé pour innodb', - 'sqlite2' => 'Surpporter sqlite2 qui conserve les données dans les fichiers.
Quand vous installez, vous devez créer le fichier de Base de Données dans une place que l\'on ne peut pas accéder par web.
(Jamais testé sur stabilization)', - 'sqlite3_pdo' => 'Supporter sqlite3 PDO de PHP.
Quand vous installez, vous devez cr?r le fichier de Base de Données dans une place que l\'on ne peut pas accéder par Web.', - 'cubrid' => 'Utiliser la Base de Données de CUBRID. manual', - 'mssql' => 'Utiliser la Base de Données de MSSQL.', - 'postgresql' => 'Utiliser la Base de Données de PostgreSql.', - 'firebird' => 'Utiliser la Base de Données de firebird.', - ); - - $lang->form_title = 'Entrer des informations de Base de données et Administrateur'; - $lang->db_title = 'Entrez l\'information de Base de Données, S.V.P.'; - $lang->db_type = 'Sorte de Base de Données'; - $lang->select_db_type = 'Choisissez la Base de Données que vous voulez utiliser.'; - $lang->db_hostname = 'Hostname(Nom de l\'ordinateur central) de Base de Données (LOCALHOST généralement)'; - $lang->db_port = 'Port de Base de Données'; - $lang->db_userid = 'Compte(ID) pour le Base de Données'; - $lang->db_password = 'Mot de passe pour le Base de Données'; - $lang->db_database = 'Nom de Base de Données'; - $lang->db_database_file = 'Fichier de Base de Données'; - $lang->db_table_prefix = 'En-tête de la table'; - - $lang->admin_title = 'Informations d\'Administrateur'; - - $lang->env_title = 'Configuration'; - $lang->use_optimizer = 'Valider Optimiseur'; - $lang->about_optimizer = 'Si l\'optimiseur est validé, utilisateur peut accéder rapidement ce site parce que plusieurs fichiers de CSS / JS sont reliés ensemble et comprimés avant transmission.
Néanmoins, cette optimisation peut arriver problématique selong CSS ou JS. Si vous l\'invalidez, ça marchera correctement pourtant il marchera plus lentement.'; - $lang->use_rewrite = 'Utiliser mode de récrire(rewrite mod)'; - $lang->about_rewrite = "Si le serveur de web est capable d'utiliser le mode de récrire, URL longue comme http://murmure/?document_srl=123 peut être abrégé comme http://murmure/123"; - $lang->time_zone = 'Fuseau horaire'; - $lang->about_time_zone = "Si l'heure de serveur et celle de votre emplacement ne s'accordent pas, vous pouvez remettre l'heure comme le même heure de votre lieu en configurant le fuseau horaire "; - $lang->qmail_compatibility = 'Compatible avec Qmail'; - $lang->about_qmail_compatibility = 'Le mél sera envoyé en MTA qui ne peut pas reconnaître le CRLF comme délimiteur des lignes comme le Qmail.'; - - $lang->about_database_file = 'Sqlite conserve des données dans le fichier. Vous devez placer le fichier de la base de données où l\'on ne peut pas accéder par web.
Le fichier des Donées doit être en dedans la permission 707.'; - - $lang->success_installed = 'Installation s\'est complété'; - - $lang->msg_cannot_proc = 'Environnement d\'Installation n\'est pas équipé à procéder.'; - $lang->msg_already_installed = 'XE est déjà installé'; - $lang->msg_dbconnect_failed = "Erreur a lieu en essayant connecter à la Base de Données.\nVérifiez encore une fois les informations sur la Base de Données, S.V.P."; - $lang->msg_table_is_exists = "La Table est déjà créée dans la Base de Données.\nLe fichier de Configuration est recréé."; - $lang->msg_install_completed = "Installation a complété.\nMerci pour choisir XE"; - $lang->msg_install_failed = "Une erreur a lieu en créant le fichier d\'installation."; - - $lang->ftp_get_list = "Get List"; -?> +introduce_title = 'Installation du XE '; + $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + 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 + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +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 +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +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 a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +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. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +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 +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +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 + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + 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 +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +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 Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 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 +above, provided that you also meet all of these conditions: + + 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. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + 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 +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +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 +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +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 +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +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 +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +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. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + 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 +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +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 +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +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 +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +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 + + + + +EndOfLicense; + + $lang->install_condition_title = "Vérifiez les conditions obligatoires pour l'installation, S.V.P."; + + $lang->install_checklist_title = array( + 'php_version' => 'Version de PHP', + 'permission' => 'Autorisation', + 'xml' => 'Bibliothèque de XML', + 'iconv' => 'Bibliothèque de ICONV', + 'gd' => 'Bibliothèque de GD', + 'session' => 'Configuration de Session.auto_start', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '[Obligatoire] Si la version de PHP est 5.2.2, XE ne sera pas installé à cause du bogue', + 'permission' => '[Obligatoire] Chemin de l\'installation de XE ou la permission de répertoire de ./files doit être 707', + 'xml' => '[Obligatoire] La bibliothèque de XML est nécessaire pour la communication de XML', + 'session' => '[Obligatoire] \'Session.auto_start\' dans le fichier de configuration pour PHP (php.ini) doit être égal à zéro car XE utilise la session', + 'iconv' => 'Iconv doit être installé afin de convertir UTF-8 et des autres assortiments des langues', + 'gd' => 'La bibliothèque de GD doit être installé afin d\'utiliser la fonction à convertir des images', + ); + + $lang->install_checklist_xml = 'Installation la bibliothèque de XML'; + $lang->install_without_xml = 'La bibliothèque de XML n\'est pas installée'; + $lang->install_checklist_gd = 'Installation la bibliothèque de GD'; + $lang->install_without_gd = 'La bibliothèque de GD pour convertir des images n\'est pas installée'; + $lang->install_checklist_iconv = 'Installation la bibliothèque d\'Iconv'; + $lang->install_without_iconv = 'La bibliothèque d\'Iconv pour traiter les caractères n\'est pas installée'; + $lang->install_session_auto_start = 'Des problèmes possibles peuvent avoir lieu car session.auto_start==1 dans la configuration de PHP'; + $lang->install_permission_denied = 'La permission du chemin d\'installation n\'est pas égale à 707'; + + $lang->cmd_agree_license = 'Je suis d\'accord avec la licence'; + $lang->cmd_install_fix_checklist = 'J\'ai corrigé les conditions obligatoires.'; + $lang->cmd_install_next = 'Continuer à installer'; + $lang->cmd_ignore = 'Ignore'; + + $lang->db_desc = array( + 'mysql' => 'Utilisera fonction mysql*() pour utiliser la base de données de mysql.
La transaction sera invalidé parce que le fichier de Base de Données est créé par myisam.', + 'mysqli' => 'Utilisera fonction mysqli*() pour utiliser la base de données de mysql.
La transaction sera invalidé parce que le fichier de Base de Données est créé par myisam.', + 'mysql_innodb' => 'Utilisera innodb pour utiliser Base de Données de mysql.
La transaction sera validé pour innodb', + 'sqlite2' => 'Surpporter sqlite2 qui conserve les données dans les fichiers.
Quand vous installez, vous devez créer le fichier de Base de Données dans une place que l\'on ne peut pas accéder par web.
(Jamais testé sur stabilization)', + 'sqlite3_pdo' => 'Supporter sqlite3 PDO de PHP.
Quand vous installez, vous devez cr?r le fichier de Base de Données dans une place que l\'on ne peut pas accéder par Web.', + 'cubrid' => 'Utiliser la Base de Données de CUBRID. manual', + 'mssql' => 'Utiliser la Base de Données de MSSQL.', + 'postgresql' => 'Utiliser la Base de Données de PostgreSql.', + 'firebird' => 'Utiliser la Base de Données de firebird.', + ); + + $lang->form_title = 'Entrer des informations de Base de données et Administrateur'; + $lang->db_title = 'Entrez l\'information de Base de Données, S.V.P.'; + $lang->db_type = 'Sorte de Base de Données'; + $lang->select_db_type = 'Choisissez la Base de Données que vous voulez utiliser.'; + $lang->db_hostname = 'Hostname(Nom de l\'ordinateur central) de Base de Données (LOCALHOST généralement)'; + $lang->db_port = 'Port de Base de Données'; + $lang->db_userid = 'Compte(ID) pour le Base de Données'; + $lang->db_password = 'Mot de passe pour le Base de Données'; + $lang->db_database = 'Nom de Base de Données'; + $lang->db_database_file = 'Fichier de Base de Données'; + $lang->db_table_prefix = 'En-tête de la table'; + + $lang->admin_title = 'Informations d\'Administrateur'; + + $lang->env_title = 'Configuration'; + $lang->use_optimizer = 'Valider Optimiseur'; + $lang->about_optimizer = 'Si l\'optimiseur est validé, utilisateur peut accéder rapidement ce site parce que plusieurs fichiers de CSS / JS sont reliés ensemble et comprimés avant transmission.
Néanmoins, cette optimisation peut arriver problématique selong CSS ou JS. Si vous l\'invalidez, ça marchera correctement pourtant il marchera plus lentement.'; + $lang->use_rewrite = 'Utiliser mode de récrire(rewrite mod)'; + $lang->about_rewrite = "Si le serveur de web est capable d'utiliser le mode de récrire, URL longue comme http://murmure/?document_srl=123 peut être abrégé comme http://murmure/123"; + $lang->time_zone = 'Fuseau horaire'; + $lang->about_time_zone = "Si l'heure de serveur et celle de votre emplacement ne s'accordent pas, vous pouvez remettre l'heure comme le même heure de votre lieu en configurant le fuseau horaire "; + $lang->qmail_compatibility = 'Compatible avec Qmail'; + $lang->about_qmail_compatibility = 'Le mél sera envoyé en MTA qui ne peut pas reconnaître le CRLF comme délimiteur des lignes comme le Qmail.'; + + $lang->about_database_file = 'Sqlite conserve des données dans le fichier. Vous devez placer le fichier de la base de données où l\'on ne peut pas accéder par web.
Le fichier des Donées doit être en dedans la permission 707.'; + + $lang->success_installed = 'Installation s\'est complété'; + + $lang->msg_cannot_proc = 'Environnement d\'Installation n\'est pas équipé à procéder.'; + $lang->msg_already_installed = 'XE est déjà installé'; + $lang->msg_dbconnect_failed = "Erreur a lieu en essayant connecter à la Base de Données.\nVérifiez encore une fois les informations sur la Base de Données, S.V.P."; + $lang->msg_table_is_exists = "La Table est déjà créée dans la Base de Données.\nLe fichier de Configuration est recréé."; + $lang->msg_install_completed = "Installation a complété.\nMerci pour choisir XE"; + $lang->msg_install_failed = "Une erreur a lieu en créant le fichier d\'installation."; + + $lang->ftp_get_list = "Get List"; +?> diff --git a/modules/install/lang/jp.lang.php b/modules/install/lang/jp.lang.php index 253c8a48e..b3d3359ff 100644 --- a/modules/install/lang/jp.lang.php +++ b/modules/install/lang/jp.lang.php @@ -1,553 +1,553 @@ -introduce_title = 'XEのインストール'; - $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - 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 - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -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 -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -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 a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -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. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -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 -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -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 - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - 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 -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -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 Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 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 -above, provided that you also meet all of these conditions: - - 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. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - 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 -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -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 -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -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 -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -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 -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -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. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - 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 -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -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 -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -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 -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -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 - -EndOfLicense; - - $lang->install_condition_title = "インストールするための必須条件を確認して下さい。"; - - $lang->install_checklist_title = array( - 'php_version' => 'PHPバージョン', - 'permission' => 'パーミッション', - 'xml' => 'XMLライブラリ', - 'iconv' => 'ICONVライブラリ', - 'gd' => 'GDライブラリ', - 'session' => 'Session.auto_startの設定', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '【必須】PHPバージョンが 5.2.2の場合は、PHPのセキュリティバグのため、インストール出来ません。', - 'permission' => '【必須】XEのインストールパスまたは「./files」ディレクトリのパーミッションを「707」に設定して下さい。', - 'xml' => '【必須】XML通信のためにXMLライブラリが必要です', - 'session' => '【必須】XEでは、セッションを使用しているため、「php.ini」の設定を「session.auto_start=0」にして下さい。', - 'iconv' => 'UTF-8と多言語サポート及び文字コード変換のため、「iconv」をインストールする必要があります。', - 'gd' => 'イメージ変換機能を使用するためには、「GDライブラリ」をインストールする必要があります。', - ); - - $lang->install_checklist_xml = 'XMLライブラリのインストール'; - $lang->install_without_xml = 'XMLライブラリがインストールされていません。'; - $lang->install_checklist_gd = 'GDライブラリのインストール'; - $lang->install_without_gd = 'イメージ変換用のGDライブラリがインストールされていません。'; - $lang->install_checklist_gd = 'GDライブラリのインストール'; - $lang->install_without_iconv = '文字列処理のための「iconv」ライブラリがインストールされていません。'; - $lang->install_session_auto_start = 'PHPの設定で「session.auto_start==1」 にするとセッション処理に問題が発生することがあります。'; - $lang->install_permission_denied = 'インストールする対象ディレクトリのパーミッションが「707」になっていません。'; - - $lang->cmd_agree_license = 'ライセンスに同意します。'; - $lang->cmd_install_fix_checklist = 'インストール必須条件を設定しました。'; - $lang->cmd_install_next = 'インストールを続けます。'; - $lang->cmd_ignore = 'FTP設定を省略する'; - - $lang->db_desc = array( - 'mysql' => 'MySQL DBでPHPの「mysql*()」関数を利用してデータの入出力を行います。
DBは「myisam」タイプで作成されるため、トランザクション処理は出来ません。', - 'mysqli' => 'MySQL DBでPHPの「mysqli*()」関数を利用してデータの入出力を行います。
DBは「myisam」タイプで作成されるため、トランザクション処理は出来ません。', - 'mysql_innodb' => 'MySQL DBで「innodb」タイプでデータの入出力を行います。
「innodb」ではトランザクションの処理が行えます。', - 'sqlite2' => 'ファイルタイプデータベースである「sqlite2」をサポートします。
インストール時、セキュリティのため、DBファイルはウェブがらアクセス出来ない場所に作成して下さい。
(安定化までのテストは行われていません)', - 'sqlite3_pdo' => 'PHPのPDOを経由うして「sqlite3」をサポートします。
インストール時、セキュリティのため、DBファイルはウェブからアクセス出来ない場所に作成して下さい。', - 'cubrid' => 'CUBRID DBを利用します。 manual', - 'mssql' => 'MSSQL DBを利用します。', - 'postgresql' => 'PostgreSql DBを利用します。', - 'firebird' => 'Firebird DBを利用します。
DB生成方法 (create database "/path/dbname.fdb" page_size=8192 default character set UTF8;)', - ); - - $lang->form_title = 'データベース & 管理者情報入力'; - $lang->db_title = 'データベース情報入力'; - $lang->db_type = 'データベースの種類'; - $lang->select_db_type = '使用するデータベース種類を選択して下さい。'; - $lang->db_hostname = 'ホスト名'; - $lang->db_port = 'ポート番号'; - $lang->db_userid = 'ユーザID'; - $lang->db_password = 'パスワード'; - $lang->db_database = 'データベース名'; - $lang->db_database_file = 'データベースファイル'; - $lang->db_table_prefix = 'テーブルプレフィックス'; - - $lang->admin_title = '管理者情報'; - - $lang->env_title = '環境設定'; - $lang->use_optimizer = 'オプティマイザー使用'; - $lang->about_optimizer = 'オプティマイザーを使用すると多数の「CSS/JS」ファイルを、統合・圧縮して転送するのでレスポンスが早くなります。
但し、CSSまたはJSファイルによっては問題が生じる場合があります。この場合は、チェックを外すと正常に動作します。'; - $lang->use_rewrite = 'リライト・モジュールを使用'; - $lang->about_rewrite = 'Webサーバで「リライト・モジュール(mod_rewrite)」をサポートしている場合は、「http://アドレス/?document_srl=123」のようなアドレスを動的だけど「http://アドレス/123」のように静的なページに見せることが出来ます。'; - $lang->time_zone = 'タイムゾーン'; - $lang->about_time_zone = 'サーバの設定時間とサービスしているローカル時間との差がある場合、タイムゾーンを指定して表示時間を合わせることが出来ます。'; - $lang->qmail_compatibility = 'Qmail 互換'; - $lang->about_qmail_compatibility = 'Qmail等、CRLFを改行コードとして認識出来ないMTA(Message Transfer Agent)で、メールの送信が出来るようにします。'; - - $lang->about_database_file = 'Sqliteはファイルにデータを保存します。そのため、データベースファイルにはウェブからアクセス出来ない場所にしなければなりません。
データファイルのパーミッションは「707」に設定して下さい。'; - - $lang->success_installed = '正常にインストールされました。'; - - $lang->msg_cannot_proc = 'インストール出来る環境が整っていないため、リクエストを実行出来ませんでした。'; - $lang->msg_already_installed = '既にインストールされています。'; - $lang->msg_dbconnect_failed = "データベースアクセスにエラーが発生しました。\nデータベースの情報をもう一度確認して下さい。"; - $lang->msg_table_is_exists = "既にデータベースにデーブルが作成されています。\nconfigファイルを再作成しました。"; - $lang->msg_install_completed = "インストールが完了しました。\nありがとうございます。"; - $lang->msg_install_failed = 'インストールファイルを作成する際にエラーが発生しました。'; - - $lang->ftp_get_list = "Get List"; -?> +introduce_title = 'XEのインストール'; + $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + 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 + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +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 +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +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 a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +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. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +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 +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +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 + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + 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 +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +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 Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 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 +above, provided that you also meet all of these conditions: + + 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. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + 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 +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +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 +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +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 +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +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 +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +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. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + 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 +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +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 +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +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 +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +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 + +EndOfLicense; + + $lang->install_condition_title = "インストールするための必須条件を確認して下さい。"; + + $lang->install_checklist_title = array( + 'php_version' => 'PHPバージョン', + 'permission' => 'パーミッション', + 'xml' => 'XMLライブラリ', + 'iconv' => 'ICONVライブラリ', + 'gd' => 'GDライブラリ', + 'session' => 'Session.auto_startの設定', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '【必須】PHPバージョンが 5.2.2の場合は、PHPのセキュリティバグのため、インストール出来ません。', + 'permission' => '【必須】XEのインストールパスまたは「./files」ディレクトリのパーミッションを「707」に設定して下さい。', + 'xml' => '【必須】XML通信のためにXMLライブラリが必要です', + 'session' => '【必須】XEでは、セッションを使用しているため、「php.ini」の設定を「session.auto_start=0」にして下さい。', + 'iconv' => 'UTF-8と多言語サポート及び文字コード変換のため、「iconv」をインストールする必要があります。', + 'gd' => 'イメージ変換機能を使用するためには、「GDライブラリ」をインストールする必要があります。', + ); + + $lang->install_checklist_xml = 'XMLライブラリのインストール'; + $lang->install_without_xml = 'XMLライブラリがインストールされていません。'; + $lang->install_checklist_gd = 'GDライブラリのインストール'; + $lang->install_without_gd = 'イメージ変換用のGDライブラリがインストールされていません。'; + $lang->install_checklist_gd = 'GDライブラリのインストール'; + $lang->install_without_iconv = '文字列処理のための「iconv」ライブラリがインストールされていません。'; + $lang->install_session_auto_start = 'PHPの設定で「session.auto_start==1」 にするとセッション処理に問題が発生することがあります。'; + $lang->install_permission_denied = 'インストールする対象ディレクトリのパーミッションが「707」になっていません。'; + + $lang->cmd_agree_license = 'ライセンスに同意します。'; + $lang->cmd_install_fix_checklist = 'インストール必須条件を設定しました。'; + $lang->cmd_install_next = 'インストールを続けます。'; + $lang->cmd_ignore = 'FTP設定を省略する'; + + $lang->db_desc = array( + 'mysql' => 'MySQL DBでPHPの「mysql*()」関数を利用してデータの入出力を行います。
DBは「myisam」タイプで作成されるため、トランザクション処理は出来ません。', + 'mysqli' => 'MySQL DBでPHPの「mysqli*()」関数を利用してデータの入出力を行います。
DBは「myisam」タイプで作成されるため、トランザクション処理は出来ません。', + 'mysql_innodb' => 'MySQL DBで「innodb」タイプでデータの入出力を行います。
「innodb」ではトランザクションの処理が行えます。', + 'sqlite2' => 'ファイルタイプデータベースである「sqlite2」をサポートします。
インストール時、セキュリティのため、DBファイルはウェブがらアクセス出来ない場所に作成して下さい。
(安定化までのテストは行われていません)', + 'sqlite3_pdo' => 'PHPのPDOを経由うして「sqlite3」をサポートします。
インストール時、セキュリティのため、DBファイルはウェブからアクセス出来ない場所に作成して下さい。', + 'cubrid' => 'CUBRID DBを利用します。 manual', + 'mssql' => 'MSSQL DBを利用します。', + 'postgresql' => 'PostgreSql DBを利用します。', + 'firebird' => 'Firebird DBを利用します。
DB生成方法 (create database "/path/dbname.fdb" page_size=8192 default character set UTF8;)', + ); + + $lang->form_title = 'データベース & 管理者情報入力'; + $lang->db_title = 'データベース情報入力'; + $lang->db_type = 'データベースの種類'; + $lang->select_db_type = '使用するデータベース種類を選択して下さい。'; + $lang->db_hostname = 'ホスト名'; + $lang->db_port = 'ポート番号'; + $lang->db_userid = 'ユーザID'; + $lang->db_password = 'パスワード'; + $lang->db_database = 'データベース名'; + $lang->db_database_file = 'データベースファイル'; + $lang->db_table_prefix = 'テーブルプレフィックス'; + + $lang->admin_title = '管理者情報'; + + $lang->env_title = '環境設定'; + $lang->use_optimizer = 'オプティマイザー使用'; + $lang->about_optimizer = 'オプティマイザーを使用すると多数の「CSS/JS」ファイルを、統合・圧縮して転送するのでレスポンスが早くなります。
但し、CSSまたはJSファイルによっては問題が生じる場合があります。この場合は、チェックを外すと正常に動作します。'; + $lang->use_rewrite = 'リライト・モジュールを使用'; + $lang->about_rewrite = 'Webサーバで「リライト・モジュール(mod_rewrite)」をサポートしている場合は、「http://アドレス/?document_srl=123」のようなアドレスを動的だけど「http://アドレス/123」のように静的なページに見せることが出来ます。'; + $lang->time_zone = 'タイムゾーン'; + $lang->about_time_zone = 'サーバの設定時間とサービスしているローカル時間との差がある場合、タイムゾーンを指定して表示時間を合わせることが出来ます。'; + $lang->qmail_compatibility = 'Qmail 互換'; + $lang->about_qmail_compatibility = 'Qmail等、CRLFを改行コードとして認識出来ないMTA(Message Transfer Agent)で、メールの送信が出来るようにします。'; + + $lang->about_database_file = 'Sqliteはファイルにデータを保存します。そのため、データベースファイルにはウェブからアクセス出来ない場所にしなければなりません。
データファイルのパーミッションは「707」に設定して下さい。'; + + $lang->success_installed = '正常にインストールされました。'; + + $lang->msg_cannot_proc = 'インストール出来る環境が整っていないため、リクエストを実行出来ませんでした。'; + $lang->msg_already_installed = '既にインストールされています。'; + $lang->msg_dbconnect_failed = "データベースアクセスにエラーが発生しました。\nデータベースの情報をもう一度確認して下さい。"; + $lang->msg_table_is_exists = "既にデータベースにデーブルが作成されています。\nconfigファイルを再作成しました。"; + $lang->msg_install_completed = "インストールが完了しました。\nありがとうございます。"; + $lang->msg_install_failed = 'インストールファイルを作成する際にエラーが発生しました。'; + + $lang->ftp_get_list = "Get List"; +?> diff --git a/modules/install/lang/ko.lang.php b/modules/install/lang/ko.lang.php index 470cfec8a..5a0c3d070 100644 --- a/modules/install/lang/ko.lang.php +++ b/modules/install/lang/ko.lang.php @@ -1,555 +1,555 @@ -introduce_title = 'XE 설치'; - $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - 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 - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -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 -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -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 a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -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. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -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 -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -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 - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - 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 -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -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 Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 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 -above, provided that you also meet all of these conditions: - - 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. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - 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 -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -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 -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -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 -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -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 -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -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. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - 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 -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -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 -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -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 -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -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 - - - -EndOfLicense; - - $lang->install_condition_title = '필수 설치조건을 확인하세요.'; - - $lang->install_checklist_title = array( - 'php_version' => 'PHP Version', - 'permission' => '퍼미션', - 'xml' => 'XML 라이브러리', - 'iconv' => 'ICONV 라이브러리', - 'gd' => 'GD 라이브러리', - 'session' => 'Session.auto_start 설정', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '[필수] PHP버전이 5.2.2일 경우 PHP의 버그로 인하여 설치되지 않습니다.', - 'permission' => '[필수] XE의 설치 경로 또는 ./files 디렉토리의 퍼미션이 707이어야 합니다.', - 'xml' => '[필수] XML통신을 위하여 XML 라이브러리가 필요합니다.', - 'session' => '[필수] XE에서 세션 사용을 위해 php.ini 설정의 session.auto_start=0 이어야 합니다.', - 'iconv' => 'UTF-8과 다른 언어셋의 변환을 위한 iconv설치가 필요합니다.', - 'gd' => '이미지변환 기능을 사용하기 위해 GD라이브러리가 설치되어 있어야 합니다.', - ); - - $lang->install_checklist_xml = 'XML라이브러리 설치'; - $lang->install_without_xml = 'xml 라이브러리가 설치되어 있지 않습니다.'; - $lang->install_checklist_gd = 'GD라이브러리 설치'; - $lang->install_without_gd = '이미지 변환을 위한 GD 라이브러리가 설치되어 있지 않습니다.'; - $lang->install_checklist_gd = 'GD라이브러리 설치'; - $lang->install_without_iconv = '문자열을 처리하기 위한 iconv 라이브러리가 설치되어 있지 않습니다.'; - $lang->install_session_auto_start = 'php설정의 session.auto_start==1 이라 세션 처리에 문제가 발생할 수 있습니다.'; - $lang->install_permission_denied = '설치대상 디렉토리의 퍼미션이 707이 아닙니다.'; - - $lang->cmd_agree_license = '라이선스에 동의합니다.'; - $lang->cmd_install_fix_checklist = '필수 설치조건을 설정하였습니다.'; - $lang->cmd_install_next = '설치를 진행합니다.'; - $lang->cmd_ignore = '무시'; - - $lang->db_desc = array( - 'mysql' => 'MySQL DB를 php의 mysql*()함수를 이용하여 사용합니다.
DB 파일은 myisam으로 생성되기에 트랜잭션이 이루어지지 않습니다.', - 'mysqli' => 'MySQL DB를 php의 mysqli*()함수를 이용하여 사용합니다.
DB 파일은 myisam으로 생성되기에 트랜잭션이 이루어지지 않습니다.', - 'mysql_innodb' => 'MySQL DB를 innodb를 이용하여 사용합니다.
innodb는 트랜잭션을 사용할 수 있습니다.', - 'sqlite2' => '파일로 데이터를 저장하는 sqlite2를 지원합니다.
설치 시 DB파일은 웹에서 접근할 수 없는 곳에 생성하여 주셔야 합니다.
(안정화 테스트가 되지 않았습니다.)', - 'sqlite3_pdo' => 'PHP의 PDO로 sqlite3를 지원합니다.
설치 시 DB파일은 웹에서 접근할 수 없는 곳에 생성하여 주셔야 합니다.', - 'cubrid' => 'CUBRID DB를 이용합니다. manual', - 'mssql' => 'MSSQL DB를 이용합니다.', - 'postgresql' => 'PostgreSql을 이용합니다.', - 'firebird' => 'Firebird를 이용합니다.
DB 생성 방법 (create database "/path/dbname.fdb" page_size=8192 default character set UTF-8;)', - ); - - $lang->form_title = 'DB & 관리자 정보 입력'; - $lang->db_title = 'DB정보 입력'; - $lang->db_type = 'DB 종류'; - $lang->select_db_type = '사용하시려는 DB를 선택해주세요.'; - $lang->db_hostname = 'DB 호스트네임'; - $lang->db_port = 'DB Port'; - $lang->db_userid = 'DB 아이디'; - $lang->db_password = 'DB 비밀번호'; - $lang->db_database = 'DB 데이터베이스'; - $lang->db_database_file = 'DB 데이터베이스 파일'; - $lang->db_table_prefix = '테이블 머리말'; - - $lang->admin_title = '관리자 정보'; - - $lang->env_title = '환경 설정'; - $lang->use_optimizer = 'Optimizer 사용'; - $lang->about_optimizer = 'Optimizer를 사용하면 다수의 CSS/JS파일을 통합/압축 전송하여 매우 빠르게 사이트 접속이 가능하게 합니다.
다만 CSS나 JS에 따라서 문제가 생길 수 있습니다. 이때는 Optimizer 비활성화 하시면 정상적인 동작은 가능합니다.'; - $lang->use_rewrite = 'rewrite mod 사용'; - $lang->about_rewrite = '웹서버에서 rewrite mod를 지원하면 http://주소/?document_srl=123 같이 복잡한 주소를 http://주소/123과 같이 간단하게 줄일 수 있습니다.'; - $lang->time_zone = '표준 시간대'; - $lang->about_time_zone = '서버의 설정시간과 사용하려는 장소의 시간이 차이가 날 경우 표준 시간대를 지정하시면 표시되는 시간을 지정된 곳의 시간으로 사용하실 수 있습니다.'; - $lang->qmail_compatibility = 'Qmail 호환'; - $lang->about_qmail_compatibility = 'Qmail등 CRLF를 줄 구분자로 인식하지 못하는 MTA에서 메일이 발송되도록 합니다.'; - - $lang->about_database_file = 'Sqlite는 파일에 데이터를 저장합니다. 데이터베이스 파일의 위치를 웹에서 접근할 수 없는 곳으로 하셔야 합니다.
데이터 파일은 707퍼미션 설정된 곳으로 지정해주세요.'; - - $lang->success_installed = '설치가 되었습니다.'; - - $lang->msg_cannot_proc = '설치 환경이 갖춰지지 않아 요청을 실행할 수가 없습니다.'; - $lang->msg_already_installed = '이미 설치가 되어 있습니다.'; - $lang->msg_dbconnect_failed = "DB접속 오류가 발생하였습니다.\nDB정보를 다시 확인해주세요."; - $lang->msg_table_is_exists = "이미 DB에 테이블이 생성되어 있습니다.\nconfig파일을 재생성하였습니다."; - $lang->msg_install_completed = "설치가 완료되었습니다.\n감사합니다."; - $lang->msg_install_failed = '설치 파일 생성 시에 오류가 발생하였습니다.'; - - $lang->ftp_get_list = '목록 가져오기'; -?> +introduce_title = 'XE 설치'; + $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + 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 + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +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 +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +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 a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +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. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +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 +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +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 + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + 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 +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +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 Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 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 +above, provided that you also meet all of these conditions: + + 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. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + 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 +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +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 +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +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 +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +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 +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +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. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + 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 +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +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 +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +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 +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +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 + + + +EndOfLicense; + + $lang->install_condition_title = '필수 설치조건을 확인하세요.'; + + $lang->install_checklist_title = array( + 'php_version' => 'PHP Version', + 'permission' => '퍼미션', + 'xml' => 'XML 라이브러리', + 'iconv' => 'ICONV 라이브러리', + 'gd' => 'GD 라이브러리', + 'session' => 'Session.auto_start 설정', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '[필수] PHP버전이 5.2.2일 경우 PHP의 버그로 인하여 설치되지 않습니다.', + 'permission' => '[필수] XE의 설치 경로 또는 ./files 디렉토리의 퍼미션이 707이어야 합니다.', + 'xml' => '[필수] XML통신을 위하여 XML 라이브러리가 필요합니다.', + 'session' => '[필수] XE에서 세션 사용을 위해 php.ini 설정의 session.auto_start=0 이어야 합니다.', + 'iconv' => 'UTF-8과 다른 언어셋의 변환을 위한 iconv설치가 필요합니다.', + 'gd' => '이미지변환 기능을 사용하기 위해 GD라이브러리가 설치되어 있어야 합니다.', + ); + + $lang->install_checklist_xml = 'XML라이브러리 설치'; + $lang->install_without_xml = 'xml 라이브러리가 설치되어 있지 않습니다.'; + $lang->install_checklist_gd = 'GD라이브러리 설치'; + $lang->install_without_gd = '이미지 변환을 위한 GD 라이브러리가 설치되어 있지 않습니다.'; + $lang->install_checklist_gd = 'GD라이브러리 설치'; + $lang->install_without_iconv = '문자열을 처리하기 위한 iconv 라이브러리가 설치되어 있지 않습니다.'; + $lang->install_session_auto_start = 'php설정의 session.auto_start==1 이라 세션 처리에 문제가 발생할 수 있습니다.'; + $lang->install_permission_denied = '설치대상 디렉토리의 퍼미션이 707이 아닙니다.'; + + $lang->cmd_agree_license = '라이선스에 동의합니다.'; + $lang->cmd_install_fix_checklist = '필수 설치조건을 설정하였습니다.'; + $lang->cmd_install_next = '설치를 진행합니다.'; + $lang->cmd_ignore = '무시'; + + $lang->db_desc = array( + 'mysql' => 'MySQL DB를 php의 mysql*()함수를 이용하여 사용합니다.
DB 파일은 myisam으로 생성되기에 트랜잭션이 이루어지지 않습니다.', + 'mysqli' => 'MySQL DB를 php의 mysqli*()함수를 이용하여 사용합니다.
DB 파일은 myisam으로 생성되기에 트랜잭션이 이루어지지 않습니다.', + 'mysql_innodb' => 'MySQL DB를 innodb를 이용하여 사용합니다.
innodb는 트랜잭션을 사용할 수 있습니다.', + 'sqlite2' => '파일로 데이터를 저장하는 sqlite2를 지원합니다.
설치 시 DB파일은 웹에서 접근할 수 없는 곳에 생성하여 주셔야 합니다.
(안정화 테스트가 되지 않았습니다.)', + 'sqlite3_pdo' => 'PHP의 PDO로 sqlite3를 지원합니다.
설치 시 DB파일은 웹에서 접근할 수 없는 곳에 생성하여 주셔야 합니다.', + 'cubrid' => 'CUBRID DB를 이용합니다. manual', + 'mssql' => 'MSSQL DB를 이용합니다.', + 'postgresql' => 'PostgreSql을 이용합니다.', + 'firebird' => 'Firebird를 이용합니다.
DB 생성 방법 (create database "/path/dbname.fdb" page_size=8192 default character set UTF-8;)', + ); + + $lang->form_title = 'DB & 관리자 정보 입력'; + $lang->db_title = 'DB정보 입력'; + $lang->db_type = 'DB 종류'; + $lang->select_db_type = '사용하시려는 DB를 선택해주세요.'; + $lang->db_hostname = 'DB 호스트네임'; + $lang->db_port = 'DB Port'; + $lang->db_userid = 'DB 아이디'; + $lang->db_password = 'DB 비밀번호'; + $lang->db_database = 'DB 데이터베이스'; + $lang->db_database_file = 'DB 데이터베이스 파일'; + $lang->db_table_prefix = '테이블 머리말'; + + $lang->admin_title = '관리자 정보'; + + $lang->env_title = '환경 설정'; + $lang->use_optimizer = 'Optimizer 사용'; + $lang->about_optimizer = 'Optimizer를 사용하면 다수의 CSS/JS파일을 통합/압축 전송하여 매우 빠르게 사이트 접속이 가능하게 합니다.
다만 CSS나 JS에 따라서 문제가 생길 수 있습니다. 이때는 Optimizer 비활성화 하시면 정상적인 동작은 가능합니다.'; + $lang->use_rewrite = 'rewrite mod 사용'; + $lang->about_rewrite = '웹서버에서 rewrite mod를 지원하면 http://주소/?document_srl=123 같이 복잡한 주소를 http://주소/123과 같이 간단하게 줄일 수 있습니다.'; + $lang->time_zone = '표준 시간대'; + $lang->about_time_zone = '서버의 설정시간과 사용하려는 장소의 시간이 차이가 날 경우 표준 시간대를 지정하시면 표시되는 시간을 지정된 곳의 시간으로 사용하실 수 있습니다.'; + $lang->qmail_compatibility = 'Qmail 호환'; + $lang->about_qmail_compatibility = 'Qmail등 CRLF를 줄 구분자로 인식하지 못하는 MTA에서 메일이 발송되도록 합니다.'; + + $lang->about_database_file = 'Sqlite는 파일에 데이터를 저장합니다. 데이터베이스 파일의 위치를 웹에서 접근할 수 없는 곳으로 하셔야 합니다.
데이터 파일은 707퍼미션 설정된 곳으로 지정해주세요.'; + + $lang->success_installed = '설치가 되었습니다.'; + + $lang->msg_cannot_proc = '설치 환경이 갖춰지지 않아 요청을 실행할 수가 없습니다.'; + $lang->msg_already_installed = '이미 설치가 되어 있습니다.'; + $lang->msg_dbconnect_failed = "DB접속 오류가 발생하였습니다.\nDB정보를 다시 확인해주세요."; + $lang->msg_table_is_exists = "이미 DB에 테이블이 생성되어 있습니다.\nconfig파일을 재생성하였습니다."; + $lang->msg_install_completed = "설치가 완료되었습니다.\n감사합니다."; + $lang->msg_install_failed = '설치 파일 생성 시에 오류가 발생하였습니다.'; + + $lang->ftp_get_list = '목록 가져오기'; +?> diff --git a/modules/install/lang/ru.lang.php b/modules/install/lang/ru.lang.php index e203801a1..75c5d1885 100644 --- a/modules/install/lang/ru.lang.php +++ b/modules/install/lang/ru.lang.php @@ -1,555 +1,555 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack for XE - **/ - - $lang->introduce_title = 'Установка XE'; - $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - 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 - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -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 -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -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 a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -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. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -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 -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -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 - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - 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 -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -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 Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 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 -above, provided that you also meet all of these conditions: - - 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. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - 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 -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -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 -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -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 -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -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 -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -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. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - 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 -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -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 -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -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 -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -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 - - - -EndOfLicense; - - $lang->install_condition_title = "Пожалуйста, проверьте требования к установке."; - - $lang->install_checklist_title = array( - 'php_version' => 'Версия PHP', - 'permission' => 'Права доступа', - 'xml' => 'XML библиотека', - 'iconv' => 'ICONV библиотека', - 'gd' => 'GD библиотека', - 'session' => 'Session.auto_start настройка', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '[Требуется] Если версия PHP равна 5.2.2, то XE не будет установлена из-за бага', - 'permission' => '[Требуется] Путь установки XE или директория ./files должна иметь права доступа 707', - 'xml' => '[Требуется] XML Библиотека нужна для XML коммуникации', - 'session' => '[Требуется] Файл настроек PHP (php.ini) \'Session.auto_start\' должен быть равен нулю, чтобы XE могла использовать сессии', - 'iconv' => 'Iconv должна быть установлена для конвертирования между UTF-8 и иными языковыми кодировками', - 'gd' => 'GD Библиотека должна быть установлена для использования функции конвертироваия изображений', - ); - - $lang->install_checklist_xml = 'Установить XML библиотеку'; - $lang->install_without_xml = 'XML библиотека не установлена'; - $lang->install_checklist_gd = 'Установить GD библиотеку'; - $lang->install_without_gd = 'GD библиотека не установлена'; - $lang->install_checklist_gd = 'Установить GD библиотеку'; - $lang->install_without_iconv = 'Iconv библиотека не установлена'; - $lang->install_session_auto_start = 'Возможно возникнут проблемы из-за настройки PHP session.auto_start, установленной в 1'; - $lang->install_permission_denied = 'Права доступа пути не установлены в 707'; - - $lang->cmd_agree_license = 'Я согласен с данной лицензией'; - $lang->cmd_install_fix_checklist = 'Я удоволетворил требуемые условия'; - $lang->cmd_install_next = 'Продолжить установку'; - $lang->cmd_ignore = 'Ignore'; - - $lang->db_desc = array( - 'mysql' => 'Используем mysql*() функцию, чтобы использовать базу данных mysql.
Транзакция отключена из-за того, что файл базы данных создан посредством myisam.', - 'mysqli' => 'Используем mysqli*() функцию, чтобы использовать базу данных mysql.
Транзакция отключена из-за того, что файл базы данных создан посредством myisam.', - 'mysql_innodb' => 'Используем innodb чтобы использовать базу данных mysql.
Транзакция включена для innodb', - 'sqlite2' => 'Поддерживает sqlite2, которая сохраняет данные в файл.
Устанавливая, следует размещать файл базы данных в недоступном с веб месте.
(Никогда не тестировалось на стабильность)', - 'sqlite3_pdo' => 'Поддерживает sqlite3 посредством PHP\'s PDO.
Устанавливая, следует размещать файл базы данных в недоступном с веб месте.', - 'cubrid' => 'Используем CUBRID DB. manual', - 'mssql' => 'Используем MSSQL DB.', - 'postgresql' => 'Используем PostgreSql DB.', - 'firebird' => 'Используем firebird DB.', - ); - - $lang->form_title = 'Пожалуйста, введите дазу данных & Административная Информация'; - $lang->db_title = 'Пожалуйста, введите информацию базы данных'; - $lang->db_type = 'Тип базы данных'; - $lang->select_db_type = 'Пожалуйста, выберите базу данных, которую Вы хотите использовать.'; - $lang->db_hostname = 'Хост базы данных'; - $lang->db_port = 'Порт базы данных'; - $lang->db_userid = 'ID базы данных'; - $lang->db_password = 'Пароль базы данных'; - $lang->db_database = 'Имя базы данных'; - $lang->db_database_file = 'Файл базы данных'; - $lang->db_table_prefix = 'Префикс таблиц'; - - $lang->admin_title = 'Административная информация'; - - $lang->env_title = 'Конфигурация'; - $lang->use_optimizer = 'Включить оптимизатор'; - $lang->about_optimizer = 'Если оптимизатор включен, пользователи могут быстро использовать этот сайт, поскольку несколько CSS / JS файлов собраны вместе и сжаты до передачи.
Тем не менее, эта оптимизация может быть проблематичной согласно CSS или JS. Если Вы выключите ее, движок будет работать правильно, хотя и медленее.'; - $lang->use_rewrite = 'Использовать модуль перезаписи (rewrite mod)'; - $lang->about_rewrite = "Если сервер предлагает rewrite mod, длинные URL такие как http://blah/?document_srl=123 могут быть сокращены до http://blah/123"; - $lang->time_zone = 'Часовой пояс'; - $lang->about_time_zone = "Если серверное время и Ваше локальное время не совпадают, Вы можете установить такое же время, как Ваше локальное, используя часовой пояс"; - $lang->qmail_compatibility = 'Qmail 호환'; - $lang->about_qmail_compatibility = 'Qmail등 CRLF를 줄 구분자로 인식하지 못하는 MTA에서 메일이 발송되도록 합니다.'; - - $lang->about_database_file = 'Sqlite сохраняет данные в файл. Размещение базы данных должно быть недоступно с веб
Файл базы данных должен иметь права доступа 707.'; - - $lang->success_installed = 'Установка завершена'; - - $lang->msg_cannot_proc = 'Невозможно исполнить запрос, поскольку окружение установки не указано'; - $lang->msg_already_installed = 'XE уже установлена'; - $lang->msg_dbconnect_failed = "Произошла ошибка подключения к базе данных.\nПожалуйста, проверьте иформацию базы данных еще раз"; - $lang->msg_table_is_exists = "Таблица существует в базе данных.\nФайл конфигурации создан заново"; - $lang->msg_install_completed = "Установка завершена.\nСпасибо Вам за выбор XE"; - $lang->msg_install_failed = "Произошла ошибка при создании файла конфигурации."; - - $lang->ftp_get_list = 'Get List'; -?> +introduce_title = 'Установка XE'; + $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + 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 + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +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 +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +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 a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +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. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +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 +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +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 + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + 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 +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +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 Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 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 +above, provided that you also meet all of these conditions: + + 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. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + 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 +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +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 +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +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 +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +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 +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +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. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + 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 +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +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 +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +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 +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +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 + + + +EndOfLicense; + + $lang->install_condition_title = "Пожалуйста, проверьте требования к установке."; + + $lang->install_checklist_title = array( + 'php_version' => 'Версия PHP', + 'permission' => 'Права доступа', + 'xml' => 'XML библиотека', + 'iconv' => 'ICONV библиотека', + 'gd' => 'GD библиотека', + 'session' => 'Session.auto_start настройка', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '[Требуется] Если версия PHP равна 5.2.2, то XE не будет установлена из-за бага', + 'permission' => '[Требуется] Путь установки XE или директория ./files должна иметь права доступа 707', + 'xml' => '[Требуется] XML Библиотека нужна для XML коммуникации', + 'session' => '[Требуется] Файл настроек PHP (php.ini) \'Session.auto_start\' должен быть равен нулю, чтобы XE могла использовать сессии', + 'iconv' => 'Iconv должна быть установлена для конвертирования между UTF-8 и иными языковыми кодировками', + 'gd' => 'GD Библиотека должна быть установлена для использования функции конвертироваия изображений', + ); + + $lang->install_checklist_xml = 'Установить XML библиотеку'; + $lang->install_without_xml = 'XML библиотека не установлена'; + $lang->install_checklist_gd = 'Установить GD библиотеку'; + $lang->install_without_gd = 'GD библиотека не установлена'; + $lang->install_checklist_gd = 'Установить GD библиотеку'; + $lang->install_without_iconv = 'Iconv библиотека не установлена'; + $lang->install_session_auto_start = 'Возможно возникнут проблемы из-за настройки PHP session.auto_start, установленной в 1'; + $lang->install_permission_denied = 'Права доступа пути не установлены в 707'; + + $lang->cmd_agree_license = 'Я согласен с данной лицензией'; + $lang->cmd_install_fix_checklist = 'Я удоволетворил требуемые условия'; + $lang->cmd_install_next = 'Продолжить установку'; + $lang->cmd_ignore = 'Ignore'; + + $lang->db_desc = array( + 'mysql' => 'Используем mysql*() функцию, чтобы использовать базу данных mysql.
Транзакция отключена из-за того, что файл базы данных создан посредством myisam.', + 'mysqli' => 'Используем mysqli*() функцию, чтобы использовать базу данных mysql.
Транзакция отключена из-за того, что файл базы данных создан посредством myisam.', + 'mysql_innodb' => 'Используем innodb чтобы использовать базу данных mysql.
Транзакция включена для innodb', + 'sqlite2' => 'Поддерживает sqlite2, которая сохраняет данные в файл.
Устанавливая, следует размещать файл базы данных в недоступном с веб месте.
(Никогда не тестировалось на стабильность)', + 'sqlite3_pdo' => 'Поддерживает sqlite3 посредством PHP\'s PDO.
Устанавливая, следует размещать файл базы данных в недоступном с веб месте.', + 'cubrid' => 'Используем CUBRID DB. manual', + 'mssql' => 'Используем MSSQL DB.', + 'postgresql' => 'Используем PostgreSql DB.', + 'firebird' => 'Используем firebird DB.', + ); + + $lang->form_title = 'Пожалуйста, введите дазу данных & Административная Информация'; + $lang->db_title = 'Пожалуйста, введите информацию базы данных'; + $lang->db_type = 'Тип базы данных'; + $lang->select_db_type = 'Пожалуйста, выберите базу данных, которую Вы хотите использовать.'; + $lang->db_hostname = 'Хост базы данных'; + $lang->db_port = 'Порт базы данных'; + $lang->db_userid = 'ID базы данных'; + $lang->db_password = 'Пароль базы данных'; + $lang->db_database = 'Имя базы данных'; + $lang->db_database_file = 'Файл базы данных'; + $lang->db_table_prefix = 'Префикс таблиц'; + + $lang->admin_title = 'Административная информация'; + + $lang->env_title = 'Конфигурация'; + $lang->use_optimizer = 'Включить оптимизатор'; + $lang->about_optimizer = 'Если оптимизатор включен, пользователи могут быстро использовать этот сайт, поскольку несколько CSS / JS файлов собраны вместе и сжаты до передачи.
Тем не менее, эта оптимизация может быть проблематичной согласно CSS или JS. Если Вы выключите ее, движок будет работать правильно, хотя и медленее.'; + $lang->use_rewrite = 'Использовать модуль перезаписи (rewrite mod)'; + $lang->about_rewrite = "Если сервер предлагает rewrite mod, длинные URL такие как http://blah/?document_srl=123 могут быть сокращены до http://blah/123"; + $lang->time_zone = 'Часовой пояс'; + $lang->about_time_zone = "Если серверное время и Ваше локальное время не совпадают, Вы можете установить такое же время, как Ваше локальное, используя часовой пояс"; + $lang->qmail_compatibility = 'Qmail 호환'; + $lang->about_qmail_compatibility = 'Qmail등 CRLF를 줄 구분자로 인식하지 못하는 MTA에서 메일이 발송되도록 합니다.'; + + $lang->about_database_file = 'Sqlite сохраняет данные в файл. Размещение базы данных должно быть недоступно с веб
Файл базы данных должен иметь права доступа 707.'; + + $lang->success_installed = 'Установка завершена'; + + $lang->msg_cannot_proc = 'Невозможно исполнить запрос, поскольку окружение установки не указано'; + $lang->msg_already_installed = 'XE уже установлена'; + $lang->msg_dbconnect_failed = "Произошла ошибка подключения к базе данных.\nПожалуйста, проверьте иформацию базы данных еще раз"; + $lang->msg_table_is_exists = "Таблица существует в базе данных.\nФайл конфигурации создан заново"; + $lang->msg_install_completed = "Установка завершена.\nСпасибо Вам за выбор XE"; + $lang->msg_install_failed = "Произошла ошибка при создании файла конфигурации."; + + $lang->ftp_get_list = 'Get List'; +?> diff --git a/modules/install/lang/vi.lang.php b/modules/install/lang/vi.lang.php index e795a859d..0f785f02b 100644 --- a/modules/install/lang/vi.lang.php +++ b/modules/install/lang/vi.lang.php @@ -1,557 +1,557 @@ -introduce_title = 'Cài đặt XE'; - $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - 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 - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -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 -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -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 a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -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. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -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 -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -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 - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - 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 -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -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 Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 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 -above, provided that you also meet all of these conditions: - - 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. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - 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 -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -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 -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -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 -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -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 -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -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. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - 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 -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -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 -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -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 -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -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 - - - -EndOfLicense; - - $lang->install_condition_title = "Xin hãy kiểm tra những yêu cầu cài đặt."; - - $lang->install_checklist_title = array( - 'php_version' => 'Phiên bản PHP', - 'permission' => 'Sự cho phép', - 'xml' => 'XML Library', - 'iconv' => 'ICONV Library', - 'gd' => 'GD Library', - 'session' => 'Thiết lập Session.auto_start', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '[Bắt buộc] Nếu phiên bản của PHP là 5.2.2, XE sẽ không thể cài đặt vì có lỗi.', - 'permission' => '[Bắt buộc] Thư mục cài đặt của XE hay ./files directory\ phải CHMOD thành 707', - 'xml' => '[Bắt buộc] XML Library cần thiết cho việc truyền thông File XML.', - 'session' => '[Bắt buộc] File thiết lập của PHP (php.ini) \'Session.auto_start\' phải là 0 theo thứ tự số cho phiên làm việc của XE hoạt động.', - 'iconv' => 'Iconv cần phải được cài đặt cho việc chuyển đổi ngôn ngữ thàng UTFF-8 của những ngôn ngữ khác.', - 'gd' => 'GD Library cần phải được cài đặt cho việc chuyển đổi hình ảnh.', - ); - - $lang->install_checklist_xml = 'Cài đặt XML Library'; - $lang->install_without_xml = 'XML Library đã không được cài đặt.'; - $lang->install_checklist_gd = 'Cài đặt GD Library'; - $lang->install_without_gd = 'GD Library đã không được cài đặt cho sự chuyển đổi hình ảnh.'; - $lang->install_checklist_gd = 'Cài đặt GD Library'; - $lang->install_without_iconv = 'Iconv Library đã không được cài đặt cho việc xử lý những đặc tính.'; - $lang->install_session_auto_start = 'Đã có lỗi xảy ra, có lẽ do sự thiết đặt PHP. session.auto_start không phải là 1'; - $lang->install_permission_denied = 'Sự cho phép của thư mục cài đặt không phải là 707'; - - $lang->cmd_agree_license = 'Tôi đã đọc và đồng ý với giấy phép này.'; - $lang->cmd_install_fix_checklist = 'Tôi đã thay đổi để phù hợp với yêu cầu cài đặt.'; - $lang->cmd_install_next = 'Tiếp tục cài đặt'; - $lang->cmd_ignore = 'Bỏ qua'; - - $lang->db_desc = array( - 'mysql' => 'Dùng chức năng mysql*() để sử dụng MySql Database.
Giao dịch được vô hiệu hóa bởi File Database được tạo ra bởi myisam.', - 'mysqli' => 'Dùng chức năng mysqli*() để sử dụng MySql Database.
Giao dịch được vô hiệu hóa bởi File Database được tạo ra bởi myisam.', - 'mysql_innodb' => 'Dùng chức năng innodb để sử dụng MySql Database.
Giao dịch được kích hoạt cho innodb', - 'sqlite2' => 'Hỗ trợ sqlite2 khi lưu Database thành File.
Khi cài đặt, File Database phải được tạo ra tại chỗ không sử dụng được từ Web.
(Không khẳng định sẽ hoạt động ổn định)', - 'sqlite3_pdo' => 'Hỗ trợ sqlite3 bởi PDO của PHP.
Khi cài đặt, File Database phải được tạo ra tại chỗ không sử dụng được từ Web.', - 'cubrid' => 'Sử dụng CUBRID Database. Hướng dẫn', - 'postgresql' => 'Sử dụng PostgreSql Database.', - 'firebird' => 'Sử dụng firebird Database.', - ); - - $lang->form_title = 'Hãy nhập thông tin Database và thông tin Administrator'; - $lang->db_title = 'Xin hãy nhập thông tin Database'; - $lang->db_type = 'Định dạng Database'; - $lang->select_db_type = 'Xin hãy chọn Database bạn muốn sử dụng.'; - $lang->db_hostname = 'Hostname'; - $lang->db_port = 'Port'; - $lang->db_userid = 'Tên truy cập'; - $lang->db_password = 'Mật khẩu'; - $lang->db_database = 'Tên Database'; - $lang->db_database_file = 'File Database'; - $lang->db_table_prefix = 'Tên Table'; - - $lang->admin_title = 'Thông tin Administrator'; - - $lang->env_title = 'Cấu hình'; - $lang->use_optimizer = 'Tối ưu hóa'; - $lang->about_optimizer = 'Nếu tối ưu hóa được kích hoạt, người sử dụng sẽ truy cập nhanh hơn vì những File CSS / JS sẽ được nén lại trước khi được tải xuống.
Tuy vậy, sự tối ưu này cũng làm ảnh hưởng một chút tới File CSS và JS. Nếu bạn tắt, Website của bạn tải chậm hơn.'; - $lang->use_rewrite = 'Mod Rewrite'; - $lang->about_rewrite = "Nếu Host của bạn hỗ trợ Mod Rewrite, khi địa chỉ có dạng http://blah/?document_srl=123 sẽ được rút ngắn thành http://blah/123"; - $lang->time_zone = 'Múi giờ'; - $lang->about_time_zone = "Nếu thời gian của khu vực bạn không tự động cập nhật. Bạn có thể chọn thời gian để hiển thị cho Website."; - $lang->qmail_compatibility = 'Mở Qmail'; - $lang->about_qmail_compatibility = 'Nó sẽ cho phép gửi thư từ MTA mà không phân biệt CRLF.'; - - $lang->about_database_file = 'Sqlite lưu trữ dữ liệu trong một File, vì vậy cần tới sự truy cập đến nó trong Database.
Hãy CHMOD thành 707.'; - - $lang->success_installed = 'Chúc mừng bạn đã cài đặt XE thành công!'; - - $lang->msg_cannot_proc = 'Môi trường cài đặt không thích hợp.'; - $lang->msg_already_installed = 'Một phiên bản nào đó của XE đã được cài đặt từ trước.
Xin hãy kiểm tra lại!'; - $lang->msg_dbconnect_failed = "Đã có lỗi xảy ra khi kết nối tới Database.\nXin vui lòng kiểm tra lại thông tin!"; - $lang->msg_table_is_exists = "Table đã có sẵn trên Database.\nFile Config đã đuwọc thiết lập lại."; - $lang->msg_install_completed = "Đã cài đặt XE thành công!.\nXin cảm ơn đã sử dụng XE!"; - $lang->msg_install_failed = "Đã có lỗi xảy ra khi tạo File cài đặt."; - - $lang->ftp_get_list = "Nhận danh sách"; -?> +introduce_title = 'Cài đặt XE'; + $lang->license = <<GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + 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 + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +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 +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +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 a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +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. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +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 +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +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 + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + 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 +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +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 Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 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 +above, provided that you also meet all of these conditions: + + 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. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + 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 +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +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 +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +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 +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +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 +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +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. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + 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 +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +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 +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +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 +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +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 + + + +EndOfLicense; + + $lang->install_condition_title = "Xin hãy kiểm tra những yêu cầu cài đặt."; + + $lang->install_checklist_title = array( + 'php_version' => 'Phiên bản PHP', + 'permission' => 'Sự cho phép', + 'xml' => 'XML Library', + 'iconv' => 'ICONV Library', + 'gd' => 'GD Library', + 'session' => 'Thiết lập Session.auto_start', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '[Bắt buộc] Nếu phiên bản của PHP là 5.2.2, XE sẽ không thể cài đặt vì có lỗi.', + 'permission' => '[Bắt buộc] Thư mục cài đặt của XE hay ./files directory\ phải CHMOD thành 707', + 'xml' => '[Bắt buộc] XML Library cần thiết cho việc truyền thông File XML.', + 'session' => '[Bắt buộc] File thiết lập của PHP (php.ini) \'Session.auto_start\' phải là 0 theo thứ tự số cho phiên làm việc của XE hoạt động.', + 'iconv' => 'Iconv cần phải được cài đặt cho việc chuyển đổi ngôn ngữ thàng UTFF-8 của những ngôn ngữ khác.', + 'gd' => 'GD Library cần phải được cài đặt cho việc chuyển đổi hình ảnh.', + ); + + $lang->install_checklist_xml = 'Cài đặt XML Library'; + $lang->install_without_xml = 'XML Library đã không được cài đặt.'; + $lang->install_checklist_gd = 'Cài đặt GD Library'; + $lang->install_without_gd = 'GD Library đã không được cài đặt cho sự chuyển đổi hình ảnh.'; + $lang->install_checklist_gd = 'Cài đặt GD Library'; + $lang->install_without_iconv = 'Iconv Library đã không được cài đặt cho việc xử lý những đặc tính.'; + $lang->install_session_auto_start = 'Đã có lỗi xảy ra, có lẽ do sự thiết đặt PHP. session.auto_start không phải là 1'; + $lang->install_permission_denied = 'Sự cho phép của thư mục cài đặt không phải là 707'; + + $lang->cmd_agree_license = 'Tôi đã đọc và đồng ý với giấy phép này.'; + $lang->cmd_install_fix_checklist = 'Tôi đã thay đổi để phù hợp với yêu cầu cài đặt.'; + $lang->cmd_install_next = 'Tiếp tục cài đặt'; + $lang->cmd_ignore = 'Bỏ qua'; + + $lang->db_desc = array( + 'mysql' => 'Dùng chức năng mysql*() để sử dụng MySql Database.
Giao dịch được vô hiệu hóa bởi File Database được tạo ra bởi myisam.', + 'mysqli' => 'Dùng chức năng mysqli*() để sử dụng MySql Database.
Giao dịch được vô hiệu hóa bởi File Database được tạo ra bởi myisam.', + 'mysql_innodb' => 'Dùng chức năng innodb để sử dụng MySql Database.
Giao dịch được kích hoạt cho innodb', + 'sqlite2' => 'Hỗ trợ sqlite2 khi lưu Database thành File.
Khi cài đặt, File Database phải được tạo ra tại chỗ không sử dụng được từ Web.
(Không khẳng định sẽ hoạt động ổn định)', + 'sqlite3_pdo' => 'Hỗ trợ sqlite3 bởi PDO của PHP.
Khi cài đặt, File Database phải được tạo ra tại chỗ không sử dụng được từ Web.', + 'cubrid' => 'Sử dụng CUBRID Database. Hướng dẫn', + 'postgresql' => 'Sử dụng PostgreSql Database.', + 'firebird' => 'Sử dụng firebird Database.', + ); + + $lang->form_title = 'Hãy nhập thông tin Database và thông tin Administrator'; + $lang->db_title = 'Xin hãy nhập thông tin Database'; + $lang->db_type = 'Định dạng Database'; + $lang->select_db_type = 'Xin hãy chọn Database bạn muốn sử dụng.'; + $lang->db_hostname = 'Hostname'; + $lang->db_port = 'Port'; + $lang->db_userid = 'Tên truy cập'; + $lang->db_password = 'Mật khẩu'; + $lang->db_database = 'Tên Database'; + $lang->db_database_file = 'File Database'; + $lang->db_table_prefix = 'Tên Table'; + + $lang->admin_title = 'Thông tin Administrator'; + + $lang->env_title = 'Cấu hình'; + $lang->use_optimizer = 'Tối ưu hóa'; + $lang->about_optimizer = 'Nếu tối ưu hóa được kích hoạt, người sử dụng sẽ truy cập nhanh hơn vì những File CSS / JS sẽ được nén lại trước khi được tải xuống.
Tuy vậy, sự tối ưu này cũng làm ảnh hưởng một chút tới File CSS và JS. Nếu bạn tắt, Website của bạn tải chậm hơn.'; + $lang->use_rewrite = 'Mod Rewrite'; + $lang->about_rewrite = "Nếu Host của bạn hỗ trợ Mod Rewrite, khi địa chỉ có dạng http://blah/?document_srl=123 sẽ được rút ngắn thành http://blah/123"; + $lang->time_zone = 'Múi giờ'; + $lang->about_time_zone = "Nếu thời gian của khu vực bạn không tự động cập nhật. Bạn có thể chọn thời gian để hiển thị cho Website."; + $lang->qmail_compatibility = 'Mở Qmail'; + $lang->about_qmail_compatibility = 'Nó sẽ cho phép gửi thư từ MTA mà không phân biệt CRLF.'; + + $lang->about_database_file = 'Sqlite lưu trữ dữ liệu trong một File, vì vậy cần tới sự truy cập đến nó trong Database.
Hãy CHMOD thành 707.'; + + $lang->success_installed = 'Chúc mừng bạn đã cài đặt XE thành công!'; + + $lang->msg_cannot_proc = 'Môi trường cài đặt không thích hợp.'; + $lang->msg_already_installed = 'Một phiên bản nào đó của XE đã được cài đặt từ trước.
Xin hãy kiểm tra lại!'; + $lang->msg_dbconnect_failed = "Đã có lỗi xảy ra khi kết nối tới Database.\nXin vui lòng kiểm tra lại thông tin!"; + $lang->msg_table_is_exists = "Table đã có sẵn trên Database.\nFile Config đã đuwọc thiết lập lại."; + $lang->msg_install_completed = "Đã cài đặt XE thành công!.\nXin cảm ơn đã sử dụng XE!"; + $lang->msg_install_failed = "Đã có lỗi xảy ra khi tạo File cài đặt."; + + $lang->ftp_get_list = "Nhận danh sách"; +?> diff --git a/modules/install/lang/zh-CN.lang.php b/modules/install/lang/zh-CN.lang.php index d42d62c5b..751572c0b 100644 --- a/modules/install/lang/zh-CN.lang.php +++ b/modules/install/lang/zh-CN.lang.php @@ -1,244 +1,244 @@ -introduce_title = '安装XE'; - $lang->license = <<GNU 较宽松公共许可证 - 1999.2, 第 2.1 版 - - 版权所有 (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - 允许每个人复制和发布本授权文件的完整副本, -但不允许对它进行任何修改。 - -[这是第一次发表的较宽松公共许可证 (Lesser GPL) 版本。它同时也可视为 GNU 函数库公共许可证 (GNU Library Public License) 第 2 版的后继者,故称为 2.1 版] - - 导言 - - 大多数软体许可证决意剥夺您共享和修改软体的自由。相反的,GNU 通用公共许可证力图保证您共享和修改自由软体的自由 —— 保证自由软体对所有使用者都是自由的。 - - 这个许可证,较宽松公共许可证,适用于一些由自由软体基金会与其他决定使用此许可证的软体作者,所特殊设计的软体套件 —— 象是函数库。您也可以使用它,但我们建议您事先仔细考虑,基于以下的说明是否此许可证或原来的通用公共许可证在任何特殊情况下均为较好的方案。 - - 当我们谈到自由软体时,我们所指的是自由,而不是价格。我们的 GNU 通用公共许可证是设计用以确保使您有发布自由软体备份的自由(如果您愿意,您可以对此项服务收取一定的费用);确保您能收到程式原始码或者在您需要时能得到它;确保您能修改软体或将它的一部分用于新的自由软体;而且还确保您知道您可以做上述的这些事情。 - - 为了保护您的权利,我们需要作出限制:禁止任何人否认您上述的权利,或者要求您放弃这些权利。如果您发布软件的副本,或者对之加以修改,这些规定就转化为您的责任。 - - 例如,如果您发布此函数库的副本,不管是免费还是收取费用,您必须将您享有的一切权利给予接受者;您必须确保他们也能收到或得到原始程式码;如果您将此函数库与其他的程式码连结,您必须提供完整的目的对象文件和程序(object file)给接受者,则当他们修改此函数库并重新编译过后,可以重新与目的档连结。您并且要将这些条款给他们看,使他们知道他们有这样的权利。 - - 我们采取两项措施来保护您的权利: (1)用版权来保护函数库。并且,(2)我们提供您这份许可证,赋予您复制,发布和(或)修改这些函数库的法律许可。 - - 为了保护每个发布者,我们需要非常清楚地让每个人明白,自由函数库是没有担保责任的。如果由于某人修改了函数库,并继续加以传播,我们需要它的接受者明白:他们所得到的并不是原始的版本。故由其他人引入的任何问题,对原作者的声誉将不会有任何的影响。 - - 最后,由于软体专利不断地威胁自由软体的存在,我们希望商业公司无法藉由自专利持有者取得一个受限的许可证,而有效地限制自由软体的使用者。因此,我们坚持一个函数库所能取得的任何专利,必须与本许可证所声明的“完全自由使用”一致。 - - 大部分的 GNU 软体,包括一些函数库,是受到原来的 GNU 通用公共许可证的保护。本许可证, GNU 较宽松通用公共许可证,适用于特殊设计的函数库,且与原来的通用公共许可证有很大的不同。我们在特定的函数库中使用它,以准许非自由的程式可以与这些函数库连结。 - - 当一个程式与一个函数库连结,不论是静态连结或使用共享函数库,二者的结合可以合理地说是结合的作品,一个原来的函数库的衍生品。因此,原来的通用公共许可证只有在整个结合品满足其自由的标准时,才予许连结。较宽松通用公共许可证则以更宽松的标准允许其他程式码与本函数库连结。 - - 我们称此许可证 "较宽松" 通用公共许可证,是因为它比起原来的通用公共许可证对使用者的自由做到较少的保护。在与非自由软体竞争时,它也提供其他自由软体的写作者较少的优势。这些不利之处正是我们使用原来的通用公共许可证于许多函数库的理由。然而,较宽松的许可证可在某些特殊场合下带来好处。 - - 例如,在少数情况下,可能会有特殊的需要而鼓励大家尽可能广泛地使用特定的函数库,因而使它成为实际上的标准。为了达到此目标,必须允许非自由的程式使用此函数库。一个较常发生的情况是一个自由的函数库与一个被广泛使用的非自由函数库做相同的工作,在此情况下,限制只有自由软体可以使用此自由函数库不会有多少好处,故我们如用了较宽松通用公共许可证。 - - 在其他情况下,允许非自由程式使用特定的函数库,可以让更多的人们使用自由软体的大部分。例如,允许非自由程式使用 GNU C 函数库可以让更多的人们使用整个 GNU 作业系统,以及它的变形,GNU/Linux 作业系统。 - - 尽管较宽松通用共公许可证对使用者的自由是较少的保护的,它却能确保与此函数库连结的程式的使用者拥有自由,而且具有使用修改过的函数库版本来执行该程式的必要方法。 - - 以下是复制、发布、以及修改的精确条款与条件。请注意 "基于函数库的作品" 以及 "使用函数库的作品" 之间的差异:前者包含来自函数库修改过的原始码;而后者则必须与函数库结合才能执行。 - - GNU 较宽松公共许可证 - 有关复制,发布和修改的条款和条件 - - 0. 本许可证适用于任何软体函数库,或其他包含了由版权所有者加入的注意事项的程式,或其他有公信力的团体宣称其程式可以在较宽松通用公共许可证 (也称之为 "本许可证") 的条款下发布。每一位许可证接受者以 "您" 来称呼。 - - 一个 "函数库" 意指一些软体函数的集合,以及或准备好的资料以方便与应用程式 (其使用了其中某些函数与资料) 连结形成可执行的程式。 - - 以下,"函数库" 一词指的是任何在本条款下发布的这一类软体函数库或作品,一个 "基于本函数库的作品" 意指函数库或任何在版权法下的衍生作品:也就是说,一个包含了本函数库或其一部分的作品,可以是原封不动的,或经过修改的,和/或直接翻译成其他语言的。(在下文中,翻译是不受限地包含在 "修改" 的条款中。) - - 作品的 "原始码" 意指对作品进行修改最优先择取的形式。对函数库而言,完整的原始码意指所有模组的所有原始程式,加上有关的介面的定义,加上控制函数库的安装和编译的 script。 - - 本许可证条款不适用于复制,发布和修改以外的活动。这些活动超出这些条款的范围。使用本函数库来执行本程式的动作不受条款的限制,而程式的输出只有在其内容所构成的作品是基于本函数库时 (与在什么样的工具中使用本函数库来输出无关) ,这一条款才适用。以上是否为真则取决于本函数库具体用来做什么。 - - 1. 只要您在每一程式副本上明显和恰当地宣告版权声明和不承担担保的声明,并保持此许可证的声明和没有担保的声明完整无损,并和程式一起给其他每位程式接受者一份许可证的副本,您就可以用任何媒体复制和发布您收到的函数库的完整原始码。 - - 您可以为转让副本的实际行动收取一定费用。您也可以选择提供担保以换取一定的费用。 - - 2. 只要您同时满足下面的所有条件,您就可以按前面第一款的要求修改函数库的一个或几个副本或它的任何部分,以此形成基于此函数库的作品,并且复制和发布这一经过修改的程式或作品: - - a) 被修改的作品本身必须是一个软体函数库。 - - b) 必须在修改过的档案中附有明确的说明:您修改了此一档案及任何修改的日期。 - - c) 您必须让整个作品允许第三方在此许可证条款下可以免费使用。 - - d)果修改过的函数库其某个设备使用到了「使用本函数库的应用程式」所提供的函数或资料表格,却不是当此设备被呼叫时以参数列传入时,则您必须确实做到,当应用程式不提供这样的函数或表格时,则此设备依旧能工作,且其执行的任何目的仍然有意义。 - - (例如,一个函数库的函数用来计算平方根,其目的是有完整的定义且与应用程式是无关的。因此, 2d 小节要求任何本函数会使用的,由应用程式所提供的函数或表格必须是选择性的:如果应用程式不提供的话,则计算平方根的函数必须依旧能计算平方根) - -这些要求适用于整个修改过的作品。如果能够确定作品的一部分并非本函数库的衍生产品,且可以合理地单独考虑并将它与原作品分开的话,则当您将它作为独立的作品发布时,它不受此许可证和其条款的约束。但是当您将这部分与基于本函数库的作品一同发布时,则整个套件将受到本许可证条款约束,其对于其他许可证持有人的使用范围扩大到整个产品,也就是套件的每个部分,不管它是谁写的。 - -因此,本条款的意图不在于索取权利,或剥夺完全由您完成的作品的权利,而是履行权利来控制基于本函数库的集体作品或衍生作品的发布。 - -此外,将与本函数库无关的作品和本函数库 (或基于本函数库的作品) 一起放在贮存媒体或发布媒体的同一卷上,并不导致将其他作品置于此许可证的约束范围之内。 - - 3.于一个函数库的副本,您可以选择性地使用原来的 GNU 通用公共许可证上的条款来取代本许可证上的条款。如果您要这么做,您必须修改所有的参考到本许可证的注意事项,使它们指向原来的 GNU 通用公共许可证,第二版,以取代本许可证(如果有比第二版的原来的 GNU 通用公共许可证更新的版本出现的话,则如果您愿意的话可以特别指明使用新版)。请不要对这些注意事项做出其他的改变。 - - 一旦在一个副本上做了这样的改变,则该副本就无法撤回这样的改变,故原来的 GNU 通用公共许可证将适用于所有后续的副本以及由此副本衍生出来的作品。 - - 此一选择性适用于当您想要将一部分的函数库原始码复制到一个非函数库的程式使用时。 - - 4. 您可以以目标码或可执行形式复制或发布本函数库 (或符合第 2 款,基于本函数库的作品),只要您遵守前面的第 1、2 款,并同时提供完整的相关机器可读的原始码,而这些原始码必须在前面的第 1 与第 2 款条件下,在一般习惯上用来做软体交换的媒体上发布。 - - 如果所发布的目标码是由指定的地点提供拷贝索取,那么由同一地点所提供等价的原始码拷贝索取可以算作原始码的发布,即使第三方不强求与目标码一起复制原始码。 - - 5. 一个程式若包含不经任何部分修改的函数库,但却是设计经由编译或连结的方式与本函数库一同工作者,称之为 "使用函数库的作品"。这样的一个作品,严格地说,并非本函数库的衍生作品,因而不在本许可证的范围之内。 - - 然而,将 "使用函数库的作品" 与本函数库连结而产生可执行程式,则是本函数库的衍生品 (因为它包函了本函数库的一部分),而不是 "使用函数库的作品",因此其可执行程式包含在本许可证的范围内。第 6 款说明了发布此可执行程式的条款。 - - 当 "使用函数库的作品" 使用了函数库部分的标头档内容时,则此作品即使其原始码不属于本函数库的衍生品,但其目标码仍然是。这一点是否为真特别在是否本作品可以在不需要本函数库即可连结,或者是否该作品本身也是一个函数库时特别明显。 - - 如果这样的目标档只使用数字参数、资料结构层级与附属品、以及小巨集和小内□式 (小于或等于十行) ,则此目标档的使用是不受限的,不论是否它是合法的衍生作品。 (但可执行程式若包函此目标档以及一部分的函数库,仍然将在第 6 款的规定下) - - 否则的话,如果本作品是本函数库的衍生品,您必须在第 6 款的规定下发布该作品的目标码。任何包含该作品的可执行程式也在第 6 款的范围内,不论它们是否直接与本函数库连结。 - - 6. 做为上述条款的例外情况,您也可以将 "使用函数库的作品" 与本函数库结合或连结,以产生包含部分本函数库的作品,并在允许使用者自身使用时可以修改该作品,以及在对修改进行反组译除错的情况下,您可以依照您的选择发布该作品。 - - 您必须在每个作品的副本突显出如下的注意事项:本函数库在作品中被使用,以及本函数库以及它的使用是在本许可证的规定下。您必须提供本许可证的副本。如果该作品在执行时显示版权声明,您必须在其中包含本函数库的版权声明,以及指引使用者取得本许可证的副本。同时,您必须做到以下其中一件事: - - a) 必须将完整的机器可读的函数库原始码包含在该作品中,包括任何该作品使用到的改变 (这些改变必须在前述第 1 与第 2 款的要求下发布);而且,如果该作品是一个与函数库连结的「完整的、机器可□的 "使用函数库的作品"」,则要有目标码和/或原始码,如此使用者可以修改本函数库且可以重新连结,以产生包函修改过的函数库的修改过的可执行程式。 (理所当然的若使用者修改了函数库的档案定义内容时,则该作品不必然可以重新编译以使用修改过的定义。) - - b) 在与函数库连结时使用适当的分享函数库连结机制。一个适当的机制是: (1) 在执行时使用已存在于使用者的电脑中的函数库副本,而不是将函数库的函数复制到可执行程式里,以及 (2) 如果使用者安装了一份修改过的函数库,只要修改过的版本在介面上与该作品在编译连结时所用的版本是相容的,则该执行程式可以与修改过的函数库运作良好。 - - c) 在该作品内提供书面报价,有效期不少于三年,以提供同样的使用者上述第 6a 款中的内容,费用不得超过该程式发布的实际成本。 - - d)如果所发布的作品是由指定的地点提供拷贝索取,则由同一地点提供上述内容的等价拷贝索取。 - - e) 确定使用者已经收到该作品的一份复制,或是您已经寄给该使用者一份复制品。 - - 对于一个可执行程式,其所需的 "使用函数库的作品" 的形式必须包括任何要从中再产生可执行程式时所需的资料与工具程式。然而,有一个特殊例外,其所发布的内容不需要包括任何一般与「可执行本程式的作业系统」的主要部分 (如编译器、核心等) 一起发布的部分 (不论是原始码或可执行码),除非这些组成部分和可执行作品结合在一起。 - - 一个可能情况是,这些要求与其他通常不与作业系统在一起的私有函数库的版权限制相抵触,这样的抵触表示您不能将它们与本函数库一起用于您发布的可执行程式中。 - - 7. 您可以将使用本函数库的函数库设备,以及其他不在本许可证范围内的函数库,对等地放入一个单独的函数库中,并在基于本函数库的作品以及其他函数库在其他状态下同意可以个别发布,以及您做到以下两点的情况下,您可以发布此结合的函数库: - - a) 将基于本函数库的作品单独不与其他函数库设备结合地,与此结合的函数库一同发布。该作品必须在上述条款的规定下发布。 - - b) 在此结合的函数库中明显地指出其中一部分的作品是基于本函数库,并且说明那里可以找到同样不具结合形式的作品。 - - 8. 非您明确按许可证提出的要求去做,否则您不能复制、修改、转发许可证、与本函数库连结、和发布本函数库。任何试图用其他方式复制、修改、转发许可证、与本函数库连结、和发布本函数库是无效的,而且将自动结束许可证赋予您的权利。然而,对那些从您那里按许可证条款得到副本和权利的人们,只要他们继续全面履行条款,许可证赋予他们的权利仍然有效。 - - 9. 您没有在许可证上签字,因而您没有必要一定接受此一许可证。然而,没有任何其他东西赋予您修改和发布本函数库及其衍生作品的权利。如果您不接受许可证,这些行为是法律禁止的。因此,如果您修改或发布函数库 (或任何基于函数库的作品) ,您就表明您接受这一许可证以及它的所有有关复制、发布和修改本函数库或基于它的作品的条款和条件。 - - 10. 每当您重新发布函数库 (或任何基于函数库的作品) 时,接受者自动从原始许可证颁发者那里接到受这些条款和条件支配的复制、发布、连结或修改本函数库的许可。您不可以强迫接受者履行除了这里赋予他们的权利之外的其他限制。您也没有强求第三方履行许可证条款的义务。 - - 11. 如果由于法院判决或违反专利的指控或任何其他原因 (不限于专利问题) 的结果,使得强加于您的条件 (不管是法院判决,协议书或其他) 和许可证的条件有冲突时,他们也不能令您背离许可证的条款。在您不能同时满足本许可证规定的义务及其他相关的义务来发布函数库时,则结果您只能够根本不发布函数库。例如,如果某一专利许可证不允许所有直接或间接从您那里接受副本的人们,在不付专利费的情况下重新发布函数库,唯一能同时满足两方面要求的办法是停止发布函数库。 - -如果本条款的任何部分在特定的环境下无效或无法实施,就使用条款的其余部分,并将这部分条款作为整体用于其他环境。 - -本条款的目的不在于引诱您侵犯专利或其他财产权的要求,或争论这种要求的有效性。本条款的主要目的在于保护自由软体发布系统的完整性。它是通过公共许可证的应用来实现的。许多人已依赖同是出自此系统的应用程式,经由此系统发布大量自由软体而做出慷慨的供献。作者/捐献者有权决定他/她是否通过任何其他系统发布软体,许可证持有人不能强加这种选择。 - -本节的目的在于明确说明许可证其余部分可能产生的结果。 - - 12.如果由于专利或者由于有版权的介面问题使函数库在某些国家的发布和使用受到限制,则在许可证约束下的原始版权拥有者可以增加发布地区的限制条款,将这些国家明确排除在外,并在这些国家以外的地区发布函数库。在这种情况下,许可证套件含的限制条款和许可证正文一样有效。 - - 13. 自由软体基金会可能随时出版较宽松通用公共许可证的修改版或新版。新版和当前的版本在原则上保持一致,但在提到新问题时或有关事项时,在细节上可能出现差别。 - -每一版本都有不同的版本号。如果函数库指定可适用的许可证版本号以及 "任何更新的版本" ,您有权选择遵循指定的版本或自由软体基金会以后出版的新版本。如果函数库未指定许可证版本,您可选择自由软体基金会已经出版的任何版本。 - - 14. 如果您愿意将函数库的一部分结合到其他自由程式中,而它们的发布条件不同,请写信给作者,要求准予使用。如果是自由软体基金会加以版权保护的软体,写信给自由软体基金会,我们有时会作为例外的情况处理。我们的决定受两个主要目标的指导,这两个主要目标是:我们的自由软体的衍生作品继续保持自由状态,以及从整体上促进软体的共享和重复利用。 - - 没有担保 - - 15. 由于函数库准予免费使用,在适用法准许的范围内,对函数库没有担保。除非另有书面说明,版权所有者和/或其他提供函数库的人们 "一样" 不提供任何类型的担保,不论是明确的,还是隐含的,包括但不限于可销售和适合特定用途的隐含保证。全部的风险,如函数库的质量和性能问题都由您来承担。如果函数库出现缺陷,您应当承担所有必要的服务、修复和改正的费用。 - - 16.非适用法或书面协议的要求,在任何情况下,任何版权所有者或任何按许可证条款修改和发布函数库的人们都不对您的损失负有任何责任。包括由于使用或不能使用函数库引起的任何一般的、特殊的、偶然发生的或重大的损失 (包括但不限于数据的损失,或者数据变得不精确,或者您或第三方的持续的损失,或者函数库不能和其他软体协调运行等) 。即使版权所有者和其他人提到这种损失的可能性也不例外。 - - -条文结束- -EndOfLicense; - - $lang->install_condition_title = "检测运行环境"; - - $lang->install_checklist_title = array( - 'php_version' => 'PHP版本', - 'permission' => '权限', - 'xml' => 'XML库', - 'iconv' => 'ICONV库', - 'gd' => 'GD库', - 'session' => 'Session.auto_start 设置', - ); - - $lang->install_checklist_desc = array( - 'php_version' => '[必须] 由于 PHP 5.2.2 版本BUG,无法安装 XE。', - 'permission' => '[必须] 的安装路径或 ./files目录属性必须是707', - 'xml' => '[必须]为了 XML通讯,将需要XML库', - 'session' => '[必须] 为了使用缓冲功能,必须在php.ini当中设置 session.auto_start=0', - 'iconv' => '为了UTF-8和其他语言环境之间的互相转换,必须安装iconv', - 'gd' => '为了使用图片转换功能,必须先得安装GD库', - ); - - $lang->install_checklist_xml = '安装XML库'; - $lang->install_without_xml = '还没有安装xml库!'; - $lang->install_checklist_gd = '安装GD库'; - $lang->install_without_gd = '还没有安装负责转换图片功能的GD库!'; - $lang->install_checklist_gd = '安装GD库'; - $lang->install_without_iconv = '还没有安装负责处理字串的iconv库!'; - $lang->install_session_auto_start = 'PHP设置中设置成session.auto_start==1,可能处理session时发生错误。'; - $lang->install_permission_denied = '安装目录属性不是707!'; - - $lang->cmd_agree_license = '同意'; - $lang->cmd_install_fix_checklist = '已设置了必要的安装条件。'; - $lang->cmd_install_next = '开始安装'; - $lang->cmd_ignore = '忽略'; - - $lang->db_desc = array( - 'mysql' => '利用php的 mysql*()函数使用mysql DB。
DB数据是以myisam生成,因此不能实现transaction。', - 'mysqli' => '利用php的 mysqli*()函数使用mysql DB。
DB数据是以myisam生成,因此不能实现transaction。', - 'mysql_innodb' => '利用innodb使用mysql DB。
innodb可以使用transaction。', - 'sqlite2' => '支持用文件形式保存数据的sqlite2。
安装时DB文件应在web不能访问的地方生成。
(还没有通过安全的测试)', - 'sqlite3_pdo' => '用PHP的 PDO支持 sqlite3。
安装时DB文件应在web不能访问的地方生成。', - 'cubrid' => '使用CUBRID DB。 manual', - 'mssql' => '使用MSSQL DB。', - 'postgresql' => '使用PostgreSql DB。', - 'firebird' => '使用Firebird DB。', - ); - - $lang->form_title = '数据库及管理员基本信息'; - $lang->db_title = '输入数据库信息'; - $lang->db_type = '数据库类型'; - $lang->select_db_type = '选择数据库'; - $lang->db_hostname = '服务器名'; - $lang->db_port = '数据库端口'; - $lang->db_userid = 'DB用户名'; - $lang->db_password = 'DB密码'; - $lang->db_database = '数据库名'; - $lang->db_database_file = '数据库文件'; - $lang->db_table_prefix = '前缀'; - - $lang->admin_title = '管理员信息'; - - $lang->env_title = '环境设置'; - $lang->use_optimizer = '使用Optimizer'; - $lang->about_optimizer = '使用Optimizer可以对大部分的CSS/ JS文件进行整合/压缩传送使之加快网站访问速度。
只是有时会发生小小的问题。这时候请暂时不要使用Optimizer。'; - $lang->use_rewrite = '使用rewrite模块'; - $lang->about_rewrite = '如服务器支持rewrite模块且选择此项,可以简化复杂的网址。
例如,http://域名/?document_srl=123简化为http://域名/123。'; - $lang->time_zone = '时区'; - $lang->about_time_zone = '服务器时间和您所处的时间有差异时,可以设置时区来满足你所需要的时间显示。'; - $lang->qmail_compatibility = 'Qmail互换'; - $lang->about_qmail_compatibility = '支持不能识别CRLF为换行符的Qmail等MTA,也能发送电子邮件。'; - - $lang->about_database_file = 'Sqlite是文件里保存数据。数据库的文件位置应该放在web不能访问的地方。
数据文件应放在具有707属性的位置。'; - - $lang->success_installed = '已完成安装。'; - - $lang->msg_cannot_proc = '不具备安装所需环境,不能继续进行。'; - $lang->msg_already_installed = '已安装'; - $lang->msg_dbconnect_failed = "连接DB时发生错误。\n请重新确认DB信息。"; - $lang->msg_table_is_exists = "已生成数据表。\n重新生成了config文件。"; - $lang->msg_install_completed = "安装完成。\n非常感谢。"; - $lang->msg_install_failed = "生成安装文件时发生错误。"; - - $lang->ftp_get_list = '载入FTP列表'; -?> +introduce_title = '安装XE'; + $lang->license = <<GNU 较宽松公共许可证 + 1999.2, 第 2.1 版 + + 版权所有 (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + 允许每个人复制和发布本授权文件的完整副本, +但不允许对它进行任何修改。 + +[这是第一次发表的较宽松公共许可证 (Lesser GPL) 版本。它同时也可视为 GNU 函数库公共许可证 (GNU Library Public License) 第 2 版的后继者,故称为 2.1 版] + + 导言 + + 大多数软体许可证决意剥夺您共享和修改软体的自由。相反的,GNU 通用公共许可证力图保证您共享和修改自由软体的自由 —— 保证自由软体对所有使用者都是自由的。 + + 这个许可证,较宽松公共许可证,适用于一些由自由软体基金会与其他决定使用此许可证的软体作者,所特殊设计的软体套件 —— 象是函数库。您也可以使用它,但我们建议您事先仔细考虑,基于以下的说明是否此许可证或原来的通用公共许可证在任何特殊情况下均为较好的方案。 + + 当我们谈到自由软体时,我们所指的是自由,而不是价格。我们的 GNU 通用公共许可证是设计用以确保使您有发布自由软体备份的自由(如果您愿意,您可以对此项服务收取一定的费用);确保您能收到程式原始码或者在您需要时能得到它;确保您能修改软体或将它的一部分用于新的自由软体;而且还确保您知道您可以做上述的这些事情。 + + 为了保护您的权利,我们需要作出限制:禁止任何人否认您上述的权利,或者要求您放弃这些权利。如果您发布软件的副本,或者对之加以修改,这些规定就转化为您的责任。 + + 例如,如果您发布此函数库的副本,不管是免费还是收取费用,您必须将您享有的一切权利给予接受者;您必须确保他们也能收到或得到原始程式码;如果您将此函数库与其他的程式码连结,您必须提供完整的目的对象文件和程序(object file)给接受者,则当他们修改此函数库并重新编译过后,可以重新与目的档连结。您并且要将这些条款给他们看,使他们知道他们有这样的权利。 + + 我们采取两项措施来保护您的权利: (1)用版权来保护函数库。并且,(2)我们提供您这份许可证,赋予您复制,发布和(或)修改这些函数库的法律许可。 + + 为了保护每个发布者,我们需要非常清楚地让每个人明白,自由函数库是没有担保责任的。如果由于某人修改了函数库,并继续加以传播,我们需要它的接受者明白:他们所得到的并不是原始的版本。故由其他人引入的任何问题,对原作者的声誉将不会有任何的影响。 + + 最后,由于软体专利不断地威胁自由软体的存在,我们希望商业公司无法藉由自专利持有者取得一个受限的许可证,而有效地限制自由软体的使用者。因此,我们坚持一个函数库所能取得的任何专利,必须与本许可证所声明的“完全自由使用”一致。 + + 大部分的 GNU 软体,包括一些函数库,是受到原来的 GNU 通用公共许可证的保护。本许可证, GNU 较宽松通用公共许可证,适用于特殊设计的函数库,且与原来的通用公共许可证有很大的不同。我们在特定的函数库中使用它,以准许非自由的程式可以与这些函数库连结。 + + 当一个程式与一个函数库连结,不论是静态连结或使用共享函数库,二者的结合可以合理地说是结合的作品,一个原来的函数库的衍生品。因此,原来的通用公共许可证只有在整个结合品满足其自由的标准时,才予许连结。较宽松通用公共许可证则以更宽松的标准允许其他程式码与本函数库连结。 + + 我们称此许可证 "较宽松" 通用公共许可证,是因为它比起原来的通用公共许可证对使用者的自由做到较少的保护。在与非自由软体竞争时,它也提供其他自由软体的写作者较少的优势。这些不利之处正是我们使用原来的通用公共许可证于许多函数库的理由。然而,较宽松的许可证可在某些特殊场合下带来好处。 + + 例如,在少数情况下,可能会有特殊的需要而鼓励大家尽可能广泛地使用特定的函数库,因而使它成为实际上的标准。为了达到此目标,必须允许非自由的程式使用此函数库。一个较常发生的情况是一个自由的函数库与一个被广泛使用的非自由函数库做相同的工作,在此情况下,限制只有自由软体可以使用此自由函数库不会有多少好处,故我们如用了较宽松通用公共许可证。 + + 在其他情况下,允许非自由程式使用特定的函数库,可以让更多的人们使用自由软体的大部分。例如,允许非自由程式使用 GNU C 函数库可以让更多的人们使用整个 GNU 作业系统,以及它的变形,GNU/Linux 作业系统。 + + 尽管较宽松通用共公许可证对使用者的自由是较少的保护的,它却能确保与此函数库连结的程式的使用者拥有自由,而且具有使用修改过的函数库版本来执行该程式的必要方法。 + + 以下是复制、发布、以及修改的精确条款与条件。请注意 "基于函数库的作品" 以及 "使用函数库的作品" 之间的差异:前者包含来自函数库修改过的原始码;而后者则必须与函数库结合才能执行。 + + GNU 较宽松公共许可证 + 有关复制,发布和修改的条款和条件 + + 0. 本许可证适用于任何软体函数库,或其他包含了由版权所有者加入的注意事项的程式,或其他有公信力的团体宣称其程式可以在较宽松通用公共许可证 (也称之为 "本许可证") 的条款下发布。每一位许可证接受者以 "您" 来称呼。 + + 一个 "函数库" 意指一些软体函数的集合,以及或准备好的资料以方便与应用程式 (其使用了其中某些函数与资料) 连结形成可执行的程式。 + + 以下,"函数库" 一词指的是任何在本条款下发布的这一类软体函数库或作品,一个 "基于本函数库的作品" 意指函数库或任何在版权法下的衍生作品:也就是说,一个包含了本函数库或其一部分的作品,可以是原封不动的,或经过修改的,和/或直接翻译成其他语言的。(在下文中,翻译是不受限地包含在 "修改" 的条款中。) + + 作品的 "原始码" 意指对作品进行修改最优先择取的形式。对函数库而言,完整的原始码意指所有模组的所有原始程式,加上有关的介面的定义,加上控制函数库的安装和编译的 script。 + + 本许可证条款不适用于复制,发布和修改以外的活动。这些活动超出这些条款的范围。使用本函数库来执行本程式的动作不受条款的限制,而程式的输出只有在其内容所构成的作品是基于本函数库时 (与在什么样的工具中使用本函数库来输出无关) ,这一条款才适用。以上是否为真则取决于本函数库具体用来做什么。 + + 1. 只要您在每一程式副本上明显和恰当地宣告版权声明和不承担担保的声明,并保持此许可证的声明和没有担保的声明完整无损,并和程式一起给其他每位程式接受者一份许可证的副本,您就可以用任何媒体复制和发布您收到的函数库的完整原始码。 + + 您可以为转让副本的实际行动收取一定费用。您也可以选择提供担保以换取一定的费用。 + + 2. 只要您同时满足下面的所有条件,您就可以按前面第一款的要求修改函数库的一个或几个副本或它的任何部分,以此形成基于此函数库的作品,并且复制和发布这一经过修改的程式或作品: + + a) 被修改的作品本身必须是一个软体函数库。 + + b) 必须在修改过的档案中附有明确的说明:您修改了此一档案及任何修改的日期。 + + c) 您必须让整个作品允许第三方在此许可证条款下可以免费使用。 + + d)果修改过的函数库其某个设备使用到了「使用本函数库的应用程式」所提供的函数或资料表格,却不是当此设备被呼叫时以参数列传入时,则您必须确实做到,当应用程式不提供这样的函数或表格时,则此设备依旧能工作,且其执行的任何目的仍然有意义。 + + (例如,一个函数库的函数用来计算平方根,其目的是有完整的定义且与应用程式是无关的。因此, 2d 小节要求任何本函数会使用的,由应用程式所提供的函数或表格必须是选择性的:如果应用程式不提供的话,则计算平方根的函数必须依旧能计算平方根) + +这些要求适用于整个修改过的作品。如果能够确定作品的一部分并非本函数库的衍生产品,且可以合理地单独考虑并将它与原作品分开的话,则当您将它作为独立的作品发布时,它不受此许可证和其条款的约束。但是当您将这部分与基于本函数库的作品一同发布时,则整个套件将受到本许可证条款约束,其对于其他许可证持有人的使用范围扩大到整个产品,也就是套件的每个部分,不管它是谁写的。 + +因此,本条款的意图不在于索取权利,或剥夺完全由您完成的作品的权利,而是履行权利来控制基于本函数库的集体作品或衍生作品的发布。 + +此外,将与本函数库无关的作品和本函数库 (或基于本函数库的作品) 一起放在贮存媒体或发布媒体的同一卷上,并不导致将其他作品置于此许可证的约束范围之内。 + + 3.于一个函数库的副本,您可以选择性地使用原来的 GNU 通用公共许可证上的条款来取代本许可证上的条款。如果您要这么做,您必须修改所有的参考到本许可证的注意事项,使它们指向原来的 GNU 通用公共许可证,第二版,以取代本许可证(如果有比第二版的原来的 GNU 通用公共许可证更新的版本出现的话,则如果您愿意的话可以特别指明使用新版)。请不要对这些注意事项做出其他的改变。 + + 一旦在一个副本上做了这样的改变,则该副本就无法撤回这样的改变,故原来的 GNU 通用公共许可证将适用于所有后续的副本以及由此副本衍生出来的作品。 + + 此一选择性适用于当您想要将一部分的函数库原始码复制到一个非函数库的程式使用时。 + + 4. 您可以以目标码或可执行形式复制或发布本函数库 (或符合第 2 款,基于本函数库的作品),只要您遵守前面的第 1、2 款,并同时提供完整的相关机器可读的原始码,而这些原始码必须在前面的第 1 与第 2 款条件下,在一般习惯上用来做软体交换的媒体上发布。 + + 如果所发布的目标码是由指定的地点提供拷贝索取,那么由同一地点所提供等价的原始码拷贝索取可以算作原始码的发布,即使第三方不强求与目标码一起复制原始码。 + + 5. 一个程式若包含不经任何部分修改的函数库,但却是设计经由编译或连结的方式与本函数库一同工作者,称之为 "使用函数库的作品"。这样的一个作品,严格地说,并非本函数库的衍生作品,因而不在本许可证的范围之内。 + + 然而,将 "使用函数库的作品" 与本函数库连结而产生可执行程式,则是本函数库的衍生品 (因为它包函了本函数库的一部分),而不是 "使用函数库的作品",因此其可执行程式包含在本许可证的范围内。第 6 款说明了发布此可执行程式的条款。 + + 当 "使用函数库的作品" 使用了函数库部分的标头档内容时,则此作品即使其原始码不属于本函数库的衍生品,但其目标码仍然是。这一点是否为真特别在是否本作品可以在不需要本函数库即可连结,或者是否该作品本身也是一个函数库时特别明显。 + + 如果这样的目标档只使用数字参数、资料结构层级与附属品、以及小巨集和小内□式 (小于或等于十行) ,则此目标档的使用是不受限的,不论是否它是合法的衍生作品。 (但可执行程式若包函此目标档以及一部分的函数库,仍然将在第 6 款的规定下) + + 否则的话,如果本作品是本函数库的衍生品,您必须在第 6 款的规定下发布该作品的目标码。任何包含该作品的可执行程式也在第 6 款的范围内,不论它们是否直接与本函数库连结。 + + 6. 做为上述条款的例外情况,您也可以将 "使用函数库的作品" 与本函数库结合或连结,以产生包含部分本函数库的作品,并在允许使用者自身使用时可以修改该作品,以及在对修改进行反组译除错的情况下,您可以依照您的选择发布该作品。 + + 您必须在每个作品的副本突显出如下的注意事项:本函数库在作品中被使用,以及本函数库以及它的使用是在本许可证的规定下。您必须提供本许可证的副本。如果该作品在执行时显示版权声明,您必须在其中包含本函数库的版权声明,以及指引使用者取得本许可证的副本。同时,您必须做到以下其中一件事: + + a) 必须将完整的机器可读的函数库原始码包含在该作品中,包括任何该作品使用到的改变 (这些改变必须在前述第 1 与第 2 款的要求下发布);而且,如果该作品是一个与函数库连结的「完整的、机器可□的 "使用函数库的作品"」,则要有目标码和/或原始码,如此使用者可以修改本函数库且可以重新连结,以产生包函修改过的函数库的修改过的可执行程式。 (理所当然的若使用者修改了函数库的档案定义内容时,则该作品不必然可以重新编译以使用修改过的定义。) + + b) 在与函数库连结时使用适当的分享函数库连结机制。一个适当的机制是: (1) 在执行时使用已存在于使用者的电脑中的函数库副本,而不是将函数库的函数复制到可执行程式里,以及 (2) 如果使用者安装了一份修改过的函数库,只要修改过的版本在介面上与该作品在编译连结时所用的版本是相容的,则该执行程式可以与修改过的函数库运作良好。 + + c) 在该作品内提供书面报价,有效期不少于三年,以提供同样的使用者上述第 6a 款中的内容,费用不得超过该程式发布的实际成本。 + + d)如果所发布的作品是由指定的地点提供拷贝索取,则由同一地点提供上述内容的等价拷贝索取。 + + e) 确定使用者已经收到该作品的一份复制,或是您已经寄给该使用者一份复制品。 + + 对于一个可执行程式,其所需的 "使用函数库的作品" 的形式必须包括任何要从中再产生可执行程式时所需的资料与工具程式。然而,有一个特殊例外,其所发布的内容不需要包括任何一般与「可执行本程式的作业系统」的主要部分 (如编译器、核心等) 一起发布的部分 (不论是原始码或可执行码),除非这些组成部分和可执行作品结合在一起。 + + 一个可能情况是,这些要求与其他通常不与作业系统在一起的私有函数库的版权限制相抵触,这样的抵触表示您不能将它们与本函数库一起用于您发布的可执行程式中。 + + 7. 您可以将使用本函数库的函数库设备,以及其他不在本许可证范围内的函数库,对等地放入一个单独的函数库中,并在基于本函数库的作品以及其他函数库在其他状态下同意可以个别发布,以及您做到以下两点的情况下,您可以发布此结合的函数库: + + a) 将基于本函数库的作品单独不与其他函数库设备结合地,与此结合的函数库一同发布。该作品必须在上述条款的规定下发布。 + + b) 在此结合的函数库中明显地指出其中一部分的作品是基于本函数库,并且说明那里可以找到同样不具结合形式的作品。 + + 8. 非您明确按许可证提出的要求去做,否则您不能复制、修改、转发许可证、与本函数库连结、和发布本函数库。任何试图用其他方式复制、修改、转发许可证、与本函数库连结、和发布本函数库是无效的,而且将自动结束许可证赋予您的权利。然而,对那些从您那里按许可证条款得到副本和权利的人们,只要他们继续全面履行条款,许可证赋予他们的权利仍然有效。 + + 9. 您没有在许可证上签字,因而您没有必要一定接受此一许可证。然而,没有任何其他东西赋予您修改和发布本函数库及其衍生作品的权利。如果您不接受许可证,这些行为是法律禁止的。因此,如果您修改或发布函数库 (或任何基于函数库的作品) ,您就表明您接受这一许可证以及它的所有有关复制、发布和修改本函数库或基于它的作品的条款和条件。 + + 10. 每当您重新发布函数库 (或任何基于函数库的作品) 时,接受者自动从原始许可证颁发者那里接到受这些条款和条件支配的复制、发布、连结或修改本函数库的许可。您不可以强迫接受者履行除了这里赋予他们的权利之外的其他限制。您也没有强求第三方履行许可证条款的义务。 + + 11. 如果由于法院判决或违反专利的指控或任何其他原因 (不限于专利问题) 的结果,使得强加于您的条件 (不管是法院判决,协议书或其他) 和许可证的条件有冲突时,他们也不能令您背离许可证的条款。在您不能同时满足本许可证规定的义务及其他相关的义务来发布函数库时,则结果您只能够根本不发布函数库。例如,如果某一专利许可证不允许所有直接或间接从您那里接受副本的人们,在不付专利费的情况下重新发布函数库,唯一能同时满足两方面要求的办法是停止发布函数库。 + +如果本条款的任何部分在特定的环境下无效或无法实施,就使用条款的其余部分,并将这部分条款作为整体用于其他环境。 + +本条款的目的不在于引诱您侵犯专利或其他财产权的要求,或争论这种要求的有效性。本条款的主要目的在于保护自由软体发布系统的完整性。它是通过公共许可证的应用来实现的。许多人已依赖同是出自此系统的应用程式,经由此系统发布大量自由软体而做出慷慨的供献。作者/捐献者有权决定他/她是否通过任何其他系统发布软体,许可证持有人不能强加这种选择。 + +本节的目的在于明确说明许可证其余部分可能产生的结果。 + + 12.如果由于专利或者由于有版权的介面问题使函数库在某些国家的发布和使用受到限制,则在许可证约束下的原始版权拥有者可以增加发布地区的限制条款,将这些国家明确排除在外,并在这些国家以外的地区发布函数库。在这种情况下,许可证套件含的限制条款和许可证正文一样有效。 + + 13. 自由软体基金会可能随时出版较宽松通用公共许可证的修改版或新版。新版和当前的版本在原则上保持一致,但在提到新问题时或有关事项时,在细节上可能出现差别。 + +每一版本都有不同的版本号。如果函数库指定可适用的许可证版本号以及 "任何更新的版本" ,您有权选择遵循指定的版本或自由软体基金会以后出版的新版本。如果函数库未指定许可证版本,您可选择自由软体基金会已经出版的任何版本。 + + 14. 如果您愿意将函数库的一部分结合到其他自由程式中,而它们的发布条件不同,请写信给作者,要求准予使用。如果是自由软体基金会加以版权保护的软体,写信给自由软体基金会,我们有时会作为例外的情况处理。我们的决定受两个主要目标的指导,这两个主要目标是:我们的自由软体的衍生作品继续保持自由状态,以及从整体上促进软体的共享和重复利用。 + + 没有担保 + + 15. 由于函数库准予免费使用,在适用法准许的范围内,对函数库没有担保。除非另有书面说明,版权所有者和/或其他提供函数库的人们 "一样" 不提供任何类型的担保,不论是明确的,还是隐含的,包括但不限于可销售和适合特定用途的隐含保证。全部的风险,如函数库的质量和性能问题都由您来承担。如果函数库出现缺陷,您应当承担所有必要的服务、修复和改正的费用。 + + 16.非适用法或书面协议的要求,在任何情况下,任何版权所有者或任何按许可证条款修改和发布函数库的人们都不对您的损失负有任何责任。包括由于使用或不能使用函数库引起的任何一般的、特殊的、偶然发生的或重大的损失 (包括但不限于数据的损失,或者数据变得不精确,或者您或第三方的持续的损失,或者函数库不能和其他软体协调运行等) 。即使版权所有者和其他人提到这种损失的可能性也不例外。 + + -条文结束- +EndOfLicense; + + $lang->install_condition_title = "检测运行环境"; + + $lang->install_checklist_title = array( + 'php_version' => 'PHP版本', + 'permission' => '权限', + 'xml' => 'XML库', + 'iconv' => 'ICONV库', + 'gd' => 'GD库', + 'session' => 'Session.auto_start 设置', + ); + + $lang->install_checklist_desc = array( + 'php_version' => '[必须] 由于 PHP 5.2.2 版本BUG,无法安装 XE。', + 'permission' => '[必须] 的安装路径或 ./files目录属性必须是707', + 'xml' => '[必须]为了 XML通讯,将需要XML库', + 'session' => '[必须] 为了使用缓冲功能,必须在php.ini当中设置 session.auto_start=0', + 'iconv' => '为了UTF-8和其他语言环境之间的互相转换,必须安装iconv', + 'gd' => '为了使用图片转换功能,必须先得安装GD库', + ); + + $lang->install_checklist_xml = '安装XML库'; + $lang->install_without_xml = '还没有安装xml库!'; + $lang->install_checklist_gd = '安装GD库'; + $lang->install_without_gd = '还没有安装负责转换图片功能的GD库!'; + $lang->install_checklist_gd = '安装GD库'; + $lang->install_without_iconv = '还没有安装负责处理字串的iconv库!'; + $lang->install_session_auto_start = 'PHP设置中设置成session.auto_start==1,可能处理session时发生错误。'; + $lang->install_permission_denied = '安装目录属性不是707!'; + + $lang->cmd_agree_license = '同意'; + $lang->cmd_install_fix_checklist = '已设置了必要的安装条件。'; + $lang->cmd_install_next = '开始安装'; + $lang->cmd_ignore = '忽略'; + + $lang->db_desc = array( + 'mysql' => '利用php的 mysql*()函数使用mysql DB。
DB数据是以myisam生成,因此不能实现transaction。', + 'mysqli' => '利用php的 mysqli*()函数使用mysql DB。
DB数据是以myisam生成,因此不能实现transaction。', + 'mysql_innodb' => '利用innodb使用mysql DB。
innodb可以使用transaction。', + 'sqlite2' => '支持用文件形式保存数据的sqlite2。
安装时DB文件应在web不能访问的地方生成。
(还没有通过安全的测试)', + 'sqlite3_pdo' => '用PHP的 PDO支持 sqlite3。
安装时DB文件应在web不能访问的地方生成。', + 'cubrid' => '使用CUBRID DB。 manual', + 'mssql' => '使用MSSQL DB。', + 'postgresql' => '使用PostgreSql DB。', + 'firebird' => '使用Firebird DB。', + ); + + $lang->form_title = '数据库及管理员基本信息'; + $lang->db_title = '输入数据库信息'; + $lang->db_type = '数据库类型'; + $lang->select_db_type = '选择数据库'; + $lang->db_hostname = '服务器名'; + $lang->db_port = '数据库端口'; + $lang->db_userid = 'DB用户名'; + $lang->db_password = 'DB密码'; + $lang->db_database = '数据库名'; + $lang->db_database_file = '数据库文件'; + $lang->db_table_prefix = '前缀'; + + $lang->admin_title = '管理员信息'; + + $lang->env_title = '环境设置'; + $lang->use_optimizer = '使用Optimizer'; + $lang->about_optimizer = '使用Optimizer可以对大部分的CSS/ JS文件进行整合/压缩传送使之加快网站访问速度。
只是有时会发生小小的问题。这时候请暂时不要使用Optimizer。'; + $lang->use_rewrite = '使用rewrite模块'; + $lang->about_rewrite = '如服务器支持rewrite模块且选择此项,可以简化复杂的网址。
例如,http://域名/?document_srl=123简化为http://域名/123。'; + $lang->time_zone = '时区'; + $lang->about_time_zone = '服务器时间和您所处的时间有差异时,可以设置时区来满足你所需要的时间显示。'; + $lang->qmail_compatibility = 'Qmail互换'; + $lang->about_qmail_compatibility = '支持不能识别CRLF为换行符的Qmail等MTA,也能发送电子邮件。'; + + $lang->about_database_file = 'Sqlite是文件里保存数据。数据库的文件位置应该放在web不能访问的地方。
数据文件应放在具有707属性的位置。'; + + $lang->success_installed = '已完成安装。'; + + $lang->msg_cannot_proc = '不具备安装所需环境,不能继续进行。'; + $lang->msg_already_installed = '已安装'; + $lang->msg_dbconnect_failed = "连接DB时发生错误。\n请重新确认DB信息。"; + $lang->msg_table_is_exists = "已生成数据表。\n重新生成了config文件。"; + $lang->msg_install_completed = "安装完成。\n非常感谢。"; + $lang->msg_install_failed = "生成安装文件时发生错误。"; + + $lang->ftp_get_list = '载入FTP列表'; +?> diff --git a/modules/install/lang/zh-TW.lang.php b/modules/install/lang/zh-TW.lang.php index bfc3dcfb7..78dee56c7 100644 --- a/modules/install/lang/zh-TW.lang.php +++ b/modules/install/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ - - 통합검색 - 综合搜索 - 統合検索 - Integrated Search - Tìm kiếm tích hợp - Búsqueda Integrada - Интегрируемый поиск - 綜合搜尋 - - 선택한 모듈들을 대상으로 통합검색을 지원합니다. - 선택된 모듈의 글중 비밀글만 검색을 하지 않고 나머지는 모두 검색을 하기에 공개되지 않은 모듈은 대상에 포함하지 않도록 하셔야 합니다. - - - 把所选模块作为搜索对象。 - 所选模块当中只有密帖不会被搜索,因此请留意您不想搜索的模块。 - - - 選択されたモジュールを対象に統合検索を行う機能をサポートします。 - 選択されたモジュールのコンテンツ(書き込み)の中で、非公開コンテンツのみ検索から除外されますので、未公開のモジュールは対象にしないようにして下さい。 - - - It supports integration search for chosen modules. - All articles except secret articles will be searched, so you need to be careful not to include secret module to target. - - - Hỗ trợ tìm kiếm tích hợp cho những Module được chọn. - Mọi bài viết đều có thể được tìm kiếm (Trừ những bài đặt bí mật), vì vậy bạn hãy cẩn thận khi chọn những Module bí mật. - - - Soporta la búsqueda integrada de los módulos elegidos. - Todo los documentos excepto los secretos serán buscados, y es necesario tener cuidado de no incluir módulo secreto como objetivo. - - - Поддерживает интеграцию поиска в выбранные модули. - Все статьи, за исключением секретных, будут подлежать поиску, поэтому Вам нужно быть осторожным с тем, чтобы не включить модуль секретов в назначение. - - - 將所選擇的模組當作搜尋對象進行搜尋。 - 所搜尋的模組中,如有私密文章時將不會被搜尋,因此請注意選擇。 - - 0.1 - 2007-07-24 - service - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 통합검색 + 综合搜索 + 統合検索 + Integrated Search + Tìm kiếm tích hợp + Búsqueda Integrada + Интегрируемый поиск + 綜合搜尋 + + 선택한 모듈들을 대상으로 통합검색을 지원합니다. + 선택된 모듈의 글중 비밀글만 검색을 하지 않고 나머지는 모두 검색을 하기에 공개되지 않은 모듈은 대상에 포함하지 않도록 하셔야 합니다. + + + 把所选模块作为搜索对象。 + 所选模块当中只有密帖不会被搜索,因此请留意您不想搜索的模块。 + + + 選択されたモジュールを対象に統合検索を行う機能をサポートします。 + 選択されたモジュールのコンテンツ(書き込み)の中で、非公開コンテンツのみ検索から除外されますので、未公開のモジュールは対象にしないようにして下さい。 + + + It supports integration search for chosen modules. + All articles except secret articles will be searched, so you need to be careful not to include secret module to target. + + + Hỗ trợ tìm kiếm tích hợp cho những Module được chọn. + Mọi bài viết đều có thể được tìm kiếm (Trừ những bài đặt bí mật), vì vậy bạn hãy cẩn thận khi chọn những Module bí mật. + + + Soporta la búsqueda integrada de los módulos elegidos. + Todo los documentos excepto los secretos serán buscados, y es necesario tener cuidado de no incluir módulo secreto como objetivo. + + + Поддерживает интеграцию поиска в выбранные модули. + Все статьи, за исключением секретных, будут подлежать поиску, поэтому Вам нужно быть осторожным с тем, чтобы не включить модуль секретов в назначение. + + + 將所選擇的模組當作搜尋對象進行搜尋。 + 所搜尋的模組中,如有私密文章時將不會被搜尋,因此請注意選擇。 + + 0.1 + 2007-07-24 + service + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/integration_search/integration_search.admin.controller.php b/modules/integration_search/integration_search.admin.controller.php index ed0eff234..46635f2ce 100644 --- a/modules/integration_search/integration_search.admin.controller.php +++ b/modules/integration_search/integration_search.admin.controller.php @@ -1,115 +1,115 @@ -getModuleConfig('integration_search'); - - $args->skin = Context::get('skin'); - $args->target = Context::get('target'); - $args->target_module_srl = Context::get('target_module_srl'); - if(!$args->target_module_srl) $args->target_module_srl = ''; - $args->skin_vars = $config->skin_vars; - - $oModuleController = &getController('module'); - return $oModuleController->insertModuleConfig('integration_search',$args); - } - - /** - * @brief 스킨 정보 저장 - **/ - function procIntegration_searchAdminInsertSkin() { - // 설정 정보를 받아옴 (module model 객체를 이용) - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('integration_search'); - - $args->skin = $config->skin; - $args->target_module_srl = $config->target_module_srl; - - // 스킨의 정보를 구해옴 (extra_vars를 체크하기 위해서) - $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $config->skin); - - // 입력받은 변수들을 체크 (mo, act, module_srl, page등 기본적인 변수들 없앰) - $obj = Context::getRequestVars(); - unset($obj->act); - unset($obj->module_srl); - unset($obj->page); - - // 원 skin_info에서 extra_vars의 type이 image일 경우 별도 처리를 해줌 - if($skin_info->extra_vars) { - foreach($skin_info->extra_vars as $vars) { - if($vars->type!='image') continue; - - $image_obj = $obj->{$vars->name}; - - // 삭제 요청에 대한 변수를 구함 - $del_var = $obj->{"del_".$vars->name}; - unset($obj->{"del_".$vars->name}); - if($del_var == 'Y') { - FileHandler::removeFile($module_info->{$vars->name}); - continue; - } - - // 업로드 되지 않았다면 이전 데이터를 그대로 사용 - if(!$image_obj['tmp_name']) { - $obj->{$vars->name} = $module_info->{$vars->name}; - continue; - } - - // 정상적으로 업로드된 파일이 아니면 무시 - if(!is_uploaded_file($image_obj['tmp_name'])) { - unset($obj->{$vars->name}); - continue; - } - - // 이미지 파일이 아니어도 무시 - if(!preg_match("/\.(jpg|jpeg|gif|png)$/i", $image_obj['name'])) { - unset($obj->{$vars->name}); - continue; - } - - // 경로를 정해서 업로드 - $path = sprintf("./files/attach/images/%s/", $module_srl); - - // 디렉토리 생성 - if(!FileHandler::makeDir($path)) return false; - - $filename = $path.$image_obj['name']; - - // 파일 이동 - if(!move_uploaded_file($image_obj['tmp_name'], $filename)) { - unset($obj->{$vars->name}); - continue; - } - - // 변수를 바꿈 - unset($obj->{$vars->name}); - $obj->{$vars->name} = $filename; - } - } - - // serialize하여 저장 - $args->skin_vars = serialize($obj); - - $oModuleController = &getController('module'); - return $oModuleController->insertModuleConfig('integration_search',$args); - } - } -?> +getModuleConfig('integration_search'); + + $args->skin = Context::get('skin'); + $args->target = Context::get('target'); + $args->target_module_srl = Context::get('target_module_srl'); + if(!$args->target_module_srl) $args->target_module_srl = ''; + $args->skin_vars = $config->skin_vars; + + $oModuleController = &getController('module'); + return $oModuleController->insertModuleConfig('integration_search',$args); + } + + /** + * @brief 스킨 정보 저장 + **/ + function procIntegration_searchAdminInsertSkin() { + // 설정 정보를 받아옴 (module model 객체를 이용) + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('integration_search'); + + $args->skin = $config->skin; + $args->target_module_srl = $config->target_module_srl; + + // 스킨의 정보를 구해옴 (extra_vars를 체크하기 위해서) + $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $config->skin); + + // 입력받은 변수들을 체크 (mo, act, module_srl, page등 기본적인 변수들 없앰) + $obj = Context::getRequestVars(); + unset($obj->act); + unset($obj->module_srl); + unset($obj->page); + + // 원 skin_info에서 extra_vars의 type이 image일 경우 별도 처리를 해줌 + if($skin_info->extra_vars) { + foreach($skin_info->extra_vars as $vars) { + if($vars->type!='image') continue; + + $image_obj = $obj->{$vars->name}; + + // 삭제 요청에 대한 변수를 구함 + $del_var = $obj->{"del_".$vars->name}; + unset($obj->{"del_".$vars->name}); + if($del_var == 'Y') { + FileHandler::removeFile($module_info->{$vars->name}); + continue; + } + + // 업로드 되지 않았다면 이전 데이터를 그대로 사용 + if(!$image_obj['tmp_name']) { + $obj->{$vars->name} = $module_info->{$vars->name}; + continue; + } + + // 정상적으로 업로드된 파일이 아니면 무시 + if(!is_uploaded_file($image_obj['tmp_name'])) { + unset($obj->{$vars->name}); + continue; + } + + // 이미지 파일이 아니어도 무시 + if(!preg_match("/\.(jpg|jpeg|gif|png)$/i", $image_obj['name'])) { + unset($obj->{$vars->name}); + continue; + } + + // 경로를 정해서 업로드 + $path = sprintf("./files/attach/images/%s/", $module_srl); + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) return false; + + $filename = $path.$image_obj['name']; + + // 파일 이동 + if(!move_uploaded_file($image_obj['tmp_name'], $filename)) { + unset($obj->{$vars->name}); + continue; + } + + // 변수를 바꿈 + unset($obj->{$vars->name}); + $obj->{$vars->name} = $filename; + } + } + + // serialize하여 저장 + $args->skin_vars = serialize($obj); + + $oModuleController = &getController('module'); + return $oModuleController->insertModuleConfig('integration_search',$args); + } + } +?> diff --git a/modules/integration_search/integration_search.admin.view.php b/modules/integration_search/integration_search.admin.view.php index 330ec82bd..70ea6a5f0 100644 --- a/modules/integration_search/integration_search.admin.view.php +++ b/modules/integration_search/integration_search.admin.view.php @@ -1,84 +1,84 @@ -config = $oModuleModel->getModuleConfig('integration_search'); - Context::set('config',$this->config); - - $this->setTemplatePath($this->module_path."/tpl/"); - } - - /** - * @brief 모듈 선정 및 스킨 설정 - **/ - function dispIntegration_searchAdminContent() { - // 스킨 목록을 구해옴 - $oModuleModel = &getModel('module'); - $skin_list = $oModuleModel->getSkins($this->module_path); - Context::set('skin_list',$skin_list); - - // 모듈 카테고리 목록을 구함 - $module_categories = $oModuleModel->getModuleCategories(); - - // 생성된 mid목록을 구함 - $obj->site_srl = 0; - $mid_list = $oModuleModel->getMidList($obj); - - // module_category와 module의 조합 - if($module_categories) { - foreach($mid_list as $module_srl => $module) { - $module_categories[$module->module_category_srl]->list[$module_srl] = $module; - } - } else { - $module_categories[0]->list = $mid_list; - } - - Context::set('mid_list',$module_categories); - - // 샘플코드 - Context::set('sample_code', htmlspecialchars('
') ); - - $this->setTemplateFile("index"); - } - - /** - * @brief 스킨 설정 - **/ - function dispIntegration_searchAdminSkinInfo() { - $oModuleModel = &getModel('module'); - $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $this->config->skin); - $skin_vars = unserialize($this->config->skin_vars); - - // skin_info에 extra_vars 값을 지정 - if(count($skin_info->extra_vars)) { - foreach($skin_info->extra_vars as $key => $val) { - $name = $val->name; - $type = $val->type; - $value = $skin_vars->{$name}; - if($type=="checkbox"&&!$value) $value = array(); - $skin_info->extra_vars[$key]->value= $value; - } - } - Context::set('skin_info', $skin_info); - Context::set('skin_vars', $skin_vars); - - $this->setTemplateFile("skin_info"); - } - } -?> +config = $oModuleModel->getModuleConfig('integration_search'); + Context::set('config',$this->config); + + $this->setTemplatePath($this->module_path."/tpl/"); + } + + /** + * @brief 모듈 선정 및 스킨 설정 + **/ + function dispIntegration_searchAdminContent() { + // 스킨 목록을 구해옴 + $oModuleModel = &getModel('module'); + $skin_list = $oModuleModel->getSkins($this->module_path); + Context::set('skin_list',$skin_list); + + // 모듈 카테고리 목록을 구함 + $module_categories = $oModuleModel->getModuleCategories(); + + // 생성된 mid목록을 구함 + $obj->site_srl = 0; + $mid_list = $oModuleModel->getMidList($obj); + + // module_category와 module의 조합 + if($module_categories) { + foreach($mid_list as $module_srl => $module) { + $module_categories[$module->module_category_srl]->list[$module_srl] = $module; + } + } else { + $module_categories[0]->list = $mid_list; + } + + Context::set('mid_list',$module_categories); + + // 샘플코드 + Context::set('sample_code', htmlspecialchars('
') ); + + $this->setTemplateFile("index"); + } + + /** + * @brief 스킨 설정 + **/ + function dispIntegration_searchAdminSkinInfo() { + $oModuleModel = &getModel('module'); + $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $this->config->skin); + $skin_vars = unserialize($this->config->skin_vars); + + // skin_info에 extra_vars 값을 지정 + if(count($skin_info->extra_vars)) { + foreach($skin_info->extra_vars as $key => $val) { + $name = $val->name; + $type = $val->type; + $value = $skin_vars->{$name}; + if($type=="checkbox"&&!$value) $value = array(); + $skin_info->extra_vars[$key]->value= $value; + } + } + Context::set('skin_info', $skin_info); + Context::set('skin_vars', $skin_vars); + + $this->setTemplateFile("skin_info"); + } + } +?> diff --git a/modules/integration_search/integration_search.class.php b/modules/integration_search/integration_search.class.php index 145bff41d..784d22841 100644 --- a/modules/integration_search/integration_search.class.php +++ b/modules/integration_search/integration_search.class.php @@ -1,41 +1,41 @@ -insertActionForward('integration_search', 'view', 'IS'); - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - } - } -?> +insertActionForward('integration_search', 'view', 'IS'); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + } + } +?> diff --git a/modules/integration_search/integration_search.model.php b/modules/integration_search/integration_search.model.php index 931b414fc..a4326c498 100644 --- a/modules/integration_search/integration_search.model.php +++ b/modules/integration_search/integration_search.model.php @@ -1,186 +1,186 @@ -exclude_module_srl = $module_srls; - else $args->module_srl = $module_srls; - - $args->page = $page; - $args->list_count = $list_count; - $args->page_count = 10; - $args->search_target = $search_target; - $args->search_keyword = $search_keyword; - $args->sort_index = 'list_order'; - $args->order_type = 'asc'; - if(!$args->module_srl) unset($args->module_srl); - - // 대상 문서들을 가져옴 - $oDocumentModel = &getModel('document'); - return $oDocumentModel->getDocumentList($args); - } - - /** - * @brief 댓글 검색 - **/ - function getComments($target, $module_srls_list, $search_keyword, $page=1, $list_count = 20) { - if(is_array($module_srls_list)) $module_srls = implode(',',$module_srls_list); - else $module_srls = $module_srls_list; - if($target == 'exclude') $args->exclude_module_srl = $module_srls; - else $args->module_srl = $module_srls; - $args->page = $page; - $args->list_count = $list_count; - $args->page_count = 10; - $args->search_target = 'content'; - $args->search_keyword = $search_keyword; - $args->sort_index = 'list_order'; - $args->order_type = 'asc'; - - // 대상 문서들을 가져옴 - $oCommentModel = &getModel('comment'); - $output = $oCommentModel->getTotalCommentList($args); - if(!$output->toBool()|| !$output->data) return $output; - return $output; - } - - /** - * @brief 엮인글 검색 - **/ - function getTrackbacks($target, $module_srls_list, $search_target = "title", $search_keyword, $page=1, $list_count = 20) { - if(is_array($module_srls_list)) $module_srls = implode(',',$module_srls_list); - else $module_srls = $module_srls_list; - if($target == 'exclude') $args->exclude_module_srl = $module_srls; - else $args->module_srl = $module_srls; - $args->page = $page; - $args->list_count = $list_count; - $args->page_count = 10; - $args->search_target = $search_target; - $args->search_keyword = $search_keyword; - $args->sort_index = 'list_order'; - $args->order_type = 'asc'; - - // 대상 문서들을 가져옴 - $oTrackbackModel = &getAdminModel('trackback'); - $output = $oTrackbackModel->getTotalTrackbackList($args); - if(!$output->toBool()|| !$output->data) return $output; - return $output; - } - - /** - * @brief 파일 검색 - **/ - function _getFiles($target, $module_srls_list, $search_keyword, $page, $list_count, $direct_download = 'Y') { - if(is_array($module_srls_list)) $module_srls = implode(',',$module_srls_list); - else $module_srls = $module_srls_list; - if($target == 'exclude') $args->exclude_module_srl = $module_srls; - else $args->module_srl = $module_srls; - $args->page = $page; - $args->list_count = $list_count; - $args->page_count = 10; - $args->search_target = 'filename'; - $args->search_keyword = $search_keyword; - $args->sort_index = 'files.file_srl'; - $args->order_type = 'desc'; - $args->isvalid = 'Y'; - $args->direct_download = $direct_download=='Y'?'Y':'N'; - - // 대상 문서들을 가져옴 - $oFileAdminModel = &getAdminModel('file'); - $output = $oFileAdminModel->getFileList($args); - if(!$output->toBool() || !$output->data) return $output; - - $list = array(); - foreach($output->data as $key => $val) { - $obj = null; - $obj->filename = $val->source_filename; - $obj->download_count = $val->download_count; - if(substr($val->download_url,0,2)=='./') $val->download_url = substr($val->download_url,2); - $obj->download_url = Context::getRequestUri().$val->download_url; - $obj->target_srl = $val->upload_target_srl; - $obj->file_size = $val->file_size; - - // 이미지 - if(preg_match('/\.(jpg|jpeg|gif|png)$/i', $val->source_filename)) { - $obj->type = 'image'; - - $thumbnail_path = sprintf('files/cache/thumbnails/%s',getNumberingPath($val->file_srl, 3)); - if(!is_dir($thumbnail_path)) FileHandler::makeDir($thumbnail_path); - $thumbnail_file = sprintf('%s%dx%d.%s.jpg', $thumbnail_path, 120, 120, 'crop'); - $thumbnail_url = Context::getRequestUri().$thumbnail_file; - if(!file_exists($thumbnail_file)) FileHandler::createImageFile($val->uploaded_filename, $thumbnail_file, 120, 120, 'jpg', 'crop'); - $obj->src = sprintf('%s', $thumbnail_url, htmlspecialchars($obj->filename), 120, 120); - - // 동영상 - } elseif(preg_match('/\.(swf|flv|wmv|avi|mpg|mpeg|asx|asf|mp3)$/i', $val->source_filename)) { - $obj->type = 'multimedia'; - $obj->src = sprintf('', $obj->download_url); - - // 기타 - } else { - $obj->type = 'binary'; - $obj->src = ''; - } - - $list[] = $obj; - $target_list[] = $val->upload_target_srl; - } - $output->data = $list; - - $oDocumentModel = &getModel('document'); - $document_list = $oDocumentModel->getDocuments($target_list); - if($document_list) foreach($document_list as $key => $val) { - foreach($output->data as $k => $v) { - if($v->target_srl== $val->document_srl) { - $output->data[$k]->url = $val->getPermanentUrl(); - $output->data[$k]->regdate = $val->getRegdate("Y-m-d H:i"); - $output->data[$k]->nick_name = $val->getNickName(); - } - } - } - - $oCommentModel = &getModel('comment'); - $comment_list = $oCommentModel->getComments($target_list); - if($comment_list) foreach($comment_list as $key => $val) { - foreach($output->data as $k => $v) { - if($v->target_srl== $val->comment_srl) { - $output->data[$k]->url = $val->getPermanentUrl(); - $output->data[$k]->regdate = $val->getRegdate("Y-m-d H:i"); - $output->data[$k]->nick_name = $val->getNickName(); - } - } - } - - return $output; - } - - /** - * @brief 멀티미디어 검색 - **/ - function getImages($target, $module_srls_list, $search_keyword, $page=1, $list_count = 20) { - return $this->_getFiles($target, $module_srls_list, $search_keyword, $page, $list_count); - } - - /** - * @brief 첨부파일 검색 - **/ - function getFiles($target, $module_srls_list, $search_keyword, $page=1, $list_count = 20) { - return $this->_getFiles($target, $module_srls_list, $search_keyword, $page, $list_count, 'N'); - } - - } -?> +exclude_module_srl = $module_srls; + else $args->module_srl = $module_srls; + + $args->page = $page; + $args->list_count = $list_count; + $args->page_count = 10; + $args->search_target = $search_target; + $args->search_keyword = $search_keyword; + $args->sort_index = 'list_order'; + $args->order_type = 'asc'; + if(!$args->module_srl) unset($args->module_srl); + + // 대상 문서들을 가져옴 + $oDocumentModel = &getModel('document'); + return $oDocumentModel->getDocumentList($args); + } + + /** + * @brief 댓글 검색 + **/ + function getComments($target, $module_srls_list, $search_keyword, $page=1, $list_count = 20) { + if(is_array($module_srls_list)) $module_srls = implode(',',$module_srls_list); + else $module_srls = $module_srls_list; + if($target == 'exclude') $args->exclude_module_srl = $module_srls; + else $args->module_srl = $module_srls; + $args->page = $page; + $args->list_count = $list_count; + $args->page_count = 10; + $args->search_target = 'content'; + $args->search_keyword = $search_keyword; + $args->sort_index = 'list_order'; + $args->order_type = 'asc'; + + // 대상 문서들을 가져옴 + $oCommentModel = &getModel('comment'); + $output = $oCommentModel->getTotalCommentList($args); + if(!$output->toBool()|| !$output->data) return $output; + return $output; + } + + /** + * @brief 엮인글 검색 + **/ + function getTrackbacks($target, $module_srls_list, $search_target = "title", $search_keyword, $page=1, $list_count = 20) { + if(is_array($module_srls_list)) $module_srls = implode(',',$module_srls_list); + else $module_srls = $module_srls_list; + if($target == 'exclude') $args->exclude_module_srl = $module_srls; + else $args->module_srl = $module_srls; + $args->page = $page; + $args->list_count = $list_count; + $args->page_count = 10; + $args->search_target = $search_target; + $args->search_keyword = $search_keyword; + $args->sort_index = 'list_order'; + $args->order_type = 'asc'; + + // 대상 문서들을 가져옴 + $oTrackbackModel = &getAdminModel('trackback'); + $output = $oTrackbackModel->getTotalTrackbackList($args); + if(!$output->toBool()|| !$output->data) return $output; + return $output; + } + + /** + * @brief 파일 검색 + **/ + function _getFiles($target, $module_srls_list, $search_keyword, $page, $list_count, $direct_download = 'Y') { + if(is_array($module_srls_list)) $module_srls = implode(',',$module_srls_list); + else $module_srls = $module_srls_list; + if($target == 'exclude') $args->exclude_module_srl = $module_srls; + else $args->module_srl = $module_srls; + $args->page = $page; + $args->list_count = $list_count; + $args->page_count = 10; + $args->search_target = 'filename'; + $args->search_keyword = $search_keyword; + $args->sort_index = 'files.file_srl'; + $args->order_type = 'desc'; + $args->isvalid = 'Y'; + $args->direct_download = $direct_download=='Y'?'Y':'N'; + + // 대상 문서들을 가져옴 + $oFileAdminModel = &getAdminModel('file'); + $output = $oFileAdminModel->getFileList($args); + if(!$output->toBool() || !$output->data) return $output; + + $list = array(); + foreach($output->data as $key => $val) { + $obj = null; + $obj->filename = $val->source_filename; + $obj->download_count = $val->download_count; + if(substr($val->download_url,0,2)=='./') $val->download_url = substr($val->download_url,2); + $obj->download_url = Context::getRequestUri().$val->download_url; + $obj->target_srl = $val->upload_target_srl; + $obj->file_size = $val->file_size; + + // 이미지 + if(preg_match('/\.(jpg|jpeg|gif|png)$/i', $val->source_filename)) { + $obj->type = 'image'; + + $thumbnail_path = sprintf('files/cache/thumbnails/%s',getNumberingPath($val->file_srl, 3)); + if(!is_dir($thumbnail_path)) FileHandler::makeDir($thumbnail_path); + $thumbnail_file = sprintf('%s%dx%d.%s.jpg', $thumbnail_path, 120, 120, 'crop'); + $thumbnail_url = Context::getRequestUri().$thumbnail_file; + if(!file_exists($thumbnail_file)) FileHandler::createImageFile($val->uploaded_filename, $thumbnail_file, 120, 120, 'jpg', 'crop'); + $obj->src = sprintf('%s', $thumbnail_url, htmlspecialchars($obj->filename), 120, 120); + + // 동영상 + } elseif(preg_match('/\.(swf|flv|wmv|avi|mpg|mpeg|asx|asf|mp3)$/i', $val->source_filename)) { + $obj->type = 'multimedia'; + $obj->src = sprintf('', $obj->download_url); + + // 기타 + } else { + $obj->type = 'binary'; + $obj->src = ''; + } + + $list[] = $obj; + $target_list[] = $val->upload_target_srl; + } + $output->data = $list; + + $oDocumentModel = &getModel('document'); + $document_list = $oDocumentModel->getDocuments($target_list); + if($document_list) foreach($document_list as $key => $val) { + foreach($output->data as $k => $v) { + if($v->target_srl== $val->document_srl) { + $output->data[$k]->url = $val->getPermanentUrl(); + $output->data[$k]->regdate = $val->getRegdate("Y-m-d H:i"); + $output->data[$k]->nick_name = $val->getNickName(); + } + } + } + + $oCommentModel = &getModel('comment'); + $comment_list = $oCommentModel->getComments($target_list); + if($comment_list) foreach($comment_list as $key => $val) { + foreach($output->data as $k => $v) { + if($v->target_srl== $val->comment_srl) { + $output->data[$k]->url = $val->getPermanentUrl(); + $output->data[$k]->regdate = $val->getRegdate("Y-m-d H:i"); + $output->data[$k]->nick_name = $val->getNickName(); + } + } + } + + return $output; + } + + /** + * @brief 멀티미디어 검색 + **/ + function getImages($target, $module_srls_list, $search_keyword, $page=1, $list_count = 20) { + return $this->_getFiles($target, $module_srls_list, $search_keyword, $page, $list_count); + } + + /** + * @brief 첨부파일 검색 + **/ + function getFiles($target, $module_srls_list, $search_keyword, $page=1, $list_count = 20) { + return $this->_getFiles($target, $module_srls_list, $search_keyword, $page, $list_count, 'N'); + } + + } +?> diff --git a/modules/integration_search/integration_search.view.php b/modules/integration_search/integration_search.view.php index 5f7b44994..8358f68ab 100644 --- a/modules/integration_search/integration_search.view.php +++ b/modules/integration_search/integration_search.view.php @@ -1,103 +1,103 @@ -grant->access) return new Object(-1,'msg_not_permitted'); - - $config = $oModuleModel->getModuleConfig('integration_search'); - if(!$config->skin) $config->skin = 'default'; - Context::set('module_info', unserialize($config->skin_vars)); - $this->setTemplatePath($this->module_path."/skins/".$config->skin."/"); - - $target = $config->target; - if(!$target) $target = 'include'; - $module_srl_list = explode(',',$config->target_module_srl); - - // 검색어 변수 설정 - $is_keyword = Context::get('is_keyword'); - - // 페이지 변수 설정 - $page = (int)Context::get('page'); - if(!$page) $page = 1; - - // 검색탭에 따른 검색 - $where = Context::get('where'); - - // integration search model객체 생성 - if($is_keyword) { - $oIS = &getModel('integration_search'); - switch($where) { - case 'document' : - $search_target = Context::get('search_target'); - if(!in_array($search_target, array('title','content','title_content','tag'))) $search_target = 'title'; - Context::set('search_target', $search_target); - - $output = $oIS->getDocuments($target, $module_srl_list, $search_target, $is_keyword, $page, 10); - Context::set('output', $output); - $this->setTemplateFile("document", $page); - break; - case 'comment' : - $output = $oIS->getComments($target, $module_srl_list, $is_keyword, $page, 10); - Context::set('output', $output); - $this->setTemplateFile("comment", $page); - break; - case 'trackback' : - $search_target = Context::get('search_target'); - if(!in_array($search_target, array('title','url','blog_name','excerpt'))) $search_target = 'title'; - Context::set('search_target', $search_target); - - $output = $oIS->getTrackbacks($target, $module_srl_list, $search_target, $is_keyword, $page, 10); - Context::set('output', $output); - $this->setTemplateFile("trackback", $page); - break; - case 'multimedia' : - $output = $oIS->getImages($target, $module_srl_list, $is_keyword, $page,20); - Context::set('output', $output); - $this->setTemplateFile("multimedia", $page); - break; - case 'file' : - $output = $oIS->getFiles($target, $module_srl_list, $is_keyword, $page, 20); - Context::set('output', $output); - $this->setTemplateFile("file", $page); - break; - default : - $output['document'] = $oIS->getDocuments($target, $module_srl_list, 'title', $is_keyword, $page, 5); - $output['comment'] = $oIS->getComments($target, $module_srl_list, $is_keyword, $page, 5); - $output['trackback'] = $oIS->getTrackbacks($target, $module_srl_list, 'title', $is_keyword, $page, 5); - $output['multimedia'] = $oIS->getImages($target, $module_srl_list, $is_keyword, $page, 5); - $output['file'] = $oIS->getFiles($target, $module_srl_list, $is_keyword, $page, 5); - Context::set('search_result', $output); - $this->setTemplateFile("index", $page); - break; - } - } else { - $this->setTemplateFile("no_keywords"); - } - } - } -?> +grant->access) return new Object(-1,'msg_not_permitted'); + + $config = $oModuleModel->getModuleConfig('integration_search'); + if(!$config->skin) $config->skin = 'default'; + Context::set('module_info', unserialize($config->skin_vars)); + $this->setTemplatePath($this->module_path."/skins/".$config->skin."/"); + + $target = $config->target; + if(!$target) $target = 'include'; + $module_srl_list = explode(',',$config->target_module_srl); + + // 검색어 변수 설정 + $is_keyword = Context::get('is_keyword'); + + // 페이지 변수 설정 + $page = (int)Context::get('page'); + if(!$page) $page = 1; + + // 검색탭에 따른 검색 + $where = Context::get('where'); + + // integration search model객체 생성 + if($is_keyword) { + $oIS = &getModel('integration_search'); + switch($where) { + case 'document' : + $search_target = Context::get('search_target'); + if(!in_array($search_target, array('title','content','title_content','tag'))) $search_target = 'title'; + Context::set('search_target', $search_target); + + $output = $oIS->getDocuments($target, $module_srl_list, $search_target, $is_keyword, $page, 10); + Context::set('output', $output); + $this->setTemplateFile("document", $page); + break; + case 'comment' : + $output = $oIS->getComments($target, $module_srl_list, $is_keyword, $page, 10); + Context::set('output', $output); + $this->setTemplateFile("comment", $page); + break; + case 'trackback' : + $search_target = Context::get('search_target'); + if(!in_array($search_target, array('title','url','blog_name','excerpt'))) $search_target = 'title'; + Context::set('search_target', $search_target); + + $output = $oIS->getTrackbacks($target, $module_srl_list, $search_target, $is_keyword, $page, 10); + Context::set('output', $output); + $this->setTemplateFile("trackback", $page); + break; + case 'multimedia' : + $output = $oIS->getImages($target, $module_srl_list, $is_keyword, $page,20); + Context::set('output', $output); + $this->setTemplateFile("multimedia", $page); + break; + case 'file' : + $output = $oIS->getFiles($target, $module_srl_list, $is_keyword, $page, 20); + Context::set('output', $output); + $this->setTemplateFile("file", $page); + break; + default : + $output['document'] = $oIS->getDocuments($target, $module_srl_list, 'title', $is_keyword, $page, 5); + $output['comment'] = $oIS->getComments($target, $module_srl_list, $is_keyword, $page, 5); + $output['trackback'] = $oIS->getTrackbacks($target, $module_srl_list, 'title', $is_keyword, $page, 5); + $output['multimedia'] = $oIS->getImages($target, $module_srl_list, $is_keyword, $page, 5); + $output['file'] = $oIS->getFiles($target, $module_srl_list, $is_keyword, $page, 5); + Context::set('search_result', $output); + $this->setTemplateFile("index", $page); + break; + } + } else { + $this->setTemplateFile("no_keywords"); + } + } + } +?> diff --git a/modules/integration_search/lang/en.lang.php b/modules/integration_search/lang/en.lang.php index 39c94a191..9a112e31b 100644 --- a/modules/integration_search/lang/en.lang.php +++ b/modules/integration_search/lang/en.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief English Language Pack (For only basic things) **/ diff --git a/modules/integration_search/lang/es.lang.php b/modules/integration_search/lang/es.lang.php index 9b3fc5e8d..f0bdcd00e 100644 --- a/modules/integration_search/lang/es.lang.php +++ b/modules/integration_search/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma español (sólo informaciones básicas). **/ diff --git a/modules/integration_search/lang/fr.lang.php b/modules/integration_search/lang/fr.lang.php index 4cf6c87fb..69e3b9565 100644 --- a/modules/integration_search/lang/fr.lang.php +++ b/modules/integration_search/lang/fr.lang.php @@ -1,7 +1,7 @@ Traduit par Pierre Duvent + * @author NHN (developers@xpressengine.com) Traduit par Pierre Duvent * @brief Paquet du langage en français pour le module de Recherche Unie **/ diff --git a/modules/integration_search/lang/jp.lang.php b/modules/integration_search/lang/jp.lang.php index 9f4c50ae0..a4562656e 100644 --- a/modules/integration_search/lang/jp.lang.php +++ b/modules/integration_search/lang/jp.lang.php @@ -1,43 +1,43 @@ - 翻訳:RisaPapa、ミニミ - * @brief 日本語言語パッケージ(基本的な内容のみう) - **/ - - $lang->integration_search = '統合検索'; - - $lang->sample_code = 'サンプルコード'; - $lang->about_target_module = '選択されたモジュールだけを検索対象とします。各モジュールの権限設定にも注意して下さい。'; - $lang->about_sample_code = '上のコードをレイアウトなどに挿入すると統合検索が可能になります。'; - $lang->msg_no_keyword = '検索語を入力して下さい。'; - $lang->msg_document_more_search = '継続サーチボタンを選択すると、まだ検索結果として引っかからなかった箇所を引き続き検索を行います。'; - - $lang->is_result_text = "'%s'に対する検索結果%d件"; - $lang->multimedia = '画像/動画'; - - $lang->include_search_target = '選択された対象のみ'; - $lang->exclude_search_target = '選択した対象を検索から除外'; - - $lang->is_search_option = array( - 'document' => array( - 'title_content' => 'タイトル+内容', - 'title' => 'タイトル', - 'content' => '内容', - 'tag' => 'タグ', - ), - 'trackback' => array( - 'url' => '対象URL', - 'blog_name' => '対象サイト(ブログ)名', - 'title' => 'タイトル', - 'excerpt' => '内容', - ), - ); - - $lang->is_sort_option = array( - 'regdate' => '登録日', - 'comment_count' => 'コメント数', - 'readed_count' => '閲覧数', - 'voted_count' => '推薦数', - ); -?> +integration_search = '統合検索'; + + $lang->sample_code = 'サンプルコード'; + $lang->about_target_module = '選択されたモジュールだけを検索対象とします。各モジュールの権限設定にも注意して下さい。'; + $lang->about_sample_code = '上のコードをレイアウトなどに挿入すると統合検索が可能になります。'; + $lang->msg_no_keyword = '検索語を入力して下さい。'; + $lang->msg_document_more_search = '継続サーチボタンを選択すると、まだ検索結果として引っかからなかった箇所を引き続き検索を行います。'; + + $lang->is_result_text = "'%s'に対する検索結果%d件"; + $lang->multimedia = '画像/動画'; + + $lang->include_search_target = '選択された対象のみ'; + $lang->exclude_search_target = '選択した対象を検索から除外'; + + $lang->is_search_option = array( + 'document' => array( + 'title_content' => 'タイトル+内容', + 'title' => 'タイトル', + 'content' => '内容', + 'tag' => 'タグ', + ), + 'trackback' => array( + 'url' => '対象URL', + 'blog_name' => '対象サイト(ブログ)名', + 'title' => 'タイトル', + 'excerpt' => '内容', + ), + ); + + $lang->is_sort_option = array( + 'regdate' => '登録日', + 'comment_count' => 'コメント数', + 'readed_count' => '閲覧数', + 'voted_count' => '推薦数', + ); +?> diff --git a/modules/integration_search/lang/ko.lang.php b/modules/integration_search/lang/ko.lang.php index 6d20d17d6..198db6e29 100644 --- a/modules/integration_search/lang/ko.lang.php +++ b/modules/integration_search/lang/ko.lang.php @@ -1,43 +1,43 @@ - - * @brief 한국어 언어팩 (기본적인 내용만 수록) - **/ - - $lang->integration_search = '통합검색'; - - $lang->sample_code = '샘플코드'; - $lang->about_target_module = '선택된 모듈만 검색 대상으로 정합니다. 권한설정에 대한 주의를 바랍니다.'; - $lang->about_sample_code = '위 코드를 레이아웃, 스킨 등에 추가하시면 통합검색이 가능합니다.'; - $lang->msg_no_keyword = '검색어를 입력해주세요.'; - $lang->msg_document_more_search = '\'계속 검색\' 버튼을 선택하시면 아직 검색하지 않은 부분까지 계속 검색 하실 수 있습니다.'; - - $lang->is_result_text = "'%s' 에 대한 검색결과 %d건"; - $lang->multimedia = '이미지/동영상'; - - $lang->include_search_target = '선택된 대상만 검색'; - $lang->exclude_search_target = '선택된 대상을 검색에서 제외'; - - $lang->is_search_option = array( - 'document' => array( - 'title_content' => '제목+내용', - 'title' => '제목', - 'content' => '내용', - 'tag' => '태그', - ), - 'trackback' => array( - 'url' => '대상 URL', - 'blog_name' => '대상 사이트 이름', - 'title' => '제목', - 'excerpt' => '내용', - ), - ); - - $lang->is_sort_option = array( - 'regdate' => '등록일', - 'comment_count' => '댓글 수', - 'readed_count' => '조회 수', - 'voted_count' => '추천 수', - ); -?> +integration_search = '통합검색'; + + $lang->sample_code = '샘플코드'; + $lang->about_target_module = '선택된 모듈만 검색 대상으로 정합니다. 권한설정에 대한 주의를 바랍니다.'; + $lang->about_sample_code = '위 코드를 레이아웃, 스킨 등에 추가하시면 통합검색이 가능합니다.'; + $lang->msg_no_keyword = '검색어를 입력해주세요.'; + $lang->msg_document_more_search = '\'계속 검색\' 버튼을 선택하시면 아직 검색하지 않은 부분까지 계속 검색 하실 수 있습니다.'; + + $lang->is_result_text = "'%s' 에 대한 검색결과 %d건"; + $lang->multimedia = '이미지/동영상'; + + $lang->include_search_target = '선택된 대상만 검색'; + $lang->exclude_search_target = '선택된 대상을 검색에서 제외'; + + $lang->is_search_option = array( + 'document' => array( + 'title_content' => '제목+내용', + 'title' => '제목', + 'content' => '내용', + 'tag' => '태그', + ), + 'trackback' => array( + 'url' => '대상 URL', + 'blog_name' => '대상 사이트 이름', + 'title' => '제목', + 'excerpt' => '내용', + ), + ); + + $lang->is_sort_option = array( + 'regdate' => '등록일', + 'comment_count' => '댓글 수', + 'readed_count' => '조회 수', + 'voted_count' => '추천 수', + ); +?> diff --git a/modules/integration_search/lang/ru.lang.php b/modules/integration_search/lang/ru.lang.php index 8ae58d8ee..ed2139544 100644 --- a/modules/integration_search/lang/ru.lang.php +++ b/modules/integration_search/lang/ru.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief Russian basic language pack **/ diff --git a/modules/integration_search/lang/vi.lang.php b/modules/integration_search/lang/vi.lang.php index ea7b5f744..349def5b4 100644 --- a/modules/integration_search/lang/vi.lang.php +++ b/modules/integration_search/lang/vi.lang.php @@ -1,7 +1,7 @@ 翻译:guny - * @brief 综合搜索简体中文语言包 - **/ - - $lang->integration_search = "综合搜索"; - - $lang->sample_code = "代码"; - $lang->about_target_module = "所选模块作为搜索对象。请注意权限设置。"; - $lang->about_sample_code = "可把上述代码插入到相应布局当中即可实现搜索功能。"; - $lang->msg_no_keyword = '请输入搜索关键词。'; - $lang->msg_document_more_search = '利用\'继续搜索\'按钮可以进一步搜索。'; - - $lang->is_result_text = "符合'%s'的搜索结果约有%d项"; - $lang->multimedia = "图片/视频"; - - $lang->include_search_target = '只搜索所选对象'; - $lang->exclude_search_target = '所选对象从搜索中排除'; - - $lang->is_search_option = array( - 'document' => array( - 'title_content' => '标题+内容', - 'title' => '标题', - 'content' => '内容', - 'tag' => '标签', - ), - 'trackback' => array( - 'url' => '对象URL', - 'blog_name' => '对象网站名称', - 'title' => '标题', - 'excerpt' => '内容', - ), - ); - - $lang->is_sort_option = array( - 'regdate' => '日期', - 'comment_count' => '评论', - 'readed_count' => '查看', - 'voted_count' => '推荐', - ); -?> +integration_search = "综合搜索"; + + $lang->sample_code = "代码"; + $lang->about_target_module = "所选模块作为搜索对象。请注意权限设置。"; + $lang->about_sample_code = "可把上述代码插入到相应布局当中即可实现搜索功能。"; + $lang->msg_no_keyword = '请输入搜索关键词。'; + $lang->msg_document_more_search = '利用\'继续搜索\'按钮可以进一步搜索。'; + + $lang->is_result_text = "符合'%s'的搜索结果约有%d项"; + $lang->multimedia = "图片/视频"; + + $lang->include_search_target = '只搜索所选对象'; + $lang->exclude_search_target = '所选对象从搜索中排除'; + + $lang->is_search_option = array( + 'document' => array( + 'title_content' => '标题+内容', + 'title' => '标题', + 'content' => '内容', + 'tag' => '标签', + ), + 'trackback' => array( + 'url' => '对象URL', + 'blog_name' => '对象网站名称', + 'title' => '标题', + 'excerpt' => '内容', + ), + ); + + $lang->is_sort_option = array( + 'regdate' => '日期', + 'comment_count' => '评论', + 'readed_count' => '查看', + 'voted_count' => '推荐', + ); +?> diff --git a/modules/integration_search/lang/zh-TW.lang.php b/modules/integration_search/lang/zh-TW.lang.php index ed58e0024..d29807db4 100644 --- a/modules/integration_search/lang/zh-TW.lang.php +++ b/modules/integration_search/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 綜合搜尋(integration_search)模組正體中文語言 **/ diff --git a/modules/integration_search/skins/default/skin.xml b/modules/integration_search/skins/default/skin.xml index 10dde8507..bb0641e11 100644 --- a/modules/integration_search/skins/default/skin.xml +++ b/modules/integration_search/skins/default/skin.xml @@ -1,54 +1,54 @@ - - - 통합 검색 기본 스킨 - Skin trang tìm kiếm - 搜索默认皮肤 - 統合検索のデフォルトスキン - Default Skin of Integration Search - 預設綜合搜尋面板 - Skin mặc định của trang tìm kiếm. - 통합검색 모듈의 기본 스킨 - 搜索模块的默认皮肤。 - 統合検索モジュールのデフォルトスキンです。 - Default skin of integration search module - 預設綜合搜尋面板。 - 0.1 - 2007-07-24 - - - zero - zero - zero - zero - zero - zero - - - - - 기본 - 默认 - デフォルト - Default - Mặc định - 預設 - - - - - - 설명 - 说明 - 説明 - Description - Mô tả - 說明 - 검색결과 상단에 결과가 출력됩니다. - 显示在搜索结果上端。 - 検索結果が上段に表示されます。 - Result will be displayed on top of search result. - Mô tả sẽ hiển thị trên đầu trang kết quả tìm kiếm. - 在最頂端顯示搜尋結果。 - - - + + + 통합 검색 기본 스킨 + Skin trang tìm kiếm + 搜索默认皮肤 + 統合検索のデフォルトスキン + Default Skin of Integration Search + 預設綜合搜尋面板 + Skin mặc định của trang tìm kiếm. + 통합검색 모듈의 기본 스킨 + 搜索模块的默认皮肤。 + 統合検索モジュールのデフォルトスキンです。 + Default skin of integration search module + 預設綜合搜尋面板。 + 0.1 + 2007-07-24 + + + NHN + NHN + NHN + NHN + NHN + NHN + + + + + 기본 + 默认 + デフォルト + Default + Mặc định + 預設 + + + + + + 설명 + 说明 + 説明 + Description + Mô tả + 說明 + 검색결과 상단에 결과가 출력됩니다. + 显示在搜索结果上端。 + 検索結果が上段に表示されます。 + Result will be displayed on top of search result. + Mô tả sẽ hiển thị trên đầu trang kết quả tìm kiếm. + 在最頂端顯示搜尋結果。 + + + diff --git a/modules/integration_search/tpl/js/integration_search_admin.js b/modules/integration_search/tpl/js/integration_search_admin.js index 3e2ba967a..0fc3ade6b 100644 --- a/modules/integration_search/tpl/js/integration_search_admin.js +++ b/modules/integration_search/tpl/js/integration_search_admin.js @@ -1,5 +1,5 @@ -/** - * @file modules/board/js/board_admin.js - * @author zero (zero@nzeo.com) - * @brief integration_search 모듈의 관리자용 javascript - **/ +/** + * @file modules/board/js/board_admin.js + * @author NHN (developers@xpressengine.com) + * @brief integration_search 모듈의 관리자용 javascript + **/ diff --git a/modules/krzip/conf/info.xml b/modules/krzip/conf/info.xml index 8eb9fd80d..0fb09e14b 100644 --- a/modules/krzip/conf/info.xml +++ b/modules/krzip/conf/info.xml @@ -1,57 +1,57 @@ - - - 한국 우편번호 - Korean Zip Code - Korean Zip Code - Código postal de Corea - 韩国邮编 - 韓国郵便番号 - Корейский почтовый индекс - 韓國郵編 - - XE 운영하는 우편번호서버를 이용하여 우편번호 검색을 합니다. - 우편번호 검색 서버는 설정을 통해 변경하실 수 있습니다. - - - Searching the zip code via zip code server operated by XE. - You can change the zip code server by setting. - - - Tìm kiếm địa chỉ với Zip Code Server được cung cấp bởi XE. - Bạn có thể thay đổi Zip Code Server bằng việc thiết lập Zip Code. - - - Busca el código postal a través del servidor operado por XE. - Usted puede cambiar la configuración del servidor de código postal. - - - 利用XE运营的邮编服务器搜索邮编。 - 通过设置可以修改邮编搜索服务器。 - - - XEで運用している郵便番号サーバを利用して韓国の郵便番号を検索します。 - 郵便番号検索サーバは設定によって変更することが出来ます。 - - - Поиск индекса через сервер почтовый индексов, оперируемый XE. - Вы можете изменить сервер почтовых индексов в настройках. - - - 利用 XE營運的郵編主機搜尋郵編。 - 透過設置可修改編輯郵編搜尋主機。 - - 0.1 - 2007-02-28 - accessory - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 한국 우편번호 + Korean Zip Code + Korean Zip Code + Código postal de Corea + 韩国邮编 + 韓国郵便番号 + Корейский почтовый индекс + 韓國郵編 + + XE 운영하는 우편번호서버를 이용하여 우편번호 검색을 합니다. + 우편번호 검색 서버는 설정을 통해 변경하실 수 있습니다. + + + Searching the zip code via zip code server operated by XE. + You can change the zip code server by setting. + + + Tìm kiếm địa chỉ với Zip Code Server được cung cấp bởi XE. + Bạn có thể thay đổi Zip Code Server bằng việc thiết lập Zip Code. + + + Busca el código postal a través del servidor operado por XE. + Usted puede cambiar la configuración del servidor de código postal. + + + 利用XE运营的邮编服务器搜索邮编。 + 通过设置可以修改邮编搜索服务器。 + + + XEで運用している郵便番号サーバを利用して韓国の郵便番号を検索します。 + 郵便番号検索サーバは設定によって変更することが出来ます。 + + + Поиск индекса через сервер почтовый индексов, оперируемый XE. + Вы можете изменить сервер почтовых индексов в настройках. + + + 利用 XE營運的郵編主機搜尋郵編。 + 透過設置可修改編輯郵編搜尋主機。 + + 0.1 + 2007-02-28 + accessory + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/krzip/krzip.admin.controller.php b/modules/krzip/krzip.admin.controller.php index 31e33907d..5a156f20c 100644 --- a/modules/krzip/krzip.admin.controller.php +++ b/modules/krzip/krzip.admin.controller.php @@ -1,33 +1,33 @@ -krzip_server_hostname) $args->krzip_server_hostname = $this->hostname; - if(!$args->krzip_server_port) $args->krzip_server_port = $this->port; - if(!$args->krzip_server_query) $args->krzip_server_query = $this->query; - - // module Controller 객체 생성하여 입력 - $oModuleController = &getController('module'); - $output = $oModuleController->insertModuleConfig('krzip',$args); - return $output; - } - - } -?> +krzip_server_hostname) $args->krzip_server_hostname = $this->hostname; + if(!$args->krzip_server_port) $args->krzip_server_port = $this->port; + if(!$args->krzip_server_query) $args->krzip_server_query = $this->query; + + // module Controller 객체 생성하여 입력 + $oModuleController = &getController('module'); + $output = $oModuleController->insertModuleConfig('krzip',$args); + return $output; + } + + } +?> diff --git a/modules/krzip/krzip.admin.view.php b/modules/krzip/krzip.admin.view.php index cff50dcdb..f0c7fca5e 100644 --- a/modules/krzip/krzip.admin.view.php +++ b/modules/krzip/krzip.admin.view.php @@ -1,32 +1,32 @@ -getModuleConfig('krzip'); - Context::set('config',$config); - - // 템플릿 파일 지정 - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('index'); - } - - - } -?> +getModuleConfig('krzip'); + Context::set('config',$config); + + // 템플릿 파일 지정 + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('index'); + } + + + } +?> diff --git a/modules/krzip/krzip.class.php b/modules/krzip/krzip.class.php index 51b38af3f..71c00072f 100644 --- a/modules/krzip/krzip.class.php +++ b/modules/krzip/krzip.class.php @@ -1,41 +1,41 @@ - + diff --git a/modules/krzip/krzip.model.php b/modules/krzip/krzip.model.php index 818c29eea..9c7cee794 100644 --- a/modules/krzip/krzip.model.php +++ b/modules/krzip/krzip.model.php @@ -1,56 +1,56 @@ -getModuleConfig('krzip'); - if($config->krzip_server_hostname) $this->hostname = $config->krzip_server_hostname; - if($config->krzip_server_port) $this->port = $config->krzip_server_port; - if($config->krzip_server_query) $this->query = $config->krzip_server_query; - - // 동네 이름을 받음 - $addr = trim(Context::get('addr')); - if(!$addr) return new Object(-1,'msg_not_exists_addr'); - - // 지정된 서버에 요청을 시도한다 - $query_string = $this->query.urlencode($addr); - - $fp = @fsockopen($this->hostname, $this->port, $errno, $errstr); - if(!$fp) return new Object(-1, 'msg_fail_to_socket_open'); - - fputs($fp, "GET {$query_string} HTTP/1.0\r\n"); - fputs($fp, "Host: {$this->hostname}\r\n\r\n"); - - $buff = ''; - while(!feof($fp)) { - $str = fgets($fp, 1024); - if(trim($str)=='') $start = true; - if($start) $buff .= $str; - } - - fclose($fp); - - $address_list = unserialize(base64_decode($buff)); - if(!$address_list) return new Object(-1, 'msg_no_result'); - - $this->add('address_list', implode("\n",$address_list)."\n"); - } - } -?> +getModuleConfig('krzip'); + if($config->krzip_server_hostname) $this->hostname = $config->krzip_server_hostname; + if($config->krzip_server_port) $this->port = $config->krzip_server_port; + if($config->krzip_server_query) $this->query = $config->krzip_server_query; + + // 동네 이름을 받음 + $addr = trim(Context::get('addr')); + if(!$addr) return new Object(-1,'msg_not_exists_addr'); + + // 지정된 서버에 요청을 시도한다 + $query_string = $this->query.urlencode($addr); + + $fp = @fsockopen($this->hostname, $this->port, $errno, $errstr); + if(!$fp) return new Object(-1, 'msg_fail_to_socket_open'); + + fputs($fp, "GET {$query_string} HTTP/1.0\r\n"); + fputs($fp, "Host: {$this->hostname}\r\n\r\n"); + + $buff = ''; + while(!feof($fp)) { + $str = fgets($fp, 1024); + if(trim($str)=='') $start = true; + if($start) $buff .= $str; + } + + fclose($fp); + + $address_list = unserialize(base64_decode($buff)); + if(!$address_list) return new Object(-1, 'msg_no_result'); + + $this->add('address_list', implode("\n",$address_list)."\n"); + } + } +?> diff --git a/modules/krzip/lang/en.lang.php b/modules/krzip/lang/en.lang.php index 9f557b753..cfde3d837 100644 --- a/modules/krzip/lang/en.lang.php +++ b/modules/krzip/lang/en.lang.php @@ -1,22 +1,22 @@ - - * @brief English language pack (Only basic contents are listed) - **/ - - // normal words - $lang->krzip = "Korean Zip Code"; - $lang->krzip_server_hostname = "Server name for zip code checking"; - $lang->krzip_server_port = "Server port for zip code checking"; - $lang->krzip_server_query = "Server path for zip code checking"; - - // descriptions - $lang->about_krzip_server_hostname = "Please input the server's domain for checking zip codes and receiving the result list"; - $lang->about_krzip_server_port = "Please input the server's port number for checking the zip code"; - $lang->about_krzip_server_query = "Please input the query url that will be requested for checking the zip code"; - - // error messages - $lang->msg_not_exists_addr = "Target for searching doesn't exist"; - $lang->msg_fail_to_socket_open = "Unabled to connect to zip code checking server"; -?> +krzip = "Korean Zip Code"; + $lang->krzip_server_hostname = "Server name for zip code checking"; + $lang->krzip_server_port = "Server port for zip code checking"; + $lang->krzip_server_query = "Server path for zip code checking"; + + // descriptions + $lang->about_krzip_server_hostname = "Please input the server's domain for checking zip codes and receiving the result list"; + $lang->about_krzip_server_port = "Please input the server's port number for checking the zip code"; + $lang->about_krzip_server_query = "Please input the query url that will be requested for checking the zip code"; + + // error messages + $lang->msg_not_exists_addr = "Target for searching doesn't exist"; + $lang->msg_fail_to_socket_open = "Unabled to connect to zip code checking server"; +?> diff --git a/modules/krzip/lang/es.lang.php b/modules/krzip/lang/es.lang.php index db5467dca..91592eecd 100644 --- a/modules/krzip/lang/es.lang.php +++ b/modules/krzip/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma espanol (Solo los contenidos basicos) **/ diff --git a/modules/krzip/lang/fr.lang.php b/modules/krzip/lang/fr.lang.php index bf8dcf120..f8d726367 100644 --- a/modules/krzip/lang/fr.lang.php +++ b/modules/krzip/lang/fr.lang.php @@ -1,22 +1,22 @@ - Traduit par Pierre Duvent - * @brief Paque du langage en français pour le module de Code postal coréen - **/ - - // mots normaux - $lang->krzip = "Code postal coréen"; - $lang->krzip_server_hostname = "Nom de serveur pour vérifier le code postal"; - $lang->krzip_server_port = "Port de serveur pour vérifier le code postal"; - $lang->krzip_server_query = "Chemin de serveur pour vérifier le code postal"; - - // descriptions - $lang->about_krzip_server_hostname = "Entrez le domaine de serveur pour vérifier le code postal et recevoir le liste des résultats, S.V.P."; - $lang->about_krzip_server_port = "Entrez le numéro de port de serveur pour vérifier le code postal, SVP"; - $lang->about_krzip_server_query = "Entrez l'URL à Requérir qui sera requis pour vérifier le code postal"; - - // messages des erreurs - $lang->msg_not_exists_addr = "Objectifs à rechercher n'existe pas"; - $lang->msg_fail_to_socket_open = "Echoué à connecter au serveur pour vérifier le code postal"; -?> + + * @brief Paque du langage en français pour le module de Code postal coréen + **/ + + // mots normaux + $lang->krzip = "Code postal coréen"; + $lang->krzip_server_hostname = "Nom de serveur pour vérifier le code postal"; + $lang->krzip_server_port = "Port de serveur pour vérifier le code postal"; + $lang->krzip_server_query = "Chemin de serveur pour vérifier le code postal"; + + // descriptions + $lang->about_krzip_server_hostname = "Entrez le domaine de serveur pour vérifier le code postal et recevoir le liste des résultats, S.V.P."; + $lang->about_krzip_server_port = "Entrez le numéro de port de serveur pour vérifier le code postal, SVP"; + $lang->about_krzip_server_query = "Entrez l'URL à Requérir qui sera requis pour vérifier le code postal"; + + // messages des erreurs + $lang->msg_not_exists_addr = "Objectifs à rechercher n'existe pas"; + $lang->msg_fail_to_socket_open = "Echoué à connecter au serveur pour vérifier le code postal"; +?> diff --git a/modules/krzip/lang/jp.lang.php b/modules/krzip/lang/jp.lang.php index 2ec5ac56f..ca3d64ad2 100644 --- a/modules/krzip/lang/jp.lang.php +++ b/modules/krzip/lang/jp.lang.php @@ -1,22 +1,22 @@ - 翻訳:RisaPapa、ミニミ - * @brief 日本語言語パッケージ(基本的な内容のみ) - **/ - - // 一般用語 - $lang->krzip = '韓国郵便番号'; - $lang->krzip_server_hostname = '郵便番号検索サーバ名'; - $lang->krzip_server_port = '郵便番号検索サーバのポート'; - $lang->krzip_server_query = '郵便番号検索サーバのクエリ'; - - // 説明 - $lang->about_krzip_server_hostname = '郵便番号を検索して結果を取り寄せるサーバのドメインを入力して下さい。'; - $lang->about_krzip_server_port = '郵便番号検索サーバのポート番号を入力して下さい。'; - $lang->about_krzip_server_query = '郵便番号検索サーバに問い合わせるクエリのURLを入力して下さい。'; - - // エラーメッセージ - $lang->msg_not_exists_addr = '入力された文字列では郵便番号が見つかりませんでした'; - $lang->msg_fail_to_socket_open = '郵便番号サーバとの接続に失敗しました'; -?> +krzip = '韓国郵便番号'; + $lang->krzip_server_hostname = '郵便番号検索サーバ名'; + $lang->krzip_server_port = '郵便番号検索サーバのポート'; + $lang->krzip_server_query = '郵便番号検索サーバのクエリ'; + + // 説明 + $lang->about_krzip_server_hostname = '郵便番号を検索して結果を取り寄せるサーバのドメインを入力して下さい。'; + $lang->about_krzip_server_port = '郵便番号検索サーバのポート番号を入力して下さい。'; + $lang->about_krzip_server_query = '郵便番号検索サーバに問い合わせるクエリのURLを入力して下さい。'; + + // エラーメッセージ + $lang->msg_not_exists_addr = '入力された文字列では郵便番号が見つかりませんでした'; + $lang->msg_fail_to_socket_open = '郵便番号サーバとの接続に失敗しました'; +?> diff --git a/modules/krzip/lang/ko.lang.php b/modules/krzip/lang/ko.lang.php index f13944612..4bbe9b23d 100644 --- a/modules/krzip/lang/ko.lang.php +++ b/modules/krzip/lang/ko.lang.php @@ -1,22 +1,22 @@ - - * @brief 한국어 언어팩 (기본적인 내용만 수록) - **/ - - // 일반 단어들 - $lang->krzip = '한국 우편번호'; - $lang->krzip_server_hostname = '우편번호 검사 서버의 이름'; - $lang->krzip_server_port = '우편번호 검사 서버 포트'; - $lang->krzip_server_query = '우편번호 검사 서버 경로'; - - // 설명문 - $lang->about_krzip_server_hostname = '우편번호를 검사하여 결과 목록을 가져올 서버의 도메인을 입력해주세요.'; - $lang->about_krzip_server_port = '우편번호를 검사서버의 포트 번호를 입력해주세요.'; - $lang->about_krzip_server_query = '우편번호를 검사서버에 요청할 query url을 입력해 주세요.'; - - // 에러 메시지들 - $lang->msg_not_exists_addr = '검색하려는 대상이 없습니다.'; - $lang->msg_fail_to_socket_open = '우편번호 검색 대상 서버 접속에 실패하였습니다.'; -?> +krzip = '한국 우편번호'; + $lang->krzip_server_hostname = '우편번호 검사 서버의 이름'; + $lang->krzip_server_port = '우편번호 검사 서버 포트'; + $lang->krzip_server_query = '우편번호 검사 서버 경로'; + + // 설명문 + $lang->about_krzip_server_hostname = '우편번호를 검사하여 결과 목록을 가져올 서버의 도메인을 입력해주세요.'; + $lang->about_krzip_server_port = '우편번호를 검사서버의 포트 번호를 입력해주세요.'; + $lang->about_krzip_server_query = '우편번호를 검사서버에 요청할 query url을 입력해 주세요.'; + + // 에러 메시지들 + $lang->msg_not_exists_addr = '검색하려는 대상이 없습니다.'; + $lang->msg_fail_to_socket_open = '우편번호 검색 대상 서버 접속에 실패하였습니다.'; +?> diff --git a/modules/krzip/lang/ru.lang.php b/modules/krzip/lang/ru.lang.php index ae3dee485..de7ab01ab 100644 --- a/modules/krzip/lang/ru.lang.php +++ b/modules/krzip/lang/ru.lang.php @@ -1,22 +1,22 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - // нормальные слова - $lang->krzip = "Корейский почтовый индекс"; - $lang->krzip_server_hostname = "Имя сервера для проверки почтового индекса"; - $lang->krzip_server_port = "Порт сервера для проверки почтового индекса"; - $lang->krzip_server_query = "Путь на сервере для проверки почтового индекса"; - - // описания - $lang->about_krzip_server_hostname = "Пожалуйста, введите доменное имя сервера для проверки почтового идекса и получения списка результатов"; - $lang->about_krzip_server_port = "Пожалуйста, введите порт сервера для проверки почтового идекса"; - $lang->about_krzip_server_query = "Пожалуйста, введите URL запроса на сервер для проверки почтового идекса"; - - // ошибки - $lang->msg_not_exists_addr = "Назначение для поиска не существует"; - $lang->msg_fail_to_socket_open = "Невозможно подключиться к серверу для проверки почтового почтового индекса"; -?> +krzip = "Корейский почтовый индекс"; + $lang->krzip_server_hostname = "Имя сервера для проверки почтового индекса"; + $lang->krzip_server_port = "Порт сервера для проверки почтового индекса"; + $lang->krzip_server_query = "Путь на сервере для проверки почтового индекса"; + + // описания + $lang->about_krzip_server_hostname = "Пожалуйста, введите доменное имя сервера для проверки почтового идекса и получения списка результатов"; + $lang->about_krzip_server_port = "Пожалуйста, введите порт сервера для проверки почтового идекса"; + $lang->about_krzip_server_query = "Пожалуйста, введите URL запроса на сервер для проверки почтового идекса"; + + // ошибки + $lang->msg_not_exists_addr = "Назначение для поиска не существует"; + $lang->msg_fail_to_socket_open = "Невозможно подключиться к серверу для проверки почтового почтового индекса"; +?> diff --git a/modules/krzip/lang/vi.lang.php b/modules/krzip/lang/vi.lang.php index 48ba205d0..1c53f08ae 100644 --- a/modules/krzip/lang/vi.lang.php +++ b/modules/krzip/lang/vi.lang.php @@ -1,24 +1,24 @@ -krzip = "Zip Code (Korea)"; - $lang->krzip_server_hostname = "Tên Server kiểm tra Zip Code"; - $lang->krzip_server_port = "Cổng Server kiểm tra Zip Code"; - $lang->krzip_server_query = "Đường dẫn Server kiểm tra Zip Code"; - - // descriptions - $lang->about_krzip_server_hostname = "Xin hãy nhập tên miền của Server để kiểm tra và kết nối cho danh sách kết quả"; - $lang->about_krzip_server_port = "Xin hãy nhập số cổng kết nối của Server để kiểm tra Zip Code"; - $lang->about_krzip_server_query = "Xin hãy nhập địa chỉ sẽ trả lời khi kiểm tra Zip Code"; - - // error messages - $lang->msg_not_exists_addr = "Khu vực tìm kiếm không tồn tại."; - $lang->msg_fail_to_socket_open = "Không thể kết nối tới Server."; -?> +krzip = "Zip Code (Korea)"; + $lang->krzip_server_hostname = "Tên Server kiểm tra Zip Code"; + $lang->krzip_server_port = "Cổng Server kiểm tra Zip Code"; + $lang->krzip_server_query = "Đường dẫn Server kiểm tra Zip Code"; + + // descriptions + $lang->about_krzip_server_hostname = "Xin hãy nhập tên miền của Server để kiểm tra và kết nối cho danh sách kết quả"; + $lang->about_krzip_server_port = "Xin hãy nhập số cổng kết nối của Server để kiểm tra Zip Code"; + $lang->about_krzip_server_query = "Xin hãy nhập địa chỉ sẽ trả lời khi kiểm tra Zip Code"; + + // error messages + $lang->msg_not_exists_addr = "Khu vực tìm kiếm không tồn tại."; + $lang->msg_fail_to_socket_open = "Không thể kết nối tới Server."; +?> diff --git a/modules/krzip/lang/zh-CN.lang.php b/modules/krzip/lang/zh-CN.lang.php index 80a924f2f..69648c12f 100644 --- a/modules/krzip/lang/zh-CN.lang.php +++ b/modules/krzip/lang/zh-CN.lang.php @@ -1,22 +1,22 @@ - - * @brief 简体中文语言包(收录了基本内容) - **/ - - // 一般单词 - $lang->krzip = "韩国邮编"; - $lang->krzip_server_hostname = "邮编检测服务器名"; - $lang->krzip_server_port = "邮编检测服务器端口"; - $lang->krzip_server_query = "邮编检测服务器路径"; - - // 说明文 - $lang->about_krzip_server_hostname = "请输入要导入的检测结果目录服务器域名。"; - $lang->about_krzip_server_port = "请输入邮编检测服务器端口。"; - $lang->about_krzip_server_query = "请输入向邮编检测服务器发出请求的 query url。"; - - // 错误提示 - $lang->msg_not_exists_addr = "没有要搜索的对象!"; - $lang->msg_fail_to_socket_open = "连接邮编搜索对象服务器失败!"; -?> +krzip = "韩国邮编"; + $lang->krzip_server_hostname = "邮编检测服务器名"; + $lang->krzip_server_port = "邮编检测服务器端口"; + $lang->krzip_server_query = "邮编检测服务器路径"; + + // 说明文 + $lang->about_krzip_server_hostname = "请输入要导入的检测结果目录服务器域名。"; + $lang->about_krzip_server_port = "请输入邮编检测服务器端口。"; + $lang->about_krzip_server_query = "请输入向邮编检测服务器发出请求的 query url。"; + + // 错误提示 + $lang->msg_not_exists_addr = "没有要搜索的对象!"; + $lang->msg_fail_to_socket_open = "连接邮编搜索对象服务器失败!"; +?> diff --git a/modules/krzip/lang/zh-TW.lang.php b/modules/krzip/lang/zh-TW.lang.php index dea0022bb..e8e85c09b 100644 --- a/modules/krzip/lang/zh-TW.lang.php +++ b/modules/krzip/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 韓國郵編(krzip)模組正體中文語言 **/ diff --git a/modules/layout/conf/info.xml b/modules/layout/conf/info.xml index 193179c7d..9121b589a 100644 --- a/modules/layout/conf/info.xml +++ b/modules/layout/conf/info.xml @@ -1,33 +1,33 @@ - - - 레이아웃 - 布局管理 - レイアウト - Layout - Giao diện - Diseño - Лейаут - 版面設計 - 레이아웃을 생성/관리하는 모듈입니다. - 生成/管理布局的模块。 - レイアウトを生成・管理するモジュールです。 - This module is for creating/managing of layouts. - Chức năng của Module này dành cho việc tạo và quản lý giao diện. - Este módulo es para crear y manejar el diseño. - Этот модуль служит для создания/управления лейаутами. - 建立/管理版面的模組。 - 0.1 - 2007-02-28 - construction - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 레이아웃 + 布局管理 + レイアウト + Layout + Giao diện + Diseño + Лейаут + 版面設計 + 레이아웃을 생성/관리하는 모듈입니다. + 生成/管理布局的模块。 + レイアウトを生成・管理するモジュールです。 + This module is for creating/managing of layouts. + Chức năng của Module này dành cho việc tạo và quản lý giao diện. + Este módulo es para crear y manejar el diseño. + Этот модуль служит для создания/управления лейаутами. + 建立/管理版面的模組。 + 0.1 + 2007-02-28 + construction + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/layout/faceoff/conf/info.xml b/modules/layout/faceoff/conf/info.xml index b833eb15b..ebd08e37e 100644 --- a/modules/layout/faceoff/conf/info.xml +++ b/modules/layout/faceoff/conf/info.xml @@ -1,134 +1,121 @@ - - - XE Face off 레이아웃 - Giao diện XE FaceOff - XE Face off官方布局 - XE Face off 版面 - XE Face offレイアウト - XE FaceOff 레이아웃입니다. - Giao diện của XE FaceOff. - XE Face off官方布局。 - XE FaceOff版面 - XE FaceOffレイアウトです。 - 0.1 - 2009-01-02 - - sol - sol - sol - sol - sol - sol - sol - sol - sol - - - sol - sol - sol - sol - sol - sol - sol - sol - sol - - - - - - 홈 페이지 URL - ホームページURL - 主页地址 - 主頁網址 - Homepage URL - URL trang chủ - Homepage URL - Домашняя страница URL - URL de la página web - 로고를 클릭시에 이동할 홈 페이지 URL을 입력해 주세요. - ロゴをクリックした際に移動するホームページのURLを入力して下さい。 - 点击网站LOGO时要移动的页面URL。 - 請輸入當用戶按了網站Logo後,要前往的頁面網址。 - Please input the URL to redirect when user clicks the logo - Hãy nhập địa chỉ trang chủ sẽ được chuyển tới khi bấm vào Logo - Bitte geben Sie die URL umzuleiten, wenn Benutzer klickt das Logo - Пожалуйста, введите URL для перенаправления, когда пользователь нажимает логотип - Ingresar el URL de la página web para redireccionar al pulsar el logotipo - - - 로고이미지 - ロゴイメージ - LOGO图片 - Logo圖片 - Logo image - Hình Logo - Logobildes - Изображения логотипа - Imagen del logotipo - 레이아웃의 상단에 표시될 로고이미지를 입력하세요. (세로길이가 23px인 투명이미지가 가장 어울립니다) - レイアウトの上段に表示されるロゴイメージを入力して下さい。 (縦幅が23pxである透明イメージが最も合います。) - 请输入显示在布局顶部的LOGO图片。(高度为23px的透明图片为适。) - 請輸入要顯示在版面上端的Logo圖片。(適當高度為23px的透明圖片。) - Please input a logo image which will be displayed on the top of layout. (Transparent image with height of 23px is recommended.) - Hãy nhập hình ảnh của Logo, Logo này sẽ hiện thị phía trên cùng của giao diện. (Nên sử dụng hình có nền trong suốt với chiều cao bằng 23px.) - Bitte geben Sie ein Logo das Bild wird auf dem oberen Layout. (Transparent Bild mit einer Höhe von 23px wird empfohlen). - Введите логотип изображение, которое будет отображаться в верхней части формы. (Прозрачный изображение с высотой 23px рекомендуется.) - Ingresar una imagen para logotipo. ( Se recomienda una imagen de fondo transparente con una altura de 23px. - - - 로고 글자 - ロゴ用テキスト - 网站标题 - Logo文字 - LOGO characters - Chữ Logo - LOGO Zeichen - LOGO символов - LOGO caracteres - 레이아웃의 상단에 표시될 로고 글자를 입력해주세요. 로고 이미지가 있으면 표시되지 않습니다. - レイアウトの上部に表示されるロゴの文字を入力して下さい。ロゴ画像がある場合は表示されません。 - 请输入网站标题(如已经使用了LOGO图片,此标题将不会显示出来)。 - 請輸入要顯示在版面上方的文字。 - Logo at the top of the display layout, please enter the letters. If the image does not display the logo. - Chữ Logo sẽ được hiển thị phía trên của trang Web. Nếu không có hình ảnh thì Logo này sẽ hiển thị. - Logo am oberen Rand des Displays Layout, geben Sie bitte die Buchstaben. Wenn das Bild nicht das Logo. - Логотип на верхней части дисплея формата, пожалуйста, введите буквы. Если изображение не отображается логотип. - Logo en la parte superior de la pantalla de diseño, por favor, introduzca las letras. Si la imagen no se muestra el logotipo. - - - 카피라이트 문구 - Copyright文章 - 网站版权文档 - 版權所有 - Copyright Stationery - Nội dung Copyright - Copyright Stationery - Copyright Канцтовары - Papel del derecho de autor - 하단에 표시될 카피라이트 문구를 설정할 수 있습니다 - レイアウトの下部に表示されるcopyrightフレーズを入力して下さい。 - 请输入网站版权文档。 - 請輸入要顯示在版面下方的版權聲明。 - Layout displayed in the bottom of the copyright notice please. - Nội dung này sẽ hiển thị phía dưới cùng của Website. - Layout angezeigt, im unteren Teil der Urheberrechtsschutz bitte. - Макет отображается в нижней части авторских прав, пожалуйста. - Diseño de muestra en la parte inferior de la nota de copyright, por favor. - - - - - 상단 메뉴 - 上段メニュー - 主菜单 - 主選單 - Top menu - Menu trên - Top Menü - Верхнее меню - Menú Principal - - - + + + XE Face off 레이아웃 + Giao diện XE FaceOff + XE Face off官方布局 + XE Face off 版面 + XE Face offレイアウト + XE FaceOff 레이아웃입니다. + Giao diện của XE FaceOff. + XE Face off官方布局。 + XE FaceOff版面 + XE FaceOffレイアウトです。 + 0.1 + 2009-01-02 + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + + + 홈 페이지 URL + ホームページURL + 主页地址 + 主頁網址 + Homepage URL + URL trang chủ + Homepage URL + Домашняя страница URL + URL de la página web + 로고를 클릭시에 이동할 홈 페이지 URL을 입력해 주세요. + ロゴをクリックした際に移動するホームページのURLを入力して下さい。 + 点击网站LOGO时要移动的页面URL。 + 請輸入當用戶按了網站Logo後,要前往的頁面網址。 + Please input the URL to redirect when user clicks the logo + Hãy nhập địa chỉ trang chủ sẽ được chuyển tới khi bấm vào Logo + Bitte geben Sie die URL umzuleiten, wenn Benutzer klickt das Logo + Пожалуйста, введите URL для перенаправления, когда пользователь нажимает логотип + Ingresar el URL de la página web para redireccionar al pulsar el logotipo + + + 로고이미지 + ロゴイメージ + LOGO图片 + Logo圖片 + Logo image + Hình Logo + Logobildes + Изображения логотипа + Imagen del logotipo + 레이아웃의 상단에 표시될 로고이미지를 입력하세요. (세로길이가 23px인 투명이미지가 가장 어울립니다) + レイアウトの上段に表示されるロゴイメージを入力して下さい。 (縦幅が23pxである透明イメージが最も合います。) + 请输入显示在布局顶部的LOGO图片。(高度为23px的透明图片为适。) + 請輸入要顯示在版面上端的Logo圖片。(適當高度為23px的透明圖片。) + Please input a logo image which will be displayed on the top of layout. (Transparent image with height of 23px is recommended.) + Hãy nhập hình ảnh của Logo, Logo này sẽ hiện thị phía trên cùng của giao diện. (Nên sử dụng hình có nền trong suốt với chiều cao bằng 23px.) + Bitte geben Sie ein Logo das Bild wird auf dem oberen Layout. (Transparent Bild mit einer Höhe von 23px wird empfohlen). + Введите логотип изображение, которое будет отображаться в верхней части формы. (Прозрачный изображение с высотой 23px рекомендуется.) + Ingresar una imagen para logotipo. ( Se recomienda una imagen de fondo transparente con una altura de 23px. + + + 로고 글자 + ロゴ用テキスト + 网站标题 + Logo文字 + LOGO characters + Chữ Logo + LOGO Zeichen + LOGO символов + LOGO caracteres + 레이아웃의 상단에 표시될 로고 글자를 입력해주세요. 로고 이미지가 있으면 표시되지 않습니다. + レイアウトの上部に表示されるロゴの文字を入力して下さい。ロゴ画像がある場合は表示されません。 + 请输入网站标题(如已经使用了LOGO图片,此标题将不会显示出来)。 + 請輸入要顯示在版面上方的文字。 + Logo at the top of the display layout, please enter the letters. If the image does not display the logo. + Chữ Logo sẽ được hiển thị phía trên của trang Web. Nếu không có hình ảnh thì Logo này sẽ hiển thị. + Logo am oberen Rand des Displays Layout, geben Sie bitte die Buchstaben. Wenn das Bild nicht das Logo. + Логотип на верхней части дисплея формата, пожалуйста, введите буквы. Если изображение не отображается логотип. + Logo en la parte superior de la pantalla de diseño, por favor, introduzca las letras. Si la imagen no se muestra el logotipo. + + + 카피라이트 문구 + Copyright文章 + 网站版权文档 + 版權所有 + Copyright Stationery + Nội dung Copyright + Copyright Stationery + Copyright Канцтовары + Papel del derecho de autor + 하단에 표시될 카피라이트 문구를 설정할 수 있습니다 + レイアウトの下部に表示されるcopyrightフレーズを入力して下さい。 + 请输入网站版权文档。 + 請輸入要顯示在版面下方的版權聲明。 + Layout displayed in the bottom of the copyright notice please. + Nội dung này sẽ hiển thị phía dưới cùng của Website. + Layout angezeigt, im unteren Teil der Urheberrechtsschutz bitte. + Макет отображается в нижней части авторских прав, пожалуйста. + Diseño de muestra en la parte inferior de la nota de copyright, por favor. + + + + + 상단 메뉴 + 上段メニュー + 主菜单 + 主選單 + Top menu + Menu trên + Top Menü + Верхнее меню + Menú Principal + + + diff --git a/modules/layout/faceoff/css/layout.css b/modules/layout/faceoff/css/layout.css index 9609fd767..cfebdd145 100644 --- a/modules/layout/faceoff/css/layout.css +++ b/modules/layout/faceoff/css/layout.css @@ -1,5 +1,5 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ /* html{ overflow:auto;} */ diff --git a/modules/layout/lang/en.lang.php b/modules/layout/lang/en.lang.php index 3460a18c3..9b9311586 100644 --- a/modules/layout/lang/en.lang.php +++ b/modules/layout/lang/en.lang.php @@ -1,118 +1,118 @@ - - * @brief Layout module's basic language pack - **/ - - $lang->cmd_layout_management = 'Layout Setting'; - $lang->cmd_layout_edit = 'Edit Layout'; - - $lang->layout_name = 'Layout Name'; - $lang->layout_maker = "Layout Developer"; - $lang->layout_license = 'License'; - $lang->layout_history = "Updates"; - $lang->layout_info = "Layout Info"; - $lang->layout_list = 'Layout List'; - $lang->menu_count = 'Menus'; - $lang->downloaded_list = 'Download List'; - $lang->layout_preview_content = 'The content gets displayed here'; - $lang->not_apply_menu = 'Apply Layouts'; - - $lang->cmd_move_to_installed_list = "View created list"; - - $lang->about_downloaded_layouts = "List of downloaded layouts"; - $lang->about_title = 'Please input the title that is easy to verify when connecting to module'; - $lang->about_not_apply_menu = 'All connected module\'s layout will be changed by checking this option.'; - - $lang->about_layout = "Layout module helps you to create the site's layout easily.
By using layout setting and menu connection, website's completed shape will be displayed with various modules.
* Those layouts which are unabled to delete or modify are the blog or other module's layout. "; - $lang->about_layout_code = - "It will be applied to the service when you save the layout code after editing it. - Please first preview your code and then save it. - You can refer grammar of XE's template from XE Template."; - - $lang->layout_export = 'Export'; - $lang->layout_btn_export = 'Download My Layout'; - $lang->about_layout_export = 'Export currently editted layout.'; - $lang->layout_import = 'Import'; - $lang->about_layout_import = 'Original layout will be deleted when you import. Please export current layout before importing.'; - - $lang->layout_manager = array( - 0 => 'Layout Manager', - 1 => 'Save', - 2 => 'Cancel', - 3 => 'Form', - 4 => 'Array', - 5 => 'Arrange', - 6 => 'Fixed Layout', - 7 => 'Variable Layout', - 8 => 'Fixed+Variable (Content)', - 9 => '1 Cell', - 10 => '2 Cells (left of content)', - 11 => '2 Cells (right of content)', - 12 => '3 Cells (left of content)', - 13 => '3 Cells (center of content)', - 14 => '3 Cells (right of content)', - 15 => 'Left', - 16 => 'Center', - 17 => 'Right', - 18 => 'All', - 19 => 'Layout', - 20 => 'Add Widget', - 21 => 'Add Content Widget', - 22 => 'Attribute', - 23 => 'Widget Style', - 24 => 'Modify', - 25 => 'Delete', - 26 => 'Align', - 27 => 'Occupy a Line', - 28 => 'Left', - 29 => 'Right', - 30 => 'Width', - 31 => 'Height', - 32 => 'Margin', - 33 => 'Padding', - 34 => 'Top', - 35 => 'Left', - 36 => 'Right', - 37 => 'Bottom', - 38 => 'Border', - 39 => 'None', - 40 => 'Background', - 41 => 'Color', - 42 => 'Image', - 43 => 'Select', - 44 => 'Repeat Background', - 45 => 'Repeat', - 46 => 'No Repeat', - 47 => 'Repeat Width', - 48 => 'Repeat Height', - 49 => 'Apply', - 50 => 'Cancel', - 51 => 'Reset', - 52 => 'Text', - 53 => 'Font', - 54 => 'Font Color', - ); - - $lang->layout_image_repository = 'Layout Repository'; - $lang->about_layout_image_repository = 'You can upload images/flash files for selected layout. They will be included in exports'; - $lang->msg_layout_image_target = 'Only gif, png, jpg, swf, flv files are allowed'; - $lang->layout_migration = 'Layout Migration'; - $lang->about_layout_migration = 'You can export or import editted layout as tar file'."\n".'(So far only FaceOff supports exports/imports)'; - - $lang->about_faceoff = array( - 'title' => 'XpressEngine FaceOff Layout Manager', - 'description' => 'FaceOff Layout Manager willl help you design layout on the web easily.
Please design your own layout with components and functions as shown below.', - 'layout' => 'FaceOff has HTML structure as above.
You can arrange/align with CSS, or use Style to design.
You can add widget from Extension(e1, e2), Neck and Knee.
Also Body, Layout, Header, Body, Footer can designed by Style, and Content will display content.', - 'setting' => 'Let me explain you the upper menu on left.
  • Save : Save current settings.
  • Cancel : Discard current settings and go back.
  • Reset : Clear current settings
  • Form : Set form as Fixed/ Variable/ Fixed+Variable(Content).
  • Arrange : Arrange 2 Extensions and Content.
  • Align : Align the position of layout.
', - 'hotkey' => 'You can design your layout more easily with Hot Keys.
  • tab : Unless a widget is selected, Header, Body, Footer will be selected in order. If not, next widget will be selected.
  • Shift + tab : It does the opposite function to tab key.
  • Esc : If nothing is selected, Neck, Extension(e1,e2),Knee will be selected in order, if a widget is selected, area of the widget will be selected.
  • Arrow Key : If a widget is selected, arrow key will move the widget to other areas.
', - 'attribute' => 'You can set background color/image to every area except widget, and font color(include tag).', - - ); - - $lang->mobile_layout_list = "Mobile Layout List"; - $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; - $lang->apply_mobile_view = "Apply Mobile View"; - $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; -?> +cmd_layout_management = 'Layout Setting'; + $lang->cmd_layout_edit = 'Edit Layout'; + + $lang->layout_name = 'Layout Name'; + $lang->layout_maker = "Layout Developer"; + $lang->layout_license = 'License'; + $lang->layout_history = "Updates"; + $lang->layout_info = "Layout Info"; + $lang->layout_list = 'Layout List'; + $lang->menu_count = 'Menus'; + $lang->downloaded_list = 'Download List'; + $lang->layout_preview_content = 'The content gets displayed here'; + $lang->not_apply_menu = 'Apply Layouts'; + + $lang->cmd_move_to_installed_list = "View created list"; + + $lang->about_downloaded_layouts = "List of downloaded layouts"; + $lang->about_title = 'Please input the title that is easy to verify when connecting to module'; + $lang->about_not_apply_menu = 'All connected module\'s layout will be changed by checking this option.'; + + $lang->about_layout = "Layout module helps you to create the site's layout easily.
By using layout setting and menu connection, website's completed shape will be displayed with various modules.
* Those layouts which are unabled to delete or modify are the blog or other module's layout. "; + $lang->about_layout_code = + "It will be applied to the service when you save the layout code after editing it. + Please first preview your code and then save it. + You can refer grammar of XE's template from
XE Template."; + + $lang->layout_export = 'Export'; + $lang->layout_btn_export = 'Download My Layout'; + $lang->about_layout_export = 'Export currently editted layout.'; + $lang->layout_import = 'Import'; + $lang->about_layout_import = 'Original layout will be deleted when you import. Please export current layout before importing.'; + + $lang->layout_manager = array( + 0 => 'Layout Manager', + 1 => 'Save', + 2 => 'Cancel', + 3 => 'Form', + 4 => 'Array', + 5 => 'Arrange', + 6 => 'Fixed Layout', + 7 => 'Variable Layout', + 8 => 'Fixed+Variable (Content)', + 9 => '1 Cell', + 10 => '2 Cells (left of content)', + 11 => '2 Cells (right of content)', + 12 => '3 Cells (left of content)', + 13 => '3 Cells (center of content)', + 14 => '3 Cells (right of content)', + 15 => 'Left', + 16 => 'Center', + 17 => 'Right', + 18 => 'All', + 19 => 'Layout', + 20 => 'Add Widget', + 21 => 'Add Content Widget', + 22 => 'Attribute', + 23 => 'Widget Style', + 24 => 'Modify', + 25 => 'Delete', + 26 => 'Align', + 27 => 'Occupy a Line', + 28 => 'Left', + 29 => 'Right', + 30 => 'Width', + 31 => 'Height', + 32 => 'Margin', + 33 => 'Padding', + 34 => 'Top', + 35 => 'Left', + 36 => 'Right', + 37 => 'Bottom', + 38 => 'Border', + 39 => 'None', + 40 => 'Background', + 41 => 'Color', + 42 => 'Image', + 43 => 'Select', + 44 => 'Repeat Background', + 45 => 'Repeat', + 46 => 'No Repeat', + 47 => 'Repeat Width', + 48 => 'Repeat Height', + 49 => 'Apply', + 50 => 'Cancel', + 51 => 'Reset', + 52 => 'Text', + 53 => 'Font', + 54 => 'Font Color', + ); + + $lang->layout_image_repository = 'Layout Repository'; + $lang->about_layout_image_repository = 'You can upload images/flash files for selected layout. They will be included in exports'; + $lang->msg_layout_image_target = 'Only gif, png, jpg, swf, flv files are allowed'; + $lang->layout_migration = 'Layout Migration'; + $lang->about_layout_migration = 'You can export or import editted layout as tar file'."\n".'(So far only FaceOff supports exports/imports)'; + + $lang->about_faceoff = array( + 'title' => 'XpressEngine FaceOff Layout Manager', + 'description' => 'FaceOff Layout Manager willl help you design layout on the web easily.
Please design your own layout with components and functions as shown below.', + 'layout' => 'FaceOff has HTML structure as above.
You can arrange/align with CSS, or use Style to design.
You can add widget from Extension(e1, e2), Neck and Knee.
Also Body, Layout, Header, Body, Footer can designed by Style, and Content will display content.', + 'setting' => 'Let me explain you the upper menu on left.
  • Save : Save current settings.
  • Cancel : Discard current settings and go back.
  • Reset : Clear current settings
  • Form : Set form as Fixed/ Variable/ Fixed+Variable(Content).
  • Arrange : Arrange 2 Extensions and Content.
  • Align : Align the position of layout.
', + 'hotkey' => 'You can design your layout more easily with Hot Keys.
  • tab : Unless a widget is selected, Header, Body, Footer will be selected in order. If not, next widget will be selected.
  • Shift + tab : It does the opposite function to tab key.
  • Esc : If nothing is selected, Neck, Extension(e1,e2),Knee will be selected in order, if a widget is selected, area of the widget will be selected.
  • Arrow Key : If a widget is selected, arrow key will move the widget to other areas.
', + 'attribute' => 'You can set background color/image to every area except widget, and font color(include tag).', + + ); + + $lang->mobile_layout_list = "Mobile Layout List"; + $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; + $lang->apply_mobile_view = "Apply Mobile View"; + $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; +?> diff --git a/modules/layout/lang/es.lang.php b/modules/layout/lang/es.lang.php index 0e5b05e1a..5506de2ba 100644 --- a/modules/layout/lang/es.lang.php +++ b/modules/layout/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma español para el Diseño. **/ diff --git a/modules/layout/lang/fr.lang.php b/modules/layout/lang/fr.lang.php index d59025224..80db91721 100644 --- a/modules/layout/lang/fr.lang.php +++ b/modules/layout/lang/fr.lang.php @@ -1,116 +1,116 @@ - Traduit par Pierre Duvent - * @brief Paquet du langage en français pour le module de Mise en Page - **/ - - $lang->cmd_layout_management = 'Configuration du Mise en Page'; - $lang->cmd_layout_edit = 'Editer le Mise en Page'; - - $lang->layout_name = 'Nom du Mise en Page'; - $lang->layout_maker = "Développeur du Mise en Page"; - $lang->layout_license = 'Licence'; - $lang->layout_history = "Mise à Jour"; - $lang->layout_info = "Informations du Mise en Page"; - $lang->layout_list = 'Liste des Mises en Page'; - $lang->menu_count = 'Menus'; - $lang->downloaded_list = 'Liste disponibles'; - $lang->layout_preview_content = 'Le contenu sera exposé ici.'; - $lang->not_apply_menu = 'Appliquer le Mise en Page sur tous les menus'; - - $lang->cmd_move_to_installed_list = "Mises en Page créés"; - - $lang->about_downloaded_layouts = "Mises en Page téléchargés"; - $lang->about_title = 'Entrez le titre pour distinguer facilement quand vous le liez à un module.'; - $lang->about_not_apply_menu = 'Tous les Mises en Page qui sont liés sur le menu seront changés si vous cochez cette option.'; - - $lang->about_layout = "Le module de Mise en Page vous aide à créer facilement le Mise en Page du site.
Vous pouvez présentez la forme du site Web complété par les modules divers en utilisant la configuration du Mise en Page et la connexion sur le menu.
* Les Mises en Page qui ne sont pas possibles à supprimer ou à modifier sont propres à ceux des blogues ou d'autres Mises en Page. Essayez à modifier/supprimer en dedans elles-mêmes"; - $lang->about_layout_code = - "Vous conservez la code de Mise en Page après l'éditer, la code sera appliquée sur le service. - Utilisez [Avant-première] avant conserver la code S.V.P. - Vous pouvez référer la grammaire de modèle de XE sur
Modèle du XE."; - - $lang->layout_export = '내보내기'; - $lang->layout_btn_export = '내 레이아웃 다운로드'; - $lang->about_layout_export = '현재 수정된 레이아웃을 내보내기를 합니다.'; - $lang->layout_import = '가져오기'; - $lang->about_layout_import = '가져오기를 할 경우 기존 수정된 레이아웃을 삭제가 됩니다. 가져오기를 하기전에 내보내기를 통해 백업을 하시기 바랍니다.'; - $lang->layout_manager = array( - 0 => '레이아웃 매니저', - 1 => '저장', - 2 => '취소', - 3 => '형태', - 4 => '배열', - 5 => '정렬', - 6 => '고정 레이아웃', - 7 => '가변 레이아웃', - 8 => '고정+가변(내용)', - 9 => '1칸', - 10 => '2칸 (내용 왼쪽)', - 11 => '2칸 (내용 오른쪽)', - 12 => '3칸 (내용 왼쪽)', - 13 => '3칸 (내용 가운데)', - 14 => '3칸 (내용 오른쪽)', - 15 => '왼쪽', - 16 => '가운데', - 17 => '오른쪽', - 18 => '전체', - 19 => '레이아웃', - 20 => '위젯 추가', - 21 => '내용 위젯 추가', - 22 => '속성', - 23 => '위젯 스타일', - 24 => '수정', - 25 => '삭제', - 26 => '정렬', - 27 => '한줄 차지', - 28 => '왼쪽', - 29 => '오른쪽', - 30 => '가로 너비', - 31 => '높이', - 32 => '바깥 여백', - 33 => '안쪽 여백', - 34 => '위', - 35 => '왼', - 36 => '오른', - 37 => '아래', - 38 => '테두리', - 39 => '없음', - 40 => '배경', - 41 => '색상', - 42 => '그림', - 43 => '선택', - 44 => '배경 그림 반복', - 45 => '반복', - 46 => '반복 안함', - 47 => '가로 반복', - 48 => '세로 반복', - 49 => '적용', - 50 => '취소', - 51 => '초기화', - 52 => '글자', - 53 => '글자 폰트', - 54 => '글자 색', - ); - - $lang->layout_image_repository = '레이아웃 파일 저장소'; - $lang->about_layout_image_repository = '선택된 레이아웃에 사용될 이미지/플래시파일등을 올릴 수 있습니다. 내보내기에 같이 포함이 됩니다'; - $lang->msg_layout_image_target = 'gif, png, jpg, swf, flv파일만 가능합니다'; - $lang->layout_migration = '레이아웃 내보내기/ 들이기'; - $lang->about_layout_migration = '수정된 레이아웃을 tar 파일로 내보내거나 tar 파일로 저장된 것을 불러올 수 있습니다'."\n".'(아직은 faceOff레이아웃만 내보내기/들이기가 됩니다'; - - $lang->about_faceoff = array( - 'title' => 'XpressEngine FaceOff Layout 관리자', - 'description' => 'FaceOff Layout관리자는 웹상에서 쉽게 레이아웃을 꾸밀 수 있습니다.
아래 그림을 보시고 구성요소와 기능을 이용하여 원하시는 레이아웃을 만드세요', - 'layout' => 'FaceOff는 위와 같은 HTML 구조로 되어 있습니다.
이 구조에서 CSS를 이용하여 형태/배열/정렬을 할 수 있고 또 Style을 이용하여 꾸밀 수 있습니다.
위젯 추가는 Extension(e1, e2)와 Neck, Knee에서 가능합니다.
이 외 Body, Layout, Header, Body, Footer는 Style을 꾸밀 수 있고 Content는 모듈의 내용이 출력됩니다.', - 'setting' => '좌측 상단의 메뉴에 대해 설명 드립니다.
  • 저장 : 설정된 내용을 저장합니다.
  • 취소 : 설정한 내용을 저장하지 않고 돌아갑니다.
  • 초기화 : 아무 설정도 되어 있지 않은 백지 상태로 돌립니다
  • 형태 : 고정/ 가변/ 고정+가변(내용)의 형태를 지정합니다.
  • 배열 : Extension 2개와 Content를 배열합니다.
  • 정렬 : 레이아웃의 위치를 정렬시킬 수 있습니다.
', - 'hotkey' => '마우스로 각 영역을 선택하면서 Hot Key를 이용하시면 더 쉽게 꾸미실 수 있습니다.
  • tab 키 : 위젯이 선택되어 있지 않으면 Header, Body, Footer 순으로 선택됩니다. 위젯이 선택되어 있다면 다음 위젯으로 선택이 이동됩니다.
  • Shift + tab키 : tab키와 반대 역할을 합니다.
  • Esc : 아무것도 선택되어 있지 않을때 Esc를 누르면 Neck, Extension(e1,e2),Knee 순서대로 선택이 되며 위젯이 선택되어 있다면 선택된 위젯을 감싸는 영역이 선택됩니다.
  • 방향키 : 위젯이 선택되어 있을때 방향키를 이용하여 위젯을 다른 영역으로 이동시킬 수 있습니다.
', - 'attribute' => '위젯을 제외한 각 영역들은 모두 배경 색/ 이미지를 지정할 수 있고 글자색(a 태그 포함됨)을 정할 수 있습니다.', - - ); - $lang->mobile_layout_list = "Mobile Layout List"; - $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; - $lang->apply_mobile_view = "Apply Mobile View"; - $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; -?> + + * @brief Paquet du langage en français pour le module de Mise en Page + **/ + + $lang->cmd_layout_management = 'Configuration du Mise en Page'; + $lang->cmd_layout_edit = 'Editer le Mise en Page'; + + $lang->layout_name = 'Nom du Mise en Page'; + $lang->layout_maker = "Développeur du Mise en Page"; + $lang->layout_license = 'Licence'; + $lang->layout_history = "Mise à Jour"; + $lang->layout_info = "Informations du Mise en Page"; + $lang->layout_list = 'Liste des Mises en Page'; + $lang->menu_count = 'Menus'; + $lang->downloaded_list = 'Liste disponibles'; + $lang->layout_preview_content = 'Le contenu sera exposé ici.'; + $lang->not_apply_menu = 'Appliquer le Mise en Page sur tous les menus'; + + $lang->cmd_move_to_installed_list = "Mises en Page créés"; + + $lang->about_downloaded_layouts = "Mises en Page téléchargés"; + $lang->about_title = 'Entrez le titre pour distinguer facilement quand vous le liez à un module.'; + $lang->about_not_apply_menu = 'Tous les Mises en Page qui sont liés sur le menu seront changés si vous cochez cette option.'; + + $lang->about_layout = "Le module de Mise en Page vous aide à créer facilement le Mise en Page du site.
Vous pouvez présentez la forme du site Web complété par les modules divers en utilisant la configuration du Mise en Page et la connexion sur le menu.
* Les Mises en Page qui ne sont pas possibles à supprimer ou à modifier sont propres à ceux des blogues ou d'autres Mises en Page. Essayez à modifier/supprimer en dedans elles-mêmes"; + $lang->about_layout_code = + "Vous conservez la code de Mise en Page après l'éditer, la code sera appliquée sur le service. + Utilisez [Avant-première] avant conserver la code S.V.P. + Vous pouvez référer la grammaire de modèle de XE sur Modèle du XE."; + + $lang->layout_export = '내보내기'; + $lang->layout_btn_export = '내 레이아웃 다운로드'; + $lang->about_layout_export = '현재 수정된 레이아웃을 내보내기를 합니다.'; + $lang->layout_import = '가져오기'; + $lang->about_layout_import = '가져오기를 할 경우 기존 수정된 레이아웃을 삭제가 됩니다. 가져오기를 하기전에 내보내기를 통해 백업을 하시기 바랍니다.'; + $lang->layout_manager = array( + 0 => '레이아웃 매니저', + 1 => '저장', + 2 => '취소', + 3 => '형태', + 4 => '배열', + 5 => '정렬', + 6 => '고정 레이아웃', + 7 => '가변 레이아웃', + 8 => '고정+가변(내용)', + 9 => '1칸', + 10 => '2칸 (내용 왼쪽)', + 11 => '2칸 (내용 오른쪽)', + 12 => '3칸 (내용 왼쪽)', + 13 => '3칸 (내용 가운데)', + 14 => '3칸 (내용 오른쪽)', + 15 => '왼쪽', + 16 => '가운데', + 17 => '오른쪽', + 18 => '전체', + 19 => '레이아웃', + 20 => '위젯 추가', + 21 => '내용 위젯 추가', + 22 => '속성', + 23 => '위젯 스타일', + 24 => '수정', + 25 => '삭제', + 26 => '정렬', + 27 => '한줄 차지', + 28 => '왼쪽', + 29 => '오른쪽', + 30 => '가로 너비', + 31 => '높이', + 32 => '바깥 여백', + 33 => '안쪽 여백', + 34 => '위', + 35 => '왼', + 36 => '오른', + 37 => '아래', + 38 => '테두리', + 39 => '없음', + 40 => '배경', + 41 => '색상', + 42 => '그림', + 43 => '선택', + 44 => '배경 그림 반복', + 45 => '반복', + 46 => '반복 안함', + 47 => '가로 반복', + 48 => '세로 반복', + 49 => '적용', + 50 => '취소', + 51 => '초기화', + 52 => '글자', + 53 => '글자 폰트', + 54 => '글자 색', + ); + + $lang->layout_image_repository = '레이아웃 파일 저장소'; + $lang->about_layout_image_repository = '선택된 레이아웃에 사용될 이미지/플래시파일등을 올릴 수 있습니다. 내보내기에 같이 포함이 됩니다'; + $lang->msg_layout_image_target = 'gif, png, jpg, swf, flv파일만 가능합니다'; + $lang->layout_migration = '레이아웃 내보내기/ 들이기'; + $lang->about_layout_migration = '수정된 레이아웃을 tar 파일로 내보내거나 tar 파일로 저장된 것을 불러올 수 있습니다'."\n".'(아직은 faceOff레이아웃만 내보내기/들이기가 됩니다'; + + $lang->about_faceoff = array( + 'title' => 'XpressEngine FaceOff Layout 관리자', + 'description' => 'FaceOff Layout관리자는 웹상에서 쉽게 레이아웃을 꾸밀 수 있습니다.
아래 그림을 보시고 구성요소와 기능을 이용하여 원하시는 레이아웃을 만드세요', + 'layout' => 'FaceOff는 위와 같은 HTML 구조로 되어 있습니다.
이 구조에서 CSS를 이용하여 형태/배열/정렬을 할 수 있고 또 Style을 이용하여 꾸밀 수 있습니다.
위젯 추가는 Extension(e1, e2)와 Neck, Knee에서 가능합니다.
이 외 Body, Layout, Header, Body, Footer는 Style을 꾸밀 수 있고 Content는 모듈의 내용이 출력됩니다.', + 'setting' => '좌측 상단의 메뉴에 대해 설명 드립니다.
  • 저장 : 설정된 내용을 저장합니다.
  • 취소 : 설정한 내용을 저장하지 않고 돌아갑니다.
  • 초기화 : 아무 설정도 되어 있지 않은 백지 상태로 돌립니다
  • 형태 : 고정/ 가변/ 고정+가변(내용)의 형태를 지정합니다.
  • 배열 : Extension 2개와 Content를 배열합니다.
  • 정렬 : 레이아웃의 위치를 정렬시킬 수 있습니다.
', + 'hotkey' => '마우스로 각 영역을 선택하면서 Hot Key를 이용하시면 더 쉽게 꾸미실 수 있습니다.
  • tab 키 : 위젯이 선택되어 있지 않으면 Header, Body, Footer 순으로 선택됩니다. 위젯이 선택되어 있다면 다음 위젯으로 선택이 이동됩니다.
  • Shift + tab키 : tab키와 반대 역할을 합니다.
  • Esc : 아무것도 선택되어 있지 않을때 Esc를 누르면 Neck, Extension(e1,e2),Knee 순서대로 선택이 되며 위젯이 선택되어 있다면 선택된 위젯을 감싸는 영역이 선택됩니다.
  • 방향키 : 위젯이 선택되어 있을때 방향키를 이용하여 위젯을 다른 영역으로 이동시킬 수 있습니다.
', + 'attribute' => '위젯을 제외한 각 영역들은 모두 배경 색/ 이미지를 지정할 수 있고 글자색(a 태그 포함됨)을 정할 수 있습니다.', + + ); + $lang->mobile_layout_list = "Mobile Layout List"; + $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; + $lang->apply_mobile_view = "Apply Mobile View"; + $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; +?> diff --git a/modules/layout/lang/jp.lang.php b/modules/layout/lang/jp.lang.php index 9f2edf56d..c06a356c5 100644 --- a/modules/layout/lang/jp.lang.php +++ b/modules/layout/lang/jp.lang.php @@ -1,117 +1,117 @@ - 翻訳:RisaPapa、ミニミ - * @brief レイアウト(layout)モジュールの基本言語パッケージ - **/ - - $lang->cmd_layout_management = 'レイアウト設定'; - $lang->cmd_layout_edit = 'レイアウト編集'; - - $lang->layout_name = 'レイアウト名'; - $lang->layout_maker = 'レイアウト作者'; - $lang->layout_license = 'ライセンス'; - $lang->layout_history = '変更内容 '; - $lang->layout_info = 'レイアウト情報'; - $lang->layout_list = 'レイアウトリスト'; - $lang->menu_count = 'メニュー数'; - $lang->downloaded_list = 'ダウンロードリスト'; - $lang->layout_preview_content = '内容が出力される部分です。'; - $lang->not_apply_menu = 'レイアウトの一括適用'; - - $lang->cmd_move_to_installed_list = '作成されたリスト表示'; - - $lang->about_downloaded_layouts = 'ダウンロードのレイアウトリスト'; - $lang->about_title = 'モジュールとの連動をわかりやすく区分するためのタイトルを入力して下さい。'; - $lang->about_not_apply_menu = 'チェックを入れると連動するすべてのメニューのモジュールのレイアウトを一括変更します。'; - - $lang->about_layout = 'レイアウトのモジュールはサイトのレイアウトを分かりやすく作成出来るようにします。
レイアウトの設定とメニューのリンクで様々なモジュールで完成されたサイト構築が出来ます。
※ ブログまたは他のモジュールのレイアウトなどの削除・修正が出来ないレイアウトは、該当モジュールにて設定を行って下さい。'; - $lang->about_layout_code = - "下のレイアウトコードを修正し、保存するとサービスに反映されます。 - 必ずプレビューで確認してから保存して下さい。 - XEのテンプレート文法はXEテンプレートを参考して下さい。"; - - $lang->layout_export = 'エクスポート'; - $lang->layout_btn_export = 'マイレイアウトをダウンロードする'; - $lang->about_layout_export = 'カスタマイズした自分のレイアウトをエクスポートします。'; - $lang->layout_import = 'インポート'; - $lang->about_layout_import = 'インポートする場合、既存の修正されたレイアウトを上書きします。インポート前にエクスポートでバックアップすることをお勧めします。'; - - $lang->layout_manager = array( - 0 => 'レイアウトマネジャー', - 1 => '保存', - 2 => '取り消し', - 3 => '基本レイアウト', - 4 => '配列', - 5 => '整列', - 6 => '固定型レイアウト', - 7 => '可変型レイアウト', - 8 => '固定+(内容部分)可変', - 9 => '1段', - 10 => '2段 (内容左側配置)', - 11 => '2段 (内容右側配置)', - 12 => '3段 (内容左側配置)', - 13 => '3段 (内容中央配置)', - 14 => '3段 (内容右側配置)', - 15 => '左', - 16 => '中央', - 17 => '右', - 18 => 'すべて', - 19 => 'レイアウト', - 20 => 'ウィジェット追加', - 21 => '内容 ウィジェット追加', - 22 => '属性', - 23 => 'ウィジェットスタイル', - 24 => '修正', - 25 => '削除', - 26 => '整列', - 27 => '一行占め', - 28 => '左', - 29 => '右', - 30 => '横幅サイズ', - 31 => '高さ', - 32 => '外側余白', - 33 => '内側余白', - 34 => '上', - 35 => '左', - 36 => '右', - 37 => '下', - 38 => 'ボーダー', - 39 => 'なし', - 40 => '背景', - 41 => '色', - 42 => '画像', - 43 => '選択', - 44 => '背景画像リピート', - 45 => 'リピート', - 46 => 'リピートしない', - 47 => '横方向リピート', - 48 => '縦方向リピート', - 49 => '適用', - 50 => '取り消し', - 51 => '初期化', - 52 => '文字', - 53 => '文字フォント', - 54 => 'テキストの色', - ); - - $lang->layout_image_repository = 'レイアウトファイル保存場所'; - $lang->about_layout_image_repository = '選択したレイアウトに使う画像・Flashファイル等のアップロード出来ます。また、エクスポートする際、一緒に含まれます。'; - $lang->msg_layout_image_target = 'gif, png, jpg, swf, flvファイルのみ可能です。'; - $lang->layout_migration = 'レイアウトのエクスポート/インポート'; - $lang->about_layout_migration = '修正したレイアウトをtar形式の圧縮ファイルにエクスポートしたり、tar形式として保存されたファイルをインポートすることが出来ます。'."\n".'(まだ、faceOffレイアウトのみエクスポート/インポートが可能です。)'; - - $lang->about_faceoff = array( - 'title' => 'XpressEngine FaceOff レイアウト管理ツール', - 'description' => 'FaceOffレイアウト管理ツールはウェブ上で、手軽なレイアウト変更を可能にします。
下の図を参照しながら構成要素と機能を理解し、自由にレイアウトをカスタマイズしてみて下さい。', - 'layout' => 'FaceOffは上のようなHTML構造になっています。
この構造にてCSSを用いた「レイアウト/配列/整列」の調整が可能になり、さらにStyleを使った自由なカスタマイズが出来ます。
ウィジェットの追加はExtension(e1、e2)と Neck、 Kneeにて可能です。
その他にもBody、Layout、Header、Body、FooterはStyleをカスタマイズが出来、Contentではモジュールの内容が出力されます。', - 'setting' => '左側上段のメニューの説明
  • 保存 : 設定内容を保存します。
  • 取り消し : 設定内容を保存せずに、差し戻します。
  • 初期化 : 何の設定もない白紙状態(もしくはインストール時のデフォールト状態)に戻ります。
  • レイアウトタイプ : 固定/可変/固定+可変(内容)型のレイアウトを指定します。
  • 配列 : Body部分に2つのExtensionとContentを配列します。
  • 整列 : レイアウトの位置を整列します。
', - 'hotkey' => 'マウスを使って各スペースを選択しながら、Hot Keyを利用すると、より便利なカスタマイズ出来ます。
  • tabキー : ウィジェットが選択されてない場合、Header、Body、 Footer順に選択されます。ウィジェットが選択されている場合は、次のウィジェットに選択されます。
  • Shift + tabキー : tabキーと逆の役割をします。
  • Esc : 何も選択されてない場合、Escを押すとNeck、Extension(e1、e2)、Knee順に選択され、また、ウィジェットが選択されている場合は選択されたウィジェットを囲む領域が選択されます。
  • 矢印 : ウィジェットが選択されている時、矢印キーを用いて、ウィジェットを他の領域に移せます。
', - 'attribute' => 'ウィジェットを除いた各領域はすべて背景の色・イメージ・文字のテキスト色(「a」タグを含む)の指定が可能です。', - - ); - $lang->mobile_layout_list = "Mobile Layout List"; - $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; - $lang->apply_mobile_view = "Apply Mobile View"; - $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; -?> +cmd_layout_management = 'レイアウト設定'; + $lang->cmd_layout_edit = 'レイアウト編集'; + + $lang->layout_name = 'レイアウト名'; + $lang->layout_maker = 'レイアウト作者'; + $lang->layout_license = 'ライセンス'; + $lang->layout_history = '変更内容 '; + $lang->layout_info = 'レイアウト情報'; + $lang->layout_list = 'レイアウトリスト'; + $lang->menu_count = 'メニュー数'; + $lang->downloaded_list = 'ダウンロードリスト'; + $lang->layout_preview_content = '内容が出力される部分です。'; + $lang->not_apply_menu = 'レイアウトの一括適用'; + + $lang->cmd_move_to_installed_list = '作成されたリスト表示'; + + $lang->about_downloaded_layouts = 'ダウンロードのレイアウトリスト'; + $lang->about_title = 'モジュールとの連動をわかりやすく区分するためのタイトルを入力して下さい。'; + $lang->about_not_apply_menu = 'チェックを入れると連動するすべてのメニューのモジュールのレイアウトを一括変更します。'; + + $lang->about_layout = 'レイアウトのモジュールはサイトのレイアウトを分かりやすく作成出来るようにします。
レイアウトの設定とメニューのリンクで様々なモジュールで完成されたサイト構築が出来ます。
※ ブログまたは他のモジュールのレイアウトなどの削除・修正が出来ないレイアウトは、該当モジュールにて設定を行って下さい。'; + $lang->about_layout_code = + "下のレイアウトコードを修正し、保存するとサービスに反映されます。 + 必ずプレビューで確認してから保存して下さい。 + XEのテンプレート文法はXEテンプレートを参考して下さい。"; + + $lang->layout_export = 'エクスポート'; + $lang->layout_btn_export = 'マイレイアウトをダウンロードする'; + $lang->about_layout_export = 'カスタマイズした自分のレイアウトをエクスポートします。'; + $lang->layout_import = 'インポート'; + $lang->about_layout_import = 'インポートする場合、既存の修正されたレイアウトを上書きします。インポート前にエクスポートでバックアップすることをお勧めします。'; + + $lang->layout_manager = array( + 0 => 'レイアウトマネジャー', + 1 => '保存', + 2 => '取り消し', + 3 => '基本レイアウト', + 4 => '配列', + 5 => '整列', + 6 => '固定型レイアウト', + 7 => '可変型レイアウト', + 8 => '固定+(内容部分)可変', + 9 => '1段', + 10 => '2段 (内容左側配置)', + 11 => '2段 (内容右側配置)', + 12 => '3段 (内容左側配置)', + 13 => '3段 (内容中央配置)', + 14 => '3段 (内容右側配置)', + 15 => '左', + 16 => '中央', + 17 => '右', + 18 => 'すべて', + 19 => 'レイアウト', + 20 => 'ウィジェット追加', + 21 => '内容 ウィジェット追加', + 22 => '属性', + 23 => 'ウィジェットスタイル', + 24 => '修正', + 25 => '削除', + 26 => '整列', + 27 => '一行占め', + 28 => '左', + 29 => '右', + 30 => '横幅サイズ', + 31 => '高さ', + 32 => '外側余白', + 33 => '内側余白', + 34 => '上', + 35 => '左', + 36 => '右', + 37 => '下', + 38 => 'ボーダー', + 39 => 'なし', + 40 => '背景', + 41 => '色', + 42 => '画像', + 43 => '選択', + 44 => '背景画像リピート', + 45 => 'リピート', + 46 => 'リピートしない', + 47 => '横方向リピート', + 48 => '縦方向リピート', + 49 => '適用', + 50 => '取り消し', + 51 => '初期化', + 52 => '文字', + 53 => '文字フォント', + 54 => 'テキストの色', + ); + + $lang->layout_image_repository = 'レイアウトファイル保存場所'; + $lang->about_layout_image_repository = '選択したレイアウトに使う画像・Flashファイル等のアップロード出来ます。また、エクスポートする際、一緒に含まれます。'; + $lang->msg_layout_image_target = 'gif, png, jpg, swf, flvファイルのみ可能です。'; + $lang->layout_migration = 'レイアウトのエクスポート/インポート'; + $lang->about_layout_migration = '修正したレイアウトをtar形式の圧縮ファイルにエクスポートしたり、tar形式として保存されたファイルをインポートすることが出来ます。'."\n".'(まだ、faceOffレイアウトのみエクスポート/インポートが可能です。)'; + + $lang->about_faceoff = array( + 'title' => 'XpressEngine FaceOff レイアウト管理ツール', + 'description' => 'FaceOffレイアウト管理ツールはウェブ上で、手軽なレイアウト変更を可能にします。
下の図を参照しながら構成要素と機能を理解し、自由にレイアウトをカスタマイズしてみて下さい。', + 'layout' => 'FaceOffは上のようなHTML構造になっています。
この構造にてCSSを用いた「レイアウト/配列/整列」の調整が可能になり、さらにStyleを使った自由なカスタマイズが出来ます。
ウィジェットの追加はExtension(e1、e2)と Neck、 Kneeにて可能です。
その他にもBody、Layout、Header、Body、FooterはStyleをカスタマイズが出来、Contentではモジュールの内容が出力されます。', + 'setting' => '左側上段のメニューの説明
  • 保存 : 設定内容を保存します。
  • 取り消し : 設定内容を保存せずに、差し戻します。
  • 初期化 : 何の設定もない白紙状態(もしくはインストール時のデフォールト状態)に戻ります。
  • レイアウトタイプ : 固定/可変/固定+可変(内容)型のレイアウトを指定します。
  • 配列 : Body部分に2つのExtensionとContentを配列します。
  • 整列 : レイアウトの位置を整列します。
', + 'hotkey' => 'マウスを使って各スペースを選択しながら、Hot Keyを利用すると、より便利なカスタマイズ出来ます。
  • tabキー : ウィジェットが選択されてない場合、Header、Body、 Footer順に選択されます。ウィジェットが選択されている場合は、次のウィジェットに選択されます。
  • Shift + tabキー : tabキーと逆の役割をします。
  • Esc : 何も選択されてない場合、Escを押すとNeck、Extension(e1、e2)、Knee順に選択され、また、ウィジェットが選択されている場合は選択されたウィジェットを囲む領域が選択されます。
  • 矢印 : ウィジェットが選択されている時、矢印キーを用いて、ウィジェットを他の領域に移せます。
', + 'attribute' => 'ウィジェットを除いた各領域はすべて背景の色・イメージ・文字のテキスト色(「a」タグを含む)の指定が可能です。', + + ); + $lang->mobile_layout_list = "Mobile Layout List"; + $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; + $lang->apply_mobile_view = "Apply Mobile View"; + $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; +?> diff --git a/modules/layout/lang/ko.lang.php b/modules/layout/lang/ko.lang.php index bc21a77d4..0919c5369 100644 --- a/modules/layout/lang/ko.lang.php +++ b/modules/layout/lang/ko.lang.php @@ -1,119 +1,119 @@ - - * @brief 레이아웃(layout) 모듈의 기본 언어팩 - **/ - - $lang->cmd_layout_management = '레이아웃 설정'; - $lang->cmd_layout_edit = '레이아웃 편집'; - - $lang->layout_name = '레이아웃 이름'; - $lang->layout_maker = '레이아웃 제작자'; - $lang->layout_license = '라이선스'; - $lang->layout_history = '변경 이력'; - $lang->layout_info = '레이아웃 정보'; - $lang->layout_list = '레이아웃 목록'; - $lang->menu_count = '메뉴 수'; - $lang->downloaded_list = '다운로드 목록'; - $lang->layout_preview_content = '내용이 출력되는 부분입니다.'; - $lang->not_apply_menu = '레이아웃 일괄 적용'; - - $lang->cmd_move_to_installed_list = '생성된 목록 보기'; - - $lang->about_downloaded_layouts = '다운로드 되어 있는 레이아웃 목록'; - $lang->about_title = '모듈에 연결시 쉽게 구분할 수 있는 제목을 입력해주세요.'; - $lang->about_not_apply_menu = '체크 하시면 연결된 모든 메뉴의 모듈 레이아웃을 일괄 변경합니다.'; - - $lang->about_layout = '레이아웃 모듈은 사이트의 레이아웃을 쉽게 만들 수 있도록 도와줍니다.
레이아웃 설정과 메뉴의 연결을 통해서 다양한 모듈이 완성된 사이트의 모습으로 보여줄 수 있도록 합니다.
* 삭제나 수정이 불가능한 레이아웃은 블로그나 기타 모듈의 자체 레이아웃이므로 해당 모듈로 가서 설정하셔야 합니다.'; - $lang->about_layout_code = - "아래 레이아웃의 코드를 직접 수정 후 저장하시면 서비스에 반영이 됩니다. - 꼭 미리보기를 하신 후에 저장을 하세요. - XE의 템플릿 문법은 XE 템플릿 을 참고하시면 됩니다."; - - $lang->layout_export = '내보내기'; - $lang->layout_btn_export = '내 레이아웃 다운로드'; - $lang->about_layout_export = '현재 수정된 레이아웃을 내보내기를 합니다.'; - $lang->layout_import = '가져오기'; - $lang->about_layout_import = '가져오기를 할 경우 기존에 수정된 레이아웃은 삭제됩니다. 가져오기를 하기 전에 내보내기를 통해 백업을 하시기 바랍니다.'; - - $lang->layout_manager = array( - 0 => '레이아웃 매니저', - 1 => '저장', - 2 => '취소', - 3 => '형태', - 4 => '배열', - 5 => '정렬', - 6 => '고정 레이아웃', - 7 => '가변 레이아웃', - 8 => '고정+가변(내용)', - 9 => '1칸', - 10 => '2칸 (내용 왼쪽)', - 11 => '2칸 (내용 오른쪽)', - 12 => '3칸 (내용 왼쪽)', - 13 => '3칸 (내용 가운데)', - 14 => '3칸 (내용 오른쪽)', - 15 => '왼쪽', - 16 => '가운데', - 17 => '오른쪽', - 18 => '전체', - 19 => '레이아웃', - 20 => '위젯 추가', - 21 => '내용 위젯 추가', - 22 => '속성', - 23 => '위젯 스타일', - 24 => '수정', - 25 => '삭제', - 26 => '정렬', - 27 => '한줄 차지', - 28 => '왼쪽', - 29 => '오른쪽', - 30 => '가로', - 31 => '세로', - 32 => '바깥 여백', - 33 => '안쪽 여백', - 34 => '위', - 35 => '왼', - 36 => '오른', - 37 => '아래', - 38 => '테두리', - 39 => '없음', - 40 => '배경', - 41 => '색상', - 42 => '그림', - 43 => '선택', - 44 => '배경 그림 반복', - 45 => '반복', - 46 => '반복 안함', - 47 => '가로 반복', - 48 => '세로 반복', - 49 => '적용', - 50 => '취소', - 51 => '초기화', - 52 => '글자', - 53 => '글자 폰트', - 54 => '글자 색', - ); - - $lang->layout_image_repository = '레이아웃 파일 저장소'; - $lang->about_layout_image_repository = '선택된 레이아웃에 사용될 이미지/플래시파일 등을 올릴 수 있습니다. 내보내기에 같이 포함 됩니다.'; - $lang->msg_layout_image_target = 'gif, png, jpg, swf, flv파일만 가능합니다.'; - $lang->layout_migration = '레이아웃 내보내기/들이기'; - $lang->about_layout_migration = '수정된 레이아웃을 tar 파일로 내보내거나 tar 파일로 저장된 것을 불러올 수 있습니다'."\n".'(아직은 faceOff레이아웃만 내보내기/들이기가 됩니다.)'; - - $lang->about_faceoff = array( - 'title' => 'XpressEngine FaceOff Layout 관리자', - 'description' => 'FaceOff Layout관리자로 웹상에서 쉽게 레이아웃을 꾸밀 수 있습니다.
아래 그림을 보시고 구성요소와 기능을 이용하여 원하시는 레이아웃을 만드세요.', - 'layout' => 'FaceOff는 위와 같은 HTML 구조로 되어 있습니다.
이 구조에서 CSS를 이용하여 형태/배열/정렬을 할 수 있고 또 Style을 이용하여 꾸밀 수 있습니다.
위젯 추가는 Extension(e1, e2)과 Neck, Knee에서 가능합니다.
이 외 Body, Layout, Header, Body, Footer는 Style을 꾸밀 수 있고 Content는 모듈의 내용이 출력됩니다.', - 'setting' => '좌측 상단의 메뉴에 대해 설명 드립니다.
  • 저장 : 설정된 내용을 저장합니다.
  • 취소 : 설정한 내용을 저장하지 않고 돌아갑니다.
  • 초기화 : 아무 설정도 되어 있지 않은 백지 상태로 돌립니다.
  • 형태 : 고정/ 가변/ 고정+가변(내용)의 형태를 지정합니다.
  • 배열 : Extension 2개와 Content를 배열합니다.
  • 정렬 : 레이아웃의 위치를 정렬시킬 수 있습니다.
', - 'hotkey' => '마우스로 각 영역을 선택하면서 Hot Key를 이용하시면 더 쉽게 꾸미실 수 있습니다.
  • tab 키 : 위젯이 선택되어 있지 않으면 Header, Body, Footer 순으로 선택됩니다. 위젯이 선택되어 있다면 다음 위젯으로 선택이 이동됩니다.
  • Shift + tab키 : tab키와 반대 역할을 합니다.
  • Esc : 아무것도 선택되어 있지 않을 때 Esc를 누르면 Neck, Extension(e1,e2),Knee 순서대로 선택이 되며 위젯이 선택되어 있다면 선택된 위젯을 감싸는 영역이 선택됩니다.
  • 방향키 : 위젯이 선택되어 있을 때 방향키를 이용하여 위젯을 다른 영역으로 이동시킬 수 있습니다.
', - 'attribute' => '위젯을 제외한 각 영역들은 모두 배경 색/ 이미지를 지정할 수 있고 글자색(a 태그 포함됨)을 정할 수 있습니다.', - - ); - - $lang->mobile_layout_list = "모바일 레이아웃 목록"; - $lang->mobile_downloaded_list = "모바일 다운로드 목록"; - $lang->apply_mobile_view = "모바일 뷰 일괄 적용"; - $lang->about_apply_mobile_view = "체크하시면 연결된 모든 메뉴에서 모바일 뷰를 사용합니다."; - -?> +cmd_layout_management = '레이아웃 설정'; + $lang->cmd_layout_edit = '레이아웃 편집'; + + $lang->layout_name = '레이아웃 이름'; + $lang->layout_maker = '레이아웃 제작자'; + $lang->layout_license = '라이선스'; + $lang->layout_history = '변경 이력'; + $lang->layout_info = '레이아웃 정보'; + $lang->layout_list = '레이아웃 목록'; + $lang->menu_count = '메뉴 수'; + $lang->downloaded_list = '다운로드 목록'; + $lang->layout_preview_content = '내용이 출력되는 부분입니다.'; + $lang->not_apply_menu = '레이아웃 일괄 적용'; + + $lang->cmd_move_to_installed_list = '생성된 목록 보기'; + + $lang->about_downloaded_layouts = '다운로드 되어 있는 레이아웃 목록'; + $lang->about_title = '모듈에 연결시 쉽게 구분할 수 있는 제목을 입력해주세요.'; + $lang->about_not_apply_menu = '체크 하시면 연결된 모든 메뉴의 모듈 레이아웃을 일괄 변경합니다.'; + + $lang->about_layout = '레이아웃 모듈은 사이트의 레이아웃을 쉽게 만들 수 있도록 도와줍니다.
레이아웃 설정과 메뉴의 연결을 통해서 다양한 모듈이 완성된 사이트의 모습으로 보여줄 수 있도록 합니다.
* 삭제나 수정이 불가능한 레이아웃은 블로그나 기타 모듈의 자체 레이아웃이므로 해당 모듈로 가서 설정하셔야 합니다.'; + $lang->about_layout_code = + "아래 레이아웃의 코드를 직접 수정 후 저장하시면 서비스에 반영이 됩니다. + 꼭 미리보기를 하신 후에 저장을 하세요. + XE의 템플릿 문법은 XE 템플릿 을 참고하시면 됩니다."; + + $lang->layout_export = '내보내기'; + $lang->layout_btn_export = '내 레이아웃 다운로드'; + $lang->about_layout_export = '현재 수정된 레이아웃을 내보내기를 합니다.'; + $lang->layout_import = '가져오기'; + $lang->about_layout_import = '가져오기를 할 경우 기존에 수정된 레이아웃은 삭제됩니다. 가져오기를 하기 전에 내보내기를 통해 백업을 하시기 바랍니다.'; + + $lang->layout_manager = array( + 0 => '레이아웃 매니저', + 1 => '저장', + 2 => '취소', + 3 => '형태', + 4 => '배열', + 5 => '정렬', + 6 => '고정 레이아웃', + 7 => '가변 레이아웃', + 8 => '고정+가변(내용)', + 9 => '1칸', + 10 => '2칸 (내용 왼쪽)', + 11 => '2칸 (내용 오른쪽)', + 12 => '3칸 (내용 왼쪽)', + 13 => '3칸 (내용 가운데)', + 14 => '3칸 (내용 오른쪽)', + 15 => '왼쪽', + 16 => '가운데', + 17 => '오른쪽', + 18 => '전체', + 19 => '레이아웃', + 20 => '위젯 추가', + 21 => '내용 위젯 추가', + 22 => '속성', + 23 => '위젯 스타일', + 24 => '수정', + 25 => '삭제', + 26 => '정렬', + 27 => '한줄 차지', + 28 => '왼쪽', + 29 => '오른쪽', + 30 => '가로', + 31 => '세로', + 32 => '바깥 여백', + 33 => '안쪽 여백', + 34 => '위', + 35 => '왼', + 36 => '오른', + 37 => '아래', + 38 => '테두리', + 39 => '없음', + 40 => '배경', + 41 => '색상', + 42 => '그림', + 43 => '선택', + 44 => '배경 그림 반복', + 45 => '반복', + 46 => '반복 안함', + 47 => '가로 반복', + 48 => '세로 반복', + 49 => '적용', + 50 => '취소', + 51 => '초기화', + 52 => '글자', + 53 => '글자 폰트', + 54 => '글자 색', + ); + + $lang->layout_image_repository = '레이아웃 파일 저장소'; + $lang->about_layout_image_repository = '선택된 레이아웃에 사용될 이미지/플래시파일 등을 올릴 수 있습니다. 내보내기에 같이 포함 됩니다.'; + $lang->msg_layout_image_target = 'gif, png, jpg, swf, flv파일만 가능합니다.'; + $lang->layout_migration = '레이아웃 내보내기/들이기'; + $lang->about_layout_migration = '수정된 레이아웃을 tar 파일로 내보내거나 tar 파일로 저장된 것을 불러올 수 있습니다'."\n".'(아직은 faceOff레이아웃만 내보내기/들이기가 됩니다.)'; + + $lang->about_faceoff = array( + 'title' => 'XpressEngine FaceOff Layout 관리자', + 'description' => 'FaceOff Layout관리자로 웹상에서 쉽게 레이아웃을 꾸밀 수 있습니다.
아래 그림을 보시고 구성요소와 기능을 이용하여 원하시는 레이아웃을 만드세요.', + 'layout' => 'FaceOff는 위와 같은 HTML 구조로 되어 있습니다.
이 구조에서 CSS를 이용하여 형태/배열/정렬을 할 수 있고 또 Style을 이용하여 꾸밀 수 있습니다.
위젯 추가는 Extension(e1, e2)과 Neck, Knee에서 가능합니다.
이 외 Body, Layout, Header, Body, Footer는 Style을 꾸밀 수 있고 Content는 모듈의 내용이 출력됩니다.', + 'setting' => '좌측 상단의 메뉴에 대해 설명 드립니다.
  • 저장 : 설정된 내용을 저장합니다.
  • 취소 : 설정한 내용을 저장하지 않고 돌아갑니다.
  • 초기화 : 아무 설정도 되어 있지 않은 백지 상태로 돌립니다.
  • 형태 : 고정/ 가변/ 고정+가변(내용)의 형태를 지정합니다.
  • 배열 : Extension 2개와 Content를 배열합니다.
  • 정렬 : 레이아웃의 위치를 정렬시킬 수 있습니다.
', + 'hotkey' => '마우스로 각 영역을 선택하면서 Hot Key를 이용하시면 더 쉽게 꾸미실 수 있습니다.
  • tab 키 : 위젯이 선택되어 있지 않으면 Header, Body, Footer 순으로 선택됩니다. 위젯이 선택되어 있다면 다음 위젯으로 선택이 이동됩니다.
  • Shift + tab키 : tab키와 반대 역할을 합니다.
  • Esc : 아무것도 선택되어 있지 않을 때 Esc를 누르면 Neck, Extension(e1,e2),Knee 순서대로 선택이 되며 위젯이 선택되어 있다면 선택된 위젯을 감싸는 영역이 선택됩니다.
  • 방향키 : 위젯이 선택되어 있을 때 방향키를 이용하여 위젯을 다른 영역으로 이동시킬 수 있습니다.
', + 'attribute' => '위젯을 제외한 각 영역들은 모두 배경 색/ 이미지를 지정할 수 있고 글자색(a 태그 포함됨)을 정할 수 있습니다.', + + ); + + $lang->mobile_layout_list = "모바일 레이아웃 목록"; + $lang->mobile_downloaded_list = "모바일 다운로드 목록"; + $lang->apply_mobile_view = "모바일 뷰 일괄 적용"; + $lang->about_apply_mobile_view = "체크하시면 연결된 모든 메뉴에서 모바일 뷰를 사용합니다."; + +?> diff --git a/modules/layout/lang/ru.lang.php b/modules/layout/lang/ru.lang.php index a0e1d2133..be930efc6 100644 --- a/modules/layout/lang/ru.lang.php +++ b/modules/layout/lang/ru.lang.php @@ -1,117 +1,117 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->cmd_layout_management = 'Настройки лейаута'; - $lang->cmd_layout_edit = 'Редактировать лейаут'; - - $lang->layout_name = 'Имя лейаута'; - $lang->layout_maker = "Разработчик лейаута"; - $lang->layout_license = 'License'; - $lang->layout_history = "Обновления"; - $lang->layout_info = "Информация лейаута"; - $lang->layout_list = 'Список лейаутов'; - $lang->menu_count = 'Меню'; - $lang->downloaded_list = 'Список закачек'; - $lang->layout_preview_content = 'Содержимое отображается здесь'; - $lang->not_apply_menu = 'Применить лейауты'; - - $lang->cmd_move_to_installed_list = "Просмотреть созданный список"; - - $lang->about_downloaded_layouts = "Список скаченных лейаутов"; - $lang->about_title = 'Пожалуйста, введите название, которое легко проверить при подключении к модулю'; - $lang->about_not_apply_menu = 'Все подключенные лейауты модулей будут изменены при включении это опции.'; - - $lang->about_layout = "Модуль лейаутов помогает Вам создать лейаут сайта с легкостью.
Используя настройки лейаута и подключение меню, полная форма сайта будет отображена множеством модулей.
* Теми лейаутами, которые невозможно удалить или изменить, являются лейауты блога и лейауты других модулей."; - $lang->about_layout_code = - "Применения к службе будут проиведены, когда Вы сохраните код лейаут после редактирование. - Пожалуйста, сначала используйте предпросмотр кода и затем сохраните его. - Вы можете обратиться к грамматике шаблонов XE с XE Template."; - - $lang->layout_export = 'Export'; - $lang->layout_btn_export = 'Download My Layout'; - $lang->about_layout_export = 'Export currently editted layout.'; - $lang->layout_import = 'Import'; - $lang->about_layout_import = 'Original layout will be deleted when you import. Please export current layout before importing.'; - - $lang->layout_manager = array( - 0 => 'Layout Manager', - 1 => 'Save', - 2 => 'Cancel', - 3 => 'Form', - 4 => 'Array', - 5 => 'Arrange', - 6 => 'Fixed Layout', - 7 => 'Variable Layout', - 8 => 'Fixed+Variable (Content)', - 9 => '1 Cell', - 10 => '2 Cells (left of content)', - 11 => '2 Cells (right of content)', - 12 => '3 Cells (left of content)', - 13 => '3 Cells (center of content)', - 14 => '3 Cells (right of content)', - 15 => 'Left', - 16 => 'Center', - 17 => 'Right', - 18 => 'All', - 19 => 'Layout', - 20 => 'Add Widget', - 21 => 'Add Content Widget', - 22 => 'Attribute', - 23 => 'Widget Style', - 24 => 'Modify', - 25 => 'Delete', - 26 => 'Align', - 27 => 'Occupy a Line', - 28 => 'Left', - 29 => 'Right', - 30 => 'Width', - 31 => 'Height', - 32 => 'Margin', - 33 => 'Padding', - 34 => 'Top', - 35 => 'Left', - 36 => 'Right', - 37 => 'Bottom', - 38 => 'Border', - 39 => 'None', - 40 => 'Background', - 41 => 'Color', - 42 => 'Image', - 43 => 'Select', - 44 => 'Repeat Background', - 45 => 'Repeat', - 46 => 'No Repeat', - 47 => 'Repeat Width', - 48 => 'Repeat Height', - 49 => 'Apply', - 50 => 'Cancel', - 51 => 'Reset', - 52 => 'Text', - 53 => 'Font', - 54 => 'Font Color', - ); - - $lang->layout_image_repository = 'Layout Repository'; - $lang->about_layout_image_repository = 'You can upload images/flash files for selected layout. They will be included in exports'; - $lang->msg_layout_image_target = 'Only gif, png, jpg, swf, flv files are allowed'; - $lang->layout_migration = 'Layout Migration'; - $lang->about_layout_migration = 'You can export or import editted layout as tar file'."\n".'(So far only FaceOff supports exports/imports)'; - - $lang->about_faceoff = array( - 'title' => 'XpressEngine FaceOff Layout Manager', - 'description' => 'FaceOff Layout Manager willl help you design layout on the web easily.
Please design your own layout with components and functions as shown below.', - 'layout' => 'FaceOff has HTML structure as above.
You can arrange/align with CSS, or use Style to design.
You can add widget from Extension(e1, e2), Neck and Knee.
Also Body, Layout, Header, Body, Footer can designed by Style, and Content will display content.', - 'setting' => 'Let me explain you the upper menu on left.
  • Save : Save current settings.
  • Cancel : Discard current settings and go back.
  • Reset : Clear current settings
  • Form : Set form as Fixed/ Variable/ Fixed+Variable(Content).
  • Arrange : Arrange 2 Extensions and Content.
  • Align : Align the position of layout.
', - 'hotkey' => 'You can design your layout more easily with Hot Keys.
  • tab : Unless a widget is selected, Header, Body, Footer will be selected in order. If not, next widget will be selected.
  • Shift + tab : It does the opposite function to tab key.
  • Esc : If nothing is selected, Neck, Extension(e1,e2),Knee will be selected in order, if a widget is selected, area of the widget will be selected.
  • Arrow Key : If a widget is selected, arrow key will move the widget to other areas.
', - 'attribute' => 'You can set background color/image to every area except widget, and font color(include tag).', - - ); - $lang->mobile_layout_list = "Mobile Layout List"; - $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; - $lang->apply_mobile_view = "Apply Mobile View"; - $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; -?> +cmd_layout_management = 'Настройки лейаута'; + $lang->cmd_layout_edit = 'Редактировать лейаут'; + + $lang->layout_name = 'Имя лейаута'; + $lang->layout_maker = "Разработчик лейаута"; + $lang->layout_license = 'License'; + $lang->layout_history = "Обновления"; + $lang->layout_info = "Информация лейаута"; + $lang->layout_list = 'Список лейаутов'; + $lang->menu_count = 'Меню'; + $lang->downloaded_list = 'Список закачек'; + $lang->layout_preview_content = 'Содержимое отображается здесь'; + $lang->not_apply_menu = 'Применить лейауты'; + + $lang->cmd_move_to_installed_list = "Просмотреть созданный список"; + + $lang->about_downloaded_layouts = "Список скаченных лейаутов"; + $lang->about_title = 'Пожалуйста, введите название, которое легко проверить при подключении к модулю'; + $lang->about_not_apply_menu = 'Все подключенные лейауты модулей будут изменены при включении это опции.'; + + $lang->about_layout = "Модуль лейаутов помогает Вам создать лейаут сайта с легкостью.
Используя настройки лейаута и подключение меню, полная форма сайта будет отображена множеством модулей.
* Теми лейаутами, которые невозможно удалить или изменить, являются лейауты блога и лейауты других модулей."; + $lang->about_layout_code = + "Применения к службе будут проиведены, когда Вы сохраните код лейаут после редактирование. + Пожалуйста, сначала используйте предпросмотр кода и затем сохраните его. + Вы можете обратиться к грамматике шаблонов XE с
XE Template."; + + $lang->layout_export = 'Export'; + $lang->layout_btn_export = 'Download My Layout'; + $lang->about_layout_export = 'Export currently editted layout.'; + $lang->layout_import = 'Import'; + $lang->about_layout_import = 'Original layout will be deleted when you import. Please export current layout before importing.'; + + $lang->layout_manager = array( + 0 => 'Layout Manager', + 1 => 'Save', + 2 => 'Cancel', + 3 => 'Form', + 4 => 'Array', + 5 => 'Arrange', + 6 => 'Fixed Layout', + 7 => 'Variable Layout', + 8 => 'Fixed+Variable (Content)', + 9 => '1 Cell', + 10 => '2 Cells (left of content)', + 11 => '2 Cells (right of content)', + 12 => '3 Cells (left of content)', + 13 => '3 Cells (center of content)', + 14 => '3 Cells (right of content)', + 15 => 'Left', + 16 => 'Center', + 17 => 'Right', + 18 => 'All', + 19 => 'Layout', + 20 => 'Add Widget', + 21 => 'Add Content Widget', + 22 => 'Attribute', + 23 => 'Widget Style', + 24 => 'Modify', + 25 => 'Delete', + 26 => 'Align', + 27 => 'Occupy a Line', + 28 => 'Left', + 29 => 'Right', + 30 => 'Width', + 31 => 'Height', + 32 => 'Margin', + 33 => 'Padding', + 34 => 'Top', + 35 => 'Left', + 36 => 'Right', + 37 => 'Bottom', + 38 => 'Border', + 39 => 'None', + 40 => 'Background', + 41 => 'Color', + 42 => 'Image', + 43 => 'Select', + 44 => 'Repeat Background', + 45 => 'Repeat', + 46 => 'No Repeat', + 47 => 'Repeat Width', + 48 => 'Repeat Height', + 49 => 'Apply', + 50 => 'Cancel', + 51 => 'Reset', + 52 => 'Text', + 53 => 'Font', + 54 => 'Font Color', + ); + + $lang->layout_image_repository = 'Layout Repository'; + $lang->about_layout_image_repository = 'You can upload images/flash files for selected layout. They will be included in exports'; + $lang->msg_layout_image_target = 'Only gif, png, jpg, swf, flv files are allowed'; + $lang->layout_migration = 'Layout Migration'; + $lang->about_layout_migration = 'You can export or import editted layout as tar file'."\n".'(So far only FaceOff supports exports/imports)'; + + $lang->about_faceoff = array( + 'title' => 'XpressEngine FaceOff Layout Manager', + 'description' => 'FaceOff Layout Manager willl help you design layout on the web easily.
Please design your own layout with components and functions as shown below.', + 'layout' => 'FaceOff has HTML structure as above.
You can arrange/align with CSS, or use Style to design.
You can add widget from Extension(e1, e2), Neck and Knee.
Also Body, Layout, Header, Body, Footer can designed by Style, and Content will display content.', + 'setting' => 'Let me explain you the upper menu on left.
  • Save : Save current settings.
  • Cancel : Discard current settings and go back.
  • Reset : Clear current settings
  • Form : Set form as Fixed/ Variable/ Fixed+Variable(Content).
  • Arrange : Arrange 2 Extensions and Content.
  • Align : Align the position of layout.
', + 'hotkey' => 'You can design your layout more easily with Hot Keys.
  • tab : Unless a widget is selected, Header, Body, Footer will be selected in order. If not, next widget will be selected.
  • Shift + tab : It does the opposite function to tab key.
  • Esc : If nothing is selected, Neck, Extension(e1,e2),Knee will be selected in order, if a widget is selected, area of the widget will be selected.
  • Arrow Key : If a widget is selected, arrow key will move the widget to other areas.
', + 'attribute' => 'You can set background color/image to every area except widget, and font color(include tag).', + + ); + $lang->mobile_layout_list = "Mobile Layout List"; + $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; + $lang->apply_mobile_view = "Apply Mobile View"; + $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; +?> diff --git a/modules/layout/lang/vi.lang.php b/modules/layout/lang/vi.lang.php index 55bfda8be..a6178fb4a 100644 --- a/modules/layout/lang/vi.lang.php +++ b/modules/layout/lang/vi.lang.php @@ -1,119 +1,119 @@ -cmd_layout_management = 'Thiết lập giao diện'; - $lang->cmd_layout_edit = 'Sửa giao diện'; - - $lang->layout_name = 'Tên giao diện'; - $lang->layout_maker = "Người tạo"; - $lang->layout_license = 'Giấy phép'; - $lang->layout_history = "Cập nhật"; - $lang->layout_info = "Thông tin giao diện"; - $lang->layout_list = 'Danh sách giao diện'; - $lang->menu_count = 'Menu'; - $lang->downloaded_list = 'Danh sách Download'; - $lang->layout_preview_content = 'Khu vực nội dung sẽ hiển thị.'; - $lang->not_apply_menu = 'Áp dụng giao diện'; - - $lang->cmd_move_to_installed_list = "Danh sách đã tạo"; - - $lang->about_downloaded_layouts = "Danh sách đã Download"; - $lang->about_title = 'Xin hãy nhập tiêu đề của giao diện cho dễ dàng lựa chọn về sau.'; - $lang->about_not_apply_menu = 'Nếu chọn, tất cả các giao diện đang sử dụng sẽ được thay đổi thành giao diện này.'; - - $lang->about_layout = "Module giao diện giúp bạn tạo ra giao diện của Website một cách dễ dàng.
Bằng cách sử dụng thiết lập giao diện và kết nối Menu, hình dạng hoàn thành của Website sẽ được trình bày bổ xung với nhiều Module.
Giao diện nào xuất hiện (*) là những giao diện không thể xóa hay điều chỉnh được Module. "; - $lang->about_layout_code = - "Nó sẽ được áp dụng vào Website ngay khi bạn bấm 'Lưu' sau khi sửa đổi. - Hãy bấm 'Xem trước' trước khi bấm 'Lưu'. - Bạn có thể tham khảo cách sửa giao diện tại
XE Template."; - - $lang->layout_export = 'Xuất ra'; - $lang->layout_btn_export = 'Download giao diện của tôi'; - $lang->about_layout_export = 'Xuất giao diện sửa chữa hiện tại.'; - $lang->layout_import = 'Nhập vào'; - $lang->about_layout_import = 'Giao diện nguyên bản sẽ bị xóa khi bạn nhập vào. Hãy xuất ra để lưu giao diện hiện thời trước khi nhập vào.'; - - $lang->layout_manager = array( - 0 => 'Quản lý giao diện', - 1 => 'Lưu lại', - 2 => 'Loại bỏ', - 3 => 'Form', - 4 => 'Giãn ra', - 5 => 'Thu lại', - 6 => 'Cố định giao diện', - 7 => 'Giao diện biến thiên', - 8 => 'Cố định+Biến thiên (Nội dung)', - 9 => '1 ô', - 10 => '2 ô (Trái của nội dung)', - 11 => '2 ô (Phải của nội dung)', - 12 => '3 ô (Trái của nội dung)', - 13 => '3 ô (Giữa của nội dung)', - 14 => '3 ô (Phải của nội dung)', - 15 => 'Trái', - 16 => 'Giữa', - 17 => 'Phải', - 18 => 'Dàn đều', - 19 => 'Giao diện', - 20 => 'Thêm Widget', - 21 => 'Thêm Widget nội dung', - 22 => 'Thuộc tính', - 23 => 'Kiểu dáng Widget', - 24 => 'Điều chỉnh', - 25 => 'Xóa', - 26 => 'Căn chỉnh', - 27 => 'Chiếm 1 hàng', - 28 => 'Trái', - 29 => 'Phải', - 30 => 'Chiều rộng', - 31 => 'Chiều cao', - 32 => 'Lề', - 33 => 'Lót', - 34 => 'Đỉnh', - 35 => 'Trái', - 36 => 'Phải', - 37 => 'Dưới', - 38 => 'Viền', - 39 => 'Không', - 40 => 'Nền', - 41 => 'Màu', - 42 => 'Hình ảnh', - 43 => 'Lựa chọn', - 44 => 'Lặp lại nền', - 45 => 'Lặp lại', - 46 => 'Không lặp', - 47 => 'Lặp lại chiều rộng', - 48 => 'Lặp lại chiều cao', - 49 => 'Áp dụng', - 50 => 'Loại bỏ', - 51 => 'Thiết lập lại', - 52 => 'Chữ', - 53 => 'Kiểu chữ', - 54 => 'Màu chữ', - ); - - $lang->layout_image_repository = 'Nơi chứa giao diện'; - $lang->about_layout_image_repository = 'Bạn có thể Upload File hình ảnh hoặc Flash cho giao diện đã chọn. Nó sẽ đi kèm khi xuất giao diện ra.'; - $lang->msg_layout_image_target = 'Chỉ cho phép những định dạng File: .gif, .png, .jpg, .swf, .flv'; - $lang->layout_migration = 'Di chuyển giao diện'; - $lang->about_layout_migration = 'You can export or import editted layout as tar file'."\n".'(So far only FaceOff supports exports/imports)'; - - $lang->about_faceoff = array( - 'title' => 'Quản lý giao diện XpressEngine FaceOff', - 'description' => 'Quản lý giao diện FaceOff sẽ giúp bạn tao ra một giao diện cho riêng mình một cách dễ dàng.
Xin hãy thiết kế giao diện của mình với những thành phần và những chức năng hiển thị phía dưới.', - 'layout' => 'FaceOff có cấu trúc HTML như trên.
bạn có thể thu vào hoặc giãn ra với CSS, hay sử dụng kiểu dáng để thiết kế.
Bạn có thể thêm Widget từ phần mở rộng (e1, e2), Neck và Knee.
Ngoài ra Body, Giao diện, Header, Body, Footer có thể được thiết kế theo kích cỡ, và Content sẽ hiển thị nội dung.', - 'setting' => 'Menu phía bên trái.
  • "Lưu lại": là lưu lại những thiết lập hiện tại.
  • "Loại bỏ": là bỏ qua những thay đổi hiện tại và trở lại.
  • "Thiết lập lại": là xóa bỏ tất cả những thay đổi.
  • "Form": đặt Form dạng Cố định, Biến thiên, Cố định+Biến thiên (Nội dung).
  • "Thu nhỏ": là thu nhỏ hai phần mở rộng và nội dung.
  • "Căn chỉnh" : là sắp xếp sự thẳng hàng.
', - 'hotkey' => 'Bạn có thể thiết kế giao diện của mình dễ dàng hơn nữa với những phím tắt.
  • "Tab": trừ khi một Widget được chọn, Header, Body, Footer sẽ được chọn trong lệnh. Nếu không, Widget tiếp theo sẽ được chọn.
  • "Shift+Tab": nó ngược lại với phím "Tab".
  • "Esc": Nếu không có gì được chọn, Neck, Extension (e1, e2 ), Knee sẽ được lựa chọn theo thứ tự, nếu một Widget được chọn, kích thước Widget sẽ được lựa chọn.
  • "4 phím mũi tên": Nếu Widget đã được chọn, nó sẽ di chuyển Widget tới một vị trí mới.
', - 'attribute' => 'Bạn có thể đặt màu nền / hình nền tới mọi khu vực trừ Widget, và màu chữ (bao gồm cả Tag).', - - ); - $lang->mobile_layout_list = "Mobile Layout List"; - $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; - $lang->apply_mobile_view = "Apply Mobile View"; - $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; -?> +cmd_layout_management = 'Thiết lập giao diện'; + $lang->cmd_layout_edit = 'Sửa giao diện'; + + $lang->layout_name = 'Tên giao diện'; + $lang->layout_maker = "Người tạo"; + $lang->layout_license = 'Giấy phép'; + $lang->layout_history = "Cập nhật"; + $lang->layout_info = "Thông tin giao diện"; + $lang->layout_list = 'Danh sách giao diện'; + $lang->menu_count = 'Menu'; + $lang->downloaded_list = 'Danh sách Download'; + $lang->layout_preview_content = 'Khu vực nội dung sẽ hiển thị.'; + $lang->not_apply_menu = 'Áp dụng giao diện'; + + $lang->cmd_move_to_installed_list = "Danh sách đã tạo"; + + $lang->about_downloaded_layouts = "Danh sách đã Download"; + $lang->about_title = 'Xin hãy nhập tiêu đề của giao diện cho dễ dàng lựa chọn về sau.'; + $lang->about_not_apply_menu = 'Nếu chọn, tất cả các giao diện đang sử dụng sẽ được thay đổi thành giao diện này.'; + + $lang->about_layout = "Module giao diện giúp bạn tạo ra giao diện của Website một cách dễ dàng.
Bằng cách sử dụng thiết lập giao diện và kết nối Menu, hình dạng hoàn thành của Website sẽ được trình bày bổ xung với nhiều Module.
Giao diện nào xuất hiện (*) là những giao diện không thể xóa hay điều chỉnh được Module. "; + $lang->about_layout_code = + "Nó sẽ được áp dụng vào Website ngay khi bạn bấm 'Lưu' sau khi sửa đổi. + Hãy bấm 'Xem trước' trước khi bấm 'Lưu'. + Bạn có thể tham khảo cách sửa giao diện tại XE Template."; + + $lang->layout_export = 'Xuất ra'; + $lang->layout_btn_export = 'Download giao diện của tôi'; + $lang->about_layout_export = 'Xuất giao diện sửa chữa hiện tại.'; + $lang->layout_import = 'Nhập vào'; + $lang->about_layout_import = 'Giao diện nguyên bản sẽ bị xóa khi bạn nhập vào. Hãy xuất ra để lưu giao diện hiện thời trước khi nhập vào.'; + + $lang->layout_manager = array( + 0 => 'Quản lý giao diện', + 1 => 'Lưu lại', + 2 => 'Loại bỏ', + 3 => 'Form', + 4 => 'Giãn ra', + 5 => 'Thu lại', + 6 => 'Cố định giao diện', + 7 => 'Giao diện biến thiên', + 8 => 'Cố định+Biến thiên (Nội dung)', + 9 => '1 ô', + 10 => '2 ô (Trái của nội dung)', + 11 => '2 ô (Phải của nội dung)', + 12 => '3 ô (Trái của nội dung)', + 13 => '3 ô (Giữa của nội dung)', + 14 => '3 ô (Phải của nội dung)', + 15 => 'Trái', + 16 => 'Giữa', + 17 => 'Phải', + 18 => 'Dàn đều', + 19 => 'Giao diện', + 20 => 'Thêm Widget', + 21 => 'Thêm Widget nội dung', + 22 => 'Thuộc tính', + 23 => 'Kiểu dáng Widget', + 24 => 'Điều chỉnh', + 25 => 'Xóa', + 26 => 'Căn chỉnh', + 27 => 'Chiếm 1 hàng', + 28 => 'Trái', + 29 => 'Phải', + 30 => 'Chiều rộng', + 31 => 'Chiều cao', + 32 => 'Lề', + 33 => 'Lót', + 34 => 'Đỉnh', + 35 => 'Trái', + 36 => 'Phải', + 37 => 'Dưới', + 38 => 'Viền', + 39 => 'Không', + 40 => 'Nền', + 41 => 'Màu', + 42 => 'Hình ảnh', + 43 => 'Lựa chọn', + 44 => 'Lặp lại nền', + 45 => 'Lặp lại', + 46 => 'Không lặp', + 47 => 'Lặp lại chiều rộng', + 48 => 'Lặp lại chiều cao', + 49 => 'Áp dụng', + 50 => 'Loại bỏ', + 51 => 'Thiết lập lại', + 52 => 'Chữ', + 53 => 'Kiểu chữ', + 54 => 'Màu chữ', + ); + + $lang->layout_image_repository = 'Nơi chứa giao diện'; + $lang->about_layout_image_repository = 'Bạn có thể Upload File hình ảnh hoặc Flash cho giao diện đã chọn. Nó sẽ đi kèm khi xuất giao diện ra.'; + $lang->msg_layout_image_target = 'Chỉ cho phép những định dạng File: .gif, .png, .jpg, .swf, .flv'; + $lang->layout_migration = 'Di chuyển giao diện'; + $lang->about_layout_migration = 'You can export or import editted layout as tar file'."\n".'(So far only FaceOff supports exports/imports)'; + + $lang->about_faceoff = array( + 'title' => 'Quản lý giao diện XpressEngine FaceOff', + 'description' => 'Quản lý giao diện FaceOff sẽ giúp bạn tao ra một giao diện cho riêng mình một cách dễ dàng.
Xin hãy thiết kế giao diện của mình với những thành phần và những chức năng hiển thị phía dưới.', + 'layout' => 'FaceOff có cấu trúc HTML như trên.
bạn có thể thu vào hoặc giãn ra với CSS, hay sử dụng kiểu dáng để thiết kế.
Bạn có thể thêm Widget từ phần mở rộng (e1, e2), Neck và Knee.
Ngoài ra Body, Giao diện, Header, Body, Footer có thể được thiết kế theo kích cỡ, và Content sẽ hiển thị nội dung.', + 'setting' => 'Menu phía bên trái.
  • "Lưu lại": là lưu lại những thiết lập hiện tại.
  • "Loại bỏ": là bỏ qua những thay đổi hiện tại và trở lại.
  • "Thiết lập lại": là xóa bỏ tất cả những thay đổi.
  • "Form": đặt Form dạng Cố định, Biến thiên, Cố định+Biến thiên (Nội dung).
  • "Thu nhỏ": là thu nhỏ hai phần mở rộng và nội dung.
  • "Căn chỉnh" : là sắp xếp sự thẳng hàng.
', + 'hotkey' => 'Bạn có thể thiết kế giao diện của mình dễ dàng hơn nữa với những phím tắt.
  • "Tab": trừ khi một Widget được chọn, Header, Body, Footer sẽ được chọn trong lệnh. Nếu không, Widget tiếp theo sẽ được chọn.
  • "Shift+Tab": nó ngược lại với phím "Tab".
  • "Esc": Nếu không có gì được chọn, Neck, Extension (e1, e2 ), Knee sẽ được lựa chọn theo thứ tự, nếu một Widget được chọn, kích thước Widget sẽ được lựa chọn.
  • "4 phím mũi tên": Nếu Widget đã được chọn, nó sẽ di chuyển Widget tới một vị trí mới.
', + 'attribute' => 'Bạn có thể đặt màu nền / hình nền tới mọi khu vực trừ Widget, và màu chữ (bao gồm cả Tag).', + + ); + $lang->mobile_layout_list = "Mobile Layout List"; + $lang->mobile_downloaded_list = "Downloaded Mobile Layouts"; + $lang->apply_mobile_view = "Apply Mobile View"; + $lang->about_apply_mobile_view = "All connected module use mobile view to display when accessing with mobile device."; +?> diff --git a/modules/layout/lang/zh-CN.lang.php b/modules/layout/lang/zh-CN.lang.php index 846eb8ad1..81e017ce5 100644 --- a/modules/layout/lang/zh-CN.lang.php +++ b/modules/layout/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ 翻译:guny + * @author NHN (developers@xpressengine.com) 翻译:guny * @brief 布局(layout) 模块简体中文语言包 **/ diff --git a/modules/layout/lang/zh-TW.lang.php b/modules/layout/lang/zh-TW.lang.php index 37047c022..d14759a6c 100644 --- a/modules/layout/lang/zh-TW.lang.php +++ b/modules/layout/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 版面設計(layout)模組正體中文語言 **/ diff --git a/modules/layout/layout.admin.controller.php b/modules/layout/layout.admin.controller.php index 2cdc577ba..264a97582 100644 --- a/modules/layout/layout.admin.controller.php +++ b/modules/layout/layout.admin.controller.php @@ -1,524 +1,524 @@ -site_srl = (int)$site_module_info->site_srl; - $args->layout_srl = getNextSequence(); - $args->layout = Context::get('layout'); - $args->title = Context::get('title'); - $args->layout_type = Context::get('layout_type'); - if(!$args->layout_type) $args->layout_type = "P"; - - // DB 입력 - $output = $this->insertLayout($args); - if(!$output->toBool()) return $output; - - // faceOff 레이아웃일 경우 init 필요 - $this->initLayout($args->layout_srl, $args->layout); - - // 결과 리턴 - $this->add('layout_srl', $args->layout_srl); - } - - // 레이아웃 정보를 DB에 입력 - function insertLayout($args) { - $output = executeQuery("layout.insertLayout", $args); - return $output; - } - - // faceOff 레이아웃을 경우 init - function initLayout($layout_srl, $layout_name){ - $oLayoutModel = &getModel('layout'); - - // faceOff일 경우 sample import - if($oLayoutModel->useDefaultLayout($layout_name)) { - $this->importLayout($layout_srl, $this->module_path.'tpl/faceOff_sample.tar'); - // 디렉토리 제거 - } else { - FileHandler::removeDir($oLayoutModel->getUserLayoutPath($layout_srl)); - } - } - - /** - * @brief 레이아웃 정보 변경 - * 생성된 레이아웃의 제목과 확장변수(extra_vars)를 적용한다 - **/ - function procLayoutAdminUpdate() { - // module, act, layout_srl, layout, title을 제외하면 확장변수로 판단.. 좀 구리다.. - $extra_vars = Context::getRequestVars(); - unset($extra_vars->module); - unset($extra_vars->act); - unset($extra_vars->layout_srl); - unset($extra_vars->layout); - unset($extra_vars->title); - unset($extra_vars->apply_layout); - unset($extra_vars->apply_mobile_view); - - $args = Context::gets('layout_srl','title'); - - // 레이아웃의 정보를 가져옴 - $oLayoutModel = &getModel('layout'); - $oMenuAdminModel = &getAdminModel('menu'); - $layout_info = $oLayoutModel->getLayout($args->layout_srl); - $menus = get_object_vars($layout_info->menu); - if(count($menus) ) { - foreach($menus as $menu_id => $val) { - $menu_srl = Context::get($menu_id); - if(!$menu_srl) continue; - - $output = $oMenuAdminModel->getMenu($menu_srl); - $menu_srl_list[] = $menu_srl; - $menu_name_list[$menu_srl] = $output->title; - - $apply_layout = Context::get('apply_layout'); - $apply_mobile_view = Context::get('apply_mobile_view'); - - if($apply_layout=='Y' || $apply_mobile_view=='Y') { - $menu_args = null; - $menu_args->menu_srl = $menu_srl; - $menu_args->site_srl = $layout_info->site_srl; - $output = executeQueryArray('layout.getLayoutModules', $menu_args); - if($output->data) { - $modules = array(); - for($i=0;$idata);$i++) { - $modules[] = $output->data[$i]->module_srl; - } - - if(count($modules)) { - $update_args->module_srls = implode(',',$modules); - if($apply_layout == "Y") { - $update_args->layout_srl = $args->layout_srl; - } - if($layout_info->layout_type == "M") - { - if(Context::get('apply_mobile_view') == "Y") - { - $update_args->use_mobile = "Y"; - } - $output = executeQuery('layout.updateModuleMLayout', $update_args); - } - else - { - $output = executeQuery('layout.updateModuleLayout', $update_args); - } - } - } - } - } - } - - // extra_vars의 type이 image일 경우 별도 처리를 해줌 - if($layout_info->extra_var) { - foreach($layout_info->extra_var as $name => $vars) { - if($vars->type!='image') continue; - - $image_obj = $extra_vars->{$name}; - $extra_vars->{$name} = $layout_info->extra_var->{$name}->value; - - // 삭제 요청에 대한 변수를 구함 - $del_var = $extra_vars->{"del_".$name}; - unset($extra_vars->{"del_".$name}); - // 삭제 요청이 있거나, 새로운 파일이 업로드 되면, 기존 파일 삭제 - if($del_var == 'Y' || $image_obj['tmp_name']) { - FileHandler::removeFile($extra_vars->{$name}); - $extra_vars->{$name} = ''; - if($del_var == 'Y' && !$image_obj['tmp_name']) continue; - } - - // 정상적으로 업로드된 파일이 아니면 무시 - if(!$image_obj['tmp_name'] || !is_uploaded_file($image_obj['tmp_name'])) continue; - - // 이미지 파일이 아니어도 무시 (swf는 패스~) - if(!preg_match("/\.(jpg|jpeg|gif|png|swf)$/i", $image_obj['name'])) continue; - - // 경로를 정해서 업로드 - $path = sprintf("./files/attach/images/%s/", $args->layout_srl); - - // 디렉토리 생성 - if(!FileHandler::makeDir($path)) continue; - - $filename = $path.$image_obj['name']; - - // 파일 이동 - if(!move_uploaded_file($image_obj['tmp_name'], $filename)) continue; - - $extra_vars->{$name} = $filename; - } - } - - // header script를 레이아웃 모듈의 config에 저장 - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - $layout_config->header_script = Context::get('header_script'); - $oModuleController->insertModulePartConfig('layout',$args->layout_srl,$layout_config); - - //menu의 title도 저장하자 - $extra_vars->menu_name_list = $menu_name_list; - - // DB에 입력하기 위한 변수 설정 - $args->extra_vars = serialize($extra_vars); - - $output = $this->updateLayout($args); - if(!$output->toBool()) return $output; - - $this->setLayoutPath('./common/tpl'); - $this->setLayoutFile('default_layout.html'); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile("top_refresh.html"); - } - - function updateLayout($args) { - $output = executeQuery('layout.updateLayout', $args); - if($output->toBool()) { - $oLayoutModel = &getModel('layout'); - $cache_file = $oLayoutModel->getUserLayoutCache($args->layout_srl, Context::getLangType()); - FileHandler::removeFile($cache_file); - } - return $output; - } - - /** - * @brief 레이아웃 삭제 - * 삭제시 메뉴 xml 캐시 파일도 삭제 - **/ - function procLayoutAdminDelete() { - $layout_srl = Context::get('layout_srl'); - return $this->deleteLayout($layout_srl); - } - - function deleteLayout($layout_srl) { - $oLayoutModel = &getModel('layout'); - - $path = $oLayoutModel->getUserLayoutPath($layout_srl); - FileHandler::removeDir($path); - - $layout_file = $oLayoutModel->getUserLayoutHtml($layout_srl); - if(file_exists($layout_file)) FileHandler::removeFile($layout_file); - - // 레이아웃 삭제 - $args->layout_srl = $layout_srl; - $output = executeQuery("layout.deleteLayout", $args); - if(!$output->toBool()) return $output; - - return new Object(0,'success_deleted'); - } - - /** - * @brief 레이아웃 코드 추가 - **/ - function procLayoutAdminCodeUpdate() { - $layout_srl = Context::get('layout_srl'); - $code = Context::get('code'); - $code_css = Context::get('code_css'); - $return_url = Context::get('_return_url'); - $is_post = (Context::getRequestMethod() == 'POST'); - if(!$layout_srl || !$code) return new Object(-1, 'msg_invalid_request'); - - $oLayoutModel = &getModel('layout'); - $layout_file = $oLayoutModel->getUserLayoutHtml($layout_srl); - FileHandler::writeFile($layout_file, $code); - - $layout_css_file = $oLayoutModel->getUserLayoutCss($layout_srl); - FileHandler::writeFile($layout_css_file, $code_css); - - if($is_post) { - if(!$return_url) $return_url = getUrl('module','admin','act','dispLayoutAdminEdit', 'layout_srl', $layout_srl); - header('Location: '.$return_url); - } else { - $this->setMessage('success_updated'); - } - } - - /** - * @brief 레이아웃 코드 초기화 - **/ - function procLayoutAdminCodeReset() { - $layout_srl = Context::get('layout_srl'); - if(!$layout_srl) return new Object(-1, 'msg_invalid_request'); - - // delete user layout file - $oLayoutModel = &getModel('layout'); - $layout_file = $oLayoutModel->getUserLayoutHtml($layout_srl); - FileHandler::removeFile($layout_file); - - $info = $oLayoutModel->getLayout($layout_srl); - - // if face off delete, tmp file - if($oLayoutModel->useDefaultLayout($info->layout)){ - $this->deleteUserLayoutTempFile($layout_srl); - $faceoff_css = $oLayoutModel->getUserLayoutFaceOffCss($layout_srl); - FileHandler::removeFile($faceoff_css); - } - - $this->initLayout($layout_srl, $info->layout); - $this->setMessage('success_reset'); - } - - - /** - * @brief 레이아웃 설정페이지 -> 이미지 업로드 - * - **/ - function procLayoutAdminUserImageUpload(){ - if(!Context::isUploaded()) exit(); - - $image = Context::get('user_layout_image'); - $layout_srl = Context::get('layout_srl'); - if(!is_uploaded_file($image['tmp_name'])) exit(); - - if(!preg_match('/\.(gif|jpg|jpeg|gif|png|swf|flv)$/i', $image['name'])){ - return false; - } - - $this->insertUserLayoutImage($layout_srl, $image); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile("top_refresh.html"); - } - - /** - * @brief 레이아웃 설정페이지 -> 이미지 업로드 - * - **/ - function insertUserLayoutImage($layout_srl,$source){ - $oLayoutModel = &getModel('layout'); - $path = $oLayoutModel->getUserLayoutImagePath($layout_srl); - if(!is_dir($path)) FileHandler::makeDir($path); - - $filename = strtolower($source['name']); - if($filename != urlencode($filename)){ - $ext = substr(strrchr($filename,'.'),1); - $filename = sprintf('%s.%s', md5($filename), $ext); - } - - if(file_exists($path .'/'. $filename)) @unlink($path . $filename); - if(!move_uploaded_file($source['tmp_name'], $path . $filename )) return false; - return true; - } - - - /** - * @brief 레이아웃 설정페이지 -> 이미지 삭제 - * - **/ - function removeUserLayoutImage($layout_srl,$filename){ - $oLayoutModel = &getModel('layout'); - $path = $oLayoutModel->getUserLayoutImagePath($layout_srl); - @unlink($path . $filename); - } - - /** - * @brief 레이아웃 설정페이지 -> 이미지 삭제 - * - **/ - function procLayoutAdminUserImageDelete(){ - $filename = Context::get('filename'); - $layout_srl = Context::get('layout_srl'); - $this->removeUserLayoutImage($layout_srl,$filename); - $this->setMessage('success_deleted'); - } - - - /** - * @brief 레이아웃 설정 저장 - * ini 로 저장한다 faceoff 용 - **/ - function procLayoutAdminUserValueInsert(){ - $oModuleModel = &getModel('module'); - - $mid = Context::get('mid'); - if(!$mid) return new Object(-1, 'msg_invalid_request'); - - $site_module_info = Context::get('site_module_info'); - $module_info = $oModuleModel->getModuleInfoByMid($mid, $site_module_info->site_srl); - $layout_srl = $module_info->layout_srl; - if(!$layout_srl) return new Object(-1, 'msg_invalid_request'); - - $oLayoutModel = &getModel('layout'); - - // save tmp? - $temp = Context::get('saveTemp'); - if($temp =='Y'){ - $oLayoutModel->setUseUserLayoutTemp(); - }else{ - // delete temp files - $this->deleteUserLayoutTempFile($layout_srl); - } - - $this->add('saveTemp',$temp); - - // write user layout - $extension_obj = Context::gets('e1','e2','neck','knee'); - - $file = $oLayoutModel->getUserLayoutHtml($layout_srl); - $content = FileHandler::readFile($file); - $content = $this->addExtension($layout_srl,$extension_obj,$content); - FileHandler::writeFile($file,$content); - - // write faceoff.css - $css = Context::get('css'); - - $css_file = $oLayoutModel->getUserLayoutFaceOffCss($layout_srl); - FileHandler::writeFile($css_file,$css); - - // write ini - $obj = Context::gets('type','align','column'); - $obj = (array)$obj; - $src = $oLayoutModel->getUserLayoutIniConfig($layout_srl); - foreach($obj as $key => $val) $src[$key] = $val; - $this->insertUserLayoutValue($layout_srl,$src); - } - - /** - * @brief 레이아웃 설정 ini 저장 - * - **/ - function insertUserLayoutValue($layout_srl,$arr){ - $oLayoutModel = &getModel('layout'); - $file = $oLayoutModel->getUserLayoutIni($layout_srl); - FileHandler::writeIniFile($file, $arr); - } - - function writeUserLayoutCss(){ - - } - - /** - * @brief faceoff용 위젯코드를 사용자 layout 파일에 직접 추가한다 - * - **/ - function addExtension($layout_srl,$arg,$content){ - $oLayoutModel = &getModel('layout'); - $reg = '(<\!\-\- start\-e1 \-\->)(.*)(<\!\-\- end\-e1 \-\->)'; - $extension_content = '\1' .stripslashes($arg->e1) . '\3'; - $content = eregi_replace($reg,$extension_content,$content); - - $reg = '(<\!\-\- start\-e2 \-\->)(.*)(<\!\-\- end\-e2 \-\->)'; - $extension_content = '\1' .stripslashes($arg->e2) . '\3'; - $content = eregi_replace($reg,$extension_content,$content); - - $reg = '(<\!\-\- start\-neck \-\->)(.*)(<\!\-\- end\-neck \-\->)'; - $extension_content = '\1' .stripslashes($arg->neck) . '\3'; - $content = eregi_replace($reg,$extension_content,$content); - - $reg = '(<\!\-\- start\-knee \-\->)(.*)(<\!\-\- end\-knee \-\->)'; - $extension_content = '\1' .stripslashes($arg->knee) . '\3'; - $content = eregi_replace($reg,$extension_content,$content); - return $content; - } - - - /** - * @brief faceoff용 temp file들을 지운다 - * - **/ - function deleteUserLayoutTempFile($layout_srl){ - $oLayoutModel = &getModel('layout'); - $file_list = $oLayoutModel->getUserLayoutTempFileList($layout_srl); - foreach($file_list as $key => $file){ - FileHandler::removeFile($file); - } - } - - /** - * @brief faceoff export - * - **/ - function procLayoutAdminUserLayoutExport(){ - $layout_srl = Context::get('layout_srl'); - if(!$layout_srl) return new Object('-1','msg_invalid_request'); - - require_once(_XE_PATH_.'libs/tar.class.php'); - - // 압축할 파일 목록을 가져온다 - $oLayoutModel = &getModel('layout'); - $file_list = $oLayoutModel->getUserLayoutFileList($layout_srl); - - // 압축을 한다. - $tar = new tar(); - $user_layout_path = FileHandler::getRealPath($oLayoutModel->getUserLayoutPath($layout_srl)); - chdir($user_layout_path); - $replace_path = getNumberingPath($layout_srl,3); - foreach($file_list as $key => $file) $tar->addFile($file,$replace_path,'__LAYOUT_PATH__'); - - $stream = $tar->toTarStream(); - $filename = 'faceoff_' . date('YmdHis') . '.tar'; - header("Cache-Control: "); - header("Pragma: "); - header("Content-Type: application/x-compressed"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); -// header("Content-Length: " .strlen($stream)); ?? why?? - header('Content-Disposition: attachment; filename="'. $filename .'"'); - header("Content-Transfer-Encoding: binary\n"); - echo $stream; - - // Context를 강제로 닫고 종료한다. - Context::close(); - exit(); - } - - /** - * @brief faceoff import - * - **/ - function procLayoutAdminUserLayoutImport(){ - // check upload - if(!Context::isUploaded()) exit(); - $file = Context::get('file'); - if(!is_uploaded_file($file['tmp_name'])) exit(); - if(!preg_match('/\.(tar)$/i', $file['name'])) exit(); - - $layout_srl = Context::get('layout_srl'); - if(!$layout_srl) exit(); - - $oLayoutModel = &getModel('layout'); - $user_layout_path = FileHandler::getRealPath($oLayoutModel->getUserLayoutPath($layout_srl)); - if(!move_uploaded_file($file['tmp_name'], $user_layout_path . 'faceoff.tar')) exit(); - - $this->importLayout($layout_srl, $user_layout_path.'faceoff.tar'); - } - - function importLayout($layout_srl, $source_file) { - $oLayoutModel = &getModel('layout'); - $user_layout_path = FileHandler::getRealPath($oLayoutModel->getUserLayoutPath($layout_srl)); - $file_list = $oLayoutModel->getUserLayoutFileList($layout_srl); - foreach($file_list as $key => $file){ - FileHandler::removeFile($user_layout_path . $file); - } - - require_once(_XE_PATH_.'libs/tar.class.php'); - $image_path = $oLayoutModel->getUserLayoutImagePath($layout_srl); - FileHandler::makeDir($image_path); - $tar = new tar(); - $tar->openTAR($source_file); - - // layout.ini 파일이 없으면 - if(!$tar->getFile('layout.ini')) return; - - $replace_path = getNumberingPath($layout_srl,3); - foreach($tar->files as $key => $info) { - FileHandler::writeFile($user_layout_path . $info['name'],str_replace('__LAYOUT_PATH__',$replace_path,$info['file'])); - } - - // 업로드한 파일을 삭제 - FileHandler::removeFile($source_file); - } - } -?> +site_srl = (int)$site_module_info->site_srl; + $args->layout_srl = getNextSequence(); + $args->layout = Context::get('layout'); + $args->title = Context::get('title'); + $args->layout_type = Context::get('layout_type'); + if(!$args->layout_type) $args->layout_type = "P"; + + // DB 입력 + $output = $this->insertLayout($args); + if(!$output->toBool()) return $output; + + // faceOff 레이아웃일 경우 init 필요 + $this->initLayout($args->layout_srl, $args->layout); + + // 결과 리턴 + $this->add('layout_srl', $args->layout_srl); + } + + // 레이아웃 정보를 DB에 입력 + function insertLayout($args) { + $output = executeQuery("layout.insertLayout", $args); + return $output; + } + + // faceOff 레이아웃을 경우 init + function initLayout($layout_srl, $layout_name){ + $oLayoutModel = &getModel('layout'); + + // faceOff일 경우 sample import + if($oLayoutModel->useDefaultLayout($layout_name)) { + $this->importLayout($layout_srl, $this->module_path.'tpl/faceOff_sample.tar'); + // 디렉토리 제거 + } else { + FileHandler::removeDir($oLayoutModel->getUserLayoutPath($layout_srl)); + } + } + + /** + * @brief 레이아웃 정보 변경 + * 생성된 레이아웃의 제목과 확장변수(extra_vars)를 적용한다 + **/ + function procLayoutAdminUpdate() { + // module, act, layout_srl, layout, title을 제외하면 확장변수로 판단.. 좀 구리다.. + $extra_vars = Context::getRequestVars(); + unset($extra_vars->module); + unset($extra_vars->act); + unset($extra_vars->layout_srl); + unset($extra_vars->layout); + unset($extra_vars->title); + unset($extra_vars->apply_layout); + unset($extra_vars->apply_mobile_view); + + $args = Context::gets('layout_srl','title'); + + // 레이아웃의 정보를 가져옴 + $oLayoutModel = &getModel('layout'); + $oMenuAdminModel = &getAdminModel('menu'); + $layout_info = $oLayoutModel->getLayout($args->layout_srl); + $menus = get_object_vars($layout_info->menu); + if(count($menus) ) { + foreach($menus as $menu_id => $val) { + $menu_srl = Context::get($menu_id); + if(!$menu_srl) continue; + + $output = $oMenuAdminModel->getMenu($menu_srl); + $menu_srl_list[] = $menu_srl; + $menu_name_list[$menu_srl] = $output->title; + + $apply_layout = Context::get('apply_layout'); + $apply_mobile_view = Context::get('apply_mobile_view'); + + if($apply_layout=='Y' || $apply_mobile_view=='Y') { + $menu_args = null; + $menu_args->menu_srl = $menu_srl; + $menu_args->site_srl = $layout_info->site_srl; + $output = executeQueryArray('layout.getLayoutModules', $menu_args); + if($output->data) { + $modules = array(); + for($i=0;$idata);$i++) { + $modules[] = $output->data[$i]->module_srl; + } + + if(count($modules)) { + $update_args->module_srls = implode(',',$modules); + if($apply_layout == "Y") { + $update_args->layout_srl = $args->layout_srl; + } + if($layout_info->layout_type == "M") + { + if(Context::get('apply_mobile_view') == "Y") + { + $update_args->use_mobile = "Y"; + } + $output = executeQuery('layout.updateModuleMLayout', $update_args); + } + else + { + $output = executeQuery('layout.updateModuleLayout', $update_args); + } + } + } + } + } + } + + // extra_vars의 type이 image일 경우 별도 처리를 해줌 + if($layout_info->extra_var) { + foreach($layout_info->extra_var as $name => $vars) { + if($vars->type!='image') continue; + + $image_obj = $extra_vars->{$name}; + $extra_vars->{$name} = $layout_info->extra_var->{$name}->value; + + // 삭제 요청에 대한 변수를 구함 + $del_var = $extra_vars->{"del_".$name}; + unset($extra_vars->{"del_".$name}); + // 삭제 요청이 있거나, 새로운 파일이 업로드 되면, 기존 파일 삭제 + if($del_var == 'Y' || $image_obj['tmp_name']) { + FileHandler::removeFile($extra_vars->{$name}); + $extra_vars->{$name} = ''; + if($del_var == 'Y' && !$image_obj['tmp_name']) continue; + } + + // 정상적으로 업로드된 파일이 아니면 무시 + if(!$image_obj['tmp_name'] || !is_uploaded_file($image_obj['tmp_name'])) continue; + + // 이미지 파일이 아니어도 무시 (swf는 패스~) + if(!preg_match("/\.(jpg|jpeg|gif|png|swf)$/i", $image_obj['name'])) continue; + + // 경로를 정해서 업로드 + $path = sprintf("./files/attach/images/%s/", $args->layout_srl); + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) continue; + + $filename = $path.$image_obj['name']; + + // 파일 이동 + if(!move_uploaded_file($image_obj['tmp_name'], $filename)) continue; + + $extra_vars->{$name} = $filename; + } + } + + // header script를 레이아웃 모듈의 config에 저장 + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + $layout_config->header_script = Context::get('header_script'); + $oModuleController->insertModulePartConfig('layout',$args->layout_srl,$layout_config); + + //menu의 title도 저장하자 + $extra_vars->menu_name_list = $menu_name_list; + + // DB에 입력하기 위한 변수 설정 + $args->extra_vars = serialize($extra_vars); + + $output = $this->updateLayout($args); + if(!$output->toBool()) return $output; + + $this->setLayoutPath('./common/tpl'); + $this->setLayoutFile('default_layout.html'); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile("top_refresh.html"); + } + + function updateLayout($args) { + $output = executeQuery('layout.updateLayout', $args); + if($output->toBool()) { + $oLayoutModel = &getModel('layout'); + $cache_file = $oLayoutModel->getUserLayoutCache($args->layout_srl, Context::getLangType()); + FileHandler::removeFile($cache_file); + } + return $output; + } + + /** + * @brief 레이아웃 삭제 + * 삭제시 메뉴 xml 캐시 파일도 삭제 + **/ + function procLayoutAdminDelete() { + $layout_srl = Context::get('layout_srl'); + return $this->deleteLayout($layout_srl); + } + + function deleteLayout($layout_srl) { + $oLayoutModel = &getModel('layout'); + + $path = $oLayoutModel->getUserLayoutPath($layout_srl); + FileHandler::removeDir($path); + + $layout_file = $oLayoutModel->getUserLayoutHtml($layout_srl); + if(file_exists($layout_file)) FileHandler::removeFile($layout_file); + + // 레이아웃 삭제 + $args->layout_srl = $layout_srl; + $output = executeQuery("layout.deleteLayout", $args); + if(!$output->toBool()) return $output; + + return new Object(0,'success_deleted'); + } + + /** + * @brief 레이아웃 코드 추가 + **/ + function procLayoutAdminCodeUpdate() { + $layout_srl = Context::get('layout_srl'); + $code = Context::get('code'); + $code_css = Context::get('code_css'); + $return_url = Context::get('_return_url'); + $is_post = (Context::getRequestMethod() == 'POST'); + if(!$layout_srl || !$code) return new Object(-1, 'msg_invalid_request'); + + $oLayoutModel = &getModel('layout'); + $layout_file = $oLayoutModel->getUserLayoutHtml($layout_srl); + FileHandler::writeFile($layout_file, $code); + + $layout_css_file = $oLayoutModel->getUserLayoutCss($layout_srl); + FileHandler::writeFile($layout_css_file, $code_css); + + if($is_post) { + if(!$return_url) $return_url = getUrl('module','admin','act','dispLayoutAdminEdit', 'layout_srl', $layout_srl); + header('Location: '.$return_url); + } else { + $this->setMessage('success_updated'); + } + } + + /** + * @brief 레이아웃 코드 초기화 + **/ + function procLayoutAdminCodeReset() { + $layout_srl = Context::get('layout_srl'); + if(!$layout_srl) return new Object(-1, 'msg_invalid_request'); + + // delete user layout file + $oLayoutModel = &getModel('layout'); + $layout_file = $oLayoutModel->getUserLayoutHtml($layout_srl); + FileHandler::removeFile($layout_file); + + $info = $oLayoutModel->getLayout($layout_srl); + + // if face off delete, tmp file + if($oLayoutModel->useDefaultLayout($info->layout)){ + $this->deleteUserLayoutTempFile($layout_srl); + $faceoff_css = $oLayoutModel->getUserLayoutFaceOffCss($layout_srl); + FileHandler::removeFile($faceoff_css); + } + + $this->initLayout($layout_srl, $info->layout); + $this->setMessage('success_reset'); + } + + + /** + * @brief 레이아웃 설정페이지 -> 이미지 업로드 + * + **/ + function procLayoutAdminUserImageUpload(){ + if(!Context::isUploaded()) exit(); + + $image = Context::get('user_layout_image'); + $layout_srl = Context::get('layout_srl'); + if(!is_uploaded_file($image['tmp_name'])) exit(); + + if(!preg_match('/\.(gif|jpg|jpeg|gif|png|swf|flv)$/i', $image['name'])){ + return false; + } + + $this->insertUserLayoutImage($layout_srl, $image); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile("top_refresh.html"); + } + + /** + * @brief 레이아웃 설정페이지 -> 이미지 업로드 + * + **/ + function insertUserLayoutImage($layout_srl,$source){ + $oLayoutModel = &getModel('layout'); + $path = $oLayoutModel->getUserLayoutImagePath($layout_srl); + if(!is_dir($path)) FileHandler::makeDir($path); + + $filename = strtolower($source['name']); + if($filename != urlencode($filename)){ + $ext = substr(strrchr($filename,'.'),1); + $filename = sprintf('%s.%s', md5($filename), $ext); + } + + if(file_exists($path .'/'. $filename)) @unlink($path . $filename); + if(!move_uploaded_file($source['tmp_name'], $path . $filename )) return false; + return true; + } + + + /** + * @brief 레이아웃 설정페이지 -> 이미지 삭제 + * + **/ + function removeUserLayoutImage($layout_srl,$filename){ + $oLayoutModel = &getModel('layout'); + $path = $oLayoutModel->getUserLayoutImagePath($layout_srl); + @unlink($path . $filename); + } + + /** + * @brief 레이아웃 설정페이지 -> 이미지 삭제 + * + **/ + function procLayoutAdminUserImageDelete(){ + $filename = Context::get('filename'); + $layout_srl = Context::get('layout_srl'); + $this->removeUserLayoutImage($layout_srl,$filename); + $this->setMessage('success_deleted'); + } + + + /** + * @brief 레이아웃 설정 저장 + * ini 로 저장한다 faceoff 용 + **/ + function procLayoutAdminUserValueInsert(){ + $oModuleModel = &getModel('module'); + + $mid = Context::get('mid'); + if(!$mid) return new Object(-1, 'msg_invalid_request'); + + $site_module_info = Context::get('site_module_info'); + $module_info = $oModuleModel->getModuleInfoByMid($mid, $site_module_info->site_srl); + $layout_srl = $module_info->layout_srl; + if(!$layout_srl) return new Object(-1, 'msg_invalid_request'); + + $oLayoutModel = &getModel('layout'); + + // save tmp? + $temp = Context::get('saveTemp'); + if($temp =='Y'){ + $oLayoutModel->setUseUserLayoutTemp(); + }else{ + // delete temp files + $this->deleteUserLayoutTempFile($layout_srl); + } + + $this->add('saveTemp',$temp); + + // write user layout + $extension_obj = Context::gets('e1','e2','neck','knee'); + + $file = $oLayoutModel->getUserLayoutHtml($layout_srl); + $content = FileHandler::readFile($file); + $content = $this->addExtension($layout_srl,$extension_obj,$content); + FileHandler::writeFile($file,$content); + + // write faceoff.css + $css = Context::get('css'); + + $css_file = $oLayoutModel->getUserLayoutFaceOffCss($layout_srl); + FileHandler::writeFile($css_file,$css); + + // write ini + $obj = Context::gets('type','align','column'); + $obj = (array)$obj; + $src = $oLayoutModel->getUserLayoutIniConfig($layout_srl); + foreach($obj as $key => $val) $src[$key] = $val; + $this->insertUserLayoutValue($layout_srl,$src); + } + + /** + * @brief 레이아웃 설정 ini 저장 + * + **/ + function insertUserLayoutValue($layout_srl,$arr){ + $oLayoutModel = &getModel('layout'); + $file = $oLayoutModel->getUserLayoutIni($layout_srl); + FileHandler::writeIniFile($file, $arr); + } + + function writeUserLayoutCss(){ + + } + + /** + * @brief faceoff용 위젯코드를 사용자 layout 파일에 직접 추가한다 + * + **/ + function addExtension($layout_srl,$arg,$content){ + $oLayoutModel = &getModel('layout'); + $reg = '(<\!\-\- start\-e1 \-\->)(.*)(<\!\-\- end\-e1 \-\->)'; + $extension_content = '\1' .stripslashes($arg->e1) . '\3'; + $content = eregi_replace($reg,$extension_content,$content); + + $reg = '(<\!\-\- start\-e2 \-\->)(.*)(<\!\-\- end\-e2 \-\->)'; + $extension_content = '\1' .stripslashes($arg->e2) . '\3'; + $content = eregi_replace($reg,$extension_content,$content); + + $reg = '(<\!\-\- start\-neck \-\->)(.*)(<\!\-\- end\-neck \-\->)'; + $extension_content = '\1' .stripslashes($arg->neck) . '\3'; + $content = eregi_replace($reg,$extension_content,$content); + + $reg = '(<\!\-\- start\-knee \-\->)(.*)(<\!\-\- end\-knee \-\->)'; + $extension_content = '\1' .stripslashes($arg->knee) . '\3'; + $content = eregi_replace($reg,$extension_content,$content); + return $content; + } + + + /** + * @brief faceoff용 temp file들을 지운다 + * + **/ + function deleteUserLayoutTempFile($layout_srl){ + $oLayoutModel = &getModel('layout'); + $file_list = $oLayoutModel->getUserLayoutTempFileList($layout_srl); + foreach($file_list as $key => $file){ + FileHandler::removeFile($file); + } + } + + /** + * @brief faceoff export + * + **/ + function procLayoutAdminUserLayoutExport(){ + $layout_srl = Context::get('layout_srl'); + if(!$layout_srl) return new Object('-1','msg_invalid_request'); + + require_once(_XE_PATH_.'libs/tar.class.php'); + + // 압축할 파일 목록을 가져온다 + $oLayoutModel = &getModel('layout'); + $file_list = $oLayoutModel->getUserLayoutFileList($layout_srl); + + // 압축을 한다. + $tar = new tar(); + $user_layout_path = FileHandler::getRealPath($oLayoutModel->getUserLayoutPath($layout_srl)); + chdir($user_layout_path); + $replace_path = getNumberingPath($layout_srl,3); + foreach($file_list as $key => $file) $tar->addFile($file,$replace_path,'__LAYOUT_PATH__'); + + $stream = $tar->toTarStream(); + $filename = 'faceoff_' . date('YmdHis') . '.tar'; + header("Cache-Control: "); + header("Pragma: "); + header("Content-Type: application/x-compressed"); + header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); +// header("Content-Length: " .strlen($stream)); ?? why?? + header('Content-Disposition: attachment; filename="'. $filename .'"'); + header("Content-Transfer-Encoding: binary\n"); + echo $stream; + + // Context를 강제로 닫고 종료한다. + Context::close(); + exit(); + } + + /** + * @brief faceoff import + * + **/ + function procLayoutAdminUserLayoutImport(){ + // check upload + if(!Context::isUploaded()) exit(); + $file = Context::get('file'); + if(!is_uploaded_file($file['tmp_name'])) exit(); + if(!preg_match('/\.(tar)$/i', $file['name'])) exit(); + + $layout_srl = Context::get('layout_srl'); + if(!$layout_srl) exit(); + + $oLayoutModel = &getModel('layout'); + $user_layout_path = FileHandler::getRealPath($oLayoutModel->getUserLayoutPath($layout_srl)); + if(!move_uploaded_file($file['tmp_name'], $user_layout_path . 'faceoff.tar')) exit(); + + $this->importLayout($layout_srl, $user_layout_path.'faceoff.tar'); + } + + function importLayout($layout_srl, $source_file) { + $oLayoutModel = &getModel('layout'); + $user_layout_path = FileHandler::getRealPath($oLayoutModel->getUserLayoutPath($layout_srl)); + $file_list = $oLayoutModel->getUserLayoutFileList($layout_srl); + foreach($file_list as $key => $file){ + FileHandler::removeFile($user_layout_path . $file); + } + + require_once(_XE_PATH_.'libs/tar.class.php'); + $image_path = $oLayoutModel->getUserLayoutImagePath($layout_srl); + FileHandler::makeDir($image_path); + $tar = new tar(); + $tar->openTAR($source_file); + + // layout.ini 파일이 없으면 + if(!$tar->getFile('layout.ini')) return; + + $replace_path = getNumberingPath($layout_srl,3); + foreach($tar->files as $key => $info) { + FileHandler::writeFile($user_layout_path . $info['name'],str_replace('__LAYOUT_PATH__',$replace_path,$info['file'])); + } + + // 업로드한 파일을 삭제 + FileHandler::removeFile($source_file); + } + } +?> diff --git a/modules/layout/layout.admin.view.php b/modules/layout/layout.admin.view.php index 4acc3b52e..c7243ea46 100644 --- a/modules/layout/layout.admin.view.php +++ b/modules/layout/layout.admin.view.php @@ -1,296 +1,296 @@ -setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief 레이아웃 관리의 첫 페이지 - **/ - function dispLayoutAdminContent() { - $oLayoutModel = &getModel('layout'); - $layout_list = $oLayoutModel->getLayoutList(); - Context::set('layout_list', $layout_list); - - $this->setTemplateFile('index'); - } - - function dispLayoutAdminMobileContent() { - $oLayoutModel = &getModel('layout'); - $layout_list = $oLayoutModel->getLayoutList(0, "M"); - Context::set('layout_list', $layout_list); - - $this->setTemplateFile('mindex'); - - } - - /** - * @brief 레이아웃 등록 페이지 - * 1차적으로 레이아웃만 선택한 후 DB 에 빈 값을 넣고 그 후 상세 값 설정하는 단계를 거침 - **/ - function dispLayoutAdminInsert() { - // 레이아웃 목록을 세팅 - $oLayoutModel = &getModel('layout'); - $layout_type = Context::get('layout_type'); - $layout_list = $oLayoutModel->getDownloadedLayoutList($layout_type); - Context::set('layout_list', $layout_list); - - $this->setTemplateFile('insert_layout'); - } - - /** - * @brief 레이아웃 세부 정보 입력 - **/ - function dispLayoutAdminModify() { - - // 선택된 레이아웃의 정보르 구해서 세팅 - $layout_srl = Context::get('layout_srl'); - - // 레이아웃의 정보를 가져옴 - $oLayoutModel = &getModel('layout'); - $layout_info = $oLayoutModel->getLayout($layout_srl); - - // 등록된 레이아웃이 없으면 오류 표시 - if(!$layout_info) return $this->dispLayoutAdminContent(); - - // faceoff면 경로를 보여줄 필요는 없다 - if($layout_info->type == 'faceoff') unset($layout_info->path); - Context::set('selected_layout', $layout_info); - - // 메뉴 목록을 가져옴 - $oMenuAdminModel = &getAdminModel('menu'); - $menu_list = $oMenuAdminModel->getMenus(); - Context::set('menu_list', $menu_list); - - $this->setTemplateFile('layout_modify'); - } - - /** - * @brief 레이아웃 코드 편집 - **/ - function dispLayoutAdminEdit() { - // 선택된 레이아웃의 정보르 구해서 세팅 - $layout_srl = Context::get('layout_srl'); - - // 레이아웃의 정보를 가져옴 - $oLayoutModel = &getModel('layout'); - $layout_info = $oLayoutModel->getLayout($layout_srl); - - // 등록된 레이아웃이 없으면 오류 표시 - if(!$layout_info) return $this->dispLayoutAdminContent(); - Context::set('selected_layout', $layout_info); - - // 레이아웃 코드 가져오기 - $oLayoutModel = &getModel('layout'); - $layout_file = $oLayoutModel->getUserLayoutHtml($layout_info->layout_srl); - if(!file_exists($layout_file)){ - // faceoff 면 - if($oLayoutModel->useDefaultLayout($layout_info->layout_srl)){ - $layout_file = $oLayoutModel->getDefaultLayoutHtml($layout_info->layout); - }else{ - $layout_file = sprintf('%s%s', $layout_info->path, 'layout.html'); - } - } - - $layout_css_file = $oLayoutModel->getUserLayoutCss($layout_info->layout_srl); - if(file_exists($layout_css_file)){ - $layout_code_css = FileHandler::readFile($layout_css_file); - Context::set('layout_code_css', $layout_code_css); - } - - $layout_code = FileHandler::readFile($layout_file); - Context::set('layout_code', $layout_code); - - // set User Images - $layout_image_list = $oLayoutModel->getUserLayoutImageList($layout_info->layout_srl); - Context::set('layout_image_list', $layout_image_list); - - $layout_image_path = $oLayoutModel->getUserLayoutImagePath($layout_info->layout_srl); - Context::set('layout_image_path', $layout_image_path); - - // 위젯 목록을 세팅 - $oWidgetModel = &getModel('widget'); - $widget_list = $oWidgetModel->getDownloadedWidgetList(); - Context::set('widget_list', $widget_list); - - $this->setTemplateFile('layout_edit'); - } - - /** - * @brief 레이아웃 목록을 보여줌 - **/ - function dispLayoutAdminDownloadedList() { - // 레이아웃 목록을 세팅 - $oLayoutModel = &getModel('layout'); - $layout_list = $oLayoutModel->getDownloadedLayoutList(); - Context::set('layout_list', $layout_list); - - $this->setTemplateFile('downloaded_layout_list'); - } - - function dispLayoutAdminDownloadedMobileList() { - // 레이아웃 목록을 세팅 - $oLayoutModel = &getModel('layout'); - $layout_list = $oLayoutModel->getDownloadedLayoutList(0, "M"); - Context::set('layout_list', $layout_list); - - $this->setTemplateFile('downloaded_mlayout_list'); - } - - /** - * @brief 레이아웃 미리 보기 - **/ - function dispLayoutAdminPreview() { - $layout_srl = Context::get('layout_srl'); - $code = Context::get('code'); - $code_css = Context::get('code_css'); - if(!$layout_srl || !$code) return new Object(-1, 'msg_invalid_request'); - - // 레이아웃 정보 가져오기 - $oLayoutModel = &getModel('layout'); - $layout_info = $oLayoutModel->getLayout($layout_srl); - if(!$layout_info) return new Object(-1, 'msg_invalid_request'); - - // faceoff 레이아웃일 경우 별도 처리 - if($layout_info && $layout_info->type == 'faceoff') $oLayoutModel->doActivateFaceOff($layout_info); - - // 직접 입력된 CSS 적용 - Context::addHtmlHeader(""); - - // 레이아웃 정보중 extra_vars의 이름과 값을 $layout_info에 입력 - if($layout_info->extra_var_count) { - foreach($layout_info->extra_var as $var_id => $val) { - $layout_info->{$var_id} = $val->value; - } - } - - // 레이아웃 정보중 menu를 Context::set - if($layout_info->menu_count) { - foreach($layout_info->menu as $menu_id => $menu) { - if(file_exists($menu->php_file)) @include($menu->php_file); - Context::set($menu_id, $menu); - } - } - - Context::set('layout_info', $layout_info); - Context::set('content', Context::getLang('layout_preview_content')); - - // 코드를 임시로 저장 - $edited_layout_file = sprintf('./files/cache/layout/tmp.tpl'); - FileHandler::writeFile($edited_layout_file, $code); - - // 컴파일 - $oTemplate = &TemplateHandler::getInstance(); - - $layout_path = $layout_info->path; - $layout_file = 'layout'; - - $layout_tpl = $oTemplate->compile($layout_path, $layout_file, $edited_layout_file); - Context::set('layout','none'); - - // 위젯등을 변환 - $oContext = &Context::getInstance(); - Context::set('layout_tpl', $layout_tpl); - - // 임시 파일 삭제 - FileHandler::removeFile($edited_layout_file); - $this->setTemplateFile('layout_preview'); - - } - - /** - * @brief 레이아웃의 상세 정보(conf/info.xml)를 팝업 출력 - **/ - function dispLayoutAdminInfo() { - // 선택된 레이아웃 정보를 구함 - $oLayoutModel = &getModel('layout'); - $layout_info = $oLayoutModel->getLayoutInfo(Context::get('selected_layout')); - Context::set('layout_info', $layout_info); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('layout_detail_info'); - } - - - /** - * @brief faceoff의 관리자 layout 수정 - **/ - function dispLayoutAdminLayoutModify(){ - //layout_srl 를 가져온다 - $current_module_info = Context::get('current_module_info'); - $layout_srl = $current_module_info->layout_srl; - - // 파일로 임시저장을 하기때문에 남아 있을지 모르는 tmp를 지운다 - // to do 개선이 필요 - $delete_tmp = Context::get('delete_tmp'); - if($delete_tmp =='Y'){ - $oLayoutAdminController = &getAdminController('layout'); - $oLayoutAdminController->deleteUserLayoutTempFile($layout_srl); - } - - $oLayoutModel = &getModel('layout'); - - // layout file들은 temp로 사용한다. - $oLayoutModel->setUseUserLayoutTemp(); - - // css 를 inline style로 뽑는다 - $faceoffcss = $oLayoutModel->_getUserLayoutFaceOffCss($current_module_info->layout_srl); - - $css = FileHandler::readFile($faceoffcss); - $match = null; - preg_match_all('/([^\{]+)\{([^\}]*)\}/is',$css,$match); - for($i=0,$c=count($match[1]);$i<$c;$i++) { - $name = trim($match[1][$i]); - $css = trim($match[2][$i]); - if(!$css) continue; - $css = str_replace('./images/',Context::getRequestUri().$oLayoutModel->getUserLayoutImagePath($layout_srl),$css); - $style[] .= sprintf('"%s":"%s"',$name,$css); - } - - if(count($style)) { - $script = ''; - Context::addHtmlHeader($script); - } - - $oTemplate = &TemplateHandler::getInstance(); - Context::set('content', $oTemplate->compile($this->module_path.'tpl','about_faceoff')); - - // 위젯 코드를 Javascript 수정모드로 변경 - $oWidgetController = &getController('widget'); - $oWidgetController->setWidgetCodeInJavascriptMode(); - - // 템플릿 파일 지정 - $this->setTemplateFile('faceoff_layout_edit'); - } - - function dispLayoutAdminLayoutImageList(){ - $layout_srl = Context::get('layout_srl'); - $oLayoutModel = &getModel('layout'); - - // 이미지 목록 - $layout_image_list = $oLayoutModel->getUserLayoutImageList($layout_srl); - Context::set('layout_image_list',$layout_image_list); - - // 경로 - $layout_image_path = $oLayoutModel->getUserLayoutImagePath($layout_srl); - Context::set('layout_image_path',$layout_image_path); - - $this->setLayoutFile('popup_layout'); - - $this->setTemplateFile('layout_image_list'); - } - } -?> +setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief 레이아웃 관리의 첫 페이지 + **/ + function dispLayoutAdminContent() { + $oLayoutModel = &getModel('layout'); + $layout_list = $oLayoutModel->getLayoutList(); + Context::set('layout_list', $layout_list); + + $this->setTemplateFile('index'); + } + + function dispLayoutAdminMobileContent() { + $oLayoutModel = &getModel('layout'); + $layout_list = $oLayoutModel->getLayoutList(0, "M"); + Context::set('layout_list', $layout_list); + + $this->setTemplateFile('mindex'); + + } + + /** + * @brief 레이아웃 등록 페이지 + * 1차적으로 레이아웃만 선택한 후 DB 에 빈 값을 넣고 그 후 상세 값 설정하는 단계를 거침 + **/ + function dispLayoutAdminInsert() { + // 레이아웃 목록을 세팅 + $oLayoutModel = &getModel('layout'); + $layout_type = Context::get('layout_type'); + $layout_list = $oLayoutModel->getDownloadedLayoutList($layout_type); + Context::set('layout_list', $layout_list); + + $this->setTemplateFile('insert_layout'); + } + + /** + * @brief 레이아웃 세부 정보 입력 + **/ + function dispLayoutAdminModify() { + + // 선택된 레이아웃의 정보르 구해서 세팅 + $layout_srl = Context::get('layout_srl'); + + // 레이아웃의 정보를 가져옴 + $oLayoutModel = &getModel('layout'); + $layout_info = $oLayoutModel->getLayout($layout_srl); + + // 등록된 레이아웃이 없으면 오류 표시 + if(!$layout_info) return $this->dispLayoutAdminContent(); + + // faceoff면 경로를 보여줄 필요는 없다 + if($layout_info->type == 'faceoff') unset($layout_info->path); + Context::set('selected_layout', $layout_info); + + // 메뉴 목록을 가져옴 + $oMenuAdminModel = &getAdminModel('menu'); + $menu_list = $oMenuAdminModel->getMenus(); + Context::set('menu_list', $menu_list); + + $this->setTemplateFile('layout_modify'); + } + + /** + * @brief 레이아웃 코드 편집 + **/ + function dispLayoutAdminEdit() { + // 선택된 레이아웃의 정보르 구해서 세팅 + $layout_srl = Context::get('layout_srl'); + + // 레이아웃의 정보를 가져옴 + $oLayoutModel = &getModel('layout'); + $layout_info = $oLayoutModel->getLayout($layout_srl); + + // 등록된 레이아웃이 없으면 오류 표시 + if(!$layout_info) return $this->dispLayoutAdminContent(); + Context::set('selected_layout', $layout_info); + + // 레이아웃 코드 가져오기 + $oLayoutModel = &getModel('layout'); + $layout_file = $oLayoutModel->getUserLayoutHtml($layout_info->layout_srl); + if(!file_exists($layout_file)){ + // faceoff 면 + if($oLayoutModel->useDefaultLayout($layout_info->layout_srl)){ + $layout_file = $oLayoutModel->getDefaultLayoutHtml($layout_info->layout); + }else{ + $layout_file = sprintf('%s%s', $layout_info->path, 'layout.html'); + } + } + + $layout_css_file = $oLayoutModel->getUserLayoutCss($layout_info->layout_srl); + if(file_exists($layout_css_file)){ + $layout_code_css = FileHandler::readFile($layout_css_file); + Context::set('layout_code_css', $layout_code_css); + } + + $layout_code = FileHandler::readFile($layout_file); + Context::set('layout_code', $layout_code); + + // set User Images + $layout_image_list = $oLayoutModel->getUserLayoutImageList($layout_info->layout_srl); + Context::set('layout_image_list', $layout_image_list); + + $layout_image_path = $oLayoutModel->getUserLayoutImagePath($layout_info->layout_srl); + Context::set('layout_image_path', $layout_image_path); + + // 위젯 목록을 세팅 + $oWidgetModel = &getModel('widget'); + $widget_list = $oWidgetModel->getDownloadedWidgetList(); + Context::set('widget_list', $widget_list); + + $this->setTemplateFile('layout_edit'); + } + + /** + * @brief 레이아웃 목록을 보여줌 + **/ + function dispLayoutAdminDownloadedList() { + // 레이아웃 목록을 세팅 + $oLayoutModel = &getModel('layout'); + $layout_list = $oLayoutModel->getDownloadedLayoutList(); + Context::set('layout_list', $layout_list); + + $this->setTemplateFile('downloaded_layout_list'); + } + + function dispLayoutAdminDownloadedMobileList() { + // 레이아웃 목록을 세팅 + $oLayoutModel = &getModel('layout'); + $layout_list = $oLayoutModel->getDownloadedLayoutList(0, "M"); + Context::set('layout_list', $layout_list); + + $this->setTemplateFile('downloaded_mlayout_list'); + } + + /** + * @brief 레이아웃 미리 보기 + **/ + function dispLayoutAdminPreview() { + $layout_srl = Context::get('layout_srl'); + $code = Context::get('code'); + $code_css = Context::get('code_css'); + if(!$layout_srl || !$code) return new Object(-1, 'msg_invalid_request'); + + // 레이아웃 정보 가져오기 + $oLayoutModel = &getModel('layout'); + $layout_info = $oLayoutModel->getLayout($layout_srl); + if(!$layout_info) return new Object(-1, 'msg_invalid_request'); + + // faceoff 레이아웃일 경우 별도 처리 + if($layout_info && $layout_info->type == 'faceoff') $oLayoutModel->doActivateFaceOff($layout_info); + + // 직접 입력된 CSS 적용 + Context::addHtmlHeader(""); + + // 레이아웃 정보중 extra_vars의 이름과 값을 $layout_info에 입력 + if($layout_info->extra_var_count) { + foreach($layout_info->extra_var as $var_id => $val) { + $layout_info->{$var_id} = $val->value; + } + } + + // 레이아웃 정보중 menu를 Context::set + if($layout_info->menu_count) { + foreach($layout_info->menu as $menu_id => $menu) { + if(file_exists($menu->php_file)) @include($menu->php_file); + Context::set($menu_id, $menu); + } + } + + Context::set('layout_info', $layout_info); + Context::set('content', Context::getLang('layout_preview_content')); + + // 코드를 임시로 저장 + $edited_layout_file = sprintf('./files/cache/layout/tmp.tpl'); + FileHandler::writeFile($edited_layout_file, $code); + + // 컴파일 + $oTemplate = &TemplateHandler::getInstance(); + + $layout_path = $layout_info->path; + $layout_file = 'layout'; + + $layout_tpl = $oTemplate->compile($layout_path, $layout_file, $edited_layout_file); + Context::set('layout','none'); + + // 위젯등을 변환 + $oContext = &Context::getInstance(); + Context::set('layout_tpl', $layout_tpl); + + // 임시 파일 삭제 + FileHandler::removeFile($edited_layout_file); + $this->setTemplateFile('layout_preview'); + + } + + /** + * @brief 레이아웃의 상세 정보(conf/info.xml)를 팝업 출력 + **/ + function dispLayoutAdminInfo() { + // 선택된 레이아웃 정보를 구함 + $oLayoutModel = &getModel('layout'); + $layout_info = $oLayoutModel->getLayoutInfo(Context::get('selected_layout')); + Context::set('layout_info', $layout_info); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('layout_detail_info'); + } + + + /** + * @brief faceoff의 관리자 layout 수정 + **/ + function dispLayoutAdminLayoutModify(){ + //layout_srl 를 가져온다 + $current_module_info = Context::get('current_module_info'); + $layout_srl = $current_module_info->layout_srl; + + // 파일로 임시저장을 하기때문에 남아 있을지 모르는 tmp를 지운다 + // to do 개선이 필요 + $delete_tmp = Context::get('delete_tmp'); + if($delete_tmp =='Y'){ + $oLayoutAdminController = &getAdminController('layout'); + $oLayoutAdminController->deleteUserLayoutTempFile($layout_srl); + } + + $oLayoutModel = &getModel('layout'); + + // layout file들은 temp로 사용한다. + $oLayoutModel->setUseUserLayoutTemp(); + + // css 를 inline style로 뽑는다 + $faceoffcss = $oLayoutModel->_getUserLayoutFaceOffCss($current_module_info->layout_srl); + + $css = FileHandler::readFile($faceoffcss); + $match = null; + preg_match_all('/([^\{]+)\{([^\}]*)\}/is',$css,$match); + for($i=0,$c=count($match[1]);$i<$c;$i++) { + $name = trim($match[1][$i]); + $css = trim($match[2][$i]); + if(!$css) continue; + $css = str_replace('./images/',Context::getRequestUri().$oLayoutModel->getUserLayoutImagePath($layout_srl),$css); + $style[] .= sprintf('"%s":"%s"',$name,$css); + } + + if(count($style)) { + $script = ''; + Context::addHtmlHeader($script); + } + + $oTemplate = &TemplateHandler::getInstance(); + Context::set('content', $oTemplate->compile($this->module_path.'tpl','about_faceoff')); + + // 위젯 코드를 Javascript 수정모드로 변경 + $oWidgetController = &getController('widget'); + $oWidgetController->setWidgetCodeInJavascriptMode(); + + // 템플릿 파일 지정 + $this->setTemplateFile('faceoff_layout_edit'); + } + + function dispLayoutAdminLayoutImageList(){ + $layout_srl = Context::get('layout_srl'); + $oLayoutModel = &getModel('layout'); + + // 이미지 목록 + $layout_image_list = $oLayoutModel->getUserLayoutImageList($layout_srl); + Context::set('layout_image_list',$layout_image_list); + + // 경로 + $layout_image_path = $oLayoutModel->getUserLayoutImagePath($layout_srl); + Context::set('layout_image_path',$layout_image_path); + + $this->setLayoutFile('popup_layout'); + + $this->setTemplateFile('layout_image_list'); + } + } +?> diff --git a/modules/layout/layout.class.php b/modules/layout/layout.class.php index c7659b91d..f207fa2e4 100644 --- a/modules/layout/layout.class.php +++ b/modules/layout/layout.class.php @@ -1,93 +1,93 @@ -isColumnExists('layouts', 'site_srl')) return true; - - // 2009. 02. 26 faceOff에 맞춰 기존 레이아웃 편집본을 이동 - $files = FileHandler::readDir('./files/cache/layout'); - for($i=0,$c=count($files);$i<$c;$i++) { - $filename = $files[$i]; - if(preg_match('/([0-9]+)\.html/i',$filename)) return true; - } - - if(!$oDB->isColumnExists('layouts', 'layout_type')) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - - // 2009. 02. 11 menu 테이블에 site_srl 추가 - if(!$oDB->isColumnExists('layouts', 'site_srl')) { - $oDB->addColumn('layouts','site_srl','number',11,0,true); - } - - // 2009. 02. 26 faceOff에 맞춰 기존 레이아웃 편집본을 이동 - $oLayoutModel = &getModel('layout'); - $files = FileHandler::readDir('./files/cache/layout'); - for($i=0,$c=count($files);$i<$c;$i++) { - $filename = $files[$i]; - if(!preg_match('/([0-9]+)\.html/i',$filename,$match)) continue; - $layout_srl = $match[1]; - if(!$layout_srl) continue; - $path = $oLayoutModel->getUserLayoutPath($layout_srl); - if(!is_dir($path)) FileHandler::makeDir($path); - FileHandler::copyFile('./files/cache/layout/'.$filename, $path.'layout.html'); - @unlink('./files/cache/layout/'.$filename); - } - - if(!$oDB->isColumnExists('layouts', 'layout_type')) { - $oDB->addColumn('layouts','layout_type','char',1,'P',true); - } - - return new Object(0, 'success_updated'); - } - - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - // 레이아웃 캐시 삭제 (수정본은 지우지 않음) - $path = './files/cache/layout'; - if(!is_dir($path)) { - FileHandler::makeDir($path); - return; - } - - $directory = dir($path); - while($entry = $directory->read()) { - if ($entry == "." || $entry == ".." || preg_match('/\.html$/i',$entry) ) continue; - FileHandler::removeFile($path."/".$entry); - } - $directory->close(); - } - } -?> +isColumnExists('layouts', 'site_srl')) return true; + + // 2009. 02. 26 faceOff에 맞춰 기존 레이아웃 편집본을 이동 + $files = FileHandler::readDir('./files/cache/layout'); + for($i=0,$c=count($files);$i<$c;$i++) { + $filename = $files[$i]; + if(preg_match('/([0-9]+)\.html/i',$filename)) return true; + } + + if(!$oDB->isColumnExists('layouts', 'layout_type')) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + + // 2009. 02. 11 menu 테이블에 site_srl 추가 + if(!$oDB->isColumnExists('layouts', 'site_srl')) { + $oDB->addColumn('layouts','site_srl','number',11,0,true); + } + + // 2009. 02. 26 faceOff에 맞춰 기존 레이아웃 편집본을 이동 + $oLayoutModel = &getModel('layout'); + $files = FileHandler::readDir('./files/cache/layout'); + for($i=0,$c=count($files);$i<$c;$i++) { + $filename = $files[$i]; + if(!preg_match('/([0-9]+)\.html/i',$filename,$match)) continue; + $layout_srl = $match[1]; + if(!$layout_srl) continue; + $path = $oLayoutModel->getUserLayoutPath($layout_srl); + if(!is_dir($path)) FileHandler::makeDir($path); + FileHandler::copyFile('./files/cache/layout/'.$filename, $path.'layout.html'); + @unlink('./files/cache/layout/'.$filename); + } + + if(!$oDB->isColumnExists('layouts', 'layout_type')) { + $oDB->addColumn('layouts','layout_type','char',1,'P',true); + } + + return new Object(0, 'success_updated'); + } + + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + // 레이아웃 캐시 삭제 (수정본은 지우지 않음) + $path = './files/cache/layout'; + if(!is_dir($path)) { + FileHandler::makeDir($path); + return; + } + + $directory = dir($path); + while($entry = $directory->read()) { + if ($entry == "." || $entry == ".." || preg_match('/\.html$/i',$entry) ) continue; + FileHandler::removeFile($path."/".$entry); + } + $directory->close(); + } + } +?> diff --git a/modules/layout/layout.model.php b/modules/layout/layout.model.php index 22994e4f3..163177b44 100644 --- a/modules/layout/layout.model.php +++ b/modules/layout/layout.model.php @@ -1,618 +1,618 @@ -site_srl; - } - $args->site_srl = $site_srl; - $args->layout_type = $layout_type; - $output = executeQuery('layout.getLayoutList', $args); - if(!$output->data) return; - if(is_array($output->data)) return $output->data; - return array($output->data); - } - - /** - * @brief DB 에 생성된 한개의 레이아웃 정보를 구함 - * 생성된 레이아웃의 DB정보+XML정보를 return - **/ - function getLayout($layout_srl) { - // 일단 DB에서 정보를 가져옴 - $args->layout_srl = $layout_srl; - $output = executeQuery('layout.getLayout', $args); - if(!$output->data) return; - - // layout, extra_vars를 정리한 후 xml 파일 정보를 정리해서 return - $layout_info = $this->getLayoutInfo($layout, $output->data, $output->data->layout_type); - return $layout_info; - } - - /** - * @brief 레이아웃의 경로를 구함 - **/ - function getLayoutPath($layout_name, $layout_type = "P") { - if($layout_name == 'faceoff'){ - $class_path = './modules/layout/faceoff/'; - }else if($layout_type == "M") { - $class_path = sprintf("./m.layouts/%s/", $layout_name); - } - else - { - $class_path = sprintf('./layouts/%s/', $layout_name); - } - if(is_dir($class_path)) return $class_path; - return ""; - } - - /** - * @brief 레이아웃의 종류와 정보를 구함 - * 다운로드되어 있는 레이아웃의 종류 (생성과 다른 의미) - **/ - function getDownloadedLayoutList($layout_type = "P") { - // 다운받은 레이아웃과 설치된 레이아웃의 목록을 구함 - if($layout_type == "M") - { - $directory = "./m.layouts"; - } - else - { - $directory = "./layouts"; - } - - $searched_list = FileHandler::readDir($directory); - $searched_count = count($searched_list); - if(!$searched_count) return; - - natcasesort($searched_list); - - // 찾아진 레이아웃 목록을 loop돌면서 필요한 정보를 간추려 return - for($i=0;$i<$searched_count;$i++) { - // 레이아웃의 이름 - $layout = $searched_list[$i]; - - // 해당 레이아웃의 정보를 구함 - $layout_info = $this->getLayoutInfo($layout, null, $layout_type); - - $list[] = $layout_info; - } - return $list; - } - - /** - * @brief 모듈의 conf/info.xml 을 읽어서 정보를 구함 - * 이것 역시 캐싱을 통해서 xml parsing 시간을 줄인다.. - **/ - function getLayoutInfo($layout, $info = null, $layout_type = "P") { - if($info) { - $layout_title = $info->title; - $layout = $info->layout; - $layout_srl = $info->layout_srl; - $site_srl = $info->site_srl; - $vars = unserialize($info->extra_vars); - - if($info->module_srl) { - $layout_path = preg_replace('/([a-zA-Z0-9\_\.]+)(\.html)$/','',$info->layout_path); - $xml_file = sprintf('%sskin.xml', $layout_path); - } - } - - // 요청된 모듈의 경로를 구한다. 없으면 return - if(!$layout_path) $layout_path = $this->getLayoutPath($layout, $layout_type); - if(!is_dir($layout_path)) return; - - // 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음 - if(!$xml_file) $xml_file = sprintf("%sconf/info.xml", $layout_path); - if(!file_exists($xml_file)) { - $layout_info->layout = $layout; - $layout_info->path = $layout_path; - $layout_info->layout_title = $layout_title; - if(!$layout_info->layout_type) - $layout_info->layout_type = $layout_type; - return $layout_info; - } - - // cache 파일을 비교하여 문제 없으면 include하고 $layout_info 변수를 return - if(!$layout_srl){ - $cache_file = $this->getLayoutCache($layout, Context::getLangType()); - }else{ - $cache_file = $this->getUserLayoutCache($layout_srl, Context::getLangType()); - } - if(file_exists($cache_file)&&filemtime($cache_file)>filemtime($xml_file)) { - @include($cache_file); - - if($layout_info->extra_var && $vars) { - foreach($vars as $key => $value) { - if(!$layout_info->extra_var->{$key} && !$layout_info->{$key}) { - $layout_info->{$key} = $value; - } - } - } - return $layout_info; - } - - // cache 파일이 없으면 xml parsing하고 변수화 한 후에 캐시 파일에 쓰고 변수 바로 return - $oXmlParser = new XmlParser(); - $tmp_xml_obj = $oXmlParser->loadXmlFile($xml_file); - if($tmp_xml_obj->layout) $xml_obj = $tmp_xml_obj->layout; - elseif($tmp_xml_obj->skin) $xml_obj = $tmp_xml_obj->skin; - - if(!$xml_obj) return; - - $buff = ''; - $buff .= sprintf('$layout_info->site_srl = "%s";', $site_srl); - - if($xml_obj->version && $xml_obj->attrs->version == '0.2') { - // 레이아웃의 제목, 버전 - sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); - $date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $buff .= sprintf('$layout_info->layout = "%s";', $layout); - $buff .= sprintf('$layout_info->type = "%s";', $xml_obj->attrs->type); - $buff .= sprintf('$layout_info->path = "%s";', $layout_path); - $buff .= sprintf('$layout_info->title = "%s";', $xml_obj->title->body); - $buff .= sprintf('$layout_info->description = "%s";', $xml_obj->description->body); - $buff .= sprintf('$layout_info->version = "%s";', $xml_obj->version->body); - $buff .= sprintf('$layout_info->date = "%s";', $date); - $buff .= sprintf('$layout_info->homepage = "%s";', $xml_obj->link->body); - $buff .= sprintf('$layout_info->layout_srl = $layout_srl;'); - $buff .= sprintf('$layout_info->layout_title = $layout_title;'); - $buff .= sprintf('$layout_info->license = "%s";', $xml_obj->license->body); - $buff .= sprintf('$layout_info->license_link = "%s";', $xml_obj->license->attrs->link); - $buff .= sprintf('$layout_info->layout_type = "%s";', $layout_type); - - // 작성자 정보 - if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; - else $author_list = $xml_obj->author; - - for($i=0; $i < count($author_list); $i++) { - $buff .= sprintf('$layout_info->author['.$i.']->name = "%s";', $author_list[$i]->name->body); - $buff .= sprintf('$layout_info->author['.$i.']->email_address = "%s";', $author_list[$i]->attrs->email_address); - $buff .= sprintf('$layout_info->author['.$i.']->homepage = "%s";', $author_list[$i]->attrs->link); - } - - - - // 추가 변수 (템플릿에서 사용할 제작자 정의 변수) - $extra_var_groups = $xml_obj->extra_vars->group; - if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; - if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); - foreach($extra_var_groups as $group){ - $extra_vars = $group->var; - if($extra_vars) { - if(!is_array($extra_vars)) $extra_vars = array($extra_vars); - - $extra_var_count = count($extra_vars); - - $buff .= sprintf('$layout_info->extra_var_count = "%s";', $extra_var_count); - for($i=0;$i<$extra_var_count;$i++) { - unset($var); - unset($options); - $var = $extra_vars[$i]; - $name = $var->attrs->name; - - $buff .= sprintf('$layout_info->extra_var->%s->group = "%s";', $name, $group->title->body); - $buff .= sprintf('$layout_info->extra_var->%s->title = "%s";', $name, $var->title->body); - $buff .= sprintf('$layout_info->extra_var->%s->type = "%s";', $name, $var->attrs->type); - $buff .= sprintf('$layout_info->extra_var->%s->value = $vars->%s;', $name, $name); - $buff .= sprintf('$layout_info->extra_var->%s->description = "%s";', $name, str_replace('"','\"',$var->description->body)); - - $options = $var->options; - if(!$options) continue; - - if(!is_array($options)) $options = array($options); - $options_count = count($options); - for($j=0;$j<$options_count;$j++) { - $buff .= sprintf('$layout_info->extra_var->%s->options["%s"] = "%s";', $var->attrs->name, $options[$j]->attrs->value, $options[$j]->title->body); - } - } - } - } - - // 메뉴 - if($xml_obj->menus->menu) { - $menus = $xml_obj->menus->menu; - if(!is_array($menus)) $menus = array($menus); - - $menu_count = count($menus); - $buff .= sprintf('$layout_info->menu_count = "%s";', $menu_count); - for($i=0;$i<$menu_count;$i++) { - $name = $menus[$i]->attrs->name; - if($menus[$i]->attrs->default == "true") $buff .= sprintf('$layout_info->default_menu = "%s";', $name); - $buff .= sprintf('$layout_info->menu->%s->name = "%s";',$name, $menus[$i]->attrs->name); - $buff .= sprintf('$layout_info->menu->%s->title = "%s";',$name, $menus[$i]->title->body); - $buff .= sprintf('$layout_info->menu->%s->maxdepth = "%s";',$name, $menus[$i]->attrs->maxdepth); - - $buff .= sprintf('$layout_info->menu->%s->menu_srl = $vars->%s;', $name, $name); - $buff .= sprintf('$layout_info->menu->%s->xml_file = "./files/cache/menu/".$vars->%s.".xml.php";',$name, $name); - $buff .= sprintf('$layout_info->menu->%s->php_file = "./files/cache/menu/".$vars->%s.".php";',$name, $name); - } - } - - - // history - if($xml_obj->history) { - if(!is_array($xml_obj->history)) $history_list[] = $xml_obj->history; - else $history_list = $xml_obj->history; - - for($i=0; $i < count($history_list); $i++) { - sscanf($history_list[$i]->attrs->date, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); - $date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $buff .= sprintf('$layout_info->history['.$i.']->description = "%s";', $history_list[$i]->description->body); - $buff .= sprintf('$layout_info->history['.$i.']->version = "%s";', $history_list[$i]->attrs->version); - $buff .= sprintf('$layout_info->history['.$i.']->date = "%s";', $date); - - if($history_list[$i]->author) { - (!is_array($history_list[$i]->author)) ? $obj->author_list[] = $history_list[$i]->author : $obj->author_list = $history_list[$i]->author; - - for($j=0; $j < count($obj->author_list); $j++) { - $buff .= sprintf('$layout_info->history['.$i.']->author['.$j.']->name = "%s";', $obj->author_list[$j]->name->body); - $buff .= sprintf('$layout_info->history['.$i.']->author['.$j.']->email_address = "%s";', $obj->author_list[$j]->attrs->email_address); - $buff .= sprintf('$layout_info->history['.$i.']->author['.$j.']->homepage = "%s";', $obj->author_list[$j]->attrs->link); - } - } - - if($history_list[$i]->log) { - (!is_array($history_list[$i]->log)) ? $obj->log_list[] = $history_list[$i]->log : $obj->log_list = $history_list[$i]->log; - - for($j=0; $j < count($obj->log_list); $j++) { - $buff .= sprintf('$layout_info->history['.$i.']->logs['.$j.']->text = "%s";', $obj->log_list[$j]->body); - $buff .= sprintf('$layout_info->history['.$i.']->logs['.$j.']->link = "%s";', $obj->log_list[$j]->attrs->link); - } - } - } - } - - - - } else { - - // 레이아웃의 제목, 버전 - sscanf($xml_obj->author->attrs->date, '%d. %d. %d', $date_obj->y, $date_obj->m, $date_obj->d); - $date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $buff .= sprintf('$layout_info->layout = "%s";', $layout); - $buff .= sprintf('$layout_info->path = "%s";', $layout_path); - $buff .= sprintf('$layout_info->title = "%s";', $xml_obj->title->body); - $buff .= sprintf('$layout_info->description = "%s";', $xml_obj->author->description->body); - $buff .= sprintf('$layout_info->version = "%s";', $xml_obj->attrs->version); - $buff .= sprintf('$layout_info->date = "%s";', $date); - $buff .= sprintf('$layout_info->layout_srl = $layout_srl;'); - $buff .= sprintf('$layout_info->layout_title = $layout_title;'); - - // 작성자 정보 - $buff .= sprintf('$layout_info->author[0]->name = "%s";', $xml_obj->author->name->body); - $buff .= sprintf('$layout_info->author[0]->email_address = "%s";', $xml_obj->author->attrs->email_address); - $buff .= sprintf('$layout_info->author[0]->homepage = "%s";', $xml_obj->author->attrs->link); - - // 추가 변수 (템플릿에서 사용할 제작자 정의 변수) - $extra_var_groups = $xml_obj->extra_vars->group; - if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; - if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); - foreach($extra_var_groups as $group){ - $extra_vars = $group->var; - if($extra_vars) { - if(!is_array($extra_vars)) $extra_vars = array($extra_vars); - - $extra_var_count = count($extra_vars); - - $buff .= sprintf('$layout_info->extra_var_count = "%s";', $extra_var_count); - for($i=0;$i<$extra_var_count;$i++) { - unset($var); - unset($options); - $var = $extra_vars[$i]; - $name = $var->attrs->name; - - $buff .= sprintf('$layout_info->extra_var->%s->group = "%s";', $name, $group->title->body); - $buff .= sprintf('$layout_info->extra_var->%s->title = "%s";', $name, $var->title->body); - $buff .= sprintf('$layout_info->extra_var->%s->type = "%s";', $name, $var->attrs->type); - $buff .= sprintf('$layout_info->extra_var->%s->value = $vars->%s;', $name, $name); - $buff .= sprintf('$layout_info->extra_var->%s->description = "%s";', $name, str_replace('"','\"',$var->description->body)); - - $options = $var->options; - if(!$options) continue; - - if(!is_array($options)) $options = array($options); - $options_count = count($options); - for($j=0;$j<$options_count;$j++) { - $buff .= sprintf('$layout_info->extra_var->%s->options["%s"] = "%s";', $var->attrs->name, $options[$j]->value->body, $options[$j]->title->body); - } - } - } - } - - // 메뉴 - if($xml_obj->menus->menu) { - $menus = $xml_obj->menus->menu; - if(!is_array($menus)) $menus = array($menus); - - $menu_count = count($menus); - $buff .= sprintf('$layout_info->menu_count = "%s";', $menu_count); - for($i=0;$i<$menu_count;$i++) { - $name = $menus[$i]->attrs->name; - if($menus[$i]->attrs->default == "true") $buff .= sprintf('$layout_info->default_menu = "%s";', $name); - $buff .= sprintf('$layout_info->menu->%s->name = "%s";',$name, $menus[$i]->attrs->name); - $buff .= sprintf('$layout_info->menu->%s->title = "%s";',$name, $menus[$i]->title->body); - $buff .= sprintf('$layout_info->menu->%s->maxdepth = "%s";',$name, $menus[$i]->maxdepth->body); - - $buff .= sprintf('$layout_info->menu->%s->menu_srl = $vars->%s;', $name, $name); - $buff .= sprintf('$layout_info->menu->%s->xml_file = "./files/cache/menu/".$vars->%s.".xml.php";',$name, $name); - $buff .= sprintf('$layout_info->menu->%s->php_file = "./files/cache/menu/".$vars->%s.".php";',$name, $name); - } - } - - } - - - // header_script - $oModuleModel = &getModel('module'); - $layout_config = $oModuleModel->getModulePartConfig('layout', $layout_srl); - $header_script = trim($layout_config->header_script); - - if($header_script) $buff .= sprintf(' $layout_info->header_script = "%s"; ', str_replace('"','\\"',$header_script)); - - $buff = ''; - FileHandler::writeFile($cache_file, $buff); - if(file_exists($cache_file)) @include($cache_file); - return $layout_info; - } - - - /** - * @brief layout설정화면에서의 업로드한 이미지목록을 반환한다 - **/ - function getUserLayoutImageList($layout_srl){ - $path = $this->getUserLayoutImagePath($layout_srl); - $list = FileHandler::readDir($path); - return $list; - } - - - /** - * @brief ini config들을 가져온다 array다. - **/ - function getUserLayoutIniConfig($layout_srl, $layout_name=null){ - $file = $this->getUserLayoutIni($layout_srl); - if($layout_name && !file_exists(FileHandler::getRealPath($file))){ - FileHandler::copyFile($this->getDefaultLayoutIni($layout_name),$this->getUserLayoutIni($layout_srl)); - } - - $output = FileHandler::readIniFile($file); - return $output; - } - - /** - * @brief user layout path - **/ - function getUserLayoutPath($layout_srl){ - return sprintf("./files/faceOff/%s",getNumberingPath($layout_srl,3)); - } - - /** - * @brief user layout image path - **/ - function getUserLayoutImagePath($layout_srl){ - return $this->getUserLayoutPath($layout_srl). 'images/'; - } - - /** - * @brief user layout css 관리자가 설정화면에서 저장한 css - **/ - function getUserLayoutCss($layout_srl){ - return $this->getUserLayoutPath($layout_srl). 'layout.css'; - } - - - /** - * @brief faceoff용 css module handler에서 import 한다 - **/ - function getUserLayoutFaceOffCss($layout_srl){ - $src = $this->_getUserLayoutFaceOffCss($layout_srl); - if($this->useUserLayoutTemp == 'temp') return; - return $src; - } - - - /** - * @brief faceoff용 css module handler에서 import 한다 - **/ - function _getUserLayoutFaceOffCss($layout_srl){ - return $this->getUserLayoutPath($layout_srl). 'faceoff.css'; - } - - /** - * @brief user layout tmp html - **/ - function getUserLayoutTempFaceOffCss($layout_srl){ - return $this->getUserLayoutPath($layout_srl). 'tmp.faceoff.css'; - } - - - - /** - * @brief user layout html - **/ - function getUserLayoutHtml($layout_srl){ - $src = $this->getUserLayoutPath($layout_srl). 'layout.html'; - $temp = $this->getUserLayoutTempHtml($layout_srl); - if($this->useUserLayoutTemp == 'temp'){ - if(!file_exists(FileHandler::getRealPath($temp))) FileHandler::copyFile($src,$temp); - return $temp; - }else{ - return $src; - } - } - - /** - * @brief user layout tmp html - **/ - function getUserLayoutTempHtml($layout_srl){ - return $this->getUserLayoutPath($layout_srl). 'tmp.layout.html'; - } - - - /** - * @brief user layout ini - **/ - function getUserLayoutIni($layout_srl){ - $src = $this->getUserLayoutPath($layout_srl). 'layout.ini'; - $temp = $this->getUserLayoutTempIni($layout_srl); - if($this->useUserLayoutTemp == 'temp'){ - if(!file_exists(FileHandler::getRealPath($temp))) FileHandler::copyFile($src,$temp); - return $temp; - }else{ - return $src; - } - } - - /** - * @brief user layout tmp ini - **/ - function getUserLayoutTempIni($layout_srl){ - return $this->getUserLayoutPath($layout_srl). 'tmp.layout.ini'; - } - - /** - * @brief user layout cache - * todo 파일 자체를 삭제 필요가 있다 - **/ - function getUserLayoutCache($layout_srl,$lang_type){ - return $this->getUserLayoutPath($layout_srl). "{$lang_type}.cache.php"; - } - - /** - * @brief layout cache - **/ - function getLayoutCache($layout_name,$lang_type){ - return sprintf("./files/cache/layout/%s.%s.cache.php",$layout_name,$lang_type); - } - - /** - * @brief default layout ini 사용자의 임의 수정을 막기 위해 - **/ - function getDefaultLayoutIni($layout_name){ - return $this->getDefaultLayoutPath($layout_name). 'layout.ini'; - } - - /** - * @brief default layout html 사용자의 임의 수정을 막기 위해 - **/ - function getDefaultLayoutHtml($layout_name){ - return $this->getDefaultLayoutPath($layout_name). 'layout.html'; - } - - /** - * @brief default layout css 사용자의 임의 수정을 막기 위해 - **/ - function getDefaultLayoutCss($layout_name){ - return $this->getDefaultLayoutPath($layout_name). 'css/layout.css'; - } - - /** - * @brief default layout path 사용자의 임의 수정을 막기 위해 - **/ - function getDefaultLayoutPath() { - return "./modules/layout/faceoff/"; - } - - - /** - * @brief faceoff 인지 - **/ - function useDefaultLayout($layout_name){ - $info = $this->getLayoutInfo($layout_name); - if($info->type == 'faceoff') return true; - else return false; - } - - - /** - * @brief User Layout 을 임시 저장 모드로 - **/ - function setUseUserLayoutTemp($flag='temp'){ - $this->useUserLayoutTemp = $flag; - } - - - /** - * @brief User Layout 임시 저장 파일 목록. - **/ - function getUserLayoutTempFileList($layout_srl){ - $file_list = array( - $this->getUserLayoutTempHtml($layout_srl) - ,$this->getUserLayoutTempFaceOffCss($layout_srl) - ,$this->getUserLayoutTempIni($layout_srl) - ); - return $file_list; - } - - - /** - * @brief User Layout 저장 파일 목록. - **/ - function getUserLayoutFileList($layout_srl){ - $file_list = array( - basename($this->getUserLayoutHtml($layout_srl)) - ,basename($this->getUserLayoutFaceOffCss($layout_srl)) - ,basename($this->getUserLayoutIni($layout_srl)) - ,basename($this->getUserLayoutCss($layout_srl)) - ); - - $image_path = $this->getUserLayoutImagePath($layout_srl); - $image_list = FileHandler::readDir($image_path,'/(.*(?:swf|jpg|jpeg|gif|bmp|png)$)/i'); - - for($i=0,$c=count($image_list);$i<$c;$i++) $file_list[] = 'images/' . $image_list[$i]; - return $file_list; - } - - /** - * @brief faceOff관련 서비스 출력을 위한 동작 실행 - **/ - function doActivateFaceOff(&$layout_info) { - $layout_info->faceoff_ini_config = $this->getUserLayoutIniConfig($layout_info->layout_srl, $layout_info->layout); - - // 기본 faceoff layout CSS - Context::addCSSFile($this->getDefaultLayoutCss($layout_info->layout)); - - // 레이아웃 매니져에서 생성된 CSS - $faceoff_layout_css = $this->getUserLayoutFaceOffCss($layout_info->layout_srl); - if($faceoff_layout_css) Context::addCSSFile($faceoff_layout_css); - - // 레이아웃의 위젯을 위한 css출력 - Context::addCSSFile($this->module_path.'/tpl/css/widget.css'); - if($layout_info->extra_var->colorset->value == 'black') Context::addCSSFile($this->module_path.'/tpl/css/widget@black.css'); - else Context::addCSSFile($this->module_path.'/tpl/css/widget@white.css'); - - // 권한에 따른 다른 내용 출력 - $logged_info = Context::get('logged_info'); - - // faceOff 레이아웃 편집 버튼 노출 - if(Context::get('module')!='admin' && strpos(Context::get('act'),'Admin')===false && ($logged_info->is_admin == 'Y' || $logged_info->is_site_admin)) { - Context::addHtmlFooter(""); - } - - // faceOff페이지 수정시에 메뉴 출력 - if(Context::get('act')=='dispLayoutAdminLayoutModify' && ($logged_info->is_admin == 'Y' || $logged_info->is_site_admin)) { - $oTemplate = &TemplateHandler::getInstance(); - Context::addBodyHeader($oTemplate->compile($this->module_path.'/tpl', 'faceoff_layout_menu')); - } - } - } -?> +site_srl; + } + $args->site_srl = $site_srl; + $args->layout_type = $layout_type; + $output = executeQuery('layout.getLayoutList', $args); + if(!$output->data) return; + if(is_array($output->data)) return $output->data; + return array($output->data); + } + + /** + * @brief DB 에 생성된 한개의 레이아웃 정보를 구함 + * 생성된 레이아웃의 DB정보+XML정보를 return + **/ + function getLayout($layout_srl) { + // 일단 DB에서 정보를 가져옴 + $args->layout_srl = $layout_srl; + $output = executeQuery('layout.getLayout', $args); + if(!$output->data) return; + + // layout, extra_vars를 정리한 후 xml 파일 정보를 정리해서 return + $layout_info = $this->getLayoutInfo($layout, $output->data, $output->data->layout_type); + return $layout_info; + } + + /** + * @brief 레이아웃의 경로를 구함 + **/ + function getLayoutPath($layout_name, $layout_type = "P") { + if($layout_name == 'faceoff'){ + $class_path = './modules/layout/faceoff/'; + }else if($layout_type == "M") { + $class_path = sprintf("./m.layouts/%s/", $layout_name); + } + else + { + $class_path = sprintf('./layouts/%s/', $layout_name); + } + if(is_dir($class_path)) return $class_path; + return ""; + } + + /** + * @brief 레이아웃의 종류와 정보를 구함 + * 다운로드되어 있는 레이아웃의 종류 (생성과 다른 의미) + **/ + function getDownloadedLayoutList($layout_type = "P") { + // 다운받은 레이아웃과 설치된 레이아웃의 목록을 구함 + if($layout_type == "M") + { + $directory = "./m.layouts"; + } + else + { + $directory = "./layouts"; + } + + $searched_list = FileHandler::readDir($directory); + $searched_count = count($searched_list); + if(!$searched_count) return; + + natcasesort($searched_list); + + // 찾아진 레이아웃 목록을 loop돌면서 필요한 정보를 간추려 return + for($i=0;$i<$searched_count;$i++) { + // 레이아웃의 이름 + $layout = $searched_list[$i]; + + // 해당 레이아웃의 정보를 구함 + $layout_info = $this->getLayoutInfo($layout, null, $layout_type); + + $list[] = $layout_info; + } + return $list; + } + + /** + * @brief 모듈의 conf/info.xml 을 읽어서 정보를 구함 + * 이것 역시 캐싱을 통해서 xml parsing 시간을 줄인다.. + **/ + function getLayoutInfo($layout, $info = null, $layout_type = "P") { + if($info) { + $layout_title = $info->title; + $layout = $info->layout; + $layout_srl = $info->layout_srl; + $site_srl = $info->site_srl; + $vars = unserialize($info->extra_vars); + + if($info->module_srl) { + $layout_path = preg_replace('/([a-zA-Z0-9\_\.]+)(\.html)$/','',$info->layout_path); + $xml_file = sprintf('%sskin.xml', $layout_path); + } + } + + // 요청된 모듈의 경로를 구한다. 없으면 return + if(!$layout_path) $layout_path = $this->getLayoutPath($layout, $layout_type); + if(!is_dir($layout_path)) return; + + // 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음 + if(!$xml_file) $xml_file = sprintf("%sconf/info.xml", $layout_path); + if(!file_exists($xml_file)) { + $layout_info->layout = $layout; + $layout_info->path = $layout_path; + $layout_info->layout_title = $layout_title; + if(!$layout_info->layout_type) + $layout_info->layout_type = $layout_type; + return $layout_info; + } + + // cache 파일을 비교하여 문제 없으면 include하고 $layout_info 변수를 return + if(!$layout_srl){ + $cache_file = $this->getLayoutCache($layout, Context::getLangType()); + }else{ + $cache_file = $this->getUserLayoutCache($layout_srl, Context::getLangType()); + } + if(file_exists($cache_file)&&filemtime($cache_file)>filemtime($xml_file)) { + @include($cache_file); + + if($layout_info->extra_var && $vars) { + foreach($vars as $key => $value) { + if(!$layout_info->extra_var->{$key} && !$layout_info->{$key}) { + $layout_info->{$key} = $value; + } + } + } + return $layout_info; + } + + // cache 파일이 없으면 xml parsing하고 변수화 한 후에 캐시 파일에 쓰고 변수 바로 return + $oXmlParser = new XmlParser(); + $tmp_xml_obj = $oXmlParser->loadXmlFile($xml_file); + if($tmp_xml_obj->layout) $xml_obj = $tmp_xml_obj->layout; + elseif($tmp_xml_obj->skin) $xml_obj = $tmp_xml_obj->skin; + + if(!$xml_obj) return; + + $buff = ''; + $buff .= sprintf('$layout_info->site_srl = "%s";', $site_srl); + + if($xml_obj->version && $xml_obj->attrs->version == '0.2') { + // 레이아웃의 제목, 버전 + sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); + $date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $buff .= sprintf('$layout_info->layout = "%s";', $layout); + $buff .= sprintf('$layout_info->type = "%s";', $xml_obj->attrs->type); + $buff .= sprintf('$layout_info->path = "%s";', $layout_path); + $buff .= sprintf('$layout_info->title = "%s";', $xml_obj->title->body); + $buff .= sprintf('$layout_info->description = "%s";', $xml_obj->description->body); + $buff .= sprintf('$layout_info->version = "%s";', $xml_obj->version->body); + $buff .= sprintf('$layout_info->date = "%s";', $date); + $buff .= sprintf('$layout_info->homepage = "%s";', $xml_obj->link->body); + $buff .= sprintf('$layout_info->layout_srl = $layout_srl;'); + $buff .= sprintf('$layout_info->layout_title = $layout_title;'); + $buff .= sprintf('$layout_info->license = "%s";', $xml_obj->license->body); + $buff .= sprintf('$layout_info->license_link = "%s";', $xml_obj->license->attrs->link); + $buff .= sprintf('$layout_info->layout_type = "%s";', $layout_type); + + // 작성자 정보 + if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; + else $author_list = $xml_obj->author; + + for($i=0; $i < count($author_list); $i++) { + $buff .= sprintf('$layout_info->author['.$i.']->name = "%s";', $author_list[$i]->name->body); + $buff .= sprintf('$layout_info->author['.$i.']->email_address = "%s";', $author_list[$i]->attrs->email_address); + $buff .= sprintf('$layout_info->author['.$i.']->homepage = "%s";', $author_list[$i]->attrs->link); + } + + + + // 추가 변수 (템플릿에서 사용할 제작자 정의 변수) + $extra_var_groups = $xml_obj->extra_vars->group; + if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; + if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); + foreach($extra_var_groups as $group){ + $extra_vars = $group->var; + if($extra_vars) { + if(!is_array($extra_vars)) $extra_vars = array($extra_vars); + + $extra_var_count = count($extra_vars); + + $buff .= sprintf('$layout_info->extra_var_count = "%s";', $extra_var_count); + for($i=0;$i<$extra_var_count;$i++) { + unset($var); + unset($options); + $var = $extra_vars[$i]; + $name = $var->attrs->name; + + $buff .= sprintf('$layout_info->extra_var->%s->group = "%s";', $name, $group->title->body); + $buff .= sprintf('$layout_info->extra_var->%s->title = "%s";', $name, $var->title->body); + $buff .= sprintf('$layout_info->extra_var->%s->type = "%s";', $name, $var->attrs->type); + $buff .= sprintf('$layout_info->extra_var->%s->value = $vars->%s;', $name, $name); + $buff .= sprintf('$layout_info->extra_var->%s->description = "%s";', $name, str_replace('"','\"',$var->description->body)); + + $options = $var->options; + if(!$options) continue; + + if(!is_array($options)) $options = array($options); + $options_count = count($options); + for($j=0;$j<$options_count;$j++) { + $buff .= sprintf('$layout_info->extra_var->%s->options["%s"] = "%s";', $var->attrs->name, $options[$j]->attrs->value, $options[$j]->title->body); + } + } + } + } + + // 메뉴 + if($xml_obj->menus->menu) { + $menus = $xml_obj->menus->menu; + if(!is_array($menus)) $menus = array($menus); + + $menu_count = count($menus); + $buff .= sprintf('$layout_info->menu_count = "%s";', $menu_count); + for($i=0;$i<$menu_count;$i++) { + $name = $menus[$i]->attrs->name; + if($menus[$i]->attrs->default == "true") $buff .= sprintf('$layout_info->default_menu = "%s";', $name); + $buff .= sprintf('$layout_info->menu->%s->name = "%s";',$name, $menus[$i]->attrs->name); + $buff .= sprintf('$layout_info->menu->%s->title = "%s";',$name, $menus[$i]->title->body); + $buff .= sprintf('$layout_info->menu->%s->maxdepth = "%s";',$name, $menus[$i]->attrs->maxdepth); + + $buff .= sprintf('$layout_info->menu->%s->menu_srl = $vars->%s;', $name, $name); + $buff .= sprintf('$layout_info->menu->%s->xml_file = "./files/cache/menu/".$vars->%s.".xml.php";',$name, $name); + $buff .= sprintf('$layout_info->menu->%s->php_file = "./files/cache/menu/".$vars->%s.".php";',$name, $name); + } + } + + + // history + if($xml_obj->history) { + if(!is_array($xml_obj->history)) $history_list[] = $xml_obj->history; + else $history_list = $xml_obj->history; + + for($i=0; $i < count($history_list); $i++) { + sscanf($history_list[$i]->attrs->date, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); + $date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $buff .= sprintf('$layout_info->history['.$i.']->description = "%s";', $history_list[$i]->description->body); + $buff .= sprintf('$layout_info->history['.$i.']->version = "%s";', $history_list[$i]->attrs->version); + $buff .= sprintf('$layout_info->history['.$i.']->date = "%s";', $date); + + if($history_list[$i]->author) { + (!is_array($history_list[$i]->author)) ? $obj->author_list[] = $history_list[$i]->author : $obj->author_list = $history_list[$i]->author; + + for($j=0; $j < count($obj->author_list); $j++) { + $buff .= sprintf('$layout_info->history['.$i.']->author['.$j.']->name = "%s";', $obj->author_list[$j]->name->body); + $buff .= sprintf('$layout_info->history['.$i.']->author['.$j.']->email_address = "%s";', $obj->author_list[$j]->attrs->email_address); + $buff .= sprintf('$layout_info->history['.$i.']->author['.$j.']->homepage = "%s";', $obj->author_list[$j]->attrs->link); + } + } + + if($history_list[$i]->log) { + (!is_array($history_list[$i]->log)) ? $obj->log_list[] = $history_list[$i]->log : $obj->log_list = $history_list[$i]->log; + + for($j=0; $j < count($obj->log_list); $j++) { + $buff .= sprintf('$layout_info->history['.$i.']->logs['.$j.']->text = "%s";', $obj->log_list[$j]->body); + $buff .= sprintf('$layout_info->history['.$i.']->logs['.$j.']->link = "%s";', $obj->log_list[$j]->attrs->link); + } + } + } + } + + + + } else { + + // 레이아웃의 제목, 버전 + sscanf($xml_obj->author->attrs->date, '%d. %d. %d', $date_obj->y, $date_obj->m, $date_obj->d); + $date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $buff .= sprintf('$layout_info->layout = "%s";', $layout); + $buff .= sprintf('$layout_info->path = "%s";', $layout_path); + $buff .= sprintf('$layout_info->title = "%s";', $xml_obj->title->body); + $buff .= sprintf('$layout_info->description = "%s";', $xml_obj->author->description->body); + $buff .= sprintf('$layout_info->version = "%s";', $xml_obj->attrs->version); + $buff .= sprintf('$layout_info->date = "%s";', $date); + $buff .= sprintf('$layout_info->layout_srl = $layout_srl;'); + $buff .= sprintf('$layout_info->layout_title = $layout_title;'); + + // 작성자 정보 + $buff .= sprintf('$layout_info->author[0]->name = "%s";', $xml_obj->author->name->body); + $buff .= sprintf('$layout_info->author[0]->email_address = "%s";', $xml_obj->author->attrs->email_address); + $buff .= sprintf('$layout_info->author[0]->homepage = "%s";', $xml_obj->author->attrs->link); + + // 추가 변수 (템플릿에서 사용할 제작자 정의 변수) + $extra_var_groups = $xml_obj->extra_vars->group; + if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; + if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); + foreach($extra_var_groups as $group){ + $extra_vars = $group->var; + if($extra_vars) { + if(!is_array($extra_vars)) $extra_vars = array($extra_vars); + + $extra_var_count = count($extra_vars); + + $buff .= sprintf('$layout_info->extra_var_count = "%s";', $extra_var_count); + for($i=0;$i<$extra_var_count;$i++) { + unset($var); + unset($options); + $var = $extra_vars[$i]; + $name = $var->attrs->name; + + $buff .= sprintf('$layout_info->extra_var->%s->group = "%s";', $name, $group->title->body); + $buff .= sprintf('$layout_info->extra_var->%s->title = "%s";', $name, $var->title->body); + $buff .= sprintf('$layout_info->extra_var->%s->type = "%s";', $name, $var->attrs->type); + $buff .= sprintf('$layout_info->extra_var->%s->value = $vars->%s;', $name, $name); + $buff .= sprintf('$layout_info->extra_var->%s->description = "%s";', $name, str_replace('"','\"',$var->description->body)); + + $options = $var->options; + if(!$options) continue; + + if(!is_array($options)) $options = array($options); + $options_count = count($options); + for($j=0;$j<$options_count;$j++) { + $buff .= sprintf('$layout_info->extra_var->%s->options["%s"] = "%s";', $var->attrs->name, $options[$j]->value->body, $options[$j]->title->body); + } + } + } + } + + // 메뉴 + if($xml_obj->menus->menu) { + $menus = $xml_obj->menus->menu; + if(!is_array($menus)) $menus = array($menus); + + $menu_count = count($menus); + $buff .= sprintf('$layout_info->menu_count = "%s";', $menu_count); + for($i=0;$i<$menu_count;$i++) { + $name = $menus[$i]->attrs->name; + if($menus[$i]->attrs->default == "true") $buff .= sprintf('$layout_info->default_menu = "%s";', $name); + $buff .= sprintf('$layout_info->menu->%s->name = "%s";',$name, $menus[$i]->attrs->name); + $buff .= sprintf('$layout_info->menu->%s->title = "%s";',$name, $menus[$i]->title->body); + $buff .= sprintf('$layout_info->menu->%s->maxdepth = "%s";',$name, $menus[$i]->maxdepth->body); + + $buff .= sprintf('$layout_info->menu->%s->menu_srl = $vars->%s;', $name, $name); + $buff .= sprintf('$layout_info->menu->%s->xml_file = "./files/cache/menu/".$vars->%s.".xml.php";',$name, $name); + $buff .= sprintf('$layout_info->menu->%s->php_file = "./files/cache/menu/".$vars->%s.".php";',$name, $name); + } + } + + } + + + // header_script + $oModuleModel = &getModel('module'); + $layout_config = $oModuleModel->getModulePartConfig('layout', $layout_srl); + $header_script = trim($layout_config->header_script); + + if($header_script) $buff .= sprintf(' $layout_info->header_script = "%s"; ', str_replace('"','\\"',$header_script)); + + $buff = ''; + FileHandler::writeFile($cache_file, $buff); + if(file_exists($cache_file)) @include($cache_file); + return $layout_info; + } + + + /** + * @brief layout설정화면에서의 업로드한 이미지목록을 반환한다 + **/ + function getUserLayoutImageList($layout_srl){ + $path = $this->getUserLayoutImagePath($layout_srl); + $list = FileHandler::readDir($path); + return $list; + } + + + /** + * @brief ini config들을 가져온다 array다. + **/ + function getUserLayoutIniConfig($layout_srl, $layout_name=null){ + $file = $this->getUserLayoutIni($layout_srl); + if($layout_name && !file_exists(FileHandler::getRealPath($file))){ + FileHandler::copyFile($this->getDefaultLayoutIni($layout_name),$this->getUserLayoutIni($layout_srl)); + } + + $output = FileHandler::readIniFile($file); + return $output; + } + + /** + * @brief user layout path + **/ + function getUserLayoutPath($layout_srl){ + return sprintf("./files/faceOff/%s",getNumberingPath($layout_srl,3)); + } + + /** + * @brief user layout image path + **/ + function getUserLayoutImagePath($layout_srl){ + return $this->getUserLayoutPath($layout_srl). 'images/'; + } + + /** + * @brief user layout css 관리자가 설정화면에서 저장한 css + **/ + function getUserLayoutCss($layout_srl){ + return $this->getUserLayoutPath($layout_srl). 'layout.css'; + } + + + /** + * @brief faceoff용 css module handler에서 import 한다 + **/ + function getUserLayoutFaceOffCss($layout_srl){ + $src = $this->_getUserLayoutFaceOffCss($layout_srl); + if($this->useUserLayoutTemp == 'temp') return; + return $src; + } + + + /** + * @brief faceoff용 css module handler에서 import 한다 + **/ + function _getUserLayoutFaceOffCss($layout_srl){ + return $this->getUserLayoutPath($layout_srl). 'faceoff.css'; + } + + /** + * @brief user layout tmp html + **/ + function getUserLayoutTempFaceOffCss($layout_srl){ + return $this->getUserLayoutPath($layout_srl). 'tmp.faceoff.css'; + } + + + + /** + * @brief user layout html + **/ + function getUserLayoutHtml($layout_srl){ + $src = $this->getUserLayoutPath($layout_srl). 'layout.html'; + $temp = $this->getUserLayoutTempHtml($layout_srl); + if($this->useUserLayoutTemp == 'temp'){ + if(!file_exists(FileHandler::getRealPath($temp))) FileHandler::copyFile($src,$temp); + return $temp; + }else{ + return $src; + } + } + + /** + * @brief user layout tmp html + **/ + function getUserLayoutTempHtml($layout_srl){ + return $this->getUserLayoutPath($layout_srl). 'tmp.layout.html'; + } + + + /** + * @brief user layout ini + **/ + function getUserLayoutIni($layout_srl){ + $src = $this->getUserLayoutPath($layout_srl). 'layout.ini'; + $temp = $this->getUserLayoutTempIni($layout_srl); + if($this->useUserLayoutTemp == 'temp'){ + if(!file_exists(FileHandler::getRealPath($temp))) FileHandler::copyFile($src,$temp); + return $temp; + }else{ + return $src; + } + } + + /** + * @brief user layout tmp ini + **/ + function getUserLayoutTempIni($layout_srl){ + return $this->getUserLayoutPath($layout_srl). 'tmp.layout.ini'; + } + + /** + * @brief user layout cache + * todo 파일 자체를 삭제 필요가 있다 + **/ + function getUserLayoutCache($layout_srl,$lang_type){ + return $this->getUserLayoutPath($layout_srl). "{$lang_type}.cache.php"; + } + + /** + * @brief layout cache + **/ + function getLayoutCache($layout_name,$lang_type){ + return sprintf("./files/cache/layout/%s.%s.cache.php",$layout_name,$lang_type); + } + + /** + * @brief default layout ini 사용자의 임의 수정을 막기 위해 + **/ + function getDefaultLayoutIni($layout_name){ + return $this->getDefaultLayoutPath($layout_name). 'layout.ini'; + } + + /** + * @brief default layout html 사용자의 임의 수정을 막기 위해 + **/ + function getDefaultLayoutHtml($layout_name){ + return $this->getDefaultLayoutPath($layout_name). 'layout.html'; + } + + /** + * @brief default layout css 사용자의 임의 수정을 막기 위해 + **/ + function getDefaultLayoutCss($layout_name){ + return $this->getDefaultLayoutPath($layout_name). 'css/layout.css'; + } + + /** + * @brief default layout path 사용자의 임의 수정을 막기 위해 + **/ + function getDefaultLayoutPath() { + return "./modules/layout/faceoff/"; + } + + + /** + * @brief faceoff 인지 + **/ + function useDefaultLayout($layout_name){ + $info = $this->getLayoutInfo($layout_name); + if($info->type == 'faceoff') return true; + else return false; + } + + + /** + * @brief User Layout 을 임시 저장 모드로 + **/ + function setUseUserLayoutTemp($flag='temp'){ + $this->useUserLayoutTemp = $flag; + } + + + /** + * @brief User Layout 임시 저장 파일 목록. + **/ + function getUserLayoutTempFileList($layout_srl){ + $file_list = array( + $this->getUserLayoutTempHtml($layout_srl) + ,$this->getUserLayoutTempFaceOffCss($layout_srl) + ,$this->getUserLayoutTempIni($layout_srl) + ); + return $file_list; + } + + + /** + * @brief User Layout 저장 파일 목록. + **/ + function getUserLayoutFileList($layout_srl){ + $file_list = array( + basename($this->getUserLayoutHtml($layout_srl)) + ,basename($this->getUserLayoutFaceOffCss($layout_srl)) + ,basename($this->getUserLayoutIni($layout_srl)) + ,basename($this->getUserLayoutCss($layout_srl)) + ); + + $image_path = $this->getUserLayoutImagePath($layout_srl); + $image_list = FileHandler::readDir($image_path,'/(.*(?:swf|jpg|jpeg|gif|bmp|png)$)/i'); + + for($i=0,$c=count($image_list);$i<$c;$i++) $file_list[] = 'images/' . $image_list[$i]; + return $file_list; + } + + /** + * @brief faceOff관련 서비스 출력을 위한 동작 실행 + **/ + function doActivateFaceOff(&$layout_info) { + $layout_info->faceoff_ini_config = $this->getUserLayoutIniConfig($layout_info->layout_srl, $layout_info->layout); + + // 기본 faceoff layout CSS + Context::addCSSFile($this->getDefaultLayoutCss($layout_info->layout)); + + // 레이아웃 매니져에서 생성된 CSS + $faceoff_layout_css = $this->getUserLayoutFaceOffCss($layout_info->layout_srl); + if($faceoff_layout_css) Context::addCSSFile($faceoff_layout_css); + + // 레이아웃의 위젯을 위한 css출력 + Context::addCSSFile($this->module_path.'/tpl/css/widget.css'); + if($layout_info->extra_var->colorset->value == 'black') Context::addCSSFile($this->module_path.'/tpl/css/widget@black.css'); + else Context::addCSSFile($this->module_path.'/tpl/css/widget@white.css'); + + // 권한에 따른 다른 내용 출력 + $logged_info = Context::get('logged_info'); + + // faceOff 레이아웃 편집 버튼 노출 + if(Context::get('module')!='admin' && strpos(Context::get('act'),'Admin')===false && ($logged_info->is_admin == 'Y' || $logged_info->is_site_admin)) { + Context::addHtmlFooter(""); + } + + // faceOff페이지 수정시에 메뉴 출력 + if(Context::get('act')=='dispLayoutAdminLayoutModify' && ($logged_info->is_admin == 'Y' || $logged_info->is_site_admin)) { + $oTemplate = &TemplateHandler::getInstance(); + Context::addBodyHeader($oTemplate->compile($this->module_path.'/tpl', 'faceoff_layout_menu')); + } + } + } +?> diff --git a/modules/layout/layout.view.php b/modules/layout/layout.view.php index 4d7c78978..50adf6552 100644 --- a/modules/layout/layout.view.php +++ b/modules/layout/layout.view.php @@ -1,34 +1,34 @@ -setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief 레이아웃의 상세 정보(conf/info.xml)를 팝업 출력 - **/ - function dispLayoutInfo() { - // 선택된 레이아웃 정보를 구함 - $oLayoutModel = &getModel('layout'); - $layout_info = $oLayoutModel->getLayoutInfo(Context::get('selected_layout')); - if(!$layout_info) exit(); - Context::set('layout_info', $layout_info); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('layout_detail_info'); - } - } -?> +setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief 레이아웃의 상세 정보(conf/info.xml)를 팝업 출력 + **/ + function dispLayoutInfo() { + // 선택된 레이아웃 정보를 구함 + $oLayoutModel = &getModel('layout'); + $layout_info = $oLayoutModel->getLayoutInfo(Context::get('selected_layout')); + if(!$layout_info) exit(); + Context::set('layout_info', $layout_info); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('layout_detail_info'); + } + } +?> diff --git a/modules/layout/tpl/css/widget.css b/modules/layout/tpl/css/widget.css index 688338131..e27138fee 100755 --- a/modules/layout/tpl/css/widget.css +++ b/modules/layout/tpl/css/widget.css @@ -1,5 +1,5 @@ @charset "utf-8"; -/* NHN > UIT Center > Open UI Technology Team > Jeong Chan Myeong(dece24@nhncorp.com) */ +/* NHN (developers@xpressengine.com) */ /* common */ .open{ display:block !important;} diff --git a/modules/layout/tpl/js/ui.hotkey.js b/modules/layout/tpl/js/ui.hotkey.js index a56d3d10a..f0fe5b336 100644 --- a/modules/layout/tpl/js/ui.hotkey.js +++ b/modules/layout/tpl/js/ui.hotkey.js @@ -1,119 +1,118 @@ -/* - * jQuery Hotkey Plug-in - * - * @author Kim Taegon(gonom9@nhncorp.com) - */ - -(function($){ - -// virtual keys -var VKEY = { - 'TAB' : 9, - 'ESC' : 27, - 'ENTER,RETURN' : 13, - 'UP' : 38, - 'DOWN' : 40, - 'LEFT' : 37, - 'RIGHT' : 39, - 'BACKSPACE,BKSP' : 8, - 'DEL' : 46, - 'SPACE' : 32 -}; - -var Hotkey = new Object; - -$.fn.hotkey = function(key, func) { - if (typeof key == "object" && key.toString() == '[object Object]') { - for(var x in key) $(this).hotkey(x, key[x]); - return this; - } - - if (!$.isString(key)) return this; - if (key == 'disable' || key == 'enable') { - this.attr('hotkey_disabled', (key=='disable')); - return this; - } - - if (!$.isFunction(func)) return this; - if ($.isObject(key)) key = hk2str(key); - - Hotkey[key] = func; - - if (!this.attr('assign-hotkey')) { - this.attr('assign-hotkey', true); - - this.keydown(function(evt){ - if ($(this).attr('hotkey_disabled')) return; - - var stroke = hk2str(evt).split(','); - - for(var i=0; i < stroke.length; i++) { - if (Hotkey[stroke[i]]) { - if ($(evt.target).is(':input') && (evt.ctrlKey||evt.altKey||evt.metaKey)) break; - - Hotkey[stroke[i]](evt, stroke[i]); - - evt.stopPropagation(); - evt.preventDefault(); - } - } - }); - } - - return this; -}; - -$.extend({ - isObject : function(obj) { - return (typeof obj == 'object' && obj.toString() == '[object Object]'); - }, - isArray : function(arr) { - return (Object.prototype.toString.call(arr) == '[object Array]'); - }, - isString : function(str) { - return (typeof str == 'string'); - } -}); - -// hotkey to string -function hk2str(key) { - var str = [], vkey = false; - var _ = null; // do nothing. It is just dummy. - - for(var x in VKEY) { - if (VKEY[x] == key.keyCode) { - vkey = x; - break; - } - } - if (!vkey) { - vkey = String.fromCharCode(key.keyCode).toUpperCase(); - if (vkey.length != 1) return ''; - } - - key.altKey?str.push('Alt'):_; - key.ctrlKey?str.push('Ctrl'):_; - key.shiftKey?str.push('Shift'):_; - - str.push(vkey); - - return str.join('+'); -} - -// string to hotkey -function str2hk(str) { - var key = {altKey:false,ctrlKey:false,shiftKey:false,keyCode:0}; - var lastKey = str.match(/\+([A-Z0-9]+)$/)[1]; - - if (!lastKey) return key; - - str += '+'; - - key.altKey = str.indexOf('Alt+') > -1; - key.ctrlKey = str.indexOf('Ctrl+') > -1; - key.shiftKey = str.indexOf('Shift+') > -1; - - key.keyCode = VKEY[lastKey] || lastKey.charCodeAt(0); -} - +/* + * jQuery Hotkey Plug-in + * @author NHN (developer@xpressengine.com) + */ + +(function($){ + +// virtual keys +var VKEY = { + 'TAB' : 9, + 'ESC' : 27, + 'ENTER,RETURN' : 13, + 'UP' : 38, + 'DOWN' : 40, + 'LEFT' : 37, + 'RIGHT' : 39, + 'BACKSPACE,BKSP' : 8, + 'DEL' : 46, + 'SPACE' : 32 +}; + +var Hotkey = new Object; + +$.fn.hotkey = function(key, func) { + if (typeof key == "object" && key.toString() == '[object Object]') { + for(var x in key) $(this).hotkey(x, key[x]); + return this; + } + + if (!$.isString(key)) return this; + if (key == 'disable' || key == 'enable') { + this.attr('hotkey_disabled', (key=='disable')); + return this; + } + + if (!$.isFunction(func)) return this; + if ($.isObject(key)) key = hk2str(key); + + Hotkey[key] = func; + + if (!this.attr('assign-hotkey')) { + this.attr('assign-hotkey', true); + + this.keydown(function(evt){ + if ($(this).attr('hotkey_disabled')) return; + + var stroke = hk2str(evt).split(','); + + for(var i=0; i < stroke.length; i++) { + if (Hotkey[stroke[i]]) { + if ($(evt.target).is(':input') && (evt.ctrlKey||evt.altKey||evt.metaKey)) break; + + Hotkey[stroke[i]](evt, stroke[i]); + + evt.stopPropagation(); + evt.preventDefault(); + } + } + }); + } + + return this; +}; + +$.extend({ + isObject : function(obj) { + return (typeof obj == 'object' && obj.toString() == '[object Object]'); + }, + isArray : function(arr) { + return (Object.prototype.toString.call(arr) == '[object Array]'); + }, + isString : function(str) { + return (typeof str == 'string'); + } +}); + +// hotkey to string +function hk2str(key) { + var str = [], vkey = false; + var _ = null; // do nothing. It is just dummy. + + for(var x in VKEY) { + if (VKEY[x] == key.keyCode) { + vkey = x; + break; + } + } + if (!vkey) { + vkey = String.fromCharCode(key.keyCode).toUpperCase(); + if (vkey.length != 1) return ''; + } + + key.altKey?str.push('Alt'):_; + key.ctrlKey?str.push('Ctrl'):_; + key.shiftKey?str.push('Shift'):_; + + str.push(vkey); + + return str.join('+'); +} + +// string to hotkey +function str2hk(str) { + var key = {altKey:false,ctrlKey:false,shiftKey:false,keyCode:0}; + var lastKey = str.match(/\+([A-Z0-9]+)$/)[1]; + + if (!lastKey) return key; + + str += '+'; + + key.altKey = str.indexOf('Alt+') > -1; + key.ctrlKey = str.indexOf('Ctrl+') > -1; + key.shiftKey = str.indexOf('Shift+') > -1; + + key.keyCode = VKEY[lastKey] || lastKey.charCodeAt(0); +} + })(jQuery); \ No newline at end of file diff --git a/modules/layout/tpl/js/ui.toolbar.js b/modules/layout/tpl/js/ui.toolbar.js index ccb061912..10989ffc6 100644 --- a/modules/layout/tpl/js/ui.toolbar.js +++ b/modules/layout/tpl/js/ui.toolbar.js @@ -1,139 +1,138 @@ -/* - * jQuery Toolbar Plug-in - * - * @author Kim Taegon(gonom9@nhncorp.com) - */ - -(function($){ - -$.fn.toolbar = function(settings) { - settings = $.extend({ - items : '.buttons button', - fade : false, - click : function(){}, - hover : function(){}, - show : function(){}, - hide : function(){} - }, settings); - - // get elements - var items = this.find(settings.items); - var menus = items.find('+ ul'); - var menuitems = menus.find('> li'); - - // hover action - submenu - menus.mouseout( - function(event) { - var el = $(event.relatedTarget).parents().add(event.relatedTarget); - - if ( el.index(this) < 0 && el.index($(this).prev()) < 0 ) hideMenu($(this), settings); - } - ).click( - function(event) { - var item = $(event.target).parent(); - - var data = createData(item); - - if ( !item.is('li') ) return; - - // radio button - selectItem(data); - - // callback - settings.click(data); - } - ); - - menuitems.mouseover( - function(event){ - var item = $(this); - - item.parent().find('> li').removeClass('tb-menu-item-hover'); - item.addClass('tb-menu-item-hover'); - - // callback - settings.hover(createData(item)); - } - ); - - // hover action - button - items.hover( - function(event) { - showMenu($(this).find('+ ul'), settings); - }, - function(event) { - var menu = $(this).find('+ ul'); - var el = $(event.relatedTarget).parents().add(event.relatedTarget); - - // hide menu - if ( el.index(menu) < 0 && el.index(this) < 0 ) hideMenu(menu, settings); - } - ); - - return this; -} - -function hideMenu(menu, settings) { - menu[settings.fade?'fadeOut':'hide'](settings.fade) - .removeClass('tb-menu-active') - .find('> li').removeClass('tb-menu-item-hover'); - - menu.prev().removeClass('tb-btn-active'); - - // hidemenu event - settings.hide(menu); -} - -function showMenu(menu, settings) { - menu[settings.fade?'fadeIn':'show'](settings.fade) - .addClass('tb-menu-active') - .css({position:'absolute',left:0,top:0}); - - menu.prev().addClass('tb-btn-active'); - - // positioning - var btn = menu.prev(); - var btn_pos = btn.offset(); - var mnu_pos = menu.offset(); - - menu.css({ - left : btn_pos.left - mnu_pos.left, - top : btn_pos.top - mnu_pos.top + btn.height() - }) - - // showmenu event - settings.show(menu); -} - -function selectItem(data) { - var item = data.element; - - switch(data.type){ - case 'radio': - item.parent().find('> li').removeClass('tb-menu-item-selected'); - item.addClass('tb-menu-item-selected') - data.checked = true; - break; - case 'checkbox': - data.checked = !data.checked; - if (data.checked) { - item.addClass('tb-menu-item-selected'); - } else { - item.removeClass('tb-menu-item-selected'); - } - break; - default: - break; - }; -} - -function createData(item) { - return { - element : item, - type : item.attr('tb:type'), - arg : item.attr('tb:arg'), - checked : item.hasClass('tb-menu-item-selected') - }; -} - +/* + * jQuery Toolbar Plug-in + * @author NHN (developer@xpressengine.com) + */ + +(function($){ + +$.fn.toolbar = function(settings) { + settings = $.extend({ + items : '.buttons button', + fade : false, + click : function(){}, + hover : function(){}, + show : function(){}, + hide : function(){} + }, settings); + + // get elements + var items = this.find(settings.items); + var menus = items.find('+ ul'); + var menuitems = menus.find('> li'); + + // hover action - submenu + menus.mouseout( + function(event) { + var el = $(event.relatedTarget).parents().add(event.relatedTarget); + + if ( el.index(this) < 0 && el.index($(this).prev()) < 0 ) hideMenu($(this), settings); + } + ).click( + function(event) { + var item = $(event.target).parent(); + + var data = createData(item); + + if ( !item.is('li') ) return; + + // radio button + selectItem(data); + + // callback + settings.click(data); + } + ); + + menuitems.mouseover( + function(event){ + var item = $(this); + + item.parent().find('> li').removeClass('tb-menu-item-hover'); + item.addClass('tb-menu-item-hover'); + + // callback + settings.hover(createData(item)); + } + ); + + // hover action - button + items.hover( + function(event) { + showMenu($(this).find('+ ul'), settings); + }, + function(event) { + var menu = $(this).find('+ ul'); + var el = $(event.relatedTarget).parents().add(event.relatedTarget); + + // hide menu + if ( el.index(menu) < 0 && el.index(this) < 0 ) hideMenu(menu, settings); + } + ); + + return this; +} + +function hideMenu(menu, settings) { + menu[settings.fade?'fadeOut':'hide'](settings.fade) + .removeClass('tb-menu-active') + .find('> li').removeClass('tb-menu-item-hover'); + + menu.prev().removeClass('tb-btn-active'); + + // hidemenu event + settings.hide(menu); +} + +function showMenu(menu, settings) { + menu[settings.fade?'fadeIn':'show'](settings.fade) + .addClass('tb-menu-active') + .css({position:'absolute',left:0,top:0}); + + menu.prev().addClass('tb-btn-active'); + + // positioning + var btn = menu.prev(); + var btn_pos = btn.offset(); + var mnu_pos = menu.offset(); + + menu.css({ + left : btn_pos.left - mnu_pos.left, + top : btn_pos.top - mnu_pos.top + btn.height() + }) + + // showmenu event + settings.show(menu); +} + +function selectItem(data) { + var item = data.element; + + switch(data.type){ + case 'radio': + item.parent().find('> li').removeClass('tb-menu-item-selected'); + item.addClass('tb-menu-item-selected') + data.checked = true; + break; + case 'checkbox': + data.checked = !data.checked; + if (data.checked) { + item.addClass('tb-menu-item-selected'); + } else { + item.removeClass('tb-menu-item-selected'); + } + break; + default: + break; + }; +} + +function createData(item) { + return { + element : item, + type : item.attr('tb:type'), + arg : item.attr('tb:arg'), + checked : item.hasClass('tb-menu-item-selected') + }; +} + })(jQuery); \ No newline at end of file diff --git a/modules/member/conf/info.xml b/modules/member/conf/info.xml index 7f188c8b7..8a78118d0 100644 --- a/modules/member/conf/info.xml +++ b/modules/member/conf/info.xml @@ -1,33 +1,33 @@ - - - 회원 관리 - 会员管理 - 会員 管理 - Member Management - Quản lý thành viên - Usuario Gestión - Управление пользователями - 會員 管理 - 회원 관리 및 회원 관련 설정등을 하는 모듈입니다. - 对会员进行管理及相关设置的模块。 - 会員管理及び会員関連設定などを行うモジュールです。 - This module is for managing or configuring members. - Module này dành cho việc quản lý và tạo thành viên. - Este módulo es para el manejo y la configuración de los usuarios. - Этот модуль служит для управления и конфигурирования пользователей. - 對會員進行管理與相關設置的模組。 - 0.1 - 2007-02-28 - member - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 회원 관리 + 会员管理 + 会員 管理 + Member Management + Quản lý thành viên + Usuario Gestión + Управление пользователями + 會員 管理 + 회원 관리 및 회원 관련 설정등을 하는 모듈입니다. + 对会员进行管理及相关设置的模块。 + 会員管理及び会員関連設定などを行うモジュールです。 + This module is for managing or configuring members. + Module này dành cho việc quản lý và tạo thành viên. + Este módulo es para el manejo y la configuración de los usuarios. + Этот модуль служит для управления и конфигурирования пользователей. + 對會員進行管理與相關設置的模組。 + 0.1 + 2007-02-28 + member + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/member/lang/en.lang.php b/modules/member/lang/en.lang.php index a22ceaf21..a824dd73f 100644 --- a/modules/member/lang/en.lang.php +++ b/modules/member/lang/en.lang.php @@ -1,7 +1,7 @@ | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; + * @author NHN (developers@xpressengine.com) | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; * @brief Russian basic language pack **/ diff --git a/modules/member/lang/vi.lang.php b/modules/member/lang/vi.lang.php index cd3a04943..db0136345 100644 --- a/modules/member/lang/vi.lang.php +++ b/modules/member/lang/vi.lang.php @@ -1,7 +1,7 @@ is_admin = Context::get('is_admin')=='Y'?'Y':''; - $args->is_denied = Context::get('is_denied')=='Y'?'Y':''; - $args->selected_group_srl = Context::get('selected_group_srl'); - - $search_target = trim(Context::get('search_target')); - $search_keyword = trim(Context::get('search_keyword')); - - if($search_target && $search_keyword) { - switch($search_target) { - case 'user_id' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_user_id = $search_keyword; - break; - case 'user_name' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_user_name = $search_keyword; - break; - case 'nick_name' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_nick_name = $search_keyword; - break; - case 'email_address' : - if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); - $args->s_email_address = $search_keyword; - break; - case 'regdate' : - $args->s_regdate = ereg_replace("[^0-9]","",$search_keyword); - break; - case 'regdate_more' : - $args->s_regdate_more = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); - break; - case 'regdate_less' : - $args->s_regdate_less = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); - break; - case 'last_login' : - $args->s_last_login = $search_keyword; - break; - case 'last_login_more' : - $args->s_last_login_more = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); - break; - case 'last_login_less' : - $args->s_last_login_less = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); - break; - case 'extra_vars' : - $args->s_extra_vars = ereg_replace("[^0-9]","",$search_keyword); - break; - } - } - - // selected_group_srl이 있으면 query id를 변경 (table join때문에) - $sort_index = Context::get('sort_index'); - if($sort_index != 'last_login') $sort_index = "member_srl"; - if($args->selected_group_srl) { - $query_id = 'member.getMemberListWithinGroup'; - $args->sort_index = "member.".$sort_index; - } else { - $query_id = 'member.getMemberList'; - $args->sort_index = $sort_index; - } - $sort_order = Context::get('sort_order'); - if($sort_order != "asc") $sort_order = "desc"; - $args->sort_order = $sort_order; - Context::set('sort_order', $sort_order); - - // 기타 변수들 정리 - $args->page = Context::get('page'); - $args->list_count = 40; - $args->page_count = 10; - return executeQuery($query_id, $args); - } - - /** - * @brief 사이트별 회원 목록을 구함 - **/ - function getSiteMemberList($site_srl, $page = 1) { - $args->site_srl = $site_srl; - $args->page = $page; - $args->list_count = 40; - $args->page_count = 10; - $query_id = 'member.getSiteMemberList'; - $output = executeQueryArray($query_id, $args); - return $output; - } - - /** - * @brief 회원 모듈의 특정 스킨에 속한 컬러셋 목록을 return - **/ - function getMemberAdminColorset() { - $skin = Context::get('skin'); - if(!$skin) $tpl = ""; - else { - $oModuleModel = &getModel('module'); - $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $skin); - Context::set('skin_info', $skin_info); - - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if(!$config->colorset) $config->colorset = "white"; - Context::set('config', $config); - - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'colorset_list'); - } - - $this->add('tpl', $tpl); - } - - } -?> +is_admin = Context::get('is_admin')=='Y'?'Y':''; + $args->is_denied = Context::get('is_denied')=='Y'?'Y':''; + $args->selected_group_srl = Context::get('selected_group_srl'); + + $search_target = trim(Context::get('search_target')); + $search_keyword = trim(Context::get('search_keyword')); + + if($search_target && $search_keyword) { + switch($search_target) { + case 'user_id' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_user_id = $search_keyword; + break; + case 'user_name' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_user_name = $search_keyword; + break; + case 'nick_name' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_nick_name = $search_keyword; + break; + case 'email_address' : + if($search_keyword) $search_keyword = str_replace(' ','%',$search_keyword); + $args->s_email_address = $search_keyword; + break; + case 'regdate' : + $args->s_regdate = ereg_replace("[^0-9]","",$search_keyword); + break; + case 'regdate_more' : + $args->s_regdate_more = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); + break; + case 'regdate_less' : + $args->s_regdate_less = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); + break; + case 'last_login' : + $args->s_last_login = $search_keyword; + break; + case 'last_login_more' : + $args->s_last_login_more = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); + break; + case 'last_login_less' : + $args->s_last_login_less = substr(ereg_replace("[^0-9]","",$search_keyword) . '00000000000000',0,14); + break; + case 'extra_vars' : + $args->s_extra_vars = ereg_replace("[^0-9]","",$search_keyword); + break; + } + } + + // selected_group_srl이 있으면 query id를 변경 (table join때문에) + $sort_index = Context::get('sort_index'); + if($sort_index != 'last_login') $sort_index = "member_srl"; + if($args->selected_group_srl) { + $query_id = 'member.getMemberListWithinGroup'; + $args->sort_index = "member.".$sort_index; + } else { + $query_id = 'member.getMemberList'; + $args->sort_index = $sort_index; + } + $sort_order = Context::get('sort_order'); + if($sort_order != "asc") $sort_order = "desc"; + $args->sort_order = $sort_order; + Context::set('sort_order', $sort_order); + + // 기타 변수들 정리 + $args->page = Context::get('page'); + $args->list_count = 40; + $args->page_count = 10; + return executeQuery($query_id, $args); + } + + /** + * @brief 사이트별 회원 목록을 구함 + **/ + function getSiteMemberList($site_srl, $page = 1) { + $args->site_srl = $site_srl; + $args->page = $page; + $args->list_count = 40; + $args->page_count = 10; + $query_id = 'member.getSiteMemberList'; + $output = executeQueryArray($query_id, $args); + return $output; + } + + /** + * @brief 회원 모듈의 특정 스킨에 속한 컬러셋 목록을 return + **/ + function getMemberAdminColorset() { + $skin = Context::get('skin'); + if(!$skin) $tpl = ""; + else { + $oModuleModel = &getModel('module'); + $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $skin); + Context::set('skin_info', $skin_info); + + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if(!$config->colorset) $config->colorset = "white"; + Context::set('config', $config); + + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'colorset_list'); + } + + $this->add('tpl', $tpl); + } + + } +?> diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index fe8bd9ad3..acf485f20 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -1,241 +1,241 @@ -member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - if(!$this->member_info) Context::set('member_srl',''); - else Context::set('member_info',$this->member_info); - } - - // retrieve group list - $this->group_list = $oMemberModel->getGroups(); - Context::set('group_list', $this->group_list); - - $this->setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief display member list - **/ - function dispMemberAdminList() { - - $oMemberAdminModel = &getAdminModel('member'); - $oMemberModel = &getModel('member'); - $output = $oMemberAdminModel->getMemberList(); - - // retrieve list of groups for each member - if($output->data) { - foreach($output->data as $key => $member) { - $output->data[$key]->group_list = $oMemberModel->getMemberGroups($member->member_srl,0); - } - } - - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('member_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('member_list'); - } - - /** - * @brief default configuration for member management - **/ - function dispMemberAdminConfig() { - // retrieve configuration via module model instance - $oModuleModel = &getModel('module'); - $oMemberModel = &getModel('member'); - $config = $oMemberModel->getMemberConfig(); - Context::set('config',$config); - - // list of skins for member module - $skin_list = $oModuleModel->getSkins($this->module_path); - Context::set('skin_list', $skin_list); - - // retrieve skins of editor - $oEditorModel = &getModel('editor'); - Context::set('editor_skin_list', $oEditorModel->getEditorSkinList()); - - // get an editor - $option->primary_key_name = 'temp_srl'; - $option->content_key_name = 'agreement'; - $option->allow_fileupload = false; - $option->enable_autosave = false; - $option->enable_default_component = true; - $option->enable_component = true; - $option->resizable = true; - $option->height = 300; - $editor = $oEditorModel->getEditor(0, $option); - Context::set('editor', $editor); - - $this->setTemplateFile('member_config'); - } - - /** - * @brief display member information - **/ - function dispMemberAdminInfo() { - $oMemberModel = &getModel('member'); - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - Context::set('member_config', $member_config); - Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($this->member_info)); - $this->setTemplateFile('member_info'); - } - - /** - * @brief display member insert form - **/ - function dispMemberAdminInsert() { - // retrieve extend form - $oMemberModel = &getModel('member'); - Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($this->member_info)); - - $member_info = Context::get('member_info'); - $member_info->signature = $oMemberModel->getSignature($this->member_info->member_srl); - Context::set('member_info', $member_info); - - // get an editor for the signature - if($this->member_info->member_srl) { - $oEditorModel = &getModel('editor'); - $option->primary_key_name = 'member_srl'; - $option->content_key_name = 'signature'; - $option->allow_fileupload = false; - $option->enable_autosave = false; - $option->enable_default_component = true; - $option->enable_component = false; - $option->resizable = false; - $option->height = 200; - $editor = $oEditorModel->getEditor($this->member_info->member_srl, $option); - Context::set('editor', $editor); - } - - $this->setTemplateFile('insert_member'); - } - - /** - * @brief display member delete form - **/ - function dispMemberAdminDeleteForm() { - if(!Context::get('member_srl')) return $this->dispMemberAdminList(); - $this->setTemplateFile('delete_form'); - } - - /** - * @brief display group list - **/ - function dispMemberAdminGroupList() { - $oModuleModel = &getModel('module'); - - $config = $oModuleModel->getModuleConfig('member'); - if($config->group_image_mark_order) $config->group_image_mark_order = explode(',', $config->group_image_mark_order); - Context::set('config', $config); - - $group_srl = Context::get('group_srl'); - - if($group_srl && $this->group_list[$group_srl]) { - Context::set('selected_group', $this->group_list[$group_srl]); - $this->setTemplateFile('group_update_form'); - } else { - $this->setTemplateFile('group_list'); - } - } - - /** - * @brief 회원 가입 폼 목록 출력 - **/ - function dispMemberAdminJoinFormList() { - // 멤버모델 객체 생성 - $oMemberModel = &getModel('member'); - - // 추가로 설정한 가입 항목 가져오기 - $form_list = $oMemberModel->getJoinFormList(); - Context::set('form_list', $form_list); - - $this->setTemplateFile('join_form_list'); - } - - /** - * @brief 회원 가입 폼 관리 화면 출력 - **/ - function dispMemberAdminInsertJoinForm() { - // 수정일 경우 대상 join_form의 값을 구함 - $member_join_form_srl = Context::get('member_join_form_srl'); - if($member_join_form_srl) { - $oMemberModel = &getModel('member'); - $join_form = $oMemberModel->getJoinForm($member_join_form_srl); - - if(!$join_form) Context::set('member_join_form_srl','',true); - else Context::set('join_form', $join_form); - } - $this->setTemplateFile('insert_join_form'); - } - - /** - * @brief 금지 목록 아이디 출력 - **/ - function dispMemberAdminDeniedIDList() { - // 멤버모델 객체 생성 - $oMemberModel = &getModel('member'); - - // 사용금지 목록 가져오기 - $output = $oMemberModel->getDeniedIDList(); - - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('member_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('denied_id_list'); - } - - /** - * @brief 회원 그룹 일괄 변경 - **/ - function dispMemberAdminManageGroup() { - // 선택된 회원 목록을 구함 - $args->member_srl = trim(Context::get('member_srls')); - $output = executeQueryArray('member.getMembers', $args); - Context::set('member_list', $output->data); - - // 회원 그룹 목록을 구함 - $oMemberModel = &getModel('member'); - Context::set('member_groups', $oMemberModel->getGroups()); - - $this->setLayoutFile('popup_layout'); - $this->setTemplateFile('manage_member_group'); - } - - /** - * @brief 회원 일괄 삭제 - **/ - function dispMemberAdminDeleteMembers() { - // 선택된 회원 목록을 구함 - $args->member_srl = trim(Context::get('member_srls')); - $output = executeQueryArray('member.getMembers', $args); - Context::set('member_list', $output->data); - - $this->setLayoutFile('popup_layout'); - $this->setTemplateFile('delete_members'); - } - } -?> +member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + if(!$this->member_info) Context::set('member_srl',''); + else Context::set('member_info',$this->member_info); + } + + // retrieve group list + $this->group_list = $oMemberModel->getGroups(); + Context::set('group_list', $this->group_list); + + $this->setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief display member list + **/ + function dispMemberAdminList() { + + $oMemberAdminModel = &getAdminModel('member'); + $oMemberModel = &getModel('member'); + $output = $oMemberAdminModel->getMemberList(); + + // retrieve list of groups for each member + if($output->data) { + foreach($output->data as $key => $member) { + $output->data[$key]->group_list = $oMemberModel->getMemberGroups($member->member_srl,0); + } + } + + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('member_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('member_list'); + } + + /** + * @brief default configuration for member management + **/ + function dispMemberAdminConfig() { + // retrieve configuration via module model instance + $oModuleModel = &getModel('module'); + $oMemberModel = &getModel('member'); + $config = $oMemberModel->getMemberConfig(); + Context::set('config',$config); + + // list of skins for member module + $skin_list = $oModuleModel->getSkins($this->module_path); + Context::set('skin_list', $skin_list); + + // retrieve skins of editor + $oEditorModel = &getModel('editor'); + Context::set('editor_skin_list', $oEditorModel->getEditorSkinList()); + + // get an editor + $option->primary_key_name = 'temp_srl'; + $option->content_key_name = 'agreement'; + $option->allow_fileupload = false; + $option->enable_autosave = false; + $option->enable_default_component = true; + $option->enable_component = true; + $option->resizable = true; + $option->height = 300; + $editor = $oEditorModel->getEditor(0, $option); + Context::set('editor', $editor); + + $this->setTemplateFile('member_config'); + } + + /** + * @brief display member information + **/ + function dispMemberAdminInfo() { + $oMemberModel = &getModel('member'); + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + Context::set('member_config', $member_config); + Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($this->member_info)); + $this->setTemplateFile('member_info'); + } + + /** + * @brief display member insert form + **/ + function dispMemberAdminInsert() { + // retrieve extend form + $oMemberModel = &getModel('member'); + Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($this->member_info)); + + $member_info = Context::get('member_info'); + $member_info->signature = $oMemberModel->getSignature($this->member_info->member_srl); + Context::set('member_info', $member_info); + + // get an editor for the signature + if($this->member_info->member_srl) { + $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'member_srl'; + $option->content_key_name = 'signature'; + $option->allow_fileupload = false; + $option->enable_autosave = false; + $option->enable_default_component = true; + $option->enable_component = false; + $option->resizable = false; + $option->height = 200; + $editor = $oEditorModel->getEditor($this->member_info->member_srl, $option); + Context::set('editor', $editor); + } + + $this->setTemplateFile('insert_member'); + } + + /** + * @brief display member delete form + **/ + function dispMemberAdminDeleteForm() { + if(!Context::get('member_srl')) return $this->dispMemberAdminList(); + $this->setTemplateFile('delete_form'); + } + + /** + * @brief display group list + **/ + function dispMemberAdminGroupList() { + $oModuleModel = &getModel('module'); + + $config = $oModuleModel->getModuleConfig('member'); + if($config->group_image_mark_order) $config->group_image_mark_order = explode(',', $config->group_image_mark_order); + Context::set('config', $config); + + $group_srl = Context::get('group_srl'); + + if($group_srl && $this->group_list[$group_srl]) { + Context::set('selected_group', $this->group_list[$group_srl]); + $this->setTemplateFile('group_update_form'); + } else { + $this->setTemplateFile('group_list'); + } + } + + /** + * @brief 회원 가입 폼 목록 출력 + **/ + function dispMemberAdminJoinFormList() { + // 멤버모델 객체 생성 + $oMemberModel = &getModel('member'); + + // 추가로 설정한 가입 항목 가져오기 + $form_list = $oMemberModel->getJoinFormList(); + Context::set('form_list', $form_list); + + $this->setTemplateFile('join_form_list'); + } + + /** + * @brief 회원 가입 폼 관리 화면 출력 + **/ + function dispMemberAdminInsertJoinForm() { + // 수정일 경우 대상 join_form의 값을 구함 + $member_join_form_srl = Context::get('member_join_form_srl'); + if($member_join_form_srl) { + $oMemberModel = &getModel('member'); + $join_form = $oMemberModel->getJoinForm($member_join_form_srl); + + if(!$join_form) Context::set('member_join_form_srl','',true); + else Context::set('join_form', $join_form); + } + $this->setTemplateFile('insert_join_form'); + } + + /** + * @brief 금지 목록 아이디 출력 + **/ + function dispMemberAdminDeniedIDList() { + // 멤버모델 객체 생성 + $oMemberModel = &getModel('member'); + + // 사용금지 목록 가져오기 + $output = $oMemberModel->getDeniedIDList(); + + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('member_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('denied_id_list'); + } + + /** + * @brief 회원 그룹 일괄 변경 + **/ + function dispMemberAdminManageGroup() { + // 선택된 회원 목록을 구함 + $args->member_srl = trim(Context::get('member_srls')); + $output = executeQueryArray('member.getMembers', $args); + Context::set('member_list', $output->data); + + // 회원 그룹 목록을 구함 + $oMemberModel = &getModel('member'); + Context::set('member_groups', $oMemberModel->getGroups()); + + $this->setLayoutFile('popup_layout'); + $this->setTemplateFile('manage_member_group'); + } + + /** + * @brief 회원 일괄 삭제 + **/ + function dispMemberAdminDeleteMembers() { + // 선택된 회원 목록을 구함 + $args->member_srl = trim(Context::get('member_srls')); + $output = executeQueryArray('member.getMembers', $args); + Context::set('member_list', $output->data); + + $this->setLayoutFile('popup_layout'); + $this->setTemplateFile('delete_members'); + } + } +?> diff --git a/modules/member/member.api.php b/modules/member/member.api.php index 66c6e2e47..3aca073e7 100644 --- a/modules/member/member.api.php +++ b/modules/member/member.api.php @@ -1,7 +1,7 @@ getModuleConfig('member'); - - // SSL 사용시 회원가입/정보/비밀번호등과 관련된 action에 대해 SSL 전송하도록 지정 - if(Context::get('_use_ssl') == 'optional') { - Context::addSSLAction('dispMemberModifyPassword'); - Context::addSSLAction('dispMemberSignUpForm'); - Context::addSSLAction('dispMemberModifyInfo'); - Context::addSSLAction('procMemberLogin'); - Context::addSSLAction('procMemberModifyPassword'); - Context::addSSLAction('procMemberInsert'); - Context::addSSLAction('procMemberModifyInfo'); - } - } - - /** - * @brief 설치시 추가 작업이 필요할시 구현 - **/ - function moduleInstall() { - // action forward에 등록 (관리자 모드에서 사용하기 위함) - $oModuleController = &getController('module'); - - $oDB = &DB::getInstance(); - $oDB->addIndex("member_group","idx_site_title", array("site_srl","title"),true); - - $oModuleModel = &getModel('module'); - $args = $oModuleModel->getModuleConfig('member'); - - // 기본 정보를 세팅 - $args->enable_join = 'Y'; - if(!$args->enable_openid) $args->enable_openid = 'N'; - if(!$args->enable_auth_mail) $args->enable_auth_mail = 'N'; - if(!$args->image_name) $args->image_name = 'Y'; - if(!$args->image_mark) $args->image_mark = 'Y'; - if(!$args->profile_image) $args->profile_image = 'Y'; - if(!$args->image_name_max_width) $args->image_name_max_width = '90'; - if(!$args->image_name_max_height) $args->image_name_max_height = '20'; - if(!$args->image_mark_max_width) $args->image_mark_max_width = '20'; - if(!$args->image_mark_max_height) $args->image_mark_max_height = '20'; - if(!$args->profile_image_max_width) $args->profile_image_max_width = '80'; - if(!$args->profile_image_max_height) $args->profile_image_max_height = '80'; - if($args->group_image_mark!='Y') $args->group_image_mark = 'N'; - - $oModuleController->insertModuleConfig('member',$args); - - // 멤버 컨트롤러 객체 생성 - $oMemberModel = &getModel('member'); - $oMemberController = &getController('member'); - $oMemberAdminController = &getAdminController('member'); - - $groups = $oMemberModel->getGroups(); - if(!count($groups)) { - // 관리자, 정회원, 준회원 그룹을 입력 - $group_args->title = Context::getLang('admin_group'); - $group_args->is_default = 'N'; - $group_args->is_admin = 'Y'; - $output = $oMemberAdminController->insertGroup($group_args); - - unset($group_args); - $group_args->title = Context::getLang('default_group_1'); - $group_args->is_default = 'Y'; - $group_args->is_admin = 'N'; - $output = $oMemberAdminController->insertGroup($group_args); - - unset($group_args); - $group_args->title = Context::getLang('default_group_2'); - $group_args->is_default = 'N'; - $group_args->is_admin = 'N'; - $oMemberAdminController->insertGroup($group_args); - } - - // 관리자 정보 세팅 - $admin_args->is_admin = 'Y'; - $output = executeQuery('member.getMemberList', $admin_args); - if(!$output->data) { - $admin_info = Context::gets('user_id','password','nick_name','user_name', 'email_address'); - if($admin_info->user_id) { - // 관리자 정보 입력 - $oMemberAdminController->insertAdmin($admin_info); - - // 로그인 처리시킴 - $output = $oMemberController->doLogin($admin_info->user_id); - } - } - - // 금지 아이디 등록 (기본 + 모듈명) - $oModuleModel = &getModel('module'); - $module_list = $oModuleModel->getModuleList(); - foreach($module_list as $key => $val) { - $oMemberAdminController->insertDeniedID($val->module,''); - } - $oMemberAdminController->insertDeniedID('www',''); - $oMemberAdminController->insertDeniedID('root',''); - $oMemberAdminController->insertDeniedID('administrator',''); - $oMemberAdminController->insertDeniedID('telnet',''); - $oMemberAdminController->insertDeniedID('ftp',''); - $oMemberAdminController->insertDeniedID('http',''); - - // member 에서 사용할 cache디렉토리 생성 - FileHandler::makeDir('./files/member_extra_info/image_name'); - FileHandler::makeDir('./files/member_extra_info/image_mark'); - FileHandler::makeDir('./files/member_extra_info/profile_image'); - FileHandler::makeDir('./files/member_extra_info/signature'); - - $oDB->addIndex("member_openid_association","idx_assoc", array("server_url(255)","handle"), false); - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB = &DB::getInstance(); - $oModuleModel = &getModel('module'); - - // member 디렉토리 체크 (2007. 8. 11 추가) - if(!is_dir("./files/member_extra_info")) return true; - - // member 디렉토리 체크 (2007. 10. 22 추가) - if(!is_dir("./files/member_extra_info/profile_image")) return true; - - // member_auth_mail 테이블에 is_register 필드 추가 (2008. 04. 22) - $act = $oDB->isColumnExists("member_auth_mail", "is_register"); - if(!$act) return true; - - // member_group_member 테이블에 site_srl 추가 (2008. 11. 15) - if(!$oDB->isColumnExists("member_group_member", "site_srl")) return true; - if(!$oDB->isColumnExists("member_group", "site_srl")) return true; - if($oDB->isIndexExists("member_group","uni_member_group_title")) return true; - - // image_mark 추가 (2009. 02. 14) - if(!$oDB->isColumnExists("member_group", "image_mark")) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - $oModuleController = &getController('module'); - - // member 디렉토리 체크 - FileHandler::makeDir('./files/member_extra_info/image_name'); - FileHandler::makeDir('./files/member_extra_info/image_mark'); - FileHandler::makeDir('./files/member_extra_info/signature'); - FileHandler::makeDir('./files/member_extra_info/profile_image'); - - // DB 필드 추가 - if (!$oDB->isColumnExists("member_auth_mail", "is_register")) { - $oDB->addColumn("member_auth_mail", "is_register", "char", 1, "N", true); - } - - // member_group_member 테이블에 site_srl 추가 (2008. 11. 15) - if (!$oDB->isColumnExists("member_group_member", "site_srl")) { - $oDB->addColumn("member_group_member", "site_srl", "number", 11, 0, true); - $oDB->addIndex("member_group_member", "idx_site_srl", "site_srl", false); - } - if (!$oDB->isColumnExists("member_group", "site_srl")) { - $oDB->addColumn("member_group", "site_srl", "number", 11, 0, true); - $oDB->addIndex("member_group","idx_site_title", array("site_srl","title"),true); - } - if($oDB->isIndexExists("member_group","uni_member_group_title")) { - $oDB->dropIndex("member_group","uni_member_group_title",true); - } - - // image_mark 추가 (2009. 02. 14) - if(!$oDB->isColumnExists("member_group", "image_mark")) { - $oDB->addColumn("member_group", "image_mark", "text"); - } - - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); - require_once('Auth/OpenID/XEStore.php'); - $store = new Auth_OpenID_XEStore(); - $store->reset(); - } - } -?> +getModuleConfig('member'); + + // SSL 사용시 회원가입/정보/비밀번호등과 관련된 action에 대해 SSL 전송하도록 지정 + if(Context::get('_use_ssl') == 'optional') { + Context::addSSLAction('dispMemberModifyPassword'); + Context::addSSLAction('dispMemberSignUpForm'); + Context::addSSLAction('dispMemberModifyInfo'); + Context::addSSLAction('procMemberLogin'); + Context::addSSLAction('procMemberModifyPassword'); + Context::addSSLAction('procMemberInsert'); + Context::addSSLAction('procMemberModifyInfo'); + } + } + + /** + * @brief 설치시 추가 작업이 필요할시 구현 + **/ + function moduleInstall() { + // action forward에 등록 (관리자 모드에서 사용하기 위함) + $oModuleController = &getController('module'); + + $oDB = &DB::getInstance(); + $oDB->addIndex("member_group","idx_site_title", array("site_srl","title"),true); + + $oModuleModel = &getModel('module'); + $args = $oModuleModel->getModuleConfig('member'); + + // 기본 정보를 세팅 + $args->enable_join = 'Y'; + if(!$args->enable_openid) $args->enable_openid = 'N'; + if(!$args->enable_auth_mail) $args->enable_auth_mail = 'N'; + if(!$args->image_name) $args->image_name = 'Y'; + if(!$args->image_mark) $args->image_mark = 'Y'; + if(!$args->profile_image) $args->profile_image = 'Y'; + if(!$args->image_name_max_width) $args->image_name_max_width = '90'; + if(!$args->image_name_max_height) $args->image_name_max_height = '20'; + if(!$args->image_mark_max_width) $args->image_mark_max_width = '20'; + if(!$args->image_mark_max_height) $args->image_mark_max_height = '20'; + if(!$args->profile_image_max_width) $args->profile_image_max_width = '80'; + if(!$args->profile_image_max_height) $args->profile_image_max_height = '80'; + if($args->group_image_mark!='Y') $args->group_image_mark = 'N'; + + $oModuleController->insertModuleConfig('member',$args); + + // 멤버 컨트롤러 객체 생성 + $oMemberModel = &getModel('member'); + $oMemberController = &getController('member'); + $oMemberAdminController = &getAdminController('member'); + + $groups = $oMemberModel->getGroups(); + if(!count($groups)) { + // 관리자, 정회원, 준회원 그룹을 입력 + $group_args->title = Context::getLang('admin_group'); + $group_args->is_default = 'N'; + $group_args->is_admin = 'Y'; + $output = $oMemberAdminController->insertGroup($group_args); + + unset($group_args); + $group_args->title = Context::getLang('default_group_1'); + $group_args->is_default = 'Y'; + $group_args->is_admin = 'N'; + $output = $oMemberAdminController->insertGroup($group_args); + + unset($group_args); + $group_args->title = Context::getLang('default_group_2'); + $group_args->is_default = 'N'; + $group_args->is_admin = 'N'; + $oMemberAdminController->insertGroup($group_args); + } + + // 관리자 정보 세팅 + $admin_args->is_admin = 'Y'; + $output = executeQuery('member.getMemberList', $admin_args); + if(!$output->data) { + $admin_info = Context::gets('user_id','password','nick_name','user_name', 'email_address'); + if($admin_info->user_id) { + // 관리자 정보 입력 + $oMemberAdminController->insertAdmin($admin_info); + + // 로그인 처리시킴 + $output = $oMemberController->doLogin($admin_info->user_id); + } + } + + // 금지 아이디 등록 (기본 + 모듈명) + $oModuleModel = &getModel('module'); + $module_list = $oModuleModel->getModuleList(); + foreach($module_list as $key => $val) { + $oMemberAdminController->insertDeniedID($val->module,''); + } + $oMemberAdminController->insertDeniedID('www',''); + $oMemberAdminController->insertDeniedID('root',''); + $oMemberAdminController->insertDeniedID('administrator',''); + $oMemberAdminController->insertDeniedID('telnet',''); + $oMemberAdminController->insertDeniedID('ftp',''); + $oMemberAdminController->insertDeniedID('http',''); + + // member 에서 사용할 cache디렉토리 생성 + FileHandler::makeDir('./files/member_extra_info/image_name'); + FileHandler::makeDir('./files/member_extra_info/image_mark'); + FileHandler::makeDir('./files/member_extra_info/profile_image'); + FileHandler::makeDir('./files/member_extra_info/signature'); + + $oDB->addIndex("member_openid_association","idx_assoc", array("server_url(255)","handle"), false); + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB = &DB::getInstance(); + $oModuleModel = &getModel('module'); + + // member 디렉토리 체크 (2007. 8. 11 추가) + if(!is_dir("./files/member_extra_info")) return true; + + // member 디렉토리 체크 (2007. 10. 22 추가) + if(!is_dir("./files/member_extra_info/profile_image")) return true; + + // member_auth_mail 테이블에 is_register 필드 추가 (2008. 04. 22) + $act = $oDB->isColumnExists("member_auth_mail", "is_register"); + if(!$act) return true; + + // member_group_member 테이블에 site_srl 추가 (2008. 11. 15) + if(!$oDB->isColumnExists("member_group_member", "site_srl")) return true; + if(!$oDB->isColumnExists("member_group", "site_srl")) return true; + if($oDB->isIndexExists("member_group","uni_member_group_title")) return true; + + // image_mark 추가 (2009. 02. 14) + if(!$oDB->isColumnExists("member_group", "image_mark")) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + $oModuleController = &getController('module'); + + // member 디렉토리 체크 + FileHandler::makeDir('./files/member_extra_info/image_name'); + FileHandler::makeDir('./files/member_extra_info/image_mark'); + FileHandler::makeDir('./files/member_extra_info/signature'); + FileHandler::makeDir('./files/member_extra_info/profile_image'); + + // DB 필드 추가 + if (!$oDB->isColumnExists("member_auth_mail", "is_register")) { + $oDB->addColumn("member_auth_mail", "is_register", "char", 1, "N", true); + } + + // member_group_member 테이블에 site_srl 추가 (2008. 11. 15) + if (!$oDB->isColumnExists("member_group_member", "site_srl")) { + $oDB->addColumn("member_group_member", "site_srl", "number", 11, 0, true); + $oDB->addIndex("member_group_member", "idx_site_srl", "site_srl", false); + } + if (!$oDB->isColumnExists("member_group", "site_srl")) { + $oDB->addColumn("member_group", "site_srl", "number", 11, 0, true); + $oDB->addIndex("member_group","idx_site_title", array("site_srl","title"),true); + } + if($oDB->isIndexExists("member_group","uni_member_group_title")) { + $oDB->dropIndex("member_group","uni_member_group_title",true); + } + + // image_mark 추가 (2009. 02. 14) + if(!$oDB->isColumnExists("member_group", "image_mark")) { + $oDB->addColumn("member_group", "image_mark", "text"); + } + + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); + require_once('Auth/OpenID/XEStore.php'); + $store = new Auth_OpenID_XEStore(); + $store->reset(); + } + } +?> diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index 97498a193..641adb410 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -1,1851 +1,1851 @@ -doLogin($user_id, $password, $keep_signed=='Y'?true:false); - - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($config->after_login_url) $this->setRedirectUrl($config->after_login_url); - - $redirect_url = Context::get('redirect_url'); - if($output->toBool() && Context::getRequestMethod() == "POST" && $redirect_url) - { - header("location:" . $redirect_url); - } - - return $output; - } - - /** - * @brief openid로그인 - **/ - function procMemberOpenIDLogin($validator = "procMemberOpenIDValidate") { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($config->enable_openid != 'Y') $this->stop('msg_invalid_request'); - - if(!defined('Auth_OpenID_RAND_SOURCE') && !file_exists("/dev/urandom")) - { - define('Auth_OpenID_RAND_SOURCE', null); - } - - set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); - require_once('Auth/OpenID.php'); - require_once('Auth/OpenID/Consumer.php'); - require_once('Auth/OpenID/XEStore.php'); - $store = new Auth_OpenID_XEStore(); - $consumer = new Auth_OpenID_Consumer($store); - - $user_id = Context::get('user_id'); - if (!$user_id) $user_id = Context::get('openid'); - $auth_request = $consumer->begin($user_id); - $auth_request->addExtensionArg('sreg', 'required', 'email'); - $auth_request->addExtensionArg('sreg', 'optional', 'dob'); - if(!$auth_request) - { - return new Object(-1, "association failed"); - } - - $trust_root = 'http://'.$_SERVER["HTTP_HOST"]; - $referer_url = Context::get('referer_url'); - if (!$referer_url) $referer_url = $_SERVER['HTTP_REFERER']; - if (!$referer_url) - $referer_url = htmlspecialchars_decode(getRequestUri(RELEASE_SSL)); - $goto = urlencode($referer_url); - $ApprovedURL = Context::getRequestUri(RELEASE_SSL) . "?module=member&act=" . $validator. "&goto=" . $goto; - $redirect_url = $auth_request->redirectURL($trust_root, $ApprovedURL); - $this->add("redirect_url", $redirect_url); - if (Context::getRequestMethod() == 'POST') - header("location:" . $redirect_url); - } - - function getLegacyUserIDsFromOpenID($openid_identity) { - // Issue 17515512: workaround - $result = array(); - $uri_matches = array(); - preg_match(Auth_OpenID_getURIPattern(), $openid_identity, $uri_matches); - - if (count($uri_matches) < 9) { - for ($i = count($uri_matches); $i <= 9; $i++) { - $uri_matches[] = ''; - } - } - - $scheme = $uri_matches[2]; - $authority = $uri_matches[4]; - $path = $uri_matches[5]; - $query = $uri_matches[6]; - $fragment = $uri_matches[8]; - - if ($scheme === null) $scheme = ''; - if ($authority === null) $authority = ''; - if ($path === null) $path = ''; - if ($query === null) $query = ''; - if ($fragment === null) $fragment = ''; - - if ($scheme == 'http' or $scheme == '') - $scheme_part = ''; - else - $scheme_part = $scheme."://"; - - - if ($path == '' || $path == '/') { - $result[] = $scheme_part.$authority.''.$query.$fragment; - $result[] = $scheme_part.$authority.'/'.$query.$fragment; - } - else { - $result[] = $scheme_part.$authority.$path.$query.$fragment; - } - - return $result; - } - - /** - * @brief openid 인증 체크 - **/ - function procMemberOpenIDValidate() { - set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); - require_once('Auth/OpenID.php'); - require_once('Auth/OpenID/Consumer.php'); - require_once('Auth/OpenID/XEStore.php'); - require_once('Auth/OpenID/URINorm.php'); - - $store = new Auth_OpenID_XEStore(); - $consumer = new Auth_OpenID_Consumer($store); - $response = $consumer->complete($_GET); - switch($response->status) { - case Auth_OpenID_CANCEL : - // 사용자가 인증을 취소했을 때의 처리 - return $this->stop('authorization_canceled'); - case Auth_OpenID_FAILURE : - // 무언가의 문제로 인해 인증이 실패했을 때의 처리(인증을 요구한 openid가 없다든가..) - return $this->stop('invalid_authorization'); - case Auth_OpenID_SUCCESS : - // 인증성공!! - break; - default: - return $this->stop('invalid_authorization'); - } - - // 인증 성공 - $oMemberModel = &getModel('member'); - - // 이 오픈아이디와 연결된 (또는 연결되어 있을 가능성이 있는) 제로보드 아이디들을 받아온다. - $login_success = false; - $assoc_member_info = null; - $openid_identity = $response->signed_args["openid.identity"]; - $args->openid = $openid_identity; - $output = executeQuery('member.getMemberSrlByOpenID', $args); - - if ($output->toBool() && $output->data && !is_array($output->data)) { - $member_srl = $output->data->member_srl; - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - if ($member_info) { - $assoc_member_info = $member_info; - } - } - - $user_id_candidates = $this->getLegacyUserIDsFromOpenID($openid_identity); - $default_user_id = $user_id_candidates[0]; - - if ($assoc_member_info != null) { - $user_id_candidates = array_merge(array($assoc_member_info->user_id), $user_id_candidates); - } - $sreg = $response->extensionResponse('sreg'); - - foreach($user_id_candidates as $user_id) { - $args->user_id = $args->nick_name = $user_id; - // 기본 정보들을 받음 - $args->email_address = $sreg['email']; - $args->user_name = $sreg['fullname']; - if(!$args->user_name) list($args->user_name) = explode('@', $args->email_address); - $args->birthday = str_replace('-','',$sreg['dob']); - - // 자체 인증 시도 - $output = $this->doLogin($args->user_id); - - if ($output->toBool()) { - if ($assoc_member_info == null) { - $logged_info = Context::get('logged_info'); - $args->member_srl = $logged_info->member_srl; - $args->openid = $openid_identity; - executeQuery('member.addOpenIDToMember', $args); - } - $login_success = true; - break; - } - } - - // 자체 인증 실패시 회원 가입시킴 - if(!$login_success) { - $args->user_id = $args->nick_name = $default_user_id; - $args->password = md5(getmicrotime()); - - $output = $this->insertMember($args); - if(!$output->toBool()) return $this->stop($output->getMessage()); - $output = $this->doLogin($args->user_id); - if(!$output->toBool()) return $this->stop($output->getMessage()); - - $logged_info = Context::get('logged_info'); - $args->member_srl = $logged_info->member_srl; - $args->openid = $openid_identity; - executeQuery('member.addOpenIDToMember', $args); - } - - Context::close(); - - // 페이지 이동 - if(Context::get('goto')) { - $goto = Context::get('goto'); - header("location:" . $goto); - } else { - header("location:./"); - } - - exit(); - } - - /** - * @brief 오픈아이디 연결 요청 - **/ - function procMemberAddOpenIDToMember() { - return $this->procMemberOpenIDLogin("procMemberValidateAddOpenIDToMember"); - } - - /** - * @brief 오픈아이디 연결 요청 마무리 - **/ - function procMemberValidateAddOpenIDToMember() { - set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); - require_once('Auth/OpenID.php'); - require_once('Auth/OpenID/Consumer.php'); - require_once('Auth/OpenID/XEStore.php'); - require_once('Auth/OpenID/URINorm.php'); - - $store = new Auth_OpenID_XEStore(); - $consumer = new Auth_OpenID_Consumer($store); - $response = $consumer->complete($_GET); - - switch($response->status) { - case Auth_OpenID_CANCEL : - // 사용자가 인증을 취소했을 때의 처리 - return $this->stop('authorization_canceled'); - case Auth_OpenID_FAILURE : - // 무언가의 문제로 인해 인증이 실패했을 때의 처리(인증을 요구한 openid가 없다든가..) - return $this->stop('invalid_authorization'); - case Auth_OpenID_SUCCESS : - { - $logged_info = Context::get('logged_info'); - if (!Context::get('is_logged')) return $this->stop('msg_not_logged'); - - $member_srl = $logged_info->member_srl; - - $args->member_srl = $member_srl; - $openid_identity = $response->signed_args["openid.identity"]; - $args->openid = $openid_identity; - - $output = executeQuery('member.addOpenIDToMember', $args); - if (!$output->toBool()) return $output; - - Context::close(); - - if(Context::get('goto')){ - $goto = Context::get('goto'); - header("location:" . $goto); - }else{ - header("location:./"); - } - exit(); - } - // 인증성공!! - break; - default: - return $this->stop('invalid_authorization'); - } - } - - /** - * @brief 오픈아이디 연결 해제 - **/ - function procMemberDeleteOpenIDFromMember() { - $logged_info = Context::get('logged_info'); - $openid_identity = Context::get('openid_to_delete'); - $arg->openid = $openid_identity; - $result = executeQuery('member.getMemberSrlByOpenID', $arg); - - if (!Context::get('is_logged')) { - $this->setError(-1); - $this->setMessage('msg_not_logged'); - return; - } else if (!$result->data || is_array($result->data)) { - $this->setError(-1); - $this->setMessage('msg_not_founded'); - return; - } else if ($result->data->member_srl != $logged_info->member_srl) { - $this->setError(-1); - $this->setMessage('msg_not_permitted'); - return; - } - - $arg->openid = $openid_identity; - - $output = executeQuery('member.deleteMemberOpenID', $arg); - if(!$output->toBool()) return $output; - - $this->setMessage('success_updated'); - } - - - /** - * @brief 로그아웃 - **/ - function procMemberLogout() { - // 로그아웃 이전에 trigger 호출 (before) - $logged_info = Context::get('logged_info'); - $trigger_output = ModuleHandler::triggerCall('member.doLogout', 'before', $logged_info); - if(!$trigger_output->toBool()) return $trigger_output; - - // 세션 정보 파기 - $this->destroySessionInfo(); - - // 로그아웃 이후 trigger 호출 (after) - $trigger_output = ModuleHandler::triggerCall('member.doLogout', 'after', $logged_info); - if(!$trigger_output->toBool()) return $trigger_output; - - $output = new Object(); - - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($config->after_logout_url) Context::set('redirect_url', $config->after_logout_url); - - return $output; - } - - /** - * @brief 스크랩 기능 - **/ - function procMemberScrapDocument() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - $document_srl = (int)Context::get('document_srl'); - if(!$document_srl) $document_srl = (int)Context::get('target_srl'); - if(!$document_srl) return new Object(-1,'msg_invalid_request'); - - // 문서 가져오기 - $oDocumentModel = &getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); - - // 변수 정리 - $args->document_srl = $document_srl; - $args->member_srl = $logged_info->member_srl; - $args->user_id = $oDocument->get('user_id'); - $args->user_name = $oDocument->get('user_name'); - $args->nick_name = $oDocument->get('nick_name'); - $args->target_member_srl = $oDocument->get('member_srl'); - $args->title = $oDocument->get('title'); - - // 있는지 조사 - $output = executeQuery('member.getScrapDocument', $args); - if($output->data->count) return new Object(-1, 'msg_alreay_scrapped'); - - // 입력 - $output = executeQuery('member.addScrapDocument', $args); - if(!$output->toBool()) return $output; - - $this->setError(-1); - $this->setMessage('success_registed'); - } - - /** - * @brief 스크랩 삭제 - **/ - function procMemberDeleteScrap() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - $document_srl = (int)Context::get('document_srl'); - if(!$document_srl) return new Object(-1,'msg_invalid_request'); - - // 변수 정리 - $args->member_srl = $logged_info->member_srl; - $args->document_srl = $document_srl; - return executeQuery('member.deleteScrapDocument', $args); - } - - /** - * @brief 게시글 저장 - **/ - function procMemberSaveDocument() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - - $logged_info = Context::get('logged_info'); - - // form 정보를 모두 받음 - $obj = Context::getRequestVars(); - - // 글의 대상 모듈을 회원 정보로 변경 - $obj->module_srl = $logged_info->member_srl; - - // 제목을 사용하지 않는 방명록 등에서 내용 앞 부분을 제목 가져오기 - if(!$obj->title) { - $obj->title = cut_str(strip_tags($obj->content), 20, '...'); - } - - $oDocumentModel = &getModel('document'); - $oDocumentController = &getController('document'); - - // 이미 존재하는 글인지 체크 - $oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager); - - // 이미 존재하는 경우 수정 - if($oDocument->isExists() && $oDocument->document_srl == $obj->document_srl) { - $output = $oDocumentController->updateDocument($oDocument, $obj); - $msg_code = 'success_updated'; - - // 그렇지 않으면 신규 등록 - } else { - $output = $oDocumentController->insertDocument($obj); - $msg_code = 'success_registed'; - $obj->document_srl = $output->get('document_srl'); - $oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager); - } - - // 등록된 첨부파일의 상태를 무효로 지정 - if($oDocument->hasUploadedFiles()) { - $args->upload_target_srl = $oDocument->document_srl; - $args->isvalid = 'N'; - executeQuery('file.updateFileValid', $args); - } - - $this->setMessage('success_saved'); - $this->add('document_srl', $obj->document_srl); - } - - /** - * @brief 저장된 글 삭제 - **/ - function procMemberDeleteSavedDocument() { - // 로그인 정보 체크 - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); - $logged_info = Context::get('logged_info'); - - $document_srl = (int)Context::get('document_srl'); - if(!$document_srl) return new Object(-1,'msg_invalid_request'); - - // 변수 정리 - $oDocumentController = &getController('document'); - $oDocumentController->deleteDocument($document_srl, true); - } - - /** - * @brief 회원 가입시 특정 항목들에 대한 값 체크 - **/ - function procMemberCheckValue() { - $name = Context::get('name'); - $value = Context::get('value'); - if(!$value) return; - - $oMemberModel = &getModel('member'); - - // 로그인 여부 체크 - $logged_info = Context::get('logged_info'); - - - switch($name) { - case 'user_id' : - // 금지 아이디 검사 - if($oMemberModel->isDeniedID($value)) return new Object(0,'denied_user_id'); - - // 중복 검사 - $member_srl = $oMemberModel->getMemberSrlByUserID($value); - if($member_srl && $logged_info->member_srl != $member_srl ) return new Object(0,'msg_exists_user_id'); - break; - case 'nick_name' : - // 중복 검사 - $member_srl = $oMemberModel->getMemberSrlByNickName($value); - if($member_srl && $logged_info->member_srl != $member_srl ) return new Object(0,'msg_exists_nick_name'); - - break; - case 'email_address' : - // 중복 검사 - $member_srl = $oMemberModel->getMemberSrlByEmailAddress($value); - if($member_srl && $logged_info->member_srl != $member_srl ) return new Object(0,'msg_exists_email_address'); - break; - } - } - - /** - * @brief 회원 가입 - **/ - function procMemberInsert() { - if(Context::getRequestMethod() == "GET") return new Object(-1, "msg_invalid_request"); - $oMemberModel = &getModel('member'); - $config = $oMemberModel->getMemberConfig(); - - // before 트리거 호출 - $trigger_output = ModuleHandler::triggerCall('member.procMemberInsert', 'before', $config); - if(!$trigger_output->toBool()) return $trigger_output; - - // 관리자가 회원가입을 허락하였는지 검사 - if($config->enable_join != 'Y') return $this->stop('msg_signup_disabled'); - - // 약관에 동의하였는지 검사 (약관이 있을 경우만) - if($config->agreement && Context::get('accept_agreement')!='Y') return $this->stop('msg_accept_agreement'); - - // 필수 정보들을 미리 추출 - $args = Context::gets('user_id','user_name','nick_name','homepage','blog','birthday','email_address','password','allow_mailing'); - $args->member_srl = getNextSequence(); - - // 넘어온 모든 변수중에서 몇가지 불필요한 것들 삭제 - $all_args = Context::getRequestVars(); - unset($all_args->module); - unset($all_args->act); - unset($all_args->is_admin); - unset($all_args->description); - unset($all_args->group_srl_list); - unset($all_args->body); - unset($all_args->accept_agreement); - unset($all_args->signature); - - // 메일 인증 기능 사용시 회원 상태를 denied로 설정 - if ($config->enable_confirm == 'Y') $args->denied = 'Y'; - - // 모든 request argument에서 필수 정보만 제외 한 후 추가 데이터로 입력 - $extra_vars = delObjectVars($all_args, $args); - $args->extra_vars = serialize($extra_vars); - - // member_srl의 값에 따라 insert/update - $output = $this->insertMember($args); - if(!$output->toBool()) return $output; - - // 가상사이트일 경우 사이트 가입 - $site_module_info = Context::get('site_module_info'); - if($site_module_info->site_srl > 0) { - $default_group = $oMemberModel->getDefaultGroup($site_module_info->site_srl); - if($default_group->group_srl) { - $this->addMemberToGroup($args->member_srl, $default_group->group_srl, $site_module_info->site_srl); - } - - } - - // 로그인 시킴 - if ($config->enable_confirm != 'Y') $this->doLogin($args->user_id); - - // 결과 정리 - $this->add('member_srl', $args->member_srl); - if($config->redirect_url) $this->add('redirect_url', $config->redirect_url); - if ($config->enable_confirm == 'Y') { - $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $args->email_address); - $this->setMessage($msg); - } - else $this->setMessage('success_registed'); - - // after 트리거 호출 - $trigger_output = ModuleHandler::triggerCall('member.procMemberInsert', 'after', $config); - if(!$trigger_output->toBool()) return $trigger_output; - } - - /** - * @brief 회원 정보 수정 - **/ - function procMemberModifyInfo() { - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - - // 필수 정보들을 미리 추출 - $args = Context::gets('user_name','nick_name','homepage','blog','birthday','email_address','allow_mailing'); - - // 로그인 정보 - $logged_info = Context::get('logged_info'); - $args->member_srl = $logged_info->member_srl; - - // 넘어온 모든 변수중에서 몇가지 불필요한 것들 삭제 - $all_args = Context::getRequestVars(); - unset($all_args->module); - unset($all_args->act); - unset($all_args->is_admin); - unset($all_args->description); - unset($all_args->group_srl_list); - unset($all_args->body); - unset($all_args->accept_agreement); - unset($all_args->signature); - - // 모든 request argument에서 필수 정보만 제외 한 후 추가 데이터로 입력 - $extra_vars = delObjectVars($all_args, $args); - $args->extra_vars = serialize($extra_vars); - - // 멤버 모델 객체 생성 - $oMemberModel = &getModel('member'); - - // member_srl의 값에 따라 insert/update - $output = $this->updateMember($args); - if(!$output->toBool()) return $output; - - // 서명 저장 - $signature = Context::get('signature'); - $this->putSignature($args->member_srl, $signature); - - // user_id 에 따른 정보 가져옴 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->member_srl); - - // 로그인 성공후 trigger 호출 (after) - $trigger_output = ModuleHandler::triggerCall('member.doLogin', 'after', $member_info); - if(!$trigger_output->toBool()) return $trigger_output; - - $this->setSessionInfo($member_info); - - // 결과 리턴 - $this->add('member_srl', $args->member_srl); - $this->setMessage('success_updated'); - } - - /** - * @brief 회원 비밀번호 수정 - **/ - function procMemberModifyPassword() { - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - - // 필수 정보들을 미리 추출 - $current_password = trim(Context::get('current_password')); - $password = trim(Context::get('password')); - - // 로그인한 유저의 정보를 가져옴 - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - // member model 객체 생성 - $oMemberModel = &getModel('member'); - - // member_srl 에 따른 정보 가져옴 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - - // 현재 비밀번호가 맞는지 확인 - if(!$oMemberModel->isValidPassword($member_info->password, $current_password)) return new Object(-1, 'invalid_password'); - - // member_srl의 값에 따라 insert/update - $args->member_srl = $member_srl; - $args->password = $password; - $output = $this->updateMemberPassword($args); - if(!$output->toBool()) return $output; - - $this->add('member_srl', $args->member_srl); - $this->setMessage('success_updated'); - } - - /** - * @brief 탈퇴 - **/ - function procMemberLeave() { - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - - // 필수 정보들을 미리 추출 - $password = trim(Context::get('password')); - - // 로그인한 유저의 정보를 가져옴 - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - // member model 객체 생성 - $oMemberModel = &getModel('member'); - - // member_srl 에 따른 정보 가져옴 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - - // 현재 비밀번호가 맞는지 확인 - if(!$oMemberModel->isValidPassword($member_info->password, $password)) return new Object(-1, 'invalid_password'); - - $output = $this->deleteMember($member_srl); - if(!$output->toBool()) return $output; - - // 모든 세션 정보 파기 - $this->destroySessionInfo(); - - // 성공 메세지 리턴 - $this->setMessage('success_leaved'); - } - - /** - * @brief 오픈아이디 탈퇴 - **/ - function procMemberOpenIDLeave() { - // 비로그인 상태이면 에러 - if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); - - // 현재 ip와 세션 아이피 비교 - if($_SESSION['ipaddress']!=$_SERVER['REMOTE_ADDR']) return $this->stop('msg_not_permitted'); - - // 로그인한 유저의 정보를 가져옴 - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - $output = $this->deleteMember($member_srl); - if(!$output->toBool()) return $output; - - // 모든 세션 정보 파기 - $this->destroySessionInfo(); - - // 성공 메세지 리턴 - $this->setMessage('success_leaved'); - } - - /** - * @brief 프로필 이미지 추가 - **/ - function procMemberInsertProfileImage() { - // 정상적으로 업로드 된 파일인지 검사 - $file = $_FILES['profile_image']; - if(!is_uploaded_file($file['tmp_name'])) return $this->stop('msg_not_uploaded_profile_image'); - - // 회원 정보를 검사해서 회원번호가 없거나 관리자가 아니고 회원번호가 틀리면 무시 - $member_srl = Context::get('member_srl'); - if(!$member_srl) return $this->stop('msg_not_uploaded_profile_image'); - - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_profile_image'); - - // 회원 모듈 설정에서 이미지 이름 사용 금지를 하였을 경우 관리자가 아니면 return; - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($logged_info->is_admin != 'Y' && $config->profile_image != 'Y') return $this->stop('msg_not_uploaded_profile_image'); - - $this->insertProfileImage($member_srl, $file['tmp_name']); - - // 페이지 리프레쉬 - $this->setRefreshPage(); - } - - function insertProfileImage($member_srl, $target_file) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - // 정해진 사이즈를 구함 - $max_width = $config->profile_image_max_width; - if(!$max_width) $max_width = "90"; - $max_height = $config->profile_image_max_height; - if(!$max_height) $max_height = "20"; - - // 저장할 위치 구함 - $target_path = sprintf('files/member_extra_info/profile_image/%s', getNumberingPath($member_srl)); - FileHandler::makeDir($target_path); - - // 파일 정보 구함 - list($width, $height, $type, $attrs) = @getimagesize($target_file); - if($type == 3) $ext = 'png'; - elseif($type == 2) $ext = 'jpg'; - else $ext = 'gif'; - - $target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext); - - // 지정된 사이즈보다 크거나 gif가 아니면 변환 - if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, $ext); - else @copy($target_file, $target_filename); - } - - /** - * @brief 이미지 이름을 추가 - **/ - function procMemberInsertImageName() { - // 정상적으로 업로드 된 파일인지 검사 - $file = $_FILES['image_name']; - if(!is_uploaded_file($file['tmp_name'])) return $this->stop('msg_not_uploaded_image_name'); - - // 회원 정보를 검사해서 회원번호가 없거나 관리자가 아니고 회원번호가 틀리면 무시 - $member_srl = Context::get('member_srl'); - if(!$member_srl) return $this->stop('msg_not_uploaded_image_name'); - - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_name'); - - // 회원 모듈 설정에서 이미지 이름 사용 금지를 하였을 경우 관리자가 아니면 return; - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($logged_info->is_admin != 'Y' && $config->image_name != 'Y') return $this->stop('msg_not_uploaded_image_name'); - - $this->insertImageName($member_srl, $file['tmp_name']); - - // 페이지 리프레쉬 - $this->setRefreshPage(); - } - - function insertImageName($member_srl, $target_file) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - // 정해진 사이즈를 구함 - $max_width = $config->image_name_max_width; - if(!$max_width) $max_width = "90"; - $max_height = $config->image_name_max_height; - if(!$max_height) $max_height = "20"; - - // 저장할 위치 구함 - $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($member_srl)); - FileHandler::makeDir($target_path); - - $target_filename = sprintf('%s%d.gif', $target_path, $member_srl); - - // 파일 정보 구함 - list($width, $height, $type, $attrs) = @getimagesize($target_file); - - // 지정된 사이즈보다 크거나 gif가 아니면 변환 - if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, 'gif'); - else @copy($target_file, $target_filename); - } - - /** - * @brief 프로필 이미지를 삭제 - **/ - function procMemberDeleteProfileImage() { - $member_srl = Context::get('member_srl'); - if(!$member_srl) return new Object(0,'success'); - - $logged_info = Context::get('logged_info'); - - if($logged_info->is_admin != 'Y') { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($config->profile_image == 'N') return new Object(0,'success'); - } - - if($logged_info->is_admin == 'Y' || $logged_info->member_srl == $member_srl) { - $oMemberModel = &getModel('member'); - $profile_image = $oMemberModel->getProfileImage($member_srl); - FileHandler::removeFile($profile_image->file); - } - return new Object(0,'success'); - } - - /** - * @brief 이미지 이름을 삭제 - **/ - function procMemberDeleteImageName() { - $member_srl = Context::get('member_srl'); - if(!$member_srl) return new Object(0,'success'); - - $logged_info = Context::get('logged_info'); - - if($logged_info->is_admin != 'Y') { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($config->image_name == 'N') return new Object(0,'success'); - } - - if($logged_info->is_admin == 'Y' || $logged_info->member_srl == $member_srl) { - $oMemberModel = &getModel('member'); - $image_name = $oMemberModel->getImageName($member_srl); - FileHandler::removeFile($image_name->file); - } - return new Object(0,'success'); - } - - /** - * @brief 이미지 마크를 추가 - **/ - function procMemberInsertImageMark() { - // 정상적으로 업로드 된 파일인지 검사 - $file = $_FILES['image_mark']; - if(!is_uploaded_file($file['tmp_name'])) return $this->stop('msg_not_uploaded_image_mark'); - - // 회원 정보를 검사해서 회원번호가 없거나 관리자가 아니고 회원번호가 틀리면 무시 - $member_srl = Context::get('member_srl'); - if(!$member_srl) return $this->stop('msg_not_uploaded_image_mark'); - - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_mark'); - - // 회원 모듈 설정에서 이미지 마크 사용 금지를 하였을 경우 관리자가 아니면 return; - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($logged_info->is_admin != 'Y' && $config->image_mark != 'Y') return $this->stop('msg_not_uploaded_image_mark'); - - $this->insertImageMark($member_srl, $file['tmp_name']); - - // 페이지 리프레쉬 - $this->setRefreshPage(); - } - - function insertImageMark($member_srl, $target_file) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - // 정해진 사이즈를 구함 - $max_width = $config->image_mark_max_width; - if(!$max_width) $max_width = "20"; - $max_height = $config->image_mark_max_height; - if(!$max_height) $max_height = "20"; - - $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($member_srl)); - FileHandler::makeDir($target_path); - - $target_filename = sprintf('%s%d.gif', $target_path, $member_srl); - - // 파일 정보 구함 - list($width, $height, $type, $attrs) = @getimagesize($target_file); - - if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, 'gif'); - else @copy($target_file, $target_filename); - - } - - /** - * @brief 이미지 마크를 삭제 - **/ - function procMemberDeleteImageMark() { - $member_srl = Context::get('member_srl'); - if(!$member_srl) return new Object(0,'success'); - - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == 'Y' || $logged_info->member_srl == $member_srl) { - $oMemberModel = &getModel('member'); - $image_mark = $oMemberModel->getImageMark($member_srl); - FileHandler::removeFile($image_mark->file); - } - return new Object(0,'success'); - } - - /** - * @brief 아이디/ 비밀번호 찾기 - **/ - function procMemberFindAccount() { - $email_address = Context::get('email_address'); - if(!$email_address) return new Object(-1, 'msg_invalid_request'); - - $oMemberModel = &getModel('member'); - $oModuleModel = &getModel('module'); - - // 메일 주소에 해당하는 회원이 있는지 검사 - $member_srl = $oMemberModel->getMemberSrlByEmailAddress($email_address); - if(!$member_srl) return new Object(-1, 'msg_email_not_exists'); - - // 회원의 정보를 가져옴 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - - // 아이디/비밀번호 찾기가 가능한 상태의 회원인지 검사 - if ($member_info->denied == 'Y') { - $chk_args->member_srl = $member_info->member_srl; - $output = executeQuery('member.chkAuthMail', $chk_args); - if ($output->toBool() && $output->data->count != '0') return new Object(-1, 'msg_user_not_confirmed'); - } - - // 인증 DB에 데이터를 넣음 - $args->user_id = $member_info->user_id; - $args->member_srl = $member_info->member_srl; - $args->new_password = rand(111111,999999); - $args->auth_key = md5( rand(0,999999 ) ); - $args->is_register = 'N'; - - $output = executeQuery('member.insertAuthMail', $args); - if(!$output->toBool()) return $output; - - // 메일 내용을 구함 - Context::set('auth_args', $args); - Context::set('member_info', $member_info); - - $member_config = $oModuleModel->getModuleConfig('member'); - if(!$member_config->skin) $this->member_config->skin = "default"; - if(!$member_config->colorset) $this->member_config->colorset = "white"; - - Context::set('member_config', $member_config); - - $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); - if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); - - $find_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$member_info->member_srl, 'auth_key',$args->auth_key); - Context::set('find_url',$find_url); - - - $oTemplate = &TemplateHandler::getInstance(); - $content = $oTemplate->compile($tpl_path, 'find_member_account_mail'); - - // 사이트 웹마스터 정보를 구함 - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - - // 메일 발송 - $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_find_account_title') ); - $oMail->setContent($content); - $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); - $oMail->setReceiptor( $member_info->user_name, $member_info->email_address ); - $oMail->send(); - - // 메세지 return - $msg = sprintf(Context::getLang('msg_auth_mail_sent'), $member_info->email_address); - return new Object(0,$msg); - } - - /** - * @brief 아이디/비밀번호 찾기 기능 실행 - * 메일에 등록된 링크를 선택시 호출되는 method로 비밀번호를 바꾸고 인증을 시켜버림 - **/ - function procMemberAuthAccount() { - // user_id, authkey 검사 - $member_srl = Context::get('member_srl'); - $auth_key = Context::get('auth_key'); - if(!$member_srl || !$auth_key) return $this->stop('msg_invalid_request'); - - // user_id, authkey로 비밀번호 찾기 로그 검사 - $args->member_srl = $member_srl; - $args->auth_key = $auth_key; - $output = executeQuery('member.getAuthMail', $args); - if(!$output->toBool() || $output->data->auth_key != $auth_key) return $this->stop('msg_invalid_auth_key'); - - // 인증 정보가 맞다면 새비밀번호로 비밀번호를 바꿈 - if ($output->data->is_register == 'Y') { - $args->password = $output->data->new_password; - $args->denied = 'N'; - } else { - $args->password = md5($output->data->new_password); - unset($args->denied); - } - - // $output->data->is_register 값을 백업해 둔다. - $is_register = $output->data->is_register; - - $output = executeQuery('member.updateMemberPassword', $args); - if(!$output->toBool()) return $this->stop($output->getMessage()); - - // 인증 테이블에서 member_srl에 해당하는 모든 값을 지움 - executeQuery('member.deleteAuthMail',$args); - - // 결과를 통보 - Context::set('is_register', $is_register); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('msg_success_authed'); - } - - /** - * @brief 아이디/비밀번호 찾기 기능 실행 - * 메일에 등록된 링크를 선택시 호출되는 method로 비밀번호를 바꾸고 인증을 시켜버림 - **/ - function procMemberUpdateAuthMail() { - $member_srl = Context::get('member_srl'); - if(!$member_srl) return new Object(-1, 'msg_invalid_request'); - - $oMemberModel = &getModel('member'); - - // 회원의 정보를 가져옴 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - - // 인증메일 재발송 요청이 가능한 상태의 회원인지 검사 - if ($member_info->denied != 'Y') - return new Object(-1, 'msg_invalid_request'); - - $chk_args->member_srl = $member_srl; - $output = executeQuery('member.chkAuthMail', $chk_args); - if ($output->toBool() && $output->data->count == '0') return new Object(-1, 'msg_invalid_request'); - - // 인증 DB에 데이터를 넣음 - $auth_args->member_srl = $member_srl; - $auth_args->auth_key = md5(rand(0, 999999)); - - $output = executeQuery('member.updateAuthMail', $auth_args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 메일 내용을 구함 - Context::set('auth_args', $auth_args); - Context::set('member_info', $member_info); - - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - if(!$member_config->skin) $this->member_config->skin = "default"; - if(!$member_config->colorset) $this->member_config->colorset = "white"; - - Context::set('member_config', $member_config); - - $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); - if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); - - $auth_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$member_info->member_srl, 'auth_key',$auth_args->auth_key); - Context::set('auth_url', $auth_url); - - $oTemplate = &TemplateHandler::getInstance(); - $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); - - // 사이트 웹마스터 정보를 구함 - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - - // 메일 발송 - $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); - $oMail->setContent($content); - $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); - $oMail->setReceiptor( $member_info->user_name, $member_info->email_address ); - $oMail->send(); - - // 메세지 return - $msg = sprintf(Context::getLang('msg_auth_mail_sent'), $member_info->email_address); - return new Object(-1, $msg); - } - - /** - * @brief 인증 메일 재발송 - **/ - function procMemberResendAuthMail() { - // email_address 검사 - $email_address = Context::get('email_address'); - if(!$email_address) return $this->stop('msg_invalid_request'); - - // email_address로 비밀번호 찾기 로그 검사 - $oMemberModel = &getModel('member'); - - $args->email_address = $email_address; - $member_info = $oMemberModel->getMemberSrlByEmailAddress($email_address); - if(!$member_info) return $this->stop('msg_not_exists_member'); - - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_info); - - // 이전에 인증 메일을 보냈는지 확인 - $chk_args->member_srl = $member_info->member_srl; - $output = executeQuery('member.chkAuthMail', $chk_args); - if($output->toBool() && $output->data->count == '0') return new Object(-1, 'msg_invalid_request'); - - $auth_args->member_srl = $member_info->member_srl; - $output = executeQueryArray('member.getAuthMailInfo', $auth_args); - if(!$output->data || !$output->data[0]->auth_key) return new Object(-1, 'msg_invalid_request'); - $auth_info = $output->data[0]; - - // 메일 내용을 구함 - Context::set('member_info', $member_info); - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - if(!$member_config->skin) $this->member_config->skin = "default"; - if(!$member_config->colorset) $this->member_config->colorset = "white"; - - Context::set('member_config', $member_config); - - $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); - if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); - - $auth_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$member_info->member_srl, 'auth_key',$auth_info->auth_key); - Context::set('auth_url', $auth_url); - - $oTemplate = &TemplateHandler::getInstance(); - $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); - - // 사이트 웹마스터 정보를 구함 - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - - // 메일 발송 - $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); - $oMail->setContent($content); - $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); - $oMail->setReceiptor( $args->user_name, $args->email_address ); - $oMail->send(); - - $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $args->email_address); - $this->setMessage($msg); - } - - /** - * @brief 가상 사이트 가입 - **/ - function procModuleSiteSignUp() { - $site_module_info = Context::get('site_module_info'); - $logged_info = Context::get('logged_info'); - if(!$site_module_info->site_srl || !Context::get('is_logged') || count($logged_info->group_srl_list) ) return new Object(-1,'msg_invalid_request'); - - $oMemberModel = &getModel('member'); - $default_group = $oMemberModel->getDefaultGroup($site_module_info->site_srl); - $this->addMemberToGroup($logged_info->member_srl, $default_group->group_srl, $site_module_info->site_srl); - $groups[$default_group->group_srl] = $default_group->title; - $logged_info->group_list = $groups; - } - - /** - * @brief 가상 사이트 탈퇴 - **/ - function procModuleSiteLeave() { - $site_module_info = Context::get('site_module_info'); - $logged_info = Context::get('logged_info'); - if(!$site_module_info->site_srl || !Context::get('is_logged') || count($logged_info->group_srl_list) ) return new Object(-1,'msg_invalid_request'); - - $args->site_srl= $site_module_info->site_srl; - $args->member_srl = $logged_info->member_srl; - $output = executeQuery('member.deleteMembersGroup', $args); - if(!$output->toBool()) return $output; - $this->setMessage('success_deleted'); - } - - /** - * @brief 회원 설정 정보를 저장 - **/ - function setMemberConfig($args) { - if(!$args->skin) $args->skin = "default"; - if(!$args->colorset) $args->colorset = "white"; - if(!$args->editor_skin) $args->editor_skin= "xpresseditor"; - if(!$args->editor_colorset) $args->editor_colorset = "white"; - if($args->enable_join!='Y') $args->enable_join = 'N'; - if($args->enable_openid!='Y') $args->enable_openid= 'N'; - if($args->profile_image !='Y') $args->profile_image = 'N'; - if($args->image_name!='Y') $args->image_name = 'N'; - if($args->image_mark!='Y') $args->image_mark = 'N'; - if($args->group_image_mark!='Y') $args->group_image_mark = 'N'; - if(!trim(strip_tags($args->agreement))) $args->agreement = null; - $args->limit_day = (int)$args->limit_day; - - $agreement = trim($args->agreement); - unset($args->agreement); - - $oModuleController = &getController('module'); - $output = $oModuleController->insertModuleConfig('member',$args); - if(!$output->toBool()) return $output; - - $agreement_file = _XE_PATH_.'files/member_extra_info/agreement.txt'; - FileHandler::writeFile($agreement_file, $agreement); - - return new Object(); - } - - /** - * @brief 서명을 파일로 저장 - **/ - function putSignature($member_srl, $signature) { - $signature = trim(removeHackTag($signature)); - $signature = preg_replace('/<(\/?)(embed|object|param)/is', '<$1$2', $signature); - - $check_signature = trim(str_replace(array(' ',"\n","\r"),'',strip_tags($signature,''))); - $path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($member_srl)); - $filename = sprintf('%s%d.signature.php', $path, $member_srl); - - if(!$check_signature) return FileHandler::removeFile($filename); - - $buff = sprintf('%s', $signature); - FileHandler::makeDir($path); - FileHandler::writeFile($filename, $buff); - } - - /** - * @brief 서명 파일 삭제 - **/ - function delSignature($member_srl) { - $filename = sprintf('files/member_extra_info/signature/%s%d.gif', getNumberingPath($member_srl), $member_srl); - FileHandler::removeFile($filename); - } - - /** - * @brief member_srl에 group_srl을 추가 - **/ - function addMemberToGroup($member_srl,$group_srl,$site_srl=0) { - $args->member_srl = $member_srl; - $args->group_srl = $group_srl; - if($site_srl) $args->site_srl = $site_srl; - - $oModel =& getModel('member'); - $groups = $oModel->getMemberGroups($member_srl, $site_srl, true); - if($groups[$group_srl]) return new Object(); - - // 추가 - $output = executeQuery('member.addMemberToGroup',$args); - $output2 = ModuleHandler::triggerCall('member.addMemberToGroup', 'after', $args); - - return $output; - } - - /** - * @brief 특정 회원들의 그룹을 일괄 변경 - * 가상 사이트와 같이 한 회원이 하나의 그룹만 가질 경우 사용할 수 있음 - **/ - function replaceMemberGroup($args) { - $obj->site_srl = $args->site_srl; - $obj->member_srl = implode(',',$args->member_srl); - - $output = executeQueryArray('member.getMembersGroup', $obj); - if($output->data) foreach($output->data as $key => $val) $date[$val->member_srl] = $val->regdate; - - $output = executeQuery('member.deleteMembersGroup', $obj); - if(!$output->toBool()) return $output; - - $inserted_members = array(); - foreach($args->member_srl as $key => $val) { - if($inserted_members[$val]) continue; - $inserted_members[$val] = true; - - unset($obj); - $obj->member_srl = $val; - $obj->group_srl = $args->group_srl; - $obj->site_srl = $args->site_srl; - $obj->regdate = $date[$obj->member_srl]; - $output = executeQuery('member.addMemberToGroup', $obj); - if(!$output->toBool()) return $output; - } - return new Object(); - } - - - /** - * @brief 자동 로그인 시킴 - **/ - function doAutologin() { - // 자동 로그인 키 값을 구함 - $args->autologin_key = $_COOKIE['xeak']; - - // 키값에 해당하는 정보 구함 - $output = executeQuery('member.getAutologin', $args); - - // 정보가 없으면 쿠키 삭제 - if(!$output->toBool() || !$output->data) { - setCookie('xeak',null,time()+60*60*24*365, '/'); - return; - } - - $user_id = $output->data->user_id; - $password = $output->data->password; - if(!$user_id || !$password) { - setCookie('xeak',null,time()+60*60*24*365, '/'); - return; - } - - // 정보를 바탕으로 키값 비교 - $key = md5($user_id.$password.$_SERVER['REMOTE_ADDR']); - - if($key == $args->autologin_key) { - $output = $this->doLogin($user_id); - } else { - executeQuery('member.deleteAutologin', $args); - setCookie('xeak',null,time()+60*60*24*365, '/'); - } - } - - /** - * @brief 로그인 시킴 - **/ - function doLogin($user_id, $password = '', $keep_signed = false) { - $user_id = strtolower($user_id); - - // 로그인 이전에 trigger 호출 (before) - $trigger_obj->user_id = $user_id; - $trigger_obj->password = $password; - $trigger_output = ModuleHandler::triggerCall('member.doLogin', 'before', $trigger_obj); - if(!$trigger_output->toBool()) return $trigger_output; - - // member model 객체 생성 - $oMemberModel = &getModel('member'); - - // user_id 에 따른 정보 가져옴 - $member_info = $oMemberModel->getMemberInfoByUserID($user_id); - - // return 값이 없으면 존재하지 않는 사용자로 지정 - if(!$user_id || strtolower($member_info->user_id) != strtolower($user_id)) return new Object(-1, 'invalid_user_id'); - - // 비밀번호 검사 - if($password && !$oMemberModel->isValidPassword($member_info->password, $password)) return new Object(-1, 'invalid_password'); - - // denied == 'Y' 이면 알림 - if($member_info->denied == 'Y') { - $args->member_srl = $member_info->member_srl; - $output = executeQuery('member.chkAuthMail', $args); - if ($output->toBool() && $output->data->count != '0') return new Object(-1,'msg_user_not_confirmed'); - return new Object(-1,'msg_user_denied'); - } - - // denied_date가 현 시간보다 적으면 알림 - if($member_info->limit_date && substr($member_info->limit_date,0,8) >= date("Ymd")) return new Object(-1,sprintf(Context::getLang('msg_user_limited'),zdate($member_info->limit_date,"Y-m-d"))); - - // 사용자 정보의 최근 로그인 시간을 기록 - $args->member_srl = $member_info->member_srl; - $output = executeQuery('member.updateLastLogin', $args); - - // 로그인 성공후 trigger 호출 (after) - $trigger_output = ModuleHandler::triggerCall('member.doLogin', 'after', $member_info); - if(!$trigger_output->toBool()) return $trigger_output; - - // 자동 로그인 사용시 정보 처리 - if($keep_signed) { - // 자동 로그인 키 생성 - $autologin_args->autologin_key = md5(strtolower($user_id).$member_info->password.$_SERVER['REMOTE_ADDR']); - $autologin_args->member_srl = $member_info->member_srl; - executeQuery('member.deleteAutologin', $autologin_args); - $autologin_output = executeQuery('member.insertAutologin', $autologin_args); - if($autologin_output->toBool()) setCookie('xeak',$autologin_args->autologin_key, time()+60*60*24*365, '/'); - } - - $this->setSessionInfo($member_info); - - return $output; - } - - /** - * @brief 세션 정보 갱싱 또는 생성 - **/ - function setSessionInfo($member_info = null) { - $oMemberModel = &getModel('member'); - - // 사용자 정보가 넘어오지 않았다면 현재 세션 정보에서 사용자 정보를 추출 - if(!$member_info && $_SESSION['member_srl'] && $oMemberModel->isLogged() ) { - $member_info = $oMemberModel->getMemberInfoByMemberSrl($_SESSION['member_srl']); - - // 회원정보가 없다면 세션 파기 - if($member_info->member_srl != $_SESSION['member_srl']) { - $this->destroySessionInfo(); - return; - } - } - - // 사용중지 아이디이면 세션 파기 - if($member_info->denied=='Y') { - $this->destroySessionInfo(); - return; - } - - // 오픈아이디인지 체크 (일단 아이디 형식으로만 결정) - if(preg_match("/^([_0-9a-zA-Z]+)$/is", $member_info->user_id)) $member_info->is_openid = false; - else $member_info->is_openid = true; - - // 로그인 처리를 위한 세션 설정 - $_SESSION['is_logged'] = true; - $_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR']; - $_SESSION['member_srl'] = $member_info->member_srl; - $_SESSION['is_admin'] = ''; - - // 비밀번호는 세션에 저장되지 않도록 지워줌;; - //unset($member_info->password); - - // 사용자 그룹 설정 - /* - if($member_info->group_list) { - $group_srl_list = array_keys($member_info->group_list); - $_SESSION['group_srls'] = $group_srl_list; - - // 관리자 그룹일 경우 관리자로 지정 - $oMemberModel = &getModel('member'); - $admin_group = $oMemberModel->getAdminGroup(); - if($admin_group->group_srl && in_array($admin_group->group_srl, $group_srl_list)) $_SESSION['is_admin'] = 'Y'; - } - */ - - // 세션에 로그인 사용자 정보 저장 - $_SESSION['logged_info'] = $member_info; - Context::set('is_logged', true); - Context::set('logged_info', $member_info); - - // 사용자의 전용 메뉴 구성 (이 메뉴는 애드온등으로 변경될 수 있음) - $this->addMemberMenu( 'dispMemberInfo', 'cmd_view_member_info'); - $this->addMemberMenu( 'dispMemberScrappedDocument', 'cmd_view_scrapped_document'); - $this->addMemberMenu( 'dispMemberSavedDocument', 'cmd_view_saved_document'); - $this->addMemberMenu( 'dispMemberOwnDocument', 'cmd_view_own_document'); - } - - /** - * @brief 로그인한 사용자의 개인화된 메뉴 제공을 위한 method - * 로그인 정보 출력 위젯 또는 개인화 페이지에서 사용됨 - **/ - function addMemberMenu($act, $str) { - $logged_info = Context::get('logged_info'); - - $logged_info->menu_list[$act] = Context::getLang($str); - - Context::set('logged_info', $logged_info); - $_SESSION['logged_info'] = $logged_info; - } - - /** - * @brief 로그인 회원의 닉네임등을 클릭할때 나타나는 팝업 메뉴를 추가하는 method - **/ - function addMemberPopupMenu($url, $str, $icon = '', $target = 'self') { - $member_popup_menu_list = Context::get('member_popup_menu_list'); - if(!is_array($member_popup_menu_list)) $member_popup_menu_list = array(); - - $obj->url = $url; - $obj->str = $str; - $obj->icon = $icon; - $obj->target = $target; - $member_popup_menu_list[] = $obj; - - Context::set('member_popup_menu_list', $member_popup_menu_list); - } - - /** - * @brief member 테이블에 사용자 추가 - **/ - function insertMember(&$args, $password_is_hashed = false) { - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('member.insertMember', 'before', $args); - if(!$output->toBool()) return $output; - - // 멤버 설정 정보에서 가입약관 부분을 재확인 - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - $logged_info = Context::get('logged_info'); - - // 임시 제한 일자가 있을 경우 제한 일자에 내용 추가 - if($config->limit_day) $args->limit_date = date("YmdHis", time()+$config->limit_day*60*60*24); - - // 입력할 사용자의 아이디를 소문자로 변경 - $args->user_id = strtolower($args->user_id); - - // 필수 변수들의 조절 - if($args->allow_mailing!='Y') $args->allow_mailing = 'N'; - if($args->denied!='Y') $args->denied = 'N'; - $args->allow_message= 'Y'; - - if($logged_info->is_admin == 'Y') { - if($args->is_admin!='Y') $args->is_admin = 'N'; - } else { - unset($args->is_admin); - } - - list($args->email_id, $args->email_host) = explode('@', $args->email_address); - - // 홈페이지, 블로그의 주소 검사 - if($args->homepage && !preg_match("/^[a-z]+:\/\//i",$args->homepage)) $args->homepage = 'http://'.$args->homepage; - if($args->blog && !preg_match("/^[a-z]+:\/\//i",$args->blog)) $args->blog = 'http://'.$args->blog; - - // 모델 객체 생성 - $oMemberModel = &getModel('member'); - // 금지 아이디인지 체크 - if($oMemberModel->isDeniedID($args->user_id)) return new Object(-1,'denied_user_id'); - - // 아이디, 닉네임, email address 의 중복 체크 - $member_srl = $oMemberModel->getMemberSrlByUserID($args->user_id); - if($member_srl) return new Object(-1,'msg_exists_user_id'); - - $member_srl = $oMemberModel->getMemberSrlByNickName($args->nick_name); - if($member_srl) return new Object(-1,'msg_exists_nick_name'); - - $member_srl = $oMemberModel->getMemberSrlByEmailAddress($args->email_address); - if($member_srl) return new Object(-1,'msg_exists_email_address'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - // DB에 입력 - $args->member_srl = getNextSequence(); - if($args->password && !$password_is_hashed) $args->password = md5($args->password); - elseif(!$args->password) unset($args->password); - - $output = executeQuery('member.insertMember', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 입력된 그룹 값이 없으면 기본 그룹의 값을 등록 - if(!$args->group_srl_list) { - $default_group = $oMemberModel->getDefaultGroup(0); - - // 기본 그룹에 추가 - $output = $this->addMemberToGroup($args->member_srl,$default_group->group_srl); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 입력된 그룹 값이 있으면 해당 그룹의 값을 등록 - } else { - $group_srl_list = explode('|@|', $args->group_srl_list); - for($i=0;$iaddMemberToGroup($args->member_srl,$group_srl_list[$i]); - - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - } - } - - // 메일 인증 모드 사용시(가입된 회원이 denied일 때) 인증 메일 발송 - if ($args->denied == 'Y') { - // 인증 DB에 데이터를 넣음 - $auth_args->user_id = $args->user_id; - $auth_args->member_srl = $args->member_srl; - $auth_args->new_password = $args->password; - $auth_args->auth_key = md5(rand(0, 999999)); - $auth_args->is_register = 'Y'; - - $output = executeQuery('member.insertAuthMail', $auth_args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 메일 내용을 구함 - Context::set('auth_args', $auth_args); - Context::set('member_info', $args); - - $member_config = $oModuleModel->getModuleConfig('member'); - if(!$member_config->skin) $this->member_config->skin = "default"; - if(!$member_config->colorset) $this->member_config->colorset = "white"; - - Context::set('member_config', $member_config); - - $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); - if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); - - $auth_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$args->member_srl, 'auth_key',$auth_args->auth_key); - Context::set('auth_url', $auth_url); - - $oTemplate = &TemplateHandler::getInstance(); - $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); - - // 사이트 웹마스터 정보를 구함 - $oModuleModel = &getModel('module'); - $member_config = $oModuleModel->getModuleConfig('member'); - - // 메일 발송 - $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); - $oMail->setContent($content); - $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); - $oMail->setReceiptor( $args->user_name, $args->email_address ); - $oMail->send(); - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('member.insertMember', 'after', $args); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - $oDB->commit(true); - - $output->add('member_srl', $args->member_srl); - return $output; - } - - /** - * @brief member 정보 수정 - **/ - function updateMember($args) { - // trigger 호출 (before) - $output = ModuleHandler::triggerCall('member.updateMember', 'before', $args); - if(!$output->toBool()) return $output; - - // 모델 객체 생성 - $oMemberModel = &getModel('member'); - - $logged_info = Context::get('logged_info'); - - // 수정하려는 대상의 원래 정보 가져오기 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->member_srl); - if(!$args->user_id) $args->user_id = $member_info->user_id; - - // 필수 변수들의 조절 - if($args->allow_mailing!='Y') $args->allow_mailing = 'N'; - if($args->allow_message && !in_array($args->allow_message, array('Y','N','F'))) $args->allow_message = 'Y'; - - if($logged_info->is_admin == 'Y') { - if($args->denied!='Y') $args->denied = 'N'; - if($args->is_admin!='Y' && $logged_info->member_srl != $args->member_srl) $args->is_admin = 'N'; - } else { - unset($args->is_admin); - unset($args->denied); - } - - list($args->email_id, $args->email_host) = explode('@', $args->email_address); - - // 홈페이지, 블로그의 주소 검사 - if($args->homepage && !preg_match("/^[a-z]+:\/\//is",$args->homepage)) $args->homepage = 'http://'.$args->homepage; - if($args->blog && !preg_match("/^[a-z]+:\/\//is",$args->blog)) $args->blog = 'http://'.$args->blog; - - // 아이디, 닉네임, email address 의 중복 체크 - $member_srl = $oMemberModel->getMemberSrlByUserID($args->user_id); - if($member_srl&&$args->member_srl!=$member_srl) return new Object(-1,'msg_exists_user_id'); - - $member_srl = $oMemberModel->getMemberSrlByNickName($args->nick_name); - if($member_srl&&$args->member_srl!=$member_srl) return new Object(-1,'msg_exists_nick_name'); - - $member_srl = $oMemberModel->getMemberSrlByEmailAddress($args->email_address); - if($member_srl&&$args->member_srl!=$member_srl) return new Object(-1,'msg_exists_email_address'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - // DB에 update - if($args->password) $args->password = md5($args->password); - else $args->password = $member_info->password; - if(!$args->user_name) $args->user_name = $member_info->user_name; - - $output = executeQuery('member.updateMember', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 그룹 정보가 있으면 그룹 정보를 변경 - if($args->group_srl_list) { - $group_srl_list = explode('|@|', $args->group_srl_list); - $args->site_srl = 0; - - // 일단 해당 회원의 모든 그룹 정보를 삭제 - $output = executeQuery('member.deleteMemberGroupMember', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 하나 하나 루프를 돌면서 입력 - for($i=0;$iaddMemberToGroup($args->member_srl,$group_srl_list[$i]); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - } - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('member.updateMember', 'after', $args); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - $oDB->commit(); - - // 세션에 저장 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->member_srl); - - $logged_info = Context::get('logged_info'); - if($logged_info->member_srl == $member_srl) { - $_SESSION['logged_info'] = $member_info; - } - - $output->add('member_srl', $args->member_srl); - return $output; - } - - /** - * @brief member 비밀번호 수정 - **/ - function updateMemberPassword($args) { - $args->password = md5($args->password); - return executeQuery('member.updateMemberPassword', $args); - } - - /** - * @brief 사용자 삭제 - **/ - function deleteMember($member_srl) { - // trigger 호출 (before) - $trigger_obj->member_srl = $member_srl; - $output = ModuleHandler::triggerCall('member.deleteMember', 'before', $trigger_obj); - if(!$output->toBool()) return $output; - - // 모델 객체 생성 - $oMemberModel = &getModel('member'); - - // 해당 사용자의 정보를 가져옴 - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - if(!$member_info) return new Object(-1, 'msg_not_exists_member'); - - // 관리자의 경우 삭제 불가능 - if($member_info->is_admin == 'Y') return new Object(-1, 'msg_cannot_delete_admin'); - - $oDB = &DB::getInstance(); - $oDB->begin(); - - $args->member_srl = $member_srl; - // member_auth_mail에서 해당 항목들 삭제 - $output = executeQuery('member.deleteAuthMail', $args); - if (!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // member_openid에서 해당 항목들 삭제 - $output = executeQuery('member.deleteMemberOpenIDByMemberSrl', $ags); - - // TODO: 테이블 업그레이드를 하지 않은 경우에 실패할 수 있다. - /* - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - */ - - // member_group_member에서 해당 항목들 삭제 - $output = executeQuery('member.deleteMemberGroupMember', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // member 테이블에서 삭제 - $output = executeQuery('member.deleteMember', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('member.deleteMember', 'after', $trigger_obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - $oDB->commit(); - - // 이름이미지, 이미지마크, 서명 삭제 - $this->procMemberDeleteImageName(); - $this->procMemberDeleteImageMark(); - $this->delSignature($member_srl); - - return $output; - } - - /** - * @brief 모든 세션 정보 파기 - **/ - function destroySessionInfo() { - if(!$_SESSION || !is_array($_SESSION)) return; - foreach($_SESSION as $key => $val) { - $_SESSION[$key] = ''; - } - session_destroy(); - setcookie(session_name(), '', time()-42000, '/'); - setcookie('sso','',time()-42000, '/'); - - if($_COOKIE['xeak']) { - $args->autologin_key = $_COOKIE['xeak']; - executeQuery('member.deleteAutologin', $args); - } - } - } -?> +doLogin($user_id, $password, $keep_signed=='Y'?true:false); + + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($config->after_login_url) $this->setRedirectUrl($config->after_login_url); + + $redirect_url = Context::get('redirect_url'); + if($output->toBool() && Context::getRequestMethod() == "POST" && $redirect_url) + { + header("location:" . $redirect_url); + } + + return $output; + } + + /** + * @brief openid로그인 + **/ + function procMemberOpenIDLogin($validator = "procMemberOpenIDValidate") { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($config->enable_openid != 'Y') $this->stop('msg_invalid_request'); + + if(!defined('Auth_OpenID_RAND_SOURCE') && !file_exists("/dev/urandom")) + { + define('Auth_OpenID_RAND_SOURCE', null); + } + + set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); + require_once('Auth/OpenID.php'); + require_once('Auth/OpenID/Consumer.php'); + require_once('Auth/OpenID/XEStore.php'); + $store = new Auth_OpenID_XEStore(); + $consumer = new Auth_OpenID_Consumer($store); + + $user_id = Context::get('user_id'); + if (!$user_id) $user_id = Context::get('openid'); + $auth_request = $consumer->begin($user_id); + $auth_request->addExtensionArg('sreg', 'required', 'email'); + $auth_request->addExtensionArg('sreg', 'optional', 'dob'); + if(!$auth_request) + { + return new Object(-1, "association failed"); + } + + $trust_root = 'http://'.$_SERVER["HTTP_HOST"]; + $referer_url = Context::get('referer_url'); + if (!$referer_url) $referer_url = $_SERVER['HTTP_REFERER']; + if (!$referer_url) + $referer_url = htmlspecialchars_decode(getRequestUri(RELEASE_SSL)); + $goto = urlencode($referer_url); + $ApprovedURL = Context::getRequestUri(RELEASE_SSL) . "?module=member&act=" . $validator. "&goto=" . $goto; + $redirect_url = $auth_request->redirectURL($trust_root, $ApprovedURL); + $this->add("redirect_url", $redirect_url); + if (Context::getRequestMethod() == 'POST') + header("location:" . $redirect_url); + } + + function getLegacyUserIDsFromOpenID($openid_identity) { + // Issue 17515512: workaround + $result = array(); + $uri_matches = array(); + preg_match(Auth_OpenID_getURIPattern(), $openid_identity, $uri_matches); + + if (count($uri_matches) < 9) { + for ($i = count($uri_matches); $i <= 9; $i++) { + $uri_matches[] = ''; + } + } + + $scheme = $uri_matches[2]; + $authority = $uri_matches[4]; + $path = $uri_matches[5]; + $query = $uri_matches[6]; + $fragment = $uri_matches[8]; + + if ($scheme === null) $scheme = ''; + if ($authority === null) $authority = ''; + if ($path === null) $path = ''; + if ($query === null) $query = ''; + if ($fragment === null) $fragment = ''; + + if ($scheme == 'http' or $scheme == '') + $scheme_part = ''; + else + $scheme_part = $scheme."://"; + + + if ($path == '' || $path == '/') { + $result[] = $scheme_part.$authority.''.$query.$fragment; + $result[] = $scheme_part.$authority.'/'.$query.$fragment; + } + else { + $result[] = $scheme_part.$authority.$path.$query.$fragment; + } + + return $result; + } + + /** + * @brief openid 인증 체크 + **/ + function procMemberOpenIDValidate() { + set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); + require_once('Auth/OpenID.php'); + require_once('Auth/OpenID/Consumer.php'); + require_once('Auth/OpenID/XEStore.php'); + require_once('Auth/OpenID/URINorm.php'); + + $store = new Auth_OpenID_XEStore(); + $consumer = new Auth_OpenID_Consumer($store); + $response = $consumer->complete($_GET); + switch($response->status) { + case Auth_OpenID_CANCEL : + // 사용자가 인증을 취소했을 때의 처리 + return $this->stop('authorization_canceled'); + case Auth_OpenID_FAILURE : + // 무언가의 문제로 인해 인증이 실패했을 때의 처리(인증을 요구한 openid가 없다든가..) + return $this->stop('invalid_authorization'); + case Auth_OpenID_SUCCESS : + // 인증성공!! + break; + default: + return $this->stop('invalid_authorization'); + } + + // 인증 성공 + $oMemberModel = &getModel('member'); + + // 이 오픈아이디와 연결된 (또는 연결되어 있을 가능성이 있는) 제로보드 아이디들을 받아온다. + $login_success = false; + $assoc_member_info = null; + $openid_identity = $response->signed_args["openid.identity"]; + $args->openid = $openid_identity; + $output = executeQuery('member.getMemberSrlByOpenID', $args); + + if ($output->toBool() && $output->data && !is_array($output->data)) { + $member_srl = $output->data->member_srl; + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + if ($member_info) { + $assoc_member_info = $member_info; + } + } + + $user_id_candidates = $this->getLegacyUserIDsFromOpenID($openid_identity); + $default_user_id = $user_id_candidates[0]; + + if ($assoc_member_info != null) { + $user_id_candidates = array_merge(array($assoc_member_info->user_id), $user_id_candidates); + } + $sreg = $response->extensionResponse('sreg'); + + foreach($user_id_candidates as $user_id) { + $args->user_id = $args->nick_name = $user_id; + // 기본 정보들을 받음 + $args->email_address = $sreg['email']; + $args->user_name = $sreg['fullname']; + if(!$args->user_name) list($args->user_name) = explode('@', $args->email_address); + $args->birthday = str_replace('-','',$sreg['dob']); + + // 자체 인증 시도 + $output = $this->doLogin($args->user_id); + + if ($output->toBool()) { + if ($assoc_member_info == null) { + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + $args->openid = $openid_identity; + executeQuery('member.addOpenIDToMember', $args); + } + $login_success = true; + break; + } + } + + // 자체 인증 실패시 회원 가입시킴 + if(!$login_success) { + $args->user_id = $args->nick_name = $default_user_id; + $args->password = md5(getmicrotime()); + + $output = $this->insertMember($args); + if(!$output->toBool()) return $this->stop($output->getMessage()); + $output = $this->doLogin($args->user_id); + if(!$output->toBool()) return $this->stop($output->getMessage()); + + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + $args->openid = $openid_identity; + executeQuery('member.addOpenIDToMember', $args); + } + + Context::close(); + + // 페이지 이동 + if(Context::get('goto')) { + $goto = Context::get('goto'); + header("location:" . $goto); + } else { + header("location:./"); + } + + exit(); + } + + /** + * @brief 오픈아이디 연결 요청 + **/ + function procMemberAddOpenIDToMember() { + return $this->procMemberOpenIDLogin("procMemberValidateAddOpenIDToMember"); + } + + /** + * @brief 오픈아이디 연결 요청 마무리 + **/ + function procMemberValidateAddOpenIDToMember() { + set_include_path(_XE_PATH_."modules/member/php-openid-1.2.3"); + require_once('Auth/OpenID.php'); + require_once('Auth/OpenID/Consumer.php'); + require_once('Auth/OpenID/XEStore.php'); + require_once('Auth/OpenID/URINorm.php'); + + $store = new Auth_OpenID_XEStore(); + $consumer = new Auth_OpenID_Consumer($store); + $response = $consumer->complete($_GET); + + switch($response->status) { + case Auth_OpenID_CANCEL : + // 사용자가 인증을 취소했을 때의 처리 + return $this->stop('authorization_canceled'); + case Auth_OpenID_FAILURE : + // 무언가의 문제로 인해 인증이 실패했을 때의 처리(인증을 요구한 openid가 없다든가..) + return $this->stop('invalid_authorization'); + case Auth_OpenID_SUCCESS : + { + $logged_info = Context::get('logged_info'); + if (!Context::get('is_logged')) return $this->stop('msg_not_logged'); + + $member_srl = $logged_info->member_srl; + + $args->member_srl = $member_srl; + $openid_identity = $response->signed_args["openid.identity"]; + $args->openid = $openid_identity; + + $output = executeQuery('member.addOpenIDToMember', $args); + if (!$output->toBool()) return $output; + + Context::close(); + + if(Context::get('goto')){ + $goto = Context::get('goto'); + header("location:" . $goto); + }else{ + header("location:./"); + } + exit(); + } + // 인증성공!! + break; + default: + return $this->stop('invalid_authorization'); + } + } + + /** + * @brief 오픈아이디 연결 해제 + **/ + function procMemberDeleteOpenIDFromMember() { + $logged_info = Context::get('logged_info'); + $openid_identity = Context::get('openid_to_delete'); + $arg->openid = $openid_identity; + $result = executeQuery('member.getMemberSrlByOpenID', $arg); + + if (!Context::get('is_logged')) { + $this->setError(-1); + $this->setMessage('msg_not_logged'); + return; + } else if (!$result->data || is_array($result->data)) { + $this->setError(-1); + $this->setMessage('msg_not_founded'); + return; + } else if ($result->data->member_srl != $logged_info->member_srl) { + $this->setError(-1); + $this->setMessage('msg_not_permitted'); + return; + } + + $arg->openid = $openid_identity; + + $output = executeQuery('member.deleteMemberOpenID', $arg); + if(!$output->toBool()) return $output; + + $this->setMessage('success_updated'); + } + + + /** + * @brief 로그아웃 + **/ + function procMemberLogout() { + // 로그아웃 이전에 trigger 호출 (before) + $logged_info = Context::get('logged_info'); + $trigger_output = ModuleHandler::triggerCall('member.doLogout', 'before', $logged_info); + if(!$trigger_output->toBool()) return $trigger_output; + + // 세션 정보 파기 + $this->destroySessionInfo(); + + // 로그아웃 이후 trigger 호출 (after) + $trigger_output = ModuleHandler::triggerCall('member.doLogout', 'after', $logged_info); + if(!$trigger_output->toBool()) return $trigger_output; + + $output = new Object(); + + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($config->after_logout_url) Context::set('redirect_url', $config->after_logout_url); + + return $output; + } + + /** + * @brief 스크랩 기능 + **/ + function procMemberScrapDocument() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + $document_srl = (int)Context::get('document_srl'); + if(!$document_srl) $document_srl = (int)Context::get('target_srl'); + if(!$document_srl) return new Object(-1,'msg_invalid_request'); + + // 문서 가져오기 + $oDocumentModel = &getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + // 변수 정리 + $args->document_srl = $document_srl; + $args->member_srl = $logged_info->member_srl; + $args->user_id = $oDocument->get('user_id'); + $args->user_name = $oDocument->get('user_name'); + $args->nick_name = $oDocument->get('nick_name'); + $args->target_member_srl = $oDocument->get('member_srl'); + $args->title = $oDocument->get('title'); + + // 있는지 조사 + $output = executeQuery('member.getScrapDocument', $args); + if($output->data->count) return new Object(-1, 'msg_alreay_scrapped'); + + // 입력 + $output = executeQuery('member.addScrapDocument', $args); + if(!$output->toBool()) return $output; + + $this->setError(-1); + $this->setMessage('success_registed'); + } + + /** + * @brief 스크랩 삭제 + **/ + function procMemberDeleteScrap() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + $document_srl = (int)Context::get('document_srl'); + if(!$document_srl) return new Object(-1,'msg_invalid_request'); + + // 변수 정리 + $args->member_srl = $logged_info->member_srl; + $args->document_srl = $document_srl; + return executeQuery('member.deleteScrapDocument', $args); + } + + /** + * @brief 게시글 저장 + **/ + function procMemberSaveDocument() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + + $logged_info = Context::get('logged_info'); + + // form 정보를 모두 받음 + $obj = Context::getRequestVars(); + + // 글의 대상 모듈을 회원 정보로 변경 + $obj->module_srl = $logged_info->member_srl; + + // 제목을 사용하지 않는 방명록 등에서 내용 앞 부분을 제목 가져오기 + if(!$obj->title) { + $obj->title = cut_str(strip_tags($obj->content), 20, '...'); + } + + $oDocumentModel = &getModel('document'); + $oDocumentController = &getController('document'); + + // 이미 존재하는 글인지 체크 + $oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager); + + // 이미 존재하는 경우 수정 + if($oDocument->isExists() && $oDocument->document_srl == $obj->document_srl) { + $output = $oDocumentController->updateDocument($oDocument, $obj); + $msg_code = 'success_updated'; + + // 그렇지 않으면 신규 등록 + } else { + $output = $oDocumentController->insertDocument($obj); + $msg_code = 'success_registed'; + $obj->document_srl = $output->get('document_srl'); + $oDocument = $oDocumentModel->getDocument($obj->document_srl, $this->grant->manager); + } + + // 등록된 첨부파일의 상태를 무효로 지정 + if($oDocument->hasUploadedFiles()) { + $args->upload_target_srl = $oDocument->document_srl; + $args->isvalid = 'N'; + executeQuery('file.updateFileValid', $args); + } + + $this->setMessage('success_saved'); + $this->add('document_srl', $obj->document_srl); + } + + /** + * @brief 저장된 글 삭제 + **/ + function procMemberDeleteSavedDocument() { + // 로그인 정보 체크 + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_logged'); + $logged_info = Context::get('logged_info'); + + $document_srl = (int)Context::get('document_srl'); + if(!$document_srl) return new Object(-1,'msg_invalid_request'); + + // 변수 정리 + $oDocumentController = &getController('document'); + $oDocumentController->deleteDocument($document_srl, true); + } + + /** + * @brief 회원 가입시 특정 항목들에 대한 값 체크 + **/ + function procMemberCheckValue() { + $name = Context::get('name'); + $value = Context::get('value'); + if(!$value) return; + + $oMemberModel = &getModel('member'); + + // 로그인 여부 체크 + $logged_info = Context::get('logged_info'); + + + switch($name) { + case 'user_id' : + // 금지 아이디 검사 + if($oMemberModel->isDeniedID($value)) return new Object(0,'denied_user_id'); + + // 중복 검사 + $member_srl = $oMemberModel->getMemberSrlByUserID($value); + if($member_srl && $logged_info->member_srl != $member_srl ) return new Object(0,'msg_exists_user_id'); + break; + case 'nick_name' : + // 중복 검사 + $member_srl = $oMemberModel->getMemberSrlByNickName($value); + if($member_srl && $logged_info->member_srl != $member_srl ) return new Object(0,'msg_exists_nick_name'); + + break; + case 'email_address' : + // 중복 검사 + $member_srl = $oMemberModel->getMemberSrlByEmailAddress($value); + if($member_srl && $logged_info->member_srl != $member_srl ) return new Object(0,'msg_exists_email_address'); + break; + } + } + + /** + * @brief 회원 가입 + **/ + function procMemberInsert() { + if(Context::getRequestMethod() == "GET") return new Object(-1, "msg_invalid_request"); + $oMemberModel = &getModel('member'); + $config = $oMemberModel->getMemberConfig(); + + // before 트리거 호출 + $trigger_output = ModuleHandler::triggerCall('member.procMemberInsert', 'before', $config); + if(!$trigger_output->toBool()) return $trigger_output; + + // 관리자가 회원가입을 허락하였는지 검사 + if($config->enable_join != 'Y') return $this->stop('msg_signup_disabled'); + + // 약관에 동의하였는지 검사 (약관이 있을 경우만) + if($config->agreement && Context::get('accept_agreement')!='Y') return $this->stop('msg_accept_agreement'); + + // 필수 정보들을 미리 추출 + $args = Context::gets('user_id','user_name','nick_name','homepage','blog','birthday','email_address','password','allow_mailing'); + $args->member_srl = getNextSequence(); + + // 넘어온 모든 변수중에서 몇가지 불필요한 것들 삭제 + $all_args = Context::getRequestVars(); + unset($all_args->module); + unset($all_args->act); + unset($all_args->is_admin); + unset($all_args->description); + unset($all_args->group_srl_list); + unset($all_args->body); + unset($all_args->accept_agreement); + unset($all_args->signature); + + // 메일 인증 기능 사용시 회원 상태를 denied로 설정 + if ($config->enable_confirm == 'Y') $args->denied = 'Y'; + + // 모든 request argument에서 필수 정보만 제외 한 후 추가 데이터로 입력 + $extra_vars = delObjectVars($all_args, $args); + $args->extra_vars = serialize($extra_vars); + + // member_srl의 값에 따라 insert/update + $output = $this->insertMember($args); + if(!$output->toBool()) return $output; + + // 가상사이트일 경우 사이트 가입 + $site_module_info = Context::get('site_module_info'); + if($site_module_info->site_srl > 0) { + $default_group = $oMemberModel->getDefaultGroup($site_module_info->site_srl); + if($default_group->group_srl) { + $this->addMemberToGroup($args->member_srl, $default_group->group_srl, $site_module_info->site_srl); + } + + } + + // 로그인 시킴 + if ($config->enable_confirm != 'Y') $this->doLogin($args->user_id); + + // 결과 정리 + $this->add('member_srl', $args->member_srl); + if($config->redirect_url) $this->add('redirect_url', $config->redirect_url); + if ($config->enable_confirm == 'Y') { + $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $args->email_address); + $this->setMessage($msg); + } + else $this->setMessage('success_registed'); + + // after 트리거 호출 + $trigger_output = ModuleHandler::triggerCall('member.procMemberInsert', 'after', $config); + if(!$trigger_output->toBool()) return $trigger_output; + } + + /** + * @brief 회원 정보 수정 + **/ + function procMemberModifyInfo() { + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + + // 필수 정보들을 미리 추출 + $args = Context::gets('user_name','nick_name','homepage','blog','birthday','email_address','allow_mailing'); + + // 로그인 정보 + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + + // 넘어온 모든 변수중에서 몇가지 불필요한 것들 삭제 + $all_args = Context::getRequestVars(); + unset($all_args->module); + unset($all_args->act); + unset($all_args->is_admin); + unset($all_args->description); + unset($all_args->group_srl_list); + unset($all_args->body); + unset($all_args->accept_agreement); + unset($all_args->signature); + + // 모든 request argument에서 필수 정보만 제외 한 후 추가 데이터로 입력 + $extra_vars = delObjectVars($all_args, $args); + $args->extra_vars = serialize($extra_vars); + + // 멤버 모델 객체 생성 + $oMemberModel = &getModel('member'); + + // member_srl의 값에 따라 insert/update + $output = $this->updateMember($args); + if(!$output->toBool()) return $output; + + // 서명 저장 + $signature = Context::get('signature'); + $this->putSignature($args->member_srl, $signature); + + // user_id 에 따른 정보 가져옴 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->member_srl); + + // 로그인 성공후 trigger 호출 (after) + $trigger_output = ModuleHandler::triggerCall('member.doLogin', 'after', $member_info); + if(!$trigger_output->toBool()) return $trigger_output; + + $this->setSessionInfo($member_info); + + // 결과 리턴 + $this->add('member_srl', $args->member_srl); + $this->setMessage('success_updated'); + } + + /** + * @brief 회원 비밀번호 수정 + **/ + function procMemberModifyPassword() { + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + + // 필수 정보들을 미리 추출 + $current_password = trim(Context::get('current_password')); + $password = trim(Context::get('password')); + + // 로그인한 유저의 정보를 가져옴 + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + // member model 객체 생성 + $oMemberModel = &getModel('member'); + + // member_srl 에 따른 정보 가져옴 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + + // 현재 비밀번호가 맞는지 확인 + if(!$oMemberModel->isValidPassword($member_info->password, $current_password)) return new Object(-1, 'invalid_password'); + + // member_srl의 값에 따라 insert/update + $args->member_srl = $member_srl; + $args->password = $password; + $output = $this->updateMemberPassword($args); + if(!$output->toBool()) return $output; + + $this->add('member_srl', $args->member_srl); + $this->setMessage('success_updated'); + } + + /** + * @brief 탈퇴 + **/ + function procMemberLeave() { + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + + // 필수 정보들을 미리 추출 + $password = trim(Context::get('password')); + + // 로그인한 유저의 정보를 가져옴 + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + // member model 객체 생성 + $oMemberModel = &getModel('member'); + + // member_srl 에 따른 정보 가져옴 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + + // 현재 비밀번호가 맞는지 확인 + if(!$oMemberModel->isValidPassword($member_info->password, $password)) return new Object(-1, 'invalid_password'); + + $output = $this->deleteMember($member_srl); + if(!$output->toBool()) return $output; + + // 모든 세션 정보 파기 + $this->destroySessionInfo(); + + // 성공 메세지 리턴 + $this->setMessage('success_leaved'); + } + + /** + * @brief 오픈아이디 탈퇴 + **/ + function procMemberOpenIDLeave() { + // 비로그인 상태이면 에러 + if(!Context::get('is_logged')) return $this->stop('msg_not_logged'); + + // 현재 ip와 세션 아이피 비교 + if($_SESSION['ipaddress']!=$_SERVER['REMOTE_ADDR']) return $this->stop('msg_not_permitted'); + + // 로그인한 유저의 정보를 가져옴 + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + $output = $this->deleteMember($member_srl); + if(!$output->toBool()) return $output; + + // 모든 세션 정보 파기 + $this->destroySessionInfo(); + + // 성공 메세지 리턴 + $this->setMessage('success_leaved'); + } + + /** + * @brief 프로필 이미지 추가 + **/ + function procMemberInsertProfileImage() { + // 정상적으로 업로드 된 파일인지 검사 + $file = $_FILES['profile_image']; + if(!is_uploaded_file($file['tmp_name'])) return $this->stop('msg_not_uploaded_profile_image'); + + // 회원 정보를 검사해서 회원번호가 없거나 관리자가 아니고 회원번호가 틀리면 무시 + $member_srl = Context::get('member_srl'); + if(!$member_srl) return $this->stop('msg_not_uploaded_profile_image'); + + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_profile_image'); + + // 회원 모듈 설정에서 이미지 이름 사용 금지를 하였을 경우 관리자가 아니면 return; + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($logged_info->is_admin != 'Y' && $config->profile_image != 'Y') return $this->stop('msg_not_uploaded_profile_image'); + + $this->insertProfileImage($member_srl, $file['tmp_name']); + + // 페이지 리프레쉬 + $this->setRefreshPage(); + } + + function insertProfileImage($member_srl, $target_file) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + // 정해진 사이즈를 구함 + $max_width = $config->profile_image_max_width; + if(!$max_width) $max_width = "90"; + $max_height = $config->profile_image_max_height; + if(!$max_height) $max_height = "20"; + + // 저장할 위치 구함 + $target_path = sprintf('files/member_extra_info/profile_image/%s', getNumberingPath($member_srl)); + FileHandler::makeDir($target_path); + + // 파일 정보 구함 + list($width, $height, $type, $attrs) = @getimagesize($target_file); + if($type == 3) $ext = 'png'; + elseif($type == 2) $ext = 'jpg'; + else $ext = 'gif'; + + $target_filename = sprintf('%s%d.%s', $target_path, $member_srl, $ext); + + // 지정된 사이즈보다 크거나 gif가 아니면 변환 + if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, $ext); + else @copy($target_file, $target_filename); + } + + /** + * @brief 이미지 이름을 추가 + **/ + function procMemberInsertImageName() { + // 정상적으로 업로드 된 파일인지 검사 + $file = $_FILES['image_name']; + if(!is_uploaded_file($file['tmp_name'])) return $this->stop('msg_not_uploaded_image_name'); + + // 회원 정보를 검사해서 회원번호가 없거나 관리자가 아니고 회원번호가 틀리면 무시 + $member_srl = Context::get('member_srl'); + if(!$member_srl) return $this->stop('msg_not_uploaded_image_name'); + + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_name'); + + // 회원 모듈 설정에서 이미지 이름 사용 금지를 하였을 경우 관리자가 아니면 return; + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($logged_info->is_admin != 'Y' && $config->image_name != 'Y') return $this->stop('msg_not_uploaded_image_name'); + + $this->insertImageName($member_srl, $file['tmp_name']); + + // 페이지 리프레쉬 + $this->setRefreshPage(); + } + + function insertImageName($member_srl, $target_file) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + // 정해진 사이즈를 구함 + $max_width = $config->image_name_max_width; + if(!$max_width) $max_width = "90"; + $max_height = $config->image_name_max_height; + if(!$max_height) $max_height = "20"; + + // 저장할 위치 구함 + $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($member_srl)); + FileHandler::makeDir($target_path); + + $target_filename = sprintf('%s%d.gif', $target_path, $member_srl); + + // 파일 정보 구함 + list($width, $height, $type, $attrs) = @getimagesize($target_file); + + // 지정된 사이즈보다 크거나 gif가 아니면 변환 + if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, 'gif'); + else @copy($target_file, $target_filename); + } + + /** + * @brief 프로필 이미지를 삭제 + **/ + function procMemberDeleteProfileImage() { + $member_srl = Context::get('member_srl'); + if(!$member_srl) return new Object(0,'success'); + + $logged_info = Context::get('logged_info'); + + if($logged_info->is_admin != 'Y') { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($config->profile_image == 'N') return new Object(0,'success'); + } + + if($logged_info->is_admin == 'Y' || $logged_info->member_srl == $member_srl) { + $oMemberModel = &getModel('member'); + $profile_image = $oMemberModel->getProfileImage($member_srl); + FileHandler::removeFile($profile_image->file); + } + return new Object(0,'success'); + } + + /** + * @brief 이미지 이름을 삭제 + **/ + function procMemberDeleteImageName() { + $member_srl = Context::get('member_srl'); + if(!$member_srl) return new Object(0,'success'); + + $logged_info = Context::get('logged_info'); + + if($logged_info->is_admin != 'Y') { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($config->image_name == 'N') return new Object(0,'success'); + } + + if($logged_info->is_admin == 'Y' || $logged_info->member_srl == $member_srl) { + $oMemberModel = &getModel('member'); + $image_name = $oMemberModel->getImageName($member_srl); + FileHandler::removeFile($image_name->file); + } + return new Object(0,'success'); + } + + /** + * @brief 이미지 마크를 추가 + **/ + function procMemberInsertImageMark() { + // 정상적으로 업로드 된 파일인지 검사 + $file = $_FILES['image_mark']; + if(!is_uploaded_file($file['tmp_name'])) return $this->stop('msg_not_uploaded_image_mark'); + + // 회원 정보를 검사해서 회원번호가 없거나 관리자가 아니고 회원번호가 틀리면 무시 + $member_srl = Context::get('member_srl'); + if(!$member_srl) return $this->stop('msg_not_uploaded_image_mark'); + + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_srl) return $this->stop('msg_not_uploaded_image_mark'); + + // 회원 모듈 설정에서 이미지 마크 사용 금지를 하였을 경우 관리자가 아니면 return; + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($logged_info->is_admin != 'Y' && $config->image_mark != 'Y') return $this->stop('msg_not_uploaded_image_mark'); + + $this->insertImageMark($member_srl, $file['tmp_name']); + + // 페이지 리프레쉬 + $this->setRefreshPage(); + } + + function insertImageMark($member_srl, $target_file) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + // 정해진 사이즈를 구함 + $max_width = $config->image_mark_max_width; + if(!$max_width) $max_width = "20"; + $max_height = $config->image_mark_max_height; + if(!$max_height) $max_height = "20"; + + $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($member_srl)); + FileHandler::makeDir($target_path); + + $target_filename = sprintf('%s%d.gif', $target_path, $member_srl); + + // 파일 정보 구함 + list($width, $height, $type, $attrs) = @getimagesize($target_file); + + if($width > $max_width || $height > $max_height || $type!=1) FileHandler::createImageFile($target_file, $target_filename, $max_width, $max_height, 'gif'); + else @copy($target_file, $target_filename); + + } + + /** + * @brief 이미지 마크를 삭제 + **/ + function procMemberDeleteImageMark() { + $member_srl = Context::get('member_srl'); + if(!$member_srl) return new Object(0,'success'); + + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin == 'Y' || $logged_info->member_srl == $member_srl) { + $oMemberModel = &getModel('member'); + $image_mark = $oMemberModel->getImageMark($member_srl); + FileHandler::removeFile($image_mark->file); + } + return new Object(0,'success'); + } + + /** + * @brief 아이디/ 비밀번호 찾기 + **/ + function procMemberFindAccount() { + $email_address = Context::get('email_address'); + if(!$email_address) return new Object(-1, 'msg_invalid_request'); + + $oMemberModel = &getModel('member'); + $oModuleModel = &getModel('module'); + + // 메일 주소에 해당하는 회원이 있는지 검사 + $member_srl = $oMemberModel->getMemberSrlByEmailAddress($email_address); + if(!$member_srl) return new Object(-1, 'msg_email_not_exists'); + + // 회원의 정보를 가져옴 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + + // 아이디/비밀번호 찾기가 가능한 상태의 회원인지 검사 + if ($member_info->denied == 'Y') { + $chk_args->member_srl = $member_info->member_srl; + $output = executeQuery('member.chkAuthMail', $chk_args); + if ($output->toBool() && $output->data->count != '0') return new Object(-1, 'msg_user_not_confirmed'); + } + + // 인증 DB에 데이터를 넣음 + $args->user_id = $member_info->user_id; + $args->member_srl = $member_info->member_srl; + $args->new_password = rand(111111,999999); + $args->auth_key = md5( rand(0,999999 ) ); + $args->is_register = 'N'; + + $output = executeQuery('member.insertAuthMail', $args); + if(!$output->toBool()) return $output; + + // 메일 내용을 구함 + Context::set('auth_args', $args); + Context::set('member_info', $member_info); + + $member_config = $oModuleModel->getModuleConfig('member'); + if(!$member_config->skin) $this->member_config->skin = "default"; + if(!$member_config->colorset) $this->member_config->colorset = "white"; + + Context::set('member_config', $member_config); + + $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); + if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); + + $find_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$member_info->member_srl, 'auth_key',$args->auth_key); + Context::set('find_url',$find_url); + + + $oTemplate = &TemplateHandler::getInstance(); + $content = $oTemplate->compile($tpl_path, 'find_member_account_mail'); + + // 사이트 웹마스터 정보를 구함 + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + + // 메일 발송 + $oMail = new Mail(); + $oMail->setTitle( Context::getLang('msg_find_account_title') ); + $oMail->setContent($content); + $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); + $oMail->setReceiptor( $member_info->user_name, $member_info->email_address ); + $oMail->send(); + + // 메세지 return + $msg = sprintf(Context::getLang('msg_auth_mail_sent'), $member_info->email_address); + return new Object(0,$msg); + } + + /** + * @brief 아이디/비밀번호 찾기 기능 실행 + * 메일에 등록된 링크를 선택시 호출되는 method로 비밀번호를 바꾸고 인증을 시켜버림 + **/ + function procMemberAuthAccount() { + // user_id, authkey 검사 + $member_srl = Context::get('member_srl'); + $auth_key = Context::get('auth_key'); + if(!$member_srl || !$auth_key) return $this->stop('msg_invalid_request'); + + // user_id, authkey로 비밀번호 찾기 로그 검사 + $args->member_srl = $member_srl; + $args->auth_key = $auth_key; + $output = executeQuery('member.getAuthMail', $args); + if(!$output->toBool() || $output->data->auth_key != $auth_key) return $this->stop('msg_invalid_auth_key'); + + // 인증 정보가 맞다면 새비밀번호로 비밀번호를 바꿈 + if ($output->data->is_register == 'Y') { + $args->password = $output->data->new_password; + $args->denied = 'N'; + } else { + $args->password = md5($output->data->new_password); + unset($args->denied); + } + + // $output->data->is_register 값을 백업해 둔다. + $is_register = $output->data->is_register; + + $output = executeQuery('member.updateMemberPassword', $args); + if(!$output->toBool()) return $this->stop($output->getMessage()); + + // 인증 테이블에서 member_srl에 해당하는 모든 값을 지움 + executeQuery('member.deleteAuthMail',$args); + + // 결과를 통보 + Context::set('is_register', $is_register); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('msg_success_authed'); + } + + /** + * @brief 아이디/비밀번호 찾기 기능 실행 + * 메일에 등록된 링크를 선택시 호출되는 method로 비밀번호를 바꾸고 인증을 시켜버림 + **/ + function procMemberUpdateAuthMail() { + $member_srl = Context::get('member_srl'); + if(!$member_srl) return new Object(-1, 'msg_invalid_request'); + + $oMemberModel = &getModel('member'); + + // 회원의 정보를 가져옴 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + + // 인증메일 재발송 요청이 가능한 상태의 회원인지 검사 + if ($member_info->denied != 'Y') + return new Object(-1, 'msg_invalid_request'); + + $chk_args->member_srl = $member_srl; + $output = executeQuery('member.chkAuthMail', $chk_args); + if ($output->toBool() && $output->data->count == '0') return new Object(-1, 'msg_invalid_request'); + + // 인증 DB에 데이터를 넣음 + $auth_args->member_srl = $member_srl; + $auth_args->auth_key = md5(rand(0, 999999)); + + $output = executeQuery('member.updateAuthMail', $auth_args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 메일 내용을 구함 + Context::set('auth_args', $auth_args); + Context::set('member_info', $member_info); + + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + if(!$member_config->skin) $this->member_config->skin = "default"; + if(!$member_config->colorset) $this->member_config->colorset = "white"; + + Context::set('member_config', $member_config); + + $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); + if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); + + $auth_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$member_info->member_srl, 'auth_key',$auth_args->auth_key); + Context::set('auth_url', $auth_url); + + $oTemplate = &TemplateHandler::getInstance(); + $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); + + // 사이트 웹마스터 정보를 구함 + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + + // 메일 발송 + $oMail = new Mail(); + $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); + $oMail->setContent($content); + $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); + $oMail->setReceiptor( $member_info->user_name, $member_info->email_address ); + $oMail->send(); + + // 메세지 return + $msg = sprintf(Context::getLang('msg_auth_mail_sent'), $member_info->email_address); + return new Object(-1, $msg); + } + + /** + * @brief 인증 메일 재발송 + **/ + function procMemberResendAuthMail() { + // email_address 검사 + $email_address = Context::get('email_address'); + if(!$email_address) return $this->stop('msg_invalid_request'); + + // email_address로 비밀번호 찾기 로그 검사 + $oMemberModel = &getModel('member'); + + $args->email_address = $email_address; + $member_info = $oMemberModel->getMemberSrlByEmailAddress($email_address); + if(!$member_info) return $this->stop('msg_not_exists_member'); + + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_info); + + // 이전에 인증 메일을 보냈는지 확인 + $chk_args->member_srl = $member_info->member_srl; + $output = executeQuery('member.chkAuthMail', $chk_args); + if($output->toBool() && $output->data->count == '0') return new Object(-1, 'msg_invalid_request'); + + $auth_args->member_srl = $member_info->member_srl; + $output = executeQueryArray('member.getAuthMailInfo', $auth_args); + if(!$output->data || !$output->data[0]->auth_key) return new Object(-1, 'msg_invalid_request'); + $auth_info = $output->data[0]; + + // 메일 내용을 구함 + Context::set('member_info', $member_info); + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + if(!$member_config->skin) $this->member_config->skin = "default"; + if(!$member_config->colorset) $this->member_config->colorset = "white"; + + Context::set('member_config', $member_config); + + $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); + if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); + + $auth_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$member_info->member_srl, 'auth_key',$auth_info->auth_key); + Context::set('auth_url', $auth_url); + + $oTemplate = &TemplateHandler::getInstance(); + $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); + + // 사이트 웹마스터 정보를 구함 + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + + // 메일 발송 + $oMail = new Mail(); + $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); + $oMail->setContent($content); + $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); + $oMail->setReceiptor( $args->user_name, $args->email_address ); + $oMail->send(); + + $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $args->email_address); + $this->setMessage($msg); + } + + /** + * @brief 가상 사이트 가입 + **/ + function procModuleSiteSignUp() { + $site_module_info = Context::get('site_module_info'); + $logged_info = Context::get('logged_info'); + if(!$site_module_info->site_srl || !Context::get('is_logged') || count($logged_info->group_srl_list) ) return new Object(-1,'msg_invalid_request'); + + $oMemberModel = &getModel('member'); + $default_group = $oMemberModel->getDefaultGroup($site_module_info->site_srl); + $this->addMemberToGroup($logged_info->member_srl, $default_group->group_srl, $site_module_info->site_srl); + $groups[$default_group->group_srl] = $default_group->title; + $logged_info->group_list = $groups; + } + + /** + * @brief 가상 사이트 탈퇴 + **/ + function procModuleSiteLeave() { + $site_module_info = Context::get('site_module_info'); + $logged_info = Context::get('logged_info'); + if(!$site_module_info->site_srl || !Context::get('is_logged') || count($logged_info->group_srl_list) ) return new Object(-1,'msg_invalid_request'); + + $args->site_srl= $site_module_info->site_srl; + $args->member_srl = $logged_info->member_srl; + $output = executeQuery('member.deleteMembersGroup', $args); + if(!$output->toBool()) return $output; + $this->setMessage('success_deleted'); + } + + /** + * @brief 회원 설정 정보를 저장 + **/ + function setMemberConfig($args) { + if(!$args->skin) $args->skin = "default"; + if(!$args->colorset) $args->colorset = "white"; + if(!$args->editor_skin) $args->editor_skin= "xpresseditor"; + if(!$args->editor_colorset) $args->editor_colorset = "white"; + if($args->enable_join!='Y') $args->enable_join = 'N'; + if($args->enable_openid!='Y') $args->enable_openid= 'N'; + if($args->profile_image !='Y') $args->profile_image = 'N'; + if($args->image_name!='Y') $args->image_name = 'N'; + if($args->image_mark!='Y') $args->image_mark = 'N'; + if($args->group_image_mark!='Y') $args->group_image_mark = 'N'; + if(!trim(strip_tags($args->agreement))) $args->agreement = null; + $args->limit_day = (int)$args->limit_day; + + $agreement = trim($args->agreement); + unset($args->agreement); + + $oModuleController = &getController('module'); + $output = $oModuleController->insertModuleConfig('member',$args); + if(!$output->toBool()) return $output; + + $agreement_file = _XE_PATH_.'files/member_extra_info/agreement.txt'; + FileHandler::writeFile($agreement_file, $agreement); + + return new Object(); + } + + /** + * @brief 서명을 파일로 저장 + **/ + function putSignature($member_srl, $signature) { + $signature = trim(removeHackTag($signature)); + $signature = preg_replace('/<(\/?)(embed|object|param)/is', '<$1$2', $signature); + + $check_signature = trim(str_replace(array(' ',"\n","\r"),'',strip_tags($signature,''))); + $path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($member_srl)); + $filename = sprintf('%s%d.signature.php', $path, $member_srl); + + if(!$check_signature) return FileHandler::removeFile($filename); + + $buff = sprintf('%s', $signature); + FileHandler::makeDir($path); + FileHandler::writeFile($filename, $buff); + } + + /** + * @brief 서명 파일 삭제 + **/ + function delSignature($member_srl) { + $filename = sprintf('files/member_extra_info/signature/%s%d.gif', getNumberingPath($member_srl), $member_srl); + FileHandler::removeFile($filename); + } + + /** + * @brief member_srl에 group_srl을 추가 + **/ + function addMemberToGroup($member_srl,$group_srl,$site_srl=0) { + $args->member_srl = $member_srl; + $args->group_srl = $group_srl; + if($site_srl) $args->site_srl = $site_srl; + + $oModel =& getModel('member'); + $groups = $oModel->getMemberGroups($member_srl, $site_srl, true); + if($groups[$group_srl]) return new Object(); + + // 추가 + $output = executeQuery('member.addMemberToGroup',$args); + $output2 = ModuleHandler::triggerCall('member.addMemberToGroup', 'after', $args); + + return $output; + } + + /** + * @brief 특정 회원들의 그룹을 일괄 변경 + * 가상 사이트와 같이 한 회원이 하나의 그룹만 가질 경우 사용할 수 있음 + **/ + function replaceMemberGroup($args) { + $obj->site_srl = $args->site_srl; + $obj->member_srl = implode(',',$args->member_srl); + + $output = executeQueryArray('member.getMembersGroup', $obj); + if($output->data) foreach($output->data as $key => $val) $date[$val->member_srl] = $val->regdate; + + $output = executeQuery('member.deleteMembersGroup', $obj); + if(!$output->toBool()) return $output; + + $inserted_members = array(); + foreach($args->member_srl as $key => $val) { + if($inserted_members[$val]) continue; + $inserted_members[$val] = true; + + unset($obj); + $obj->member_srl = $val; + $obj->group_srl = $args->group_srl; + $obj->site_srl = $args->site_srl; + $obj->regdate = $date[$obj->member_srl]; + $output = executeQuery('member.addMemberToGroup', $obj); + if(!$output->toBool()) return $output; + } + return new Object(); + } + + + /** + * @brief 자동 로그인 시킴 + **/ + function doAutologin() { + // 자동 로그인 키 값을 구함 + $args->autologin_key = $_COOKIE['xeak']; + + // 키값에 해당하는 정보 구함 + $output = executeQuery('member.getAutologin', $args); + + // 정보가 없으면 쿠키 삭제 + if(!$output->toBool() || !$output->data) { + setCookie('xeak',null,time()+60*60*24*365, '/'); + return; + } + + $user_id = $output->data->user_id; + $password = $output->data->password; + if(!$user_id || !$password) { + setCookie('xeak',null,time()+60*60*24*365, '/'); + return; + } + + // 정보를 바탕으로 키값 비교 + $key = md5($user_id.$password.$_SERVER['REMOTE_ADDR']); + + if($key == $args->autologin_key) { + $output = $this->doLogin($user_id); + } else { + executeQuery('member.deleteAutologin', $args); + setCookie('xeak',null,time()+60*60*24*365, '/'); + } + } + + /** + * @brief 로그인 시킴 + **/ + function doLogin($user_id, $password = '', $keep_signed = false) { + $user_id = strtolower($user_id); + + // 로그인 이전에 trigger 호출 (before) + $trigger_obj->user_id = $user_id; + $trigger_obj->password = $password; + $trigger_output = ModuleHandler::triggerCall('member.doLogin', 'before', $trigger_obj); + if(!$trigger_output->toBool()) return $trigger_output; + + // member model 객체 생성 + $oMemberModel = &getModel('member'); + + // user_id 에 따른 정보 가져옴 + $member_info = $oMemberModel->getMemberInfoByUserID($user_id); + + // return 값이 없으면 존재하지 않는 사용자로 지정 + if(!$user_id || strtolower($member_info->user_id) != strtolower($user_id)) return new Object(-1, 'invalid_user_id'); + + // 비밀번호 검사 + if($password && !$oMemberModel->isValidPassword($member_info->password, $password)) return new Object(-1, 'invalid_password'); + + // denied == 'Y' 이면 알림 + if($member_info->denied == 'Y') { + $args->member_srl = $member_info->member_srl; + $output = executeQuery('member.chkAuthMail', $args); + if ($output->toBool() && $output->data->count != '0') return new Object(-1,'msg_user_not_confirmed'); + return new Object(-1,'msg_user_denied'); + } + + // denied_date가 현 시간보다 적으면 알림 + if($member_info->limit_date && substr($member_info->limit_date,0,8) >= date("Ymd")) return new Object(-1,sprintf(Context::getLang('msg_user_limited'),zdate($member_info->limit_date,"Y-m-d"))); + + // 사용자 정보의 최근 로그인 시간을 기록 + $args->member_srl = $member_info->member_srl; + $output = executeQuery('member.updateLastLogin', $args); + + // 로그인 성공후 trigger 호출 (after) + $trigger_output = ModuleHandler::triggerCall('member.doLogin', 'after', $member_info); + if(!$trigger_output->toBool()) return $trigger_output; + + // 자동 로그인 사용시 정보 처리 + if($keep_signed) { + // 자동 로그인 키 생성 + $autologin_args->autologin_key = md5(strtolower($user_id).$member_info->password.$_SERVER['REMOTE_ADDR']); + $autologin_args->member_srl = $member_info->member_srl; + executeQuery('member.deleteAutologin', $autologin_args); + $autologin_output = executeQuery('member.insertAutologin', $autologin_args); + if($autologin_output->toBool()) setCookie('xeak',$autologin_args->autologin_key, time()+60*60*24*365, '/'); + } + + $this->setSessionInfo($member_info); + + return $output; + } + + /** + * @brief 세션 정보 갱싱 또는 생성 + **/ + function setSessionInfo($member_info = null) { + $oMemberModel = &getModel('member'); + + // 사용자 정보가 넘어오지 않았다면 현재 세션 정보에서 사용자 정보를 추출 + if(!$member_info && $_SESSION['member_srl'] && $oMemberModel->isLogged() ) { + $member_info = $oMemberModel->getMemberInfoByMemberSrl($_SESSION['member_srl']); + + // 회원정보가 없다면 세션 파기 + if($member_info->member_srl != $_SESSION['member_srl']) { + $this->destroySessionInfo(); + return; + } + } + + // 사용중지 아이디이면 세션 파기 + if($member_info->denied=='Y') { + $this->destroySessionInfo(); + return; + } + + // 오픈아이디인지 체크 (일단 아이디 형식으로만 결정) + if(preg_match("/^([_0-9a-zA-Z]+)$/is", $member_info->user_id)) $member_info->is_openid = false; + else $member_info->is_openid = true; + + // 로그인 처리를 위한 세션 설정 + $_SESSION['is_logged'] = true; + $_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR']; + $_SESSION['member_srl'] = $member_info->member_srl; + $_SESSION['is_admin'] = ''; + + // 비밀번호는 세션에 저장되지 않도록 지워줌;; + //unset($member_info->password); + + // 사용자 그룹 설정 + /* + if($member_info->group_list) { + $group_srl_list = array_keys($member_info->group_list); + $_SESSION['group_srls'] = $group_srl_list; + + // 관리자 그룹일 경우 관리자로 지정 + $oMemberModel = &getModel('member'); + $admin_group = $oMemberModel->getAdminGroup(); + if($admin_group->group_srl && in_array($admin_group->group_srl, $group_srl_list)) $_SESSION['is_admin'] = 'Y'; + } + */ + + // 세션에 로그인 사용자 정보 저장 + $_SESSION['logged_info'] = $member_info; + Context::set('is_logged', true); + Context::set('logged_info', $member_info); + + // 사용자의 전용 메뉴 구성 (이 메뉴는 애드온등으로 변경될 수 있음) + $this->addMemberMenu( 'dispMemberInfo', 'cmd_view_member_info'); + $this->addMemberMenu( 'dispMemberScrappedDocument', 'cmd_view_scrapped_document'); + $this->addMemberMenu( 'dispMemberSavedDocument', 'cmd_view_saved_document'); + $this->addMemberMenu( 'dispMemberOwnDocument', 'cmd_view_own_document'); + } + + /** + * @brief 로그인한 사용자의 개인화된 메뉴 제공을 위한 method + * 로그인 정보 출력 위젯 또는 개인화 페이지에서 사용됨 + **/ + function addMemberMenu($act, $str) { + $logged_info = Context::get('logged_info'); + + $logged_info->menu_list[$act] = Context::getLang($str); + + Context::set('logged_info', $logged_info); + $_SESSION['logged_info'] = $logged_info; + } + + /** + * @brief 로그인 회원의 닉네임등을 클릭할때 나타나는 팝업 메뉴를 추가하는 method + **/ + function addMemberPopupMenu($url, $str, $icon = '', $target = 'self') { + $member_popup_menu_list = Context::get('member_popup_menu_list'); + if(!is_array($member_popup_menu_list)) $member_popup_menu_list = array(); + + $obj->url = $url; + $obj->str = $str; + $obj->icon = $icon; + $obj->target = $target; + $member_popup_menu_list[] = $obj; + + Context::set('member_popup_menu_list', $member_popup_menu_list); + } + + /** + * @brief member 테이블에 사용자 추가 + **/ + function insertMember(&$args, $password_is_hashed = false) { + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('member.insertMember', 'before', $args); + if(!$output->toBool()) return $output; + + // 멤버 설정 정보에서 가입약관 부분을 재확인 + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + $logged_info = Context::get('logged_info'); + + // 임시 제한 일자가 있을 경우 제한 일자에 내용 추가 + if($config->limit_day) $args->limit_date = date("YmdHis", time()+$config->limit_day*60*60*24); + + // 입력할 사용자의 아이디를 소문자로 변경 + $args->user_id = strtolower($args->user_id); + + // 필수 변수들의 조절 + if($args->allow_mailing!='Y') $args->allow_mailing = 'N'; + if($args->denied!='Y') $args->denied = 'N'; + $args->allow_message= 'Y'; + + if($logged_info->is_admin == 'Y') { + if($args->is_admin!='Y') $args->is_admin = 'N'; + } else { + unset($args->is_admin); + } + + list($args->email_id, $args->email_host) = explode('@', $args->email_address); + + // 홈페이지, 블로그의 주소 검사 + if($args->homepage && !preg_match("/^[a-z]+:\/\//i",$args->homepage)) $args->homepage = 'http://'.$args->homepage; + if($args->blog && !preg_match("/^[a-z]+:\/\//i",$args->blog)) $args->blog = 'http://'.$args->blog; + + // 모델 객체 생성 + $oMemberModel = &getModel('member'); + // 금지 아이디인지 체크 + if($oMemberModel->isDeniedID($args->user_id)) return new Object(-1,'denied_user_id'); + + // 아이디, 닉네임, email address 의 중복 체크 + $member_srl = $oMemberModel->getMemberSrlByUserID($args->user_id); + if($member_srl) return new Object(-1,'msg_exists_user_id'); + + $member_srl = $oMemberModel->getMemberSrlByNickName($args->nick_name); + if($member_srl) return new Object(-1,'msg_exists_nick_name'); + + $member_srl = $oMemberModel->getMemberSrlByEmailAddress($args->email_address); + if($member_srl) return new Object(-1,'msg_exists_email_address'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + // DB에 입력 + $args->member_srl = getNextSequence(); + if($args->password && !$password_is_hashed) $args->password = md5($args->password); + elseif(!$args->password) unset($args->password); + + $output = executeQuery('member.insertMember', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 입력된 그룹 값이 없으면 기본 그룹의 값을 등록 + if(!$args->group_srl_list) { + $default_group = $oMemberModel->getDefaultGroup(0); + + // 기본 그룹에 추가 + $output = $this->addMemberToGroup($args->member_srl,$default_group->group_srl); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 입력된 그룹 값이 있으면 해당 그룹의 값을 등록 + } else { + $group_srl_list = explode('|@|', $args->group_srl_list); + for($i=0;$iaddMemberToGroup($args->member_srl,$group_srl_list[$i]); + + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + } + } + + // 메일 인증 모드 사용시(가입된 회원이 denied일 때) 인증 메일 발송 + if ($args->denied == 'Y') { + // 인증 DB에 데이터를 넣음 + $auth_args->user_id = $args->user_id; + $auth_args->member_srl = $args->member_srl; + $auth_args->new_password = $args->password; + $auth_args->auth_key = md5(rand(0, 999999)); + $auth_args->is_register = 'Y'; + + $output = executeQuery('member.insertAuthMail', $auth_args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 메일 내용을 구함 + Context::set('auth_args', $auth_args); + Context::set('member_info', $args); + + $member_config = $oModuleModel->getModuleConfig('member'); + if(!$member_config->skin) $this->member_config->skin = "default"; + if(!$member_config->colorset) $this->member_config->colorset = "white"; + + Context::set('member_config', $member_config); + + $tpl_path = sprintf('%sskins/%s', $this->module_path, $member_config->skin); + if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); + + $auth_url = getFullUrl('','module','member','act','procMemberAuthAccount','member_srl',$args->member_srl, 'auth_key',$auth_args->auth_key); + Context::set('auth_url', $auth_url); + + $oTemplate = &TemplateHandler::getInstance(); + $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); + + // 사이트 웹마스터 정보를 구함 + $oModuleModel = &getModel('module'); + $member_config = $oModuleModel->getModuleConfig('member'); + + // 메일 발송 + $oMail = new Mail(); + $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); + $oMail->setContent($content); + $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); + $oMail->setReceiptor( $args->user_name, $args->email_address ); + $oMail->send(); + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('member.insertMember', 'after', $args); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + $oDB->commit(true); + + $output->add('member_srl', $args->member_srl); + return $output; + } + + /** + * @brief member 정보 수정 + **/ + function updateMember($args) { + // trigger 호출 (before) + $output = ModuleHandler::triggerCall('member.updateMember', 'before', $args); + if(!$output->toBool()) return $output; + + // 모델 객체 생성 + $oMemberModel = &getModel('member'); + + $logged_info = Context::get('logged_info'); + + // 수정하려는 대상의 원래 정보 가져오기 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->member_srl); + if(!$args->user_id) $args->user_id = $member_info->user_id; + + // 필수 변수들의 조절 + if($args->allow_mailing!='Y') $args->allow_mailing = 'N'; + if($args->allow_message && !in_array($args->allow_message, array('Y','N','F'))) $args->allow_message = 'Y'; + + if($logged_info->is_admin == 'Y') { + if($args->denied!='Y') $args->denied = 'N'; + if($args->is_admin!='Y' && $logged_info->member_srl != $args->member_srl) $args->is_admin = 'N'; + } else { + unset($args->is_admin); + unset($args->denied); + } + + list($args->email_id, $args->email_host) = explode('@', $args->email_address); + + // 홈페이지, 블로그의 주소 검사 + if($args->homepage && !preg_match("/^[a-z]+:\/\//is",$args->homepage)) $args->homepage = 'http://'.$args->homepage; + if($args->blog && !preg_match("/^[a-z]+:\/\//is",$args->blog)) $args->blog = 'http://'.$args->blog; + + // 아이디, 닉네임, email address 의 중복 체크 + $member_srl = $oMemberModel->getMemberSrlByUserID($args->user_id); + if($member_srl&&$args->member_srl!=$member_srl) return new Object(-1,'msg_exists_user_id'); + + $member_srl = $oMemberModel->getMemberSrlByNickName($args->nick_name); + if($member_srl&&$args->member_srl!=$member_srl) return new Object(-1,'msg_exists_nick_name'); + + $member_srl = $oMemberModel->getMemberSrlByEmailAddress($args->email_address); + if($member_srl&&$args->member_srl!=$member_srl) return new Object(-1,'msg_exists_email_address'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + // DB에 update + if($args->password) $args->password = md5($args->password); + else $args->password = $member_info->password; + if(!$args->user_name) $args->user_name = $member_info->user_name; + + $output = executeQuery('member.updateMember', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 그룹 정보가 있으면 그룹 정보를 변경 + if($args->group_srl_list) { + $group_srl_list = explode('|@|', $args->group_srl_list); + $args->site_srl = 0; + + // 일단 해당 회원의 모든 그룹 정보를 삭제 + $output = executeQuery('member.deleteMemberGroupMember', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 하나 하나 루프를 돌면서 입력 + for($i=0;$iaddMemberToGroup($args->member_srl,$group_srl_list[$i]); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + } + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('member.updateMember', 'after', $args); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + $oDB->commit(); + + // 세션에 저장 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->member_srl); + + $logged_info = Context::get('logged_info'); + if($logged_info->member_srl == $member_srl) { + $_SESSION['logged_info'] = $member_info; + } + + $output->add('member_srl', $args->member_srl); + return $output; + } + + /** + * @brief member 비밀번호 수정 + **/ + function updateMemberPassword($args) { + $args->password = md5($args->password); + return executeQuery('member.updateMemberPassword', $args); + } + + /** + * @brief 사용자 삭제 + **/ + function deleteMember($member_srl) { + // trigger 호출 (before) + $trigger_obj->member_srl = $member_srl; + $output = ModuleHandler::triggerCall('member.deleteMember', 'before', $trigger_obj); + if(!$output->toBool()) return $output; + + // 모델 객체 생성 + $oMemberModel = &getModel('member'); + + // 해당 사용자의 정보를 가져옴 + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + if(!$member_info) return new Object(-1, 'msg_not_exists_member'); + + // 관리자의 경우 삭제 불가능 + if($member_info->is_admin == 'Y') return new Object(-1, 'msg_cannot_delete_admin'); + + $oDB = &DB::getInstance(); + $oDB->begin(); + + $args->member_srl = $member_srl; + // member_auth_mail에서 해당 항목들 삭제 + $output = executeQuery('member.deleteAuthMail', $args); + if (!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // member_openid에서 해당 항목들 삭제 + $output = executeQuery('member.deleteMemberOpenIDByMemberSrl', $ags); + + // TODO: 테이블 업그레이드를 하지 않은 경우에 실패할 수 있다. + /* + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + */ + + // member_group_member에서 해당 항목들 삭제 + $output = executeQuery('member.deleteMemberGroupMember', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // member 테이블에서 삭제 + $output = executeQuery('member.deleteMember', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('member.deleteMember', 'after', $trigger_obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + $oDB->commit(); + + // 이름이미지, 이미지마크, 서명 삭제 + $this->procMemberDeleteImageName(); + $this->procMemberDeleteImageMark(); + $this->delSignature($member_srl); + + return $output; + } + + /** + * @brief 모든 세션 정보 파기 + **/ + function destroySessionInfo() { + if(!$_SESSION || !is_array($_SESSION)) return; + foreach($_SESSION as $key => $val) { + $_SESSION[$key] = ''; + } + session_destroy(); + setcookie(session_name(), '', time()-42000, '/'); + setcookie('sso','',time()-42000, '/'); + + if($_COOKIE['xeak']) { + $args->autologin_key = $_COOKIE['xeak']; + executeQuery('member.deleteAutologin', $args); + } + } + } +?> diff --git a/modules/member/member.model.php b/modules/member/member.model.php index 5b27aedd2..c5670636c 100644 --- a/modules/member/member.model.php +++ b/modules/member/member.model.php @@ -1,716 +1,716 @@ -getModuleConfig('member'); - - // 회원가입 약관 구함 - $agreement_file = _XE_PATH_.'files/member_extra_info/agreement.txt'; - if(file_exists($agreement_file)) $config->agreement = FileHandler::readFile($agreement_file); - - if(!$config->webmaster_name) $config->webmaster_name = 'webmaster'; - if(!$config->image_name_max_width) $config->image_name_max_width = 90; - if(!$config->image_name_max_height) $config->image_name_max_height = 20; - if(!$config->image_mark_max_width) $config->image_mark_max_width = 20; - if(!$config->image_mark_max_height) $config->image_mark_max_height = 20; - if(!$config->profile_image_max_width) $config->profile_image_max_width = 80; - if(!$config->profile_image_max_height) $config->profile_image_max_height = 80; - if(!$config->skin) $config->skin = "default"; - if(!$config->editor_skin || $config->editor_skin == 'default') $config->editor_skin = "xpresseditor"; - if(!$config->group_image_mark) $config->group_image_mark = "N"; - - return $config; - } - - /** - * @brief 선택된 회원의 간단한 메뉴를 표시 - **/ - function getMemberMenu() { - // 요청된 회원 번호와 현재 사용자의 로그인 정보 구함 - $member_srl = Context::get('target_srl'); - $mid = Context::get('cur_mid'); - $logged_info = Context::get('logged_info'); - $act = Context::get('cur_act'); - - // 자신의 아이디를 클릭한 경우 - if($member_srl == $logged_info->member_srl) $member_info = $logged_info; - - // 다른 사람의 아이디를 클릭한 경우 - else $member_info = $this->getMemberInfoByMemberSrl($member_srl); - - $member_srl = $member_info->member_srl; - if(!$member_srl) return; - - // 변수 정리 - $user_id = $member_info->user_id; - $user_name = $member_info->user_name; - - ModuleHandler::triggerCall('member.getMemberMenu', 'before', $null); - - $oMemberController = &getController('member'); - - // 회원 정보 보기 (비회원일 경우 볼 수 없도록 수정) - if($logged_info->member_srl) { - $url = getUrl('','mid',$mid,'act','dispMemberInfo','member_srl',$member_srl); - $icon_path = './modules/member/tpl/images/icon_view_info.gif'; - $oMemberController->addMemberPopupMenu($url,'cmd_view_member_info',$icon_path,'self'); - } - - // 다른 사람의 아이디를 클릭한 경우 - if($member_srl != $logged_info->member_srl) { - - // 메일 보내기 - if($member_info->email_address) { - $url = 'mailto:'.htmlspecialchars($member_info->email_address); - $icon_path = './modules/member/tpl/images/icon_sendmail.gif'; - $oMemberController->addMemberPopupMenu($url,'cmd_send_email',$icon_path); - } - } - - // 홈페이지 보기 - if($member_info->homepage) - $oMemberController->addMemberPopupMenu(htmlspecialchars($member_info->homepage), 'homepage', './modules/member/tpl/images/icon_homepage.gif','blank'); - - // 블로그 보기 - if($member_info->blog) - $oMemberController->addMemberPopupMenu(htmlspecialchars($member_info->blog), 'blog', './modules/member/tpl/images/icon_blog.gif','blank'); - - // trigger 호출 (after) - ModuleHandler::triggerCall('member.getMemberMenu', 'after', $null); - - // 최고 관리자라면 회원정보 수정 메뉴 만듬 - if($logged_info->is_admin == 'Y') { - $url = getUrl('','module','admin','act','dispMemberAdminInsert','member_srl',$member_srl); - $icon_path = './modules/member/tpl/images/icon_management.gif'; - $oMemberController->addMemberPopupMenu($url,'cmd_manage_member_info',$icon_path,'MemberModifyInfo'); - - $url = getUrl('','module','admin','act','dispDocumentAdminList','search_target','member_srl','search_keyword',$member_srl); - $icon_path = './modules/member/tpl/images/icon_trace_document.gif'; - $oMemberController->addMemberPopupMenu($url,'cmd_trace_document',$icon_path,'TraceMemberDocument'); - - $url = getUrl('','module','admin','act','dispCommentAdminList','search_target','member_srl','search_keyword',$member_srl); - $icon_path = './modules/member/tpl/images/icon_trace_comment.gif'; - $oMemberController->addMemberPopupMenu($url,'cmd_trace_comment',$icon_path,'TraceMemberComment'); - } - - // 팝업메뉴의 언어 변경 - $menus = Context::get('member_popup_menu_list'); - $menus_count = count($menus); - for($i=0;$i<$menus_count;$i++) { - $menus[$i]->str = Context::getLang($menus[$i]->str); - } - - // 최종적으로 정리된 팝업메뉴 목록을 구함 - $this->add('menus', $menus); - } - - /** - * @brief 로그인 되어 있는지에 대한 체크 - **/ - function isLogged() { - if($_SESSION['is_logged']&&$_SESSION['ipaddress']==$_SERVER['REMOTE_ADDR']) return true; - - $_SESSION['is_logged'] = false; - $_SESSION['logged_info'] = ''; - return false; - } - - /** - * @brief 인증된 사용자의 정보 return - **/ - function getLoggedInfo() { - // 로그인 되어 있고 세션 정보를 요청하면 세션 정보를 return - if($this->isLogged()) { - $logged_info = $_SESSION['logged_info']; - - // site_module_info에 따라서 관리자/ 그룹 목록을 매번 재지정 - $site_module_info = Context::get('site_module_info'); - if($site_module_info->site_srl) { - $logged_info->group_list = $this->getMemberGroups($logged_info->member_srl, $site_module_info->site_srl); - - // 사이트 관리자이면 로그인 정보에 is_site_admin bool변수를 추가 - $oModuleModel = &getModel('module'); - if($oModuleModel->isSiteAdmin($logged_info)) $logged_info->is_site_admin = true; - else $logged_info->is_site_admin = false; - } else { - // 만약 기본 사이트인데 회원 그룹이 존재하지 않으면 등록 - if(!count($logged_info->group_list)) { - $default_group = $this->getDefaultGroup(0); - $oMemberController = &getController('member'); - $oMemberController->addMemberToGroup($logged_info->member_srl, $default_group->group_srl, 0); - $groups[$default_group->group_srl] = $default_group->title; - $logged_info->group_list = $groups; - } - - $logged_info->is_site_admin = false; - } - - $_SESSION['logged_info'] = $logged_info; - - return $logged_info; - } - return NULL; - } - - /** - * @brief user_id에 해당하는 사용자 정보 return - **/ - function getMemberInfoByUserID($user_id) { - if(!$user_id) return; - - $args->user_id = $user_id; - $output = executeQuery('member.getMemberInfo', $args); - if(!$output->toBool()) return $output; - if(!$output->data) return; - - $member_info = $this->arrangeMemberInfo($output->data); - - return $member_info; - } - - /** - * @brief member_srl로 사용자 정보 return - **/ - function getMemberInfoByMemberSrl($member_srl, $site_srl = 0) { - if(!$member_srl) return; - - if(!$GLOBALS['__member_info__'][$member_srl]) { - $args->member_srl = $member_srl; - $output = executeQuery('member.getMemberInfoByMemberSrl', $args); - if(!$output->data) return; - - $this->arrangeMemberInfo($output->data, $site_srl); - } - - return $GLOBALS['__member_info__'][$member_srl]; - } - - /** - * @brief 사용자 정보 중 extra_vars와 기타 정보를 알맞게 편집 - **/ - function arrangeMemberInfo($info, $site_srl = 0) { - if(!$GLOBALS['__member_info__'][$info->member_srl]) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - - $info->profile_image = $this->getProfileImage($info->member_srl); - $info->image_name = $this->getImageName($info->member_srl); - $info->image_mark = $this->getImageMark($info->member_srl); - if($config->group_image_mark=='Y'){ - $info->group_mark = $this->getGroupImageMark($info->member_srl,$site_srl); - } - $info->signature = $this->getSignature($info->member_srl); - $info->group_list = $this->getMemberGroups($info->member_srl, $site_srl); - - $extra_vars = unserialize($info->extra_vars); - unset($info->extra_vars); - if($extra_vars) { - foreach($extra_vars as $key => $val) { - if(preg_match('/\|\@\|/i', $val)) $val = explode('|@|', $val); - if(!$info->{$key}) $info->{$key} = $val; - } - } - - $GLOBALS['__member_info__'][$info->member_srl] = $info; - } - - return $GLOBALS['__member_info__'][$info->member_srl]; - } - - /** - * @brief userid에 해당하는 member_srl을 구함 - **/ - function getMemberSrlByUserID($user_id) { - $args->user_id = $user_id; - $output = executeQuery('member.getMemberSrl', $args); - return $output->data->member_srl; - } - - /** - * @brief EmailAddress에 해당하는 member_srl을 구함 - **/ - function getMemberSrlByEmailAddress($email_address) { - $args->email_address = $email_address; - $output = executeQuery('member.getMemberSrl', $args); - return $output->data->member_srl; - } - - /** - * @brief NickName에 해당하는 member_srl을 구함 - **/ - function getMemberSrlByNickName($nick_name) { - $args->nick_name = $nick_name; - $output = executeQuery('member.getMemberSrl', $args); - return $output->data->member_srl; - } - - /** - * @brief 현재 접속자의 member_srl을 return - **/ - function getLoggedMemberSrl() { - if(!$this->isLogged()) return; - return $_SESSION['member_srl']; - } - - /** - * @brief 현재 접속자의 user_id을 return - **/ - function getLoggedUserID() { - if(!$this->isLogged()) return; - $logged_info = $_SESSION['logged_info']; - return $logged_info->user_id; - } - - /** - * @brief member_srl이 속한 group 목록을 가져옴 - **/ - function getMemberGroups($member_srl, $site_srl = 0, $force_reload = false) { - static $member_groups = array(); - if(!$member_groups[$member_srl][$site_srl] || $force_reload) { - $args->member_srl = $member_srl; - $args->site_srl = $site_srl; - $output = executeQuery('member.getMemberGroups', $args); - if(!$output->data) return array(); - - $group_list = $output->data; - if(!is_array($group_list)) $group_list = array($group_list); - - foreach($group_list as $group) { - $result[$group->group_srl] = $group->title; - } - $member_groups[$member_srl][$site_srl] = $result; - } - return $member_groups[$member_srl][$site_srl]; - } - - /** - * @brief member_srl들이 속한 group 목록을 가져옴 - **/ - function getMembersGroups($member_srls, $site_srl = 0) { - $args->member_srls = implode(',',$member_srls); - $args->site_srl = $site_srl; - $output = executeQueryArray('member.getMembersGroups', $args); - if(!$output->data) return array(); - - $result = array(); - foreach($output->data as $key=>$val) { - $result[$val->member_srl][] = $val->title; - } - return $result; - } - - /** - * @brief 기본 그룹을 가져옴 - **/ - function getDefaultGroup($site_srl = 0) { - $args->site_srl = $site_srl; - $output = executeQuery('member.getDefaultGroup', $args); - return $output->data; - } - - /** - * @brief 관리자 그룹을 가져옴 - **/ - function getAdminGroup() { - $output = executeQuery('member.getAdminGroup'); - return $output->data; - } - - /** - * @brief group_srl에 해당하는 그룹 정보 가져옴 - **/ - function getGroup($group_srl) { - $args->group_srl = $group_srl; - $output = executeQuery('member.getGroup', $args); - return $output->data; - } - - /** - * @brief 그룹 목록을 가져옴 - **/ - function getGroups($site_srl = 0) { - if(!$GLOBALS['__group_info__'][$site_srl]) { - $args->site_srl = $site_srl; - $output = executeQuery('member.getGroups', $args); - if(!$output->data) return; - - $group_list = $output->data; - if(!is_array($group_list)) $group_list = array($group_list); - - foreach($group_list as $val) { - $result[$val->group_srl] = $val; - } - - $GLOBALS['__group_info__'][$site_srl] = $result; - } - return $GLOBALS['__group_info__'][$site_srl]; - } - - /** - * @brief 회원 가입폼 추가 확장 목록 가져오기 - * - * 이 메소드는 modules/member/tpl/filter/insert.xml 의 extend_filter로 동작을 한다. - * extend_filter로 사용을 하기 위해서는 인자값으로 boolean값을 받도록 규정한다. - * 이 인자값이 true일 경우 filter 타입에 맞는 형태의 object로 결과를 return하여야 한다. - **/ - function getJoinFormList($filter_response = false) { - global $lang; - - // 최고관리자는 무시하도록 설정 - $logged_info = Context::get('logged_info'); - - if(!$this->join_form_list) { - // list_order 컬럼의 정렬을 위한 인자 세팅 - $args->sort_index = "list_order"; - $output = executeQuery('member.getJoinFormList', $args); - - // 결과 데이터가 없으면 NULL return - $join_form_list = $output->data; - if(!$join_form_list) return NULL; - - // default_value의 경우 DB에 array가 serialize되어 입력되므로 unserialize가 필요 - if(!is_array($join_form_list)) $join_form_list = array($join_form_list); - $join_form_count = count($join_form_list); - for($i=0;$i<$join_form_count;$i++) { - $join_form_list[$i]->column_name = strtolower($join_form_list[$i]->column_name); - - $member_join_form_srl = $join_form_list[$i]->member_join_form_srl; - $column_type = $join_form_list[$i]->column_type; - $column_name = $join_form_list[$i]->column_name; - $column_title = $join_form_list[$i]->column_title; - $default_value = $join_form_list[$i]->default_value; - - // 언어변수에 추가 - $lang->extend_vars[$column_name] = $column_title; - - // checkbox, select등 다수 데이터 형식일 경우 unserialize해줌 - if(in_array($column_type, array('checkbox','select','radio'))) { - $join_form_list[$i]->default_value = unserialize($default_value); - if(!$join_form_list[$i]->default_value[0]) $join_form_list[$i]->default_value = ''; - } else { - $join_form_list[$i]->default_value = ''; - } - - $list[$member_join_form_srl] = $join_form_list[$i]; - } - $this->join_form_list = $list; - } - - // filter_response가 true일 경우 object 스타일을 구함 - if($filter_response && count($this->join_form_list)) { - - foreach($this->join_form_list as $key => $val) { - if($val->is_active != 'Y') continue; - unset($obj); - $obj->type = $val->column_type; - $obj->name = $val->column_name; - $obj->lang = $val->column_title; - if($logged_info->is_admin != 'Y') $obj->required = $val->required=='Y'?true:false; - else $obj->required = false; - $filter_output[] = $obj; - - unset($open_obj); - $open_obj->name = 'open_'.$val->column_name; - $open_obj->required = false; - $filter_output[] = $open_obj; - - } - return $filter_output; - - } - - // 결과 리턴 - return $this->join_form_list; - } - - /** - * @brief 추가 회원가입폼과 특정 회원의 정보를 조합 (회원정보 수정등에 사용) - **/ - function getCombineJoinForm($member_info) { - $extend_form_list = $this->getJoinFormlist(); - if(!$extend_form_list) return; - - // 관리자이거나 자기 자신이 아니면 비공개의 경우 무조건 패스해버림 - $logged_info = Context::get('logged_info'); - - foreach($extend_form_list as $srl => $item) { - $column_name = $item->column_name; - $value = $member_info->{$column_name}; - - if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_info->member_srl && $member_info->{'open_'.$column_name}!='Y') { - $extend_form_list[$srl]->is_private = true; - continue; - } - - // 추가 확장폼의 종류에 따라 값을 변경 - switch($item->column_type) { - case 'checkbox' : - if($value && !is_array($value)) $value = array($value); - break; - case 'text' : - case 'homepage' : - case 'email_address' : - case 'tel' : - case 'textarea' : - case 'select' : - case 'kr_zip' : - break; - } - - $extend_form_list[$srl]->value = $value; - - if($member_info->{'open_'.$column_name}=='Y') $extend_form_list[$srl]->is_opened = true; - else $extend_form_list[$srl]->is_opened = false; - } - return $extend_form_list; - } - - /** - * @brief 한개의 가입항목을 가져옴 - **/ - function getJoinForm($member_join_form_srl) { - $args->member_join_form_srl = $member_join_form_srl; - $output = executeQuery('member.getJoinForm', $args); - $join_form = $output->data; - if(!$join_form) return NULL; - - $column_type = $join_form->column_type; - $default_value = $join_form->default_value; - - if(in_array($column_type, array('checkbox','select','radio'))) { - $join_form->default_value = unserialize($default_value); - } else { - $join_form->default_value = ''; - } - - return $join_form; - } - - /** - * @brief 금지 아이디 목록 가져오기 - **/ - function getDeniedIDList() { - if(!$this->denied_id_list) { - $args->sort_index = "list_order"; - $args->page = Context::get('page'); - $args->list_count = 40; - $args->page_count = 10; - - $output = executeQuery('member.getDeniedIDList', $args); - $this->denied_id_list = $output; - } - return $this->denied_id_list; - } - - /** - * @brief 금지 아이디인지 확인 - **/ - function isDeniedID($user_id) { - $args->user_id = $user_id; - $output = executeQuery('member.chkDeniedID', $args); - if($output->data->count) return true; - return false; - } - - /** - * @brief 프로필 이미지의 정보를 구함 - **/ - function getProfileImage($member_srl) { - if(!isset($GLOBALS['__member_info__']['profile_image'][$member_srl])) { - $GLOBALS['__member_info__']['profile_image'][$member_srl] = null; - $exts = array('gif','jpg','png'); - for($i=0;$i<3;$i++) { - $image_name_file = sprintf('files/member_extra_info/profile_image/%s%d.%s', getNumberingPath($member_srl), $member_srl, $exts[$i]); - if(file_exists($image_name_file)) { - list($width, $height, $type, $attrs) = getimagesize($image_name_file); - $info = null; - $info->width = $width; - $info->height = $height; - $info->src = Context::getRequestUri().$image_name_file; - $info->file = './'.$image_name_file; - $GLOBALS['__member_info__']['profile_image'][$member_srl] = $info; - break; - } - } - } - - return $GLOBALS['__member_info__']['profile_image'][$member_srl]; - } - - /** - * @brief 이미지이름의 정보를 구함 - **/ - function getImageName($member_srl) { - if(!isset($GLOBALS['__member_info__']['image_name'][$member_srl])) { - $image_name_file = sprintf('files/member_extra_info/image_name/%s%d.gif', getNumberingPath($member_srl), $member_srl); - if(file_exists($image_name_file)) { - list($width, $height, $type, $attrs) = getimagesize($image_name_file); - $info->width = $width; - $info->height = $height; - $info->src = Context::getRequestUri().$image_name_file; - $info->file = './'.$image_name_file; - $GLOBALS['__member_info__']['image_name'][$member_srl] = $info; - } else $GLOBALS['__member_info__']['image_name'][$member_srl] = null; - } - return $GLOBALS['__member_info__']['image_name'][$member_srl]; - } - - /** - * @brief 이미지마크의 정보를 구함 - **/ - function getImageMark($member_srl) { - if(!isset($GLOBALS['__member_info__']['image_mark'][$member_srl])) { - $image_mark_file = sprintf('files/member_extra_info/image_mark/%s%d.gif', getNumberingPath($member_srl), $member_srl); - if(file_exists($image_mark_file)) { - list($width, $height, $type, $attrs) = getimagesize($image_mark_file); - $info->width = $width; - $info->height = $height; - $info->src = Context::getRequestUri().$image_mark_file; - $info->file = './'.$image_mark_file; - $GLOBALS['__member_info__']['image_mark'][$member_srl] = $info; - } else $GLOBALS['__member_info__']['image_mark'][$member_srl] = null; - } - - return $GLOBALS['__member_info__']['image_mark'][$member_srl]; - } - - - /** - * @brief group의 이미지마크 정보를 구함 - **/ - function getGroupImageMark($member_srl,$site_srl=0) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - if($config->group_image_mark!='Y'){ - return null; - } - $member_group = $this->getMemberGroups($member_srl,$site_srl); - - $groups_info = $this->getGroups($site_srl); - $image_mark = null; - if(count($member_group) > 0 && is_array($member_group)){ - $group_srl = array_keys($member_group); - $image_mark = $groups_info[$group_srl[0]]->image_mark; - } - if($image_mark){ -// list($width, $height, $type, $attrs) = getimagesize($image_mark); -// $info->width = $width; -// $info->height = $height; - $info->src = $image_mark; - return $info; - - }else return false; - } - - /** - * @brief 사용자의 signature를 구함 - **/ - function getSignature($member_srl) { - if(!isset($GLOBALS['__member_info__']['signature'][$member_srl])) { - $filename = sprintf('files/member_extra_info/signature/%s%d.signature.php', getNumberingPath($member_srl), $member_srl); - if(file_exists($filename)) { - $buff = FileHandler::readFile($filename); - $signature = trim(substr($buff, 40)); - $GLOBALS['__member_info__']['signature'][$member_srl] = $signature; - } else $GLOBALS['__member_info__']['signature'][$member_srl] = null; - } - return $GLOBALS['__member_info__']['signature'][$member_srl]; - } - - /** - * @brief 입력된 plain text 비밀번호와 DB에 저장된 비밀번호와의 비교 - **/ - function isValidPassword($hashed_password, $password_text) { - // 입력된 비밀번호가 없으면 무조건 falase - if(!$password_text) return false; - - // md5 해쉬된값가 맞으면 return true - if($hashed_password == md5($password_text)) return true; - - // mysql_pre4_hash_password함수의 값과 동일하면 return true - if(mysql_pre4_hash_password($password_text) == $hashed_password) return true; - - // 현재 DB에서 mysql DB를 이용시 직접 old_password를 이용하여 검사하고 맞으면 비밀번호를 변경 - if(substr(Context::getDBType(),0,5)=='mysql') { - $oDB = &DB::getInstance(); - if($oDB->isValidOldPassword($password_text, $hashed_password)) return true; - } - - return false; - } - - /** - * @brief 멤버와 연결된 오픈아이디들을 모두 리턴한다. - **/ - function getMemberOpenIDByMemberSrl($member_srl) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - $result = array(); - if ($config->enable_openid != 'Y') return $result; - - $args->member_srl = $member_srl; - $output = executeQuery('member.getMemberOpenIDByMemberSrl', $args); - - if (!$output->data) { - } - else if (is_array($output->data)) { - foreach($output->data as $row) { - $result[] = $row; - } - } - else { - $result[] = $output->data; - } - - foreach($result as $row) { - $openid = $row->openid; - $bookmarklet_header = "javascript:var%20U='"; - $bookmarklet_footer = "';function%20Z(W){var%20X=/(openid|ident)/i;try{var%20F=W.frames;var%20E=W.document.getElementsByTagName('input');for(var%20i=0;ibookmarklet = $bookmarklet_header . $openid . $bookmarklet_footer; - } - - return $result; - } - - /** - * @brief 오픈아이디에 연결된 멤버를 리턴한다. - **/ - function getMemberSrlByOpenID($openid) { - $oModuleModel = &getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); - - if ($config->enable_openid != 'Y') return $result; - - $args->member_srl = $member_srl; - $output = executeQuery('member.getMemberSrlByOpenID', $args); - - if (!$output->data) return null; - return $output->data->member_srl; - } - - } -?> +getModuleConfig('member'); + + // 회원가입 약관 구함 + $agreement_file = _XE_PATH_.'files/member_extra_info/agreement.txt'; + if(file_exists($agreement_file)) $config->agreement = FileHandler::readFile($agreement_file); + + if(!$config->webmaster_name) $config->webmaster_name = 'webmaster'; + if(!$config->image_name_max_width) $config->image_name_max_width = 90; + if(!$config->image_name_max_height) $config->image_name_max_height = 20; + if(!$config->image_mark_max_width) $config->image_mark_max_width = 20; + if(!$config->image_mark_max_height) $config->image_mark_max_height = 20; + if(!$config->profile_image_max_width) $config->profile_image_max_width = 80; + if(!$config->profile_image_max_height) $config->profile_image_max_height = 80; + if(!$config->skin) $config->skin = "default"; + if(!$config->editor_skin || $config->editor_skin == 'default') $config->editor_skin = "xpresseditor"; + if(!$config->group_image_mark) $config->group_image_mark = "N"; + + return $config; + } + + /** + * @brief 선택된 회원의 간단한 메뉴를 표시 + **/ + function getMemberMenu() { + // 요청된 회원 번호와 현재 사용자의 로그인 정보 구함 + $member_srl = Context::get('target_srl'); + $mid = Context::get('cur_mid'); + $logged_info = Context::get('logged_info'); + $act = Context::get('cur_act'); + + // 자신의 아이디를 클릭한 경우 + if($member_srl == $logged_info->member_srl) $member_info = $logged_info; + + // 다른 사람의 아이디를 클릭한 경우 + else $member_info = $this->getMemberInfoByMemberSrl($member_srl); + + $member_srl = $member_info->member_srl; + if(!$member_srl) return; + + // 변수 정리 + $user_id = $member_info->user_id; + $user_name = $member_info->user_name; + + ModuleHandler::triggerCall('member.getMemberMenu', 'before', $null); + + $oMemberController = &getController('member'); + + // 회원 정보 보기 (비회원일 경우 볼 수 없도록 수정) + if($logged_info->member_srl) { + $url = getUrl('','mid',$mid,'act','dispMemberInfo','member_srl',$member_srl); + $icon_path = './modules/member/tpl/images/icon_view_info.gif'; + $oMemberController->addMemberPopupMenu($url,'cmd_view_member_info',$icon_path,'self'); + } + + // 다른 사람의 아이디를 클릭한 경우 + if($member_srl != $logged_info->member_srl) { + + // 메일 보내기 + if($member_info->email_address) { + $url = 'mailto:'.htmlspecialchars($member_info->email_address); + $icon_path = './modules/member/tpl/images/icon_sendmail.gif'; + $oMemberController->addMemberPopupMenu($url,'cmd_send_email',$icon_path); + } + } + + // 홈페이지 보기 + if($member_info->homepage) + $oMemberController->addMemberPopupMenu(htmlspecialchars($member_info->homepage), 'homepage', './modules/member/tpl/images/icon_homepage.gif','blank'); + + // 블로그 보기 + if($member_info->blog) + $oMemberController->addMemberPopupMenu(htmlspecialchars($member_info->blog), 'blog', './modules/member/tpl/images/icon_blog.gif','blank'); + + // trigger 호출 (after) + ModuleHandler::triggerCall('member.getMemberMenu', 'after', $null); + + // 최고 관리자라면 회원정보 수정 메뉴 만듬 + if($logged_info->is_admin == 'Y') { + $url = getUrl('','module','admin','act','dispMemberAdminInsert','member_srl',$member_srl); + $icon_path = './modules/member/tpl/images/icon_management.gif'; + $oMemberController->addMemberPopupMenu($url,'cmd_manage_member_info',$icon_path,'MemberModifyInfo'); + + $url = getUrl('','module','admin','act','dispDocumentAdminList','search_target','member_srl','search_keyword',$member_srl); + $icon_path = './modules/member/tpl/images/icon_trace_document.gif'; + $oMemberController->addMemberPopupMenu($url,'cmd_trace_document',$icon_path,'TraceMemberDocument'); + + $url = getUrl('','module','admin','act','dispCommentAdminList','search_target','member_srl','search_keyword',$member_srl); + $icon_path = './modules/member/tpl/images/icon_trace_comment.gif'; + $oMemberController->addMemberPopupMenu($url,'cmd_trace_comment',$icon_path,'TraceMemberComment'); + } + + // 팝업메뉴의 언어 변경 + $menus = Context::get('member_popup_menu_list'); + $menus_count = count($menus); + for($i=0;$i<$menus_count;$i++) { + $menus[$i]->str = Context::getLang($menus[$i]->str); + } + + // 최종적으로 정리된 팝업메뉴 목록을 구함 + $this->add('menus', $menus); + } + + /** + * @brief 로그인 되어 있는지에 대한 체크 + **/ + function isLogged() { + if($_SESSION['is_logged']&&$_SESSION['ipaddress']==$_SERVER['REMOTE_ADDR']) return true; + + $_SESSION['is_logged'] = false; + $_SESSION['logged_info'] = ''; + return false; + } + + /** + * @brief 인증된 사용자의 정보 return + **/ + function getLoggedInfo() { + // 로그인 되어 있고 세션 정보를 요청하면 세션 정보를 return + if($this->isLogged()) { + $logged_info = $_SESSION['logged_info']; + + // site_module_info에 따라서 관리자/ 그룹 목록을 매번 재지정 + $site_module_info = Context::get('site_module_info'); + if($site_module_info->site_srl) { + $logged_info->group_list = $this->getMemberGroups($logged_info->member_srl, $site_module_info->site_srl); + + // 사이트 관리자이면 로그인 정보에 is_site_admin bool변수를 추가 + $oModuleModel = &getModel('module'); + if($oModuleModel->isSiteAdmin($logged_info)) $logged_info->is_site_admin = true; + else $logged_info->is_site_admin = false; + } else { + // 만약 기본 사이트인데 회원 그룹이 존재하지 않으면 등록 + if(!count($logged_info->group_list)) { + $default_group = $this->getDefaultGroup(0); + $oMemberController = &getController('member'); + $oMemberController->addMemberToGroup($logged_info->member_srl, $default_group->group_srl, 0); + $groups[$default_group->group_srl] = $default_group->title; + $logged_info->group_list = $groups; + } + + $logged_info->is_site_admin = false; + } + + $_SESSION['logged_info'] = $logged_info; + + return $logged_info; + } + return NULL; + } + + /** + * @brief user_id에 해당하는 사용자 정보 return + **/ + function getMemberInfoByUserID($user_id) { + if(!$user_id) return; + + $args->user_id = $user_id; + $output = executeQuery('member.getMemberInfo', $args); + if(!$output->toBool()) return $output; + if(!$output->data) return; + + $member_info = $this->arrangeMemberInfo($output->data); + + return $member_info; + } + + /** + * @brief member_srl로 사용자 정보 return + **/ + function getMemberInfoByMemberSrl($member_srl, $site_srl = 0) { + if(!$member_srl) return; + + if(!$GLOBALS['__member_info__'][$member_srl]) { + $args->member_srl = $member_srl; + $output = executeQuery('member.getMemberInfoByMemberSrl', $args); + if(!$output->data) return; + + $this->arrangeMemberInfo($output->data, $site_srl); + } + + return $GLOBALS['__member_info__'][$member_srl]; + } + + /** + * @brief 사용자 정보 중 extra_vars와 기타 정보를 알맞게 편집 + **/ + function arrangeMemberInfo($info, $site_srl = 0) { + if(!$GLOBALS['__member_info__'][$info->member_srl]) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + + $info->profile_image = $this->getProfileImage($info->member_srl); + $info->image_name = $this->getImageName($info->member_srl); + $info->image_mark = $this->getImageMark($info->member_srl); + if($config->group_image_mark=='Y'){ + $info->group_mark = $this->getGroupImageMark($info->member_srl,$site_srl); + } + $info->signature = $this->getSignature($info->member_srl); + $info->group_list = $this->getMemberGroups($info->member_srl, $site_srl); + + $extra_vars = unserialize($info->extra_vars); + unset($info->extra_vars); + if($extra_vars) { + foreach($extra_vars as $key => $val) { + if(preg_match('/\|\@\|/i', $val)) $val = explode('|@|', $val); + if(!$info->{$key}) $info->{$key} = $val; + } + } + + $GLOBALS['__member_info__'][$info->member_srl] = $info; + } + + return $GLOBALS['__member_info__'][$info->member_srl]; + } + + /** + * @brief userid에 해당하는 member_srl을 구함 + **/ + function getMemberSrlByUserID($user_id) { + $args->user_id = $user_id; + $output = executeQuery('member.getMemberSrl', $args); + return $output->data->member_srl; + } + + /** + * @brief EmailAddress에 해당하는 member_srl을 구함 + **/ + function getMemberSrlByEmailAddress($email_address) { + $args->email_address = $email_address; + $output = executeQuery('member.getMemberSrl', $args); + return $output->data->member_srl; + } + + /** + * @brief NickName에 해당하는 member_srl을 구함 + **/ + function getMemberSrlByNickName($nick_name) { + $args->nick_name = $nick_name; + $output = executeQuery('member.getMemberSrl', $args); + return $output->data->member_srl; + } + + /** + * @brief 현재 접속자의 member_srl을 return + **/ + function getLoggedMemberSrl() { + if(!$this->isLogged()) return; + return $_SESSION['member_srl']; + } + + /** + * @brief 현재 접속자의 user_id을 return + **/ + function getLoggedUserID() { + if(!$this->isLogged()) return; + $logged_info = $_SESSION['logged_info']; + return $logged_info->user_id; + } + + /** + * @brief member_srl이 속한 group 목록을 가져옴 + **/ + function getMemberGroups($member_srl, $site_srl = 0, $force_reload = false) { + static $member_groups = array(); + if(!$member_groups[$member_srl][$site_srl] || $force_reload) { + $args->member_srl = $member_srl; + $args->site_srl = $site_srl; + $output = executeQuery('member.getMemberGroups', $args); + if(!$output->data) return array(); + + $group_list = $output->data; + if(!is_array($group_list)) $group_list = array($group_list); + + foreach($group_list as $group) { + $result[$group->group_srl] = $group->title; + } + $member_groups[$member_srl][$site_srl] = $result; + } + return $member_groups[$member_srl][$site_srl]; + } + + /** + * @brief member_srl들이 속한 group 목록을 가져옴 + **/ + function getMembersGroups($member_srls, $site_srl = 0) { + $args->member_srls = implode(',',$member_srls); + $args->site_srl = $site_srl; + $output = executeQueryArray('member.getMembersGroups', $args); + if(!$output->data) return array(); + + $result = array(); + foreach($output->data as $key=>$val) { + $result[$val->member_srl][] = $val->title; + } + return $result; + } + + /** + * @brief 기본 그룹을 가져옴 + **/ + function getDefaultGroup($site_srl = 0) { + $args->site_srl = $site_srl; + $output = executeQuery('member.getDefaultGroup', $args); + return $output->data; + } + + /** + * @brief 관리자 그룹을 가져옴 + **/ + function getAdminGroup() { + $output = executeQuery('member.getAdminGroup'); + return $output->data; + } + + /** + * @brief group_srl에 해당하는 그룹 정보 가져옴 + **/ + function getGroup($group_srl) { + $args->group_srl = $group_srl; + $output = executeQuery('member.getGroup', $args); + return $output->data; + } + + /** + * @brief 그룹 목록을 가져옴 + **/ + function getGroups($site_srl = 0) { + if(!$GLOBALS['__group_info__'][$site_srl]) { + $args->site_srl = $site_srl; + $output = executeQuery('member.getGroups', $args); + if(!$output->data) return; + + $group_list = $output->data; + if(!is_array($group_list)) $group_list = array($group_list); + + foreach($group_list as $val) { + $result[$val->group_srl] = $val; + } + + $GLOBALS['__group_info__'][$site_srl] = $result; + } + return $GLOBALS['__group_info__'][$site_srl]; + } + + /** + * @brief 회원 가입폼 추가 확장 목록 가져오기 + * + * 이 메소드는 modules/member/tpl/filter/insert.xml 의 extend_filter로 동작을 한다. + * extend_filter로 사용을 하기 위해서는 인자값으로 boolean값을 받도록 규정한다. + * 이 인자값이 true일 경우 filter 타입에 맞는 형태의 object로 결과를 return하여야 한다. + **/ + function getJoinFormList($filter_response = false) { + global $lang; + + // 최고관리자는 무시하도록 설정 + $logged_info = Context::get('logged_info'); + + if(!$this->join_form_list) { + // list_order 컬럼의 정렬을 위한 인자 세팅 + $args->sort_index = "list_order"; + $output = executeQuery('member.getJoinFormList', $args); + + // 결과 데이터가 없으면 NULL return + $join_form_list = $output->data; + if(!$join_form_list) return NULL; + + // default_value의 경우 DB에 array가 serialize되어 입력되므로 unserialize가 필요 + if(!is_array($join_form_list)) $join_form_list = array($join_form_list); + $join_form_count = count($join_form_list); + for($i=0;$i<$join_form_count;$i++) { + $join_form_list[$i]->column_name = strtolower($join_form_list[$i]->column_name); + + $member_join_form_srl = $join_form_list[$i]->member_join_form_srl; + $column_type = $join_form_list[$i]->column_type; + $column_name = $join_form_list[$i]->column_name; + $column_title = $join_form_list[$i]->column_title; + $default_value = $join_form_list[$i]->default_value; + + // 언어변수에 추가 + $lang->extend_vars[$column_name] = $column_title; + + // checkbox, select등 다수 데이터 형식일 경우 unserialize해줌 + if(in_array($column_type, array('checkbox','select','radio'))) { + $join_form_list[$i]->default_value = unserialize($default_value); + if(!$join_form_list[$i]->default_value[0]) $join_form_list[$i]->default_value = ''; + } else { + $join_form_list[$i]->default_value = ''; + } + + $list[$member_join_form_srl] = $join_form_list[$i]; + } + $this->join_form_list = $list; + } + + // filter_response가 true일 경우 object 스타일을 구함 + if($filter_response && count($this->join_form_list)) { + + foreach($this->join_form_list as $key => $val) { + if($val->is_active != 'Y') continue; + unset($obj); + $obj->type = $val->column_type; + $obj->name = $val->column_name; + $obj->lang = $val->column_title; + if($logged_info->is_admin != 'Y') $obj->required = $val->required=='Y'?true:false; + else $obj->required = false; + $filter_output[] = $obj; + + unset($open_obj); + $open_obj->name = 'open_'.$val->column_name; + $open_obj->required = false; + $filter_output[] = $open_obj; + + } + return $filter_output; + + } + + // 결과 리턴 + return $this->join_form_list; + } + + /** + * @brief 추가 회원가입폼과 특정 회원의 정보를 조합 (회원정보 수정등에 사용) + **/ + function getCombineJoinForm($member_info) { + $extend_form_list = $this->getJoinFormlist(); + if(!$extend_form_list) return; + + // 관리자이거나 자기 자신이 아니면 비공개의 경우 무조건 패스해버림 + $logged_info = Context::get('logged_info'); + + foreach($extend_form_list as $srl => $item) { + $column_name = $item->column_name; + $value = $member_info->{$column_name}; + + if($logged_info->is_admin != 'Y' && $logged_info->member_srl != $member_info->member_srl && $member_info->{'open_'.$column_name}!='Y') { + $extend_form_list[$srl]->is_private = true; + continue; + } + + // 추가 확장폼의 종류에 따라 값을 변경 + switch($item->column_type) { + case 'checkbox' : + if($value && !is_array($value)) $value = array($value); + break; + case 'text' : + case 'homepage' : + case 'email_address' : + case 'tel' : + case 'textarea' : + case 'select' : + case 'kr_zip' : + break; + } + + $extend_form_list[$srl]->value = $value; + + if($member_info->{'open_'.$column_name}=='Y') $extend_form_list[$srl]->is_opened = true; + else $extend_form_list[$srl]->is_opened = false; + } + return $extend_form_list; + } + + /** + * @brief 한개의 가입항목을 가져옴 + **/ + function getJoinForm($member_join_form_srl) { + $args->member_join_form_srl = $member_join_form_srl; + $output = executeQuery('member.getJoinForm', $args); + $join_form = $output->data; + if(!$join_form) return NULL; + + $column_type = $join_form->column_type; + $default_value = $join_form->default_value; + + if(in_array($column_type, array('checkbox','select','radio'))) { + $join_form->default_value = unserialize($default_value); + } else { + $join_form->default_value = ''; + } + + return $join_form; + } + + /** + * @brief 금지 아이디 목록 가져오기 + **/ + function getDeniedIDList() { + if(!$this->denied_id_list) { + $args->sort_index = "list_order"; + $args->page = Context::get('page'); + $args->list_count = 40; + $args->page_count = 10; + + $output = executeQuery('member.getDeniedIDList', $args); + $this->denied_id_list = $output; + } + return $this->denied_id_list; + } + + /** + * @brief 금지 아이디인지 확인 + **/ + function isDeniedID($user_id) { + $args->user_id = $user_id; + $output = executeQuery('member.chkDeniedID', $args); + if($output->data->count) return true; + return false; + } + + /** + * @brief 프로필 이미지의 정보를 구함 + **/ + function getProfileImage($member_srl) { + if(!isset($GLOBALS['__member_info__']['profile_image'][$member_srl])) { + $GLOBALS['__member_info__']['profile_image'][$member_srl] = null; + $exts = array('gif','jpg','png'); + for($i=0;$i<3;$i++) { + $image_name_file = sprintf('files/member_extra_info/profile_image/%s%d.%s', getNumberingPath($member_srl), $member_srl, $exts[$i]); + if(file_exists($image_name_file)) { + list($width, $height, $type, $attrs) = getimagesize($image_name_file); + $info = null; + $info->width = $width; + $info->height = $height; + $info->src = Context::getRequestUri().$image_name_file; + $info->file = './'.$image_name_file; + $GLOBALS['__member_info__']['profile_image'][$member_srl] = $info; + break; + } + } + } + + return $GLOBALS['__member_info__']['profile_image'][$member_srl]; + } + + /** + * @brief 이미지이름의 정보를 구함 + **/ + function getImageName($member_srl) { + if(!isset($GLOBALS['__member_info__']['image_name'][$member_srl])) { + $image_name_file = sprintf('files/member_extra_info/image_name/%s%d.gif', getNumberingPath($member_srl), $member_srl); + if(file_exists($image_name_file)) { + list($width, $height, $type, $attrs) = getimagesize($image_name_file); + $info->width = $width; + $info->height = $height; + $info->src = Context::getRequestUri().$image_name_file; + $info->file = './'.$image_name_file; + $GLOBALS['__member_info__']['image_name'][$member_srl] = $info; + } else $GLOBALS['__member_info__']['image_name'][$member_srl] = null; + } + return $GLOBALS['__member_info__']['image_name'][$member_srl]; + } + + /** + * @brief 이미지마크의 정보를 구함 + **/ + function getImageMark($member_srl) { + if(!isset($GLOBALS['__member_info__']['image_mark'][$member_srl])) { + $image_mark_file = sprintf('files/member_extra_info/image_mark/%s%d.gif', getNumberingPath($member_srl), $member_srl); + if(file_exists($image_mark_file)) { + list($width, $height, $type, $attrs) = getimagesize($image_mark_file); + $info->width = $width; + $info->height = $height; + $info->src = Context::getRequestUri().$image_mark_file; + $info->file = './'.$image_mark_file; + $GLOBALS['__member_info__']['image_mark'][$member_srl] = $info; + } else $GLOBALS['__member_info__']['image_mark'][$member_srl] = null; + } + + return $GLOBALS['__member_info__']['image_mark'][$member_srl]; + } + + + /** + * @brief group의 이미지마크 정보를 구함 + **/ + function getGroupImageMark($member_srl,$site_srl=0) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + if($config->group_image_mark!='Y'){ + return null; + } + $member_group = $this->getMemberGroups($member_srl,$site_srl); + + $groups_info = $this->getGroups($site_srl); + $image_mark = null; + if(count($member_group) > 0 && is_array($member_group)){ + $group_srl = array_keys($member_group); + $image_mark = $groups_info[$group_srl[0]]->image_mark; + } + if($image_mark){ +// list($width, $height, $type, $attrs) = getimagesize($image_mark); +// $info->width = $width; +// $info->height = $height; + $info->src = $image_mark; + return $info; + + }else return false; + } + + /** + * @brief 사용자의 signature를 구함 + **/ + function getSignature($member_srl) { + if(!isset($GLOBALS['__member_info__']['signature'][$member_srl])) { + $filename = sprintf('files/member_extra_info/signature/%s%d.signature.php', getNumberingPath($member_srl), $member_srl); + if(file_exists($filename)) { + $buff = FileHandler::readFile($filename); + $signature = trim(substr($buff, 40)); + $GLOBALS['__member_info__']['signature'][$member_srl] = $signature; + } else $GLOBALS['__member_info__']['signature'][$member_srl] = null; + } + return $GLOBALS['__member_info__']['signature'][$member_srl]; + } + + /** + * @brief 입력된 plain text 비밀번호와 DB에 저장된 비밀번호와의 비교 + **/ + function isValidPassword($hashed_password, $password_text) { + // 입력된 비밀번호가 없으면 무조건 falase + if(!$password_text) return false; + + // md5 해쉬된값가 맞으면 return true + if($hashed_password == md5($password_text)) return true; + + // mysql_pre4_hash_password함수의 값과 동일하면 return true + if(mysql_pre4_hash_password($password_text) == $hashed_password) return true; + + // 현재 DB에서 mysql DB를 이용시 직접 old_password를 이용하여 검사하고 맞으면 비밀번호를 변경 + if(substr(Context::getDBType(),0,5)=='mysql') { + $oDB = &DB::getInstance(); + if($oDB->isValidOldPassword($password_text, $hashed_password)) return true; + } + + return false; + } + + /** + * @brief 멤버와 연결된 오픈아이디들을 모두 리턴한다. + **/ + function getMemberOpenIDByMemberSrl($member_srl) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + $result = array(); + if ($config->enable_openid != 'Y') return $result; + + $args->member_srl = $member_srl; + $output = executeQuery('member.getMemberOpenIDByMemberSrl', $args); + + if (!$output->data) { + } + else if (is_array($output->data)) { + foreach($output->data as $row) { + $result[] = $row; + } + } + else { + $result[] = $output->data; + } + + foreach($result as $row) { + $openid = $row->openid; + $bookmarklet_header = "javascript:var%20U='"; + $bookmarklet_footer = "';function%20Z(W){var%20X=/(openid|ident)/i;try{var%20F=W.frames;var%20E=W.document.getElementsByTagName('input');for(var%20i=0;ibookmarklet = $bookmarklet_header . $openid . $bookmarklet_footer; + } + + return $result; + } + + /** + * @brief 오픈아이디에 연결된 멤버를 리턴한다. + **/ + function getMemberSrlByOpenID($openid) { + $oModuleModel = &getModel('module'); + $config = $oModuleModel->getModuleConfig('member'); + + if ($config->enable_openid != 'Y') return $result; + + $args->member_srl = $member_srl; + $output = executeQuery('member.getMemberSrlByOpenID', $args); + + if (!$output->data) return null; + return $output->data->member_srl; + } + + } +?> diff --git a/modules/member/member.view.php b/modules/member/member.view.php index a89fa19c1..84e498cad 100644 --- a/modules/member/member.view.php +++ b/modules/member/member.view.php @@ -1,340 +1,340 @@ -member_config = $oModuleModel->getModuleConfig('member'); - if(!$this->member_config->skin) $this->member_config->skin = "default"; - if(!$this->member_config->colorset) $this->member_config->colorset = "white"; - - Context::set('member_config', $this->member_config); - $skin = $this->member_config->skin; - - // template path 지정 - $tpl_path = sprintf('%sskins/%s', $this->module_path, $skin); - if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); - $this->setTemplatePath($tpl_path); - } - - /** - * @brief 회원 정보 출력 - **/ - function dispMemberInfo() { - $oMemberModel = &getModel('member'); - $logged_info = Context::get('logged_info'); - - // 비회원일 경우 정보 열람 중지 - if(!$logged_info->member_srl) return $this->stop('msg_not_permitted'); - - $member_srl = Context::get('member_srl'); - if(!$member_srl && Context::get('is_logged')) { - $member_srl = $logged_info->member_srl; - } elseif(!$member_srl) { - return $this->dispMemberSignUpForm(); - } - - $site_module_info = Context::get('site_module_info'); - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl, $site_module_info->site_srl); - unset($member_info->password); - unset($member_info->email_id); - unset($member_info->email_host); - unset($member_info->email_address); - - if(!$member_info->member_srl) return $this->dispMemberSignUpForm(); - - Context::set('member_info', $member_info); - Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($member_info)); - if ($member_info->member_srl == $logged_info->member_srl) - Context::set('openids', $oMemberModel->getMemberOpenIDByMemberSrl($member_srl)); - - $this->setTemplateFile('member_info'); - } - - /** - * @brief 회원 가입 폼 출력 - **/ - function dispMemberSignUpForm() { - $oMemberModel = &getModel('member'); - - // 로그인한 회원일 경우 해당 회원의 정보를 받음 - if($oMemberModel->isLogged()) return $this->stop('msg_already_logged'); - - // before 트리거 호출 - $trigger_output = ModuleHandler::triggerCall('member.dispMemberSignUpForm', 'before', $this->member_config); - if(!$trigger_output->toBool()) return $trigger_output; - - // 회원가입을 중지시켰을 때는 에러 표시 - if($this->member_config->enable_join != 'Y') return $this->stop('msg_signup_disabled'); - Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($member_info)); - - $member_config = $oMemberModel->getMemberConfig(); - Context::set('member_config', $member_config); - - // 템플릿 파일 지정 - $this->setTemplateFile('signup_form'); - } - - /** - * @brief 회원 정보 수정 - **/ - function dispMemberModifyInfo() { - $oMemberModel = &getModel('member'); - $oModuleModel = &getModel('module'); - $memberModuleConfig = $oModuleModel->getModuleConfig('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - $member_info->signature = $oMemberModel->getSignature($member_srl); - Context::set('member_info',$member_info); - - // 추가 가입폼 목록을 받음 - Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($member_info)); - - Context::set('openids', $oMemberModel->getMemberOpenIDByMemberSrl($member_srl)); - - // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 - if($member_info->member_srl) { - $oEditorModel = &getModel('editor'); - $option->primary_key_name = 'member_srl'; - $option->content_key_name = 'signature'; - $option->allow_fileupload = false; - $option->enable_autosave = false; - $option->enable_default_component = true; - $option->enable_component = false; - $option->resizable = false; - $option->disable_html = true; - $option->height = 200; - $option->skin = $this->member_config->editor_skin; - $option->colorset = $this->member_config->editor_colorset; - $editor = $oEditorModel->getEditor($member_info->member_srl, $option); - Context::set('editor', $editor); - } - - // 템플릿 파일 지정 - $this->setTemplateFile('modify_info'); - } - - - /** - * @brief 회원 작성글 보기 - **/ - function dispMemberOwnDocument() { - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - $module_srl = Context::get('module_srl'); - Context::set('module_srl',Context::get('selected_module_srl')); - Context::set('search_target','member_srl'); - Context::set('search_keyword',$member_srl); - - $oDocumentAdminView = &getAdminView('document'); - $oDocumentAdminView->dispDocumentAdminList(); - - Context::set('module_srl', $module_srl); - $this->setTemplateFile('document_list'); - } - - /** - * @brief 회원 스크랩 게시물 보기 - **/ - function dispMemberScrappedDocument() { - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - $logged_info = Context::get('logged_info'); - $args->member_srl = $logged_info->member_srl; - $args->page = (int)Context::get('page'); - - $output = executeQuery('member.getScrapDocumentList', $args); - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('document_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('scrapped_list'); - } - - /** - * @brief 회원의 저장함 보기 - **/ - function dispMemberSavedDocument() { - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - // 저장함에 보관된 글을 가져옴 (저장함은 module_srl이 member_srl로 세팅되어 있음) - $logged_info = Context::get('logged_info'); - $args->module_srl = $logged_info->member_srl; - $args->page = (int)Context::get('page'); - - $oDocumentModel = &getModel('document'); - $output = $oDocumentModel->getDocumentList($args, true); - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('document_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('saved_list'); - } - - /** - * @brief 로그인 폼 출력 - **/ - function dispMemberLoginForm() { - if(Context::get('is_logged')) { - Context::set('redirect_url', getUrl('act','')); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('redirect.html'); - return; - } - - // 템플릿 파일 지정 - Context::set('referer_url', $_SERVER['HTTP_REFERER']); - $this->setTemplateFile('login_form'); - } - - /** - * @brief 회원 비밀번호 수정 - **/ - function dispMemberModifyPassword() { - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - Context::set('member_info',$member_info); - - // 템플릿 파일 지정 - $this->setTemplateFile('modify_password'); - } - - /** - * @brief 탈퇴 화면 - **/ - function dispMemberLeave() { - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - Context::set('member_info',$member_info); - - // 템플릿 파일 지정 - $this->setTemplateFile('leave_form'); - } - - /** - * @brief 오픈 아이디 탈퇴 화면 - **/ - function dispMemberOpenIDLeave() { - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - $logged_info = Context::get('logged_info'); - $member_srl = $logged_info->member_srl; - - $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - Context::set('member_info',$member_info); - - // 템플릿 파일 지정 - $this->setTemplateFile('openid_leave_form'); - } - - /** - * @brief 로그아웃 출력 - **/ - function dispMemberLogout() { - $oMemberController = &getController('member'); - $oMemberController->procMemberLogout(); - - Context::set('layout','none'); - $this->setTemplatePath($this->module_path.'/tpl'); - $this->setTemplateFile('logout'); - } - - /** - * @brief 저장된 글 목록을 보여줌 - **/ - function dispSavedDocumentList() { - $this->setLayoutFile('popup_layout'); - - $oMemberModel = &getModel('member'); - - // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 - if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); - - // 저장함에 보관된 글을 가져옴 (저장함은 module_srl이 member_srl로 세팅되어 있음) - $logged_info = Context::get('logged_info'); - $args->module_srl = $logged_info->member_srl; - $args->page = (int)Context::get('page'); - $args->list_count = 10; - - $oDocumentModel = &getModel('document'); - $output = $oDocumentModel->getDocumentList($args, true); - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('document_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('saved_list_popup'); - } - - /** - * @brief 아이디/ 비밀번호 찾기 기능 - **/ - function dispMemberFindAccount() { - if(Context::get('is_logged')) return $this->stop('already_logged'); - - $this->setTemplateFile('find_member_account'); - } - - /** - * @brief 인증 메일 재발송 페이지 - **/ - function dispMemberResendAuthMail() { - if(Context::get('is_logged')) return $this->stop('already_logged'); - - $this->setTemplateFile('resend_auth_mail'); - } - } -?> +member_config = $oModuleModel->getModuleConfig('member'); + if(!$this->member_config->skin) $this->member_config->skin = "default"; + if(!$this->member_config->colorset) $this->member_config->colorset = "white"; + + Context::set('member_config', $this->member_config); + $skin = $this->member_config->skin; + + // template path 지정 + $tpl_path = sprintf('%sskins/%s', $this->module_path, $skin); + if(!is_dir($tpl_path)) $tpl_path = sprintf('%sskins/%s', $this->module_path, 'default'); + $this->setTemplatePath($tpl_path); + } + + /** + * @brief 회원 정보 출력 + **/ + function dispMemberInfo() { + $oMemberModel = &getModel('member'); + $logged_info = Context::get('logged_info'); + + // 비회원일 경우 정보 열람 중지 + if(!$logged_info->member_srl) return $this->stop('msg_not_permitted'); + + $member_srl = Context::get('member_srl'); + if(!$member_srl && Context::get('is_logged')) { + $member_srl = $logged_info->member_srl; + } elseif(!$member_srl) { + return $this->dispMemberSignUpForm(); + } + + $site_module_info = Context::get('site_module_info'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl, $site_module_info->site_srl); + unset($member_info->password); + unset($member_info->email_id); + unset($member_info->email_host); + unset($member_info->email_address); + + if(!$member_info->member_srl) return $this->dispMemberSignUpForm(); + + Context::set('member_info', $member_info); + Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($member_info)); + if ($member_info->member_srl == $logged_info->member_srl) + Context::set('openids', $oMemberModel->getMemberOpenIDByMemberSrl($member_srl)); + + $this->setTemplateFile('member_info'); + } + + /** + * @brief 회원 가입 폼 출력 + **/ + function dispMemberSignUpForm() { + $oMemberModel = &getModel('member'); + + // 로그인한 회원일 경우 해당 회원의 정보를 받음 + if($oMemberModel->isLogged()) return $this->stop('msg_already_logged'); + + // before 트리거 호출 + $trigger_output = ModuleHandler::triggerCall('member.dispMemberSignUpForm', 'before', $this->member_config); + if(!$trigger_output->toBool()) return $trigger_output; + + // 회원가입을 중지시켰을 때는 에러 표시 + if($this->member_config->enable_join != 'Y') return $this->stop('msg_signup_disabled'); + Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($member_info)); + + $member_config = $oMemberModel->getMemberConfig(); + Context::set('member_config', $member_config); + + // 템플릿 파일 지정 + $this->setTemplateFile('signup_form'); + } + + /** + * @brief 회원 정보 수정 + **/ + function dispMemberModifyInfo() { + $oMemberModel = &getModel('member'); + $oModuleModel = &getModel('module'); + $memberModuleConfig = $oModuleModel->getModuleConfig('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + $member_info->signature = $oMemberModel->getSignature($member_srl); + Context::set('member_info',$member_info); + + // 추가 가입폼 목록을 받음 + Context::set('extend_form_list', $oMemberModel->getCombineJoinForm($member_info)); + + Context::set('openids', $oMemberModel->getMemberOpenIDByMemberSrl($member_srl)); + + // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 + if($member_info->member_srl) { + $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'member_srl'; + $option->content_key_name = 'signature'; + $option->allow_fileupload = false; + $option->enable_autosave = false; + $option->enable_default_component = true; + $option->enable_component = false; + $option->resizable = false; + $option->disable_html = true; + $option->height = 200; + $option->skin = $this->member_config->editor_skin; + $option->colorset = $this->member_config->editor_colorset; + $editor = $oEditorModel->getEditor($member_info->member_srl, $option); + Context::set('editor', $editor); + } + + // 템플릿 파일 지정 + $this->setTemplateFile('modify_info'); + } + + + /** + * @brief 회원 작성글 보기 + **/ + function dispMemberOwnDocument() { + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + $module_srl = Context::get('module_srl'); + Context::set('module_srl',Context::get('selected_module_srl')); + Context::set('search_target','member_srl'); + Context::set('search_keyword',$member_srl); + + $oDocumentAdminView = &getAdminView('document'); + $oDocumentAdminView->dispDocumentAdminList(); + + Context::set('module_srl', $module_srl); + $this->setTemplateFile('document_list'); + } + + /** + * @brief 회원 스크랩 게시물 보기 + **/ + function dispMemberScrappedDocument() { + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + $args->page = (int)Context::get('page'); + + $output = executeQuery('member.getScrapDocumentList', $args); + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('document_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('scrapped_list'); + } + + /** + * @brief 회원의 저장함 보기 + **/ + function dispMemberSavedDocument() { + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + // 저장함에 보관된 글을 가져옴 (저장함은 module_srl이 member_srl로 세팅되어 있음) + $logged_info = Context::get('logged_info'); + $args->module_srl = $logged_info->member_srl; + $args->page = (int)Context::get('page'); + + $oDocumentModel = &getModel('document'); + $output = $oDocumentModel->getDocumentList($args, true); + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('document_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('saved_list'); + } + + /** + * @brief 로그인 폼 출력 + **/ + function dispMemberLoginForm() { + if(Context::get('is_logged')) { + Context::set('redirect_url', getUrl('act','')); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('redirect.html'); + return; + } + + // 템플릿 파일 지정 + Context::set('referer_url', $_SERVER['HTTP_REFERER']); + $this->setTemplateFile('login_form'); + } + + /** + * @brief 회원 비밀번호 수정 + **/ + function dispMemberModifyPassword() { + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + Context::set('member_info',$member_info); + + // 템플릿 파일 지정 + $this->setTemplateFile('modify_password'); + } + + /** + * @brief 탈퇴 화면 + **/ + function dispMemberLeave() { + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + Context::set('member_info',$member_info); + + // 템플릿 파일 지정 + $this->setTemplateFile('leave_form'); + } + + /** + * @brief 오픈 아이디 탈퇴 화면 + **/ + function dispMemberOpenIDLeave() { + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + Context::set('member_info',$member_info); + + // 템플릿 파일 지정 + $this->setTemplateFile('openid_leave_form'); + } + + /** + * @brief 로그아웃 출력 + **/ + function dispMemberLogout() { + $oMemberController = &getController('member'); + $oMemberController->procMemberLogout(); + + Context::set('layout','none'); + $this->setTemplatePath($this->module_path.'/tpl'); + $this->setTemplateFile('logout'); + } + + /** + * @brief 저장된 글 목록을 보여줌 + **/ + function dispSavedDocumentList() { + $this->setLayoutFile('popup_layout'); + + $oMemberModel = &getModel('member'); + + // 로그인 되어 있지 않을 경우 로그인 되어 있지 않다는 메세지 출력 + if(!$oMemberModel->isLogged()) return $this->stop('msg_not_logged'); + + // 저장함에 보관된 글을 가져옴 (저장함은 module_srl이 member_srl로 세팅되어 있음) + $logged_info = Context::get('logged_info'); + $args->module_srl = $logged_info->member_srl; + $args->page = (int)Context::get('page'); + $args->list_count = 10; + + $oDocumentModel = &getModel('document'); + $output = $oDocumentModel->getDocumentList($args, true); + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('document_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('saved_list_popup'); + } + + /** + * @brief 아이디/ 비밀번호 찾기 기능 + **/ + function dispMemberFindAccount() { + if(Context::get('is_logged')) return $this->stop('already_logged'); + + $this->setTemplateFile('find_member_account'); + } + + /** + * @brief 인증 메일 재발송 페이지 + **/ + function dispMemberResendAuthMail() { + if(Context::get('is_logged')) return $this->stop('already_logged'); + + $this->setTemplateFile('resend_auth_mail'); + } + } +?> diff --git a/modules/member/skins/default/skin.xml b/modules/member/skins/default/skin.xml index a29e0fbbc..5e419e760 100644 --- a/modules/member/skins/default/skin.xml +++ b/modules/member/skins/default/skin.xml @@ -1,77 +1,69 @@ - - - 회원 기본 스킨 - 会员模块默认皮肤 - 会員デフォルトスキン - Default Member Skin - Giao diện thành viên mặc định - Por defecto miembro piel - По умолчанию членом кожи - 會員模組預設面板 - - 회원모듈의 default스킨 - 디자인 : 서기정 (http://blog.naver.com/addcozy) - HTML/CSS : 정찬명 (http://naradesign.net) - - - 会员模块的默认皮肤。 - 设计 : Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - - 会員モジュールのデフォルトスキン - デザイン:ソギジョン (http://blog.naver.com/addcozy) - HTML/CSS:ジョンチャンミョン (http://naradesign.net) - - - default skin of member module - Design : Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - - Giao diện mặc định của Module Thành viên - Thiết kế: Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - - Por defecto de la piel miembro módulo - Diseño: Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML / CSS: Jeong Chan-Myung (http://naradesign.net) - - - умолчанию кожу члена модуль - Дизайн: Ги Чен Се (http://blog.naver.com/addcozy) - HTML / CSS: Чен-Чен Мен (http://naradesign.net) - - - 會員模組預設面板。 - 設計 : Ki-Jeong Seo (http://blog.naver.com/addcozy) - HTML/CSS : Chan-Myung Jeong (http://naradesign.net) - - 0.1 - 2007-02-28 - - - (주)NHN - (株)NHN - (株)NHN - NHN Corp - NHN Corp - NHN Corp - NHN Корп - NHN Corp - - - - - 기본 - 默认 - デフォルト - default - Mặc định - Por defecto - умолчанию - 預設 - - - + + + 회원 기본 스킨 + 会员模块默认皮肤 + 会員デフォルトスキン + Default Member Skin + Giao diện thành viên mặc định + Por defecto miembro piel + По умолчанию членом кожи + 會員模組預設面板 + + 회원모듈의 default스킨 + NHN (developers@xpressengine.com) + + + 会员模块的默认皮肤。 + NHN (developers@xpressengine.com) + + + 会員モジュールのデフォルトスキン + NHN (developers@xpressengine.com) + + + default skin of member module + NHN (developers@xpressengine.com) + + + Giao diện mặc định của Module Thành viên + NHN (developers@xpressengine.com) + + + Por defecto de la piel miembro módulo + NHN (developers@xpressengine.com) + + + умолчанию кожу члена модуль + NHN (developers@xpressengine.com) + + + 會員模組預設面板。 + NHN (developers@xpressengine.com) + + 0.1 + 2007-02-28 + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + + + + 기본 + 默认 + デフォルト + default + Mặc định + Por defecto + умолчанию + 預設 + + + diff --git a/modules/member/tpl/js/signup_check.js b/modules/member/tpl/js/signup_check.js index 0193ab489..78dac67f7 100644 --- a/modules/member/tpl/js/signup_check.js +++ b/modules/member/tpl/js/signup_check.js @@ -1,52 +1,52 @@ -/** - * @brief 회원 가입시나 정보 수정시 각 항목의 중복 검사등을 하는 기능을 구현 - * @author zero - **/ - -// 입력이 시작된 것과 입력후 정해진 시간동안 내용이 변하였을 경우 서버에 ajax로 체크를 하기 위한 변수 설정 -var memberCheckObj = { target:null, value:null } - -// domready시에 특정 필드들에 대해 이벤트를 걸어 놓음 -jQuery(document).ready(memberSetEvent); - -function memberSetEvent() { - jQuery('#fo_insert_member :input') - .filter('[name=user_id],[name=nick_name],[name=email_address]') - .blur(memberCheckValue); -} - - -// 실제 서버에 특정 필드의 value check를 요청하고 이상이 있으면 메세지를 뿌려주는 함수 -function memberCheckValue(event) { - var field = event.target; - var _name = field.name; - var _value = field.value; - if(!_name || !_value) return; - - var params = {name:_name, value:_value}; - var response_tags = ['error','message']; - - exec_xml('member','procMemberCheckValue', params, completeMemberCheckValue, response_tags, field); -} - -// 서버에서 응답이 올 경우 이상이 있으면 메세지를 출력 -function completeMemberCheckValue(ret_obj, response_tags, field) { - var _id = 'dummy_check'+field.name; - var dummy = jQuery('#'+_id); - - if(ret_obj['message']=='success') { - dummy.html('').hide(); - return; - } - - if (!dummy.length) { - dummy = jQuery('
').attr('id', _id).appendTo(field.parentNode); - } - - dummy.html(ret_obj['message']).show(); -} - -// 결과 메세지를 정리하는 함수 -function removeMemberCheckValueOutput(dummy, obj) { - dummy.style.display = "none"; -} +/** + * @brief 회원 가입시나 정보 수정시 각 항목의 중복 검사등을 하는 기능을 구현 + * @author NHN (developer@xpressengine.com) + **/ + +// 입력이 시작된 것과 입력후 정해진 시간동안 내용이 변하였을 경우 서버에 ajax로 체크를 하기 위한 변수 설정 +var memberCheckObj = { target:null, value:null } + +// domready시에 특정 필드들에 대해 이벤트를 걸어 놓음 +jQuery(document).ready(memberSetEvent); + +function memberSetEvent() { + jQuery('#fo_insert_member :input') + .filter('[name=user_id],[name=nick_name],[name=email_address]') + .blur(memberCheckValue); +} + + +// 실제 서버에 특정 필드의 value check를 요청하고 이상이 있으면 메세지를 뿌려주는 함수 +function memberCheckValue(event) { + var field = event.target; + var _name = field.name; + var _value = field.value; + if(!_name || !_value) return; + + var params = {name:_name, value:_value}; + var response_tags = ['error','message']; + + exec_xml('member','procMemberCheckValue', params, completeMemberCheckValue, response_tags, field); +} + +// 서버에서 응답이 올 경우 이상이 있으면 메세지를 출력 +function completeMemberCheckValue(ret_obj, response_tags, field) { + var _id = 'dummy_check'+field.name; + var dummy = jQuery('#'+_id); + + if(ret_obj['message']=='success') { + dummy.html('').hide(); + return; + } + + if (!dummy.length) { + dummy = jQuery('
').attr('id', _id).appendTo(field.parentNode); + } + + dummy.html(ret_obj['message']).show(); +} + +// 결과 메세지를 정리하는 함수 +function removeMemberCheckValueOutput(dummy, obj) { + dummy.style.display = "none"; +} diff --git a/modules/menu/conf/info.xml b/modules/menu/conf/info.xml index e2950189d..17dc41a85 100644 --- a/modules/menu/conf/info.xml +++ b/modules/menu/conf/info.xml @@ -1,33 +1,33 @@ - - - 메뉴 - 菜单管理 - メニュー - Menu - Menu - Menú - Меню - 選單 - 레이아웃, 모듈을 연결하는 메뉴를 생성/관리하는 모듈입니다. - 此模块将生成并管理连接布局,模块的菜单。 - レイアウト、モジュールを連動させるメニューを作成・管理するモジュールです。 - This module is for creating/managering menues that linking layouts or modules. - Module này dành cho việc tạo và quản lý Menu sẽ liên kết với giao diện hoặc Mudule. - Este módulo es para crear/manejar los menús que que son conectados con los diseños o módulos. - Этот модуль служит для создания/управления меню, соединяюще лейауты и модули. - 可建立並管理連結版面和模組的選單。 - 0.1 - 2007-02-28 - construction - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 메뉴 + 菜单管理 + メニュー + Menu + Menu + Menú + Меню + 選單 + 레이아웃, 모듈을 연결하는 메뉴를 생성/관리하는 모듈입니다. + 此模块将生成并管理连接布局,模块的菜单。 + レイアウト、モジュールを連動させるメニューを作成・管理するモジュールです。 + This module is for creating/managering menues that linking layouts or modules. + Module này dành cho việc tạo và quản lý Menu sẽ liên kết với giao diện hoặc Mudule. + Este módulo es para crear/manejar los menús que que son conectados con los diseños o módulos. + Этот модуль служит для создания/управления меню, соединяюще лейауты и модули. + 可建立並管理連結版面和模組的選單。 + 0.1 + 2007-02-28 + construction + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/menu/lang/en.lang.php b/modules/menu/lang/en.lang.php index b0418e4b1..bf6bdb815 100644 --- a/modules/menu/lang/en.lang.php +++ b/modules/menu/lang/en.lang.php @@ -1,53 +1,53 @@ - - * @brief Menu module's basic language pack - **/ - - $lang->cmd_menu_insert = 'Create Menu'; - $lang->cmd_menu_management = 'Menu Management'; - - $lang->menu = 'Menu'; - $lang->menu_count = 'No. of menu'; - $lang->menu_management = 'Menu Management'; - $lang->depth = 'Step'; - $lang->parent_menu_name = 'Parent Menu Name'; - $lang->menu_name = 'Menu Name'; - $lang->menu_srl = 'Menu Serial Number'; - $lang->menu_id = 'Menu ID'; - $lang->menu_url = 'Menu URL'; - $lang->menu_open_window = 'Open a new window'; - $lang->menu_expand = 'Expand'; - $lang->menu_img_btn = 'Image button'; - $lang->menu_normal_btn = 'Normal'; - $lang->menu_hover_btn = 'Mouse over'; - $lang->menu_active_btn = 'When selected'; - $lang->menu_group_srls = 'Accessable Groups'; - $lang->layout_maker = "Layout Maker"; - $lang->layout_history = "Update History "; - $lang->layout_info = "Layout Info"; - $lang->layout_list = 'Layouts List'; - $lang->downloaded_list = 'Downloads List'; - $lang->limit_menu_depth = 'Display Enabled'; - - $lang->cmd_make_child = 'Add a Child Menu'; - $lang->cmd_move_to_installed_list = "View Created List"; - $lang->cmd_enable_move_menu = "Move Menu (Drag the top menu after selecting)"; - $lang->cmd_search_mid = "Search mid"; - - $lang->msg_cannot_delete_for_child = 'A menu with child menus cannot be deleted.'; - - $lang->about_title = 'Please input the title that is easy to verify when connecting to module.'; - $lang->about_menu_management = "Menu management enables you to consist menu in the selected layout.\nYou can create menu upto setted depth and can enter information in details by clicking the menu.\nMenu will be expanded by cliking the folder image.\nIf menu is not shown normally, refresh the information by clicking the button \"Re-create cache file\".\n* Menu created over the depth limit may not be shown properly."; - $lang->about_menu_name = 'The name will be shown as a menu name if it is not an admin or image button.'; - $lang->about_menu_url = "It is the menu URL when select the menu.
You may enter only id value to link to other module.
If no contents exist, nothing will happen even though you click the menu."; - $lang->about_menu_open_window = 'You can assign it to open a page in a new window when the menu clicked.'; - $lang->about_menu_expand = 'It enables the menu to remain expanded when the tree menu(tree_menu.js) is used.'; - $lang->about_menu_img_btn = 'If you register an image button, the image button will automatically replace the text button, and it will be shown in the layout.'; - $lang->about_menu_group_srls = 'If you select a group, only the group members can see the menu. (if xml file is directly opened, it will be shown.)'; - - $lang->about_menu = "Menu module will help you to create a complete site through the convenient menu management which arranges created modules and links to layouts without any manual works..\nMenu is not a site manager, but it just has information which can link to modules and layouts so you can express different types of menu."; - - $lang->alert_image_only = "Only image files can be registered."; -?> +cmd_menu_insert = 'Create Menu'; + $lang->cmd_menu_management = 'Menu Management'; + + $lang->menu = 'Menu'; + $lang->menu_count = 'No. of menu'; + $lang->menu_management = 'Menu Management'; + $lang->depth = 'Step'; + $lang->parent_menu_name = 'Parent Menu Name'; + $lang->menu_name = 'Menu Name'; + $lang->menu_srl = 'Menu Serial Number'; + $lang->menu_id = 'Menu ID'; + $lang->menu_url = 'Menu URL'; + $lang->menu_open_window = 'Open a new window'; + $lang->menu_expand = 'Expand'; + $lang->menu_img_btn = 'Image button'; + $lang->menu_normal_btn = 'Normal'; + $lang->menu_hover_btn = 'Mouse over'; + $lang->menu_active_btn = 'When selected'; + $lang->menu_group_srls = 'Accessable Groups'; + $lang->layout_maker = "Layout Maker"; + $lang->layout_history = "Update History "; + $lang->layout_info = "Layout Info"; + $lang->layout_list = 'Layouts List'; + $lang->downloaded_list = 'Downloads List'; + $lang->limit_menu_depth = 'Display Enabled'; + + $lang->cmd_make_child = 'Add a Child Menu'; + $lang->cmd_move_to_installed_list = "View Created List"; + $lang->cmd_enable_move_menu = "Move Menu (Drag the top menu after selecting)"; + $lang->cmd_search_mid = "Search mid"; + + $lang->msg_cannot_delete_for_child = 'A menu with child menus cannot be deleted.'; + + $lang->about_title = 'Please input the title that is easy to verify when connecting to module.'; + $lang->about_menu_management = "Menu management enables you to consist menu in the selected layout.\nYou can create menu upto setted depth and can enter information in details by clicking the menu.\nMenu will be expanded by cliking the folder image.\nIf menu is not shown normally, refresh the information by clicking the button \"Re-create cache file\".\n* Menu created over the depth limit may not be shown properly."; + $lang->about_menu_name = 'The name will be shown as a menu name if it is not an admin or image button.'; + $lang->about_menu_url = "It is the menu URL when select the menu.
You may enter only id value to link to other module.
If no contents exist, nothing will happen even though you click the menu."; + $lang->about_menu_open_window = 'You can assign it to open a page in a new window when the menu clicked.'; + $lang->about_menu_expand = 'It enables the menu to remain expanded when the tree menu(tree_menu.js) is used.'; + $lang->about_menu_img_btn = 'If you register an image button, the image button will automatically replace the text button, and it will be shown in the layout.'; + $lang->about_menu_group_srls = 'If you select a group, only the group members can see the menu. (if xml file is directly opened, it will be shown.)'; + + $lang->about_menu = "Menu module will help you to create a complete site through the convenient menu management which arranges created modules and links to layouts without any manual works..\nMenu is not a site manager, but it just has information which can link to modules and layouts so you can express different types of menu."; + + $lang->alert_image_only = "Only image files can be registered."; +?> diff --git a/modules/menu/lang/es.lang.php b/modules/menu/lang/es.lang.php index 86e6aac19..bfe5cb5dc 100644 --- a/modules/menu/lang/es.lang.php +++ b/modules/menu/lang/es.lang.php @@ -1,7 +1,7 @@ + * @autor NHN (developers@xpressengine.com) * @sumario Paquete del idioma español para el Menú del módulo básico **/ diff --git a/modules/menu/lang/fr.lang.php b/modules/menu/lang/fr.lang.php index 887d8a941..e7bbdc8d4 100644 --- a/modules/menu/lang/fr.lang.php +++ b/modules/menu/lang/fr.lang.php @@ -1,53 +1,53 @@ - Traduit par Pierre Duvent - * @brief Paque du langage en français pour le module de Menu - **/ - - $lang->cmd_menu_insert = 'Créer un Menu'; - $lang->cmd_menu_management = 'Administer des Menus'; - - $lang->menu = 'Menu'; - $lang->menu_count = 'Somme de menu'; - $lang->menu_management = 'Administration de Menu'; - $lang->depth = 'Niveau'; - $lang->parent_menu_name = 'Nom de Menu supérieur'; - $lang->menu_name = 'Nom de Menu'; - $lang->menu_srl = 'Numéro de série de Menu'; - $lang->menu_id = 'Nom d\'Identité de Menu'; - $lang->menu_url = 'URL de Menu'; - $lang->menu_open_window = 'Ouvrire une nouvelle fenêtre'; - $lang->menu_expand = 'Étendre'; - $lang->menu_img_btn = 'Bouton en Image'; - $lang->menu_normal_btn = 'Normal'; - $lang->menu_hover_btn = 'Survolé'; - $lang->menu_active_btn = 'Choisi'; - $lang->menu_group_srls = 'Groupes qui peuvent accéder'; - $lang->layout_maker = "Auteur de la Mise en Page"; - $lang->layout_history = "Histoire des Mises à Jour"; - $lang->layout_info = "Information de la Mise en Page"; - $lang->layout_list = 'Liste des Mises en Page'; - $lang->downloaded_list = 'Liste de Téléchargement'; - $lang->limit_menu_depth = 'Niveau permis d\'exposer'; - - $lang->cmd_make_child = 'Ajouter un menu inférieur'; - $lang->cmd_move_to_installed_list = "Voir la liste créé"; - $lang->cmd_enable_move_menu = "Bouger le Menu (glisser-déposer un menu après cocher)"; - $lang->cmd_search_mid = "Rechercher mid"; - - $lang->msg_cannot_delete_for_child = 'Un menu qui a des menus inférieurs ne peut pas être supprimé.'; - - $lang->about_title = 'Entrez un titre facile à vérifier quand on le connecte à un module.'; - $lang->about_menu_management = "Administration de Menu vous permet de composer le menu dans la Mise en Page que vous choisissez.\nVous pouvez créer le menu jusqu'au niveau permis et entrer des informations détaillées si vou cliquez le menu.\nMenu sera étendu si vous cliquez l'image de dossier.\nSi le menu n'est pas représenté normalement, rafraîchir les informations en cliquant le bouton \"Recréer \'antémémoire de fichier\".\n* Menu cré qui passe plus que le niveau permis pourra être représenté incorrectement."; - $lang->about_menu_name = 'Ce nom sera représenté comme le nom de menu si ce n\'est pas le bouton en image ou le bouton pour administrer.'; - $lang->about_menu_url = "C'est le URL où l'on bouge quand on choisit le menu.
Vous pouvez entrer la valeur d'identité(nom d'idendité) seulement pour lier à un autre module.
Si nul contenu n'existe, rien n'aura lieu même si l'on clique le menu."; - $lang->about_menu_open_window = 'Vous pouvez faire ouvrir une page dans une nouvelle fenêtre quand le menu est cliqué.'; - $lang->about_menu_expand = 'L\'Arbre de Menu(tree_menu.js) peut faire resté le menu étendu toujours.'; - $lang->about_menu_img_btn = 'Si vous enrégistez un bouton en image, l\'image remplacera automatiquement le bouton en texte, et ce sera représenté dans la Mise en Page.'; - $lang->about_menu_group_srls = 'Si vous choisissez un groupe, les membres de ce groupe seulement peuvent voir le menu. (Si l\'on ouvre un fichier xml, le fichier sera exposé.)'; - - $lang->about_menu = "Le Module de Menu vous aidrera à établir un site complet par l'administration confortable qui arrange les modules créés et liens à la mise en page sans aucun travaux manuels.\nMenu n'est pas un administrateur du Site, mais il a seulement l'information qui peut lier les modules à la mise en page, et on peut représenter les menu en formes diverses par la mise en page."; - - $lang->alert_image_only = "Fichiers d'image seulement peuvent être enrégistrés."; -?> + + * @brief Paque du langage en français pour le module de Menu + **/ + + $lang->cmd_menu_insert = 'Créer un Menu'; + $lang->cmd_menu_management = 'Administer des Menus'; + + $lang->menu = 'Menu'; + $lang->menu_count = 'Somme de menu'; + $lang->menu_management = 'Administration de Menu'; + $lang->depth = 'Niveau'; + $lang->parent_menu_name = 'Nom de Menu supérieur'; + $lang->menu_name = 'Nom de Menu'; + $lang->menu_srl = 'Numéro de série de Menu'; + $lang->menu_id = 'Nom d\'Identité de Menu'; + $lang->menu_url = 'URL de Menu'; + $lang->menu_open_window = 'Ouvrire une nouvelle fenêtre'; + $lang->menu_expand = 'Étendre'; + $lang->menu_img_btn = 'Bouton en Image'; + $lang->menu_normal_btn = 'Normal'; + $lang->menu_hover_btn = 'Survolé'; + $lang->menu_active_btn = 'Choisi'; + $lang->menu_group_srls = 'Groupes qui peuvent accéder'; + $lang->layout_maker = "Auteur de la Mise en Page"; + $lang->layout_history = "Histoire des Mises à Jour"; + $lang->layout_info = "Information de la Mise en Page"; + $lang->layout_list = 'Liste des Mises en Page'; + $lang->downloaded_list = 'Liste de Téléchargement'; + $lang->limit_menu_depth = 'Niveau permis d\'exposer'; + + $lang->cmd_make_child = 'Ajouter un menu inférieur'; + $lang->cmd_move_to_installed_list = "Voir la liste créé"; + $lang->cmd_enable_move_menu = "Bouger le Menu (glisser-déposer un menu après cocher)"; + $lang->cmd_search_mid = "Rechercher mid"; + + $lang->msg_cannot_delete_for_child = 'Un menu qui a des menus inférieurs ne peut pas être supprimé.'; + + $lang->about_title = 'Entrez un titre facile à vérifier quand on le connecte à un module.'; + $lang->about_menu_management = "Administration de Menu vous permet de composer le menu dans la Mise en Page que vous choisissez.\nVous pouvez créer le menu jusqu'au niveau permis et entrer des informations détaillées si vou cliquez le menu.\nMenu sera étendu si vous cliquez l'image de dossier.\nSi le menu n'est pas représenté normalement, rafraîchir les informations en cliquant le bouton \"Recréer \'antémémoire de fichier\".\n* Menu cré qui passe plus que le niveau permis pourra être représenté incorrectement."; + $lang->about_menu_name = 'Ce nom sera représenté comme le nom de menu si ce n\'est pas le bouton en image ou le bouton pour administrer.'; + $lang->about_menu_url = "C'est le URL où l'on bouge quand on choisit le menu.
Vous pouvez entrer la valeur d'identité(nom d'idendité) seulement pour lier à un autre module.
Si nul contenu n'existe, rien n'aura lieu même si l'on clique le menu."; + $lang->about_menu_open_window = 'Vous pouvez faire ouvrir une page dans une nouvelle fenêtre quand le menu est cliqué.'; + $lang->about_menu_expand = 'L\'Arbre de Menu(tree_menu.js) peut faire resté le menu étendu toujours.'; + $lang->about_menu_img_btn = 'Si vous enrégistez un bouton en image, l\'image remplacera automatiquement le bouton en texte, et ce sera représenté dans la Mise en Page.'; + $lang->about_menu_group_srls = 'Si vous choisissez un groupe, les membres de ce groupe seulement peuvent voir le menu. (Si l\'on ouvre un fichier xml, le fichier sera exposé.)'; + + $lang->about_menu = "Le Module de Menu vous aidrera à établir un site complet par l'administration confortable qui arrange les modules créés et liens à la mise en page sans aucun travaux manuels.\nMenu n'est pas un administrateur du Site, mais il a seulement l'information qui peut lier les modules à la mise en page, et on peut représenter les menu en formes diverses par la mise en page."; + + $lang->alert_image_only = "Fichiers d'image seulement peuvent être enrégistrés."; +?> diff --git a/modules/menu/lang/jp.lang.php b/modules/menu/lang/jp.lang.php index 92fdc4a01..53f64f9b8 100644 --- a/modules/menu/lang/jp.lang.php +++ b/modules/menu/lang/jp.lang.php @@ -1,53 +1,53 @@ - 翻訳:RisaPapa、liahona、ミニミ - * @brief メニュー(menu)モジュールの基本言語パッケージ - **/ - - $lang->cmd_menu_insert = 'メニュー生成'; - $lang->cmd_menu_management = 'メニュー設定'; - - $lang->menu = 'メニュー'; - $lang->menu_count = 'メニュー数'; - $lang->menu_management = 'メニュー管理'; - $lang->depth = 'スレッド'; - $lang->parent_menu_name = '上位メニュー名'; - $lang->menu_name = 'メニュー名'; - $lang->menu_srl = 'メニュー固有番号'; - $lang->menu_id = 'メニュー名'; - $lang->menu_url = 'リンクURL'; - $lang->menu_open_window = '新しいウィンドウズで開く'; - $lang->menu_expand = '拡張表示'; - $lang->menu_img_btn = 'イメージボタン'; - $lang->menu_normal_btn = '一般ボタン'; - $lang->menu_hover_btn = 'マウスオーバー'; - $lang->menu_active_btn = '選択時のボタン'; - $lang->menu_group_srls = 'グループ制限'; - $lang->layout_maker = 'レイアウト作者'; - $lang->layout_history = '変更内容'; - $lang->layout_info = 'レイアウト情報'; - $lang->layout_list = 'レイアウトリスト'; - $lang->downloaded_list = 'ダウンロードリスト'; - $lang->limit_menu_depth = '表示スレッド'; - - $lang->cmd_make_child = '下位メニュー追加'; - $lang->cmd_move_to_installed_list = '生成されたリスト表示'; - $lang->cmd_enable_move_menu = 'メニュー移動(選択後メニューをドラッグして下さい)'; - $lang->cmd_search_mid = 'mid 検索'; - - $lang->msg_cannot_delete_for_child = '下位メニューが存在するメニューは削除出来ません。'; - - $lang->about_title = 'モジュールをリンクする際に分かりやすいタイトルを入力して下さい。'; - $lang->about_menu_management = "メニュー管理は、選択されたレイアウトで使用するメニューを構成出来るようにします。
一定レベルまでメニューの構成が出来、入力したメニューをクリックすると詳細情報が入力出来ます。
フォルダーのイメージをクリックするとメニューを拡張することが出来ます。
もしメニューが正常に表示されない場合は、 「キャッシュファイル再生成」ボタンをクリックして情報を更新して下さい。
* 一定レベル以上のメニューは正しく表示されない場合があります。"; - $lang->about_menu_name = '管理及びイメージボタンではない場合、メニュー名として表示されるタイトルです。'; - $lang->about_menu_url = 'メニュー選択時、移動するURLです。
他のモジュールとリンクを張る場合はIDの値のみ入力して下さい。
内容がない場合は、メニューを選択しても何の動作もありません。'; - $lang->about_menu_open_window = 'メニュー選択時、新しいウィンドウで開くかを指定することが出来ます。'; - $lang->about_menu_expand = 'ツリーメニュー(tree_menu.js)を利用すると常に拡張表示(すべて表示)の状態にすることが出来ます。'; - $lang->about_menu_img_btn = 'イメージボタンを登録するとレイアウトで自動的にイメージボタンに入れ替わって表示されます。'; - $lang->about_menu_group_srls = 'グループを選択すると該当するグループのユーザにのみメニューが表示されます(XMLファイルを直接開くと情報が表示されます)。'; - - $lang->about_menu = "メニューモジュールは、メニュー管理機能にて生成モジュールの整理やレイアウトとのリンクを設定し、簡単に管理者画面上でサイトを構築出来るようにします。\nメニューはサイトを管理するというより、モジュールとレイアウトをリンクし、様々なメニューを表示させる情報だけ持っています。"; - - $lang->alert_image_only = 'イメージ(画像)ファイルのみ登録出来ます。'; -?> +cmd_menu_insert = 'メニュー生成'; + $lang->cmd_menu_management = 'メニュー設定'; + + $lang->menu = 'メニュー'; + $lang->menu_count = 'メニュー数'; + $lang->menu_management = 'メニュー管理'; + $lang->depth = 'スレッド'; + $lang->parent_menu_name = '上位メニュー名'; + $lang->menu_name = 'メニュー名'; + $lang->menu_srl = 'メニュー固有番号'; + $lang->menu_id = 'メニュー名'; + $lang->menu_url = 'リンクURL'; + $lang->menu_open_window = '新しいウィンドウズで開く'; + $lang->menu_expand = '拡張表示'; + $lang->menu_img_btn = 'イメージボタン'; + $lang->menu_normal_btn = '一般ボタン'; + $lang->menu_hover_btn = 'マウスオーバー'; + $lang->menu_active_btn = '選択時のボタン'; + $lang->menu_group_srls = 'グループ制限'; + $lang->layout_maker = 'レイアウト作者'; + $lang->layout_history = '変更内容'; + $lang->layout_info = 'レイアウト情報'; + $lang->layout_list = 'レイアウトリスト'; + $lang->downloaded_list = 'ダウンロードリスト'; + $lang->limit_menu_depth = '表示スレッド'; + + $lang->cmd_make_child = '下位メニュー追加'; + $lang->cmd_move_to_installed_list = '生成されたリスト表示'; + $lang->cmd_enable_move_menu = 'メニュー移動(選択後メニューをドラッグして下さい)'; + $lang->cmd_search_mid = 'mid 検索'; + + $lang->msg_cannot_delete_for_child = '下位メニューが存在するメニューは削除出来ません。'; + + $lang->about_title = 'モジュールをリンクする際に分かりやすいタイトルを入力して下さい。'; + $lang->about_menu_management = "メニュー管理は、選択されたレイアウトで使用するメニューを構成出来るようにします。
一定レベルまでメニューの構成が出来、入力したメニューをクリックすると詳細情報が入力出来ます。
フォルダーのイメージをクリックするとメニューを拡張することが出来ます。
もしメニューが正常に表示されない場合は、 「キャッシュファイル再生成」ボタンをクリックして情報を更新して下さい。
* 一定レベル以上のメニューは正しく表示されない場合があります。"; + $lang->about_menu_name = '管理及びイメージボタンではない場合、メニュー名として表示されるタイトルです。'; + $lang->about_menu_url = 'メニュー選択時、移動するURLです。
他のモジュールとリンクを張る場合はIDの値のみ入力して下さい。
内容がない場合は、メニューを選択しても何の動作もありません。'; + $lang->about_menu_open_window = 'メニュー選択時、新しいウィンドウで開くかを指定することが出来ます。'; + $lang->about_menu_expand = 'ツリーメニュー(tree_menu.js)を利用すると常に拡張表示(すべて表示)の状態にすることが出来ます。'; + $lang->about_menu_img_btn = 'イメージボタンを登録するとレイアウトで自動的にイメージボタンに入れ替わって表示されます。'; + $lang->about_menu_group_srls = 'グループを選択すると該当するグループのユーザにのみメニューが表示されます(XMLファイルを直接開くと情報が表示されます)。'; + + $lang->about_menu = "メニューモジュールは、メニュー管理機能にて生成モジュールの整理やレイアウトとのリンクを設定し、簡単に管理者画面上でサイトを構築出来るようにします。\nメニューはサイトを管理するというより、モジュールとレイアウトをリンクし、様々なメニューを表示させる情報だけ持っています。"; + + $lang->alert_image_only = 'イメージ(画像)ファイルのみ登録出来ます。'; +?> diff --git a/modules/menu/lang/ko.lang.php b/modules/menu/lang/ko.lang.php index 3be5b2e6c..c2580e269 100644 --- a/modules/menu/lang/ko.lang.php +++ b/modules/menu/lang/ko.lang.php @@ -1,53 +1,53 @@ - - * @brief 메뉴(menu) 모듈의 기본 언어팩 - **/ - - $lang->cmd_menu_insert = '메뉴 생성'; - $lang->cmd_menu_management = '메뉴 설정'; - - $lang->menu = '메뉴'; - $lang->menu_count = '메뉴 수'; - $lang->menu_management = '메뉴 관리'; - $lang->depth = '단계'; - $lang->parent_menu_name = '상위 메뉴명'; - $lang->menu_name = '메뉴명'; - $lang->menu_srl = '메뉴 고유 번호'; - $lang->menu_id = '메뉴 이름'; - $lang->menu_url = '연결 url'; - $lang->menu_open_window = '새 창 열기'; - $lang->menu_expand = '펼침'; - $lang->menu_img_btn = '이미지 버튼'; - $lang->menu_normal_btn = '일반'; - $lang->menu_hover_btn = '마우스 오버'; - $lang->menu_active_btn = '선택 시'; - $lang->menu_group_srls = '그룹 제한'; - $lang->layout_maker = '레이아웃 제작자'; - $lang->layout_history = '변경 사항 '; - $lang->layout_info = '레이아웃 정보'; - $lang->layout_list = '레이아웃 목록'; - $lang->downloaded_list = '다운로드 목록'; - $lang->limit_menu_depth = '표시 가능'; - - $lang->cmd_make_child = '하부 메뉴 추가'; - $lang->cmd_move_to_installed_list = '생성된 목록 보기'; - $lang->cmd_enable_move_menu = '메뉴 옮기기 (선택 후, 위 메뉴를 드래그하세요.)'; - $lang->cmd_search_mid = 'mid 찾기'; - - $lang->msg_cannot_delete_for_child = '하부 메뉴가 있는 메뉴는 삭제하실 수 없습니다.'; - - $lang->about_title = '모듈에 연결할 때, 쉽게 구분할 수 있는 제목을 입력해주세요.'; - $lang->about_menu_management = "메뉴관리는 선택하신 레이아웃에서 사용하는 메뉴를 구성할 수 있도록 합니다.\n정해진 단계까지 메뉴를 구성 가능하며 입력하신 메뉴를 클릭하시면 상세 정보를 입력할 수 있습니다.\n폴더 그림을 클릭하시면 메뉴를 확장하실 수 있습니다.\n간혹 메뉴가 정상적으로 나타나지 않으면 \"캐시파일 재생성\" 버튼을 눌러서 정보를 갱신하세요.\n* 정해진 단계 이상의 메뉴는 제대로 표시되지 않을 수 있습니다."; - $lang->about_menu_name = '관리 및 이미지 버튼이 아닐 경우 메뉴 명으로 나타날 제목입니다.'; - $lang->about_menu_url = '메뉴 선택 시 이동할 URL입니다.
다른 모듈을 연결하고자 할 때는 mid값만 입력해주시면 됩니다.
내용이 없으면 이 메뉴를 선택해도 아무런 동작이 없습니다.'; - $lang->about_menu_open_window = '메뉴를 선택 했을 때, 새 창을 띄울 것인지 정할 수 있습니다.'; - $lang->about_menu_expand = '트리메뉴(tree_menu.js)를 사용 하면, 메뉴가 늘 펼쳐진 상태로 있게 합니다.'; - $lang->about_menu_img_btn = '이미지 버튼을 등록하면 레이아웃에서 이 메뉴가 이미지 버튼으로 교체되어 표시 됩니다.'; - $lang->about_menu_group_srls = '그룹을 선택하시면 해당 그룹의 사용자만 메뉴가 보이게 됩니다. (xml파일을 직접 열람하면 노출이 됩니다.)'; - - $lang->about_menu = "메뉴모듈은 생성된 모듈을 편리한 메뉴관리기를 통해 정리하고 레이아웃과 연결하여 별도의 수작업 없이 완성된 사이트를 구축하도록 도와줍니다. \n메뉴는 사이트를 관리하기 보다는 모듈과 레이아웃을 연결해 주며 레이아웃을 통해 여러 가지 형태의 메뉴를 표시할 수 있도록 하는 정보만 가지고 있습니다."; - - $lang->alert_image_only = '이미지 파일만 등록 가능합니다.'; -?> +cmd_menu_insert = '메뉴 생성'; + $lang->cmd_menu_management = '메뉴 설정'; + + $lang->menu = '메뉴'; + $lang->menu_count = '메뉴 수'; + $lang->menu_management = '메뉴 관리'; + $lang->depth = '단계'; + $lang->parent_menu_name = '상위 메뉴명'; + $lang->menu_name = '메뉴명'; + $lang->menu_srl = '메뉴 고유 번호'; + $lang->menu_id = '메뉴 이름'; + $lang->menu_url = '연결 url'; + $lang->menu_open_window = '새 창 열기'; + $lang->menu_expand = '펼침'; + $lang->menu_img_btn = '이미지 버튼'; + $lang->menu_normal_btn = '일반'; + $lang->menu_hover_btn = '마우스 오버'; + $lang->menu_active_btn = '선택 시'; + $lang->menu_group_srls = '그룹 제한'; + $lang->layout_maker = '레이아웃 제작자'; + $lang->layout_history = '변경 사항 '; + $lang->layout_info = '레이아웃 정보'; + $lang->layout_list = '레이아웃 목록'; + $lang->downloaded_list = '다운로드 목록'; + $lang->limit_menu_depth = '표시 가능'; + + $lang->cmd_make_child = '하부 메뉴 추가'; + $lang->cmd_move_to_installed_list = '생성된 목록 보기'; + $lang->cmd_enable_move_menu = '메뉴 옮기기 (선택 후, 위 메뉴를 드래그하세요.)'; + $lang->cmd_search_mid = 'mid 찾기'; + + $lang->msg_cannot_delete_for_child = '하부 메뉴가 있는 메뉴는 삭제하실 수 없습니다.'; + + $lang->about_title = '모듈에 연결할 때, 쉽게 구분할 수 있는 제목을 입력해주세요.'; + $lang->about_menu_management = "메뉴관리는 선택하신 레이아웃에서 사용하는 메뉴를 구성할 수 있도록 합니다.\n정해진 단계까지 메뉴를 구성 가능하며 입력하신 메뉴를 클릭하시면 상세 정보를 입력할 수 있습니다.\n폴더 그림을 클릭하시면 메뉴를 확장하실 수 있습니다.\n간혹 메뉴가 정상적으로 나타나지 않으면 \"캐시파일 재생성\" 버튼을 눌러서 정보를 갱신하세요.\n* 정해진 단계 이상의 메뉴는 제대로 표시되지 않을 수 있습니다."; + $lang->about_menu_name = '관리 및 이미지 버튼이 아닐 경우 메뉴 명으로 나타날 제목입니다.'; + $lang->about_menu_url = '메뉴 선택 시 이동할 URL입니다.
다른 모듈을 연결하고자 할 때는 mid값만 입력해주시면 됩니다.
내용이 없으면 이 메뉴를 선택해도 아무런 동작이 없습니다.'; + $lang->about_menu_open_window = '메뉴를 선택 했을 때, 새 창을 띄울 것인지 정할 수 있습니다.'; + $lang->about_menu_expand = '트리메뉴(tree_menu.js)를 사용 하면, 메뉴가 늘 펼쳐진 상태로 있게 합니다.'; + $lang->about_menu_img_btn = '이미지 버튼을 등록하면 레이아웃에서 이 메뉴가 이미지 버튼으로 교체되어 표시 됩니다.'; + $lang->about_menu_group_srls = '그룹을 선택하시면 해당 그룹의 사용자만 메뉴가 보이게 됩니다. (xml파일을 직접 열람하면 노출이 됩니다.)'; + + $lang->about_menu = "메뉴모듈은 생성된 모듈을 편리한 메뉴관리기를 통해 정리하고 레이아웃과 연결하여 별도의 수작업 없이 완성된 사이트를 구축하도록 도와줍니다. \n메뉴는 사이트를 관리하기 보다는 모듈과 레이아웃을 연결해 주며 레이아웃을 통해 여러 가지 형태의 메뉴를 표시할 수 있도록 하는 정보만 가지고 있습니다."; + + $lang->alert_image_only = '이미지 파일만 등록 가능합니다.'; +?> diff --git a/modules/menu/lang/ru.lang.php b/modules/menu/lang/ru.lang.php index d04002fc5..6bc903385 100644 --- a/modules/menu/lang/ru.lang.php +++ b/modules/menu/lang/ru.lang.php @@ -1,53 +1,53 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->cmd_menu_insert = 'Создать меню'; - $lang->cmd_menu_management = 'Управление меню'; - - $lang->menu = 'Меню'; - $lang->menu_count = 'Меню No.'; - $lang->menu_management = 'Управление меню'; - $lang->depth = 'Ступень'; - $lang->parent_menu_name = 'Имя верхнего меню'; - $lang->menu_name = 'Имя меню'; - $lang->menu_srl = 'SRL меню'; - $lang->menu_id = 'ID меню'; - $lang->menu_url = 'URL меню'; - $lang->menu_open_window = 'Открыть новое окно'; - $lang->menu_expand = 'Раскрыть'; - $lang->menu_img_btn = 'Изображение кнопки'; - $lang->menu_normal_btn = 'Обычное'; - $lang->menu_hover_btn = 'Мышь над'; - $lang->menu_active_btn = 'При выборе'; - $lang->menu_group_srls = 'Группы с доступом'; - $lang->layout_maker = "Маркет лейаута"; - $lang->layout_history = "История обновлений"; - $lang->layout_info = "Информация лейаутов"; - $lang->layout_list = 'Список лейаутов'; - $lang->downloaded_list = 'Список закачек'; - $lang->limit_menu_depth = 'Лимит глубины'; - - $lang->cmd_make_child = 'Добавть дочернее меню'; - $lang->cmd_move_to_installed_list = "Просмотреть созданные меню"; - $lang->cmd_enable_move_menu = "Переместить меню (Перетащите верхнее меню после выделения)"; - $lang->cmd_search_mid = "Поиск mid"; - - $lang->msg_cannot_delete_for_child = 'Невозможно удалить меню с дочерними меню'; - - $lang->about_title = 'Пожалуйста, введите название меню, которое легко проверить при подключению к модулю'; - $lang->about_menu_management = "Управление меню позволяет Вам заключить меню в вабранный лейаут.\nВы можете создать меню до установленной грубины и ввести информацию детально посредством целчка по нему\nМеню будет разкрыто щелчком по изображению папки.\nЕсли меню не отображается нормально, обновите информацию щелчком по кнопке \"Пересоздать файл кеша\".\n* Меню, созданное за пределами лимита глубины может отображаться неверно."; - $lang->about_menu_name = 'Это имя будет показано, если это не административная книпка или кнопка с изображением.'; - $lang->about_menu_url = "Это URL, связанный с меню.
Вы можете ввести только ID значение к ссылке на другой модуль.
Если содержания нет, ничего не произойдет при щелчке по меню."; - $lang->about_menu_open_window = 'Вы можете присвоить это для открытия ссылки в новом окне при щелчке по меню.'; - $lang->about_menu_expand = 'Это позволяет меню оставаться раскрытым, когда древовидное меню (tree_menu.js) используется.'; - $lang->about_menu_img_btn = 'Если Вы регистрируете кнопку с изображением, изображение автоматически заменит текстовую кнопку, и будет показано в лейауте.'; - $lang->about_menu_group_srls = 'Если Вы выберите группу, то только ее члены могут видеть это меню. (если XML файл открыт напрямую, оно будет показано.)'; - - $lang->about_menu = "Модуль меню поможет Вам создать полноценный сайт посредством удобного менеджмента меню, которое расставляет созданные модули и ссылки в лейауты без всякой ручной работы.\nМеню не является менеджером сайта, но оно содержит информацию, которая может связываться с модулями и лейаутами так, что Вы можете выразить различные виды меню."; - - $lang->alert_image_only = "Возможна регистрация только картинок"; -?> +cmd_menu_insert = 'Создать меню'; + $lang->cmd_menu_management = 'Управление меню'; + + $lang->menu = 'Меню'; + $lang->menu_count = 'Меню No.'; + $lang->menu_management = 'Управление меню'; + $lang->depth = 'Ступень'; + $lang->parent_menu_name = 'Имя верхнего меню'; + $lang->menu_name = 'Имя меню'; + $lang->menu_srl = 'SRL меню'; + $lang->menu_id = 'ID меню'; + $lang->menu_url = 'URL меню'; + $lang->menu_open_window = 'Открыть новое окно'; + $lang->menu_expand = 'Раскрыть'; + $lang->menu_img_btn = 'Изображение кнопки'; + $lang->menu_normal_btn = 'Обычное'; + $lang->menu_hover_btn = 'Мышь над'; + $lang->menu_active_btn = 'При выборе'; + $lang->menu_group_srls = 'Группы с доступом'; + $lang->layout_maker = "Маркет лейаута"; + $lang->layout_history = "История обновлений"; + $lang->layout_info = "Информация лейаутов"; + $lang->layout_list = 'Список лейаутов'; + $lang->downloaded_list = 'Список закачек'; + $lang->limit_menu_depth = 'Лимит глубины'; + + $lang->cmd_make_child = 'Добавть дочернее меню'; + $lang->cmd_move_to_installed_list = "Просмотреть созданные меню"; + $lang->cmd_enable_move_menu = "Переместить меню (Перетащите верхнее меню после выделения)"; + $lang->cmd_search_mid = "Поиск mid"; + + $lang->msg_cannot_delete_for_child = 'Невозможно удалить меню с дочерними меню'; + + $lang->about_title = 'Пожалуйста, введите название меню, которое легко проверить при подключению к модулю'; + $lang->about_menu_management = "Управление меню позволяет Вам заключить меню в вабранный лейаут.\nВы можете создать меню до установленной грубины и ввести информацию детально посредством целчка по нему\nМеню будет разкрыто щелчком по изображению папки.\nЕсли меню не отображается нормально, обновите информацию щелчком по кнопке \"Пересоздать файл кеша\".\n* Меню, созданное за пределами лимита глубины может отображаться неверно."; + $lang->about_menu_name = 'Это имя будет показано, если это не административная книпка или кнопка с изображением.'; + $lang->about_menu_url = "Это URL, связанный с меню.
Вы можете ввести только ID значение к ссылке на другой модуль.
Если содержания нет, ничего не произойдет при щелчке по меню."; + $lang->about_menu_open_window = 'Вы можете присвоить это для открытия ссылки в новом окне при щелчке по меню.'; + $lang->about_menu_expand = 'Это позволяет меню оставаться раскрытым, когда древовидное меню (tree_menu.js) используется.'; + $lang->about_menu_img_btn = 'Если Вы регистрируете кнопку с изображением, изображение автоматически заменит текстовую кнопку, и будет показано в лейауте.'; + $lang->about_menu_group_srls = 'Если Вы выберите группу, то только ее члены могут видеть это меню. (если XML файл открыт напрямую, оно будет показано.)'; + + $lang->about_menu = "Модуль меню поможет Вам создать полноценный сайт посредством удобного менеджмента меню, которое расставляет созданные модули и ссылки в лейауты без всякой ручной работы.\nМеню не является менеджером сайта, но оно содержит информацию, которая может связываться с модулями и лейаутами так, что Вы можете выразить различные виды меню."; + + $lang->alert_image_only = "Возможна регистрация только картинок"; +?> diff --git a/modules/menu/lang/vi.lang.php b/modules/menu/lang/vi.lang.php index a4e93a929..a9ed11e80 100644 --- a/modules/menu/lang/vi.lang.php +++ b/modules/menu/lang/vi.lang.php @@ -1,55 +1,55 @@ -cmd_menu_insert = 'Tạo Menu'; - $lang->cmd_menu_management = 'Quản lý Menu'; - - $lang->menu = 'Menu'; - $lang->menu_count = 'Số Menu'; - $lang->menu_management = 'Quản lý Menu'; - $lang->depth = 'Bước'; - $lang->parent_menu_name = 'Tên Menu chính'; - $lang->menu_name = 'Tên Menu'; - $lang->menu_srl = 'Số Serial của Menu'; - $lang->menu_id = 'Menu ID'; - $lang->menu_url = 'Menu URL'; - $lang->menu_open_window = 'Mở ra trang mới'; - $lang->menu_expand = 'Trải rộng'; - $lang->menu_img_btn = 'Hình nút bấm'; - $lang->menu_normal_btn = 'Bình thường'; - $lang->menu_hover_btn = 'Khi trỏ chuột'; - $lang->menu_active_btn = 'Khi chọn'; - $lang->menu_group_srls = 'Nhóm được phép'; - $lang->layout_maker = "Người tạo giao diện"; - $lang->layout_history = "Lịch sử cập nhật"; - $lang->layout_info = "Thông tin giao diện"; - $lang->layout_list = 'Danh sách giao diện'; - $lang->downloaded_list = 'Danh sách Download'; - $lang->limit_menu_depth = 'Được phép hiển thị'; - - $lang->cmd_make_child = 'Thêm Menu con'; - $lang->cmd_move_to_installed_list = "Xem danh sách đã tạo"; - $lang->cmd_enable_move_menu = "Di chuyển Menu (Kéo lên Menu trên sau khi lựa chọn)"; - $lang->cmd_search_mid = "Tìm kiếm Module"; - - $lang->msg_cannot_delete_for_child = 'Không thể xóa Menu khi có những Menu con.'; - - $lang->about_title = 'Xin hãy nhập tiêu đề để dễ dàng xác minh khi kết nối tới Module.'; - $lang->about_menu_management = "Quản lý Menu cho phép bạn bố trí, chọn cách trình bày của Menu.\nBạn có thể tạo những menu và nhập những thông tin khi menu được lựa chọn.\nMenu sẽ đuwọc trải rộng khi bấm và hình thư mục trên Menu.\nNếu Menu không hiển thị một cách bình thường, hãy làm mới thông tin bằng cách bấm \"Tạo File Cache mới\".\n* Menu được tạo quá giới hạn có thể sẽ không hiển thị được như mong muốn."; - $lang->about_menu_name = 'Tên sẽ hiển thị là Tên Menu nếu không phải là Admin hay nút hình ảnh.'; - $lang->about_menu_url = "Nó sẽ là đường dẫn khi bấm vào Menu.
Bạn có thể chỉ nhập ID cho đường dẫn của Module.
Nếu để trống, sẽ không thấy tác dụng gì khi bấm vào Menu."; - $lang->about_menu_open_window = 'Hãy chọn nếu bạn muốn mở ra một trang mới khi bấm vào Menu.'; - $lang->about_menu_expand = 'Cho phép Menu luôn trải ra khi (tree_menu.js) được sử dụng.'; - $lang->about_menu_img_btn = 'Nếu đăng kí nút hình ảnh, hình ảnh sẽ tự động chèn lên tên của Menu, và sẽ hiển thị trong giao diện.'; - $lang->about_menu_group_srls = 'Nếu lựa chọn nhóm, thì chỉ những nhóm được chọn mới thấy được Menu. (nếu File XML trực tiếp mở ra, nó sẽ được hiển thị).'; - - $lang->about_menu = "Menu Module sẽ giúp bạn hoàn thiện một trang Web thông qua việc quản lý và sắp xếp thuận tiện, nó sẽ liên kết tới những Module trong Website.\nMenu không phải là người quản lý, nhiệm vụ của nó chỉ là liên kết và tạo sự phong phú trong Website của bạn."; - - $lang->alert_image_only = "Chỉ được phép sử dụng File hình ảnh."; -?> +cmd_menu_insert = 'Tạo Menu'; + $lang->cmd_menu_management = 'Quản lý Menu'; + + $lang->menu = 'Menu'; + $lang->menu_count = 'Số Menu'; + $lang->menu_management = 'Quản lý Menu'; + $lang->depth = 'Bước'; + $lang->parent_menu_name = 'Tên Menu chính'; + $lang->menu_name = 'Tên Menu'; + $lang->menu_srl = 'Số Serial của Menu'; + $lang->menu_id = 'Menu ID'; + $lang->menu_url = 'Menu URL'; + $lang->menu_open_window = 'Mở ra trang mới'; + $lang->menu_expand = 'Trải rộng'; + $lang->menu_img_btn = 'Hình nút bấm'; + $lang->menu_normal_btn = 'Bình thường'; + $lang->menu_hover_btn = 'Khi trỏ chuột'; + $lang->menu_active_btn = 'Khi chọn'; + $lang->menu_group_srls = 'Nhóm được phép'; + $lang->layout_maker = "Người tạo giao diện"; + $lang->layout_history = "Lịch sử cập nhật"; + $lang->layout_info = "Thông tin giao diện"; + $lang->layout_list = 'Danh sách giao diện'; + $lang->downloaded_list = 'Danh sách Download'; + $lang->limit_menu_depth = 'Được phép hiển thị'; + + $lang->cmd_make_child = 'Thêm Menu con'; + $lang->cmd_move_to_installed_list = "Xem danh sách đã tạo"; + $lang->cmd_enable_move_menu = "Di chuyển Menu (Kéo lên Menu trên sau khi lựa chọn)"; + $lang->cmd_search_mid = "Tìm kiếm Module"; + + $lang->msg_cannot_delete_for_child = 'Không thể xóa Menu khi có những Menu con.'; + + $lang->about_title = 'Xin hãy nhập tiêu đề để dễ dàng xác minh khi kết nối tới Module.'; + $lang->about_menu_management = "Quản lý Menu cho phép bạn bố trí, chọn cách trình bày của Menu.\nBạn có thể tạo những menu và nhập những thông tin khi menu được lựa chọn.\nMenu sẽ đuwọc trải rộng khi bấm và hình thư mục trên Menu.\nNếu Menu không hiển thị một cách bình thường, hãy làm mới thông tin bằng cách bấm \"Tạo File Cache mới\".\n* Menu được tạo quá giới hạn có thể sẽ không hiển thị được như mong muốn."; + $lang->about_menu_name = 'Tên sẽ hiển thị là Tên Menu nếu không phải là Admin hay nút hình ảnh.'; + $lang->about_menu_url = "Nó sẽ là đường dẫn khi bấm vào Menu.
Bạn có thể chỉ nhập ID cho đường dẫn của Module.
Nếu để trống, sẽ không thấy tác dụng gì khi bấm vào Menu."; + $lang->about_menu_open_window = 'Hãy chọn nếu bạn muốn mở ra một trang mới khi bấm vào Menu.'; + $lang->about_menu_expand = 'Cho phép Menu luôn trải ra khi (tree_menu.js) được sử dụng.'; + $lang->about_menu_img_btn = 'Nếu đăng kí nút hình ảnh, hình ảnh sẽ tự động chèn lên tên của Menu, và sẽ hiển thị trong giao diện.'; + $lang->about_menu_group_srls = 'Nếu lựa chọn nhóm, thì chỉ những nhóm được chọn mới thấy được Menu. (nếu File XML trực tiếp mở ra, nó sẽ được hiển thị).'; + + $lang->about_menu = "Menu Module sẽ giúp bạn hoàn thiện một trang Web thông qua việc quản lý và sắp xếp thuận tiện, nó sẽ liên kết tới những Module trong Website.\nMenu không phải là người quản lý, nhiệm vụ của nó chỉ là liên kết và tạo sự phong phú trong Website của bạn."; + + $lang->alert_image_only = "Chỉ được phép sử dụng File hình ảnh."; +?> diff --git a/modules/menu/lang/zh-CN.lang.php b/modules/menu/lang/zh-CN.lang.php index 8da5153fa..34108b4fe 100644 --- a/modules/menu/lang/zh-CN.lang.php +++ b/modules/menu/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ + * @author NHN (developers@xpressengine.com) * @brief 菜单(menu) 模块的基本语言包 **/ diff --git a/modules/menu/lang/zh-TW.lang.php b/modules/menu/lang/zh-TW.lang.php index 46cdcca3f..af91649ed 100644 --- a/modules/menu/lang/zh-TW.lang.php +++ b/modules/menu/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ 翻譯:royallin + * @author NHN (developers@xpressengine.com) 翻譯:royallin * @brief 選單(menu) 模組正體中文語言 **/ diff --git a/modules/menu/menu.admin.controller.php b/modules/menu/menu.admin.controller.php index db299b87c..fb266a54b 100644 --- a/modules/menu/menu.admin.controller.php +++ b/modules/menu/menu.admin.controller.php @@ -1,654 +1,654 @@ -site_srl = (int)$site_module_info->site_srl; - $args->title = Context::get('title'); - $args->menu_srl = getNextSequence(); - $args->listorder = $args->menu_srl * -1; - - $output = executeQuery('menu.insertMenu', $args); - if(!$output->toBool()) return $output; - - $this->add('menu_srl', $args->menu_srl); - $this->setMessage('success_registed'); - } - - /** - * @brief 메뉴 제목 변경 - **/ - function procMenuAdminUpdate() { - // 입력할 변수 정리 - $args->title = Context::get('title'); - $args->menu_srl = Context::get('menu_srl'); - - $output = executeQuery('menu.updateMenu', $args); - if(!$output->toBool()) return $output; - - $this->setMessage('success_registed'); - } - - /** - * @brief 메뉴 삭제 - * menu_item과 xml 캐시 파일 모두 삭제 - **/ - function procMenuAdminDelete() { - $menu_srl = Context::get('menu_srl'); - return $this->deleteMenu($menu_srl); - } - - function deleteMenu($menu_srl) { - // 캐시 파일 삭제 - $cache_list = FileHandler::readDir("./files/cache/menu","",false,true); - if(count($cache_list)) { - foreach($cache_list as $cache_file) { - $pos = strpos($cache_file, $menu_srl.'_'); - if($pos>0)FileHandler::removeFile($cache_file); - } - } - - // 이미지 버튼 모두 삭제 - $image_path = sprintf('./files/attach/menu_button/%s', $menu_srl); - FileHandler::removeDir($image_path); - - $args->menu_srl = $menu_srl; - - // 메뉴 메뉴 삭제 - $output = executeQuery("menu.deleteMenuItems", $args); - if(!$output->toBool()) return $output; - - // 메뉴 삭제 - $output = executeQuery("menu.deleteMenu", $args); - if(!$output->toBool()) return $output; - - return new Object(0,'success_deleted'); - } - - /** - * @brief 메뉴에 아이템 추가 - **/ - function procMenuAdminInsertItem() { - // 입력할 변수 정리 - $source_args = Context::getRequestVars(); - unset($source_args->module); - unset($source_args->act); - if($source_args->menu_open_window!="Y") $source_args->menu_open_window = "N"; - if($source_args->menu_expand !="Y") $source_args->menu_expand = "N"; - $source_args->group_srls = str_replace('|@|',',',$source_args->group_srls); - $source_args->parent_srl = (int)$source_args->parent_srl; - - // 변수를 다시 정리 (form문의 column과 DB column이 달라서) - $args->menu_srl = $source_args->menu_srl; - $args->menu_item_srl = $source_args->menu_item_srl; - $args->parent_srl = $source_args->parent_srl; - $args->menu_srl = $source_args->menu_srl; - $args->menu_id = $source_args->menu_id; - $args->name = $source_args->menu_name; - $args->url = trim($source_args->menu_url); - $args->open_window = $source_args->menu_open_window; - $args->expand = $source_args->menu_expand; - $args->normal_btn = $source_args->normal_btn; - $args->hover_btn = $source_args->hover_btn; - $args->active_btn = $source_args->active_btn; - $args->group_srls = $source_args->group_srls; - - // 이미 존재하는지를 확인 - $oMenuModel = &getAdminModel('menu'); - $item_info = $oMenuModel->getMenuItemInfo($args->menu_item_srl); - - // 존재하게 되면 update를 해준다 - if($item_info->menu_item_srl == $args->menu_item_srl) { - $output = executeQuery('menu.updateMenuItem', $args); - if(!$output->toBool()) return $output; - - // 존재하지 않으면 insert를 해준다 - } else { - $args->listorder = -1*$args->menu_item_srl; - $output = executeQuery('menu.insertMenuItem', $args); - if(!$output->toBool()) return $output; - } - - // 해당 메뉴의 정보를 구함 - $menu_info = $oMenuModel->getMenu($args->menu_srl); - $menu_title = $menu_info->title; - - // XML 파일을 갱신하고 위치을 넘겨 받음 - $xml_file = $this->makeXmlFile($args->menu_srl); - - // url이 mid일 경우 기록 남김 - if(preg_match('/^([a-zA-Z0-9\_\-]+)$/', $args->url)) { - $mid = $args->url; - - $mid_args->menu_srl = $args->menu_srl; - $mid_args->mid = $mid; - - // menu_srl에 해당하는 레이아웃 값을 구함 - $output = executeQuery('menu.getMenuLayout', $args); - - // 해당 모듈에 레이아웃 값이 정해져 있지 않으면 지정 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByMid($mid); - if(!$module_info->layout_srl&&$output->data->layout_srl) $mid_args->layout_srl = $output->data->layout_srl; - - // 해당 mid의 메뉴값을 선택된 메뉴로 변경 - $oModuleController = &getController('module'); - $oModuleController->updateModuleMenu($mid_args); - } - - $this->add('xml_file', $xml_file); - $this->add('menu_srl', $args->menu_srl); - $this->add('menu_item_srl', $args->menu_item_srl); - $this->add('menu_title', $menu_title); - $this->add('parent_srl', $args->parent_srl); - } - - /** - * @brief 메뉴 메뉴 삭제 - **/ - function procMenuAdminDeleteItem() { - // 변수 정리 - $args = Context::gets('menu_srl','menu_item_srl'); - - $oMenuAdminModel = &getAdminModel('menu'); - - // 원정보를 가져옴 - $item_info = $oMenuAdminModel->getMenuItemInfo($args->menu_item_srl); - if($item_info->parent_srl) $parent_srl = $item_info->parent_srl; - - // 자식 노드가 있는지 체크하여 있으면 삭제 못한다는 에러 출력 - $output = executeQuery('menu.getChildMenuCount', $args); - if(!$output->toBool()) return $output; - if($output->data->count>0) return new Object(-1, 'msg_cannot_delete_for_child'); - - // DB에서 삭제 - $output = executeQuery("menu.deleteMenuItem", $args); - if(!$output->toBool()) return $output; - - // 해당 메뉴의 정보를 구함 - $menu_info = $oMenuAdminModel->getMenu($args->menu_srl); - $menu_title = $menu_info->title; - - // XML 파일을 갱신하고 위치을 넘겨 받음 - $xml_file = $this->makeXmlFile($args->menu_srl); - - // 이미지 버튼 모두 삭제 - if($item_info->normal_btn) FileHandler::removeFile($item_info->normal_btn); - if($item_info->hover_btn) FileHandler::removeFile($item_info->hover_btn); - if($item_info->active_btn) FileHandler::removeFile($item_info->active_btn); - - $this->add('xml_file', $xml_file); - $this->add('menu_title', $menu_title); - $this->add('menu_item_srl', $parent_srl); - $this->setMessage('success_deleted'); - } - - /** - * @brief 메뉴의 메뉴를 이동 - **/ - function procMenuAdminMoveItem() { - $menu_srl = Context::get('menu_srl'); - $mode = Context::get('mode'); - $parent_srl = Context::get('parent_srl'); - $source_srl = Context::get('source_srl'); - $target_srl = Context::get('target_srl'); - - if(!$menu_srl || !$mode || !$target_srl) return new Object(-1,'msg_invalid_request'); - $this->moveMenuItem($menu_srl,$parent_srl,$source_srl,$target_srl,$mode); - } - - function moveMenuItem($menu_srl,$parent_srl,$source_srl,$target_srl,$mode){ - // 원본 메뉴들을 구함 - $oMenuAdminModel = &getAdminModel('menu'); - - $target_item = $oMenuAdminModel->getMenuItemInfo($target_srl); - if($target_item->menu_item_srl != $target_srl) return new Object(-1,'msg_invalid_request'); - - // 위치 이동 (순서 조절) - if($mode == 'move') { - $args->parent_srl = $parent_srl; - $args->menu_srl = $menu_srl; - - if($source_srl) { - $source_item = $oMenuAdminModel->getMenuItemInfo($source_srl); - if($source_item->menu_item_srl != $source_srl) return new Object(-1,'msg_invalid_request'); - $args->listorder = $source_item->listorder-1; - } else { - $output = executeQuery('menu.getMaxListorder', $args); - if(!$output->toBool()) return $output; - $args->listorder = (int)$output->data->listorder; - if(!$args->listorder) $args->listorder= 0; - } - $args->parent_srl = $parent_srl; - $output = executeQuery('menu.updateMenuItemListorder', $args); - if(!$output->toBool()) return $output; - - $args->parent_srl = $parent_srl; - $args->menu_item_srl = $target_srl; - $output = executeQuery('menu.updateMenuItemNode', $args); - if(!$output->toBool()) return $output; - // 자식으로 추가 - } elseif($mode == 'insert') { - $args->menu_item_srl = $target_srl; - $args->parent_srl = $parent_srl; - $args->listorder = -1*getNextSequence(); - $output = executeQuery('menu.updateMenuItemNode', $args); - if(!$output->toBool()) return $output; - } - - $xml_file = $this->makeXmlFile($menu_srl); - return $xml_file; - } - - /** - * @brief xml 파일을 갱신 - * 관리자페이지에서 메뉴 구성 후 간혹 xml파일이 재생성 안되는 경우가 있는데\n - * 이럴 경우 관리자의 수동 갱신 기능을 구현해줌\n - * 개발 중간의 문제인 것 같고 현재는 문제가 생기지 않으나 굳이 없앨 필요 없는 기능 - **/ - function procMenuAdminMakeXmlFile() { - // 입력값을 체크 - $menu_srl = Context::get('menu_srl'); - - // 해당 메뉴의 정보를 구함 - $oMenuAdminModel = &getAdminModel('menu'); - $menu_info = $oMenuAdminModel->getMenu($menu_srl); - $menu_title = $menu_info->title; - - // xml파일 재생성 - $xml_file = $this->makeXmlFile($menu_srl); - - // return 값 설정 - $this->add('menu_title',$menu_title); - $this->add('xml_file',$xml_file); - } - - /** - * @brief 메뉴 이미지 버튼을 등록 - **/ - function procMenuAdminUploadButton() { - $menu_srl = Context::get('menu_srl'); - $menu_item_srl = Context::get('menu_item_srl'); - $target = Context::get('target'); - $target_file = Context::get($target); - - // 필수 요건이 없거나 업로드된 파일이 아니면 오류 발생 - if(!$menu_srl || !$menu_item_srl || !$target_file || !is_uploaded_file($target_file['tmp_name']) || !preg_match('/\.(gif|jpeg|jpg|png)/i',$target_file['name'])) { - Context::set('error_messge', Context::getLang('msg_invalid_request')); - - // 요건을 만족하고 업로드된 파일이면 지정된 위치로 이동 - } else { - $tmp_arr = explode('.',$target_file['name']); - $ext = $tmp_arr[count($tmp_arr)-1]; - - $path = sprintf('./files/attach/menu_button/%d/', $menu_srl); - $filename = sprintf('%s%d.%s.%s', $path, $menu_item_srl, $target, $ext); - - if(!is_dir($path)) FileHandler::makeDir($path); - - move_uploaded_file($target_file['tmp_name'], $filename); - Context::set('filename', $filename); - } - - - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('menu_file_uploaded'); - } - - /** - * @brief 등록된 메뉴 이미지 제거 - **/ - function procMenuAdminDeleteButton() { - $menu_srl = Context::get('menu_srl'); - $menu_item_srl = Context::get('menu_item_srl'); - $target = Context::get('target'); - $filename = Context::get('filename'); - FileHandler::removeFile($filename); - - $this->add('target', $target); - } - - /** - * @brief 메뉴의 xml 파일을 만들고 위치를 return - **/ - function makeXmlFile($menu_srl) { - // xml파일 생성시 필요한 정보가 없으면 그냥 return - if(!$menu_srl) return; - - // 메뉴 정보를 구함 - $args->menu_srl = $menu_srl; - $output = executeQuery('menu.getMenu', $args); - if(!$output->toBool() || !$output->data) return $output; - $site_srl = (int)$output->data->site_srl; - - if($site_srl) { - $oModuleModel = &getModel('module'); - $site_info = $oModuleModel->getSiteInfo($site_srl); - $domain = $site_info->domain; - } - - // DB에서 menu_srl에 해당하는 메뉴 아이템 목록을 listorder순으로 구해옴 - $args->menu_srl = $menu_srl; - $args->sort_index = 'listorder'; - $output = executeQuery('menu.getMenuItems', $args); - if(!$output->toBool()) return; - - // 캐시 파일의 이름을 지정 - $xml_file = sprintf("./files/cache/menu/%s.xml.php", $menu_srl); - $php_file = sprintf("./files/cache/menu/%s.php", $menu_srl); - - // 구해온 데이터가 없다면 노드데이터가 없는 xml 파일만 생성 - $list = $output->data; - if(!$list) { - $xml_buff = ""; - FileHandler::writeFile($xml_file, $xml_buff); - FileHandler::writeFile($php_file, ''); - return $xml_file; - } - - // 구해온 데이터가 하나라면 array로 바꾸어줌 - if(!is_array($list)) $list = array($list); - - // 루프를 돌면서 tree 구성 - $list_count = count($list); - for($i=0;$i<$list_count;$i++) { - $node = $list[$i]; - $menu_item_srl = $node->menu_item_srl; - $parent_srl = $node->parent_srl; - - $tree[$parent_srl][$menu_item_srl] = $node; - } - - // 캐시 파일의 권한과 그룹 설정을 위한 공통 헤더 - $header_script = - '$lang_type = Context::getLangType(); '. - '$is_logged = Context::get(\'is_logged\'); '. - '$logged_info = Context::get(\'logged_info\'); '. - '$site_srl = '.$site_srl.';'. - '$site_admin = false;'. - 'if($site_srl) { '. - '$oModuleModel = &getModel(\'module\');'. - '$site_module_info = $oModuleModel->getSiteInfo($site_srl); '. - 'Context::set(\'site_module_info\',$site_module_info);'. - '$grant = $oModuleModel->getGrant($site_module_info, $logged_info); '. - 'if($grant->manager ==1) $site_admin = true;'. - '}'. - 'if($is_logged) {'. - 'if($logged_info->is_admin=="Y" || $site_admin) $is_admin = true; '. - 'else $is_admin = false; '. - '$group_srls = array_keys($logged_info->group_list); '. - '} else { '. - '$is_admin = false; '. - '$group_srsl = array(); '. - '} '; - - // xml 캐시 파일 생성 (xml캐시는 따로 동작하기에 session 지정을 해주어야 함) - $xml_buff = sprintf( - 'init(); '. - 'header("Content-Type: text/xml; charset=UTF-8"); '. - 'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '. - 'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '. - 'header("Cache-Control: no-store, no-cache, must-revalidate"); '. - 'header("Cache-Control: post-check=0, pre-check=0", false); '. - 'header("Pragma: no-cache"); '. - '%s '. - '$oContext->close(); '. - '?>'. - '%s', - $header_script, - $this->getXmlTree($tree[0], $tree, $site_srl, $domain) - ); - - // php 캐시 파일 생성 - $php_output = $this->getPhpCacheCode($tree[0], $tree, $site_srl, $domain); - $php_buff = sprintf( - 'list = array(%s); '. - '?>', - $header_script, - $php_output['name'], - $php_output['buff'] - ); - - // 파일 저장 - FileHandler::writeFile($xml_file, $xml_buff); - FileHandler::writeFile($php_file, $php_buff); - return $xml_file; - } - - /** - * @brief array로 정렬된 노드들을 parent_srl을 참조하면서 recursive하게 돌면서 xml 데이터 생성 - * 메뉴 xml파일은 node라는 tag가 중첩으로 사용되며 이 xml doc으로 관리자 페이지에서 메뉴를 구성해줌\n - * (tree_menu.js 에서 xml파일을 바로 읽고 tree menu를 구현) - **/ - function getXmlTree($source_node, $tree, $site_srl, $domain) { - if(!$source_node) return; - - $oMenuAdminModel = &getAdminModel('menu'); - - foreach($source_node as $menu_item_srl => $node) { - $child_buff = ""; - - // 자식 노드의 데이터 가져옴 - if($menu_item_srl&&$tree[$menu_item_srl]) $child_buff = $this->getXmlTree($tree[$menu_item_srl], $tree, $site_srl, $domain); - - // 변수 정리 - $names = $oMenuAdminModel->getMenuItemNames($node->name, $site_srl); - foreach($names as $key => $val) { - $name_arr_str .= sprintf('"%s"=>"%s",',$key, str_replace('\\','\\\\',htmlspecialchars($val))); - } - $name_str = sprintf('$_names = array(%s); print $_names[$lang_type];', $name_arr_str); - - $url = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->url); - if(preg_match('/^([0-9a-zA-Z\_\-]+)$/', $node->url)) { - $href = getSiteUrl($domain, '','mid',$node->url); - $pos = strpos($href, $_SERVER['HTTP_HOST']); - if($pos !== false) $href = substr($href, $pos+strlen($_SERVER['HTTP_HOST'])); - } else $href = $url; - $open_window = $node->open_window; - $expand = $node->expand; - - $normal_btn = $node->normal_btn; - if($normal_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$normal_btn)) $normal_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$normal_btn); - else $normal_btn = ''; - $hover_btn = $node->hover_btn; - if($hover_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$hover_btn)) $hover_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$hover_btn); - else $hover_btn = ''; - $active_btn = $node->active_btn; - if($active_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$active_btn)) $active_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$active_btn); - else $active_btn = ''; - - $group_srls = $node->group_srls; - - if($normal_btn) { - if(preg_match('/\.png$/',$normal_btn)) $classname = 'class="iePngFix"'; - else $classname = ''; - if($hover_btn) $hover_str = sprintf('onmouseover="this.src=\'%s\'"', $hover_btn); else $hover_str = ''; - if($active_btn) $active_str = sprintf('onmousedown="this.src=\'%s\'"', $active_btn); else $active_str = ''; - $link = sprintf('<img src="%s" onmouseout="this.src=\'%s\'" alt="" %s %s %s />', $normal_btn, $normal_btn, $hover_str, $active_str, $classname); - } else { - $link = ''; - } - - // node->group_srls값이 있으면 - if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls); - else $group_check_code = "true"; - $attribute = sprintf( - 'node_srl="%s" parent_srl="%s" text="" url="" href="" open_window="%s" expand="%s" normal_btn="%s" hover_btn="%s" active_btn="%s" link="%s"', - $menu_item_srl, - $node->parent_srl, - $group_check_code, - $name_str, - $group_check_code, - $url, - $group_check_code, - $href, - $open_window, - $expand, - $normal_btn, - $hover_btn, - $active_btn, - $group_check_code, - $link - ); - - if($child_buff) $buff .= sprintf('%s', $attribute, $child_buff); - else $buff .= sprintf('', $attribute); - } - return $buff; - } - - /** - * @brief array로 정렬된 노드들을 php code로 변경하여 return - * 메뉴에서 메뉴를 tpl에 사용시 xml데이터를 사용할 수도 있지만 별도의 javascript 사용이 필요하기에 - * php로 된 캐시파일을 만들어서 db이용없이 바로 메뉴 정보를 구할 수 있도록 한다 - * 이 캐시는 ModuleHandler::displayContent() 에서 include하여 Context::set() 한다 - **/ - function getPhpCacheCode($source_node, $tree, $site_srl, $domain) { - $output = array("buff"=>"", "url_list"=>array()); - if(!$source_node) return $output; - - $oMenuAdminModel = &getAdminModel('menu'); - - foreach($source_node as $menu_item_srl => $node) { - // 자식 노드가 있으면 자식 노드의 데이터를 먼저 얻어옴 - if($menu_item_srl&&$tree[$menu_item_srl]) $child_output = $this->getPhpCacheCode($tree[$menu_item_srl], $tree, $site_srl, $domain); - else $child_output = array("buff"=>"", "url_list"=>array()); - - // 변수 정리 - $names = $oMenuAdminModel->getMenuItemNames($node->name, $site_srl); - foreach($names as $key => $val) { - $name_arr_str .= sprintf('"%s"=>"%s",',$key, str_replace(array('\\','"'),array('\\\\','"'),$val)); - } - $name_str = sprintf('$_menu_names[%d] = array(%s); %s', $node->menu_item_srl, $name_arr_str, $child_output['name']); - - // 현재 노드의 url값이 공란이 아니라면 url_list 배열값에 입력 - if($node->url) $child_output['url_list'][] = $node->url; - $output['url_list'] = array_merge($output['url_list'], $child_output['url_list']); - - // node->group_srls값이 있으면 - if($node->group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls); - else $group_check_code = "true"; - - // 변수 정리 - $href = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->href); - $url = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->url); - if(preg_match('/^([0-9a-zA-Z\_\-]+)$/i', $node->url)) { - $href = getSiteUrl($domain, '','mid',$node->url); - $pos = strpos($href, $_SERVER['HTTP_HOST']); - if($pos !== false) $href = substr($href, $pos+strlen($_SERVER['HTTP_HOST'])); - } else $href = $url; - $open_window = $node->open_window; - $normal_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->normal_btn); - $hover_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->hover_btn); - $active_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->active_btn); - $selected = '"'.implode('","',$child_output['url_list']).'"'; - $child_buff = $child_output['buff']; - $expand = $node->expand; - - $normal_btn = $node->normal_btn; - if($normal_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$normal_btn)) $normal_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$normal_btn); - else $normal_btn = ''; - - $hover_btn = $node->hover_btn; - if($hover_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$hover_btn)) $hover_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$hover_btn); - else $hover_btn = ''; - - $active_btn = $node->active_btn; - if($active_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$active_btn)) $active_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$active_btn); - else $active_btn = ''; - - $group_srls = $node->group_srls; - - if($normal_btn) { - if(preg_match('/\.png$/',$normal_btn)) $classname = 'class=\"iePngFix\"'; - else $classname = ''; - if($hover_btn) $hover_str = sprintf('onmouseover=\"this.src=\'%s\'\"', $hover_btn); else $hover_str = ''; - if($active_btn) $active_str = sprintf('onmousedown=\"this.src=\'%s\'\"', $active_btn); else $active_str = ''; - $link = sprintf('"\"".$_menu_names[%d][$lang_type]."\""', $normal_btn, $normal_btn, $node->menu_item_srl, $hover_str, $active_str, $classname); - if($active_btn) $link_active = sprintf('"\"".$_menu_names[%d][$lang_type]."\""', $active_btn, $node->menu_item_srl, $classname); - else $link_active = $link; - } else { - $link_active = $link = sprintf('$_menu_names[%d][$lang_type]', $node->menu_item_srl); - } - - // 속성을 생성한다 ( url_list를 이용해서 선택된 메뉴의 노드에 속하는지를 검사한다. 꽁수지만 빠르고 강력하다고 생각;;) - $attribute = sprintf( - '"node_srl"=>"%s","parent_srl"=>"%s","text"=>(%s?$_menu_names[%d][$lang_type]:""),"href"=>(%s?"%s":""),"url"=>(%s?"%s":""),"open_window"=>"%s","normal_btn"=>"%s","hover_btn"=>"%s","active_btn"=>"%s","selected"=>(array(%s)&&in_array(Context::get("mid"),array(%s))?1:0),"expand"=>"%s", "list"=>array(%s), "link"=>(%s? ( array(%s)&&in_array(Context::get("mid"),array(%s)) ?%s:%s):""),', - $node->menu_item_srl, - $node->parent_srl, - $group_check_code, - $node->menu_item_srl, - $group_check_code, - $href, - $group_check_code, - $url, - $open_window, - $normal_btn, - $hover_btn, - $active_btn, - $selected, - $selected, - $expand, - $child_buff, - $group_check_code, - $selected, - $selected, - $link_active, - $link - ); - - // buff 데이터를 생성한다 - $output['buff'] .= sprintf('%s=>array(%s),', $node->menu_item_srl, $attribute); - $output['name'] .= $name_str; - } - return $output; - } - - /** - * @brief 메뉴와 레이아웃 매핑 - * 레이아웃에서 메뉴를 지정할때 지정된 메뉴의 기본 레이아웃을 매핑 - **/ - function updateMenuLayout($layout_srl, $menu_srl_list) { - if(!count($menu_srl_list)) return; - - // 일단 menu_srls의 값을 지움 - $args->menu_srls = implode(',',$menu_srl_list); - $output = executeQuery('menu.deleteMenuLayout', $args); - if(!$output->toBool()) return $output; - - $args->layout_srl = $layout_srl; - - // menu_srls, layout_srl 매핑 - for($i=0;$imenu_srl = $menu_srl_list[$i]; - $output = executeQuery('menu.insertMenuLayout', $args); - if(!$output->toBool()) return $output; - } - } - - } -?> +site_srl = (int)$site_module_info->site_srl; + $args->title = Context::get('title'); + $args->menu_srl = getNextSequence(); + $args->listorder = $args->menu_srl * -1; + + $output = executeQuery('menu.insertMenu', $args); + if(!$output->toBool()) return $output; + + $this->add('menu_srl', $args->menu_srl); + $this->setMessage('success_registed'); + } + + /** + * @brief 메뉴 제목 변경 + **/ + function procMenuAdminUpdate() { + // 입력할 변수 정리 + $args->title = Context::get('title'); + $args->menu_srl = Context::get('menu_srl'); + + $output = executeQuery('menu.updateMenu', $args); + if(!$output->toBool()) return $output; + + $this->setMessage('success_registed'); + } + + /** + * @brief 메뉴 삭제 + * menu_item과 xml 캐시 파일 모두 삭제 + **/ + function procMenuAdminDelete() { + $menu_srl = Context::get('menu_srl'); + return $this->deleteMenu($menu_srl); + } + + function deleteMenu($menu_srl) { + // 캐시 파일 삭제 + $cache_list = FileHandler::readDir("./files/cache/menu","",false,true); + if(count($cache_list)) { + foreach($cache_list as $cache_file) { + $pos = strpos($cache_file, $menu_srl.'_'); + if($pos>0)FileHandler::removeFile($cache_file); + } + } + + // 이미지 버튼 모두 삭제 + $image_path = sprintf('./files/attach/menu_button/%s', $menu_srl); + FileHandler::removeDir($image_path); + + $args->menu_srl = $menu_srl; + + // 메뉴 메뉴 삭제 + $output = executeQuery("menu.deleteMenuItems", $args); + if(!$output->toBool()) return $output; + + // 메뉴 삭제 + $output = executeQuery("menu.deleteMenu", $args); + if(!$output->toBool()) return $output; + + return new Object(0,'success_deleted'); + } + + /** + * @brief 메뉴에 아이템 추가 + **/ + function procMenuAdminInsertItem() { + // 입력할 변수 정리 + $source_args = Context::getRequestVars(); + unset($source_args->module); + unset($source_args->act); + if($source_args->menu_open_window!="Y") $source_args->menu_open_window = "N"; + if($source_args->menu_expand !="Y") $source_args->menu_expand = "N"; + $source_args->group_srls = str_replace('|@|',',',$source_args->group_srls); + $source_args->parent_srl = (int)$source_args->parent_srl; + + // 변수를 다시 정리 (form문의 column과 DB column이 달라서) + $args->menu_srl = $source_args->menu_srl; + $args->menu_item_srl = $source_args->menu_item_srl; + $args->parent_srl = $source_args->parent_srl; + $args->menu_srl = $source_args->menu_srl; + $args->menu_id = $source_args->menu_id; + $args->name = $source_args->menu_name; + $args->url = trim($source_args->menu_url); + $args->open_window = $source_args->menu_open_window; + $args->expand = $source_args->menu_expand; + $args->normal_btn = $source_args->normal_btn; + $args->hover_btn = $source_args->hover_btn; + $args->active_btn = $source_args->active_btn; + $args->group_srls = $source_args->group_srls; + + // 이미 존재하는지를 확인 + $oMenuModel = &getAdminModel('menu'); + $item_info = $oMenuModel->getMenuItemInfo($args->menu_item_srl); + + // 존재하게 되면 update를 해준다 + if($item_info->menu_item_srl == $args->menu_item_srl) { + $output = executeQuery('menu.updateMenuItem', $args); + if(!$output->toBool()) return $output; + + // 존재하지 않으면 insert를 해준다 + } else { + $args->listorder = -1*$args->menu_item_srl; + $output = executeQuery('menu.insertMenuItem', $args); + if(!$output->toBool()) return $output; + } + + // 해당 메뉴의 정보를 구함 + $menu_info = $oMenuModel->getMenu($args->menu_srl); + $menu_title = $menu_info->title; + + // XML 파일을 갱신하고 위치을 넘겨 받음 + $xml_file = $this->makeXmlFile($args->menu_srl); + + // url이 mid일 경우 기록 남김 + if(preg_match('/^([a-zA-Z0-9\_\-]+)$/', $args->url)) { + $mid = $args->url; + + $mid_args->menu_srl = $args->menu_srl; + $mid_args->mid = $mid; + + // menu_srl에 해당하는 레이아웃 값을 구함 + $output = executeQuery('menu.getMenuLayout', $args); + + // 해당 모듈에 레이아웃 값이 정해져 있지 않으면 지정 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByMid($mid); + if(!$module_info->layout_srl&&$output->data->layout_srl) $mid_args->layout_srl = $output->data->layout_srl; + + // 해당 mid의 메뉴값을 선택된 메뉴로 변경 + $oModuleController = &getController('module'); + $oModuleController->updateModuleMenu($mid_args); + } + + $this->add('xml_file', $xml_file); + $this->add('menu_srl', $args->menu_srl); + $this->add('menu_item_srl', $args->menu_item_srl); + $this->add('menu_title', $menu_title); + $this->add('parent_srl', $args->parent_srl); + } + + /** + * @brief 메뉴 메뉴 삭제 + **/ + function procMenuAdminDeleteItem() { + // 변수 정리 + $args = Context::gets('menu_srl','menu_item_srl'); + + $oMenuAdminModel = &getAdminModel('menu'); + + // 원정보를 가져옴 + $item_info = $oMenuAdminModel->getMenuItemInfo($args->menu_item_srl); + if($item_info->parent_srl) $parent_srl = $item_info->parent_srl; + + // 자식 노드가 있는지 체크하여 있으면 삭제 못한다는 에러 출력 + $output = executeQuery('menu.getChildMenuCount', $args); + if(!$output->toBool()) return $output; + if($output->data->count>0) return new Object(-1, 'msg_cannot_delete_for_child'); + + // DB에서 삭제 + $output = executeQuery("menu.deleteMenuItem", $args); + if(!$output->toBool()) return $output; + + // 해당 메뉴의 정보를 구함 + $menu_info = $oMenuAdminModel->getMenu($args->menu_srl); + $menu_title = $menu_info->title; + + // XML 파일을 갱신하고 위치을 넘겨 받음 + $xml_file = $this->makeXmlFile($args->menu_srl); + + // 이미지 버튼 모두 삭제 + if($item_info->normal_btn) FileHandler::removeFile($item_info->normal_btn); + if($item_info->hover_btn) FileHandler::removeFile($item_info->hover_btn); + if($item_info->active_btn) FileHandler::removeFile($item_info->active_btn); + + $this->add('xml_file', $xml_file); + $this->add('menu_title', $menu_title); + $this->add('menu_item_srl', $parent_srl); + $this->setMessage('success_deleted'); + } + + /** + * @brief 메뉴의 메뉴를 이동 + **/ + function procMenuAdminMoveItem() { + $menu_srl = Context::get('menu_srl'); + $mode = Context::get('mode'); + $parent_srl = Context::get('parent_srl'); + $source_srl = Context::get('source_srl'); + $target_srl = Context::get('target_srl'); + + if(!$menu_srl || !$mode || !$target_srl) return new Object(-1,'msg_invalid_request'); + $this->moveMenuItem($menu_srl,$parent_srl,$source_srl,$target_srl,$mode); + } + + function moveMenuItem($menu_srl,$parent_srl,$source_srl,$target_srl,$mode){ + // 원본 메뉴들을 구함 + $oMenuAdminModel = &getAdminModel('menu'); + + $target_item = $oMenuAdminModel->getMenuItemInfo($target_srl); + if($target_item->menu_item_srl != $target_srl) return new Object(-1,'msg_invalid_request'); + + // 위치 이동 (순서 조절) + if($mode == 'move') { + $args->parent_srl = $parent_srl; + $args->menu_srl = $menu_srl; + + if($source_srl) { + $source_item = $oMenuAdminModel->getMenuItemInfo($source_srl); + if($source_item->menu_item_srl != $source_srl) return new Object(-1,'msg_invalid_request'); + $args->listorder = $source_item->listorder-1; + } else { + $output = executeQuery('menu.getMaxListorder', $args); + if(!$output->toBool()) return $output; + $args->listorder = (int)$output->data->listorder; + if(!$args->listorder) $args->listorder= 0; + } + $args->parent_srl = $parent_srl; + $output = executeQuery('menu.updateMenuItemListorder', $args); + if(!$output->toBool()) return $output; + + $args->parent_srl = $parent_srl; + $args->menu_item_srl = $target_srl; + $output = executeQuery('menu.updateMenuItemNode', $args); + if(!$output->toBool()) return $output; + // 자식으로 추가 + } elseif($mode == 'insert') { + $args->menu_item_srl = $target_srl; + $args->parent_srl = $parent_srl; + $args->listorder = -1*getNextSequence(); + $output = executeQuery('menu.updateMenuItemNode', $args); + if(!$output->toBool()) return $output; + } + + $xml_file = $this->makeXmlFile($menu_srl); + return $xml_file; + } + + /** + * @brief xml 파일을 갱신 + * 관리자페이지에서 메뉴 구성 후 간혹 xml파일이 재생성 안되는 경우가 있는데\n + * 이럴 경우 관리자의 수동 갱신 기능을 구현해줌\n + * 개발 중간의 문제인 것 같고 현재는 문제가 생기지 않으나 굳이 없앨 필요 없는 기능 + **/ + function procMenuAdminMakeXmlFile() { + // 입력값을 체크 + $menu_srl = Context::get('menu_srl'); + + // 해당 메뉴의 정보를 구함 + $oMenuAdminModel = &getAdminModel('menu'); + $menu_info = $oMenuAdminModel->getMenu($menu_srl); + $menu_title = $menu_info->title; + + // xml파일 재생성 + $xml_file = $this->makeXmlFile($menu_srl); + + // return 값 설정 + $this->add('menu_title',$menu_title); + $this->add('xml_file',$xml_file); + } + + /** + * @brief 메뉴 이미지 버튼을 등록 + **/ + function procMenuAdminUploadButton() { + $menu_srl = Context::get('menu_srl'); + $menu_item_srl = Context::get('menu_item_srl'); + $target = Context::get('target'); + $target_file = Context::get($target); + + // 필수 요건이 없거나 업로드된 파일이 아니면 오류 발생 + if(!$menu_srl || !$menu_item_srl || !$target_file || !is_uploaded_file($target_file['tmp_name']) || !preg_match('/\.(gif|jpeg|jpg|png)/i',$target_file['name'])) { + Context::set('error_messge', Context::getLang('msg_invalid_request')); + + // 요건을 만족하고 업로드된 파일이면 지정된 위치로 이동 + } else { + $tmp_arr = explode('.',$target_file['name']); + $ext = $tmp_arr[count($tmp_arr)-1]; + + $path = sprintf('./files/attach/menu_button/%d/', $menu_srl); + $filename = sprintf('%s%d.%s.%s', $path, $menu_item_srl, $target, $ext); + + if(!is_dir($path)) FileHandler::makeDir($path); + + move_uploaded_file($target_file['tmp_name'], $filename); + Context::set('filename', $filename); + } + + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('menu_file_uploaded'); + } + + /** + * @brief 등록된 메뉴 이미지 제거 + **/ + function procMenuAdminDeleteButton() { + $menu_srl = Context::get('menu_srl'); + $menu_item_srl = Context::get('menu_item_srl'); + $target = Context::get('target'); + $filename = Context::get('filename'); + FileHandler::removeFile($filename); + + $this->add('target', $target); + } + + /** + * @brief 메뉴의 xml 파일을 만들고 위치를 return + **/ + function makeXmlFile($menu_srl) { + // xml파일 생성시 필요한 정보가 없으면 그냥 return + if(!$menu_srl) return; + + // 메뉴 정보를 구함 + $args->menu_srl = $menu_srl; + $output = executeQuery('menu.getMenu', $args); + if(!$output->toBool() || !$output->data) return $output; + $site_srl = (int)$output->data->site_srl; + + if($site_srl) { + $oModuleModel = &getModel('module'); + $site_info = $oModuleModel->getSiteInfo($site_srl); + $domain = $site_info->domain; + } + + // DB에서 menu_srl에 해당하는 메뉴 아이템 목록을 listorder순으로 구해옴 + $args->menu_srl = $menu_srl; + $args->sort_index = 'listorder'; + $output = executeQuery('menu.getMenuItems', $args); + if(!$output->toBool()) return; + + // 캐시 파일의 이름을 지정 + $xml_file = sprintf("./files/cache/menu/%s.xml.php", $menu_srl); + $php_file = sprintf("./files/cache/menu/%s.php", $menu_srl); + + // 구해온 데이터가 없다면 노드데이터가 없는 xml 파일만 생성 + $list = $output->data; + if(!$list) { + $xml_buff = ""; + FileHandler::writeFile($xml_file, $xml_buff); + FileHandler::writeFile($php_file, ''); + return $xml_file; + } + + // 구해온 데이터가 하나라면 array로 바꾸어줌 + if(!is_array($list)) $list = array($list); + + // 루프를 돌면서 tree 구성 + $list_count = count($list); + for($i=0;$i<$list_count;$i++) { + $node = $list[$i]; + $menu_item_srl = $node->menu_item_srl; + $parent_srl = $node->parent_srl; + + $tree[$parent_srl][$menu_item_srl] = $node; + } + + // 캐시 파일의 권한과 그룹 설정을 위한 공통 헤더 + $header_script = + '$lang_type = Context::getLangType(); '. + '$is_logged = Context::get(\'is_logged\'); '. + '$logged_info = Context::get(\'logged_info\'); '. + '$site_srl = '.$site_srl.';'. + '$site_admin = false;'. + 'if($site_srl) { '. + '$oModuleModel = &getModel(\'module\');'. + '$site_module_info = $oModuleModel->getSiteInfo($site_srl); '. + 'Context::set(\'site_module_info\',$site_module_info);'. + '$grant = $oModuleModel->getGrant($site_module_info, $logged_info); '. + 'if($grant->manager ==1) $site_admin = true;'. + '}'. + 'if($is_logged) {'. + 'if($logged_info->is_admin=="Y" || $site_admin) $is_admin = true; '. + 'else $is_admin = false; '. + '$group_srls = array_keys($logged_info->group_list); '. + '} else { '. + '$is_admin = false; '. + '$group_srsl = array(); '. + '} '; + + // xml 캐시 파일 생성 (xml캐시는 따로 동작하기에 session 지정을 해주어야 함) + $xml_buff = sprintf( + 'init(); '. + 'header("Content-Type: text/xml; charset=UTF-8"); '. + 'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '. + 'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '. + 'header("Cache-Control: no-store, no-cache, must-revalidate"); '. + 'header("Cache-Control: post-check=0, pre-check=0", false); '. + 'header("Pragma: no-cache"); '. + '%s '. + '$oContext->close(); '. + '?>'. + '%s', + $header_script, + $this->getXmlTree($tree[0], $tree, $site_srl, $domain) + ); + + // php 캐시 파일 생성 + $php_output = $this->getPhpCacheCode($tree[0], $tree, $site_srl, $domain); + $php_buff = sprintf( + 'list = array(%s); '. + '?>', + $header_script, + $php_output['name'], + $php_output['buff'] + ); + + // 파일 저장 + FileHandler::writeFile($xml_file, $xml_buff); + FileHandler::writeFile($php_file, $php_buff); + return $xml_file; + } + + /** + * @brief array로 정렬된 노드들을 parent_srl을 참조하면서 recursive하게 돌면서 xml 데이터 생성 + * 메뉴 xml파일은 node라는 tag가 중첩으로 사용되며 이 xml doc으로 관리자 페이지에서 메뉴를 구성해줌\n + * (tree_menu.js 에서 xml파일을 바로 읽고 tree menu를 구현) + **/ + function getXmlTree($source_node, $tree, $site_srl, $domain) { + if(!$source_node) return; + + $oMenuAdminModel = &getAdminModel('menu'); + + foreach($source_node as $menu_item_srl => $node) { + $child_buff = ""; + + // 자식 노드의 데이터 가져옴 + if($menu_item_srl&&$tree[$menu_item_srl]) $child_buff = $this->getXmlTree($tree[$menu_item_srl], $tree, $site_srl, $domain); + + // 변수 정리 + $names = $oMenuAdminModel->getMenuItemNames($node->name, $site_srl); + foreach($names as $key => $val) { + $name_arr_str .= sprintf('"%s"=>"%s",',$key, str_replace('\\','\\\\',htmlspecialchars($val))); + } + $name_str = sprintf('$_names = array(%s); print $_names[$lang_type];', $name_arr_str); + + $url = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->url); + if(preg_match('/^([0-9a-zA-Z\_\-]+)$/', $node->url)) { + $href = getSiteUrl($domain, '','mid',$node->url); + $pos = strpos($href, $_SERVER['HTTP_HOST']); + if($pos !== false) $href = substr($href, $pos+strlen($_SERVER['HTTP_HOST'])); + } else $href = $url; + $open_window = $node->open_window; + $expand = $node->expand; + + $normal_btn = $node->normal_btn; + if($normal_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$normal_btn)) $normal_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$normal_btn); + else $normal_btn = ''; + $hover_btn = $node->hover_btn; + if($hover_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$hover_btn)) $hover_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$hover_btn); + else $hover_btn = ''; + $active_btn = $node->active_btn; + if($active_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$active_btn)) $active_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$active_btn); + else $active_btn = ''; + + $group_srls = $node->group_srls; + + if($normal_btn) { + if(preg_match('/\.png$/',$normal_btn)) $classname = 'class="iePngFix"'; + else $classname = ''; + if($hover_btn) $hover_str = sprintf('onmouseover="this.src=\'%s\'"', $hover_btn); else $hover_str = ''; + if($active_btn) $active_str = sprintf('onmousedown="this.src=\'%s\'"', $active_btn); else $active_str = ''; + $link = sprintf('<img src="%s" onmouseout="this.src=\'%s\'" alt="" %s %s %s />', $normal_btn, $normal_btn, $hover_str, $active_str, $classname); + } else { + $link = ''; + } + + // node->group_srls값이 있으면 + if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls); + else $group_check_code = "true"; + $attribute = sprintf( + 'node_srl="%s" parent_srl="%s" text="" url="" href="" open_window="%s" expand="%s" normal_btn="%s" hover_btn="%s" active_btn="%s" link="%s"', + $menu_item_srl, + $node->parent_srl, + $group_check_code, + $name_str, + $group_check_code, + $url, + $group_check_code, + $href, + $open_window, + $expand, + $normal_btn, + $hover_btn, + $active_btn, + $group_check_code, + $link + ); + + if($child_buff) $buff .= sprintf('%s', $attribute, $child_buff); + else $buff .= sprintf('', $attribute); + } + return $buff; + } + + /** + * @brief array로 정렬된 노드들을 php code로 변경하여 return + * 메뉴에서 메뉴를 tpl에 사용시 xml데이터를 사용할 수도 있지만 별도의 javascript 사용이 필요하기에 + * php로 된 캐시파일을 만들어서 db이용없이 바로 메뉴 정보를 구할 수 있도록 한다 + * 이 캐시는 ModuleHandler::displayContent() 에서 include하여 Context::set() 한다 + **/ + function getPhpCacheCode($source_node, $tree, $site_srl, $domain) { + $output = array("buff"=>"", "url_list"=>array()); + if(!$source_node) return $output; + + $oMenuAdminModel = &getAdminModel('menu'); + + foreach($source_node as $menu_item_srl => $node) { + // 자식 노드가 있으면 자식 노드의 데이터를 먼저 얻어옴 + if($menu_item_srl&&$tree[$menu_item_srl]) $child_output = $this->getPhpCacheCode($tree[$menu_item_srl], $tree, $site_srl, $domain); + else $child_output = array("buff"=>"", "url_list"=>array()); + + // 변수 정리 + $names = $oMenuAdminModel->getMenuItemNames($node->name, $site_srl); + foreach($names as $key => $val) { + $name_arr_str .= sprintf('"%s"=>"%s",',$key, str_replace(array('\\','"'),array('\\\\','"'),$val)); + } + $name_str = sprintf('$_menu_names[%d] = array(%s); %s', $node->menu_item_srl, $name_arr_str, $child_output['name']); + + // 현재 노드의 url값이 공란이 아니라면 url_list 배열값에 입력 + if($node->url) $child_output['url_list'][] = $node->url; + $output['url_list'] = array_merge($output['url_list'], $child_output['url_list']); + + // node->group_srls값이 있으면 + if($node->group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls); + else $group_check_code = "true"; + + // 변수 정리 + $href = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->href); + $url = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->url); + if(preg_match('/^([0-9a-zA-Z\_\-]+)$/i', $node->url)) { + $href = getSiteUrl($domain, '','mid',$node->url); + $pos = strpos($href, $_SERVER['HTTP_HOST']); + if($pos !== false) $href = substr($href, $pos+strlen($_SERVER['HTTP_HOST'])); + } else $href = $url; + $open_window = $node->open_window; + $normal_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->normal_btn); + $hover_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->hover_btn); + $active_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$node->active_btn); + $selected = '"'.implode('","',$child_output['url_list']).'"'; + $child_buff = $child_output['buff']; + $expand = $node->expand; + + $normal_btn = $node->normal_btn; + if($normal_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$normal_btn)) $normal_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$normal_btn); + else $normal_btn = ''; + + $hover_btn = $node->hover_btn; + if($hover_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$hover_btn)) $hover_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$hover_btn); + else $hover_btn = ''; + + $active_btn = $node->active_btn; + if($active_btn && preg_match('/^\.\/files\/attach\/menu_button/i',$active_btn)) $active_btn = str_replace(array('&','"','<','>'),array('&','"','<','>'),$active_btn); + else $active_btn = ''; + + $group_srls = $node->group_srls; + + if($normal_btn) { + if(preg_match('/\.png$/',$normal_btn)) $classname = 'class=\"iePngFix\"'; + else $classname = ''; + if($hover_btn) $hover_str = sprintf('onmouseover=\"this.src=\'%s\'\"', $hover_btn); else $hover_str = ''; + if($active_btn) $active_str = sprintf('onmousedown=\"this.src=\'%s\'\"', $active_btn); else $active_str = ''; + $link = sprintf('"\"".$_menu_names[%d][$lang_type]."\""', $normal_btn, $normal_btn, $node->menu_item_srl, $hover_str, $active_str, $classname); + if($active_btn) $link_active = sprintf('"\"".$_menu_names[%d][$lang_type]."\""', $active_btn, $node->menu_item_srl, $classname); + else $link_active = $link; + } else { + $link_active = $link = sprintf('$_menu_names[%d][$lang_type]', $node->menu_item_srl); + } + + // 속성을 생성한다 ( url_list를 이용해서 선택된 메뉴의 노드에 속하는지를 검사한다. 꽁수지만 빠르고 강력하다고 생각;;) + $attribute = sprintf( + '"node_srl"=>"%s","parent_srl"=>"%s","text"=>(%s?$_menu_names[%d][$lang_type]:""),"href"=>(%s?"%s":""),"url"=>(%s?"%s":""),"open_window"=>"%s","normal_btn"=>"%s","hover_btn"=>"%s","active_btn"=>"%s","selected"=>(array(%s)&&in_array(Context::get("mid"),array(%s))?1:0),"expand"=>"%s", "list"=>array(%s), "link"=>(%s? ( array(%s)&&in_array(Context::get("mid"),array(%s)) ?%s:%s):""),', + $node->menu_item_srl, + $node->parent_srl, + $group_check_code, + $node->menu_item_srl, + $group_check_code, + $href, + $group_check_code, + $url, + $open_window, + $normal_btn, + $hover_btn, + $active_btn, + $selected, + $selected, + $expand, + $child_buff, + $group_check_code, + $selected, + $selected, + $link_active, + $link + ); + + // buff 데이터를 생성한다 + $output['buff'] .= sprintf('%s=>array(%s),', $node->menu_item_srl, $attribute); + $output['name'] .= $name_str; + } + return $output; + } + + /** + * @brief 메뉴와 레이아웃 매핑 + * 레이아웃에서 메뉴를 지정할때 지정된 메뉴의 기본 레이아웃을 매핑 + **/ + function updateMenuLayout($layout_srl, $menu_srl_list) { + if(!count($menu_srl_list)) return; + + // 일단 menu_srls의 값을 지움 + $args->menu_srls = implode(',',$menu_srl_list); + $output = executeQuery('menu.deleteMenuLayout', $args); + if(!$output->toBool()) return $output; + + $args->layout_srl = $layout_srl; + + // menu_srls, layout_srl 매핑 + for($i=0;$imenu_srl = $menu_srl_list[$i]; + $output = executeQuery('menu.insertMenuLayout', $args); + if(!$output->toBool()) return $output; + } + } + + } +?> diff --git a/modules/menu/menu.admin.model.php b/modules/menu/menu.admin.model.php index e5d3ebb08..a1714ef4c 100644 --- a/modules/menu/menu.admin.model.php +++ b/modules/menu/menu.admin.model.php @@ -1,154 +1,154 @@ -site_srl) { - $site_module_info = Context::get('site_module_info'); - $obj->site_srl = (int)$site_module_info->site_srl; - } - $args->site_srl = $obj->site_srl; - $args->sort_index = $obj->sort_index; - $args->page = $obj->page?$obj->page:1; - $args->list_count = $obj->list_count?$obj->list_count:20; - $args->page_count = $obj->page_count?$obj->page_count:10; - - // document.getDocumentList 쿼리 실행 - $output = executeQuery('menu.getMenuList', $args); - - // 결과가 없거나 오류 발생시 그냥 return - if(!$output->toBool()||!count($output->data)) return $output; - - return $output; - } - - /** - * @brief 등록된 모든 메뉴를 return - **/ - function getMenus($site_srl = null) { - if(!isset($site_srl)) { - $site_module_info = Context::get('site_module_info'); - $site_srl = (int)$site_module_info->site_srl; - } - // 일단 DB에서 정보를 가져옴 - $args->site_srl = $site_srl ; - $args->menu_srl = $menu_srl; - $output = executeQuery('menu.getMenus', $args); - if(!$output->data) return; - $menus = $output->data; - if(!is_array($menus)) $menus = array($menus); - return $menus; - } - - /** - * @brief DB 에 생성된 한개의 메뉴 정보를 구함 - * 생성된 메뉴의 DB정보+XML정보를 return - **/ - function getMenu($menu_srl) { - // 일단 DB에서 정보를 가져옴 - $args->menu_srl = $menu_srl; - $output = executeQuery('menu.getMenu', $args); - if(!$output->data) return; - - $menu_info = $output->data; - $menu_info->xml_file = sprintf('./files/cache/menu/%s.xml.php',$menu_srl); - $menu_info->php_file = sprintf('./files/cache/menu/%s.php',$menu_srl); - return $menu_info; - } - - /** - * @brief 특정 menu_srl의 아이템 정보를 return - * 이 정보중에 group_srls의 경우는 , 로 연결되어 들어가며 사용시에는 explode를 통해 array로 변환 시킴 - **/ - function getMenuItemInfo($menu_item_srl) { - // menu_item_srl이 있으면 해당 메뉴의 정보를 가져온다 - $args->menu_item_srl = $menu_item_srl; - $output = executeQuery('menu.getMenuItem', $args); - $node = $output->data; - if($node->group_srls) $node->group_srls = explode(',',$node->group_srls); - else $node->group_srls = array(); - - $tmp_name = unserialize($node->name); - if($tmp_name && count($tmp_name) ) { - $selected_lang = array(); - $rand_name = $tmp_name[Context::getLangType()]; - if(!$rand_name) $rand_name = array_shift($tmp_name); - $node->name = $rand_name; - } - return $node; - } - - /** - * @brief 다국어 지원을 위해 menu의 name을 언어별로 나눠서 return - */ - function getMenuItemNames($source_name, $site_srl = null) { - if(!$site_srl) { - $site_module_info = Context::get('site_module_info'); - $site_srl = (int)$site_module_info->site_srl; - } - - // 언어코드 구함 - $oModuleAdminModel = &getAdminModel('module'); - return $oModuleAdminModel->getLangCode($site_srl, $source_name); - } - - /** - * @brief 특정 menu_srl의 정보를 이용하여 템플릿을 구한후 return - * 관리자 페이지에서 특정 메뉴의 정보를 추가하기 위해 서버에서 tpl을 컴파일 한후 컴파일 된 html을 직접 return - **/ - function getMenuAdminTplInfo() { - // 해당 메뉴의 정보를 가져오기 위한 변수 설정 - $menu_item_srl = Context::get('menu_item_srl'); - $parent_srl = Context::get('parent_srl'); - - // 회원 그룹의 목록을 가져옴 - $oMemberModel = &getModel('member'); - $group_list = $oMemberModel->getGroups(); - Context::set('group_list', $group_list); - - // parent_srl이 있고 menu_item_srl이 없으면 하부 메뉴 추가임 - if(!$menu_item_srl && $parent_srl) { - // 상위 메뉴의 정보를 가져옴 - $parent_info = $this->getMenuItemInfo($parent_srl); - - // 추가하려는 메뉴의 기본 변수 설정 - $item_info->menu_item_srl = getNextSequence(); - $item_info->parent_srl = $parent_srl; - $item_info->parent_menu_name = $parent_info->name; - - // root에 메뉴 추가하거나 기존 메뉴의 수정일 경우 - } else { - // menu_item_srl 이 있으면 해당 메뉴의 정보를 가져온다 - if($menu_item_srl) $item_info = $this->getMenuItemInfo($menu_item_srl); - - // 찾아진 값이 없다면 신규 메뉴 추가로 보고 menu_item_srl값만 구해줌 - if(!$item_info->menu_item_srl) { - $item_info->menu_item_srl = getNextSequence(); - } - } - Context::set('item_info', $item_info); - - // template 파일을 직접 컴파일한후 tpl변수에 담아서 return한다. - $oTemplate = &TemplateHandler::getInstance(); - $tpl = $oTemplate->compile($this->module_path.'tpl', 'menu_item_info'); - - $this->add('tpl', str_replace("\n"," ",$tpl)); - } - - } -?> +site_srl) { + $site_module_info = Context::get('site_module_info'); + $obj->site_srl = (int)$site_module_info->site_srl; + } + $args->site_srl = $obj->site_srl; + $args->sort_index = $obj->sort_index; + $args->page = $obj->page?$obj->page:1; + $args->list_count = $obj->list_count?$obj->list_count:20; + $args->page_count = $obj->page_count?$obj->page_count:10; + + // document.getDocumentList 쿼리 실행 + $output = executeQuery('menu.getMenuList', $args); + + // 결과가 없거나 오류 발생시 그냥 return + if(!$output->toBool()||!count($output->data)) return $output; + + return $output; + } + + /** + * @brief 등록된 모든 메뉴를 return + **/ + function getMenus($site_srl = null) { + if(!isset($site_srl)) { + $site_module_info = Context::get('site_module_info'); + $site_srl = (int)$site_module_info->site_srl; + } + // 일단 DB에서 정보를 가져옴 + $args->site_srl = $site_srl ; + $args->menu_srl = $menu_srl; + $output = executeQuery('menu.getMenus', $args); + if(!$output->data) return; + $menus = $output->data; + if(!is_array($menus)) $menus = array($menus); + return $menus; + } + + /** + * @brief DB 에 생성된 한개의 메뉴 정보를 구함 + * 생성된 메뉴의 DB정보+XML정보를 return + **/ + function getMenu($menu_srl) { + // 일단 DB에서 정보를 가져옴 + $args->menu_srl = $menu_srl; + $output = executeQuery('menu.getMenu', $args); + if(!$output->data) return; + + $menu_info = $output->data; + $menu_info->xml_file = sprintf('./files/cache/menu/%s.xml.php',$menu_srl); + $menu_info->php_file = sprintf('./files/cache/menu/%s.php',$menu_srl); + return $menu_info; + } + + /** + * @brief 특정 menu_srl의 아이템 정보를 return + * 이 정보중에 group_srls의 경우는 , 로 연결되어 들어가며 사용시에는 explode를 통해 array로 변환 시킴 + **/ + function getMenuItemInfo($menu_item_srl) { + // menu_item_srl이 있으면 해당 메뉴의 정보를 가져온다 + $args->menu_item_srl = $menu_item_srl; + $output = executeQuery('menu.getMenuItem', $args); + $node = $output->data; + if($node->group_srls) $node->group_srls = explode(',',$node->group_srls); + else $node->group_srls = array(); + + $tmp_name = unserialize($node->name); + if($tmp_name && count($tmp_name) ) { + $selected_lang = array(); + $rand_name = $tmp_name[Context::getLangType()]; + if(!$rand_name) $rand_name = array_shift($tmp_name); + $node->name = $rand_name; + } + return $node; + } + + /** + * @brief 다국어 지원을 위해 menu의 name을 언어별로 나눠서 return + */ + function getMenuItemNames($source_name, $site_srl = null) { + if(!$site_srl) { + $site_module_info = Context::get('site_module_info'); + $site_srl = (int)$site_module_info->site_srl; + } + + // 언어코드 구함 + $oModuleAdminModel = &getAdminModel('module'); + return $oModuleAdminModel->getLangCode($site_srl, $source_name); + } + + /** + * @brief 특정 menu_srl의 정보를 이용하여 템플릿을 구한후 return + * 관리자 페이지에서 특정 메뉴의 정보를 추가하기 위해 서버에서 tpl을 컴파일 한후 컴파일 된 html을 직접 return + **/ + function getMenuAdminTplInfo() { + // 해당 메뉴의 정보를 가져오기 위한 변수 설정 + $menu_item_srl = Context::get('menu_item_srl'); + $parent_srl = Context::get('parent_srl'); + + // 회원 그룹의 목록을 가져옴 + $oMemberModel = &getModel('member'); + $group_list = $oMemberModel->getGroups(); + Context::set('group_list', $group_list); + + // parent_srl이 있고 menu_item_srl이 없으면 하부 메뉴 추가임 + if(!$menu_item_srl && $parent_srl) { + // 상위 메뉴의 정보를 가져옴 + $parent_info = $this->getMenuItemInfo($parent_srl); + + // 추가하려는 메뉴의 기본 변수 설정 + $item_info->menu_item_srl = getNextSequence(); + $item_info->parent_srl = $parent_srl; + $item_info->parent_menu_name = $parent_info->name; + + // root에 메뉴 추가하거나 기존 메뉴의 수정일 경우 + } else { + // menu_item_srl 이 있으면 해당 메뉴의 정보를 가져온다 + if($menu_item_srl) $item_info = $this->getMenuItemInfo($menu_item_srl); + + // 찾아진 값이 없다면 신규 메뉴 추가로 보고 menu_item_srl값만 구해줌 + if(!$item_info->menu_item_srl) { + $item_info->menu_item_srl = getNextSequence(); + } + } + Context::set('item_info', $item_info); + + // template 파일을 직접 컴파일한후 tpl변수에 담아서 return한다. + $oTemplate = &TemplateHandler::getInstance(); + $tpl = $oTemplate->compile($this->module_path.'tpl', 'menu_item_info'); + + $this->add('tpl', str_replace("\n"," ",$tpl)); + } + + } +?> diff --git a/modules/menu/menu.admin.view.php b/modules/menu/menu.admin.view.php index ca48223c0..af2e99d92 100644 --- a/modules/menu/menu.admin.view.php +++ b/modules/menu/menu.admin.view.php @@ -1,105 +1,105 @@ -setTemplatePath($this->module_path.'tpl'); - Context::addJsFile('./common/js/tree_menu.js'); - } - - /** - * @brief 메뉴 관리의 첫 페이지 - **/ - function dispMenuAdminContent() { - // 등록된 메뉴 목록을 구해옴 - $obj->page = Context::get('page'); - $obj->sort_index = 'listorder'; - $obj->list_count = 20; - $obj->page_count = 20; - - $oMenuModel = &getAdminModel('menu'); - $output = $oMenuModel->getMenuList($obj); - - Context::set('total_count', $output->total_count); - Context::set('total_page', $output->total_page); - Context::set('page', $output->page); - Context::set('menu_list', $output->data); - Context::set('page_navigation', $output->page_navigation); - - $this->setTemplateFile('index'); - } - - /** - * @brief 메뉴 등록 페이지 - **/ - function dispMenuAdminInsert() { - // 선택된 메뉴의 정보르 구해서 세팅 - $menu_srl = Context::get('menu_srl'); - - if($menu_srl) { - // 메뉴의 정보를 가져옴 - $oMenuModel = &getAdminModel('menu'); - $menu_info = $oMenuModel->getMenu($menu_srl); - if($menu_info->menu_srl == $menu_srl) Context::set('menu_info', $menu_info); - } - - $this->setTemplateFile('menu_insert'); - } - - /** - * @brief 메뉴 관리 페이지 - **/ - function dispMenuAdminManagement() { - // 선택된 메뉴의 정보르 구해서 세팅 - $menu_srl = Context::get('menu_srl'); - - if(!$menu_srl) return $this->dispMenuAdminContent(); - - // 메뉴의 정보를 가져옴 - $oMenuModel = &getAdminModel('menu'); - $menu_info = $oMenuModel->getMenu($menu_srl); - if($menu_info->menu_srl != $menu_srl) return $this->dispMenuAdminContent(); - - Context::set('menu_info', $menu_info); - - // 레이아웃을 팝업으로 지정 - $this->setTemplateFile('menu_management'); - } - - - /** - * @brief 메뉴에서 선택할 수 있는 mid목록을 보여줌 - **/ - function dispMenuAdminMidList() { - $oModuleModel = &getModel('module'); - - // 모듈 카테고리 목록을 구함 - $module_category = $oModuleModel->getModuleCategories(); - Context::set('module_category', $module_category); - - // 모듈 목록을 구함 - $module_list = $oModuleModel->getModuleList(); - Context::set('module_list', $module_list); - - // mid 목록을 구해옴 - $args->module_category_srl = Context::get('module_category_srl'); - $args->module = Context::get('target_module'); - $mid_list = $oModuleModel->getMidList($args); - Context::set('mid_list', $mid_list); - - // 메뉴을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('mid_list'); - } - } -?> +setTemplatePath($this->module_path.'tpl'); + Context::addJsFile('./common/js/tree_menu.js'); + } + + /** + * @brief 메뉴 관리의 첫 페이지 + **/ + function dispMenuAdminContent() { + // 등록된 메뉴 목록을 구해옴 + $obj->page = Context::get('page'); + $obj->sort_index = 'listorder'; + $obj->list_count = 20; + $obj->page_count = 20; + + $oMenuModel = &getAdminModel('menu'); + $output = $oMenuModel->getMenuList($obj); + + Context::set('total_count', $output->total_count); + Context::set('total_page', $output->total_page); + Context::set('page', $output->page); + Context::set('menu_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('index'); + } + + /** + * @brief 메뉴 등록 페이지 + **/ + function dispMenuAdminInsert() { + // 선택된 메뉴의 정보르 구해서 세팅 + $menu_srl = Context::get('menu_srl'); + + if($menu_srl) { + // 메뉴의 정보를 가져옴 + $oMenuModel = &getAdminModel('menu'); + $menu_info = $oMenuModel->getMenu($menu_srl); + if($menu_info->menu_srl == $menu_srl) Context::set('menu_info', $menu_info); + } + + $this->setTemplateFile('menu_insert'); + } + + /** + * @brief 메뉴 관리 페이지 + **/ + function dispMenuAdminManagement() { + // 선택된 메뉴의 정보르 구해서 세팅 + $menu_srl = Context::get('menu_srl'); + + if(!$menu_srl) return $this->dispMenuAdminContent(); + + // 메뉴의 정보를 가져옴 + $oMenuModel = &getAdminModel('menu'); + $menu_info = $oMenuModel->getMenu($menu_srl); + if($menu_info->menu_srl != $menu_srl) return $this->dispMenuAdminContent(); + + Context::set('menu_info', $menu_info); + + // 레이아웃을 팝업으로 지정 + $this->setTemplateFile('menu_management'); + } + + + /** + * @brief 메뉴에서 선택할 수 있는 mid목록을 보여줌 + **/ + function dispMenuAdminMidList() { + $oModuleModel = &getModel('module'); + + // 모듈 카테고리 목록을 구함 + $module_category = $oModuleModel->getModuleCategories(); + Context::set('module_category', $module_category); + + // 모듈 목록을 구함 + $module_list = $oModuleModel->getModuleList(); + Context::set('module_list', $module_list); + + // mid 목록을 구해옴 + $args->module_category_srl = Context::get('module_category_srl'); + $args->module = Context::get('target_module'); + $mid_list = $oModuleModel->getMidList($args); + Context::set('mid_list', $mid_list); + + // 메뉴을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('mid_list'); + } + } +?> diff --git a/modules/menu/menu.class.php b/modules/menu/menu.class.php index fdc7c46e8..4a2ba9f5c 100644 --- a/modules/menu/menu.class.php +++ b/modules/menu/menu.class.php @@ -1,67 +1,67 @@ -isColumnExists('menu', 'site_srl')) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - - // 2009. 02. 11 menu 테이블에 site_srl 추가 - if(!$oDB->isColumnExists('menu', 'site_srl')) { - $oDB->addColumn('menu','site_srl','number',11,0,true); - } - - return new Object(0, 'success_updated'); - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - // 메뉴 모듈의 캐시 파일 모두 삭제 - FileHandler::removeFilesInDir("./files/cache/menu"); - - $oMenuAdminController = &getAdminController('menu'); - - // 블로그 모듈 목록을 모두 구함 - $output = executeQueryArray("menu.getMenus"); - $list = $output->data; - if(!count($list)) return; - - // 메뉴 모듈에서 사용되는 모든 메뉴 목록을 재 생성 - foreach($list as $menu_item) { - $menu_srl = $menu_item->menu_srl; - $oMenuAdminController->makeXmlFile($menu_srl); - } - } - } -?> +isColumnExists('menu', 'site_srl')) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + + // 2009. 02. 11 menu 테이블에 site_srl 추가 + if(!$oDB->isColumnExists('menu', 'site_srl')) { + $oDB->addColumn('menu','site_srl','number',11,0,true); + } + + return new Object(0, 'success_updated'); + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + // 메뉴 모듈의 캐시 파일 모두 삭제 + FileHandler::removeFilesInDir("./files/cache/menu"); + + $oMenuAdminController = &getAdminController('menu'); + + // 블로그 모듈 목록을 모두 구함 + $output = executeQueryArray("menu.getMenus"); + $list = $output->data; + if(!count($list)) return; + + // 메뉴 모듈에서 사용되는 모든 메뉴 목록을 재 생성 + foreach($list as $menu_item) { + $menu_srl = $menu_item->menu_srl; + $oMenuAdminController->makeXmlFile($menu_srl); + } + } + } +?> diff --git a/modules/message/lang/es.lang.php b/modules/message/lang/es.lang.php index 665bc7191..5182af3c0 100644 --- a/modules/message/lang/es.lang.php +++ b/modules/message/lang/es.lang.php @@ -1,7 +1,7 @@ -mobile

{$system_message}

diff --git a/modules/module/conf/info.xml b/modules/module/conf/info.xml index 09e4d4753..ddb15cca3 100644 --- a/modules/module/conf/info.xml +++ b/modules/module/conf/info.xml @@ -1,33 +1,33 @@ - - - 모듈 - 模块列表 - モジュール - Module - Module - Módulo - Модули - 模組 - 모듈 생성 및 관리하는 모듈입니다. - 生成及管理模块的模块。 - モジュールの生成、管理するモジュールです。 - This module is for creating/managering the other modules. - Module cho phép tạo và quản lý những Module khác. - Este módulo is para crear y manejar los otros módulos. - Этот модуль служит для создания/управления другими модулями. - 用於建立與管理其他模組。 - 0.1 - 2007-02-28 - system - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 모듈 + 模块列表 + モジュール + Module + Module + Módulo + Модули + 模組 + 모듈 생성 및 관리하는 모듈입니다. + 生成及管理模块的模块。 + モジュールの生成、管理するモジュールです。 + This module is for creating/managering the other modules. + Module cho phép tạo và quản lý những Module khác. + Este módulo is para crear y manejar los otros módulos. + Этот модуль служит для создания/управления другими модулями. + 用於建立與管理其他模組。 + 0.1 + 2007-02-28 + system + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/module/lang/en.lang.php b/modules/module/lang/en.lang.php index 467471006..dfda4e598 100644 --- a/modules/module/lang/en.lang.php +++ b/modules/module/lang/en.lang.php @@ -1,99 +1,99 @@ -virtual_site = "Virtual Site"; - $lang->module_list = "Modules List"; - $lang->module_index = "Modules List"; - $lang->module_category = "Module Category"; - $lang->module_info = "Module Info"; - $lang->add_shortcut = "Add Shortcuts"; - $lang->module_action = "Actions"; - $lang->module_maker = "Module Developer"; - $lang->module_license = 'License'; - $lang->module_history = "Update history"; - $lang->category_title = "Category Title"; - $lang->header_text = 'Header Text'; - $lang->footer_text = 'Footer Text'; - $lang->use_category = 'Enable Category'; - $lang->category_title = 'Category Title'; - $lang->checked_count = 'Number of Checked Articles'; - $lang->skin_default_info = 'Default Skin Info'; - $lang->skin_author = 'Skin Developer'; - $lang->skin_license = 'License'; - $lang->skin_history = 'Update history'; - $lang->module_copy = "Duplicate Module"; - $lang->module_selector = "Module Selector"; - $lang->do_selected = "I want to"; - $lang->bundle_setup = "Bundle Setup"; - $lang->bundle_addition_setup = "Bundle Additional Setup"; - $lang->bundle_grant_setup = "Bundle Permission Setup"; - $lang->lang_code = "Language Code"; - $lang->filebox = "FileBox"; - - $lang->access_type = 'Access Type'; - $lang->access_domain = 'With Domain Name'; - $lang->access_vid = 'With Site ID'; - $lang->about_domain = "In order to create more than one virtual site, every club needs to have its own domain name.
Sub-domain (e.g., aaa.bbb.com of bbb.com) also can be used. Input the address including the path where XE is installed.
ex) www.xpressengine.com/xe"; - $lang->about_vid = 'Users can access via http://XEaddress/ID. You cannot use same site id as the existing module name(mid).
Site id should start with an alphabet character . Alphabet characters, numbers and _ can be used for the site id.'; - $lang->msg_already_registed_vid = 'Already registered site id. Please input another ID.'; - $lang->msg_already_registed_domain = "Domain name has already been used. Please input another domain name."; - - $lang->header_script = "Header Script"; - $lang->about_header_script = "You can input the html script between <header> and </header> by yourself.
You can use <script, <style or <meta tag"; - - $lang->grant_access = "Access"; - $lang->grant_manager = "Management"; - - $lang->grant_to_all = "All users"; - $lang->grant_to_login_user = "Logged users"; - $lang->grant_to_site_user = "Registered users"; - $lang->grant_to_group = "Specification group users"; - - $lang->cmd_add_shortcut = "Add Shortcut"; - $lang->cmd_install = "Install"; - $lang->cmd_update = "Update"; - $lang->cmd_manage_category = 'Manage Categories'; - $lang->cmd_manage_grant = 'Manage Permission'; - $lang->cmd_manage_skin = 'Manage Skins'; - $lang->cmd_manage_document = 'Manage Articles'; - $lang->cmd_find_module = 'Find Module'; - $lang->cmd_find_langcode = 'Find lang code'; - - $lang->msg_new_module = "Create new module"; - $lang->msg_update_module = "Modify module"; - $lang->msg_module_name_exists = "The name already exists. Please try another name."; - $lang->msg_category_is_null = 'There is no registered category.'; - $lang->msg_grant_is_null = 'There is no permission list.'; - $lang->msg_no_checked_document = 'No checked articles exist.'; - $lang->msg_move_failed = 'Failed to move'; - $lang->msg_cannot_delete_for_child = 'Cannot delete a category having child categories.'; - $lang->msg_limit_mid ="Only alphabets+[alphabets+numbers+_] can be used as module name."; - $lang->msg_extra_name_exists = 'Already registered extra variable name. Please input another name.'; - - $lang->about_browser_title = "It will be shown in the browser title. It will be also used in a RSS/Trackback."; - $lang->about_mid = "The module name will be used like http://address/?mid=ModuleName.\n(Only english alphabet + [english alphabet, numbers, and underscore(_)] are allowed. The maximum length is 40.)"; - $lang->about_default = "If checked, the default will be shown when access to the site without no mid value(mid=NoValue)."; - $lang->about_module_category = "It enables you to manage it through module category.\n The URL for the module manager is Manage module > Module category ."; - $lang->about_description= 'It is the description only for a manager.'; - $lang->about_default = 'If checked, this module will be shown when users access to the site without mid value (mid=NoValue).'; - $lang->about_header_text = 'The contents will be shown on the top of the module.(html tags available)'; - $lang->about_footer_text = 'The contents will be shown on the bottom of the module.(html tags available)'; - $lang->about_skin = 'You may choose a module skin.'; - $lang->about_use_category = 'If checked, category function will be enabled.'; - $lang->about_list_count = 'You can set the number of limit to show article in a page.(default is 20)'; - $lang->about_search_list_count = 'You may set the number of articles to be exposed when you use search or category function. (default is 20)'; - $lang->about_page_count = 'You can set the number of page link to move pages in a bottom of page.(default is 10)'; - $lang->about_admin_id = 'You can grant a manager to have all permissions to the module.'; - $lang->about_grant = 'If you disable all permissions for a specific object, members who has not logged in would get permission.'; - $lang->about_grant_deatil = 'Registered users mean users who signed-up to the virtual sites (e.g., cafeXE).'; - $lang->about_module = "XE consists of modules except basic library.\n [Module Manage] module will show all installed modules and help you to manage them."; - - $lang->about_extra_vars_default_value = 'If multiple default values are needed, you can link them with comma(,).'; - $lang->about_search_virtual_site = "Input domain of virtual sites.
To search modules of non-virtual site, search with blank"; - $lang->about_langcode = "If you want to configure seperately, use 'find language code'"; - $lang->about_file_extension= "Only %s extension(s) is available."; -?> +virtual_site = "Virtual Site"; + $lang->module_list = "Modules List"; + $lang->module_index = "Modules List"; + $lang->module_category = "Module Category"; + $lang->module_info = "Module Info"; + $lang->add_shortcut = "Add Shortcuts"; + $lang->module_action = "Actions"; + $lang->module_maker = "Module Developer"; + $lang->module_license = 'License'; + $lang->module_history = "Update history"; + $lang->category_title = "Category Title"; + $lang->header_text = 'Header Text'; + $lang->footer_text = 'Footer Text'; + $lang->use_category = 'Enable Category'; + $lang->category_title = 'Category Title'; + $lang->checked_count = 'Number of Checked Articles'; + $lang->skin_default_info = 'Default Skin Info'; + $lang->skin_author = 'Skin Developer'; + $lang->skin_license = 'License'; + $lang->skin_history = 'Update history'; + $lang->module_copy = "Duplicate Module"; + $lang->module_selector = "Module Selector"; + $lang->do_selected = "I want to"; + $lang->bundle_setup = "Bundle Setup"; + $lang->bundle_addition_setup = "Bundle Additional Setup"; + $lang->bundle_grant_setup = "Bundle Permission Setup"; + $lang->lang_code = "Language Code"; + $lang->filebox = "FileBox"; + + $lang->access_type = 'Access Type'; + $lang->access_domain = 'With Domain Name'; + $lang->access_vid = 'With Site ID'; + $lang->about_domain = "In order to create more than one virtual site, every club needs to have its own domain name.
Sub-domain (e.g., aaa.bbb.com of bbb.com) also can be used. Input the address including the path where XE is installed.
ex) www.xpressengine.com/xe"; + $lang->about_vid = 'Users can access via http://XEaddress/ID. You cannot use same site id as the existing module name(mid).
Site id should start with an alphabet character . Alphabet characters, numbers and _ can be used for the site id.'; + $lang->msg_already_registed_vid = 'Already registered site id. Please input another ID.'; + $lang->msg_already_registed_domain = "Domain name has already been used. Please input another domain name."; + + $lang->header_script = "Header Script"; + $lang->about_header_script = "You can input the html script between <header> and </header> by yourself.
You can use <script, <style or <meta tag"; + + $lang->grant_access = "Access"; + $lang->grant_manager = "Management"; + + $lang->grant_to_all = "All users"; + $lang->grant_to_login_user = "Logged users"; + $lang->grant_to_site_user = "Registered users"; + $lang->grant_to_group = "Specification group users"; + + $lang->cmd_add_shortcut = "Add Shortcut"; + $lang->cmd_install = "Install"; + $lang->cmd_update = "Update"; + $lang->cmd_manage_category = 'Manage Categories'; + $lang->cmd_manage_grant = 'Manage Permission'; + $lang->cmd_manage_skin = 'Manage Skins'; + $lang->cmd_manage_document = 'Manage Articles'; + $lang->cmd_find_module = 'Find Module'; + $lang->cmd_find_langcode = 'Find lang code'; + + $lang->msg_new_module = "Create new module"; + $lang->msg_update_module = "Modify module"; + $lang->msg_module_name_exists = "The name already exists. Please try another name."; + $lang->msg_category_is_null = 'There is no registered category.'; + $lang->msg_grant_is_null = 'There is no permission list.'; + $lang->msg_no_checked_document = 'No checked articles exist.'; + $lang->msg_move_failed = 'Failed to move'; + $lang->msg_cannot_delete_for_child = 'Cannot delete a category having child categories.'; + $lang->msg_limit_mid ="Only alphabets+[alphabets+numbers+_] can be used as module name."; + $lang->msg_extra_name_exists = 'Already registered extra variable name. Please input another name.'; + + $lang->about_browser_title = "It will be shown in the browser title. It will be also used in a RSS/Trackback."; + $lang->about_mid = "The module name will be used like http://address/?mid=ModuleName.\n(Only english alphabet + [english alphabet, numbers, and underscore(_)] are allowed. The maximum length is 40.)"; + $lang->about_default = "If checked, the default will be shown when access to the site without no mid value(mid=NoValue)."; + $lang->about_module_category = "It enables you to manage it through module category.\n The URL for the module manager is Manage module > Module category ."; + $lang->about_description= 'It is the description only for a manager.'; + $lang->about_default = 'If checked, this module will be shown when users access to the site without mid value (mid=NoValue).'; + $lang->about_header_text = 'The contents will be shown on the top of the module.(html tags available)'; + $lang->about_footer_text = 'The contents will be shown on the bottom of the module.(html tags available)'; + $lang->about_skin = 'You may choose a module skin.'; + $lang->about_use_category = 'If checked, category function will be enabled.'; + $lang->about_list_count = 'You can set the number of limit to show article in a page.(default is 20)'; + $lang->about_search_list_count = 'You may set the number of articles to be exposed when you use search or category function. (default is 20)'; + $lang->about_page_count = 'You can set the number of page link to move pages in a bottom of page.(default is 10)'; + $lang->about_admin_id = 'You can grant a manager to have all permissions to the module.'; + $lang->about_grant = 'If you disable all permissions for a specific object, members who has not logged in would get permission.'; + $lang->about_grant_deatil = 'Registered users mean users who signed-up to the virtual sites (e.g., cafeXE).'; + $lang->about_module = "XE consists of modules except basic library.\n [Module Manage] module will show all installed modules and help you to manage them."; + + $lang->about_extra_vars_default_value = 'If multiple default values are needed, you can link them with comma(,).'; + $lang->about_search_virtual_site = "Input domain of virtual sites.
To search modules of non-virtual site, search with blank"; + $lang->about_langcode = "If you want to configure seperately, use 'find language code'"; + $lang->about_file_extension= "Only %s extension(s) is available."; +?> diff --git a/modules/module/lang/es.lang.php b/modules/module/lang/es.lang.php index bbaeb3447..ad699a9a0 100644 --- a/modules/module/lang/es.lang.php +++ b/modules/module/lang/es.lang.php @@ -1,7 +1,7 @@ - * @brief Paque du langage en français pour le module de Module - **/ - - $lang->virtual_site = "Virtual Site"; - $lang->module_list = "Liste des Modules"; - $lang->module_index = "Liste des Modules"; - $lang->module_category = "Catégorie des Modules"; - $lang->module_info = "Information de Module"; - $lang->add_shortcut = "Ajouter un raccourci dans le menu pour l'administrateur"; - $lang->module_action = "Actions"; - $lang->module_maker = "Développeur du Module"; - $lang->module_license = 'Licence'; - $lang->module_history = "Histoire de Mise à Jour"; - $lang->category_title = "Titre de la Catégorie"; - $lang->header_text = 'Texte en-tête'; - $lang->footer_text = 'Text au bas de page'; - $lang->use_category = 'Utiliser catégorie'; - $lang->category_title = 'Titre de la Catégorie'; - $lang->checked_count = 'somme des Articles choisis'; - $lang->skin_default_info = 'Information fondamental de l\'habillage'; - $lang->skin_author = 'Developpeur de l\'habillage'; - $lang->skin_license = 'Licence'; - $lang->skin_history = 'Histoire des Mises à jour'; - $lang->module_copy = "Copier un Module"; - $lang->module_selector = "Module Selector"; - $lang->do_selected = "선택된 것들을..."; - $lang->bundle_setup = "일괄 기본 설정"; - $lang->bundle_addition_setup = "일괄 추가 설정"; - $lang->bundle_grant_setup = "일괄 권한 설정"; - $lang->lang_code = "언어 코드"; - $lang->filebox = "파일박스"; - - $lang->access_type = '접속 방법'; - $lang->access_domain = 'Domain 접속'; - $lang->access_vid = 'Site ID 접속'; - $lang->about_vid = '별도의 도메인이 아닌 http://XE주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다.
첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; - $lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; - $lang->msg_already_registed_domain = '이미 등록된 도메인입니다. 다른 도메인을 사용해주세요'; - - $lang->header_script = "Script en-tête"; - $lang->about_header_script = "Vous pouvez entrer un script en html par vous-même entre <header> et </header>.
Vous pouvez utiliser <script, <style ou <meta tag"; - - $lang->grant_access = "Access"; - $lang->grant_manager = "Management"; - - $lang->grant_to_all = "All users"; - $lang->grant_to_login_user = "Logged users"; - $lang->grant_to_site_user = "Joined users"; - $lang->grant_to_group = "Specification group users"; - - $lang->cmd_add_shortcut = "Ajouter un raccourci"; - $lang->cmd_install = "Installer"; - $lang->cmd_update = "Mettre à Jour"; - $lang->cmd_manage_category = 'Administrer des Catégories'; - $lang->cmd_manage_grant = 'Administrer des Permissions'; - $lang->cmd_manage_skin = 'Administrer des Habillages'; - $lang->cmd_manage_document = 'Administrer des Articles'; - $lang->cmd_find_module = '모듈 찾기'; - $lang->cmd_find_langcode = 'Find lang code'; - - $lang->msg_new_module = "Créer un module"; - $lang->msg_update_module = "Modifier un module"; - $lang->msg_module_name_exists = "Le nom existe déjà. Essayez un autre nom, S.V.P."; - $lang->msg_category_is_null = 'Il n\'y a pas de catégorie enrégistrée.'; - $lang->msg_grant_is_null = 'Il n\'y a pas de liste de permission.'; - $lang->msg_no_checked_document = 'Pas un article est choisi.'; - $lang->msg_move_failed = 'Echoué de bouger'; - $lang->msg_cannot_delete_for_child = 'On ne peut pas supprimer une catégorie qui a des catégories inférieures.'; - $lang->msg_limit_mid ='모듈이름은 영문+[영문+숫자+_] 만 가능합니다.'; - $lang->msg_extra_name_exists = '이미 존재하는 확장변수 이름입니다. 다른 이름을 입력해주세요.'; - - $lang->about_browser_title = "C'est la valeur qui se représentera dans le titre de navigateur Web. Ce sera encore utilisé dans RSS/Rétrolien."; - $lang->about_mid = "Le nom de module sera utilisé comme http://adresse/?mid=ModuleName.\n(alphabet anglais + [alphabet anglais, nombres, et soulignement(_)] sont seulement permis. The maximum length is 40.)"; - $lang->about_default = "Si c'est coché, on verra ce module quand on connecte ce site sans aucune valeur de mid(mid=Nulle Valeur)."; - $lang->about_module_category = "Ça vous permet d'administrer le module par la catégorie.\nOn peut administrer la classification des modules à Administration des modules > Catégorie des Modules ."; - $lang->about_description= 'C\'est la description pour la facilité à administrer.'; - $lang->about_default = 'Si c\'est coché, on verra ce module quand on connecte ce site sans aucune valeur de mid(mid=Nulle Valeur).'; - $lang->about_header_text = 'Ce contenu sera exposé en tête du module.(balise en html est disponible)'; - $lang->about_footer_text = 'Ce contenu sera exposé en bas du module.(balise en html est disponible)'; - $lang->about_skin = 'Vous pouvez choisir un habillage pour le module.'; - $lang->about_use_category = 'Cochez pour utiliser la fonction de catégorie, .'; - $lang->about_list_count = 'Vous pouvez configurer combien d\'articles soient exposés dans une page.(20 par défaut)'; - $lang->about_search_list_count = 'Vous pouvez configurer combien d\'articles soient exposés quand vous utilisez la fonction de recherche ou de catégorie. (20 par défaut)'; - $lang->about_page_count = 'Vous pouvez configurer combien de liens pour les Pages à Bouger en bas de chaque page.(10 par défaut)'; - $lang->about_admin_id = 'Vous pouvez désigner un directeur qui aura tous les permissions sur le module.\nVous pouvez entrer plusieurs compte en utilisant.'; - $lang->about_grant = 'Si vous ne donnez pas la permission à aucune personne, même les membres qui n\'a pas ouvert la connexion auront la permission. '; - $lang->about_grant_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; - $lang->about_module = "XE se compose des modules sauf la bibliothèque fondamental.\nLe module [Administration des Modules] montera tous les modules installés et vous aidera les administrer."; - - $lang->about_extra_vars_default_value = 'Si plusieurs valeurs sont nécessaires, vous pouvez les connecter avec la virgule(,).'; - $lang->about_search_virtual_site = "가상 사이트(카페XE등)의 도메인을 입력하신 후 검색하세요.
가상 사이트이외의 모듈은 내용을 비우고 검색하시면 됩니다. (http:// 는 제외)"; - $lang->about_langcode = "언어별로 다르게 설정하고 싶으시면 언어코드 찾기를 이용해주세요"; - $lang->about_file_extension= "%s 파일만 가능합니다."; -?> + + * @brief Paque du langage en français pour le module de Module + **/ + + $lang->virtual_site = "Virtual Site"; + $lang->module_list = "Liste des Modules"; + $lang->module_index = "Liste des Modules"; + $lang->module_category = "Catégorie des Modules"; + $lang->module_info = "Information de Module"; + $lang->add_shortcut = "Ajouter un raccourci dans le menu pour l'administrateur"; + $lang->module_action = "Actions"; + $lang->module_maker = "Développeur du Module"; + $lang->module_license = 'Licence'; + $lang->module_history = "Histoire de Mise à Jour"; + $lang->category_title = "Titre de la Catégorie"; + $lang->header_text = 'Texte en-tête'; + $lang->footer_text = 'Text au bas de page'; + $lang->use_category = 'Utiliser catégorie'; + $lang->category_title = 'Titre de la Catégorie'; + $lang->checked_count = 'somme des Articles choisis'; + $lang->skin_default_info = 'Information fondamental de l\'habillage'; + $lang->skin_author = 'Developpeur de l\'habillage'; + $lang->skin_license = 'Licence'; + $lang->skin_history = 'Histoire des Mises à jour'; + $lang->module_copy = "Copier un Module"; + $lang->module_selector = "Module Selector"; + $lang->do_selected = "선택된 것들을..."; + $lang->bundle_setup = "일괄 기본 설정"; + $lang->bundle_addition_setup = "일괄 추가 설정"; + $lang->bundle_grant_setup = "일괄 권한 설정"; + $lang->lang_code = "언어 코드"; + $lang->filebox = "파일박스"; + + $lang->access_type = '접속 방법'; + $lang->access_domain = 'Domain 접속'; + $lang->access_vid = 'Site ID 접속'; + $lang->about_vid = '별도의 도메인이 아닌 http://XE주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다.
첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; + $lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; + $lang->msg_already_registed_domain = '이미 등록된 도메인입니다. 다른 도메인을 사용해주세요'; + + $lang->header_script = "Script en-tête"; + $lang->about_header_script = "Vous pouvez entrer un script en html par vous-même entre <header> et </header>.
Vous pouvez utiliser <script, <style ou <meta tag"; + + $lang->grant_access = "Access"; + $lang->grant_manager = "Management"; + + $lang->grant_to_all = "All users"; + $lang->grant_to_login_user = "Logged users"; + $lang->grant_to_site_user = "Joined users"; + $lang->grant_to_group = "Specification group users"; + + $lang->cmd_add_shortcut = "Ajouter un raccourci"; + $lang->cmd_install = "Installer"; + $lang->cmd_update = "Mettre à Jour"; + $lang->cmd_manage_category = 'Administrer des Catégories'; + $lang->cmd_manage_grant = 'Administrer des Permissions'; + $lang->cmd_manage_skin = 'Administrer des Habillages'; + $lang->cmd_manage_document = 'Administrer des Articles'; + $lang->cmd_find_module = '모듈 찾기'; + $lang->cmd_find_langcode = 'Find lang code'; + + $lang->msg_new_module = "Créer un module"; + $lang->msg_update_module = "Modifier un module"; + $lang->msg_module_name_exists = "Le nom existe déjà. Essayez un autre nom, S.V.P."; + $lang->msg_category_is_null = 'Il n\'y a pas de catégorie enrégistrée.'; + $lang->msg_grant_is_null = 'Il n\'y a pas de liste de permission.'; + $lang->msg_no_checked_document = 'Pas un article est choisi.'; + $lang->msg_move_failed = 'Echoué de bouger'; + $lang->msg_cannot_delete_for_child = 'On ne peut pas supprimer une catégorie qui a des catégories inférieures.'; + $lang->msg_limit_mid ='모듈이름은 영문+[영문+숫자+_] 만 가능합니다.'; + $lang->msg_extra_name_exists = '이미 존재하는 확장변수 이름입니다. 다른 이름을 입력해주세요.'; + + $lang->about_browser_title = "C'est la valeur qui se représentera dans le titre de navigateur Web. Ce sera encore utilisé dans RSS/Rétrolien."; + $lang->about_mid = "Le nom de module sera utilisé comme http://adresse/?mid=ModuleName.\n(alphabet anglais + [alphabet anglais, nombres, et soulignement(_)] sont seulement permis. The maximum length is 40.)"; + $lang->about_default = "Si c'est coché, on verra ce module quand on connecte ce site sans aucune valeur de mid(mid=Nulle Valeur)."; + $lang->about_module_category = "Ça vous permet d'administrer le module par la catégorie.\nOn peut administrer la classification des modules à Administration des modules > Catégorie des Modules ."; + $lang->about_description= 'C\'est la description pour la facilité à administrer.'; + $lang->about_default = 'Si c\'est coché, on verra ce module quand on connecte ce site sans aucune valeur de mid(mid=Nulle Valeur).'; + $lang->about_header_text = 'Ce contenu sera exposé en tête du module.(balise en html est disponible)'; + $lang->about_footer_text = 'Ce contenu sera exposé en bas du module.(balise en html est disponible)'; + $lang->about_skin = 'Vous pouvez choisir un habillage pour le module.'; + $lang->about_use_category = 'Cochez pour utiliser la fonction de catégorie, .'; + $lang->about_list_count = 'Vous pouvez configurer combien d\'articles soient exposés dans une page.(20 par défaut)'; + $lang->about_search_list_count = 'Vous pouvez configurer combien d\'articles soient exposés quand vous utilisez la fonction de recherche ou de catégorie. (20 par défaut)'; + $lang->about_page_count = 'Vous pouvez configurer combien de liens pour les Pages à Bouger en bas de chaque page.(10 par défaut)'; + $lang->about_admin_id = 'Vous pouvez désigner un directeur qui aura tous les permissions sur le module.\nVous pouvez entrer plusieurs compte en utilisant.'; + $lang->about_grant = 'Si vous ne donnez pas la permission à aucune personne, même les membres qui n\'a pas ouvert la connexion auront la permission. '; + $lang->about_grant_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; + $lang->about_module = "XE se compose des modules sauf la bibliothèque fondamental.\nLe module [Administration des Modules] montera tous les modules installés et vous aidera les administrer."; + + $lang->about_extra_vars_default_value = 'Si plusieurs valeurs sont nécessaires, vous pouvez les connecter avec la virgule(,).'; + $lang->about_search_virtual_site = "가상 사이트(카페XE등)의 도메인을 입력하신 후 검색하세요.
가상 사이트이외의 모듈은 내용을 비우고 검색하시면 됩니다. (http:// 는 제외)"; + $lang->about_langcode = "언어별로 다르게 설정하고 싶으시면 언어코드 찾기를 이용해주세요"; + $lang->about_file_extension= "%s 파일만 가능합니다."; +?> diff --git a/modules/module/lang/jp.lang.php b/modules/module/lang/jp.lang.php index 38df27081..0f35eb2f8 100644 --- a/modules/module/lang/jp.lang.php +++ b/modules/module/lang/jp.lang.php @@ -1,98 +1,98 @@ -virtual_site = 'バーチャル(Virtual)サイト'; - $lang->module_list = 'モジュールリスト'; - $lang->module_index = 'モジュールインデックス'; - $lang->module_category = 'モジュールカテゴリ'; - $lang->module_info = '詳細'; - $lang->add_shortcut = '管理者メニューに追加する'; - $lang->module_action = '動作'; - $lang->module_maker = 'モジュール作者'; - $lang->module_license = 'ライセンス'; - $lang->module_history = '変更履歴 '; - $lang->category_title = 'カテゴリ名'; - $lang->header_text = 'ヘッダー内容'; - $lang->footer_text = 'フッター内容'; - $lang->use_category = 'カテゴリ使用'; - $lang->category_title = 'カテゴリ名'; - $lang->checked_count = '選択された書き込み数'; - $lang->skin_default_info = 'スキン基本情報'; - $lang->skin_author = 'スキン作者'; - $lang->skin_license = 'ライセンス'; - $lang->skin_history = '変更内容'; - $lang->module_copy = 'モジュールコピー'; - $lang->module_selector = 'モジュールセレクター'; - $lang->do_selected = '選択したものを...'; - $lang->bundle_setup = '一括基本設定'; - $lang->bundle_addition_setup = '一括追加設定'; - $lang->bundle_grant_setup = '一括権限設定'; - $lang->lang_code = '言語コード'; - $lang->filebox = 'ファイルボックス'; - - $lang->access_type = 'アクセスタイプ'; - $lang->access_domain = 'Doaminアクセス'; - $lang->access_vid = 'Site IDアクセス'; - $lang->about_domain = '複数のホームページを作成するためには、「オリジナルドメイン」や「サブ ドメイン」のような専用のドメインが必要です。
また、 XEのインストールパスも一緒に記入して下さい。
ex) www.xpressengine.com/xe'; - $lang->about_vid = '別の違うドメインではなく、「http://XEアドレス/ID」へのアクセスが可能です。この際、モジュール名(mid)と重複しないように登録して下さい。
必ず、頭文字は半角英文字にし、「(すべて半角の)英数字・_ 」 だけの組み合わせで入力して下さい。'; - $lang->msg_already_registed_vid = '既に登録されたサイトIDです。掲示板などのmidと重複は不可です。異なるIDを入力して下さい。'; - $lang->msg_already_registed_domain = '既に登録されているドメインです。異なるドメインを利用して下さい。'; - - $lang->header_script = 'ヘッダースクリプト'; - $lang->about_header_script = 'HTMLの<header>と</header>の間に入れるコードを直接入力出来ます。
<script、<styleまたは<metaタグなどが利用出来ます。'; - - $lang->grant_access = 'アクセス権限'; - $lang->grant_manager = '管理権限'; - - $lang->grant_to_all = 'すべてのユーザー'; - $lang->grant_to_login_user = 'ログインユーザー'; - $lang->grant_to_site_user = '登録ユーザー'; - $lang->grant_to_group = '特定グループのユーザー'; - - $lang->cmd_add_shortcut = 'ショットカット追加'; - $lang->cmd_install = 'インストール'; - $lang->cmd_update = 'アップデート'; - $lang->cmd_manage_category = 'カテゴリ管理'; - $lang->cmd_manage_grant = '権限管理'; - $lang->cmd_manage_skin = 'スキン管理'; - $lang->cmd_manage_document = '書き込み管理'; - $lang->cmd_find_module = 'モジュール検索'; - $lang->cmd_find_langcode = '言語コード検索'; - - $lang->msg_new_module = 'モジュール作成'; - $lang->msg_update_module = 'モジュール修正'; - $lang->msg_module_name_exists = '既に存在するモジュール名です。他の名前を入力して下さい。'; - $lang->msg_category_is_null = '登録されているカテゴリがありません。'; - $lang->msg_grant_is_null = '登録された権限がありません。'; - $lang->msg_no_checked_document = '選択された書き込みがありません。'; - $lang->msg_move_failed = '移動することが出来ませんでした。'; - $lang->msg_cannot_delete_for_child = '下位カテゴリのカテゴリは削除することが出来ません。'; - $lang->msg_limit_mid ='モジュール名は「 半角英小文字+[半角英小文字+半角数字+_] 」のみ出来ます。'; - $lang->msg_extra_name_exists = '既に存在する拡張変数名です。他の拡張変数名を入力して下さい。'; - - $lang->about_browser_title = 'ブラウザのタイトルバーに表示される内容です。RSS/Trackbackでも使用します。'; - $lang->about_mid = 'モジュール名は「http://アドレス/?mid=モジュール名」のように直接呼び出せるパラメーター値です。
※英数の頭文字と[英数と_のみ]の組み合わせ (すべて半角、最大40文字) '; - $lang->about_default = 'チェックすると、サイトに「mid値」なしでアクセスした場合、デフォルトで表示します。'; - $lang->about_module_category = "カテゴリで管理出来るようにします。モジュールのカテゴリの管理は、「モジュール管理 > モジュールカテゴリ」にて行います。"; - $lang->about_description= '管理用として用いられる説明です。'; - $lang->about_header_text = 'モジュールのヘッダーに表示される内容です。(HTMLタグの使用可能)'; - $lang->about_footer_text = 'モジュールのフッターに表示される内容です。(HTMLタグの使用可能)'; - $lang->about_skin = 'モジュールのスキンを選択します。'; - $lang->about_use_category = 'チェックするとカテゴリ機能が使用出来ます。'; - $lang->about_list_count = '1ページ当たりに表示される書き込みの数が指定出来ます(デフォルト20個)。'; - $lang->about_search_list_count = 'お勧めの記事数を設定するにさらされるかのカテゴリ検索機能を使用する場合です。 (デフォルトは20 )'; - $lang->about_page_count = 'リストの下段に移動出来るページのリンク数が指定出来ます(デフォルト10個)。'; - $lang->about_admin_id = '該当するモジュールに対して最高権限を持つ管理者を指定することが出来ます。'; - $lang->about_grant = '特定権限の対象をすべて解除するとログインしていない会員ユーザまで権限が与えられます。'; - $lang->about_grant_deatil = '登録ユーザーとはcafeXEなど分譲型バーチャル(Virtual)サイトに登録した、ログインユーザーを意味します。'; - $lang->about_module = "XEは、基本ライブラリの他は、すべてモジュールで構成されています。モジュール管理用のモジュールはインストールされたすべてを表示し、管理出来るようにします。"; - $lang->about_extra_vars_default_value = '多重・単一選択などのデフォルト値が、複数必要な場合は、「, (コンマ)」で区切って追加することが出来ます。'; - $lang->about_search_virtual_site = 'バーチャル(Virtual)サイト(:cafeXEなど)のドメインを入力して検索して下さい。
バーチャル(Virtual)サイト以外のモジュールは内容を空にしてから検索します。(http://は省く)'; - $lang->about_extra_vars_eid_value = '拡張変数名を入力して下さい。 (英字+[英字+数字+_]のみ可能(全て半角))'; - $lang->about_langcode = '言語ごとに異なる設定をする場合、言語コード検索を利用して下さい。'; - $lang->about_file_extension= "%s ファイルのみ可能です。"; -?> +virtual_site = 'バーチャル(Virtual)サイト'; + $lang->module_list = 'モジュールリスト'; + $lang->module_index = 'モジュールインデックス'; + $lang->module_category = 'モジュールカテゴリ'; + $lang->module_info = '詳細'; + $lang->add_shortcut = '管理者メニューに追加する'; + $lang->module_action = '動作'; + $lang->module_maker = 'モジュール作者'; + $lang->module_license = 'ライセンス'; + $lang->module_history = '変更履歴 '; + $lang->category_title = 'カテゴリ名'; + $lang->header_text = 'ヘッダー内容'; + $lang->footer_text = 'フッター内容'; + $lang->use_category = 'カテゴリ使用'; + $lang->category_title = 'カテゴリ名'; + $lang->checked_count = '選択された書き込み数'; + $lang->skin_default_info = 'スキン基本情報'; + $lang->skin_author = 'スキン作者'; + $lang->skin_license = 'ライセンス'; + $lang->skin_history = '変更内容'; + $lang->module_copy = 'モジュールコピー'; + $lang->module_selector = 'モジュールセレクター'; + $lang->do_selected = '選択したものを...'; + $lang->bundle_setup = '一括基本設定'; + $lang->bundle_addition_setup = '一括追加設定'; + $lang->bundle_grant_setup = '一括権限設定'; + $lang->lang_code = '言語コード'; + $lang->filebox = 'ファイルボックス'; + + $lang->access_type = 'アクセスタイプ'; + $lang->access_domain = 'Doaminアクセス'; + $lang->access_vid = 'Site IDアクセス'; + $lang->about_domain = '複数のホームページを作成するためには、「オリジナルドメイン」や「サブ ドメイン」のような専用のドメインが必要です。
また、 XEのインストールパスも一緒に記入して下さい。
ex) www.xpressengine.com/xe'; + $lang->about_vid = '別の違うドメインではなく、「http://XEアドレス/ID」へのアクセスが可能です。この際、モジュール名(mid)と重複しないように登録して下さい。
必ず、頭文字は半角英文字にし、「(すべて半角の)英数字・_ 」 だけの組み合わせで入力して下さい。'; + $lang->msg_already_registed_vid = '既に登録されたサイトIDです。掲示板などのmidと重複は不可です。異なるIDを入力して下さい。'; + $lang->msg_already_registed_domain = '既に登録されているドメインです。異なるドメインを利用して下さい。'; + + $lang->header_script = 'ヘッダースクリプト'; + $lang->about_header_script = 'HTMLの<header>と</header>の間に入れるコードを直接入力出来ます。
<script、<styleまたは<metaタグなどが利用出来ます。'; + + $lang->grant_access = 'アクセス権限'; + $lang->grant_manager = '管理権限'; + + $lang->grant_to_all = 'すべてのユーザー'; + $lang->grant_to_login_user = 'ログインユーザー'; + $lang->grant_to_site_user = '登録ユーザー'; + $lang->grant_to_group = '特定グループのユーザー'; + + $lang->cmd_add_shortcut = 'ショットカット追加'; + $lang->cmd_install = 'インストール'; + $lang->cmd_update = 'アップデート'; + $lang->cmd_manage_category = 'カテゴリ管理'; + $lang->cmd_manage_grant = '権限管理'; + $lang->cmd_manage_skin = 'スキン管理'; + $lang->cmd_manage_document = '書き込み管理'; + $lang->cmd_find_module = 'モジュール検索'; + $lang->cmd_find_langcode = '言語コード検索'; + + $lang->msg_new_module = 'モジュール作成'; + $lang->msg_update_module = 'モジュール修正'; + $lang->msg_module_name_exists = '既に存在するモジュール名です。他の名前を入力して下さい。'; + $lang->msg_category_is_null = '登録されているカテゴリがありません。'; + $lang->msg_grant_is_null = '登録された権限がありません。'; + $lang->msg_no_checked_document = '選択された書き込みがありません。'; + $lang->msg_move_failed = '移動することが出来ませんでした。'; + $lang->msg_cannot_delete_for_child = '下位カテゴリのカテゴリは削除することが出来ません。'; + $lang->msg_limit_mid ='モジュール名は「 半角英小文字+[半角英小文字+半角数字+_] 」のみ出来ます。'; + $lang->msg_extra_name_exists = '既に存在する拡張変数名です。他の拡張変数名を入力して下さい。'; + + $lang->about_browser_title = 'ブラウザのタイトルバーに表示される内容です。RSS/Trackbackでも使用します。'; + $lang->about_mid = 'モジュール名は「http://アドレス/?mid=モジュール名」のように直接呼び出せるパラメーター値です。
※英数の頭文字と[英数と_のみ]の組み合わせ (すべて半角、最大40文字) '; + $lang->about_default = 'チェックすると、サイトに「mid値」なしでアクセスした場合、デフォルトで表示します。'; + $lang->about_module_category = "カテゴリで管理出来るようにします。モジュールのカテゴリの管理は、「モジュール管理 > モジュールカテゴリ」にて行います。"; + $lang->about_description= '管理用として用いられる説明です。'; + $lang->about_header_text = 'モジュールのヘッダーに表示される内容です。(HTMLタグの使用可能)'; + $lang->about_footer_text = 'モジュールのフッターに表示される内容です。(HTMLタグの使用可能)'; + $lang->about_skin = 'モジュールのスキンを選択します。'; + $lang->about_use_category = 'チェックするとカテゴリ機能が使用出来ます。'; + $lang->about_list_count = '1ページ当たりに表示される書き込みの数が指定出来ます(デフォルト20個)。'; + $lang->about_search_list_count = 'お勧めの記事数を設定するにさらされるかのカテゴリ検索機能を使用する場合です。 (デフォルトは20 )'; + $lang->about_page_count = 'リストの下段に移動出来るページのリンク数が指定出来ます(デフォルト10個)。'; + $lang->about_admin_id = '該当するモジュールに対して最高権限を持つ管理者を指定することが出来ます。'; + $lang->about_grant = '特定権限の対象をすべて解除するとログインしていない会員ユーザまで権限が与えられます。'; + $lang->about_grant_deatil = '登録ユーザーとはcafeXEなど分譲型バーチャル(Virtual)サイトに登録した、ログインユーザーを意味します。'; + $lang->about_module = "XEは、基本ライブラリの他は、すべてモジュールで構成されています。モジュール管理用のモジュールはインストールされたすべてを表示し、管理出来るようにします。"; + $lang->about_extra_vars_default_value = '多重・単一選択などのデフォルト値が、複数必要な場合は、「, (コンマ)」で区切って追加することが出来ます。'; + $lang->about_search_virtual_site = 'バーチャル(Virtual)サイト(:cafeXEなど)のドメインを入力して検索して下さい。
バーチャル(Virtual)サイト以外のモジュールは内容を空にしてから検索します。(http://は省く)'; + $lang->about_extra_vars_eid_value = '拡張変数名を入力して下さい。 (英字+[英字+数字+_]のみ可能(全て半角))'; + $lang->about_langcode = '言語ごとに異なる設定をする場合、言語コード検索を利用して下さい。'; + $lang->about_file_extension= "%s ファイルのみ可能です。"; +?> diff --git a/modules/module/lang/ko.lang.php b/modules/module/lang/ko.lang.php index 4d1c8c034..831f8a742 100644 --- a/modules/module/lang/ko.lang.php +++ b/modules/module/lang/ko.lang.php @@ -1,98 +1,98 @@ -virtual_site = '가상 사이트'; - $lang->module_list = '모듈 목록'; - $lang->module_index = '모듈 목록'; - $lang->module_category = '모듈 분류'; - $lang->module_info = '모듈 정보'; - $lang->add_shortcut = '관리자 메뉴에 추가'; - $lang->module_action = '동작'; - $lang->module_maker = '모듈 제작자'; - $lang->module_license = '라이선스'; - $lang->module_history = '변경 이력 '; - $lang->category_title = '분류 이름'; - $lang->header_text = '상단 내용'; - $lang->footer_text = '하단 내용'; - $lang->use_category = '분류 사용'; - $lang->category_title = '분류명'; - $lang->checked_count = '선택된 글 수'; - $lang->skin_default_info = '스킨 기본정보'; - $lang->skin_author = '스킨 제작자'; - $lang->skin_license = '라이선스'; - $lang->skin_history = '변경 이력'; - $lang->module_copy = '모듈 복사'; - $lang->module_selector = '모듈 선택기'; - $lang->do_selected = '선택된 것들을...'; - $lang->bundle_setup = '일괄 기본 설정'; - $lang->bundle_addition_setup = '일괄 추가 설정'; - $lang->bundle_grant_setup = '일괄 권한 설정'; - $lang->lang_code = '언어 코드'; - $lang->filebox = '파일박스'; - - $lang->access_type = '접속 방법'; - $lang->access_domain = 'Domain 접속'; - $lang->access_vid = 'Site ID 접속'; - $lang->about_domain = '1개 이상의 사이트를 만들기 위해서는 전용 도메인이 있어야 합니다.
독립 도메인이나 서브 도메인이 있으면 되고 XE가 설치된 경로까지 같이 넣어주세요.
예) www.xpressengine.com/xe'; - $lang->about_vid = '별도의 도메인이 아닌 http://XE주소/ID 로 접속할 수 있습니다. 모듈명(mid)과 중복될 수 없습니다.
첫 글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; - $lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판 등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; - $lang->msg_already_registed_domain = '이미 등록된 도메인입니다. 다른 도메인을 사용해주세요'; - - $lang->header_script = '헤더 스크립트'; - $lang->about_header_script = 'HTML의 <head>와 </head> 사이에 들어가는 코드를 직접 입력할 수 있습니다.
<script, <style 또는 <meta 태그 등을 이용하실 수 있습니다'; - - $lang->grant_access = '접근 권한'; - $lang->grant_manager = '관리 권한'; - - $lang->grant_to_all = '모든 사용자'; - $lang->grant_to_login_user = '로그인 사용자'; - $lang->grant_to_site_user = '가입한 사용자'; - $lang->grant_to_group = '특정 그룹 사용자'; - - $lang->cmd_add_shortcut = '바로가기 추가'; - $lang->cmd_install = '설치'; - $lang->cmd_update = '업데이트'; - $lang->cmd_manage_category = '분류 관리'; - $lang->cmd_manage_grant = '권한 관리'; - $lang->cmd_manage_skin = '스킨 관리'; - $lang->cmd_manage_document = '게시글 관리'; - $lang->cmd_find_module = '모듈 찾기'; - $lang->cmd_find_langcode = '언어 코드 찾기'; - - $lang->msg_new_module = '모듈 생성'; - $lang->msg_update_module = '모듈 수정'; - $lang->msg_module_name_exists = '이미 존재하는 모듈 이름입니다. 다른 이름을 입력해주세요.'; - $lang->msg_category_is_null = '등록된 분류가 없습니다.'; - $lang->msg_grant_is_null = '등록된 권한 대상이 없습니다.'; - $lang->msg_no_checked_document = '선택된 게시물이 없습니다.'; - $lang->msg_move_failed = '이동 실패하였습니다.'; - $lang->msg_cannot_delete_for_child = '하부 분류가 있는 분류는 삭제하실 수 없습니다.'; - $lang->msg_limit_mid ='모듈 이름은 영문+[영문+숫자+_] 만 가능합니다.'; - $lang->msg_extra_name_exists = '이미 존재하는 확장 변수 이름입니다. 다른 이름을 입력해주세요.'; - - $lang->about_browser_title = '브라우저 제목에 나타나는 값입니다. RSS/Trackback에서도 사용됩니다.'; - $lang->about_mid = '모듈 이름은 http://주소/?mid=모듈이름 처럼 직접 호출할 수 있는 값입니다. (영문+[영문+숫자+_] 만 가능. 최대 40 글자)'; - $lang->about_default = '선택하시면 사이트에 mid값 없이 접속하였을 경우 기본으로 보여줍니다.'; - $lang->about_module_category = "분류를 통한 관리를 할 수 있도록 합니다. 모듈 분류 관리는 모듈관리 > 모듈분류에서 하실 수 있습니다."; - $lang->about_description= '관리용으로 사용되는 설명입니다.'; - $lang->about_header_text = '모듈 상단에 표시되는 내용입니다. (HTML 태그 사용 가능)'; - $lang->about_footer_text = '모듈 하단에 표시되는 내용입니다. (HTML 태그 사용 가능)'; - $lang->about_skin = '모듈 스킨을 선택하실 수 있습니다.'; - $lang->about_use_category = '선택하시면 분류 기능을 사용할 수 있습니다.'; - $lang->about_list_count = '한 페이지에 표시될 글 수를 지정하실 수 있습니다. (기본 20개)'; - $lang->about_search_list_count = '검색, 카테고리 선택 등을 할 경우 표시될 글 수를 지정하실 수 있습니다. (기본 20개)'; - $lang->about_page_count = '목록 하단, 페이지를 이동하는 링크 수를 지정하실 수 있습니다. (기본 10개)'; - $lang->about_admin_id = '해당 모듈에 대해 최고 권한을 가지는 관리자를 지정할 수 있습니다.'; - $lang->about_grant = '특정 권한의 대상을 모두 해제하면 로그인하지 않은 회원까지 권한을 가질 수 있습니다.'; - $lang->about_grant_deatil = '가입한 사용자는 cafeXE 등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다.'; - $lang->about_module = "XE는 기본 라이브러리를 제외한 나머지는 모두 모듈로 구성되어 있습니다.\n모듈 관리 모듈은 설치된 모든 모듈을 보여주고 관리를 돕습니다."; - $lang->about_extra_vars_default_value = '다중/단일 선택 등 기본 값이 여러 개가 필요한 경우 , (콤마)로 연결하시면 됩니다.'; - $lang->about_search_virtual_site = '가상 사이트(예:cafeXE) 도메인을 입력하신 후 검색하세요.
가상 사이트 이외의 모듈은 내용을 비우고 검색하시면 됩니다. (http:// 는 제외)'; - $lang->about_extra_vars_eid_value = '확장 변수의 이름을 적어주세요. (영문+[영문+숫자+_] 만 가능)'; - $lang->about_langcode = '언어별로 다르게 설정하고 싶으시면 언어 코드 찾기를 이용해주세요.'; - $lang->about_file_extension= "%s 파일만 가능합니다."; -?> +virtual_site = '가상 사이트'; + $lang->module_list = '모듈 목록'; + $lang->module_index = '모듈 목록'; + $lang->module_category = '모듈 분류'; + $lang->module_info = '모듈 정보'; + $lang->add_shortcut = '관리자 메뉴에 추가'; + $lang->module_action = '동작'; + $lang->module_maker = '모듈 제작자'; + $lang->module_license = '라이선스'; + $lang->module_history = '변경 이력 '; + $lang->category_title = '분류 이름'; + $lang->header_text = '상단 내용'; + $lang->footer_text = '하단 내용'; + $lang->use_category = '분류 사용'; + $lang->category_title = '분류명'; + $lang->checked_count = '선택된 글 수'; + $lang->skin_default_info = '스킨 기본정보'; + $lang->skin_author = '스킨 제작자'; + $lang->skin_license = '라이선스'; + $lang->skin_history = '변경 이력'; + $lang->module_copy = '모듈 복사'; + $lang->module_selector = '모듈 선택기'; + $lang->do_selected = '선택된 것들을...'; + $lang->bundle_setup = '일괄 기본 설정'; + $lang->bundle_addition_setup = '일괄 추가 설정'; + $lang->bundle_grant_setup = '일괄 권한 설정'; + $lang->lang_code = '언어 코드'; + $lang->filebox = '파일박스'; + + $lang->access_type = '접속 방법'; + $lang->access_domain = 'Domain 접속'; + $lang->access_vid = 'Site ID 접속'; + $lang->about_domain = '1개 이상의 사이트를 만들기 위해서는 전용 도메인이 있어야 합니다.
독립 도메인이나 서브 도메인이 있으면 되고 XE가 설치된 경로까지 같이 넣어주세요.
예) www.xpressengine.com/xe'; + $lang->about_vid = '별도의 도메인이 아닌 http://XE주소/ID 로 접속할 수 있습니다. 모듈명(mid)과 중복될 수 없습니다.
첫 글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; + $lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판 등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; + $lang->msg_already_registed_domain = '이미 등록된 도메인입니다. 다른 도메인을 사용해주세요'; + + $lang->header_script = '헤더 스크립트'; + $lang->about_header_script = 'HTML의 <head>와 </head> 사이에 들어가는 코드를 직접 입력할 수 있습니다.
<script, <style 또는 <meta 태그 등을 이용하실 수 있습니다'; + + $lang->grant_access = '접근 권한'; + $lang->grant_manager = '관리 권한'; + + $lang->grant_to_all = '모든 사용자'; + $lang->grant_to_login_user = '로그인 사용자'; + $lang->grant_to_site_user = '가입한 사용자'; + $lang->grant_to_group = '특정 그룹 사용자'; + + $lang->cmd_add_shortcut = '바로가기 추가'; + $lang->cmd_install = '설치'; + $lang->cmd_update = '업데이트'; + $lang->cmd_manage_category = '분류 관리'; + $lang->cmd_manage_grant = '권한 관리'; + $lang->cmd_manage_skin = '스킨 관리'; + $lang->cmd_manage_document = '게시글 관리'; + $lang->cmd_find_module = '모듈 찾기'; + $lang->cmd_find_langcode = '언어 코드 찾기'; + + $lang->msg_new_module = '모듈 생성'; + $lang->msg_update_module = '모듈 수정'; + $lang->msg_module_name_exists = '이미 존재하는 모듈 이름입니다. 다른 이름을 입력해주세요.'; + $lang->msg_category_is_null = '등록된 분류가 없습니다.'; + $lang->msg_grant_is_null = '등록된 권한 대상이 없습니다.'; + $lang->msg_no_checked_document = '선택된 게시물이 없습니다.'; + $lang->msg_move_failed = '이동 실패하였습니다.'; + $lang->msg_cannot_delete_for_child = '하부 분류가 있는 분류는 삭제하실 수 없습니다.'; + $lang->msg_limit_mid ='모듈 이름은 영문+[영문+숫자+_] 만 가능합니다.'; + $lang->msg_extra_name_exists = '이미 존재하는 확장 변수 이름입니다. 다른 이름을 입력해주세요.'; + + $lang->about_browser_title = '브라우저 제목에 나타나는 값입니다. RSS/Trackback에서도 사용됩니다.'; + $lang->about_mid = '모듈 이름은 http://주소/?mid=모듈이름 처럼 직접 호출할 수 있는 값입니다. (영문+[영문+숫자+_] 만 가능. 최대 40 글자)'; + $lang->about_default = '선택하시면 사이트에 mid값 없이 접속하였을 경우 기본으로 보여줍니다.'; + $lang->about_module_category = "분류를 통한 관리를 할 수 있도록 합니다. 모듈 분류 관리는 모듈관리 > 모듈분류에서 하실 수 있습니다."; + $lang->about_description= '관리용으로 사용되는 설명입니다.'; + $lang->about_header_text = '모듈 상단에 표시되는 내용입니다. (HTML 태그 사용 가능)'; + $lang->about_footer_text = '모듈 하단에 표시되는 내용입니다. (HTML 태그 사용 가능)'; + $lang->about_skin = '모듈 스킨을 선택하실 수 있습니다.'; + $lang->about_use_category = '선택하시면 분류 기능을 사용할 수 있습니다.'; + $lang->about_list_count = '한 페이지에 표시될 글 수를 지정하실 수 있습니다. (기본 20개)'; + $lang->about_search_list_count = '검색, 카테고리 선택 등을 할 경우 표시될 글 수를 지정하실 수 있습니다. (기본 20개)'; + $lang->about_page_count = '목록 하단, 페이지를 이동하는 링크 수를 지정하실 수 있습니다. (기본 10개)'; + $lang->about_admin_id = '해당 모듈에 대해 최고 권한을 가지는 관리자를 지정할 수 있습니다.'; + $lang->about_grant = '특정 권한의 대상을 모두 해제하면 로그인하지 않은 회원까지 권한을 가질 수 있습니다.'; + $lang->about_grant_deatil = '가입한 사용자는 cafeXE 등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다.'; + $lang->about_module = "XE는 기본 라이브러리를 제외한 나머지는 모두 모듈로 구성되어 있습니다.\n모듈 관리 모듈은 설치된 모든 모듈을 보여주고 관리를 돕습니다."; + $lang->about_extra_vars_default_value = '다중/단일 선택 등 기본 값이 여러 개가 필요한 경우 , (콤마)로 연결하시면 됩니다.'; + $lang->about_search_virtual_site = '가상 사이트(예:cafeXE) 도메인을 입력하신 후 검색하세요.
가상 사이트 이외의 모듈은 내용을 비우고 검색하시면 됩니다. (http:// 는 제외)'; + $lang->about_extra_vars_eid_value = '확장 변수의 이름을 적어주세요. (영문+[영문+숫자+_] 만 가능)'; + $lang->about_langcode = '언어별로 다르게 설정하고 싶으시면 언어 코드 찾기를 이용해주세요.'; + $lang->about_file_extension= "%s 파일만 가능합니다."; +?> diff --git a/modules/module/lang/ru.lang.php b/modules/module/lang/ru.lang.php index 243c661a1..a0c12a934 100644 --- a/modules/module/lang/ru.lang.php +++ b/modules/module/lang/ru.lang.php @@ -1,99 +1,99 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->virtual_site = "Virtual Site"; - $lang->module_list = "Список модулей"; - $lang->module_index = "Список модулей"; - $lang->module_category = "Категория модуля"; - $lang->module_info = "Информация"; - $lang->add_shortcut = "Добавить ярлыки"; - $lang->module_action = "Действия"; - $lang->module_maker = "Разработчик модуля"; - $lang->module_license = 'Лицензия'; - $lang->module_history = "История обновлений"; - $lang->category_title = "Название категории"; - $lang->header_text = 'Верхний колонтитул'; - $lang->footer_text = 'Нижний колонтитул'; - $lang->use_category = 'Включить категорию'; - $lang->category_title = 'Название категории'; - $lang->checked_count = 'Число выбранных статей'; // translator's note: возможно "checked" следует перевести как "проверенных" - $lang->skin_default_info = 'Информация стандартного скина'; - $lang->skin_author = 'Разработчик скина'; - $lang->skin_license = 'License'; - $lang->skin_history = 'История обновлений'; - $lang->module_selector = "Module Selector"; - $lang->do_selected = "Выбранные..."; - $lang->bundle_setup = "일괄 기본 설정"; - $lang->bundle_addition_setup = "일괄 추가 설정"; - $lang->bundle_grant_setup = "일괄 권한 설정"; - $lang->lang_code = "Код языка"; - $lang->filebox = "Файлбокс"; - - $lang->access_type = 'Способ соединения'; - $lang->access_domain = 'Domain соединения'; - $lang->access_vid = 'Site ID соединение'; - $lang->about_vid = '별도의 도메인이 아닌 http://XE주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다.
첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; - $lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; - $lang->msg_already_registed_domain = '이미 등록된 도메인입니다. 다른 도메인을 사용해주세요'; - - $lang->module_copy = "Копировать модуль"; - - $lang->header_script = "Скрипт Header"; - $lang->about_header_script = "html의 <header>와 </header> 사이에 들어가는 코드를 직접 입력할 수 있습니다.
<script, <style 또는 <meta 태그등을 이용하실 수 있습니다"; - - $lang->grant_access = "Access"; - $lang->grant_manager = "Management"; - - $lang->grant_to_all = "All users"; - $lang->grant_to_login_user = "Logged users"; - $lang->grant_to_site_user = "Joined users"; - $lang->grant_to_group = "Specification group users"; - - $lang->cmd_add_shortcut = "Добавить ярлык"; - $lang->cmd_install = "Установить"; - $lang->cmd_update = "Обновить"; - $lang->cmd_manage_category = 'Управление категориями'; - $lang->cmd_manage_grant = 'Управление правами доступа'; - $lang->cmd_manage_skin = 'Управление скинами'; - $lang->cmd_manage_document = 'Управление статьями'; - $lang->cmd_find_module = 'Искать модуль'; - $lang->cmd_find_langcode = 'Find lang code'; - - $lang->msg_new_module = "Создать новый модуль"; - $lang->msg_update_module = "Изменить модуль"; - $lang->msg_module_name_exists = "Имя уже существует. Пожалуйста, попробуйте другое"; - $lang->msg_category_is_null = 'Зарегистрированной категории не существует.'; - $lang->msg_grant_is_null = 'Списка для управления правами доступа не существует.'; - $lang->msg_no_checked_document = 'Нет выбранных статей.'; // translator's note: выше... - $lang->msg_move_failed = 'Невозможно переместить'; - $lang->msg_cannot_delete_for_child = 'Невозможно удалить категорию, имеющую дочерние категории.'; - $lang->msg_limit_mid ='모듈이름은 영문+[영문+숫자+_] 만 가능합니다.'; - $lang->msg_extra_name_exists = '이미 존재하는 확장변수 이름입니다. 다른 이름을 입력해주세요.'; - - $lang->about_browser_title = "Это будет показано в заголовке браузера. Также, это будет использоваться в RSS/Трекбеке."; - $lang->about_mid = "Имя модуля будет использовано как http://address/?mid=Имя_модуля.\n(только латиница, цифры и символ подчеркивания(_) разрешены. The maximum length is 40.)"; - $lang->about_default = "Если выбрано, модуль будет главным на сайте. Для доступа не нужен будет идентификатор модуля."; - $lang->about_module_category = "Это позволяет Вам управлять посредством категорий модулей.\nURL для менеджера модулей Manage module > Категория Модуля ."; - $lang->about_description= 'Это описание только для менеджера.'; - $lang->about_default = 'Если выбрано, этот модуль будет показан, когда пользователи входят на сайт без идентификатора модуля (mid=NoValue).'; - $lang->about_header_text = 'Это содержимое будет показано сверху модуля. (HTML разрешен)'; - $lang->about_footer_text = 'Это содержимое будет показано снизу модуля. (HTML разрешен)'; - $lang->about_skin = 'Вы можете выбрать скин модуля.'; - $lang->about_use_category = 'Если выбрано, функция категорий будет включена.'; - $lang->about_list_count = 'Вы можете установить лимит показа статей на страницу. (по умолчанию: 20)'; - $lang->about_search_list_count = '검색 또는 카테고리 선택등을 할 경우 표시될 글의 수를 지정하실 수 있습니다. 기본(20개)'; - $lang->about_page_count = 'Вы можете установить число страниц внизу. (по умолчанию: 10)'; - $lang->about_admin_id = 'Вы можете разрешить менеджеру иметь полные права доступа к этому модулю.\nВы можете ввести несколько ID, используя '; - $lang->about_grant = 'Если Вы отключите все права доступа для отдельного объекта, не прошедшие процедуру входа на сайт пользователи получат доступ.'; - $lang->about_grant_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; - $lang->about_module = "XE состоит из модулей, за исключением базовой библиотеки.\n Управление модулем покажет все установленные модули и поможет управлять ими."; - - $lang->about_extra_vars_default_value = 'Если нужно несколько значений по умолчанию, разделите их запятыми(,).'; - $lang->about_search_virtual_site = "가상 사이트(카페XE등)의 도메인을 입력하신 후 검색하세요.
가상 사이트이외의 모듈은 내용을 비우고 검색하시면 됩니다. (http:// 는 제외)"; - $lang->about_langcode = "언어별로 다르게 설정하고 싶으시면 언어코드 찾기를 이용해주세요"; - $lang->about_file_extension= "%s 파일만 가능합니다."; -?> +virtual_site = "Virtual Site"; + $lang->module_list = "Список модулей"; + $lang->module_index = "Список модулей"; + $lang->module_category = "Категория модуля"; + $lang->module_info = "Информация"; + $lang->add_shortcut = "Добавить ярлыки"; + $lang->module_action = "Действия"; + $lang->module_maker = "Разработчик модуля"; + $lang->module_license = 'Лицензия'; + $lang->module_history = "История обновлений"; + $lang->category_title = "Название категории"; + $lang->header_text = 'Верхний колонтитул'; + $lang->footer_text = 'Нижний колонтитул'; + $lang->use_category = 'Включить категорию'; + $lang->category_title = 'Название категории'; + $lang->checked_count = 'Число выбранных статей'; // translator's note: возможно "checked" следует перевести как "проверенных" + $lang->skin_default_info = 'Информация стандартного скина'; + $lang->skin_author = 'Разработчик скина'; + $lang->skin_license = 'License'; + $lang->skin_history = 'История обновлений'; + $lang->module_selector = "Module Selector"; + $lang->do_selected = "Выбранные..."; + $lang->bundle_setup = "일괄 기본 설정"; + $lang->bundle_addition_setup = "일괄 추가 설정"; + $lang->bundle_grant_setup = "일괄 권한 설정"; + $lang->lang_code = "Код языка"; + $lang->filebox = "Файлбокс"; + + $lang->access_type = 'Способ соединения'; + $lang->access_domain = 'Domain соединения'; + $lang->access_vid = 'Site ID соединение'; + $lang->about_vid = '별도의 도메인이 아닌 http://XE주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다.
첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; + $lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; + $lang->msg_already_registed_domain = '이미 등록된 도메인입니다. 다른 도메인을 사용해주세요'; + + $lang->module_copy = "Копировать модуль"; + + $lang->header_script = "Скрипт Header"; + $lang->about_header_script = "html의 <header>와 </header> 사이에 들어가는 코드를 직접 입력할 수 있습니다.
<script, <style 또는 <meta 태그등을 이용하실 수 있습니다"; + + $lang->grant_access = "Access"; + $lang->grant_manager = "Management"; + + $lang->grant_to_all = "All users"; + $lang->grant_to_login_user = "Logged users"; + $lang->grant_to_site_user = "Joined users"; + $lang->grant_to_group = "Specification group users"; + + $lang->cmd_add_shortcut = "Добавить ярлык"; + $lang->cmd_install = "Установить"; + $lang->cmd_update = "Обновить"; + $lang->cmd_manage_category = 'Управление категориями'; + $lang->cmd_manage_grant = 'Управление правами доступа'; + $lang->cmd_manage_skin = 'Управление скинами'; + $lang->cmd_manage_document = 'Управление статьями'; + $lang->cmd_find_module = 'Искать модуль'; + $lang->cmd_find_langcode = 'Find lang code'; + + $lang->msg_new_module = "Создать новый модуль"; + $lang->msg_update_module = "Изменить модуль"; + $lang->msg_module_name_exists = "Имя уже существует. Пожалуйста, попробуйте другое"; + $lang->msg_category_is_null = 'Зарегистрированной категории не существует.'; + $lang->msg_grant_is_null = 'Списка для управления правами доступа не существует.'; + $lang->msg_no_checked_document = 'Нет выбранных статей.'; // translator's note: выше... + $lang->msg_move_failed = 'Невозможно переместить'; + $lang->msg_cannot_delete_for_child = 'Невозможно удалить категорию, имеющую дочерние категории.'; + $lang->msg_limit_mid ='모듈이름은 영문+[영문+숫자+_] 만 가능합니다.'; + $lang->msg_extra_name_exists = '이미 존재하는 확장변수 이름입니다. 다른 이름을 입력해주세요.'; + + $lang->about_browser_title = "Это будет показано в заголовке браузера. Также, это будет использоваться в RSS/Трекбеке."; + $lang->about_mid = "Имя модуля будет использовано как http://address/?mid=Имя_модуля.\n(только латиница, цифры и символ подчеркивания(_) разрешены. The maximum length is 40.)"; + $lang->about_default = "Если выбрано, модуль будет главным на сайте. Для доступа не нужен будет идентификатор модуля."; + $lang->about_module_category = "Это позволяет Вам управлять посредством категорий модулей.\nURL для менеджера модулей Manage module > Категория Модуля ."; + $lang->about_description= 'Это описание только для менеджера.'; + $lang->about_default = 'Если выбрано, этот модуль будет показан, когда пользователи входят на сайт без идентификатора модуля (mid=NoValue).'; + $lang->about_header_text = 'Это содержимое будет показано сверху модуля. (HTML разрешен)'; + $lang->about_footer_text = 'Это содержимое будет показано снизу модуля. (HTML разрешен)'; + $lang->about_skin = 'Вы можете выбрать скин модуля.'; + $lang->about_use_category = 'Если выбрано, функция категорий будет включена.'; + $lang->about_list_count = 'Вы можете установить лимит показа статей на страницу. (по умолчанию: 20)'; + $lang->about_search_list_count = '검색 또는 카테고리 선택등을 할 경우 표시될 글의 수를 지정하실 수 있습니다. 기본(20개)'; + $lang->about_page_count = 'Вы можете установить число страниц внизу. (по умолчанию: 10)'; + $lang->about_admin_id = 'Вы можете разрешить менеджеру иметь полные права доступа к этому модулю.\nВы можете ввести несколько ID, используя '; + $lang->about_grant = 'Если Вы отключите все права доступа для отдельного объекта, не прошедшие процедуру входа на сайт пользователи получат доступ.'; + $lang->about_grant_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; + $lang->about_module = "XE состоит из модулей, за исключением базовой библиотеки.\n Управление модулем покажет все установленные модули и поможет управлять ими."; + + $lang->about_extra_vars_default_value = 'Если нужно несколько значений по умолчанию, разделите их запятыми(,).'; + $lang->about_search_virtual_site = "가상 사이트(카페XE등)의 도메인을 입력하신 후 검색하세요.
가상 사이트이외의 모듈은 내용을 비우고 검색하시면 됩니다. (http:// 는 제외)"; + $lang->about_langcode = "언어별로 다르게 설정하고 싶으시면 언어코드 찾기를 이용해주세요"; + $lang->about_file_extension= "%s 파일만 가능합니다."; +?> diff --git a/modules/module/lang/vi.lang.php b/modules/module/lang/vi.lang.php index 7b27792f8..f002f6473 100644 --- a/modules/module/lang/vi.lang.php +++ b/modules/module/lang/vi.lang.php @@ -1,101 +1,101 @@ -virtual_site = "Site thực"; - $lang->module_list = "Danh sách Module"; - $lang->module_index = "Danh sách Module"; - $lang->module_category = "Thể loại"; - $lang->module_info = "Thông tin Module"; - $lang->add_shortcut = "Thêm phím tắt"; - $lang->module_action = "Hoạt động"; - $lang->module_maker = "Người thiết kế"; - $lang->module_license = 'Giấy phép'; - $lang->module_history = "Lịch sử cập nhật"; - $lang->category_title = "Tiêu đề phân loại"; - $lang->header_text = 'Nội dung Header'; - $lang->footer_text = 'Nội dung Footer'; - $lang->use_category = 'Mở phân loại'; - $lang->category_title = 'Tiêu đề phân loại'; - $lang->checked_count = 'Số bài viết đã chọn'; - $lang->skin_default_info = 'Thông tin Skin mặc định'; - $lang->skin_author = 'Thiết kế'; - $lang->skin_license = 'Giấy phép'; - $lang->skin_history = 'Lịch sử cập nhật'; - $lang->module_copy = "Nhân bản Module"; - $lang->module_selector = "Chọn lọc Module"; - $lang->do_selected = "Bình chọn / Phê bình."; - $lang->bundle_setup = "Gói cài đặt"; - $lang->bundle_addition_setup = "Gói cài đặt bổ xung"; - $lang->bundle_grant_setup = "Gói cài đặt cho phép"; - $lang->lang_code = "Mã ngôn ngữ"; - $lang->filebox = "FileBox"; - - $lang->access_type = 'Kiểu truy cập'; - $lang->access_domain = 'Với tên miền'; - $lang->access_vid = 'Với ID Website'; - $lang->about_domain = "Để tạo nhiều Website nhỏ, các Website nhỏ này cần những tên miền riêng của mình.
Có thể sử dụng những Subdomain dạng aaa.bbb.com của bbb.com. Hãy nhập địa chỉ bao gồm cả Domain cài đặt XE.
Ví dụ: www.vietxe.net/xe"; - $lang->about_vid = 'Người sử dụng có thể truy cập qua http://XEaddress/ID. Bạn không thể sử dụng ID giống nhau và giống tên Module đã có.
Teen ID có dạng là các chữ cái, số và dấu gạch dưới (_).'; - $lang->msg_already_registed_vid = 'Tên ID này đã được đăng kí. Xin hãy chọn tên khác.'; - $lang->msg_already_registed_domain = "Tên miền đã được sử dụng. Xin hãy chọn tên khác."; - - $lang->header_script = "Header Script"; - $lang->about_header_script = "Bạn co thể nhập mã dang HTML vào giữa <header> và </header>.
Bạn có thể sử dụng <script, <style hay <meta tag"; - - $lang->grant_access = "Truy cập"; - $lang->grant_manager = "Quản lý"; - - $lang->grant_to_all = "Tất cả"; - $lang->grant_to_login_user = "Đã đăng nhập"; - $lang->grant_to_site_user = "Đã đăng kí"; - $lang->grant_to_group = "Nhóm chỉ định"; - - $lang->cmd_add_shortcut = "Thêm phím tắt"; - $lang->cmd_install = "Cài đặt"; - $lang->cmd_update = "Cập nhật"; - $lang->cmd_manage_category = 'Quản lý thể loại'; - $lang->cmd_manage_grant = 'Quản lý quyền'; - $lang->cmd_manage_skin = 'Quản lý Skin'; - $lang->cmd_manage_document = 'Quản lý bài viết'; - $lang->cmd_find_module = 'Tìm Module'; - $lang->cmd_find_langcode = 'Tìm mã ngôn ngữ'; - - $lang->msg_new_module = "Tạo Module mới"; - $lang->msg_update_module = "Sửa Module"; - $lang->msg_module_name_exists = "Tên này đã được sử dụng. Hãy thử lại với tên khác."; - $lang->msg_category_is_null = 'Không có phân loại nào được tạo.'; - $lang->msg_grant_is_null = 'Không có danh sách quyền nào.'; - $lang->msg_no_checked_document = 'Không có bài viết nào được kiểm tra.'; - $lang->msg_move_failed = 'Không thể di chuyển'; - $lang->msg_cannot_delete_for_child = 'Không thể xóa được phân loại khi có những phân loại con.'; - $lang->msg_limit_mid ="Tên Module chỉ hỗ trợ định dạng [Kí tự], [Kí tự+Số], [Kí tự+Số+_]."; - $lang->msg_extra_name_exists = 'Tên biến đã được sử dụng. Xin hãy chọn tên khác.'; - - $lang->about_browser_title = "Nó sẽ hiển thị trên tiêu đề của trình duyệt và trong RSS/Trackback."; - $lang->about_mid = "Tên Module được sử dụng dạng http://address/?mid=ModuleName.\n(Chỉ cho phép chữ cái tiếng Anh + [chữ cái tiếng Anh, số, và dấu gạch dưới (_)] và tối đa 40 kí tự.)"; - $lang->about_default = "Nếu chọn, Sẽ hiển thị mặc định là (mid=NoValue) khi truy cập tên Module không đúng."; - $lang->about_module_category = "Nó cho phép bạn quản lý thông qua Module thể loại.\n URL quản lý có dạng Quản lý Module > Module thể loại ."; - $lang->about_description= 'Mô tả cho một quản lý.'; - $lang->about_default = 'Nếu chọn, Sẽ hiển thị mặc định là (mid=NoValue) khi truy cập tên Module không đúng.'; - $lang->about_header_text = 'Nội dung sẽ hiển thị trên đầu Module.(sau http tag có sẵn)'; - $lang->about_footer_text = 'Nội dung sẽ hiển thị phía dưới Module.(trước http tag có sẵn)'; - $lang->about_skin = 'Banj có thể chọn Skin cho Module.'; - $lang->about_use_category = 'Nếu chon, chức năng thể loại sẽ hoạt động.'; - $lang->about_list_count = 'Bạn có thể giới hạn bài viết hiển thị trên một trang.(Mặc định là 20)'; - $lang->about_search_list_count = 'Bạn có thể đặt giới hạn số bài viết sẽ hiển thị khi tìm kiếm hay chọn thể loại. (Mặc định là 20)'; - $lang->about_page_count = 'bạn có thể giới hạn số trang liên kết hiển thị phía dưới.(Mặc định là 10)'; - $lang->about_admin_id = 'Bạn có thể đặt quyền hạn cho người sử dụng khi truy cập tới Module.'; - $lang->about_grant = 'Nếu bạn khóa tất cả quyền hạn cho một thành viên đặc biệt nào đó, những thành viên đó sẽ không được phép đăng nhập.'; - $lang->about_grant_deatil = 'Khi thành viên dăng kí tại trang chủ, nghĩa là họ cũng là thành viên của những trang khác (Ví dụ: cafeXE,...).'; - $lang->about_module = "Khu vực Module trong XE ngoại trừ Library là tại [Module Manage]. Tất cả những Module đang có sẽ hiển thị, giúp bạn quản lý một cách dễ dàng."; - - $lang->about_extra_vars_default_value = 'Nếu cần nhiều giá trị mặc định, bạn có thể thêm dấu (,) và giữa các kết nối.'; - $lang->about_search_virtual_site = "Hãy nhập tên miền thực tế của Website.
Để tìm kiếm những Module không thực tế của Website hãy để trống."; - $lang->about_langcode = "Nếu bạn muốn sử dụng định hình riêng, hãy sử dụng 'Tìm kiếm mã ngôn ngữ'"; - $lang->about_file_extension= "Chỉ cho phép những phần mở rộng là: %s."; -?> +virtual_site = "Site thực"; + $lang->module_list = "Danh sách Module"; + $lang->module_index = "Danh sách Module"; + $lang->module_category = "Thể loại"; + $lang->module_info = "Thông tin Module"; + $lang->add_shortcut = "Thêm phím tắt"; + $lang->module_action = "Hoạt động"; + $lang->module_maker = "Người thiết kế"; + $lang->module_license = 'Giấy phép'; + $lang->module_history = "Lịch sử cập nhật"; + $lang->category_title = "Tiêu đề phân loại"; + $lang->header_text = 'Nội dung Header'; + $lang->footer_text = 'Nội dung Footer'; + $lang->use_category = 'Mở phân loại'; + $lang->category_title = 'Tiêu đề phân loại'; + $lang->checked_count = 'Số bài viết đã chọn'; + $lang->skin_default_info = 'Thông tin Skin mặc định'; + $lang->skin_author = 'Thiết kế'; + $lang->skin_license = 'Giấy phép'; + $lang->skin_history = 'Lịch sử cập nhật'; + $lang->module_copy = "Nhân bản Module"; + $lang->module_selector = "Chọn lọc Module"; + $lang->do_selected = "Bình chọn / Phê bình."; + $lang->bundle_setup = "Gói cài đặt"; + $lang->bundle_addition_setup = "Gói cài đặt bổ xung"; + $lang->bundle_grant_setup = "Gói cài đặt cho phép"; + $lang->lang_code = "Mã ngôn ngữ"; + $lang->filebox = "FileBox"; + + $lang->access_type = 'Kiểu truy cập'; + $lang->access_domain = 'Với tên miền'; + $lang->access_vid = 'Với ID Website'; + $lang->about_domain = "Để tạo nhiều Website nhỏ, các Website nhỏ này cần những tên miền riêng của mình.
Có thể sử dụng những Subdomain dạng aaa.bbb.com của bbb.com. Hãy nhập địa chỉ bao gồm cả Domain cài đặt XE.
Ví dụ: www.vietxe.net/xe"; + $lang->about_vid = 'Người sử dụng có thể truy cập qua http://XEaddress/ID. Bạn không thể sử dụng ID giống nhau và giống tên Module đã có.
Teen ID có dạng là các chữ cái, số và dấu gạch dưới (_).'; + $lang->msg_already_registed_vid = 'Tên ID này đã được đăng kí. Xin hãy chọn tên khác.'; + $lang->msg_already_registed_domain = "Tên miền đã được sử dụng. Xin hãy chọn tên khác."; + + $lang->header_script = "Header Script"; + $lang->about_header_script = "Bạn co thể nhập mã dang HTML vào giữa <header> và </header>.
Bạn có thể sử dụng <script, <style hay <meta tag"; + + $lang->grant_access = "Truy cập"; + $lang->grant_manager = "Quản lý"; + + $lang->grant_to_all = "Tất cả"; + $lang->grant_to_login_user = "Đã đăng nhập"; + $lang->grant_to_site_user = "Đã đăng kí"; + $lang->grant_to_group = "Nhóm chỉ định"; + + $lang->cmd_add_shortcut = "Thêm phím tắt"; + $lang->cmd_install = "Cài đặt"; + $lang->cmd_update = "Cập nhật"; + $lang->cmd_manage_category = 'Quản lý thể loại'; + $lang->cmd_manage_grant = 'Quản lý quyền'; + $lang->cmd_manage_skin = 'Quản lý Skin'; + $lang->cmd_manage_document = 'Quản lý bài viết'; + $lang->cmd_find_module = 'Tìm Module'; + $lang->cmd_find_langcode = 'Tìm mã ngôn ngữ'; + + $lang->msg_new_module = "Tạo Module mới"; + $lang->msg_update_module = "Sửa Module"; + $lang->msg_module_name_exists = "Tên này đã được sử dụng. Hãy thử lại với tên khác."; + $lang->msg_category_is_null = 'Không có phân loại nào được tạo.'; + $lang->msg_grant_is_null = 'Không có danh sách quyền nào.'; + $lang->msg_no_checked_document = 'Không có bài viết nào được kiểm tra.'; + $lang->msg_move_failed = 'Không thể di chuyển'; + $lang->msg_cannot_delete_for_child = 'Không thể xóa được phân loại khi có những phân loại con.'; + $lang->msg_limit_mid ="Tên Module chỉ hỗ trợ định dạng [Kí tự], [Kí tự+Số], [Kí tự+Số+_]."; + $lang->msg_extra_name_exists = 'Tên biến đã được sử dụng. Xin hãy chọn tên khác.'; + + $lang->about_browser_title = "Nó sẽ hiển thị trên tiêu đề của trình duyệt và trong RSS/Trackback."; + $lang->about_mid = "Tên Module được sử dụng dạng http://address/?mid=ModuleName.\n(Chỉ cho phép chữ cái tiếng Anh + [chữ cái tiếng Anh, số, và dấu gạch dưới (_)] và tối đa 40 kí tự.)"; + $lang->about_default = "Nếu chọn, Sẽ hiển thị mặc định là (mid=NoValue) khi truy cập tên Module không đúng."; + $lang->about_module_category = "Nó cho phép bạn quản lý thông qua Module thể loại.\n URL quản lý có dạng Quản lý Module > Module thể loại ."; + $lang->about_description= 'Mô tả cho một quản lý.'; + $lang->about_default = 'Nếu chọn, Sẽ hiển thị mặc định là (mid=NoValue) khi truy cập tên Module không đúng.'; + $lang->about_header_text = 'Nội dung sẽ hiển thị trên đầu Module.(sau http tag có sẵn)'; + $lang->about_footer_text = 'Nội dung sẽ hiển thị phía dưới Module.(trước http tag có sẵn)'; + $lang->about_skin = 'Banj có thể chọn Skin cho Module.'; + $lang->about_use_category = 'Nếu chon, chức năng thể loại sẽ hoạt động.'; + $lang->about_list_count = 'Bạn có thể giới hạn bài viết hiển thị trên một trang.(Mặc định là 20)'; + $lang->about_search_list_count = 'Bạn có thể đặt giới hạn số bài viết sẽ hiển thị khi tìm kiếm hay chọn thể loại. (Mặc định là 20)'; + $lang->about_page_count = 'bạn có thể giới hạn số trang liên kết hiển thị phía dưới.(Mặc định là 10)'; + $lang->about_admin_id = 'Bạn có thể đặt quyền hạn cho người sử dụng khi truy cập tới Module.'; + $lang->about_grant = 'Nếu bạn khóa tất cả quyền hạn cho một thành viên đặc biệt nào đó, những thành viên đó sẽ không được phép đăng nhập.'; + $lang->about_grant_deatil = 'Khi thành viên dăng kí tại trang chủ, nghĩa là họ cũng là thành viên của những trang khác (Ví dụ: cafeXE,...).'; + $lang->about_module = "Khu vực Module trong XE ngoại trừ Library là tại [Module Manage]. Tất cả những Module đang có sẽ hiển thị, giúp bạn quản lý một cách dễ dàng."; + + $lang->about_extra_vars_default_value = 'Nếu cần nhiều giá trị mặc định, bạn có thể thêm dấu (,) và giữa các kết nối.'; + $lang->about_search_virtual_site = "Hãy nhập tên miền thực tế của Website.
Để tìm kiếm những Module không thực tế của Website hãy để trống."; + $lang->about_langcode = "Nếu bạn muốn sử dụng định hình riêng, hãy sử dụng 'Tìm kiếm mã ngôn ngữ'"; + $lang->about_file_extension= "Chỉ cho phép những phần mở rộng là: %s."; +?> diff --git a/modules/module/lang/zh-CN.lang.php b/modules/module/lang/zh-CN.lang.php index 18410dc61..0a47be86e 100644 --- a/modules/module/lang/zh-CN.lang.php +++ b/modules/module/lang/zh-CN.lang.php @@ -1,7 +1,7 @@ title = Context::get('title'); - $output = executeQuery('module.insertModuleCategory', $args); - if(!$output->toBool()) return $output; - - $this->setMessage("success_registed"); - } - - /** - * @brief 카테고리의 내용 수정 - **/ - function procModuleAdminUpdateCategory() { - $mode = Context::get('mode'); - - switch($mode) { - case 'delete' : - $output = $this->doDeleteModuleCategory(); - $msg_code = 'success_deleted'; - break; - case 'update' : - $output = $this->doUpdateModuleCategory(); - $msg_code = 'success_updated'; - break; - } - if(!$output->toBool()) return $output; - - $this->setMessage($msg_code); - } - - /** - * @brief 모듈 카테고리의 제목 변경 - **/ - function doUpdateModuleCategory() { - $args->title = Context::get('title'); - $args->module_category_srl = Context::get('module_category_srl'); - return executeQuery('module.updateModuleCategory', $args); - } - - /** - * @brief 모듈 카테고리 삭제 - **/ - function doDeleteModuleCategory() { - $args->module_category_srl = Context::get('module_category_srl'); - return executeQuery('module.deleteModuleCategory', $args); - } - - /** - * @brief 모듈 복사 - **/ - function procModuleAdminCopyModule() { - // 복사하려는 대상 모듈의 정보를 구함 - $module_srl = Context::get('module_srl'); - if(!$module_srl) return; - - // 새로 생성하려는 모듈들의 이름/브라우저 제목을 구함 - $clones = array(); - $args = Context::getAll(); - for($i=1;$i<=10;$i++) { - $mid = trim($args->{"mid_".$i}); - if(!$mid) continue; - if(!preg_match("/^[a-zA-Z]([a-zA-Z0-9_]*)$/i", $mid)) return new Object(-1, 'msg_limit_mid'); - $browser_title = $args->{"browser_title_".$i}; - if(!$mid) continue; - if($mid && !$browser_title) $browser_title = $mid; - $clones[$mid] = $browser_title; - } - if(!count($clones)) return; - - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - - // 모듈 정보 가져옴 - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - - // 권한 정보 가져옴 - $module_args->module_srl = $module_srl; - $output = executeQueryArray('module.getModuleGrants', $module_args); - $grant = array(); - if($output->data) { - foreach($output->data as $key => $val) $grant[$val->name][] = $val->group_srl; - } - - - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 모듈 복사 - foreach($clones as $mid => $browser_title) { - $clone_args = null; - $clone_args = clone($module_info); - $clone_args->module_srl = null; - $clone_args->content = null; - $clone_args->mid = $mid; - $clone_args->browser_title = $browser_title; - $clone_args->is_default = 'N'; - - // 모듈 생성 - $output = $oModuleController->insertModule($clone_args); - $module_srl = $output->get('module_srl'); - - // 권한 정보 등록 - if(count($grant)) $oModuleController->insertModuleGrants($module_srl, $grant); - } - - $oDB->commit(); - $this->setMessage('success_registed'); - } - - /** - * @brief 모듈 권한 저장 - **/ - function procModuleAdminInsertGrant() { - $oModuleController = &getController('module'); - $oModuleModel = &getModel('module'); - - // 모듈 번호 구함 - $module_srl = Context::get('module_srl'); - - // 해당 모듈의 정보를 구함 - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - if(!$module_info) return new Object(-1,'msg_invalid_request'); - - // 관리자 아이디 등록 - $oModuleController->deleteAdminId($module_srl); - $admin_member = Context::get('admin_member'); - if($admin_member) { - $admin_members = explode(',',$admin_member); - for($i=0;$iinsertAdminId($module_srl, $admin_id); - - } - } - - // 권한 정리 - $xml_info = $oModuleModel->getModuleActionXML($module_info->module); - - $grant_list = $xml_info->grant; - - $grant_list->access->default = 'guest'; - $grant_list->manager->default = 'manager'; - - foreach($grant_list as $grant_name => $grant_info) { - // default값을 구함 - $default = Context::get($grant_name.'_default'); - - // -1 = 로그인 사용자만, -2 = 사이트 가입자만, 0 = 모든 사용자 - if(strlen($default)){ - $grant->{$grant_name}[] = $default; - continue; - - // 특정 그룹 사용자 - } else { - $group_srls = Context::get($grant_name); - if($group_srls) { - if(strpos($group_srls,'|@|')!==false) $group_srls = explode('|@|',$group_srls); - elseif(strpos($group_srls,',')!==false) $group_srls = explode(',',$group_srls); - else $group_srls = array($group_srls); - $grant->{$grant_name} = $group_srls; - } - continue; - } - $grant->{$group_srls} = array(); - } - - // DB에 저장 - $args->module_srl = $module_srl; - $output = executeQuery('module.deleteModuleGrants', $args); - if(!$output->toBool()) return $output; - - // DB에 권한 저장 - foreach($grant as $grant_name => $group_srls) { - foreach($group_srls as $key => $val) { - $args = null; - $args->module_srl = $module_srl; - $args->name = $grant_name; - $args->group_srl = $val; - $output = executeQuery('module.insertModuleGrant', $args); - if(!$output->toBool()) return $output; - } - } - $this->setMessage('success_registed'); - } - - /** - * @brief 스킨 정보 업데이트 - **/ - function procModuleAdminUpdateSkinInfo() { - // module_srl에 해당하는 정보들을 가져오기 - $module_srl = Context::get('module_srl'); - - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - if($module_info->module_srl) { - $skin = $module_info->skin; - - // 스킨의 정보를 구해옴 (extra_vars를 체크하기 위해서) - $module_path = './modules/'.$module_info->module; - $skin_info = $oModuleModel->loadSkinInfo($module_path, $skin); - $skin_vars = $oModuleModel->getModuleSkinVars($module_srl); - // 입력받은 변수들을 체크 (mo, act, module_srl, page등 기본적인 변수들 없앰) - $obj = Context::getRequestVars(); - unset($obj->act); - unset($obj->module_srl); - unset($obj->page); - unset($obj->mid); - unset($obj->module); - - // 원 skin_info에서 extra_vars의 type이 image일 경우 별도 처리를 해줌 - if($skin_info->extra_vars) { - foreach($skin_info->extra_vars as $vars) { - if($vars->type!='image') continue; - - $image_obj = $obj->{$vars->name}; - - // 삭제 요청에 대한 변수를 구함 - $del_var = $obj->{"del_".$vars->name}; - unset($obj->{"del_".$vars->name}); - if($del_var == 'Y') { - FileHandler::removeFile($skin_vars[$vars->name]->value); - continue; - } - - // 업로드 되지 않았다면 이전 데이터를 그대로 사용 - if(!$image_obj['tmp_name']) { - $obj->{$vars->name} = $module_info->{$vars->name}; - continue; - } - - // 정상적으로 업로드된 파일이 아니면 무시 - if(!is_uploaded_file($image_obj['tmp_name'])) { - unset($obj->{$vars->name}); - continue; - } - - // 이미지 파일이 아니어도 무시 - if(!preg_match("/\.(jpg|jpeg|gif|png)$/i", $image_obj['name'])) { - unset($obj->{$vars->name}); - continue; - } - - // 경로를 정해서 업로드 - $path = sprintf("./files/attach/images/%s/", $module_srl); - - // 디렉토리 생성 - if(!FileHandler::makeDir($path)) return false; - - $filename = $path.$image_obj['name']; - - // 파일 이동 - if(!move_uploaded_file($image_obj['tmp_name'], $filename)) { - unset($obj->{$vars->name}); - continue; - } - - // 정상 파일 업로드 - FileHandler::removeFile($skin_vars[$vars->name]->value); - // 변수를 바꿈 - unset($obj->{$vars->name}); - $obj->{$vars->name} = $filename; - } - } - // 해당 모듈의 전체 스킨 불러와서 이미지는 제거 - /* - if($skin_info->extra_vars) { - foreach($skin_info->extra_vars as $vars) { - if($vars->type!='image') continue; - $value = $skin_vars[$vars->name]; - if(file_exists($value)) @unlink($value); - } - } - */ - $oModuleController = &getController('module'); - $oModuleController->deleteModuleSkinVars($module_srl); - - // 등록 - $oModuleController->insertModuleSkinVars($module_srl, $obj); - } - - $this->setLayoutPath('./common/tpl'); - $this->setLayoutFile('default_layout.html'); - $this->setTemplatePath('./modules/module/tpl'); - $this->setTemplateFile("top_refresh.html"); - } - - /** - * @brief 모듈 일괄 정리 - **/ - function procModuleAdminModuleSetup() { - $vars = Context::getRequestVars(); - - if(!$vars->module_srls) return new Object(-1,'msg_invalid_request'); - - $module_srls = explode(',',$vars->module_srls); - if(!count($module_srls)) return new Object(-1,'msg_invalid_request'); - - $oModuleModel = &getModel('module'); - $oModuleController= &getController('module'); - foreach($module_srls as $module_srl) { - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - $module_info->module_category_srl = $vars->module_category_srl; - $module_info->layout_srl = $vars->layout_srl; - $module_info->skin = $vars->skin; - $module_info->description = $vars->description; - $module_info->header_text = $vars->header_text; - $module_info->footer_text = $vars->footer_text; - $oModuleController->updateModule($module_info); - } - - $this->setMessage('success_registed'); - } - - /** - * @brief 모듈 권한 일괄 정리 - **/ - function procModuleAdminModuleGrantSetup() { - $module_srls = Context::get('module_srls'); - if(!$module_srls) return new Object(-1,'msg_invalid_request'); - - $modules = explode(',',$module_srls); - if(!count($modules)) return new Object(-1,'msg_invalid_request'); - - $oModuleController = &getController('module'); - $oModuleModel = &getModel('module'); - - $module_info = $oModuleModel->getModuleInfoByModuleSrl($modules[0]); - $xml_info = $oModuleModel->getModuleActionXml($module_info->module); - $grant_list = $xml_info->grant; - - $grant_list->access->default = 'guest'; - $grant_list->manager->default = 'manager'; - - foreach($grant_list as $grant_name => $grant_info) { - // default값을 구함 - $default = Context::get($grant_name.'_default'); - - // -1 = 로그인 사용자만, 0 = 모든 사용자 - if(strlen($default)){ - $grant->{$grant_name}[] = $default; - continue; - - // 특정 그룹 사용자 - } else { - $group_srls = Context::get($grant_name); - if($group_srls) { - if(strpos($group_srls,'|@|')!==false) $group_srls = explode('|@|',$group_srls); - elseif(strpos($group_srls,',')!==false) $group_srls = explode(',',$group_srls); - else $group_srls = array($group_srls); - $grant->{$grant_name} = $group_srls; - } - continue; - } - $grant->{$group_srls} = array(); - } - - - // DB에 저장 - foreach($modules as $module_srl) { - $args = null; - $args->module_srl = $module_srl; - $output = executeQuery('module.deleteModuleGrants', $args); - if(!$output->toBool()) continue; - - // DB에 권한 저장 - foreach($grant as $grant_name => $group_srls) { - foreach($group_srls as $key => $val) { - $args = null; - $args->module_srl = $module_srl; - $args->name = $grant_name; - $args->group_srl = $val; - $output = executeQuery('module.insertModuleGrant', $args); - if(!$output->toBool()) return $output; - } - } - } - $this->setMessage('success_registed'); - } - - /** - * @brief 언어 추가/ 업데이트 - **/ - function procModuleAdminInsertLang() { - // 언어코드명 가져옴 - $site_module_info = Context::get('site_module_info'); - $args->site_srl = (int)$site_module_info->site_srl; - $args->name = str_replace(' ','_',Context::get('lang_code')); - if(!$args->name) return new Object(-1,'msg_invalid_request'); - - // 언어코드가 있는지 조사 - $output = executeQueryArray('module.getLang', $args); - if(!$output->toBool()) return $output; - - // 있으면 업데이트를 위해 기존 값들을 지움 - if($output->data) $output = executeQuery('module.deleteLang', $args); - if(!$output->toBool()) return $output; - - // 입력 - $lang_supported = Context::get('lang_supported'); - foreach($lang_supported as $key => $val) { - $args->lang_code = $key; - $args->value = trim(Context::get($key)); - if(!$args->value) { - $args->value = Context::get(strtolower($key)); - if(!$args->value) $args->value = $args->name; - } - $output = executeQuery('module.insertLang', $args); - if(!$output->toBool()) return $output; - } - $this->makeCacheDefinedLangCode($args->site_srl); - - $this->add('name', $args->name); - } - - /** - * @brief 언어 제거 - **/ - function procModuleAdminDeleteLang() { - // 언어코드명 가져옴 - $site_module_info = Context::get('site_module_info'); - $args->site_srl = (int)$site_module_info->site_srl; - $args->name = str_replace(' ','_',Context::get('name')); - if(!$args->name) return new Object(-1,'msg_invalid_request'); - - $output = executeQuery('module.deleteLang', $args); - if(!$output->toBool()) return $output; - $this->makeCacheDefinedLangCode($args->site_srl); - } - - /** - * @brief 사용자 정이 언어코드 파일 저장 - **/ - function makeCacheDefinedLangCode($site_srl = 0) { - // 현재 사이트의 언어파일 가져오기 - if(!$site_srl) { - $site_module_info = Context::get('site_module_info'); - $args->site_srl = (int)$site_module_info->site_srl; - } else { - $args->site_srl = $site_srl; - } - $output = executeQueryArray('module.getLang', $args); - if(!$output->toBool() || !$output->data) return; - - // 캐시 디렉토리 설정 - $cache_path = _XE_PATH_.'files/cache/lang_defined/'; - if(!is_dir($cache_path)) FileHandler::makeDir($cache_path); - - $lang_supported = Context::get('lang_supported'); - foreach($lang_supported as $key => $val) { - $fp[$key] = fopen( sprintf('%s/%d.%s.php', $cache_path, $args->site_srl, $key), 'w' ); - if(!$fp[$key]) return; - fwrite($fp[$key],"data as $key => $val) { - if($fp[$val->lang_code]) fwrite($fp[$val->lang_code], sprintf('$lang["%s"] = "%s";'."\r\n", $val->name, str_replace('"','\\"',$val->value))); - } - - foreach($lang_supported as $key => $val) { - if(!$fp[$key]) continue; - fwrite($fp[$key],"?>"); - fclose($fp[$key]); - } - } - - } -?> +title = Context::get('title'); + $output = executeQuery('module.insertModuleCategory', $args); + if(!$output->toBool()) return $output; + + $this->setMessage("success_registed"); + } + + /** + * @brief 카테고리의 내용 수정 + **/ + function procModuleAdminUpdateCategory() { + $mode = Context::get('mode'); + + switch($mode) { + case 'delete' : + $output = $this->doDeleteModuleCategory(); + $msg_code = 'success_deleted'; + break; + case 'update' : + $output = $this->doUpdateModuleCategory(); + $msg_code = 'success_updated'; + break; + } + if(!$output->toBool()) return $output; + + $this->setMessage($msg_code); + } + + /** + * @brief 모듈 카테고리의 제목 변경 + **/ + function doUpdateModuleCategory() { + $args->title = Context::get('title'); + $args->module_category_srl = Context::get('module_category_srl'); + return executeQuery('module.updateModuleCategory', $args); + } + + /** + * @brief 모듈 카테고리 삭제 + **/ + function doDeleteModuleCategory() { + $args->module_category_srl = Context::get('module_category_srl'); + return executeQuery('module.deleteModuleCategory', $args); + } + + /** + * @brief 모듈 복사 + **/ + function procModuleAdminCopyModule() { + // 복사하려는 대상 모듈의 정보를 구함 + $module_srl = Context::get('module_srl'); + if(!$module_srl) return; + + // 새로 생성하려는 모듈들의 이름/브라우저 제목을 구함 + $clones = array(); + $args = Context::getAll(); + for($i=1;$i<=10;$i++) { + $mid = trim($args->{"mid_".$i}); + if(!$mid) continue; + if(!preg_match("/^[a-zA-Z]([a-zA-Z0-9_]*)$/i", $mid)) return new Object(-1, 'msg_limit_mid'); + $browser_title = $args->{"browser_title_".$i}; + if(!$mid) continue; + if($mid && !$browser_title) $browser_title = $mid; + $clones[$mid] = $browser_title; + } + if(!count($clones)) return; + + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + + // 모듈 정보 가져옴 + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + + // 권한 정보 가져옴 + $module_args->module_srl = $module_srl; + $output = executeQueryArray('module.getModuleGrants', $module_args); + $grant = array(); + if($output->data) { + foreach($output->data as $key => $val) $grant[$val->name][] = $val->group_srl; + } + + + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 모듈 복사 + foreach($clones as $mid => $browser_title) { + $clone_args = null; + $clone_args = clone($module_info); + $clone_args->module_srl = null; + $clone_args->content = null; + $clone_args->mid = $mid; + $clone_args->browser_title = $browser_title; + $clone_args->is_default = 'N'; + + // 모듈 생성 + $output = $oModuleController->insertModule($clone_args); + $module_srl = $output->get('module_srl'); + + // 권한 정보 등록 + if(count($grant)) $oModuleController->insertModuleGrants($module_srl, $grant); + } + + $oDB->commit(); + $this->setMessage('success_registed'); + } + + /** + * @brief 모듈 권한 저장 + **/ + function procModuleAdminInsertGrant() { + $oModuleController = &getController('module'); + $oModuleModel = &getModel('module'); + + // 모듈 번호 구함 + $module_srl = Context::get('module_srl'); + + // 해당 모듈의 정보를 구함 + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + if(!$module_info) return new Object(-1,'msg_invalid_request'); + + // 관리자 아이디 등록 + $oModuleController->deleteAdminId($module_srl); + $admin_member = Context::get('admin_member'); + if($admin_member) { + $admin_members = explode(',',$admin_member); + for($i=0;$iinsertAdminId($module_srl, $admin_id); + + } + } + + // 권한 정리 + $xml_info = $oModuleModel->getModuleActionXML($module_info->module); + + $grant_list = $xml_info->grant; + + $grant_list->access->default = 'guest'; + $grant_list->manager->default = 'manager'; + + foreach($grant_list as $grant_name => $grant_info) { + // default값을 구함 + $default = Context::get($grant_name.'_default'); + + // -1 = 로그인 사용자만, -2 = 사이트 가입자만, 0 = 모든 사용자 + if(strlen($default)){ + $grant->{$grant_name}[] = $default; + continue; + + // 특정 그룹 사용자 + } else { + $group_srls = Context::get($grant_name); + if($group_srls) { + if(strpos($group_srls,'|@|')!==false) $group_srls = explode('|@|',$group_srls); + elseif(strpos($group_srls,',')!==false) $group_srls = explode(',',$group_srls); + else $group_srls = array($group_srls); + $grant->{$grant_name} = $group_srls; + } + continue; + } + $grant->{$group_srls} = array(); + } + + // DB에 저장 + $args->module_srl = $module_srl; + $output = executeQuery('module.deleteModuleGrants', $args); + if(!$output->toBool()) return $output; + + // DB에 권한 저장 + foreach($grant as $grant_name => $group_srls) { + foreach($group_srls as $key => $val) { + $args = null; + $args->module_srl = $module_srl; + $args->name = $grant_name; + $args->group_srl = $val; + $output = executeQuery('module.insertModuleGrant', $args); + if(!$output->toBool()) return $output; + } + } + $this->setMessage('success_registed'); + } + + /** + * @brief 스킨 정보 업데이트 + **/ + function procModuleAdminUpdateSkinInfo() { + // module_srl에 해당하는 정보들을 가져오기 + $module_srl = Context::get('module_srl'); + + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + if($module_info->module_srl) { + $skin = $module_info->skin; + + // 스킨의 정보를 구해옴 (extra_vars를 체크하기 위해서) + $module_path = './modules/'.$module_info->module; + $skin_info = $oModuleModel->loadSkinInfo($module_path, $skin); + $skin_vars = $oModuleModel->getModuleSkinVars($module_srl); + // 입력받은 변수들을 체크 (mo, act, module_srl, page등 기본적인 변수들 없앰) + $obj = Context::getRequestVars(); + unset($obj->act); + unset($obj->module_srl); + unset($obj->page); + unset($obj->mid); + unset($obj->module); + + // 원 skin_info에서 extra_vars의 type이 image일 경우 별도 처리를 해줌 + if($skin_info->extra_vars) { + foreach($skin_info->extra_vars as $vars) { + if($vars->type!='image') continue; + + $image_obj = $obj->{$vars->name}; + + // 삭제 요청에 대한 변수를 구함 + $del_var = $obj->{"del_".$vars->name}; + unset($obj->{"del_".$vars->name}); + if($del_var == 'Y') { + FileHandler::removeFile($skin_vars[$vars->name]->value); + continue; + } + + // 업로드 되지 않았다면 이전 데이터를 그대로 사용 + if(!$image_obj['tmp_name']) { + $obj->{$vars->name} = $module_info->{$vars->name}; + continue; + } + + // 정상적으로 업로드된 파일이 아니면 무시 + if(!is_uploaded_file($image_obj['tmp_name'])) { + unset($obj->{$vars->name}); + continue; + } + + // 이미지 파일이 아니어도 무시 + if(!preg_match("/\.(jpg|jpeg|gif|png)$/i", $image_obj['name'])) { + unset($obj->{$vars->name}); + continue; + } + + // 경로를 정해서 업로드 + $path = sprintf("./files/attach/images/%s/", $module_srl); + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) return false; + + $filename = $path.$image_obj['name']; + + // 파일 이동 + if(!move_uploaded_file($image_obj['tmp_name'], $filename)) { + unset($obj->{$vars->name}); + continue; + } + + // 정상 파일 업로드 + FileHandler::removeFile($skin_vars[$vars->name]->value); + // 변수를 바꿈 + unset($obj->{$vars->name}); + $obj->{$vars->name} = $filename; + } + } + // 해당 모듈의 전체 스킨 불러와서 이미지는 제거 + /* + if($skin_info->extra_vars) { + foreach($skin_info->extra_vars as $vars) { + if($vars->type!='image') continue; + $value = $skin_vars[$vars->name]; + if(file_exists($value)) @unlink($value); + } + } + */ + $oModuleController = &getController('module'); + $oModuleController->deleteModuleSkinVars($module_srl); + + // 등록 + $oModuleController->insertModuleSkinVars($module_srl, $obj); + } + + $this->setLayoutPath('./common/tpl'); + $this->setLayoutFile('default_layout.html'); + $this->setTemplatePath('./modules/module/tpl'); + $this->setTemplateFile("top_refresh.html"); + } + + /** + * @brief 모듈 일괄 정리 + **/ + function procModuleAdminModuleSetup() { + $vars = Context::getRequestVars(); + + if(!$vars->module_srls) return new Object(-1,'msg_invalid_request'); + + $module_srls = explode(',',$vars->module_srls); + if(!count($module_srls)) return new Object(-1,'msg_invalid_request'); + + $oModuleModel = &getModel('module'); + $oModuleController= &getController('module'); + foreach($module_srls as $module_srl) { + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + $module_info->module_category_srl = $vars->module_category_srl; + $module_info->layout_srl = $vars->layout_srl; + $module_info->skin = $vars->skin; + $module_info->description = $vars->description; + $module_info->header_text = $vars->header_text; + $module_info->footer_text = $vars->footer_text; + $oModuleController->updateModule($module_info); + } + + $this->setMessage('success_registed'); + } + + /** + * @brief 모듈 권한 일괄 정리 + **/ + function procModuleAdminModuleGrantSetup() { + $module_srls = Context::get('module_srls'); + if(!$module_srls) return new Object(-1,'msg_invalid_request'); + + $modules = explode(',',$module_srls); + if(!count($modules)) return new Object(-1,'msg_invalid_request'); + + $oModuleController = &getController('module'); + $oModuleModel = &getModel('module'); + + $module_info = $oModuleModel->getModuleInfoByModuleSrl($modules[0]); + $xml_info = $oModuleModel->getModuleActionXml($module_info->module); + $grant_list = $xml_info->grant; + + $grant_list->access->default = 'guest'; + $grant_list->manager->default = 'manager'; + + foreach($grant_list as $grant_name => $grant_info) { + // default값을 구함 + $default = Context::get($grant_name.'_default'); + + // -1 = 로그인 사용자만, 0 = 모든 사용자 + if(strlen($default)){ + $grant->{$grant_name}[] = $default; + continue; + + // 특정 그룹 사용자 + } else { + $group_srls = Context::get($grant_name); + if($group_srls) { + if(strpos($group_srls,'|@|')!==false) $group_srls = explode('|@|',$group_srls); + elseif(strpos($group_srls,',')!==false) $group_srls = explode(',',$group_srls); + else $group_srls = array($group_srls); + $grant->{$grant_name} = $group_srls; + } + continue; + } + $grant->{$group_srls} = array(); + } + + + // DB에 저장 + foreach($modules as $module_srl) { + $args = null; + $args->module_srl = $module_srl; + $output = executeQuery('module.deleteModuleGrants', $args); + if(!$output->toBool()) continue; + + // DB에 권한 저장 + foreach($grant as $grant_name => $group_srls) { + foreach($group_srls as $key => $val) { + $args = null; + $args->module_srl = $module_srl; + $args->name = $grant_name; + $args->group_srl = $val; + $output = executeQuery('module.insertModuleGrant', $args); + if(!$output->toBool()) return $output; + } + } + } + $this->setMessage('success_registed'); + } + + /** + * @brief 언어 추가/ 업데이트 + **/ + function procModuleAdminInsertLang() { + // 언어코드명 가져옴 + $site_module_info = Context::get('site_module_info'); + $args->site_srl = (int)$site_module_info->site_srl; + $args->name = str_replace(' ','_',Context::get('lang_code')); + if(!$args->name) return new Object(-1,'msg_invalid_request'); + + // 언어코드가 있는지 조사 + $output = executeQueryArray('module.getLang', $args); + if(!$output->toBool()) return $output; + + // 있으면 업데이트를 위해 기존 값들을 지움 + if($output->data) $output = executeQuery('module.deleteLang', $args); + if(!$output->toBool()) return $output; + + // 입력 + $lang_supported = Context::get('lang_supported'); + foreach($lang_supported as $key => $val) { + $args->lang_code = $key; + $args->value = trim(Context::get($key)); + if(!$args->value) { + $args->value = Context::get(strtolower($key)); + if(!$args->value) $args->value = $args->name; + } + $output = executeQuery('module.insertLang', $args); + if(!$output->toBool()) return $output; + } + $this->makeCacheDefinedLangCode($args->site_srl); + + $this->add('name', $args->name); + } + + /** + * @brief 언어 제거 + **/ + function procModuleAdminDeleteLang() { + // 언어코드명 가져옴 + $site_module_info = Context::get('site_module_info'); + $args->site_srl = (int)$site_module_info->site_srl; + $args->name = str_replace(' ','_',Context::get('name')); + if(!$args->name) return new Object(-1,'msg_invalid_request'); + + $output = executeQuery('module.deleteLang', $args); + if(!$output->toBool()) return $output; + $this->makeCacheDefinedLangCode($args->site_srl); + } + + /** + * @brief 사용자 정이 언어코드 파일 저장 + **/ + function makeCacheDefinedLangCode($site_srl = 0) { + // 현재 사이트의 언어파일 가져오기 + if(!$site_srl) { + $site_module_info = Context::get('site_module_info'); + $args->site_srl = (int)$site_module_info->site_srl; + } else { + $args->site_srl = $site_srl; + } + $output = executeQueryArray('module.getLang', $args); + if(!$output->toBool() || !$output->data) return; + + // 캐시 디렉토리 설정 + $cache_path = _XE_PATH_.'files/cache/lang_defined/'; + if(!is_dir($cache_path)) FileHandler::makeDir($cache_path); + + $lang_supported = Context::get('lang_supported'); + foreach($lang_supported as $key => $val) { + $fp[$key] = fopen( sprintf('%s/%d.%s.php', $cache_path, $args->site_srl, $key), 'w' ); + if(!$fp[$key]) return; + fwrite($fp[$key],"data as $key => $val) { + if($fp[$val->lang_code]) fwrite($fp[$val->lang_code], sprintf('$lang["%s"] = "%s";'."\r\n", $val->name, str_replace('"','\\"',$val->value))); + } + + foreach($lang_supported as $key => $val) { + if(!$fp[$key]) continue; + fwrite($fp[$key],"?>"); + fclose($fp[$key]); + } + } + + } +?> diff --git a/modules/module/module.admin.model.php b/modules/module/module.admin.model.php index afadd762f..2b54c7458 100644 --- a/modules/module/module.admin.model.php +++ b/modules/module/module.admin.model.php @@ -1,189 +1,189 @@ -module_srls = Context::get('module_srls'); - $output = executeQueryArray('module.getModulesInfo', $args); - if(!$output->toBool() || !$output->data) return new Object(); - - foreach($output->data as $key => $val) { - $list[$val->module_srl] = array('module_srl'=>$val->module_srl,'mid'=>$val->mid,'browser_title'=>$val->browser_title); - } - $modules = explode(',',$args->module_srls); - for($i=0;$iadd('id', Context::get('id')); - $this->add('module_list', $module_list); - } - - function getModuleMidList($args){ - $args->list_count = 20; - $args->page_count = 10; - $output = executeQueryArray('module.getModuleMidList', $args); - if(!$output->toBool()) return $output; - - ModuleModel::syncModuleToSite($output->data); - - return $output; - } - - /** - * @brief 공통 :: 모듈의 모듈 권한 출력 페이지 - * 모듈의 모듈 권한 출력은 모든 모듈에서 module instance를 이용할때 사용할 수 있음 - **/ - function getModuleGrantHTML($module_srl, $source_grant_list) { - - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - - // access, manager 권한은 가상 권한으로 설정 - $grant_list->access->title = Context::getLang('grant_access'); - $grant_list->access->default = 'guest'; - if(count($source_grant_list)) { - foreach($source_grant_list as $key => $val) { - if(!$val->default) $val->default = 'guest'; - if($val->default == 'root') $val->default = 'manager'; - $grant_list->{$key} = $val; - } - } - $grant_list->manager->title = Context::getLang('grant_manager'); - $grant_list->manager->default = 'manager'; - Context::set('grant_list', $grant_list); - - // 현재 모듈에 설정된 권한 그룹을 가져옴 - $default_grant = array(); - $args->module_srl = $module_srl; - $output = executeQueryArray('module.getModuleGrants', $args); - if($output->data) { - foreach($output->data as $val) { - if($val->group_srl == 0) $default_grant[$val->name] = 'all'; - else if($val->group_srl == -1) $default_grant[$val->name] = 'member'; - else if($val->group_srl == -2) $default_grant[$val->name] = 'site'; - else { - $selected_group[$val->name][] = $val->group_srl; - $default_grant[$val->name] = 'group'; - } - } - } - Context::set('selected_group', $selected_group); - Context::set('default_grant', $default_grant); - Context::set('module_srl', $module_srl); - // 현재 모듈에 설정된 관리자 아이디를 추출 - $admin_member = $oModuleModel->getAdminId($module_srl); - Context::set('admin_member', $admin_member); - - // 그룹을 가져옴 - $oMemberModel = &getModel('member'); - $group_list = $oMemberModel->getGroups($module_info->site_srl); - Context::set('group_list', $group_list); - - // grant 정보를 추출 - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($this->module_path.'tpl', 'module_grants'); - } - - /** - * @brief 공통 :: 모듈의 스킨 설정 출력 페이지 - **/ - function getModuleSkinHTML($module_srl) { - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - if(!$module_info) return; - - $skin = $module_info->skin; - $module_path = './modules/'.$module_info->module; - - // 스킨의 XML 정보를 구함 - $skin_info = $oModuleModel->loadSkinInfo($module_path, $skin); - - // DB에 설정된 스킨 정보를 구함 - $skin_vars = $oModuleModel->getModuleSkinVars($module_srl); - - if(count($skin_info->extra_vars)) { - foreach($skin_info->extra_vars as $key => $val) { - $group = $val->group; - $name = $val->name; - $type = $val->type; - if($skin_vars[$name]) $value = $skin_vars[$name]->value; - else $value = ''; - if($type=="checkbox" && !$value) $value = array(); - $skin_info->extra_vars[$key]->value= $value; - } - } - - Context::set('module_info', $module_info); - Context::set('mid', $module_info->mid); - Context::set('skin_info', $skin_info); - Context::set('skin_vars', $skin_vars); - - $oTemplate = &TemplateHandler::getInstance(); - return $oTemplate->compile($this->module_path.'tpl', 'skin_config'); - } - - /** - * @brief 특정 언어 코드에 대한 값들을 가져오기 - * lang_code를 직접 기입하면 해당 언어코드에 대해서만 가져오고 값이 없으면 $name을 그대로 return - **/ - function getLangCode($site_srl, $name) { - $lang_supported = Context::get('lang_supported'); - - if(substr($name,0,12)=='$user_lang->') { - $args->site_srl = (int)$site_srl; - $args->name = substr($name,12); - $output = executeQueryArray('module.getLang', $args); - if($output->data) { - foreach($output->data as $key => $val) { - $selected_lang[$val->lang_code] = $val->value; - } - } - } else { - $tmp = unserialize($name); - if($tmp) { - $selected_lang = array(); - $rand_name = $tmp[Context::getLangType()]; - if(!$rand_name) $rand_name = array_shift($tmp); - foreach($lang_supported as $key => $val) { - $selected_lang[$key] = $tmp[$key]?$tmp[$key]:$rand_name; - } - } - } - - $output = array(); - foreach($lang_supported as $key => $val) { - $output[$key] = $selected_lang[$key]?$selected_lang[$key]:$name; - } - return $output; - } - - /** - * @brief 모듈 언어를 ajax로 요청시 return - **/ - function getModuleAdminLangCode() { - $name = Context::get('name'); - if(!$name) return new Object(-1,'msg_invalid_request'); - $site_module_info = Context::get('site_module_info'); - $this->add('name', $name); - $output = $this->getLangCode($site_module_info->site_srl, '$user_lang->'.$name); - $this->add('langs', $output); - } - } -?> +module_srls = Context::get('module_srls'); + $output = executeQueryArray('module.getModulesInfo', $args); + if(!$output->toBool() || !$output->data) return new Object(); + + foreach($output->data as $key => $val) { + $list[$val->module_srl] = array('module_srl'=>$val->module_srl,'mid'=>$val->mid,'browser_title'=>$val->browser_title); + } + $modules = explode(',',$args->module_srls); + for($i=0;$iadd('id', Context::get('id')); + $this->add('module_list', $module_list); + } + + function getModuleMidList($args){ + $args->list_count = 20; + $args->page_count = 10; + $output = executeQueryArray('module.getModuleMidList', $args); + if(!$output->toBool()) return $output; + + ModuleModel::syncModuleToSite($output->data); + + return $output; + } + + /** + * @brief 공통 :: 모듈의 모듈 권한 출력 페이지 + * 모듈의 모듈 권한 출력은 모든 모듈에서 module instance를 이용할때 사용할 수 있음 + **/ + function getModuleGrantHTML($module_srl, $source_grant_list) { + + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + + // access, manager 권한은 가상 권한으로 설정 + $grant_list->access->title = Context::getLang('grant_access'); + $grant_list->access->default = 'guest'; + if(count($source_grant_list)) { + foreach($source_grant_list as $key => $val) { + if(!$val->default) $val->default = 'guest'; + if($val->default == 'root') $val->default = 'manager'; + $grant_list->{$key} = $val; + } + } + $grant_list->manager->title = Context::getLang('grant_manager'); + $grant_list->manager->default = 'manager'; + Context::set('grant_list', $grant_list); + + // 현재 모듈에 설정된 권한 그룹을 가져옴 + $default_grant = array(); + $args->module_srl = $module_srl; + $output = executeQueryArray('module.getModuleGrants', $args); + if($output->data) { + foreach($output->data as $val) { + if($val->group_srl == 0) $default_grant[$val->name] = 'all'; + else if($val->group_srl == -1) $default_grant[$val->name] = 'member'; + else if($val->group_srl == -2) $default_grant[$val->name] = 'site'; + else { + $selected_group[$val->name][] = $val->group_srl; + $default_grant[$val->name] = 'group'; + } + } + } + Context::set('selected_group', $selected_group); + Context::set('default_grant', $default_grant); + Context::set('module_srl', $module_srl); + // 현재 모듈에 설정된 관리자 아이디를 추출 + $admin_member = $oModuleModel->getAdminId($module_srl); + Context::set('admin_member', $admin_member); + + // 그룹을 가져옴 + $oMemberModel = &getModel('member'); + $group_list = $oMemberModel->getGroups($module_info->site_srl); + Context::set('group_list', $group_list); + + // grant 정보를 추출 + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($this->module_path.'tpl', 'module_grants'); + } + + /** + * @brief 공통 :: 모듈의 스킨 설정 출력 페이지 + **/ + function getModuleSkinHTML($module_srl) { + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + if(!$module_info) return; + + $skin = $module_info->skin; + $module_path = './modules/'.$module_info->module; + + // 스킨의 XML 정보를 구함 + $skin_info = $oModuleModel->loadSkinInfo($module_path, $skin); + + // DB에 설정된 스킨 정보를 구함 + $skin_vars = $oModuleModel->getModuleSkinVars($module_srl); + + if(count($skin_info->extra_vars)) { + foreach($skin_info->extra_vars as $key => $val) { + $group = $val->group; + $name = $val->name; + $type = $val->type; + if($skin_vars[$name]) $value = $skin_vars[$name]->value; + else $value = ''; + if($type=="checkbox" && !$value) $value = array(); + $skin_info->extra_vars[$key]->value= $value; + } + } + + Context::set('module_info', $module_info); + Context::set('mid', $module_info->mid); + Context::set('skin_info', $skin_info); + Context::set('skin_vars', $skin_vars); + + $oTemplate = &TemplateHandler::getInstance(); + return $oTemplate->compile($this->module_path.'tpl', 'skin_config'); + } + + /** + * @brief 특정 언어 코드에 대한 값들을 가져오기 + * lang_code를 직접 기입하면 해당 언어코드에 대해서만 가져오고 값이 없으면 $name을 그대로 return + **/ + function getLangCode($site_srl, $name) { + $lang_supported = Context::get('lang_supported'); + + if(substr($name,0,12)=='$user_lang->') { + $args->site_srl = (int)$site_srl; + $args->name = substr($name,12); + $output = executeQueryArray('module.getLang', $args); + if($output->data) { + foreach($output->data as $key => $val) { + $selected_lang[$val->lang_code] = $val->value; + } + } + } else { + $tmp = unserialize($name); + if($tmp) { + $selected_lang = array(); + $rand_name = $tmp[Context::getLangType()]; + if(!$rand_name) $rand_name = array_shift($tmp); + foreach($lang_supported as $key => $val) { + $selected_lang[$key] = $tmp[$key]?$tmp[$key]:$rand_name; + } + } + } + + $output = array(); + foreach($lang_supported as $key => $val) { + $output[$key] = $selected_lang[$key]?$selected_lang[$key]:$name; + } + return $output; + } + + /** + * @brief 모듈 언어를 ajax로 요청시 return + **/ + function getModuleAdminLangCode() { + $name = Context::get('name'); + if(!$name) return new Object(-1,'msg_invalid_request'); + $site_module_info = Context::get('site_module_info'); + $this->add('name', $name); + $output = $this->getLangCode($site_module_info->site_srl, '$user_lang->'.$name); + $this->add('langs', $output); + } + } +?> diff --git a/modules/module/module.admin.view.php b/modules/module/module.admin.view.php index 7b80eec0d..ae7615173 100644 --- a/modules/module/module.admin.view.php +++ b/modules/module/module.admin.view.php @@ -1,224 +1,224 @@ -setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief 모듈 관리자 페이지 - **/ - function dispModuleAdminContent() { - $this->dispModuleAdminList(); - } - - /** - * @brief 모듈 목록 출력 - **/ - function dispModuleAdminList() { - // 모듈 목록을 구해서 - $oModuleModel = &getModel('module'); - $module_list = $oModuleModel->getModuleList(); - Context::set('module_list', $module_list); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_list'); - } - - /** - * @brief 모듈의 상세 정보(conf/info.xml)를 팝업 출력 - **/ - function dispModuleAdminInfo() { - // 모듈 목록을 구해서 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoXml(Context::get('selected_module')); - Context::set('module_info', $module_info); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_info'); - } - - /** - * @brief 모듈 카테고리 목록 - **/ - function dispModuleAdminCategory() { - $module_category_srl = Context::get('module_category_srl'); - - // 모듈 목록을 구해서 - $oModuleModel = &getModel('module'); - - // 선택된 카테고리가 있으면 해당 카테고리의 정보 수정 페이지로 - if($module_category_srl) { - $selected_category = $oModuleModel->getModuleCategory($module_category_srl); - Context::set('selected_category', $selected_category); - - // 템플릿 파일 지정 - $this->setTemplateFile('category_update_form'); - - // 아니면 전체 목록 - } else { - $category_list = $oModuleModel->getModuleCategories(); - Context::set('category_list', $category_list); - - // 템플릿 파일 지정 - $this->setTemplateFile('category_list'); - } - } - - /** - * @brief 모듈 복사 기능 - **/ - function dispModuleAdminCopyModule() { - // 복사하려는 대상 모듈을 구함 - $module_srl = Context::get('module_srl'); - - // 해당 모듈의 정보를 구함 - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - Context::set('module_info', $module_info); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('copy_module'); - } - - /** - * @brief 모듈 기본 설정 일괄 적용 - **/ - function dispModuleAdminModuleSetup() { - $module_srls = Context::get('module_srls'); - - $modules = explode(',',$module_srls); - if(!count($modules)) if(!$module_srls) return new Object(-1,'msg_invalid_request'); - - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($modules[0]); - - // 모듈의 스킨 목록을 구함 - $skin_list = $oModuleModel->getSkins('./modules/'.$module_info->module); - Context::set('skin_list',$skin_list); - - // 레이아웃 목록을 구해옴 - $oLayoutMode = &getModel('layout'); - $layout_list = $oLayoutMode->getLayoutList(); - Context::set('layout_list', $layout_list); - - // 모듈 카테고리 목록을 구함 - $module_category = $oModuleModel->getModuleCategories(); - Context::set('module_category', $module_category); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_setup'); - } - - /** - * @brief 모듈 추가 설정 일괄 적용 - **/ - function dispModuleAdminModuleAdditionSetup() { - $module_srls = Context::get('module_srls'); - - $modules = explode(',',$module_srls); - if(!count($modules)) if(!$module_srls) return new Object(-1,'msg_invalid_request'); - - // content는 다른 모듈에서 call by reference로 받아오기에 미리 변수 선언만 해 놓음 - $content = ''; - - // 추가 설정을 위한 트리거 호출 - // 게시판 모듈이지만 차후 다른 모듈에서의 사용도 고려하여 trigger 이름을 공용으로 사용할 수 있도록 하였음 - $output = ModuleHandler::triggerCall('module.dispAdditionSetup', 'before', $content); - $output = ModuleHandler::triggerCall('module.dispAdditionSetup', 'after', $content); - Context::set('setup_content', $content); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_addition_setup'); - } - - /** - * @brief 모듈 권한 설정 일괄 적용 - **/ - function dispModuleAdminModuleGrantSetup() { - $module_srls = Context::get('module_srls'); - - $modules = explode(',',$module_srls); - if(!count($modules)) if(!$module_srls) return new Object(-1,'msg_invalid_request'); - - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($modules[0]); - $xml_info = $oModuleModel->getModuleActionXml($module_info->module); - $source_grant_list = $xml_info->grant; - - // access, manager 권한은 가상 권한으로 설정 - $grant_list->access->title = Context::getLang('grant_access'); - $grant_list->access->default = 'guest'; - if(count($source_grant_list)) { - foreach($source_grant_list as $key => $val) { - if(!$val->default) $val->default = 'guest'; - if($val->default == 'root') $val->default = 'manager'; - $grant_list->{$key} = $val; - } - } - $grant_list->manager->title = Context::getLang('grant_manager'); - $grant_list->manager->default = 'manager'; - Context::set('grant_list', $grant_list); - - // 그룹을 가져옴 - $oMemberModel = &getModel('member'); - $group_list = $oMemberModel->getGroups($module_info->site_srl); - Context::set('group_list', $group_list); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_grant_setup'); - } - - /** - * @brief 언어 코드 - **/ - function dispModuleAdminLangcode() { - // 현재 사이트의 언어파일 가져오기 - $site_module_info = Context::get('site_module_info'); - $args->site_srl = (int)$site_module_info->site_srl; - $args->sort_index = 'name'; - $args->order_type = 'asc'; - $output = executeQueryArray('module.getLangList', $args); - Context::set('lang_list', $output->data); - - // 현재 선택된 언어 가져오기 - $name = Context::get('name'); - if($name) { - $oModuleAdminModel = &getAdminModel('module'); - Context::set('selected_lang', $oModuleAdminModel->getLangCode($args->site_srl,'$user_lang->'.$name)); - } - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_langcode'); - } - - } -?> +setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief 모듈 관리자 페이지 + **/ + function dispModuleAdminContent() { + $this->dispModuleAdminList(); + } + + /** + * @brief 모듈 목록 출력 + **/ + function dispModuleAdminList() { + // 모듈 목록을 구해서 + $oModuleModel = &getModel('module'); + $module_list = $oModuleModel->getModuleList(); + Context::set('module_list', $module_list); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_list'); + } + + /** + * @brief 모듈의 상세 정보(conf/info.xml)를 팝업 출력 + **/ + function dispModuleAdminInfo() { + // 모듈 목록을 구해서 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoXml(Context::get('selected_module')); + Context::set('module_info', $module_info); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_info'); + } + + /** + * @brief 모듈 카테고리 목록 + **/ + function dispModuleAdminCategory() { + $module_category_srl = Context::get('module_category_srl'); + + // 모듈 목록을 구해서 + $oModuleModel = &getModel('module'); + + // 선택된 카테고리가 있으면 해당 카테고리의 정보 수정 페이지로 + if($module_category_srl) { + $selected_category = $oModuleModel->getModuleCategory($module_category_srl); + Context::set('selected_category', $selected_category); + + // 템플릿 파일 지정 + $this->setTemplateFile('category_update_form'); + + // 아니면 전체 목록 + } else { + $category_list = $oModuleModel->getModuleCategories(); + Context::set('category_list', $category_list); + + // 템플릿 파일 지정 + $this->setTemplateFile('category_list'); + } + } + + /** + * @brief 모듈 복사 기능 + **/ + function dispModuleAdminCopyModule() { + // 복사하려는 대상 모듈을 구함 + $module_srl = Context::get('module_srl'); + + // 해당 모듈의 정보를 구함 + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + Context::set('module_info', $module_info); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('copy_module'); + } + + /** + * @brief 모듈 기본 설정 일괄 적용 + **/ + function dispModuleAdminModuleSetup() { + $module_srls = Context::get('module_srls'); + + $modules = explode(',',$module_srls); + if(!count($modules)) if(!$module_srls) return new Object(-1,'msg_invalid_request'); + + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($modules[0]); + + // 모듈의 스킨 목록을 구함 + $skin_list = $oModuleModel->getSkins('./modules/'.$module_info->module); + Context::set('skin_list',$skin_list); + + // 레이아웃 목록을 구해옴 + $oLayoutMode = &getModel('layout'); + $layout_list = $oLayoutMode->getLayoutList(); + Context::set('layout_list', $layout_list); + + // 모듈 카테고리 목록을 구함 + $module_category = $oModuleModel->getModuleCategories(); + Context::set('module_category', $module_category); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_setup'); + } + + /** + * @brief 모듈 추가 설정 일괄 적용 + **/ + function dispModuleAdminModuleAdditionSetup() { + $module_srls = Context::get('module_srls'); + + $modules = explode(',',$module_srls); + if(!count($modules)) if(!$module_srls) return new Object(-1,'msg_invalid_request'); + + // content는 다른 모듈에서 call by reference로 받아오기에 미리 변수 선언만 해 놓음 + $content = ''; + + // 추가 설정을 위한 트리거 호출 + // 게시판 모듈이지만 차후 다른 모듈에서의 사용도 고려하여 trigger 이름을 공용으로 사용할 수 있도록 하였음 + $output = ModuleHandler::triggerCall('module.dispAdditionSetup', 'before', $content); + $output = ModuleHandler::triggerCall('module.dispAdditionSetup', 'after', $content); + Context::set('setup_content', $content); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_addition_setup'); + } + + /** + * @brief 모듈 권한 설정 일괄 적용 + **/ + function dispModuleAdminModuleGrantSetup() { + $module_srls = Context::get('module_srls'); + + $modules = explode(',',$module_srls); + if(!count($modules)) if(!$module_srls) return new Object(-1,'msg_invalid_request'); + + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($modules[0]); + $xml_info = $oModuleModel->getModuleActionXml($module_info->module); + $source_grant_list = $xml_info->grant; + + // access, manager 권한은 가상 권한으로 설정 + $grant_list->access->title = Context::getLang('grant_access'); + $grant_list->access->default = 'guest'; + if(count($source_grant_list)) { + foreach($source_grant_list as $key => $val) { + if(!$val->default) $val->default = 'guest'; + if($val->default == 'root') $val->default = 'manager'; + $grant_list->{$key} = $val; + } + } + $grant_list->manager->title = Context::getLang('grant_manager'); + $grant_list->manager->default = 'manager'; + Context::set('grant_list', $grant_list); + + // 그룹을 가져옴 + $oMemberModel = &getModel('member'); + $group_list = $oMemberModel->getGroups($module_info->site_srl); + Context::set('group_list', $group_list); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_grant_setup'); + } + + /** + * @brief 언어 코드 + **/ + function dispModuleAdminLangcode() { + // 현재 사이트의 언어파일 가져오기 + $site_module_info = Context::get('site_module_info'); + $args->site_srl = (int)$site_module_info->site_srl; + $args->sort_index = 'name'; + $args->order_type = 'asc'; + $output = executeQueryArray('module.getLangList', $args); + Context::set('lang_list', $output->data); + + // 현재 선택된 언어 가져오기 + $name = Context::get('name'); + if($name) { + $oModuleAdminModel = &getAdminModel('module'); + Context::set('selected_lang', $oModuleAdminModel->getLangCode($args->site_srl,'$user_lang->'.$name)); + } + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_langcode'); + } + + } +?> diff --git a/modules/module/module.class.php b/modules/module/module.class.php index a2a628c0b..c8809298f 100644 --- a/modules/module/module.class.php +++ b/modules/module/module.class.php @@ -1,367 +1,367 @@ -addIndex("modules","idx_site_mid", array("site_srl","mid"), true); - $oDB->addIndex('sites','unique_domain',array('domain'),true); - - // module 모듈에서 사용할 디렉토리 생성 - FileHandler::makeDir('./files/cache/module_info'); - FileHandler::makeDir('./files/cache/triggers'); - - // sites 테이블에 기본 사이트 정보 입력 - $args->site_srl = 0; - $output = $oDB->executeQuery('module.getSite', $args); - if(!$output->data || !$output->data->index_module_srl) { - $db_info = Context::getDBInfo(); - $domain = Context::getDefaultUrl(); - $url_info = parse_url($domain); - $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; - $site_args->site_srl = 0; - $site_args->index_module_srl = 0; - $site_args->domain = $domain; - $site_args->default_language = $db_info->lang_type; - - $output = executeQuery('module.insertSite', $site_args); - if(!$output->toBool()) return $output; - } - - return new Object(); - } - - /** - * @brief 설치가 이상이 없는지 체크하는 method - **/ - function checkUpdate() { - $oDB = &DB::getInstance(); - - // 2008. 10. 27 module_part_config 테이블의 결합 인덱스 추가 - if(!$oDB->isIndexExists("module_part_config","idx_module_part_config")) return true; - - // 2008. 11. 13 modules 의 mid를 unique를 없애고 site_srl을 추가 후에 site_srl + mid unique index - if(!$oDB->isIndexExists('modules',"idx_site_mid")) return true; - - // 모든 모듈의 권한/스킨정보를 grants 테이블로 이전시키는 업데이트 - if($oDB->isColumnExists('modules', 'grants')) return true; - - // 모든 모듈의 권한/스킨정보를 grants 테이블로 이전시키는 업데이트 - if(!$oDB->isColumnExists('sites', 'default_language')) return true; - - // extra_vars* 컬럼 제거 - for($i=1;$i<=20;$i++) { - if($oDB->isColumnExists("documents","extra_vars".$i)) return true; - } - - // sites 테이블에 기본 사이트 정보 입력 - $args->site_srl = 0; - $output = $oDB->executeQuery('module.getSite', $args); - if(!$output->data) return true; - - // sites 테이블에서 도메인이 인덱스로 걸린경우 - if($oDB->isIndexExists('sites', 'idx_domain')) return true; - if(!$oDB->isIndexExists('sites','unique_domain')) return true; - - if(!$oDB->isColumnExists("modules", "use_mobile")) return true; - if(!$oDB->isColumnExists("modules", "mlayout_srl")) return true; - if(!$oDB->isColumnExists("modules", "mcontent")) return true; - if(!$oDB->isColumnExists("modules", "mskin")) return true; - - return false; - } - - /** - * @brief 업데이트 실행 - **/ - function moduleUpdate() { - $oDB = &DB::getInstance(); - - // 2008. 10. 27 module_part_config 테이블의 결합 인덱스 추가하고 기존에 module_config에 몰려 있던 모든 정보를 재점검 - if(!$oDB->isIndexExists("module_part_config","idx_module_part_config")) { - $oModuleModel = &getModel('module'); - $oModuleController = &getController('module'); - $modules = $oModuleModel->getModuleList(); - foreach($modules as $key => $module_info) { - $module = $module_info->module; - if(!in_array($module, array('point','trackback','layout','rss','file','comment','editor'))) continue; - $config = $oModuleModel->getModuleConfig($module); - - $module_config = null; - switch($module) { - case 'point' : - $module_config = $config->module_point; - unset($config->module_point); - break; - case 'trackback' : - case 'rss' : - case 'file' : - case 'comment' : - case 'editor' : - $module_config = $config->module_config; - unset($config->module_config); - if(is_array($module_config) && count($module_config)) { - foreach($module_config as $key => $val) { - if(isset($module_config[$key]->module_srl)) unset($module_config[$key]->module_srl); - } - } - break; - case 'layout' : - $tmp = $config->header_script; - if(is_array($tmp) && count($tmp)) { - foreach($tmp as $k => $v) { - if(!$v && !trim($v)) continue; - $module_config[$k]->header_script = $v; - } - } - $config = null; - break; - - } - - $oModuleController->insertModuleConfig($module, $config); - - if(is_array($module_config) && count($module_config)) { - foreach($module_config as $module_srl => $module_part_config) { - $oModuleController->insertModulePartConfig($module,$module_srl,$module_part_config); - } - } - } - $oDB->addIndex("module_part_config","idx_module_part_config", array("module","module_srl")); - } - - // 2008. 11. 13 modules 의 mid를 unique를 없애고 site_srl을 추가 후에 site_srl + mid unique index - if(!$oDB->isIndexExists('modules',"idx_site_mid")) { - $oDB->dropIndex("modules","unique_mid",true); - $oDB->addColumn('modules','site_srl','number',11,0,true); - $oDB->addIndex("modules","idx_site_mid", array("site_srl","mid"),true); - } - - // document 확장변수의 확장을 위한 처리 - if(!$oDB->isTableExists('document_extra_vars')) $oDB->createTableByXmlFile('./modules/document/schemas/document_extra_vars.xml'); - - if(!$oDB->isTableExists('document_extra_keys')) $oDB->createTableByXmlFile('./modules/document/schemas/document_extra_keys.xml'); - - // 모든 모듈의 권한, 스킨정보, 확장정보, 관리자 아이디를 grants 테이블로 이전시키는 업데이트 - if($oDB->isColumnExists('modules', 'grants')) { - $oModuleController = &getController('module'); - $oDocumentController = &getController('document'); - - // 현재 시스템 언어 코드값을 가져옴 - $lang_code = Context::getLangType(); - - // 모든 모듈의 module_info를 가져옴 - $output = executeQueryArray('module.getModuleInfos'); - if(count($output->data)) { - foreach($output->data as $module_info) { - // 모듈들의 권한/ 확장변수(게시글 확장 포함)/ 스킨 변수/ 최고관리권한 정보 분리 - $module_srl = trim($module_info->module_srl); - - // 권한 등록 - $grants = unserialize($module_info->grants); - if($grants) $oModuleController->insertModuleGrants($module_srl, $grants); - - // 스킨 변수 등록 - $skin_vars = unserialize($module_info->skin_vars); - if($skin_vars) $oModuleController->insertModuleSkinVars($module_srl, $skin_vars); - - // 최고 관리자 아이디 등록 - $admin_id = trim($module_info->admin_id); - if($admin_id && $admin_id != 'Array') { - $admin_ids = explode(',',$admin_id); - if(count($admin_id)) { - foreach($admin_ids as $admin_id) { - $oModuleController->insertAdminId($module_srl, $admin_id); - } - } - } - - // 모듈별 추가 설정 저장 (기본 modules에 없던 컬럼 데이터) - $extra_vars = unserialize($module_info->extra_vars); - $document_extra_keys = null; - if($extra_vars->extra_vars && count($extra_vars->extra_vars)) { - $document_extra_keys = $extra_vars->extra_vars; - unset($extra_vars->extra_vars); - } - if($extra_vars) $oModuleController->insertModuleExtraVars($module_srl, $extra_vars); - - /** - * 게시글 확장변수 이동 (documents모듈에서 해야 하지만 modules 테이블의 추가 변수들이 정리되기에 여기서 함) - **/ - // 플래닛모듈의 경우 직접 추가 변수 입력 - if($module_info->module == 'planet') { - if(!$document_extra_keys || !is_array($document_extra_keys)) $document_extra_keys = array(); - $planet_extra_keys->name = 'postscript'; - $planet_extra_keys->type = 'text'; - $planet_extra_keys->is_required = 'N'; - $planet_extra_keys->search = 'N'; - $planet_extra_keys->default = ''; - $planet_extra_keys->desc = ''; - $document_extra_keys[20] = $planet_extra_keys; - } - - // 게시글 확장변수 키 등록 - if(count($document_extra_keys)) { - foreach($document_extra_keys as $var_idx => $val) { - $oDocumentController->insertDocumentExtraKey($module_srl, $var_idx, $val->name, $val->type, $val->is_required, $val->search, $val->default, $val->desc, 'extra_vars'.$var_idx); - } - - // 2009-04-14 #17923809 게시물 100개의 확장 변수만 이전되는 문제점 수정 - $oDocumentModel = &getModel('document'); - $total_count = $oDocumentModel->getDocumentCount($module_srl); - - if ($total_count > 0) { - $per_page = 100; - $total_pages = (int) (($total_count - 1) / $per_page) + 1; - - // 확장변수가 존재하면 확장변수 가져오기 - $doc_args = null; - $doc_args->module_srl = $module_srl; - $doc_args->list_count = $per_page; - $doc_args->sort_index = 'list_order'; - $doc_args->order_type = 'asc'; - - for ($doc_args->page = 1; $doc_args->page <= $total_pages; $doc_args->page++) { - $output = executeQueryArray('document.getDocumentList', $doc_args); - - if ($output->toBool() && $output->data && count($output->data)) { - foreach ($output->data as $document) { - if (!$document) continue; - foreach ($document as $key => $var) { - if (strpos($key, 'extra_vars') !== 0 || !trim($var) || $var == 'N;') continue; - $var_idx = str_replace('extra_vars','',$key); - $oDocumentController->insertDocumentExtraVar($module_srl, $document->document_srl, $var_idx, $var, 'extra_vars'.$var_idx, $lang_code); - } - } - } - } // for total_pages - } // if count - } - - // 해당 모듈들의 추가 변수들 제거 - $module_info->grant = null; - $module_info->extra_vars = null; - $module_info->skin_vars = null; - $module_info->admin_id = null; - executeQuery('module.updateModule', $module_info); - } - } - - // 각종 column drop - $oDB->dropColumn('modules','grants'); - $oDB->dropColumn('modules','admin_id'); - $oDB->dropColumn('modules','skin_vars'); - $oDB->dropColumn('modules','extra_vars'); - } - - // 모든 모듈의 권한/스킨정보를 grants 테이블로 이전시키는 업데이트 - if(!$oDB->isColumnExists('sites', 'default_language')) { - $oDB->addColumn('sites','default_language','varchar',255,0,false); - } - - // extra_vars* 컬럼 제거 - for($i=1;$i<=20;$i++) { - if(!$oDB->isColumnExists("documents","extra_vars".$i)) continue; - $oDB->dropColumn('documents','extra_vars'.$i); - } - - // sites 테이블에 기본 사이트 정보 입력 - $args->site_srl = 0; - $output = $oDB->executeQuery('module.getSite', $args); - if(!$output->data) { - // 기본 mid, 언어 구함 - $mid_output = $oDB->executeQuery('module.getDefaultMidInfo', $args); - $db_info = Context::getDBInfo(); - $domain = Context::getDefaultUrl(); - $url_info = parse_url($domain); - $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; - $site_args->site_srl = 0; - $site_args->index_module_srl = $mid_output->data->module_srl; - $site_args->domain = $domain; - $site_args->default_language = $db_info->lang_type; - - $output = executeQuery('module.insertSite', $site_args); - if(!$output->toBool()) return $output; - } - - if($oDB->isIndexExists('sites','idx_domain')){ - $oDB->dropIndex('sites','idx_domain'); - } - if(!$oDB->isIndexExists('sites','unique_domain')){ - $this->updateForUniqueSiteDomain(); - $oDB->addIndex('sites','unique_domain',array('domain'),true); - } - - if(!$oDB->isColumnExists("modules", "use_mobile")) { - $oDB->addColumn('modules','use_mobile','char',1,'N'); - } - if(!$oDB->isColumnExists("modules", "mlayout_srl")) { - $oDB->addColumn('modules','mlayout_srl','number',11, 0); - } - if(!$oDB->isColumnExists("modules", "mcontent")) { - $oDB->addColumn('modules','mcontent','bigtext'); - } - if(!$oDB->isColumnExists("modules", "mskin")) { - $oDB->addColumn('modules','mskin','varchar',250); - } - - return new Object(0, 'success_updated'); - } - - function updateForUniqueSiteDomain() - { - $output = executeQueryArray("module.getNonuniqueDomains"); - if(!$output->data) return; - foreach($output->data as $data) - { - if($data->count == 1) continue; - $domain = $data->domain; - $args = null; - $args->domain = $domain; - $output2 = executeQueryArray("module.getSiteByDomain", $args); - $bFirst = true; - foreach($output2->data as $site) - { - if($bFirst) - { - $bFirst = false; - continue; - } - $domain .= "_"; - $args = null; - $args->domain = $domain; - $args->site_srl = $site->site_srl; - $output3 = executeQuery("module.updateSite", $args); - } - } - } - - /** - * @brief 캐시 파일 재생성 - **/ - function recompileCache() { - // 모듈 정보 캐시 파일 모두 삭제 - FileHandler::removeFilesInDir("./files/cache/module_info"); - - // 트리거 정보가 있는 파일 모두 삭제 - FileHandler::removeFilesInDir("./files/cache/triggers"); - - // DB캐시 파일을 모두 삭제 - FileHandler::removeFilesInDir("./files/cache/db"); - - // 기타 캐시 삭제 - FileHandler::removeDir("./files/cache/tmp"); - } - } -?> +addIndex("modules","idx_site_mid", array("site_srl","mid"), true); + $oDB->addIndex('sites','unique_domain',array('domain'),true); + + // module 모듈에서 사용할 디렉토리 생성 + FileHandler::makeDir('./files/cache/module_info'); + FileHandler::makeDir('./files/cache/triggers'); + + // sites 테이블에 기본 사이트 정보 입력 + $args->site_srl = 0; + $output = $oDB->executeQuery('module.getSite', $args); + if(!$output->data || !$output->data->index_module_srl) { + $db_info = Context::getDBInfo(); + $domain = Context::getDefaultUrl(); + $url_info = parse_url($domain); + $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; + $site_args->site_srl = 0; + $site_args->index_module_srl = 0; + $site_args->domain = $domain; + $site_args->default_language = $db_info->lang_type; + + $output = executeQuery('module.insertSite', $site_args); + if(!$output->toBool()) return $output; + } + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + $oDB = &DB::getInstance(); + + // 2008. 10. 27 module_part_config 테이블의 결합 인덱스 추가 + if(!$oDB->isIndexExists("module_part_config","idx_module_part_config")) return true; + + // 2008. 11. 13 modules 의 mid를 unique를 없애고 site_srl을 추가 후에 site_srl + mid unique index + if(!$oDB->isIndexExists('modules',"idx_site_mid")) return true; + + // 모든 모듈의 권한/스킨정보를 grants 테이블로 이전시키는 업데이트 + if($oDB->isColumnExists('modules', 'grants')) return true; + + // 모든 모듈의 권한/스킨정보를 grants 테이블로 이전시키는 업데이트 + if(!$oDB->isColumnExists('sites', 'default_language')) return true; + + // extra_vars* 컬럼 제거 + for($i=1;$i<=20;$i++) { + if($oDB->isColumnExists("documents","extra_vars".$i)) return true; + } + + // sites 테이블에 기본 사이트 정보 입력 + $args->site_srl = 0; + $output = $oDB->executeQuery('module.getSite', $args); + if(!$output->data) return true; + + // sites 테이블에서 도메인이 인덱스로 걸린경우 + if($oDB->isIndexExists('sites', 'idx_domain')) return true; + if(!$oDB->isIndexExists('sites','unique_domain')) return true; + + if(!$oDB->isColumnExists("modules", "use_mobile")) return true; + if(!$oDB->isColumnExists("modules", "mlayout_srl")) return true; + if(!$oDB->isColumnExists("modules", "mcontent")) return true; + if(!$oDB->isColumnExists("modules", "mskin")) return true; + + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + $oDB = &DB::getInstance(); + + // 2008. 10. 27 module_part_config 테이블의 결합 인덱스 추가하고 기존에 module_config에 몰려 있던 모든 정보를 재점검 + if(!$oDB->isIndexExists("module_part_config","idx_module_part_config")) { + $oModuleModel = &getModel('module'); + $oModuleController = &getController('module'); + $modules = $oModuleModel->getModuleList(); + foreach($modules as $key => $module_info) { + $module = $module_info->module; + if(!in_array($module, array('point','trackback','layout','rss','file','comment','editor'))) continue; + $config = $oModuleModel->getModuleConfig($module); + + $module_config = null; + switch($module) { + case 'point' : + $module_config = $config->module_point; + unset($config->module_point); + break; + case 'trackback' : + case 'rss' : + case 'file' : + case 'comment' : + case 'editor' : + $module_config = $config->module_config; + unset($config->module_config); + if(is_array($module_config) && count($module_config)) { + foreach($module_config as $key => $val) { + if(isset($module_config[$key]->module_srl)) unset($module_config[$key]->module_srl); + } + } + break; + case 'layout' : + $tmp = $config->header_script; + if(is_array($tmp) && count($tmp)) { + foreach($tmp as $k => $v) { + if(!$v && !trim($v)) continue; + $module_config[$k]->header_script = $v; + } + } + $config = null; + break; + + } + + $oModuleController->insertModuleConfig($module, $config); + + if(is_array($module_config) && count($module_config)) { + foreach($module_config as $module_srl => $module_part_config) { + $oModuleController->insertModulePartConfig($module,$module_srl,$module_part_config); + } + } + } + $oDB->addIndex("module_part_config","idx_module_part_config", array("module","module_srl")); + } + + // 2008. 11. 13 modules 의 mid를 unique를 없애고 site_srl을 추가 후에 site_srl + mid unique index + if(!$oDB->isIndexExists('modules',"idx_site_mid")) { + $oDB->dropIndex("modules","unique_mid",true); + $oDB->addColumn('modules','site_srl','number',11,0,true); + $oDB->addIndex("modules","idx_site_mid", array("site_srl","mid"),true); + } + + // document 확장변수의 확장을 위한 처리 + if(!$oDB->isTableExists('document_extra_vars')) $oDB->createTableByXmlFile('./modules/document/schemas/document_extra_vars.xml'); + + if(!$oDB->isTableExists('document_extra_keys')) $oDB->createTableByXmlFile('./modules/document/schemas/document_extra_keys.xml'); + + // 모든 모듈의 권한, 스킨정보, 확장정보, 관리자 아이디를 grants 테이블로 이전시키는 업데이트 + if($oDB->isColumnExists('modules', 'grants')) { + $oModuleController = &getController('module'); + $oDocumentController = &getController('document'); + + // 현재 시스템 언어 코드값을 가져옴 + $lang_code = Context::getLangType(); + + // 모든 모듈의 module_info를 가져옴 + $output = executeQueryArray('module.getModuleInfos'); + if(count($output->data)) { + foreach($output->data as $module_info) { + // 모듈들의 권한/ 확장변수(게시글 확장 포함)/ 스킨 변수/ 최고관리권한 정보 분리 + $module_srl = trim($module_info->module_srl); + + // 권한 등록 + $grants = unserialize($module_info->grants); + if($grants) $oModuleController->insertModuleGrants($module_srl, $grants); + + // 스킨 변수 등록 + $skin_vars = unserialize($module_info->skin_vars); + if($skin_vars) $oModuleController->insertModuleSkinVars($module_srl, $skin_vars); + + // 최고 관리자 아이디 등록 + $admin_id = trim($module_info->admin_id); + if($admin_id && $admin_id != 'Array') { + $admin_ids = explode(',',$admin_id); + if(count($admin_id)) { + foreach($admin_ids as $admin_id) { + $oModuleController->insertAdminId($module_srl, $admin_id); + } + } + } + + // 모듈별 추가 설정 저장 (기본 modules에 없던 컬럼 데이터) + $extra_vars = unserialize($module_info->extra_vars); + $document_extra_keys = null; + if($extra_vars->extra_vars && count($extra_vars->extra_vars)) { + $document_extra_keys = $extra_vars->extra_vars; + unset($extra_vars->extra_vars); + } + if($extra_vars) $oModuleController->insertModuleExtraVars($module_srl, $extra_vars); + + /** + * 게시글 확장변수 이동 (documents모듈에서 해야 하지만 modules 테이블의 추가 변수들이 정리되기에 여기서 함) + **/ + // 플래닛모듈의 경우 직접 추가 변수 입력 + if($module_info->module == 'planet') { + if(!$document_extra_keys || !is_array($document_extra_keys)) $document_extra_keys = array(); + $planet_extra_keys->name = 'postscript'; + $planet_extra_keys->type = 'text'; + $planet_extra_keys->is_required = 'N'; + $planet_extra_keys->search = 'N'; + $planet_extra_keys->default = ''; + $planet_extra_keys->desc = ''; + $document_extra_keys[20] = $planet_extra_keys; + } + + // 게시글 확장변수 키 등록 + if(count($document_extra_keys)) { + foreach($document_extra_keys as $var_idx => $val) { + $oDocumentController->insertDocumentExtraKey($module_srl, $var_idx, $val->name, $val->type, $val->is_required, $val->search, $val->default, $val->desc, 'extra_vars'.$var_idx); + } + + // 2009-04-14 #17923809 게시물 100개의 확장 변수만 이전되는 문제점 수정 + $oDocumentModel = &getModel('document'); + $total_count = $oDocumentModel->getDocumentCount($module_srl); + + if ($total_count > 0) { + $per_page = 100; + $total_pages = (int) (($total_count - 1) / $per_page) + 1; + + // 확장변수가 존재하면 확장변수 가져오기 + $doc_args = null; + $doc_args->module_srl = $module_srl; + $doc_args->list_count = $per_page; + $doc_args->sort_index = 'list_order'; + $doc_args->order_type = 'asc'; + + for ($doc_args->page = 1; $doc_args->page <= $total_pages; $doc_args->page++) { + $output = executeQueryArray('document.getDocumentList', $doc_args); + + if ($output->toBool() && $output->data && count($output->data)) { + foreach ($output->data as $document) { + if (!$document) continue; + foreach ($document as $key => $var) { + if (strpos($key, 'extra_vars') !== 0 || !trim($var) || $var == 'N;') continue; + $var_idx = str_replace('extra_vars','',$key); + $oDocumentController->insertDocumentExtraVar($module_srl, $document->document_srl, $var_idx, $var, 'extra_vars'.$var_idx, $lang_code); + } + } + } + } // for total_pages + } // if count + } + + // 해당 모듈들의 추가 변수들 제거 + $module_info->grant = null; + $module_info->extra_vars = null; + $module_info->skin_vars = null; + $module_info->admin_id = null; + executeQuery('module.updateModule', $module_info); + } + } + + // 각종 column drop + $oDB->dropColumn('modules','grants'); + $oDB->dropColumn('modules','admin_id'); + $oDB->dropColumn('modules','skin_vars'); + $oDB->dropColumn('modules','extra_vars'); + } + + // 모든 모듈의 권한/스킨정보를 grants 테이블로 이전시키는 업데이트 + if(!$oDB->isColumnExists('sites', 'default_language')) { + $oDB->addColumn('sites','default_language','varchar',255,0,false); + } + + // extra_vars* 컬럼 제거 + for($i=1;$i<=20;$i++) { + if(!$oDB->isColumnExists("documents","extra_vars".$i)) continue; + $oDB->dropColumn('documents','extra_vars'.$i); + } + + // sites 테이블에 기본 사이트 정보 입력 + $args->site_srl = 0; + $output = $oDB->executeQuery('module.getSite', $args); + if(!$output->data) { + // 기본 mid, 언어 구함 + $mid_output = $oDB->executeQuery('module.getDefaultMidInfo', $args); + $db_info = Context::getDBInfo(); + $domain = Context::getDefaultUrl(); + $url_info = parse_url($domain); + $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; + $site_args->site_srl = 0; + $site_args->index_module_srl = $mid_output->data->module_srl; + $site_args->domain = $domain; + $site_args->default_language = $db_info->lang_type; + + $output = executeQuery('module.insertSite', $site_args); + if(!$output->toBool()) return $output; + } + + if($oDB->isIndexExists('sites','idx_domain')){ + $oDB->dropIndex('sites','idx_domain'); + } + if(!$oDB->isIndexExists('sites','unique_domain')){ + $this->updateForUniqueSiteDomain(); + $oDB->addIndex('sites','unique_domain',array('domain'),true); + } + + if(!$oDB->isColumnExists("modules", "use_mobile")) { + $oDB->addColumn('modules','use_mobile','char',1,'N'); + } + if(!$oDB->isColumnExists("modules", "mlayout_srl")) { + $oDB->addColumn('modules','mlayout_srl','number',11, 0); + } + if(!$oDB->isColumnExists("modules", "mcontent")) { + $oDB->addColumn('modules','mcontent','bigtext'); + } + if(!$oDB->isColumnExists("modules", "mskin")) { + $oDB->addColumn('modules','mskin','varchar',250); + } + + return new Object(0, 'success_updated'); + } + + function updateForUniqueSiteDomain() + { + $output = executeQueryArray("module.getNonuniqueDomains"); + if(!$output->data) return; + foreach($output->data as $data) + { + if($data->count == 1) continue; + $domain = $data->domain; + $args = null; + $args->domain = $domain; + $output2 = executeQueryArray("module.getSiteByDomain", $args); + $bFirst = true; + foreach($output2->data as $site) + { + if($bFirst) + { + $bFirst = false; + continue; + } + $domain .= "_"; + $args = null; + $args->domain = $domain; + $args->site_srl = $site->site_srl; + $output3 = executeQuery("module.updateSite", $args); + } + } + } + + /** + * @brief 캐시 파일 재생성 + **/ + function recompileCache() { + // 모듈 정보 캐시 파일 모두 삭제 + FileHandler::removeFilesInDir("./files/cache/module_info"); + + // 트리거 정보가 있는 파일 모두 삭제 + FileHandler::removeFilesInDir("./files/cache/triggers"); + + // DB캐시 파일을 모두 삭제 + FileHandler::removeFilesInDir("./files/cache/db"); + + // 기타 캐시 삭제 + FileHandler::removeDir("./files/cache/tmp"); + } + } +?> diff --git a/modules/module/module.controller.php b/modules/module/module.controller.php index 8d67358a8..dac43f770 100644 --- a/modules/module/module.controller.php +++ b/modules/module/module.controller.php @@ -1,706 +1,706 @@ -module = $module; - $args->type = $type; - $args->act = $act; - - $output = executeQuery('module.insertActionFoward', $args); - return $output; - } - - /** - * @brief action forward 삭제 - **/ - function deleteActionForward($module, $type, $act) { - $args->module = $module; - $args->type = $type; - $args->act = $act; - - $output = executeQuery('module.deleteActionFoward', $args); - return $output; - } - - /** - * @brief module trigger 추가 - * module trigger는 trigger 대상이 등록된 대상을 호출하는 방법이다. - * - **/ - function insertTrigger($trigger_name, $module, $type, $called_method, $called_position) { - $args->trigger_name = $trigger_name; - $args->module = $module; - $args->type = $type; - $args->called_method = $called_method; - $args->called_position = $called_position; - - $output = executeQuery('module.insertTrigger', $args); - - // 트리거 정보가 있는 파일 모두 삭제 - FileHandler::removeFilesInDir("./files/cache/triggers"); - - return $output; - } - - /** - * @brief module trigger 삭제 - * - **/ - function deleteTrigger($trigger_name, $module, $type, $called_method, $called_position) { - $args->trigger_name = $trigger_name; - $args->module = $module; - $args->type = $type; - $args->called_method = $called_method; - $args->called_position = $called_position; - - $output = executeQuery('module.deleteTrigger', $args); - - // 트리거 캐시 삭제 - FileHandler::removeFilesInDir('./files/cache/triggers'); - - return $output; - } - - /** - * @brief 특정 모듈의 설정 입력 - * board, member등 특정 모듈의 global config 관리용 - **/ - function insertModuleConfig($module, $config) { - $args->module = $module; - $args->config = serialize($config); - - $output = executeQuery('module.deleteModuleConfig', $args); - if(!$output->toBool()) return $output; - - $output = executeQuery('module.insertModuleConfig', $args); - return $output; - } - - /** - * @brief 특정 mid의 모듈 설정 정보 저장 - * mid의 모듈 의존적인 설정을 관리 - **/ - function insertModulePartConfig($module, $module_srl, $config) { - $args->module = $module; - $args->module_srl = $module_srl; - $args->config = serialize($config); - - $output = executeQuery('module.deleteModulePartConfig', $args); - if(!$output->toBool()) return $output; - - $output = executeQuery('module.insertModulePartConfig', $args); - return $output; - } - - /** - * @brief virtual site 생성 - **/ - function insertSite($domain, $index_module_srl) { - if(isSiteID($domain)) { - $oModuleModel = &getModel('module'); - if($oModuleModel->isIDExists($domain, 0)) return new Object(-1,'msg_already_registed_vid'); - } - $args->site_srl = getNextSequence(); - $args->domain = preg_replace('/\/$/','',$domain); - $args->index_module_srl = $index_module_srl; - $args->default_language = Context::getLangType(); - $output = executeQuery('module.getSiteInfoByDomain', $args); - if($output->data) return new Object(-1,'msg_already_registed_vid'); - - $output = executeQuery('module.insertSite', $args); - if(!$output->toBool()) return $output; - - $output->add('site_srl', $args->site_srl); - return $output; - } - - /** - * @brief virtual site 수정 - **/ - function updateSite($args) { - $oModuleModel = &getModel('module'); - $site_info = $oModuleModel->getSiteInfo($args->site_srl); - if($site_info->domain != $args->domain) { - $info = $oModuleModel->getSiteInfoByDomain($args->domain); - if($info->site_srl && $info->site_srl != $args->site_srl) return new Object(-1,'msg_already_registed_domain'); - if(isSiteID($args->domain) && $oModuleModel->isIDExists($args->domain)) return new Object(-1,'msg_already_registed_vid'); - } - $output = executeQuery('module.updateSite', $args); - return $output; - } - - /** - * @brief 모듈 정보 정리 - **/ - function arrangeModuleInfo(&$args, &$extra_vars) { - // 불필요한 내용 제거 - unset($args->body); - unset($args->act); - unset($args->page); - - // mid값 검사 - if(!preg_match("/^[a-z][a-z0-9_]+$/i", $args->mid)) return new Object(-1, 'msg_limit_mid'); - - // 변수를 검사 (modules의 기본 변수와 그렇지 않은 변수로 분리) - $extra_vars = clone($args); - unset($extra_vars->module_srl); - unset($extra_vars->module); - unset($extra_vars->module_category_srl); - unset($extra_vars->layout_srl); - unset($extra_vars->mlayout_srl); - unset($extra_vars->use_mobile); - unset($extra_vars->menu_srl); - unset($extra_vars->site_srl); - unset($extra_vars->mid); - unset($extra_vars->skin); - unset($extra_vars->mskin); - unset($extra_vars->browser_title); - unset($extra_vars->description); - unset($extra_vars->is_default); - unset($extra_vars->content); - unset($extra_vars->mcontent); - unset($extra_vars->open_rss); - unset($extra_vars->header_text); - unset($extra_vars->footer_text); - $args = delObjectVars($args, $extra_vars); - - return new Object(); - } - - /** - * @brief 모듈 입력 - **/ - function insertModule($args) { - $output = $this->arrangeModuleInfo($args, $extra_vars); - if(!$output->toBool()) return $output; - - // 이미 존재하는 모듈 이름인지 체크 - if(!$args->site_srl) $args->site_srl = 0; - $oModuleModel = &getModel('module'); - if($oModuleModel->isIDExists($args->mid, $args->site_srl)) return new Object(-1, 'msg_module_name_exists'); - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - // 선택된 스킨정보에서 colorset을 구함 - $module_path = ModuleHandler::getModulePath($args->module); - $skin_info = $oModuleModel->loadSkinInfo($module_path, $args->skin); - $skin_vars->colorset = $skin_info->colorset[0]->name; - - // 변수 정리후 query 실행 - if(!$args->module_srl) $args->module_srl = getNextSequence(); - - // 모듈 등록 - $output = executeQuery('module.insertModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 모듈 추가 변수 등록 - $this->insertModuleExtraVars($args->module_srl, $extra_vars); - - // commit - $oDB->commit(); - - $output->add('module_srl',$args->module_srl); - return $output; - } - - /** - * @brief 모듈의 정보를 수정 - **/ - function updateModule($args) { - $output = $this->arrangeModuleInfo($args, $extra_vars); - if(!$output->toBool()) return $output; - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - $oModuleModel = &getModel('module'); - $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); - - $args->site_srl = (int)$module_info->site_srl; - if(!$args->browser_title) $args->browser_title = $module_info->browser_title; - - $output = executeQuery('module.isExistsModuleName', $args); - if(!$output->toBool() || $output->data->count) { - $oDB->rollback(); - return new Object(-1, 'msg_module_name_exists'); - } - - $output = executeQuery('module.updateModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 모듈 추가 변수 등록 - $this->insertModuleExtraVars($args->module_srl, $extra_vars); - - $oDB->commit(); - - $output->add('module_srl',$args->module_srl); - return $output; - } - - /** - * @brief 모듈의 가상사이트 변경 - **/ - function updateModuleSite($module_srl, $site_srl, $layout_srl = 0) { - $args->module_srl = $module_srl; - $args->site_srl = $site_srl; - $args->layout_srl = $layout_srl; - return executeQuery('module.updateModuleSite', $args); - } - - /** - * @brief 모듈을 삭제 - * - * 모듈 삭제시는 관련 정보들을 모두 삭제 시도한다. - **/ - function deleteModule($module_srl) { - if(!$module_srl) return new Object(-1,'msg_invalid_request'); - - // trigger 호출 (before) - $trigger_obj->module_srl = $module_srl; - $output = ModuleHandler::triggerCall('module.deleteModule', 'before', $trigger_obj); - if(!$output->toBool()) return $output; - - // begin transaction - $oDB = &DB::getInstance(); - $oDB->begin(); - - $args->module_srl = $module_srl; - - // module 정보를 DB에서 삭제 - $output = executeQuery('module.deleteModule', $args); - if(!$output->toBool()) { - $oDB->rollback(); - return $output; - } - - // 권한 정보 삭제 - $this->deleteModuleGrants($module_srl); - - // 스킨 정보 삭제 - $this->deleteModuleSkinVars($module_srl); - - // 모듈 추가 변수 삭제 - $this->deleteModuleExtraVars($module_srl); - - // 모듈 관리자 제거 - $this->deleteAdminId($module_srl); - - // trigger 호출 (after) - if($output->toBool()) { - $trigger_output = ModuleHandler::triggerCall('module.deleteModule', 'after', $trigger_obj); - if(!$trigger_output->toBool()) { - $oDB->rollback(); - return $trigger_output; - } - } - - // commit - $oDB->commit(); - - return $output; - } - - /** - * @brief 모듈의 기타 정보를 변경 - **/ - function updateModuleSkinVars($module_srl, $skin_vars) { - // skin_vars 정보 세팅 - $args->module_srl = $module_srl; - $args->skin_vars = $skin_vars; - $output = executeQuery('module.updateModuleSkinVars', $args); - if(!$output->toBool()) return $output; - - return $output; - } - - /** - * @brief 모든 모듈의 is_default값을 N 으로 세팅 (기본 모듈 해제) - **/ - function clearDefaultModule() { - $output = executeQuery('module.clearDefaultModule'); - if(!$output->toBool()) return $output; - - return $output; - } - - /** - * @brief 지정된 menu_srl에 속한 mid 의 menu_srl 을 변경 - **/ - function updateModuleMenu($args) { - return executeQuery('module.updateModuleMenu', $args); - } - - /** - * @brief 지정된 menu_srl에 속한 mid 의 layout_srl을 변경 - **/ - function updateModuleLayout($layout_srl, $menu_srl_list) { - if(!count($menu_srl_list)) return; - - $args->layout_srl = $layout_srl; - $args->menu_srls = implode(',',$menu_srl_list); - $output = executeQuery('module.updateModuleLayout', $args); - return $output; - } - - /** - * @brief 사이트의 관리를 변경 - **/ - function insertSiteAdmin($site_srl, $arr_admins) { - // 사이트 관리자 제거 - $args->site_srl = $site_srl; - $output = executeQuery('module.deleteSiteAdmin', $args); - if(!$output->toBool()) return $output; - - // 관리자 대상 멤버 번호를 구함 - if(!is_array($arr_admins) || !count($arr_admins)) return new Object(); - foreach($arr_admins as $key => $user_id) { - if(!trim($user_id)) continue; - $admins[] = trim($user_id); - } - if(!count($admins)) return new Object(); - - $args->user_ids = '\''.implode('\',\'',$admins).'\''; - $output = executeQueryArray('module.getAdminSrls', $args); - if(!$output->toBool()||!$output->data) return $output; - - foreach($output->data as $key => $val) { - unset($args); - $args->site_srl = $site_srl; - $args->member_srl = $val->member_srl; - $output = executeQueryArray('module.insertSiteAdmin', $args); - if(!$output->toBool()) return $output; - } - return new Object(); - } - - /** - * @brief 특정 모듈에 관리자 아이디 지정 - **/ - function insertAdminId($module_srl, $admin_id) { - $oMemberModel = &getModel('member'); - $member_info = $oMemberModel->getMemberInfoByUserID($admin_id); - if(!$member_info->member_srl) return; - $args->module_srl = $module_srl; - $args->member_srl = $member_info->member_srl; - return executeQuery('module.insertAdminId', $args); - } - - /** - * @brief 특정 모듈의 관리자 아이디 제거 - **/ - function deleteAdminId($module_srl, $admin_id = '') { - $args->module_srl = $module_srl; - - if($admin_id) { - $oMemberModel = &getModel('member'); - $member_info = $oMemberModel->getMemberInfoByUserID($admin_id); - if($member_info->member_srl) $args->member_srl = $member_info->member_srl; - } - return executeQuery('module.deleteAdminId', $args); - } - - /** - * @brief 특정 모듈에 스킨 변수 등록 - **/ - function insertModuleSkinVars($module_srl, $obj) { - $this->deleteModuleSkinVars($module_srl); - if(!$obj || !count($obj)) return; - - $args->module_srl = $module_srl; - foreach($obj as $key => $val) { - // #17927989 예전 블로그 모듈을 사용하던 게시판의 경우 - // 스킨 정보 필드에 메뉴 항목(stdClass)을 저장해놓은 경우가 있어 - // 1.2.0 이상 버전으로 업그레이드한 후 모듈 업데이트할 때 - // 오류가 발생하는 문제 수정 - if (is_array($val) || is_object($val)) continue; - - $args->name = trim($key); - $args->value = trim($val); - if(!$args->name || !$args->value) continue; - executeQuery('module.insertModuleSkinVars', $args); - } - } - - /** - * @brief 특정 모듈의 스킨 변수 제거 - **/ - function deleteModuleSkinVars($module_srl) { - $args->module_srl = $module_srl; - return executeQuery('module.deleteModuleSkinVars', $args); - } - - /** - * @brief 특정 모듈에 확장 변수 등록 - **/ - function insertModuleExtraVars($module_srl, $obj) { - $this->deleteModuleExtraVars($module_srl); - if(!$obj || !count($obj)) return; - - foreach($obj as $key => $val) { - $args = null; - $args->module_srl = $module_srl; - $args->name = trim($key); - $args->value = trim($val); - if(!$args->name || !$args->value) continue; - executeQuery('module.insertModuleExtraVars', $args); - } - } - - /** - * @brief 특정 모듈의 확장 변수 제거 - **/ - function deleteModuleExtraVars($module_srl) { - $args->module_srl = $module_srl; - return executeQuery('module.deleteModuleExtraVars', $args); - } - - /** - * @brief 특정 모듈에 권한 등록 - **/ - function insertModuleGrants($module_srl, $obj) { - $this->deleteModuleGrants($module_srl); - if(!$obj || !count($obj)) return; - - foreach($obj as $name => $val) { - if(!$val || !count($val)) continue; - - foreach($val as $group_srl) { - $args = null; - $args->module_srl = $module_srl; - $args->name = $name; - $args->group_srl = trim($group_srl); - if(!$args->name || !$args->group_srl) continue; - executeQuery('module.insertModuleGrant', $args); - - } - } - } - - /** - * @brief 특정 모듈의 권한 제거 - **/ - function deleteModuleGrants($module_srl) { - $args->module_srl = $module_srl; - return executeQuery('module.deleteModuleGrants', $args); - } - - /** - * @brief 사용자 정의 언어 변경 - **/ - function replaceDefinedLangCode(&$output) { - $output = preg_replace_callback('!\$user_lang->([a-z0-9\_]+)!is', array($this,'_replaceLangCode'), $output); - } - function _replaceLangCode($matches) { - static $lang = null; - if(is_null($lang)) { - $site_module_info = Context::get('site_module_info'); - $cache_file = sprintf('%sfiles/cache/lang_defined/%d.%s.php', _XE_PATH_, $site_module_info->site_srl, Context::getLangType()); - if(!file_exists($cache_file)) { - $oModuleAdminController = &getAdminController('module'); - $oModuleAdminController->makeCacheDefinedLangCode($site_module_info->site_srl); - } - - if(file_exists($cache_file)) require_once($cache_file); - } - if(!Context::get($matches[1]) && $lang[$matches[1]]) return $lang[$matches[1]]; - - return str_replace('$user_lang->','',$matches[0]); - } - - - /** - * @brief 파일박스에 파일 추가 및 업데이트 - **/ - function procModuleFileBoxAdd(){ - - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); - - $vars = Context::gets('comment','addfile','filter'); - $module_filebox_srl = Context::get('module_filebox_srl'); - - $ext = strtolower(substr(strrchr($vars->addfile['name'],'.'),1)); - $vars->ext = $ext; - if($vars->filter) $filter = explode(',',$vars->filter); - else $filter = array('jpg','jpeg','gif','png'); - if(!in_array($ext,$filter)) return new Object(-1, 'msg_error_occured'); - - $vars->member_srl = $logged_info->member_srl; - - // update - if($module_filebox_srl > 0){ - $vars->module_filebox_srl = $module_filebox_srl; - $output = $this->updateModuleFileBox($vars); - - // insert - }else{ - if(!Context::isUploaded()) return new Object(-1, 'msg_error_occured'); - $addfile = Context::get('addfile'); - if(!is_uploaded_file($addfile['tmp_name'])) return new Object(-1, 'msg_error_occured'); - if($vars->addfile['error'] != 0) return new Object(-1, 'msg_error_occured'); - $output = $this->insertModuleFileBox($vars); - } - - $url = getUrl('','module','module','act','dispModuleFileBox','input',Context::get('input'),'filter',$vars->filter); - $url = html_entity_decode($url); - $vars = Context::set('url',$url); - $this->setTemplatePath($this->module_path.'tpl'); - $this->setTemplateFile('move_filebox_list'); - } - - - /** - * @brief 파일박스에 파일 업데이트 - **/ - function updateModuleFileBox($vars){ - - // have file - if($vars->addfile['tmp_name'] && is_uploaded_file($vars->addfile['tmp_name'])){ - $oModuleModel = &getModel('module'); - $output = $oModuleModel->getModuleFileBox($vars->module_filebox_srl); - FileHandler::removeFile($output->data->filename); - - $path = $oModuleModel->getModuleFileBoxPath($vars->module_filebox_srl); - FileHandler::makeDir($path); - - $save_filename = sprintf('%s%s.%s',$path, $vars->module_filebox_srl, $ext); - $tmp = $vars->addfile['tmp_name']; - - if(!@move_uploaded_file($tmp, $save_filename)) { - return false; - } - - $args->fileextension = strtolower(substr(strrchr($vars->addfile['name'],'.'),1)); - $args->filename = $save_filename; - $args->filesize = $vars->addfile['size']; - - } - - $args->module_filebox_srl = $vars->module_filebox_srl; - $args->comment = $vars->comment; - - return executeQuery('module.updateModuleFileBox', $vars); - } - - - /** - * @brief 파일박스에 파일 추가 - **/ - function insertModuleFileBox($vars){ - // set module_filebox_srl - $vars->module_filebox_srl = getNextSequence(); - - // get file path - $oModuleModel = &getModel('module'); - $path = $oModuleModel->getModuleFileBoxPath($vars->module_filebox_srl); - FileHandler::makeDir($path); - $save_filename = sprintf('%s%s.%s',$path, $vars->module_filebox_srl, $vars->ext); - $tmp = $vars->addfile['tmp_name']; - - // upload - if(!@move_uploaded_file($tmp, $save_filename)) { - return false; - } - - - // insert - $args->module_filebox_srl = $vars->module_filebox_srl; - $args->member_srl = $vars->member_srl; - $args->comment = $vars->comment; - $args->filename = $save_filename; - $args->fileextension = strtolower(substr(strrchr($vars->addfile['name'],'.'),1)); - $args->filesize = $vars->addfile['size']; - - $output = executeQuery('module.insertModuleFileBox', $args); - return $output; - } - - - /** - * @brief 파일박스에 파일 삭제 - **/ - - function procModuleFileBoxDelete(){ - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); - - $module_filebox_srl = Context::get('module_filebox_srl'); - if(!$module_filebox_srl) return new Object(-1, 'msg_invalid_request'); - $vars->module_filebox_srl = $module_filebox_srl; - $output = $this->deleteModuleFileBox($vars); - if(!$output->toBool()) return $output; - } - - function deleteModuleFileBox($vars){ - - // delete real file - $oModuleModel = &getModel('module'); - $output = $oModuleModel->getModuleFileBox($vars->module_filebox_srl); - FileHandler::removeFile($output->data->filename); - - $args->module_filebox_srl = $vars->module_filebox_srl; - return executeQuery('module.deleteModuleFileBox', $args); - } - - /** - * @brief function of locking (timeout is in seconds) - */ - function lock($lock_name, $timeout, $member_srl = null) { - $this->unlockTimeoutPassed(); - $args->lock_name = $lock_name; - if(!$timeout) $timeout = 60; - $args->deadline = date("YmdHis", time() + $timeout); - if($member_srl) $args->member_srl = $member_srl; - $output = executeQuery('module.insertLock', $args); - if($output->toBool()) { - $output->add('lock_name', $lock_name); - $output->add('deadline', $args->deadline); - } - return $output; - } - - function unlockTimeoutPassed() { - executeQuery('module.deleteLocksTimeoutPassed'); - } - - function unlock($lock_name, $deadline) { - $args->lock_name = $lock_name; - $args->deadline = $deadline; - $output = executeQuery('module.deleteLock', $args); - return $output; - } - - function updateModuleInSites($site_srls, $args) - { - $args->site_srls = $site_srls; - $output = executeQuery('module.updateModuleInSites', $args); - return $output; - } - } -?> +module = $module; + $args->type = $type; + $args->act = $act; + + $output = executeQuery('module.insertActionFoward', $args); + return $output; + } + + /** + * @brief action forward 삭제 + **/ + function deleteActionForward($module, $type, $act) { + $args->module = $module; + $args->type = $type; + $args->act = $act; + + $output = executeQuery('module.deleteActionFoward', $args); + return $output; + } + + /** + * @brief module trigger 추가 + * module trigger는 trigger 대상이 등록된 대상을 호출하는 방법이다. + * + **/ + function insertTrigger($trigger_name, $module, $type, $called_method, $called_position) { + $args->trigger_name = $trigger_name; + $args->module = $module; + $args->type = $type; + $args->called_method = $called_method; + $args->called_position = $called_position; + + $output = executeQuery('module.insertTrigger', $args); + + // 트리거 정보가 있는 파일 모두 삭제 + FileHandler::removeFilesInDir("./files/cache/triggers"); + + return $output; + } + + /** + * @brief module trigger 삭제 + * + **/ + function deleteTrigger($trigger_name, $module, $type, $called_method, $called_position) { + $args->trigger_name = $trigger_name; + $args->module = $module; + $args->type = $type; + $args->called_method = $called_method; + $args->called_position = $called_position; + + $output = executeQuery('module.deleteTrigger', $args); + + // 트리거 캐시 삭제 + FileHandler::removeFilesInDir('./files/cache/triggers'); + + return $output; + } + + /** + * @brief 특정 모듈의 설정 입력 + * board, member등 특정 모듈의 global config 관리용 + **/ + function insertModuleConfig($module, $config) { + $args->module = $module; + $args->config = serialize($config); + + $output = executeQuery('module.deleteModuleConfig', $args); + if(!$output->toBool()) return $output; + + $output = executeQuery('module.insertModuleConfig', $args); + return $output; + } + + /** + * @brief 특정 mid의 모듈 설정 정보 저장 + * mid의 모듈 의존적인 설정을 관리 + **/ + function insertModulePartConfig($module, $module_srl, $config) { + $args->module = $module; + $args->module_srl = $module_srl; + $args->config = serialize($config); + + $output = executeQuery('module.deleteModulePartConfig', $args); + if(!$output->toBool()) return $output; + + $output = executeQuery('module.insertModulePartConfig', $args); + return $output; + } + + /** + * @brief virtual site 생성 + **/ + function insertSite($domain, $index_module_srl) { + if(isSiteID($domain)) { + $oModuleModel = &getModel('module'); + if($oModuleModel->isIDExists($domain, 0)) return new Object(-1,'msg_already_registed_vid'); + } + $args->site_srl = getNextSequence(); + $args->domain = preg_replace('/\/$/','',$domain); + $args->index_module_srl = $index_module_srl; + $args->default_language = Context::getLangType(); + $output = executeQuery('module.getSiteInfoByDomain', $args); + if($output->data) return new Object(-1,'msg_already_registed_vid'); + + $output = executeQuery('module.insertSite', $args); + if(!$output->toBool()) return $output; + + $output->add('site_srl', $args->site_srl); + return $output; + } + + /** + * @brief virtual site 수정 + **/ + function updateSite($args) { + $oModuleModel = &getModel('module'); + $site_info = $oModuleModel->getSiteInfo($args->site_srl); + if($site_info->domain != $args->domain) { + $info = $oModuleModel->getSiteInfoByDomain($args->domain); + if($info->site_srl && $info->site_srl != $args->site_srl) return new Object(-1,'msg_already_registed_domain'); + if(isSiteID($args->domain) && $oModuleModel->isIDExists($args->domain)) return new Object(-1,'msg_already_registed_vid'); + } + $output = executeQuery('module.updateSite', $args); + return $output; + } + + /** + * @brief 모듈 정보 정리 + **/ + function arrangeModuleInfo(&$args, &$extra_vars) { + // 불필요한 내용 제거 + unset($args->body); + unset($args->act); + unset($args->page); + + // mid값 검사 + if(!preg_match("/^[a-z][a-z0-9_]+$/i", $args->mid)) return new Object(-1, 'msg_limit_mid'); + + // 변수를 검사 (modules의 기본 변수와 그렇지 않은 변수로 분리) + $extra_vars = clone($args); + unset($extra_vars->module_srl); + unset($extra_vars->module); + unset($extra_vars->module_category_srl); + unset($extra_vars->layout_srl); + unset($extra_vars->mlayout_srl); + unset($extra_vars->use_mobile); + unset($extra_vars->menu_srl); + unset($extra_vars->site_srl); + unset($extra_vars->mid); + unset($extra_vars->skin); + unset($extra_vars->mskin); + unset($extra_vars->browser_title); + unset($extra_vars->description); + unset($extra_vars->is_default); + unset($extra_vars->content); + unset($extra_vars->mcontent); + unset($extra_vars->open_rss); + unset($extra_vars->header_text); + unset($extra_vars->footer_text); + $args = delObjectVars($args, $extra_vars); + + return new Object(); + } + + /** + * @brief 모듈 입력 + **/ + function insertModule($args) { + $output = $this->arrangeModuleInfo($args, $extra_vars); + if(!$output->toBool()) return $output; + + // 이미 존재하는 모듈 이름인지 체크 + if(!$args->site_srl) $args->site_srl = 0; + $oModuleModel = &getModel('module'); + if($oModuleModel->isIDExists($args->mid, $args->site_srl)) return new Object(-1, 'msg_module_name_exists'); + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + // 선택된 스킨정보에서 colorset을 구함 + $module_path = ModuleHandler::getModulePath($args->module); + $skin_info = $oModuleModel->loadSkinInfo($module_path, $args->skin); + $skin_vars->colorset = $skin_info->colorset[0]->name; + + // 변수 정리후 query 실행 + if(!$args->module_srl) $args->module_srl = getNextSequence(); + + // 모듈 등록 + $output = executeQuery('module.insertModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 모듈 추가 변수 등록 + $this->insertModuleExtraVars($args->module_srl, $extra_vars); + + // commit + $oDB->commit(); + + $output->add('module_srl',$args->module_srl); + return $output; + } + + /** + * @brief 모듈의 정보를 수정 + **/ + function updateModule($args) { + $output = $this->arrangeModuleInfo($args, $extra_vars); + if(!$output->toBool()) return $output; + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + $oModuleModel = &getModel('module'); + $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); + + $args->site_srl = (int)$module_info->site_srl; + if(!$args->browser_title) $args->browser_title = $module_info->browser_title; + + $output = executeQuery('module.isExistsModuleName', $args); + if(!$output->toBool() || $output->data->count) { + $oDB->rollback(); + return new Object(-1, 'msg_module_name_exists'); + } + + $output = executeQuery('module.updateModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 모듈 추가 변수 등록 + $this->insertModuleExtraVars($args->module_srl, $extra_vars); + + $oDB->commit(); + + $output->add('module_srl',$args->module_srl); + return $output; + } + + /** + * @brief 모듈의 가상사이트 변경 + **/ + function updateModuleSite($module_srl, $site_srl, $layout_srl = 0) { + $args->module_srl = $module_srl; + $args->site_srl = $site_srl; + $args->layout_srl = $layout_srl; + return executeQuery('module.updateModuleSite', $args); + } + + /** + * @brief 모듈을 삭제 + * + * 모듈 삭제시는 관련 정보들을 모두 삭제 시도한다. + **/ + function deleteModule($module_srl) { + if(!$module_srl) return new Object(-1,'msg_invalid_request'); + + // trigger 호출 (before) + $trigger_obj->module_srl = $module_srl; + $output = ModuleHandler::triggerCall('module.deleteModule', 'before', $trigger_obj); + if(!$output->toBool()) return $output; + + // begin transaction + $oDB = &DB::getInstance(); + $oDB->begin(); + + $args->module_srl = $module_srl; + + // module 정보를 DB에서 삭제 + $output = executeQuery('module.deleteModule', $args); + if(!$output->toBool()) { + $oDB->rollback(); + return $output; + } + + // 권한 정보 삭제 + $this->deleteModuleGrants($module_srl); + + // 스킨 정보 삭제 + $this->deleteModuleSkinVars($module_srl); + + // 모듈 추가 변수 삭제 + $this->deleteModuleExtraVars($module_srl); + + // 모듈 관리자 제거 + $this->deleteAdminId($module_srl); + + // trigger 호출 (after) + if($output->toBool()) { + $trigger_output = ModuleHandler::triggerCall('module.deleteModule', 'after', $trigger_obj); + if(!$trigger_output->toBool()) { + $oDB->rollback(); + return $trigger_output; + } + } + + // commit + $oDB->commit(); + + return $output; + } + + /** + * @brief 모듈의 기타 정보를 변경 + **/ + function updateModuleSkinVars($module_srl, $skin_vars) { + // skin_vars 정보 세팅 + $args->module_srl = $module_srl; + $args->skin_vars = $skin_vars; + $output = executeQuery('module.updateModuleSkinVars', $args); + if(!$output->toBool()) return $output; + + return $output; + } + + /** + * @brief 모든 모듈의 is_default값을 N 으로 세팅 (기본 모듈 해제) + **/ + function clearDefaultModule() { + $output = executeQuery('module.clearDefaultModule'); + if(!$output->toBool()) return $output; + + return $output; + } + + /** + * @brief 지정된 menu_srl에 속한 mid 의 menu_srl 을 변경 + **/ + function updateModuleMenu($args) { + return executeQuery('module.updateModuleMenu', $args); + } + + /** + * @brief 지정된 menu_srl에 속한 mid 의 layout_srl을 변경 + **/ + function updateModuleLayout($layout_srl, $menu_srl_list) { + if(!count($menu_srl_list)) return; + + $args->layout_srl = $layout_srl; + $args->menu_srls = implode(',',$menu_srl_list); + $output = executeQuery('module.updateModuleLayout', $args); + return $output; + } + + /** + * @brief 사이트의 관리를 변경 + **/ + function insertSiteAdmin($site_srl, $arr_admins) { + // 사이트 관리자 제거 + $args->site_srl = $site_srl; + $output = executeQuery('module.deleteSiteAdmin', $args); + if(!$output->toBool()) return $output; + + // 관리자 대상 멤버 번호를 구함 + if(!is_array($arr_admins) || !count($arr_admins)) return new Object(); + foreach($arr_admins as $key => $user_id) { + if(!trim($user_id)) continue; + $admins[] = trim($user_id); + } + if(!count($admins)) return new Object(); + + $args->user_ids = '\''.implode('\',\'',$admins).'\''; + $output = executeQueryArray('module.getAdminSrls', $args); + if(!$output->toBool()||!$output->data) return $output; + + foreach($output->data as $key => $val) { + unset($args); + $args->site_srl = $site_srl; + $args->member_srl = $val->member_srl; + $output = executeQueryArray('module.insertSiteAdmin', $args); + if(!$output->toBool()) return $output; + } + return new Object(); + } + + /** + * @brief 특정 모듈에 관리자 아이디 지정 + **/ + function insertAdminId($module_srl, $admin_id) { + $oMemberModel = &getModel('member'); + $member_info = $oMemberModel->getMemberInfoByUserID($admin_id); + if(!$member_info->member_srl) return; + $args->module_srl = $module_srl; + $args->member_srl = $member_info->member_srl; + return executeQuery('module.insertAdminId', $args); + } + + /** + * @brief 특정 모듈의 관리자 아이디 제거 + **/ + function deleteAdminId($module_srl, $admin_id = '') { + $args->module_srl = $module_srl; + + if($admin_id) { + $oMemberModel = &getModel('member'); + $member_info = $oMemberModel->getMemberInfoByUserID($admin_id); + if($member_info->member_srl) $args->member_srl = $member_info->member_srl; + } + return executeQuery('module.deleteAdminId', $args); + } + + /** + * @brief 특정 모듈에 스킨 변수 등록 + **/ + function insertModuleSkinVars($module_srl, $obj) { + $this->deleteModuleSkinVars($module_srl); + if(!$obj || !count($obj)) return; + + $args->module_srl = $module_srl; + foreach($obj as $key => $val) { + // #17927989 예전 블로그 모듈을 사용하던 게시판의 경우 + // 스킨 정보 필드에 메뉴 항목(stdClass)을 저장해놓은 경우가 있어 + // 1.2.0 이상 버전으로 업그레이드한 후 모듈 업데이트할 때 + // 오류가 발생하는 문제 수정 + if (is_array($val) || is_object($val)) continue; + + $args->name = trim($key); + $args->value = trim($val); + if(!$args->name || !$args->value) continue; + executeQuery('module.insertModuleSkinVars', $args); + } + } + + /** + * @brief 특정 모듈의 스킨 변수 제거 + **/ + function deleteModuleSkinVars($module_srl) { + $args->module_srl = $module_srl; + return executeQuery('module.deleteModuleSkinVars', $args); + } + + /** + * @brief 특정 모듈에 확장 변수 등록 + **/ + function insertModuleExtraVars($module_srl, $obj) { + $this->deleteModuleExtraVars($module_srl); + if(!$obj || !count($obj)) return; + + foreach($obj as $key => $val) { + $args = null; + $args->module_srl = $module_srl; + $args->name = trim($key); + $args->value = trim($val); + if(!$args->name || !$args->value) continue; + executeQuery('module.insertModuleExtraVars', $args); + } + } + + /** + * @brief 특정 모듈의 확장 변수 제거 + **/ + function deleteModuleExtraVars($module_srl) { + $args->module_srl = $module_srl; + return executeQuery('module.deleteModuleExtraVars', $args); + } + + /** + * @brief 특정 모듈에 권한 등록 + **/ + function insertModuleGrants($module_srl, $obj) { + $this->deleteModuleGrants($module_srl); + if(!$obj || !count($obj)) return; + + foreach($obj as $name => $val) { + if(!$val || !count($val)) continue; + + foreach($val as $group_srl) { + $args = null; + $args->module_srl = $module_srl; + $args->name = $name; + $args->group_srl = trim($group_srl); + if(!$args->name || !$args->group_srl) continue; + executeQuery('module.insertModuleGrant', $args); + + } + } + } + + /** + * @brief 특정 모듈의 권한 제거 + **/ + function deleteModuleGrants($module_srl) { + $args->module_srl = $module_srl; + return executeQuery('module.deleteModuleGrants', $args); + } + + /** + * @brief 사용자 정의 언어 변경 + **/ + function replaceDefinedLangCode(&$output) { + $output = preg_replace_callback('!\$user_lang->([a-z0-9\_]+)!is', array($this,'_replaceLangCode'), $output); + } + function _replaceLangCode($matches) { + static $lang = null; + if(is_null($lang)) { + $site_module_info = Context::get('site_module_info'); + $cache_file = sprintf('%sfiles/cache/lang_defined/%d.%s.php', _XE_PATH_, $site_module_info->site_srl, Context::getLangType()); + if(!file_exists($cache_file)) { + $oModuleAdminController = &getAdminController('module'); + $oModuleAdminController->makeCacheDefinedLangCode($site_module_info->site_srl); + } + + if(file_exists($cache_file)) require_once($cache_file); + } + if(!Context::get($matches[1]) && $lang[$matches[1]]) return $lang[$matches[1]]; + + return str_replace('$user_lang->','',$matches[0]); + } + + + /** + * @brief 파일박스에 파일 추가 및 업데이트 + **/ + function procModuleFileBoxAdd(){ + + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); + + $vars = Context::gets('comment','addfile','filter'); + $module_filebox_srl = Context::get('module_filebox_srl'); + + $ext = strtolower(substr(strrchr($vars->addfile['name'],'.'),1)); + $vars->ext = $ext; + if($vars->filter) $filter = explode(',',$vars->filter); + else $filter = array('jpg','jpeg','gif','png'); + if(!in_array($ext,$filter)) return new Object(-1, 'msg_error_occured'); + + $vars->member_srl = $logged_info->member_srl; + + // update + if($module_filebox_srl > 0){ + $vars->module_filebox_srl = $module_filebox_srl; + $output = $this->updateModuleFileBox($vars); + + // insert + }else{ + if(!Context::isUploaded()) return new Object(-1, 'msg_error_occured'); + $addfile = Context::get('addfile'); + if(!is_uploaded_file($addfile['tmp_name'])) return new Object(-1, 'msg_error_occured'); + if($vars->addfile['error'] != 0) return new Object(-1, 'msg_error_occured'); + $output = $this->insertModuleFileBox($vars); + } + + $url = getUrl('','module','module','act','dispModuleFileBox','input',Context::get('input'),'filter',$vars->filter); + $url = html_entity_decode($url); + $vars = Context::set('url',$url); + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('move_filebox_list'); + } + + + /** + * @brief 파일박스에 파일 업데이트 + **/ + function updateModuleFileBox($vars){ + + // have file + if($vars->addfile['tmp_name'] && is_uploaded_file($vars->addfile['tmp_name'])){ + $oModuleModel = &getModel('module'); + $output = $oModuleModel->getModuleFileBox($vars->module_filebox_srl); + FileHandler::removeFile($output->data->filename); + + $path = $oModuleModel->getModuleFileBoxPath($vars->module_filebox_srl); + FileHandler::makeDir($path); + + $save_filename = sprintf('%s%s.%s',$path, $vars->module_filebox_srl, $ext); + $tmp = $vars->addfile['tmp_name']; + + if(!@move_uploaded_file($tmp, $save_filename)) { + return false; + } + + $args->fileextension = strtolower(substr(strrchr($vars->addfile['name'],'.'),1)); + $args->filename = $save_filename; + $args->filesize = $vars->addfile['size']; + + } + + $args->module_filebox_srl = $vars->module_filebox_srl; + $args->comment = $vars->comment; + + return executeQuery('module.updateModuleFileBox', $vars); + } + + + /** + * @brief 파일박스에 파일 추가 + **/ + function insertModuleFileBox($vars){ + // set module_filebox_srl + $vars->module_filebox_srl = getNextSequence(); + + // get file path + $oModuleModel = &getModel('module'); + $path = $oModuleModel->getModuleFileBoxPath($vars->module_filebox_srl); + FileHandler::makeDir($path); + $save_filename = sprintf('%s%s.%s',$path, $vars->module_filebox_srl, $vars->ext); + $tmp = $vars->addfile['tmp_name']; + + // upload + if(!@move_uploaded_file($tmp, $save_filename)) { + return false; + } + + + // insert + $args->module_filebox_srl = $vars->module_filebox_srl; + $args->member_srl = $vars->member_srl; + $args->comment = $vars->comment; + $args->filename = $save_filename; + $args->fileextension = strtolower(substr(strrchr($vars->addfile['name'],'.'),1)); + $args->filesize = $vars->addfile['size']; + + $output = executeQuery('module.insertModuleFileBox', $args); + return $output; + } + + + /** + * @brief 파일박스에 파일 삭제 + **/ + + function procModuleFileBoxDelete(){ + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); + + $module_filebox_srl = Context::get('module_filebox_srl'); + if(!$module_filebox_srl) return new Object(-1, 'msg_invalid_request'); + $vars->module_filebox_srl = $module_filebox_srl; + $output = $this->deleteModuleFileBox($vars); + if(!$output->toBool()) return $output; + } + + function deleteModuleFileBox($vars){ + + // delete real file + $oModuleModel = &getModel('module'); + $output = $oModuleModel->getModuleFileBox($vars->module_filebox_srl); + FileHandler::removeFile($output->data->filename); + + $args->module_filebox_srl = $vars->module_filebox_srl; + return executeQuery('module.deleteModuleFileBox', $args); + } + + /** + * @brief function of locking (timeout is in seconds) + */ + function lock($lock_name, $timeout, $member_srl = null) { + $this->unlockTimeoutPassed(); + $args->lock_name = $lock_name; + if(!$timeout) $timeout = 60; + $args->deadline = date("YmdHis", time() + $timeout); + if($member_srl) $args->member_srl = $member_srl; + $output = executeQuery('module.insertLock', $args); + if($output->toBool()) { + $output->add('lock_name', $lock_name); + $output->add('deadline', $args->deadline); + } + return $output; + } + + function unlockTimeoutPassed() { + executeQuery('module.deleteLocksTimeoutPassed'); + } + + function unlock($lock_name, $deadline) { + $args->lock_name = $lock_name; + $args->deadline = $deadline; + $output = executeQuery('module.deleteLock', $args); + return $output; + } + + function updateModuleInSites($site_srls, $args) + { + $args->site_srls = $site_srls; + $output = executeQuery('module.updateModuleInSites', $args); + return $output; + } + } +?> diff --git a/modules/module/module.model.php b/modules/module/module.model.php index e7083bd16..faf844522 100644 --- a/modules/module/module.model.php +++ b/modules/module/module.model.php @@ -1,1282 +1,1282 @@ -mid = $id; - $args->site_srl = $site_srl; - $output = executeQuery('module.isExistsModuleName', $args); - if($output->data->count) return true; - - // vid 검사 (site_srl이 0일때 즉 가상사이트가 아닌 경우 mid != vid임을 체크) - if(!$site_srl) { - $site_args->domain = $id; - $output = executeQuery('module.isExistsSiteDomain', $site_args); - if($output->data->count) return true; - } - - return false; - } - - /** - * @brief site 정보를 구함 - **/ - function getSiteInfo($site_srl) { - $args->site_srl = $site_srl; - $output = executeQuery('module.getSiteInfo', $args); - return $output->data; - } - - function getSiteInfoByDomain($domain) { - $args->domain= $domain; - $output = executeQuery('module.getSiteInfoByDomain', $args); - return $output->data; - } - - /** - * @brief document_srl로 모듈의 정보르 구함 - * 이 경우는 캐시파일을 이용할 수가 없음 - **/ - function getModuleInfoByDocumentSrl($document_srl) { - $args->document_srl = $document_srl; - $output = executeQuery('module.getModuleInfoByDocument', $args); - return $this->addModuleExtraVars($output->data); - } - - /** - * @brief domain에 따른 기본 mid를 구함 - **/ - function getDefaultMid() { - $default_url = preg_replace('/\/$/','',Context::getDefaultUrl()); - $request_url = preg_replace('/\/$/','',Context::getRequestUri()); - $vid = Context::get('vid'); - $mid = Context::get('mid'); - - // 기본 URL이 설정되어 있고 이 기본 URL과 요청 URL이 다르면 가상 사이트 확인 - if($default_url && $default_url != $request_url) { - $url_info = parse_url($request_url); - $hostname = $url_info['host']; - $path = preg_replace('/\/$/','',$url_info['path']); - $sites_args->domain = sprintf('%s%s%s', $hostname, $url_info['port']&&$url_info['port']!=80?':'.$url_info['port']:'',$path); - $output = executeQuery('module.getSiteInfoByDomain', $sites_args); - } - if(!$output || !$output->data) - { - if(!$vid) $vid = $mid; - if($vid) { - $vid_args->domain = $vid; - $output = executeQuery('module.getSiteInfoByDomain', $vid_args); - if($output->toBool() && $output->data) { - Context::set('vid', $output->data->domain, true); - if($mid==$output->data->domain) Context::set('mid',$output->data->mid,true); - } - } - } - - // 가상 사이트가 아닐 경우 기본 사이트 정보를 구함 - if(!$output->data) { - $args->site_srl = 0; - $output = executeQuery('module.getSiteInfo', $args); - - // 기본 사이트 정보가 없으면 관련된 정보를 갱신 - if(!$output->data) { - // sites 테이블이 없을 경우 생성 - $oDB = &DB::getInstance(); - if(!$oDB->isTableExists('sites')) $oDB->createTableByXmlFile(_XE_PATH_.'modules/module/schemas/sites.xml'); - if(!$oDB->isTableExists('sites')) return; - - // 기본 mid, 언어 구함 - $mid_output = $oDB->executeQuery('module.getDefaultMidInfo', $args); - $db_info = Context::getDBInfo(); - $domain = Context::getDefaultUrl(); - $url_info = parse_url($domain); - $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; - $site_args->site_srl = 0; - $site_args->index_module_srl = $mid_output->data->module_srl; - $site_args->domain = $domain; - $site_args->default_language = $db_info->lang_type; - - if($output->data && !$output->data->index_module_srl) { - $output = executeQuery('module.updateSite', $site_args); - } else { - $output = executeQuery('module.insertSite', $site_args); - if(!$output->toBool()) return $output; - } - $output = executeQuery('module.getSiteInfo', $args); - } - } - $module_info = $output->data; - if(!$module_info->module_srl) return $module_info; - if(is_array($module_info) && $module_info->data[0]) $module_info = $module_info[0]; - return $this->addModuleExtraVars($module_info); - } - - /** - * @brief mid로 모듈의 정보를 구함 - **/ - function getModuleInfoByMid($mid, $site_srl = 0) { - $args->mid = $mid; - $args->site_srl = (int)$site_srl; - $output = executeQuery('module.getMidInfo', $args); - $module_info = $output->data; - if(!$module_info->module_srl && $module_info->data[0]) $module_info = $module_info->data[0]; - return $this->addModuleExtraVars($module_info); - } - - /** - * @brief module_srl에 해당하는 모듈의 정보를 구함 - **/ - function getModuleInfoByModuleSrl($module_srl) { - // 데이터를 가져옴 - $args->module_srl = $module_srl; - $output = executeQuery('module.getMidInfo', $args); - if(!$output->data) return; - $module_info = $this->addModuleExtraVars($output->data); - return $module_info; - } - - /** - * @brief layout_srl에 해당하는 모듈의 정보를 구함 - **/ - function getModulesInfoByLayout($layout_srl) { - // 데이터를 가져옴 - $args->layout_srl = $layout_srl; - $output = executeQueryArray('module.getModulesByLayout', $args); - - $count = count($output->data); - - $modules = array(); - for($i=0;$i<$count;$i++) { - $modules[] = $output->data[$i]; - } - return $this->addModuleExtraVars($modules); - } - - /** - * @brief 여러개의 module_srl에 해당하는 모듈의 정보를 구함 - **/ - function getModulesInfo($module_srls) { - if(is_array($module_srls)) $module_srls = implode(',',$module_srls); - $args->module_srls = $module_srls; - $output = executeQueryArray('module.getModulesInfo', $args); - if(!$output->toBool()) return; - return $this->addModuleExtraVars($output->data); - } - - /** - * @brief 모듈의 기본 정보에 추가 변수 구함 - **/ - function addModuleExtraVars($module_info) { - // 1개 이상의 모듈정보를 요청받아도 처리 가능하도록 - if(!is_array($module_info)) $target_module_info = array($module_info); - else $target_module_info = $module_info; - - // 모듈 번호를 구함 - $module_srls = array(); - foreach($target_module_info as $key => $val) { - $module_srl = $val->module_srl; - if(!$module_srl) continue; - $module_srls[] = $val->module_srl; - } - - // 모듈의 추가정보/ 스킨 정보를 추출 - $extra_vars = $this->getModuleExtraVars($module_srls); - if(!count($module_srls) || !count($extra_vars)) return $module_info; - - foreach($target_module_info as $key => $val) { - if(!$extra_vars[$val->module_srl] || !count($extra_vars[$val->module_srl])) continue; - foreach($extra_vars[$val->module_srl] as $k => $v) { - if($target_module_info[$key]->{$k}) continue; - $target_module_info[$key]->{$k} = $v; - } - } - if(is_array($module_info)) return $target_module_info; - return $target_module_info[0]; - } - - /** - * @brief DB에 생성된 mid 전체 목록을 구해옴 - **/ - function getMidList($args = null) { - $output = executeQuery('module.getMidList', $args); - if(!$output->toBool()) return $output; - - $list = $output->data; - if(!$list) return; - - if(!is_array($list)) $list = array($list); - - foreach($list as $val) { - $mid_list[$val->mid] = $val; - } - return $mid_list; - } - - /** - * @brief mid 목록에 대응하는 module_srl을 배열로 return - **/ - function getModuleSrlByMid($mid) { - if($mid && !is_array($mid)) $mid = explode(',',$mid); - if(is_array($mid)) $mid = "'".implode("','",$mid)."'"; - - $site_module_info = Context::get('site_module_info'); - - $args->mid = $mid; - if($site_module_info) $args->site_srl = $site_module_info->site_srl; - $output = executeQuery('module.getModuleSrlByMid', $args); - if(!$output->toBool()) return $output; - - $list = $output->data; - if(!$list) return; - if(!is_array($list)) $list = array($list); - - foreach($list as $key => $val) { - $module_srl_list[] = $val->module_srl; - } - - return $module_srl_list; - } - - /** - * @brief act 값에 의한 forward 값을 구함 - **/ - function getActionForward($act, $module = "") { - $args->act = $act; - $args->module = ($module)?$module:null; - if (strlen ($args->module) > 0) $output = executeQuery ('module.getActionForwardWithModule', $args); - else $output = executeQuery('module.getActionForward',$args); - return $output->data; - } - - /** - * @brief trigger_name에 등록된 모든 목록을 추출 - **/ - function getTriggers($trigger_name, $called_position) { - $args->trigger_name = $trigger_name; - $args->called_position = $called_position; - $output = executeQueryArray('module.getTriggers',$args); - return $output->data; - } - - /** - * @brief 특정 trigger_name의 특정 대상을 추출 - **/ - function getTrigger($trigger_name, $module, $type, $called_method, $called_position) { - $args->trigger_name = $trigger_name; - $args->module = $module; - $args->type = $type; - $args->called_method = $called_method; - $args->called_position = $called_position; - $output = executeQuery('module.getTrigger',$args); - return $output->data; - } - - /** - * @brief 모듈의 conf/info.xml 을 읽어서 정보를 구함 - **/ - function getModuleInfoXml($module) { - // 요청된 모듈의 경로를 구한다. 없으면 return - $module_path = ModuleHandler::getModulePath($module); - if(!$module_path) return; - - // 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음 - $xml_file = sprintf("%s/conf/info.xml", $module_path); - if(!file_exists($xml_file)) return; - - $oXmlParser = new XmlParser(); - $tmp_xml_obj = $oXmlParser->loadXmlFile($xml_file); - $xml_obj = $tmp_xml_obj->module; - - if(!$xml_obj) return; - - // 모듈 정보 - if($xml_obj->version && $xml_obj->attrs->version == '0.2') { - // module format 0.2 - $module_info->title = $xml_obj->title->body; - $module_info->description = $xml_obj->description->body; - $module_info->version = $xml_obj->version->body; - $module_info->homepage = $xml_obj->link->body; - $module_info->category = $xml_obj->category->body; - if(!$module_info->category) $module_info->category = 'service'; - sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); - $module_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $module_info->license = $xml_obj->license->body; - $module_info->license_link = $xml_obj->license->attrs->link; - - if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; - else $author_list = $xml_obj->author; - - foreach($author_list as $author) { - unset($author_obj); - $author_obj->name = $author->name->body; - $author_obj->email_address = $author->attrs->email_address; - $author_obj->homepage = $author->attrs->link; - $module_info->author[] = $author_obj; - } - - // history - if($xml_obj->history) { - if(!is_array($xml_obj->history)) $history[] = $xml_obj->history; - else $history = $xml_obj->history; - - foreach($history as $item) { - unset($obj); - - if($item->author) { - (!is_array($item->author)) ? $obj->author_list[] = $item->author : $obj->author_list = $item->author; - - foreach($obj->author_list as $author) { - unset($author_obj); - $author_obj->name = $author->name->body; - $author_obj->email_address = $author->attrs->email_address; - $author_obj->homepage = $author->attrs->link; - $obj->author[] = $author_obj; - } - } - - $obj->name = $item->name->body; - $obj->email_address = $item->attrs->email_address; - $obj->homepage = $item->attrs->link; - $obj->version = $item->attrs->version; - $obj->date = $item->attrs->date; - $obj->description = $item->description->body; - - if($item->log) { - (!is_array($item->log)) ? $obj->log[] = $item->log : $obj->log = $item->log; - - foreach($obj->log as $log) { - unset($logs_obj); - $logs_obj->text = $log->body; - $logs_obj->link = $log->attrs->link; - $obj->logs[] = $logs_obj; - } - } - - $module_info->history[] = $obj; - } - } - - - } else { - // module format 0.1 - $module_info->title = $xml_obj->title->body; - $module_info->description = $xml_obj->author->description->body; - $module_info->version = $xml_obj->attrs->version; - $module_info->category = $xml_obj->attrs->category; - if(!$module_info->category) $module_info->category = 'service'; - sscanf($xml_obj->author->attrs->date, '%d. %d. %d', $date_obj->y, $date_obj->m, $date_obj->d); - $module_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $author_obj->name = $xml_obj->author->name->body; - $author_obj->email_address = $xml_obj->author->attrs->email_address; - $author_obj->homepage = $xml_obj->author->attrs->link; - $module_info->author[] = $author_obj; - } - - // action 정보를 얻어서 admin_index를 추가 - $action_info = $this->getModuleActionXml($module); - $module_info->admin_index_act = $action_info->admin_index_act; - $module_info->default_index_act = $action_info->default_index_act; - $module_info->setup_index_act = $action_info->setup_index_act; - - return $module_info; - } - - /** - * @brief module의 conf/module.xml 을 통해 grant(권한) 및 action 데이터를 return - * module.xml 파일의 경우 파싱하는데 시간이 걸리기에 캐싱을 한다... - * 캐싱을 할때 바로 include 할 수 있도록 역시 코드까지 추가하여 캐싱을 한다. - * 이게 퍼포먼스 상으로는 좋은데 어떤 부정적인 결과를 유도할지는 잘 모르겠... - **/ - function getModuleActionXml($module) { - // 요청된 모듈의 경로를 구한다. 없으면 return - $class_path = ModuleHandler::getModulePath($module); - if(!$class_path) return; - - // 해당 경로에 module.xml 파일이 있는지 체크한다. 없으면 return - $xml_file = sprintf("%sconf/module.xml", $class_path); - if(!file_exists($xml_file)) return; - - // 캐시된 파일이 있는지 확인 - $cache_file = sprintf("./files/cache/module_info/%s.%s.php", $module, Context::getLangType()); - - // 캐시 파일이 없거나 캐시 파일이 xml 파일보다 오래되었으면 내용 다시 갱신 - if(!file_exists($cache_file) || filemtime($cache_file)module)) return; ///< xml 내용중에 module 태그가 없다면 오류;; - - $grants = $xml_obj->module->grants->grant; ///< 권한 정보 (없는 경우도 있음) - $permissions = $xml_obj->module->permissions->permission; ///< 권한 대행 (없는 경우도 있음) - $actions = $xml_obj->module->actions->action; ///< action list (필수) - - $default_index = $admin_index = ''; - - // 권한 정보의 정리 - if($grants) { - if(is_array($grants)) $grant_list = $grants; - else $grant_list[] = $grants; - - foreach($grant_list as $grant) { - $name = $grant->attrs->name; - $default = $grant->attrs->default?$grant->attrs->default:'guest'; - $title = $grant->title->body; - - $info->grant->{$name}->title = $title; - $info->grant->{$name}->default = $default; - - $buff .= sprintf('$info->grant->%s->title=\'%s\';', $name, $title); - $buff .= sprintf('$info->grant->%s->default=\'%s\';', $name, $default); - } - } - - // 권한 허용 정리 - if($permissions) { - if(is_array($permissions)) $permission_list = $permissions; - else $permission_list[] = $permissions; - - foreach($permission_list as $permission) { - $action = $permission->attrs->action; - $target = $permission->attrs->target; - - $info->permission->{$action} = $target; - - $buff .= sprintf('$info->permission->%s = \'%s\';', $action, $target); - } - } - - // actions 정리 - if($actions) { - if(is_array($actions)) $action_list = $actions; - else $action_list[] = $actions; - - foreach($action_list as $action) { - $name = $action->attrs->name; - - $type = $action->attrs->type; - $grant = $action->attrs->grant?$action->attrs->grant:'guest'; - $standalone = $action->attrs->standalone=='true'?'true':'false'; - - $index = $action->attrs->index; - $admin_index = $action->attrs->admin_index; - $setup_index = $action->attrs->setup_index; - - $output->action->{$name}->type = $type; - $output->action->{$name}->grant = $grant; - $output->action->{$name}->standalone= $standalone; - - $info->action->{$name}->type = $type; - $info->action->{$name}->grant = $grant; - $info->action->{$name}->standalone = $standalone=='true'?true:false; - - $buff .= sprintf('$info->action->%s->type=\'%s\';', $name, $type); - $buff .= sprintf('$info->action->%s->grant=\'%s\';', $name, $grant); - $buff .= sprintf('$info->action->%s->standalone=%s;', $name, $standalone); - - if($index=='true') { - $default_index_act = $name; - $info->default_index_act = $name; - } - if($admin_index=='true') { - $admin_index_act = $name; - $info->admin_index_act = $name; - } - if($setup_index=='true') { - $setup_index_act = $name; - $info->setup_index_act = $name; - } - } - } - $buff = sprintf('default_index_act = \'%s\';$info->setup_index_act=\'%s\';$info->admin_index_act = \'%s\';%s?>', $default_index_act, $setup_index_act, $admin_index_act, $buff); - - FileHandler::writeFile($cache_file, $buff); - - return $info; - } - - @include($cache_file); - - return $info; - } - - - /** - * @brief 주어진 곳의 스킨 목록을 구함 - * 스킨과 skin.xml 파일을 분석 정리한 결과를 return - **/ - function getSkins($path, $dir = 'skins') { - $skin_path = sprintf("%s/%s/", $path, $dir); - $list = FileHandler::readDir($skin_path); - if(!count($list)) return; - - natcasesort($list); - - foreach($list as $skin_name) { - unset($skin_info); - $skin_info = $this->loadSkinInfo($path, $skin_name, $dir); - if(!$skin_info) $skin_info->title = $skin_name; - - $skin_list[$skin_name] = $skin_info; - } - - return $skin_list; - } - - /** - * @brief 특정 위치의 특정 스킨의 정보를 구해옴 - **/ - function loadSkinInfo($path, $skin, $dir = 'skins') { - - // 모듈의 스킨의 정보 xml 파일을 읽음 - if(substr($path,-1)!='/') $path .= '/'; - $skin_xml_file = sprintf("%s%s/%s/skin.xml", $path, $dir, $skin); - if(!file_exists($skin_xml_file)) return; - - // XmlParser 객체 생성 - $oXmlParser = new XmlParser(); - $_xml_obj = $oXmlParser->loadXmlFile($skin_xml_file); - - // 스킨 정보가 없으면 return - if(!$_xml_obj->skin) return; - $xml_obj = $_xml_obj->skin; - - // 스킨이름 - $skin_info->title = $xml_obj->title->body; - - - // 작성자 정보 - if($xml_obj->version && $xml_obj->attrs->version == '0.2') { - // skin format v0.2 - sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); - $skin_info->version = $xml_obj->version->body; - $skin_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $skin_info->homepage = $xml_obj->link->body; - $skin_info->license = $xml_obj->license->body; - $skin_info->license_link = $xml_obj->license->attrs->link; - $skin_info->description = $xml_obj->description->body; - - if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; - else $author_list = $xml_obj->author; - - foreach($author_list as $author) { - unset($author_obj); - $author_obj->name = $author->name->body; - $author_obj->email_address = $author->attrs->email_address; - $author_obj->homepage = $author->attrs->link; - $skin_info->author[] = $author_obj; - } - - // 확장변수를 정리 - if($xml_obj->extra_vars) { - $extra_var_groups = $xml_obj->extra_vars->group; - if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; - if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); - - foreach($extra_var_groups as $group) { - $extra_vars = $group->var; - if(!is_array($group->var)) $extra_vars = array($group->var); - - foreach($extra_vars as $key => $val) { - unset($obj); - if(!$val->attrs->type) { $val->attrs->type = 'text'; } - - $obj->group = $group->title->body; - $obj->name = $val->attrs->name; - $obj->title = $val->title->body; - $obj->type = $val->attrs->type; - $obj->description = $val->description->body; - $obj->value = $extra_vals->{$obj->name}; - $obj->default = $val->attrs->default; - if(strpos($obj->value, '|@|') != false) { $obj->value = explode('|@|', $obj->value); } - if($obj->type == 'mid_list' && !is_array($obj->value)) { $obj->value = array($obj->value); } - - // 'select'type에서 option목록을 구한다. - if(is_array($val->options)) { - $option_count = count($val->options); - - for($i = 0; $i < $option_count; $i++) { - $obj->options[$i]->title = $val->options[$i]->title->body; - $obj->options[$i]->value = $val->options[$i]->attrs->value; - } - } else { - $obj->options[0]->title = $val->options->title->body; - $obj->options[0]->value = $val->options->attrs->value; - } - - $skin_info->extra_vars[] = $obj; - } - } - } - - // history - if($xml_obj->history) { - if(!is_array($xml_obj->history)) $history[] = $xml_obj->history; - else $history = $xml_obj->history; - - foreach($history as $item) { - unset($obj); - - if($item->author) { - (!is_array($item->author)) ? $obj->author_list[] = $item->author : $obj->author_list = $item->author; - - foreach($obj->author_list as $author) { - unset($author_obj); - $author_obj->name = $author->name->body; - $author_obj->email_address = $author->attrs->email_address; - $author_obj->homepage = $author->attrs->link; - $obj->author[] = $author_obj; - } - } - - $obj->name = $item->name->body; - $obj->email_address = $item->attrs->email_address; - $obj->homepage = $item->attrs->link; - $obj->version = $item->attrs->version; - $obj->date = $item->attrs->date; - $obj->description = $item->description->body; - - if($item->log) { - (!is_array($item->log)) ? $obj->log[] = $item->log : $obj->log = $item->log; - - foreach($obj->log as $log) { - unset($log_obj); - $log_obj->text = $log->body; - $log_obj->link = $log->attrs->link; - $obj->logs[] = $log_obj; - } - } - - $skin_info->history[] = $obj; - } - } - - - } else { - - // skin format v0.1 - sscanf($xml_obj->maker->attrs->date, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); - - $skin_info->version = $xml_obj->version->body; - $skin_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); - $skin_info->homepage = $xml_obj->link->body; - $skin_info->license = $xml_obj->license->body; - $skin_info->license_link = $xml_obj->license->attrs->link; - $skin_info->description = $xml_obj->maker->description->body; - - $skin_info->author[0]->name = $xml_obj->maker->name->body; - $skin_info->author[0]->email_address = $xml_obj->maker->attrs->email_address; - $skin_info->author[0]->homepage = $xml_obj->maker->attrs->link; - - // 스킨에서 사용되는 변수들 - $extra_var_groups = $xml_obj->extra_vars->group; - if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; - if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); - - foreach($extra_var_groups as $group){ - $extra_vars = $group->var; - - if($extra_vars) { - - if(!is_array($extra_vars)) $extra_vars = array($extra_vars); - - foreach($extra_vars as $var) { - unset($obj); - unset($options); - - $group = $group->title->body; - $name = $var->attrs->name; - $type = $var->attrs->type; - $title = $var->title->body; - $description = $var->description->body; - - // 'select'type에서 option목록을 구한다. - if(is_array($var->default)) { - $option_count = count($var->default); - - for($i = 0; $i < $option_count; $i++) { - $options[$i]->title = $var->default[$i]->body; - $options[$i]->value = $var->default[$i]->body; - } - } else { - $options[0]->title = $var->default->body; - $options[0]->value = $var->default->body; - } - - $width = $var->attrs->width; - $height = $var->attrs->height; - - unset($obj); - $obj->group = $group; - $obj->title = $title; - $obj->description = $description; - $obj->name = $name; - $obj->type = $type; - $obj->options = $options; - $obj->width = $width; - $obj->height = $height; - $obj->default = $options[0]->value; - - $skin_info->extra_vars[] = $obj; - } - } - } - } - - // colorset - $colorset = $xml_obj->colorset->color; - if($colorset) { - if(!is_array($colorset)) $colorset = array($colorset); - - foreach($colorset as $color) { - $name = $color->attrs->name; - $title = $color->title->body; - $screenshot = $color->attrs->src; - if($screenshot) { - $screenshot = sprintf("%sskins/%s/%s", $path, $skin, $screenshot); - if(!file_exists($screenshot)) $screenshot = ""; - } else $screenshot = ""; - - unset($obj); - $obj->name = $name; - $obj->title = $title; - $obj->screenshot = $screenshot; - $skin_info->colorset[] = $obj; - } - } - - // 메뉴 종류 (레이아웃을 위한 설정) - if($xml_obj->menus->menu) { - $menus = $xml_obj->menus->menu; - if(!is_array($menus)) $menus = array($menus); - - $menu_count = count($menus); - $skin_info->menu_count = $menu_count; - for($i=0;$i<$menu_count;$i++) { - unset($obj); - - $obj->name = $menus[$i]->attrs->name; - if($menus[$i]->attrs->default == "true") $obj->default = true; - $obj->title = $menus[$i]->title->body; - $obj->maxdepth = $menus[$i]->maxdepth->body; - - $skin_info->menu->{$obj->name} = $obj; - } - } - - return $skin_info; - } - - /** - * @brief 특정 가상 사이트에 등록된 특정 모듈의 개수를 return - **/ - function getModuleCount($site_srl, $module = null) { - $args->site_srl = $site_srl; - if(!is_null($module)) $args->module = $module; - $output = executeQuery('module.getModuleCount', $args); - return $output->data->count; - } - - /** - * @brief 특정 모듈의 설정 return - * board, member등 특정 모듈의 global config 관리용 - **/ - function getModuleConfig($module) { - if(!$GLOBALS['__ModuleConfig__'][$module]) { - $args->module = $module; - $output = executeQuery('module.getModuleConfig', $args); - $config = unserialize($output->data->config); - $GLOBALS['__ModuleConfig__'][$module] = $config; - } - return $GLOBALS['__ModuleConfig__'][$module]; - } - - /** - * @brief 특정 mid의 모듈 설정 정보 return - * mid의 모듈 의존적인 설정을 관리 - **/ - function getModulePartConfig($module, $module_srl) { - if(!$GLOBALS['__ModulePartConfig__'][$module][$module_srl]) { - $args->module = $module; - $args->module_srl = $module_srl; - $output = executeQuery('module.getModulePartConfig', $args); - $config = unserialize($output->data->config); - $GLOBALS['__ModulePartConfig__'][$module][$module_srl] = $config; - } - return $GLOBALS['__ModulePartConfig__'][$module][$module_srl]; - } - - /** - * @brief mid별 모듈 설정 정보 전체를 구함 - **/ - function getModulePartConfigs($module, $site_srl = 0) { - $args->module = $module; - if($site_srl) $args->site_srl = $site_srl; - $output = executeQueryArray('module.getModulePartConfigs', $args); - if(!$output->toBool() || !$output->data) return array(); - - foreach($output->data as $key => $val) { - $result[$val->module_srl] = unserialize($val->config); - } - return $result; - } - - - /** - * @brief 모듈 카테고리의 목록을 구함 - **/ - function getModuleCategories() { - // 데이터를 DB에서 가져옴 - $output = executeQuery('module.getModuleCategories'); - if(!$output->toBool()) return $output; - $list = $output->data; - if(!$list) return; - if(!is_array($list)) $list = array($list); - - foreach($list as $val) { - $category_list[$val->module_category_srl] = $val; - } - return $category_list; - } - - /** - * @brief 특정 모듈 카테고리의 내용을 구함 - **/ - function getModuleCategory($module_category_srl) { - // 데이터를 DB에서 가져옴 - $args->module_category_srl = $module_category_srl; - $output = executeQuery('module.getModuleCategory', $args); - if(!$output->toBool()) return $output; - return $output->data; - } - - /** - * @brief 모듈의 xml 정보만 구함 - **/ - function getModulesXmlInfo() { - // 다운받은 모듈과 설치된 모듈의 목록을 구함 - $searched_list = FileHandler::readDir('./modules'); - $searched_count = count($searched_list); - if(!$searched_count) return; - sort($searched_list); - - for($i=0;$i<$searched_count;$i++) { - // 모듈의 이름 - $module_name = $searched_list[$i]; - - $path = ModuleHandler::getModulePath($module_name); - - // 해당 모듈의 정보를 구함 - $info = $this->getModuleInfoXml($module_name); - unset($obj); - - $info->module = $module_name; - $info->created_table_count = $created_table_count; - $info->table_count = $table_count; - $info->path = $path; - $info->admin_index_act = $info->admin_index_act; - $list[] = $info; - } - return $list; - } - - function checkNeedInstall($module_name) - { - $oDB = &DB::getInstance(); - $info = null; - - $moduledir = ModuleHandler::getModulePath($module_name); - if(file_exists(FileHandler::getRealPath($moduledir."schemas"))) - { - $tmp_files = FileHandler::readDir($moduledir."schemas", '/(\.xml)$/'); - $table_count = count($tmp_files); - - // 테이블이 설치되어 있는지 체크 - $created_table_count = 0; - for($j=0;$jisTableExists($table_name)) $created_table_count ++; - } - - // 설치 유무 체크 (설치는 DB의 설치만 관리) - if($table_count > $created_table_count) return true; - else return false; - } - return false; - } - - function checkNeedUpdate($module_name) - { - // 각 모듈의 module.class.php로 upgrade 유무 체크 - $oDummy = &getModule($module_name, 'class'); - if($oDummy && method_exists($oDummy, "checkUpdate")) { - return $oDummy->checkUpdate(); - } - return false; - } - - /** - * @brief 모듈의 종류와 정보를 구함 - **/ - function getModuleList() { - // DB 객체 생성 - $oDB = &DB::getInstance(); - - // 다운받은 모듈과 설치된 모듈의 목록을 구함 - $searched_list = FileHandler::readDir('./modules'); - sort($searched_list); - - $searched_count = count($searched_list); - if(!$searched_count) return; - - for($i=0;$i<$searched_count;$i++) { - // 모듈의 이름 - $module_name = $searched_list[$i]; - - $path = ModuleHandler::getModulePath($module_name); - - // schemas내의 테이블 생성 xml파일수를 구함 - $tmp_files = FileHandler::readDir($path."schemas", '/(\.xml)$/'); - $table_count = count($tmp_files); - - // 테이블이 설치되어 있는지 체크 - $created_table_count = 0; - for($j=0;$jisTableExists($table_name)) $created_table_count ++; - } - - // 해당 모듈의 정보를 구함 - $info = $this->getModuleInfoXml($module_name); - unset($obj); - - $info->module = $module_name; - $info->category = $info->category; - $info->created_table_count = $created_table_count; - $info->table_count = $table_count; - $info->path = $path; - $info->admin_index_act = $info->admin_index_act; - - // 설치 유무 체크 (설치는 DB의 설치만 관리) - if($table_count > $created_table_count) $info->need_install = true; - else $info->need_install = false; - - // 각 모듈의 module.class.php로 upgrade 유무 체크 - $oDummy = null; - $oDummy = &getModule($module_name, 'class'); - if($oDummy && method_exists($oDummy, "checkUpdate")) { - $info->need_update = $oDummy->checkUpdate(); - } - else - { - continue; - } - - $list[] = $info; - } - return $list; - } - - /** - * @brief 특정 module srls를 sites의 domain과 결합 - * 아직 XE DBHandler에서 left outer join이 안되어서.. - * $output->data[]->module_srl 과 같은 구조여야 함 - **/ - function syncModuleToSite(&$data) { - if(!$data) return; - - if(is_array($data)) { - foreach($data as $key => $val) { - $module_srls[] = $val->module_srl; - } - if(!count($module_srls)) return; - } else { - $module_srls[] = $data->module_srl; - } - - $args->module_srls = implode(',',$module_srls); - $output = executeQueryArray('module.getModuleSites', $args); - if(!$output->data) return array(); - foreach($output->data as $key => $val) { - $modules[$val->module_srl] = $val; - } - - if(is_array($data)) { - foreach($data as $key => $val) { - $data[$key]->domain = $modules[$val->module_srl]->domain; - } - } else { - $data->domain = $modules[$data->module_srl]->domain; - } - } - - /** - * @brief site_module_info의 관리자 인지 체크 - **/ - function isSiteAdmin($member_info, $site_srl = null) { - if(!$member_info->member_srl) return false; - if($member_info->is_admin == 'Y') return true; - - if(!isset($site_srl)) - { - $site_module_info = Context::get('site_module_info'); - if(!$site_module_info) return; - $args->site_srl = $site_module_info->site_srl; - } - else - { - $args->site_srl = $site_srl; - } - - $args->member_srl = $member_info->member_srl; - $output = executeQuery('module.isSiteAdmin', $args); - if($output->data->member_srl == $args->member_srl) return true; - return false; - - } - - /** - * @brief site의 관리자 정보를 구함 - **/ - function getSiteAdmin($site_srl) { - $args->site_srl = $site_srl; - $output = executeQueryArray('module.getSiteAdmin', $args); - return $output->data; - } - - /** - * @brief 특정 모듈의 관리자 아이디 구함 - **/ - function getAdminId($module_srl) { - $obj->module_srl = $module_srl; - $output = executeQueryArray('module.getAdminID', $obj); - if(!$output->toBool() || !$output->data) return; - - return $output->data; - } - - /** - * @brief 특정 모듈의 추가 변수를 구함 - * modules 테이블의 기본 정보 이외의 것 - **/ - function getModuleExtraVars($module_srl) { - if(is_array($module_srl)) $module_srl = implode(',',$module_srl); - $args->module_srl = $module_srl; - $output = executeQueryArray('module.getModuleExtraVars',$args); - if(!$output->toBool() || !$output->data) return; - - $vars = array(); - foreach($output->data as $key => $val) { - if(in_array($val->name, array('mid','module')) || $val->value == 'Array') continue; - $vars[$val->module_srl]->{$val->name} = $val->value; - } - return $vars; - } - - /** - * @brief 특정 모듈의 스킨 정보를 구함 - **/ - function getModuleSkinVars($module_srl) { - $args->module_srl = $module_srl; - $output = executeQueryArray('module.getModuleSkinVars',$args); - if(!$output->toBool() || !$output->data) return; - - $skin_vars = array(); - foreach($output->data as $val) $skin_vars[$val->name] = $val; - return $skin_vars; - } - - /** - * @brief 특정 모듈의 스킨 정보를 모듈 정보와 결합 - **/ - function syncSkinInfoToModuleInfo(&$module_info) { - if(!$module_info->module_srl) return; - - $args->module_srl = $module_info->module_srl; - $output = executeQueryArray('module.getModuleSkinVars',$args); - if(!$output->toBool() || !$output->data) return; - - foreach($output->data as $val) { - if(isset($module_info->{$val->name})) continue; - $module_info->{$val->name} = $val->value; - } - } - - /** - * @brief 특정 모듈정보와 XML, 그리고 회원 정보로 권한을 return - **/ - function getGrant($module_info, $member_info, $xml_info = '') { - if(!$xml_info) { - $module = $module_info->module; - $xml_info = $this->getModuleActionXml($module); - } - // 그룹 권한 설정에 필요한 변수를 세팅 - $module_srl = $module_info->module_srl; - $grant_info = $xml_info->grant; - if($member_info->member_srl) { - if(is_array($member_info->group_list)) $group_list = array_keys($member_info->group_list); - else $group_list = array(); - } else { - $group_list = array(); - } - - // module_srl이 없는 즉 별도의 권한 설정이 안되는 경우 - if(!$module_srl) { - $grant->access = true; - if($this->isSiteAdmin($member_info)) $grant->access = $grant->is_admin = $grant->manager = true; - else $grant->is_admin = $grant->manager = $member_info->is_admin=='Y'?true:false; - - // module_srl이 있는 경우 - } else { - - // grant 종류를 구함 - $grant->access = $grant->is_admin = $grant->manager = ($member_info->is_admin=='Y'||$this->isSiteAdmin($member_info))?true:false; - - // 관리자가 아니라 로그인 회원일 경우 이 모듈의 관리자인지 확인 - if(!$grant->manager && $member_info->member_srl) { - $args->module_srl = $module_srl; - $args->member_srl = $member_info->member_srl; - $output = executeQuery('module.getModuleAdmin',$args); - if($output->data && $output->data->member_srl == $member_info->member_srl) $grant->manager = $grant->is_admin = true; - } - - // 관리자가 아니면 직접 DB에서 정보를 구해서 권한 설정 - if(!$grant->manager) { - $args = null; - - // 플래닛인 경우 planet home의 권한 설정을 가져온다 - if ($module_info->module == 'planet') { - $output = executeQueryArray('module.getPlanetGrants', $args); - } - else { - $args->module_srl = $module_srl; - $output = executeQueryArray('module.getModuleGrants', $args); - } - - $grant_exists = $granted = array(); - - if($output->data) { - // 1차적으로 권한 대상 이름과 그룹을 정리 - foreach($output->data as $val) { - $grant_exists[$val->name] = true; - if($granted[$val->name]) continue; - - // 로그인 회원만 - if($val->group_srl == -1) { - $granted[$val->name] = true; - if($member_info->member_srl) $grant->{$val->name} = true; - - // 사이트 가입한 회원만 - } elseif($val->group_srl == -2) { - $granted[$val->name] = true; - // 비로그인 회원이면 권한 미부여 - if(!$member_info->member_srl) $grant->{$val->name} = false; - // 로그인 회원 - else { - $site_module_info = Context::get('site_module_info'); - // 현재 접속된 사이트 정보가 없으면 권한 부여 - if(!$site_module_info->site_srl) $grant->{$val->name} = true; - // 현재 접속된 사이트의 그룹 정보가 있 으면 권한 미부여 - elseif(count($group_list)) $grant->{$val->name} = true; - } - - // 비로그인 회원 모두 - } elseif($val->group_srl == 0) { - $granted[$val->name] = true; - $grant->{$val->name} = true; - // 특정 그룹 대상일 경우 - } else { - if($group_list && count($group_list) && in_array($val->group_srl, $group_list)) { - $grant->{$val->name} = true; - $granted[$val->name] = true; - } - } - } - } - - // 가상 그룹인 access에 대해서 별도 처리 - if(!$grant_exists['access']) $grant->access = true; - if(count($grant_info)) { - foreach($grant_info as $grant_name => $grant_item) { - if($grant_exists[$grant_name]) continue; - switch($grant_item->default) { - case 'guest' : - $grant->{$grant_name} = true; - break; - case 'member' : - if($member_info->member_srl) $grant->{$grant_name} = true; - else $grant->{$grant_name} = false; - break; - case 'site' : - $site_module_info = Context::get('site_module_info'); - if($member_info->member_srl && (($site_module_info->site_srl && count($group_list)) || !$site_module_info->site_srl)) $grant->{$grant_name} = true; - else $grant->{$grant_name} = false; - break; - case 'manager' : - case 'root' : - if($member_info->is_admin == 'Y') $grant->{$grant_name} = true; - else $grant->{$grant_name} = false; - break; - } - } - } - } - - // 관리자일 경우 모든 권한에 대해 true 지정 - if($grant->manager) { - $grant->access = true; - if(count($grant_info)) { - foreach($grant_info as $key => $val) { - $grant->{$key} = true; - } - } - } - - } - return $grant; - } - - - - function getModuleFileBox($module_filebox_srl){ - $args->module_filebox_srl = $module_filebox_srl; - return executeQuery('module.getModuleFileBox', $args); - } - - function getModuleFileBoxList(){ - $args->page = Context::get('page'); - $args->list_count = 10; - $args->page_count = 10; - return executeQuery('module.getModuleFileBoxList', $args); - } - - function getModuleFileBoxPath($module_filebox_srl){ - return sprintf("./files/attach/filebox/%s",getNumberingPath($module_filebox_srl,3)); - } - } -?> +mid = $id; + $args->site_srl = $site_srl; + $output = executeQuery('module.isExistsModuleName', $args); + if($output->data->count) return true; + + // vid 검사 (site_srl이 0일때 즉 가상사이트가 아닌 경우 mid != vid임을 체크) + if(!$site_srl) { + $site_args->domain = $id; + $output = executeQuery('module.isExistsSiteDomain', $site_args); + if($output->data->count) return true; + } + + return false; + } + + /** + * @brief site 정보를 구함 + **/ + function getSiteInfo($site_srl) { + $args->site_srl = $site_srl; + $output = executeQuery('module.getSiteInfo', $args); + return $output->data; + } + + function getSiteInfoByDomain($domain) { + $args->domain= $domain; + $output = executeQuery('module.getSiteInfoByDomain', $args); + return $output->data; + } + + /** + * @brief document_srl로 모듈의 정보르 구함 + * 이 경우는 캐시파일을 이용할 수가 없음 + **/ + function getModuleInfoByDocumentSrl($document_srl) { + $args->document_srl = $document_srl; + $output = executeQuery('module.getModuleInfoByDocument', $args); + return $this->addModuleExtraVars($output->data); + } + + /** + * @brief domain에 따른 기본 mid를 구함 + **/ + function getDefaultMid() { + $default_url = preg_replace('/\/$/','',Context::getDefaultUrl()); + $request_url = preg_replace('/\/$/','',Context::getRequestUri()); + $vid = Context::get('vid'); + $mid = Context::get('mid'); + + // 기본 URL이 설정되어 있고 이 기본 URL과 요청 URL이 다르면 가상 사이트 확인 + if($default_url && $default_url != $request_url) { + $url_info = parse_url($request_url); + $hostname = $url_info['host']; + $path = preg_replace('/\/$/','',$url_info['path']); + $sites_args->domain = sprintf('%s%s%s', $hostname, $url_info['port']&&$url_info['port']!=80?':'.$url_info['port']:'',$path); + $output = executeQuery('module.getSiteInfoByDomain', $sites_args); + } + if(!$output || !$output->data) + { + if(!$vid) $vid = $mid; + if($vid) { + $vid_args->domain = $vid; + $output = executeQuery('module.getSiteInfoByDomain', $vid_args); + if($output->toBool() && $output->data) { + Context::set('vid', $output->data->domain, true); + if($mid==$output->data->domain) Context::set('mid',$output->data->mid,true); + } + } + } + + // 가상 사이트가 아닐 경우 기본 사이트 정보를 구함 + if(!$output->data) { + $args->site_srl = 0; + $output = executeQuery('module.getSiteInfo', $args); + + // 기본 사이트 정보가 없으면 관련된 정보를 갱신 + if(!$output->data) { + // sites 테이블이 없을 경우 생성 + $oDB = &DB::getInstance(); + if(!$oDB->isTableExists('sites')) $oDB->createTableByXmlFile(_XE_PATH_.'modules/module/schemas/sites.xml'); + if(!$oDB->isTableExists('sites')) return; + + // 기본 mid, 언어 구함 + $mid_output = $oDB->executeQuery('module.getDefaultMidInfo', $args); + $db_info = Context::getDBInfo(); + $domain = Context::getDefaultUrl(); + $url_info = parse_url($domain); + $domain = $url_info['host'].( (!empty($url_info['port'])&&$url_info['port']!=80)?':'.$url_info['port']:'').$url_info['path']; + $site_args->site_srl = 0; + $site_args->index_module_srl = $mid_output->data->module_srl; + $site_args->domain = $domain; + $site_args->default_language = $db_info->lang_type; + + if($output->data && !$output->data->index_module_srl) { + $output = executeQuery('module.updateSite', $site_args); + } else { + $output = executeQuery('module.insertSite', $site_args); + if(!$output->toBool()) return $output; + } + $output = executeQuery('module.getSiteInfo', $args); + } + } + $module_info = $output->data; + if(!$module_info->module_srl) return $module_info; + if(is_array($module_info) && $module_info->data[0]) $module_info = $module_info[0]; + return $this->addModuleExtraVars($module_info); + } + + /** + * @brief mid로 모듈의 정보를 구함 + **/ + function getModuleInfoByMid($mid, $site_srl = 0) { + $args->mid = $mid; + $args->site_srl = (int)$site_srl; + $output = executeQuery('module.getMidInfo', $args); + $module_info = $output->data; + if(!$module_info->module_srl && $module_info->data[0]) $module_info = $module_info->data[0]; + return $this->addModuleExtraVars($module_info); + } + + /** + * @brief module_srl에 해당하는 모듈의 정보를 구함 + **/ + function getModuleInfoByModuleSrl($module_srl) { + // 데이터를 가져옴 + $args->module_srl = $module_srl; + $output = executeQuery('module.getMidInfo', $args); + if(!$output->data) return; + $module_info = $this->addModuleExtraVars($output->data); + return $module_info; + } + + /** + * @brief layout_srl에 해당하는 모듈의 정보를 구함 + **/ + function getModulesInfoByLayout($layout_srl) { + // 데이터를 가져옴 + $args->layout_srl = $layout_srl; + $output = executeQueryArray('module.getModulesByLayout', $args); + + $count = count($output->data); + + $modules = array(); + for($i=0;$i<$count;$i++) { + $modules[] = $output->data[$i]; + } + return $this->addModuleExtraVars($modules); + } + + /** + * @brief 여러개의 module_srl에 해당하는 모듈의 정보를 구함 + **/ + function getModulesInfo($module_srls) { + if(is_array($module_srls)) $module_srls = implode(',',$module_srls); + $args->module_srls = $module_srls; + $output = executeQueryArray('module.getModulesInfo', $args); + if(!$output->toBool()) return; + return $this->addModuleExtraVars($output->data); + } + + /** + * @brief 모듈의 기본 정보에 추가 변수 구함 + **/ + function addModuleExtraVars($module_info) { + // 1개 이상의 모듈정보를 요청받아도 처리 가능하도록 + if(!is_array($module_info)) $target_module_info = array($module_info); + else $target_module_info = $module_info; + + // 모듈 번호를 구함 + $module_srls = array(); + foreach($target_module_info as $key => $val) { + $module_srl = $val->module_srl; + if(!$module_srl) continue; + $module_srls[] = $val->module_srl; + } + + // 모듈의 추가정보/ 스킨 정보를 추출 + $extra_vars = $this->getModuleExtraVars($module_srls); + if(!count($module_srls) || !count($extra_vars)) return $module_info; + + foreach($target_module_info as $key => $val) { + if(!$extra_vars[$val->module_srl] || !count($extra_vars[$val->module_srl])) continue; + foreach($extra_vars[$val->module_srl] as $k => $v) { + if($target_module_info[$key]->{$k}) continue; + $target_module_info[$key]->{$k} = $v; + } + } + if(is_array($module_info)) return $target_module_info; + return $target_module_info[0]; + } + + /** + * @brief DB에 생성된 mid 전체 목록을 구해옴 + **/ + function getMidList($args = null) { + $output = executeQuery('module.getMidList', $args); + if(!$output->toBool()) return $output; + + $list = $output->data; + if(!$list) return; + + if(!is_array($list)) $list = array($list); + + foreach($list as $val) { + $mid_list[$val->mid] = $val; + } + return $mid_list; + } + + /** + * @brief mid 목록에 대응하는 module_srl을 배열로 return + **/ + function getModuleSrlByMid($mid) { + if($mid && !is_array($mid)) $mid = explode(',',$mid); + if(is_array($mid)) $mid = "'".implode("','",$mid)."'"; + + $site_module_info = Context::get('site_module_info'); + + $args->mid = $mid; + if($site_module_info) $args->site_srl = $site_module_info->site_srl; + $output = executeQuery('module.getModuleSrlByMid', $args); + if(!$output->toBool()) return $output; + + $list = $output->data; + if(!$list) return; + if(!is_array($list)) $list = array($list); + + foreach($list as $key => $val) { + $module_srl_list[] = $val->module_srl; + } + + return $module_srl_list; + } + + /** + * @brief act 값에 의한 forward 값을 구함 + **/ + function getActionForward($act, $module = "") { + $args->act = $act; + $args->module = ($module)?$module:null; + if (strlen ($args->module) > 0) $output = executeQuery ('module.getActionForwardWithModule', $args); + else $output = executeQuery('module.getActionForward',$args); + return $output->data; + } + + /** + * @brief trigger_name에 등록된 모든 목록을 추출 + **/ + function getTriggers($trigger_name, $called_position) { + $args->trigger_name = $trigger_name; + $args->called_position = $called_position; + $output = executeQueryArray('module.getTriggers',$args); + return $output->data; + } + + /** + * @brief 특정 trigger_name의 특정 대상을 추출 + **/ + function getTrigger($trigger_name, $module, $type, $called_method, $called_position) { + $args->trigger_name = $trigger_name; + $args->module = $module; + $args->type = $type; + $args->called_method = $called_method; + $args->called_position = $called_position; + $output = executeQuery('module.getTrigger',$args); + return $output->data; + } + + /** + * @brief 모듈의 conf/info.xml 을 읽어서 정보를 구함 + **/ + function getModuleInfoXml($module) { + // 요청된 모듈의 경로를 구한다. 없으면 return + $module_path = ModuleHandler::getModulePath($module); + if(!$module_path) return; + + // 현재 선택된 모듈의 스킨의 정보 xml 파일을 읽음 + $xml_file = sprintf("%s/conf/info.xml", $module_path); + if(!file_exists($xml_file)) return; + + $oXmlParser = new XmlParser(); + $tmp_xml_obj = $oXmlParser->loadXmlFile($xml_file); + $xml_obj = $tmp_xml_obj->module; + + if(!$xml_obj) return; + + // 모듈 정보 + if($xml_obj->version && $xml_obj->attrs->version == '0.2') { + // module format 0.2 + $module_info->title = $xml_obj->title->body; + $module_info->description = $xml_obj->description->body; + $module_info->version = $xml_obj->version->body; + $module_info->homepage = $xml_obj->link->body; + $module_info->category = $xml_obj->category->body; + if(!$module_info->category) $module_info->category = 'service'; + sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); + $module_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $module_info->license = $xml_obj->license->body; + $module_info->license_link = $xml_obj->license->attrs->link; + + if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; + else $author_list = $xml_obj->author; + + foreach($author_list as $author) { + unset($author_obj); + $author_obj->name = $author->name->body; + $author_obj->email_address = $author->attrs->email_address; + $author_obj->homepage = $author->attrs->link; + $module_info->author[] = $author_obj; + } + + // history + if($xml_obj->history) { + if(!is_array($xml_obj->history)) $history[] = $xml_obj->history; + else $history = $xml_obj->history; + + foreach($history as $item) { + unset($obj); + + if($item->author) { + (!is_array($item->author)) ? $obj->author_list[] = $item->author : $obj->author_list = $item->author; + + foreach($obj->author_list as $author) { + unset($author_obj); + $author_obj->name = $author->name->body; + $author_obj->email_address = $author->attrs->email_address; + $author_obj->homepage = $author->attrs->link; + $obj->author[] = $author_obj; + } + } + + $obj->name = $item->name->body; + $obj->email_address = $item->attrs->email_address; + $obj->homepage = $item->attrs->link; + $obj->version = $item->attrs->version; + $obj->date = $item->attrs->date; + $obj->description = $item->description->body; + + if($item->log) { + (!is_array($item->log)) ? $obj->log[] = $item->log : $obj->log = $item->log; + + foreach($obj->log as $log) { + unset($logs_obj); + $logs_obj->text = $log->body; + $logs_obj->link = $log->attrs->link; + $obj->logs[] = $logs_obj; + } + } + + $module_info->history[] = $obj; + } + } + + + } else { + // module format 0.1 + $module_info->title = $xml_obj->title->body; + $module_info->description = $xml_obj->author->description->body; + $module_info->version = $xml_obj->attrs->version; + $module_info->category = $xml_obj->attrs->category; + if(!$module_info->category) $module_info->category = 'service'; + sscanf($xml_obj->author->attrs->date, '%d. %d. %d', $date_obj->y, $date_obj->m, $date_obj->d); + $module_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $author_obj->name = $xml_obj->author->name->body; + $author_obj->email_address = $xml_obj->author->attrs->email_address; + $author_obj->homepage = $xml_obj->author->attrs->link; + $module_info->author[] = $author_obj; + } + + // action 정보를 얻어서 admin_index를 추가 + $action_info = $this->getModuleActionXml($module); + $module_info->admin_index_act = $action_info->admin_index_act; + $module_info->default_index_act = $action_info->default_index_act; + $module_info->setup_index_act = $action_info->setup_index_act; + + return $module_info; + } + + /** + * @brief module의 conf/module.xml 을 통해 grant(권한) 및 action 데이터를 return + * module.xml 파일의 경우 파싱하는데 시간이 걸리기에 캐싱을 한다... + * 캐싱을 할때 바로 include 할 수 있도록 역시 코드까지 추가하여 캐싱을 한다. + * 이게 퍼포먼스 상으로는 좋은데 어떤 부정적인 결과를 유도할지는 잘 모르겠... + **/ + function getModuleActionXml($module) { + // 요청된 모듈의 경로를 구한다. 없으면 return + $class_path = ModuleHandler::getModulePath($module); + if(!$class_path) return; + + // 해당 경로에 module.xml 파일이 있는지 체크한다. 없으면 return + $xml_file = sprintf("%sconf/module.xml", $class_path); + if(!file_exists($xml_file)) return; + + // 캐시된 파일이 있는지 확인 + $cache_file = sprintf("./files/cache/module_info/%s.%s.php", $module, Context::getLangType()); + + // 캐시 파일이 없거나 캐시 파일이 xml 파일보다 오래되었으면 내용 다시 갱신 + if(!file_exists($cache_file) || filemtime($cache_file)module)) return; ///< xml 내용중에 module 태그가 없다면 오류;; + + $grants = $xml_obj->module->grants->grant; ///< 권한 정보 (없는 경우도 있음) + $permissions = $xml_obj->module->permissions->permission; ///< 권한 대행 (없는 경우도 있음) + $actions = $xml_obj->module->actions->action; ///< action list (필수) + + $default_index = $admin_index = ''; + + // 권한 정보의 정리 + if($grants) { + if(is_array($grants)) $grant_list = $grants; + else $grant_list[] = $grants; + + foreach($grant_list as $grant) { + $name = $grant->attrs->name; + $default = $grant->attrs->default?$grant->attrs->default:'guest'; + $title = $grant->title->body; + + $info->grant->{$name}->title = $title; + $info->grant->{$name}->default = $default; + + $buff .= sprintf('$info->grant->%s->title=\'%s\';', $name, $title); + $buff .= sprintf('$info->grant->%s->default=\'%s\';', $name, $default); + } + } + + // 권한 허용 정리 + if($permissions) { + if(is_array($permissions)) $permission_list = $permissions; + else $permission_list[] = $permissions; + + foreach($permission_list as $permission) { + $action = $permission->attrs->action; + $target = $permission->attrs->target; + + $info->permission->{$action} = $target; + + $buff .= sprintf('$info->permission->%s = \'%s\';', $action, $target); + } + } + + // actions 정리 + if($actions) { + if(is_array($actions)) $action_list = $actions; + else $action_list[] = $actions; + + foreach($action_list as $action) { + $name = $action->attrs->name; + + $type = $action->attrs->type; + $grant = $action->attrs->grant?$action->attrs->grant:'guest'; + $standalone = $action->attrs->standalone=='true'?'true':'false'; + + $index = $action->attrs->index; + $admin_index = $action->attrs->admin_index; + $setup_index = $action->attrs->setup_index; + + $output->action->{$name}->type = $type; + $output->action->{$name}->grant = $grant; + $output->action->{$name}->standalone= $standalone; + + $info->action->{$name}->type = $type; + $info->action->{$name}->grant = $grant; + $info->action->{$name}->standalone = $standalone=='true'?true:false; + + $buff .= sprintf('$info->action->%s->type=\'%s\';', $name, $type); + $buff .= sprintf('$info->action->%s->grant=\'%s\';', $name, $grant); + $buff .= sprintf('$info->action->%s->standalone=%s;', $name, $standalone); + + if($index=='true') { + $default_index_act = $name; + $info->default_index_act = $name; + } + if($admin_index=='true') { + $admin_index_act = $name; + $info->admin_index_act = $name; + } + if($setup_index=='true') { + $setup_index_act = $name; + $info->setup_index_act = $name; + } + } + } + $buff = sprintf('default_index_act = \'%s\';$info->setup_index_act=\'%s\';$info->admin_index_act = \'%s\';%s?>', $default_index_act, $setup_index_act, $admin_index_act, $buff); + + FileHandler::writeFile($cache_file, $buff); + + return $info; + } + + @include($cache_file); + + return $info; + } + + + /** + * @brief 주어진 곳의 스킨 목록을 구함 + * 스킨과 skin.xml 파일을 분석 정리한 결과를 return + **/ + function getSkins($path, $dir = 'skins') { + $skin_path = sprintf("%s/%s/", $path, $dir); + $list = FileHandler::readDir($skin_path); + if(!count($list)) return; + + natcasesort($list); + + foreach($list as $skin_name) { + unset($skin_info); + $skin_info = $this->loadSkinInfo($path, $skin_name, $dir); + if(!$skin_info) $skin_info->title = $skin_name; + + $skin_list[$skin_name] = $skin_info; + } + + return $skin_list; + } + + /** + * @brief 특정 위치의 특정 스킨의 정보를 구해옴 + **/ + function loadSkinInfo($path, $skin, $dir = 'skins') { + + // 모듈의 스킨의 정보 xml 파일을 읽음 + if(substr($path,-1)!='/') $path .= '/'; + $skin_xml_file = sprintf("%s%s/%s/skin.xml", $path, $dir, $skin); + if(!file_exists($skin_xml_file)) return; + + // XmlParser 객체 생성 + $oXmlParser = new XmlParser(); + $_xml_obj = $oXmlParser->loadXmlFile($skin_xml_file); + + // 스킨 정보가 없으면 return + if(!$_xml_obj->skin) return; + $xml_obj = $_xml_obj->skin; + + // 스킨이름 + $skin_info->title = $xml_obj->title->body; + + + // 작성자 정보 + if($xml_obj->version && $xml_obj->attrs->version == '0.2') { + // skin format v0.2 + sscanf($xml_obj->date->body, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); + $skin_info->version = $xml_obj->version->body; + $skin_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $skin_info->homepage = $xml_obj->link->body; + $skin_info->license = $xml_obj->license->body; + $skin_info->license_link = $xml_obj->license->attrs->link; + $skin_info->description = $xml_obj->description->body; + + if(!is_array($xml_obj->author)) $author_list[] = $xml_obj->author; + else $author_list = $xml_obj->author; + + foreach($author_list as $author) { + unset($author_obj); + $author_obj->name = $author->name->body; + $author_obj->email_address = $author->attrs->email_address; + $author_obj->homepage = $author->attrs->link; + $skin_info->author[] = $author_obj; + } + + // 확장변수를 정리 + if($xml_obj->extra_vars) { + $extra_var_groups = $xml_obj->extra_vars->group; + if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; + if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); + + foreach($extra_var_groups as $group) { + $extra_vars = $group->var; + if(!is_array($group->var)) $extra_vars = array($group->var); + + foreach($extra_vars as $key => $val) { + unset($obj); + if(!$val->attrs->type) { $val->attrs->type = 'text'; } + + $obj->group = $group->title->body; + $obj->name = $val->attrs->name; + $obj->title = $val->title->body; + $obj->type = $val->attrs->type; + $obj->description = $val->description->body; + $obj->value = $extra_vals->{$obj->name}; + $obj->default = $val->attrs->default; + if(strpos($obj->value, '|@|') != false) { $obj->value = explode('|@|', $obj->value); } + if($obj->type == 'mid_list' && !is_array($obj->value)) { $obj->value = array($obj->value); } + + // 'select'type에서 option목록을 구한다. + if(is_array($val->options)) { + $option_count = count($val->options); + + for($i = 0; $i < $option_count; $i++) { + $obj->options[$i]->title = $val->options[$i]->title->body; + $obj->options[$i]->value = $val->options[$i]->attrs->value; + } + } else { + $obj->options[0]->title = $val->options->title->body; + $obj->options[0]->value = $val->options->attrs->value; + } + + $skin_info->extra_vars[] = $obj; + } + } + } + + // history + if($xml_obj->history) { + if(!is_array($xml_obj->history)) $history[] = $xml_obj->history; + else $history = $xml_obj->history; + + foreach($history as $item) { + unset($obj); + + if($item->author) { + (!is_array($item->author)) ? $obj->author_list[] = $item->author : $obj->author_list = $item->author; + + foreach($obj->author_list as $author) { + unset($author_obj); + $author_obj->name = $author->name->body; + $author_obj->email_address = $author->attrs->email_address; + $author_obj->homepage = $author->attrs->link; + $obj->author[] = $author_obj; + } + } + + $obj->name = $item->name->body; + $obj->email_address = $item->attrs->email_address; + $obj->homepage = $item->attrs->link; + $obj->version = $item->attrs->version; + $obj->date = $item->attrs->date; + $obj->description = $item->description->body; + + if($item->log) { + (!is_array($item->log)) ? $obj->log[] = $item->log : $obj->log = $item->log; + + foreach($obj->log as $log) { + unset($log_obj); + $log_obj->text = $log->body; + $log_obj->link = $log->attrs->link; + $obj->logs[] = $log_obj; + } + } + + $skin_info->history[] = $obj; + } + } + + + } else { + + // skin format v0.1 + sscanf($xml_obj->maker->attrs->date, '%d-%d-%d', $date_obj->y, $date_obj->m, $date_obj->d); + + $skin_info->version = $xml_obj->version->body; + $skin_info->date = sprintf('%04d%02d%02d', $date_obj->y, $date_obj->m, $date_obj->d); + $skin_info->homepage = $xml_obj->link->body; + $skin_info->license = $xml_obj->license->body; + $skin_info->license_link = $xml_obj->license->attrs->link; + $skin_info->description = $xml_obj->maker->description->body; + + $skin_info->author[0]->name = $xml_obj->maker->name->body; + $skin_info->author[0]->email_address = $xml_obj->maker->attrs->email_address; + $skin_info->author[0]->homepage = $xml_obj->maker->attrs->link; + + // 스킨에서 사용되는 변수들 + $extra_var_groups = $xml_obj->extra_vars->group; + if(!$extra_var_groups) $extra_var_groups = $xml_obj->extra_vars; + if(!is_array($extra_var_groups)) $extra_var_groups = array($extra_var_groups); + + foreach($extra_var_groups as $group){ + $extra_vars = $group->var; + + if($extra_vars) { + + if(!is_array($extra_vars)) $extra_vars = array($extra_vars); + + foreach($extra_vars as $var) { + unset($obj); + unset($options); + + $group = $group->title->body; + $name = $var->attrs->name; + $type = $var->attrs->type; + $title = $var->title->body; + $description = $var->description->body; + + // 'select'type에서 option목록을 구한다. + if(is_array($var->default)) { + $option_count = count($var->default); + + for($i = 0; $i < $option_count; $i++) { + $options[$i]->title = $var->default[$i]->body; + $options[$i]->value = $var->default[$i]->body; + } + } else { + $options[0]->title = $var->default->body; + $options[0]->value = $var->default->body; + } + + $width = $var->attrs->width; + $height = $var->attrs->height; + + unset($obj); + $obj->group = $group; + $obj->title = $title; + $obj->description = $description; + $obj->name = $name; + $obj->type = $type; + $obj->options = $options; + $obj->width = $width; + $obj->height = $height; + $obj->default = $options[0]->value; + + $skin_info->extra_vars[] = $obj; + } + } + } + } + + // colorset + $colorset = $xml_obj->colorset->color; + if($colorset) { + if(!is_array($colorset)) $colorset = array($colorset); + + foreach($colorset as $color) { + $name = $color->attrs->name; + $title = $color->title->body; + $screenshot = $color->attrs->src; + if($screenshot) { + $screenshot = sprintf("%sskins/%s/%s", $path, $skin, $screenshot); + if(!file_exists($screenshot)) $screenshot = ""; + } else $screenshot = ""; + + unset($obj); + $obj->name = $name; + $obj->title = $title; + $obj->screenshot = $screenshot; + $skin_info->colorset[] = $obj; + } + } + + // 메뉴 종류 (레이아웃을 위한 설정) + if($xml_obj->menus->menu) { + $menus = $xml_obj->menus->menu; + if(!is_array($menus)) $menus = array($menus); + + $menu_count = count($menus); + $skin_info->menu_count = $menu_count; + for($i=0;$i<$menu_count;$i++) { + unset($obj); + + $obj->name = $menus[$i]->attrs->name; + if($menus[$i]->attrs->default == "true") $obj->default = true; + $obj->title = $menus[$i]->title->body; + $obj->maxdepth = $menus[$i]->maxdepth->body; + + $skin_info->menu->{$obj->name} = $obj; + } + } + + return $skin_info; + } + + /** + * @brief 특정 가상 사이트에 등록된 특정 모듈의 개수를 return + **/ + function getModuleCount($site_srl, $module = null) { + $args->site_srl = $site_srl; + if(!is_null($module)) $args->module = $module; + $output = executeQuery('module.getModuleCount', $args); + return $output->data->count; + } + + /** + * @brief 특정 모듈의 설정 return + * board, member등 특정 모듈의 global config 관리용 + **/ + function getModuleConfig($module) { + if(!$GLOBALS['__ModuleConfig__'][$module]) { + $args->module = $module; + $output = executeQuery('module.getModuleConfig', $args); + $config = unserialize($output->data->config); + $GLOBALS['__ModuleConfig__'][$module] = $config; + } + return $GLOBALS['__ModuleConfig__'][$module]; + } + + /** + * @brief 특정 mid의 모듈 설정 정보 return + * mid의 모듈 의존적인 설정을 관리 + **/ + function getModulePartConfig($module, $module_srl) { + if(!$GLOBALS['__ModulePartConfig__'][$module][$module_srl]) { + $args->module = $module; + $args->module_srl = $module_srl; + $output = executeQuery('module.getModulePartConfig', $args); + $config = unserialize($output->data->config); + $GLOBALS['__ModulePartConfig__'][$module][$module_srl] = $config; + } + return $GLOBALS['__ModulePartConfig__'][$module][$module_srl]; + } + + /** + * @brief mid별 모듈 설정 정보 전체를 구함 + **/ + function getModulePartConfigs($module, $site_srl = 0) { + $args->module = $module; + if($site_srl) $args->site_srl = $site_srl; + $output = executeQueryArray('module.getModulePartConfigs', $args); + if(!$output->toBool() || !$output->data) return array(); + + foreach($output->data as $key => $val) { + $result[$val->module_srl] = unserialize($val->config); + } + return $result; + } + + + /** + * @brief 모듈 카테고리의 목록을 구함 + **/ + function getModuleCategories() { + // 데이터를 DB에서 가져옴 + $output = executeQuery('module.getModuleCategories'); + if(!$output->toBool()) return $output; + $list = $output->data; + if(!$list) return; + if(!is_array($list)) $list = array($list); + + foreach($list as $val) { + $category_list[$val->module_category_srl] = $val; + } + return $category_list; + } + + /** + * @brief 특정 모듈 카테고리의 내용을 구함 + **/ + function getModuleCategory($module_category_srl) { + // 데이터를 DB에서 가져옴 + $args->module_category_srl = $module_category_srl; + $output = executeQuery('module.getModuleCategory', $args); + if(!$output->toBool()) return $output; + return $output->data; + } + + /** + * @brief 모듈의 xml 정보만 구함 + **/ + function getModulesXmlInfo() { + // 다운받은 모듈과 설치된 모듈의 목록을 구함 + $searched_list = FileHandler::readDir('./modules'); + $searched_count = count($searched_list); + if(!$searched_count) return; + sort($searched_list); + + for($i=0;$i<$searched_count;$i++) { + // 모듈의 이름 + $module_name = $searched_list[$i]; + + $path = ModuleHandler::getModulePath($module_name); + + // 해당 모듈의 정보를 구함 + $info = $this->getModuleInfoXml($module_name); + unset($obj); + + $info->module = $module_name; + $info->created_table_count = $created_table_count; + $info->table_count = $table_count; + $info->path = $path; + $info->admin_index_act = $info->admin_index_act; + $list[] = $info; + } + return $list; + } + + function checkNeedInstall($module_name) + { + $oDB = &DB::getInstance(); + $info = null; + + $moduledir = ModuleHandler::getModulePath($module_name); + if(file_exists(FileHandler::getRealPath($moduledir."schemas"))) + { + $tmp_files = FileHandler::readDir($moduledir."schemas", '/(\.xml)$/'); + $table_count = count($tmp_files); + + // 테이블이 설치되어 있는지 체크 + $created_table_count = 0; + for($j=0;$jisTableExists($table_name)) $created_table_count ++; + } + + // 설치 유무 체크 (설치는 DB의 설치만 관리) + if($table_count > $created_table_count) return true; + else return false; + } + return false; + } + + function checkNeedUpdate($module_name) + { + // 각 모듈의 module.class.php로 upgrade 유무 체크 + $oDummy = &getModule($module_name, 'class'); + if($oDummy && method_exists($oDummy, "checkUpdate")) { + return $oDummy->checkUpdate(); + } + return false; + } + + /** + * @brief 모듈의 종류와 정보를 구함 + **/ + function getModuleList() { + // DB 객체 생성 + $oDB = &DB::getInstance(); + + // 다운받은 모듈과 설치된 모듈의 목록을 구함 + $searched_list = FileHandler::readDir('./modules'); + sort($searched_list); + + $searched_count = count($searched_list); + if(!$searched_count) return; + + for($i=0;$i<$searched_count;$i++) { + // 모듈의 이름 + $module_name = $searched_list[$i]; + + $path = ModuleHandler::getModulePath($module_name); + + // schemas내의 테이블 생성 xml파일수를 구함 + $tmp_files = FileHandler::readDir($path."schemas", '/(\.xml)$/'); + $table_count = count($tmp_files); + + // 테이블이 설치되어 있는지 체크 + $created_table_count = 0; + for($j=0;$jisTableExists($table_name)) $created_table_count ++; + } + + // 해당 모듈의 정보를 구함 + $info = $this->getModuleInfoXml($module_name); + unset($obj); + + $info->module = $module_name; + $info->category = $info->category; + $info->created_table_count = $created_table_count; + $info->table_count = $table_count; + $info->path = $path; + $info->admin_index_act = $info->admin_index_act; + + // 설치 유무 체크 (설치는 DB의 설치만 관리) + if($table_count > $created_table_count) $info->need_install = true; + else $info->need_install = false; + + // 각 모듈의 module.class.php로 upgrade 유무 체크 + $oDummy = null; + $oDummy = &getModule($module_name, 'class'); + if($oDummy && method_exists($oDummy, "checkUpdate")) { + $info->need_update = $oDummy->checkUpdate(); + } + else + { + continue; + } + + $list[] = $info; + } + return $list; + } + + /** + * @brief 특정 module srls를 sites의 domain과 결합 + * 아직 XE DBHandler에서 left outer join이 안되어서.. + * $output->data[]->module_srl 과 같은 구조여야 함 + **/ + function syncModuleToSite(&$data) { + if(!$data) return; + + if(is_array($data)) { + foreach($data as $key => $val) { + $module_srls[] = $val->module_srl; + } + if(!count($module_srls)) return; + } else { + $module_srls[] = $data->module_srl; + } + + $args->module_srls = implode(',',$module_srls); + $output = executeQueryArray('module.getModuleSites', $args); + if(!$output->data) return array(); + foreach($output->data as $key => $val) { + $modules[$val->module_srl] = $val; + } + + if(is_array($data)) { + foreach($data as $key => $val) { + $data[$key]->domain = $modules[$val->module_srl]->domain; + } + } else { + $data->domain = $modules[$data->module_srl]->domain; + } + } + + /** + * @brief site_module_info의 관리자 인지 체크 + **/ + function isSiteAdmin($member_info, $site_srl = null) { + if(!$member_info->member_srl) return false; + if($member_info->is_admin == 'Y') return true; + + if(!isset($site_srl)) + { + $site_module_info = Context::get('site_module_info'); + if(!$site_module_info) return; + $args->site_srl = $site_module_info->site_srl; + } + else + { + $args->site_srl = $site_srl; + } + + $args->member_srl = $member_info->member_srl; + $output = executeQuery('module.isSiteAdmin', $args); + if($output->data->member_srl == $args->member_srl) return true; + return false; + + } + + /** + * @brief site의 관리자 정보를 구함 + **/ + function getSiteAdmin($site_srl) { + $args->site_srl = $site_srl; + $output = executeQueryArray('module.getSiteAdmin', $args); + return $output->data; + } + + /** + * @brief 특정 모듈의 관리자 아이디 구함 + **/ + function getAdminId($module_srl) { + $obj->module_srl = $module_srl; + $output = executeQueryArray('module.getAdminID', $obj); + if(!$output->toBool() || !$output->data) return; + + return $output->data; + } + + /** + * @brief 특정 모듈의 추가 변수를 구함 + * modules 테이블의 기본 정보 이외의 것 + **/ + function getModuleExtraVars($module_srl) { + if(is_array($module_srl)) $module_srl = implode(',',$module_srl); + $args->module_srl = $module_srl; + $output = executeQueryArray('module.getModuleExtraVars',$args); + if(!$output->toBool() || !$output->data) return; + + $vars = array(); + foreach($output->data as $key => $val) { + if(in_array($val->name, array('mid','module')) || $val->value == 'Array') continue; + $vars[$val->module_srl]->{$val->name} = $val->value; + } + return $vars; + } + + /** + * @brief 특정 모듈의 스킨 정보를 구함 + **/ + function getModuleSkinVars($module_srl) { + $args->module_srl = $module_srl; + $output = executeQueryArray('module.getModuleSkinVars',$args); + if(!$output->toBool() || !$output->data) return; + + $skin_vars = array(); + foreach($output->data as $val) $skin_vars[$val->name] = $val; + return $skin_vars; + } + + /** + * @brief 특정 모듈의 스킨 정보를 모듈 정보와 결합 + **/ + function syncSkinInfoToModuleInfo(&$module_info) { + if(!$module_info->module_srl) return; + + $args->module_srl = $module_info->module_srl; + $output = executeQueryArray('module.getModuleSkinVars',$args); + if(!$output->toBool() || !$output->data) return; + + foreach($output->data as $val) { + if(isset($module_info->{$val->name})) continue; + $module_info->{$val->name} = $val->value; + } + } + + /** + * @brief 특정 모듈정보와 XML, 그리고 회원 정보로 권한을 return + **/ + function getGrant($module_info, $member_info, $xml_info = '') { + if(!$xml_info) { + $module = $module_info->module; + $xml_info = $this->getModuleActionXml($module); + } + // 그룹 권한 설정에 필요한 변수를 세팅 + $module_srl = $module_info->module_srl; + $grant_info = $xml_info->grant; + if($member_info->member_srl) { + if(is_array($member_info->group_list)) $group_list = array_keys($member_info->group_list); + else $group_list = array(); + } else { + $group_list = array(); + } + + // module_srl이 없는 즉 별도의 권한 설정이 안되는 경우 + if(!$module_srl) { + $grant->access = true; + if($this->isSiteAdmin($member_info)) $grant->access = $grant->is_admin = $grant->manager = true; + else $grant->is_admin = $grant->manager = $member_info->is_admin=='Y'?true:false; + + // module_srl이 있는 경우 + } else { + + // grant 종류를 구함 + $grant->access = $grant->is_admin = $grant->manager = ($member_info->is_admin=='Y'||$this->isSiteAdmin($member_info))?true:false; + + // 관리자가 아니라 로그인 회원일 경우 이 모듈의 관리자인지 확인 + if(!$grant->manager && $member_info->member_srl) { + $args->module_srl = $module_srl; + $args->member_srl = $member_info->member_srl; + $output = executeQuery('module.getModuleAdmin',$args); + if($output->data && $output->data->member_srl == $member_info->member_srl) $grant->manager = $grant->is_admin = true; + } + + // 관리자가 아니면 직접 DB에서 정보를 구해서 권한 설정 + if(!$grant->manager) { + $args = null; + + // 플래닛인 경우 planet home의 권한 설정을 가져온다 + if ($module_info->module == 'planet') { + $output = executeQueryArray('module.getPlanetGrants', $args); + } + else { + $args->module_srl = $module_srl; + $output = executeQueryArray('module.getModuleGrants', $args); + } + + $grant_exists = $granted = array(); + + if($output->data) { + // 1차적으로 권한 대상 이름과 그룹을 정리 + foreach($output->data as $val) { + $grant_exists[$val->name] = true; + if($granted[$val->name]) continue; + + // 로그인 회원만 + if($val->group_srl == -1) { + $granted[$val->name] = true; + if($member_info->member_srl) $grant->{$val->name} = true; + + // 사이트 가입한 회원만 + } elseif($val->group_srl == -2) { + $granted[$val->name] = true; + // 비로그인 회원이면 권한 미부여 + if(!$member_info->member_srl) $grant->{$val->name} = false; + // 로그인 회원 + else { + $site_module_info = Context::get('site_module_info'); + // 현재 접속된 사이트 정보가 없으면 권한 부여 + if(!$site_module_info->site_srl) $grant->{$val->name} = true; + // 현재 접속된 사이트의 그룹 정보가 있 으면 권한 미부여 + elseif(count($group_list)) $grant->{$val->name} = true; + } + + // 비로그인 회원 모두 + } elseif($val->group_srl == 0) { + $granted[$val->name] = true; + $grant->{$val->name} = true; + // 특정 그룹 대상일 경우 + } else { + if($group_list && count($group_list) && in_array($val->group_srl, $group_list)) { + $grant->{$val->name} = true; + $granted[$val->name] = true; + } + } + } + } + + // 가상 그룹인 access에 대해서 별도 처리 + if(!$grant_exists['access']) $grant->access = true; + if(count($grant_info)) { + foreach($grant_info as $grant_name => $grant_item) { + if($grant_exists[$grant_name]) continue; + switch($grant_item->default) { + case 'guest' : + $grant->{$grant_name} = true; + break; + case 'member' : + if($member_info->member_srl) $grant->{$grant_name} = true; + else $grant->{$grant_name} = false; + break; + case 'site' : + $site_module_info = Context::get('site_module_info'); + if($member_info->member_srl && (($site_module_info->site_srl && count($group_list)) || !$site_module_info->site_srl)) $grant->{$grant_name} = true; + else $grant->{$grant_name} = false; + break; + case 'manager' : + case 'root' : + if($member_info->is_admin == 'Y') $grant->{$grant_name} = true; + else $grant->{$grant_name} = false; + break; + } + } + } + } + + // 관리자일 경우 모든 권한에 대해 true 지정 + if($grant->manager) { + $grant->access = true; + if(count($grant_info)) { + foreach($grant_info as $key => $val) { + $grant->{$key} = true; + } + } + } + + } + return $grant; + } + + + + function getModuleFileBox($module_filebox_srl){ + $args->module_filebox_srl = $module_filebox_srl; + return executeQuery('module.getModuleFileBox', $args); + } + + function getModuleFileBoxList(){ + $args->page = Context::get('page'); + $args->list_count = 10; + $args->page_count = 10; + return executeQuery('module.getModuleFileBoxList', $args); + } + + function getModuleFileBoxPath($module_filebox_srl){ + return sprintf("./files/attach/filebox/%s",getNumberingPath($module_filebox_srl,3)); + } + } +?> diff --git a/modules/module/module.view.php b/modules/module/module.view.php index 10f0bf29e..65ec532ab 100644 --- a/modules/module/module.view.php +++ b/modules/module/module.view.php @@ -1,161 +1,161 @@ -setTemplatePath($this->module_path.'tpl'); - } - - /** - * @brief 스킨 정보 출력 - **/ - function dispModuleSkinInfo() { - $selected_module = Context::get('selected_module'); - $skin = Context::get('skin'); - - // 모듈/스킨 정보를 구함 - $module_path = sprintf("./modules/%s/", $selected_module); - if(!is_dir($module_path)) $this->stop("msg_invalid_request"); - - $skin_info_xml = sprintf("%sskins/%s/skin.xml", $module_path, $skin); - if(!file_exists($skin_info_xml)) $this->stop("msg_invalid_request"); - - $oModuleModel = &getModel('module'); - $skin_info = $oModuleModel->loadSkinInfo($module_path, $skin); - Context::set('skin_info',$skin_info); - - $this->setLayoutFile("popup_layout"); - $this->setTemplateFile("skin_info"); - } - - /** - * @brief 모듈 선택기 - **/ - function dispModuleSelectList() { - if(!Context::get('is_logged')) return new Object(-1, 'msg_not_permitted'); - - $oModuleModel = &getModel('module'); - - // virtual site의 개수를 추출 - $output = executeQuery('module.getSiteCount'); - $site_count = $output->data->count; - Context::set('site_count', $site_count); - - // 사이트 검색어 변수 설정 - $site_keyword = Context::get('site_keyword'); - - // 사이트 검색어가 없으면 현재 가상 사이트의 정보를 설정 - $args = null; - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == 'Y') { - $query_id = 'module.getSiteModules'; - $module_category_exists = false; - if(!$site_keyword) { - $site_module_info = Context::get('site_module_info'); - if($site_module_info && $logged_info->is_admin != 'Y') { - $site_keyword = $site_module_info->domain; - $args->site_srl = (int)$site_module_info->site_srl; - Context::set('site_keyword', $site_keyword); - } else { - $query_id = 'module.getDefaultModules'; - $args->site_srl = 0; - $module_category_exists = true; - } - // 사이트 검색어가 있으면 해당 사이트(들)의 정보를 추출 - } else { - $args->site_keyword = $site_keyword; - } - } else { - $query_id = 'module.getSiteModules'; - $site_module_info = Context::get('site_module_info'); - $args->site_srl = (int)$site_module_info->site_srl; - } - //if(is_null($args->site_srl)) $query_id = 'module.getDefaultModules'; - - // 지정된 사이트(혹은 전체)의 module 목록을 구함 - $output = executeQueryArray($query_id, $args); - $category_list = $mid_list = array(); - if(count($output->data)) { - foreach($output->data as $key => $val) { - $module = trim($val->module); - if(!$module) continue; - - $category = $val->category; - $obj = null; - $obj->module_srl = $val->module_srl; - $obj->browser_title = $val->browser_title; - $mid_list[$module]->list[$category][$val->mid] = $obj; - } - } - - $selected_module = Context::get('selected_module'); - if(count($mid_list)) { - foreach($mid_list as $module => $val) { - if(!$selected_module) $selected_module = $module; - $xml_info = $oModuleModel->getModuleInfoXml($module); - $mid_list[$module]->title = $xml_info->title; - } - } - - Context::set('mid_list', $mid_list); - Context::set('selected_module', $selected_module); - Context::set('selected_mids', $mid_list[$selected_module]->list); - Context::set('module_category_exists', $module_category_exists); - - // 레이아웃을 팝업으로 지정 - $this->setLayoutFile('popup_layout'); - - // 템플릿 파일 지정 - $this->setTemplateFile('module_selector'); - } - - - // 파일 박스 보기 - function dispModuleFileBox(){ - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); - - $input_name = Context::get('input'); - - if(!$input_name) return new Object(-1, 'msg_not_permitted'); - - - $addscript = sprintf('',$input_name); - Context::addHtmlHeader($addscript); - - $oModuleModel = &getModel('module'); - $output = $oModuleModel->getModuleFileBoxList(); - Context::set('filebox_list', $output->data); - - $filter = Context::get('filter'); - if($filter) Context::set('arrfilter',explode(',',$filter)); - - Context::set('page_navigation', $output->page_navigation); - $this->setLayoutFile('popup_layout'); - $this->setTemplateFile('filebox_list'); - } - - // 파일 박스 등록화면 - function dispModuleFileBoxAdd(){ - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); - - $filter = Context::get('filter'); - if($filter) Context::set('arrfilter',explode(',',$filter)); - - $this->setLayoutFile('popup_layout'); - $this->setTemplateFile('filebox_add'); - } - } -?> +setTemplatePath($this->module_path.'tpl'); + } + + /** + * @brief 스킨 정보 출력 + **/ + function dispModuleSkinInfo() { + $selected_module = Context::get('selected_module'); + $skin = Context::get('skin'); + + // 모듈/스킨 정보를 구함 + $module_path = sprintf("./modules/%s/", $selected_module); + if(!is_dir($module_path)) $this->stop("msg_invalid_request"); + + $skin_info_xml = sprintf("%sskins/%s/skin.xml", $module_path, $skin); + if(!file_exists($skin_info_xml)) $this->stop("msg_invalid_request"); + + $oModuleModel = &getModel('module'); + $skin_info = $oModuleModel->loadSkinInfo($module_path, $skin); + Context::set('skin_info',$skin_info); + + $this->setLayoutFile("popup_layout"); + $this->setTemplateFile("skin_info"); + } + + /** + * @brief 모듈 선택기 + **/ + function dispModuleSelectList() { + if(!Context::get('is_logged')) return new Object(-1, 'msg_not_permitted'); + + $oModuleModel = &getModel('module'); + + // virtual site의 개수를 추출 + $output = executeQuery('module.getSiteCount'); + $site_count = $output->data->count; + Context::set('site_count', $site_count); + + // 사이트 검색어 변수 설정 + $site_keyword = Context::get('site_keyword'); + + // 사이트 검색어가 없으면 현재 가상 사이트의 정보를 설정 + $args = null; + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin == 'Y') { + $query_id = 'module.getSiteModules'; + $module_category_exists = false; + if(!$site_keyword) { + $site_module_info = Context::get('site_module_info'); + if($site_module_info && $logged_info->is_admin != 'Y') { + $site_keyword = $site_module_info->domain; + $args->site_srl = (int)$site_module_info->site_srl; + Context::set('site_keyword', $site_keyword); + } else { + $query_id = 'module.getDefaultModules'; + $args->site_srl = 0; + $module_category_exists = true; + } + // 사이트 검색어가 있으면 해당 사이트(들)의 정보를 추출 + } else { + $args->site_keyword = $site_keyword; + } + } else { + $query_id = 'module.getSiteModules'; + $site_module_info = Context::get('site_module_info'); + $args->site_srl = (int)$site_module_info->site_srl; + } + //if(is_null($args->site_srl)) $query_id = 'module.getDefaultModules'; + + // 지정된 사이트(혹은 전체)의 module 목록을 구함 + $output = executeQueryArray($query_id, $args); + $category_list = $mid_list = array(); + if(count($output->data)) { + foreach($output->data as $key => $val) { + $module = trim($val->module); + if(!$module) continue; + + $category = $val->category; + $obj = null; + $obj->module_srl = $val->module_srl; + $obj->browser_title = $val->browser_title; + $mid_list[$module]->list[$category][$val->mid] = $obj; + } + } + + $selected_module = Context::get('selected_module'); + if(count($mid_list)) { + foreach($mid_list as $module => $val) { + if(!$selected_module) $selected_module = $module; + $xml_info = $oModuleModel->getModuleInfoXml($module); + $mid_list[$module]->title = $xml_info->title; + } + } + + Context::set('mid_list', $mid_list); + Context::set('selected_module', $selected_module); + Context::set('selected_mids', $mid_list[$selected_module]->list); + Context::set('module_category_exists', $module_category_exists); + + // 레이아웃을 팝업으로 지정 + $this->setLayoutFile('popup_layout'); + + // 템플릿 파일 지정 + $this->setTemplateFile('module_selector'); + } + + + // 파일 박스 보기 + function dispModuleFileBox(){ + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); + + $input_name = Context::get('input'); + + if(!$input_name) return new Object(-1, 'msg_not_permitted'); + + + $addscript = sprintf('',$input_name); + Context::addHtmlHeader($addscript); + + $oModuleModel = &getModel('module'); + $output = $oModuleModel->getModuleFileBoxList(); + Context::set('filebox_list', $output->data); + + $filter = Context::get('filter'); + if($filter) Context::set('arrfilter',explode(',',$filter)); + + Context::set('page_navigation', $output->page_navigation); + $this->setLayoutFile('popup_layout'); + $this->setTemplateFile('filebox_list'); + } + + // 파일 박스 등록화면 + function dispModuleFileBoxAdd(){ + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin !='Y' && !$logged_info->is_site_admin) return new Object(-1, 'msg_not_permitted'); + + $filter = Context::get('filter'); + if($filter) Context::set('arrfilter',explode(',',$filter)); + + $this->setLayoutFile('popup_layout'); + $this->setTemplateFile('filebox_add'); + } + } +?> diff --git a/modules/module/tpl/js/module_admin.js b/modules/module/tpl/js/module_admin.js index e4aa237df..944082d76 100644 --- a/modules/module/tpl/js/module_admin.js +++ b/modules/module/tpl/js/module_admin.js @@ -1,190 +1,190 @@ -/** - * @file modules/module/js/module_admin.js - * @author zero (zero@nzeo.com) - * @brief module 모듈의 관리자용 javascript - **/ - -/* 카테고리 관련 작업들 */ -function doUpdateCategory(module_category_srl, mode, message) { - if(typeof(message)!='undefined'&&!confirm(message)) return; - - var fo_obj = xGetElementById('fo_category_info'); - fo_obj.module_category_srl.value = module_category_srl; - fo_obj.mode.value = mode; - - procFilter(fo_obj, update_category); -} - -/* 카테고리 정보 수정 후 */ -function completeUpdateCategory(ret_obj) { - var error = ret_obj['error']; - var message = ret_obj['message']; - - alert(message); - - location.href = current_url.setQuery('module_category_srl',''); -} - -/* 선택된 모듈을 관리자 메뉴의 바로가기에 등록 */ -function doAddShortCut(module) { - var fo_obj = xGetElementById("fo_shortcut"); - fo_obj.selected_module.value = module; - procFilter(fo_obj, insert_shortcut); -} - -/* 모듈 설치 */ -function doInstallModule(module) { - var params = new Array(); - params['module_name'] = module; - exec_xml('install','procInstallAdminInstall',params, completeInstallModule); -} - -function completeInstallModule(ret_obj) { - alert(ret_obj['message']); - location.reload(); -} - -/* 모듈 업그레이드 */ -function doUpdateModule(module) { - var params = new Array(); - params['module_name'] = module; - exec_xml('install','procInstallAdminUpdate',params, completeInstallModule); -} - -/* 모듈 복사후 */ -function completeCopyModule() { - if(typeof(opener)!='undefined') opener.location.href = opener.location.href; - window.close(); -} - -/* 모듈 선택기에서 선택된 모듈의 입력 */ -function insertModule(id, module_srl, mid, browser_title, multi_select) { - if(typeof(multi_select)=='undefined') multi_select = true; - if(!window.opener) window.close(); - - if(multi_select) { - if(typeof(opener.insertSelectedModules)=='undefined') return; - opener.insertSelectedModules(id, module_srl, mid, browser_title); - } else { - if(typeof(opener.insertSelectedModule)=='undefined') return; - opener.insertSelectedModule(id, module_srl, mid, browser_title); - window.close(); - } -} - -/* 권한 선택용 */ -function doShowGrantZone() { - jQuery(".grant_default").each( function() { - var id = "#zone_"+this.name.replace(/_default$/,''); - if(!jQuery(this).val()) jQuery(id).css("display","block"); - else jQuery(id).css("display","none"); - } ); -} - -/* 권한 등록 후 알림 메세지 */ -function completeInsertGrant(ret_obj) { - alert(ret_obj['message']); - location.reload(); -} - -/* 관리자 아이디 등록/ 제거 */ -function doInsertAdmin() { - var fo_obj = xGetElementById("fo_obj"); - var sel_obj = fo_obj._admin_member; - var admin_id = fo_obj.admin_id.value; - if(!admin_id) return; - - var opt = new Option(admin_id,admin_id,true,true); - sel_obj.options[sel_obj.options.length] = opt; - - fo_obj.admin_id.value = ''; - sel_obj.size = sel_obj.options.length; - sel_obj.selectedIndex = -1; - - var members = new Array(); - for(var i=0;i/.test(value)) { - var param = new Array(); - param['name'] = value.replace(/^\$user_lang->/,''); - var response_tags = new Array('error','message','name','langs'); - exec_xml('module','getModuleAdminLangCode',param,completeFillLangName, response_tags); - } - } -} - -function completeFillLangName(ret_obj, response_tags) { - var name = ret_obj['name']; - var langs = ret_obj['langs']; - if(typeof(langs)=='undefined') return; - var $form = jQuery("#menu_fo"); - $form[0].lang_code.value = name; - for(var i in langs) { - $form[0][i].value = langs[i]; - } - -} +/** + * @file modules/module/js/module_admin.js + * @author NHN (developers@xpressengine.com) + * @brief module 모듈의 관리자용 javascript + **/ + +/* 카테고리 관련 작업들 */ +function doUpdateCategory(module_category_srl, mode, message) { + if(typeof(message)!='undefined'&&!confirm(message)) return; + + var fo_obj = xGetElementById('fo_category_info'); + fo_obj.module_category_srl.value = module_category_srl; + fo_obj.mode.value = mode; + + procFilter(fo_obj, update_category); +} + +/* 카테고리 정보 수정 후 */ +function completeUpdateCategory(ret_obj) { + var error = ret_obj['error']; + var message = ret_obj['message']; + + alert(message); + + location.href = current_url.setQuery('module_category_srl',''); +} + +/* 선택된 모듈을 관리자 메뉴의 바로가기에 등록 */ +function doAddShortCut(module) { + var fo_obj = xGetElementById("fo_shortcut"); + fo_obj.selected_module.value = module; + procFilter(fo_obj, insert_shortcut); +} + +/* 모듈 설치 */ +function doInstallModule(module) { + var params = new Array(); + params['module_name'] = module; + exec_xml('install','procInstallAdminInstall',params, completeInstallModule); +} + +function completeInstallModule(ret_obj) { + alert(ret_obj['message']); + location.reload(); +} + +/* 모듈 업그레이드 */ +function doUpdateModule(module) { + var params = new Array(); + params['module_name'] = module; + exec_xml('install','procInstallAdminUpdate',params, completeInstallModule); +} + +/* 모듈 복사후 */ +function completeCopyModule() { + if(typeof(opener)!='undefined') opener.location.href = opener.location.href; + window.close(); +} + +/* 모듈 선택기에서 선택된 모듈의 입력 */ +function insertModule(id, module_srl, mid, browser_title, multi_select) { + if(typeof(multi_select)=='undefined') multi_select = true; + if(!window.opener) window.close(); + + if(multi_select) { + if(typeof(opener.insertSelectedModules)=='undefined') return; + opener.insertSelectedModules(id, module_srl, mid, browser_title); + } else { + if(typeof(opener.insertSelectedModule)=='undefined') return; + opener.insertSelectedModule(id, module_srl, mid, browser_title); + window.close(); + } +} + +/* 권한 선택용 */ +function doShowGrantZone() { + jQuery(".grant_default").each( function() { + var id = "#zone_"+this.name.replace(/_default$/,''); + if(!jQuery(this).val()) jQuery(id).css("display","block"); + else jQuery(id).css("display","none"); + } ); +} + +/* 권한 등록 후 알림 메세지 */ +function completeInsertGrant(ret_obj) { + alert(ret_obj['message']); + location.reload(); +} + +/* 관리자 아이디 등록/ 제거 */ +function doInsertAdmin() { + var fo_obj = xGetElementById("fo_obj"); + var sel_obj = fo_obj._admin_member; + var admin_id = fo_obj.admin_id.value; + if(!admin_id) return; + + var opt = new Option(admin_id,admin_id,true,true); + sel_obj.options[sel_obj.options.length] = opt; + + fo_obj.admin_id.value = ''; + sel_obj.size = sel_obj.options.length; + sel_obj.selectedIndex = -1; + + var members = new Array(); + for(var i=0;i/.test(value)) { + var param = new Array(); + param['name'] = value.replace(/^\$user_lang->/,''); + var response_tags = new Array('error','message','name','langs'); + exec_xml('module','getModuleAdminLangCode',param,completeFillLangName, response_tags); + } + } +} + +function completeFillLangName(ret_obj, response_tags) { + var name = ret_obj['name']; + var langs = ret_obj['langs']; + if(typeof(langs)=='undefined') return; + var $form = jQuery("#menu_fo"); + $form[0].lang_code.value = name; + for(var i in langs) { + $form[0][i].value = langs[i]; + } + +} diff --git a/modules/opage/conf/info.xml b/modules/opage/conf/info.xml index 70a91fd11..8f6a7e731 100644 --- a/modules/opage/conf/info.xml +++ b/modules/opage/conf/info.xml @@ -1,34 +1,34 @@ - - - 외부 페이지 - 外部页面 - 外部ページ - External Page - Trang ngoài - Afuera Página - Внешние страницы - 外部頁面 - 외부페이지를 XE내부로 삽입시키는 모듈 - 可以把外部页面插入到 Zeroboard XE内部的模块。 - 外部ページをXE内部に挿入させるモジュール - Module for inserting external pages into inside of Zeroboard XE. - Module cho phépchèn một trang từ bên ngoài vào bên trong Zeroboard XE. - 외부페이지를 XE내부로 삽입시키는 모듈 - Модуль для вставки внешних страниц внутрь Zeroboard XE. - 可將外部頁面插入至XE裡面的模組。 - 0.1 - 2007-09-17 - service - http://www.zeroboard.com - - - zero - zero - zero - zero - zero - zero - zero - zero - - + + + 외부 페이지 + 外部页面 + 外部ページ + External Page + Trang ngoài + Afuera Página + Внешние страницы + 外部頁面 + 외부페이지를 XE내부로 삽입시키는 모듈 + 可以把外部页面插入到 Zeroboard XE内部的模块。 + 外部ページをXE内部に挿入させるモジュール + Module for inserting external pages into inside of Zeroboard XE. + Module cho phépchèn một trang từ bên ngoài vào bên trong Zeroboard XE. + 외부페이지를 XE내부로 삽입시키는 모듈 + Модуль для вставки внешних страниц внутрь Zeroboard XE. + 可將外部頁面插入至XE裡面的模組。 + 0.1 + 2007-09-17 + service + http://xpressengine.com/ + + + NHN + NHN + NHN + NHN + NHN + NHN + NHN + NHN + + diff --git a/modules/opage/lang/en.lang.php b/modules/opage/lang/en.lang.php index 38f220996..27141ef49 100644 --- a/modules/opage/lang/en.lang.php +++ b/modules/opage/lang/en.lang.php @@ -1,18 +1,18 @@ -opage = "External Page"; - $lang->opage_path = "Location of External Document"; - $lang->opage_caching_interval = "Caching Time"; - - $lang->about_opage = "This module enables usage of external html or php files in XE.
It allows absolute or relative path, and if the url starts with 'http://' , it can display the external page of the server."; - $lang->about_opage_path= "Please input the location of external document.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; - $lang->about_opage_caching_interval = "The unit is minute, and it displays temporary saved data for assigned time.
It is recommended to cache for proper time if a lot of resources are needed when displaying other servers' data or information.
A value of 0 will not cache."; - - $lang->opage_mobile_path = 'Location of External Document for Mobile View'; - $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; -?> +opage = "External Page"; + $lang->opage_path = "Location of External Document"; + $lang->opage_caching_interval = "Caching Time"; + + $lang->about_opage = "This module enables usage of external html or php files in XE.
It allows absolute or relative path, and if the url starts with 'http://' , it can display the external page of the server."; + $lang->about_opage_path= "Please input the location of external document.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; + $lang->about_opage_caching_interval = "The unit is minute, and it displays temporary saved data for assigned time.
It is recommended to cache for proper time if a lot of resources are needed when displaying other servers' data or information.
A value of 0 will not cache."; + + $lang->opage_mobile_path = 'Location of External Document for Mobile View'; + $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; +?> diff --git a/modules/opage/lang/es.lang.php b/modules/opage/lang/es.lang.php index 9e2798103..27cb800f9 100644 --- a/modules/opage/lang/es.lang.php +++ b/modules/opage/lang/es.lang.php @@ -1,17 +1,17 @@ -opage = "Page Exteriores"; - $lang->opage_path = "Ubicacion del documento externo"; - $lang->opage_caching_interval = "Establezca el tiempo de cache"; - - $lang->about_opage = 'Este modulo permite el uso externo de archivos html o php en XE.
Permite ruta absoluta o relativa, y si la URL comienza con "http://", se puede mostrar la pagina externa del servidor.'; - $lang->about_opage_path= "Por favor ingrese la ubicacion del documento externos.
Ambos ruta absoluta como '/ path1/path2/sample.php' o ruta relativa como \"../path2/sample.php\" puede ser utilizado.
Si la via de entrada, como \"http://url/sample.php\", el resultado sera recibido y, a continuacion se muestran.
Esta es la actual XE ruta absoluta.
"; - $lang->about_opage_caching_interval = "La unidad es minuto, y se muestra temporal de los datos guardados por el tiempo asignado.
Se recomienda a la cache para una buena vez si una gran cantidad de recursos se necesitan otros servidores cuando se muestran los datos o la informacion.
Un valor de 0 no cache."; - $lang->opage_mobile_path = 'Location of External Document for Mobile View'; - $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; -?> +opage = "Page Exteriores"; + $lang->opage_path = "Ubicacion del documento externo"; + $lang->opage_caching_interval = "Establezca el tiempo de cache"; + + $lang->about_opage = 'Este modulo permite el uso externo de archivos html o php en XE.
Permite ruta absoluta o relativa, y si la URL comienza con "http://", se puede mostrar la pagina externa del servidor.'; + $lang->about_opage_path= "Por favor ingrese la ubicacion del documento externos.
Ambos ruta absoluta como '/ path1/path2/sample.php' o ruta relativa como \"../path2/sample.php\" puede ser utilizado.
Si la via de entrada, como \"http://url/sample.php\", el resultado sera recibido y, a continuacion se muestran.
Esta es la actual XE ruta absoluta.
"; + $lang->about_opage_caching_interval = "La unidad es minuto, y se muestra temporal de los datos guardados por el tiempo asignado.
Se recomienda a la cache para una buena vez si una gran cantidad de recursos se necesitan otros servidores cuando se muestran los datos o la informacion.
Un valor de 0 no cache."; + $lang->opage_mobile_path = 'Location of External Document for Mobile View'; + $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; +?> diff --git a/modules/opage/lang/fr.lang.php b/modules/opage/lang/fr.lang.php index e138bf155..8ee06ec29 100644 --- a/modules/opage/lang/fr.lang.php +++ b/modules/opage/lang/fr.lang.php @@ -1,17 +1,17 @@ -opage = "Page Extérieure"; - $lang->opage_path = "Localisation du Document Extérieur"; - $lang->opage_caching_interval = "Temps de antémémoire"; - - $lang->about_opage = "Ce module vous fait pouvoir utiliser des documents extérieurs en html ou en php dans XE.
Il est possible d'utiliser le chemin absolu ou relatif, et si l'URL commence avec 'http://' , il est possible de représenter des pages extérieurs du serveur."; - $lang->about_opage_path= "Entrez la localisation du document extérieur.
Non seulement le chemin absolu comme '/path1/path2/sample.php' mais aussi le chemin relatif comme '../path2/sample.php' peuvent être utilisés.
Si vous entrez le chemin comme 'http://url/sample.php', le résultat sera reçu et puis exposé
Le chemin suivant, c'est le chemin absolu de XE.
"; - $lang->about_opage_caching_interval = "L'unité est minute, et ça exposera des données conservées temporairement pendant le temps assigné.
Il est recommandé d'utiliser l'antémémoire pendant le temps convenable si beaucoup de ressource est nécessaire pour représenter les données ou l'information d'autre serveur.
La valeur 0 signifie de ne pas utiliser antémémoire."; - $lang->opage_mobile_path = 'Location of External Document for Mobile View'; - $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; -?> +opage = "Page Extérieure"; + $lang->opage_path = "Localisation du Document Extérieur"; + $lang->opage_caching_interval = "Temps de antémémoire"; + + $lang->about_opage = "Ce module vous fait pouvoir utiliser des documents extérieurs en html ou en php dans XE.
Il est possible d'utiliser le chemin absolu ou relatif, et si l'URL commence avec 'http://' , il est possible de représenter des pages extérieurs du serveur."; + $lang->about_opage_path= "Entrez la localisation du document extérieur.
Non seulement le chemin absolu comme '/path1/path2/sample.php' mais aussi le chemin relatif comme '../path2/sample.php' peuvent être utilisés.
Si vous entrez le chemin comme 'http://url/sample.php', le résultat sera reçu et puis exposé
Le chemin suivant, c'est le chemin absolu de XE.
"; + $lang->about_opage_caching_interval = "L'unité est minute, et ça exposera des données conservées temporairement pendant le temps assigné.
Il est recommandé d'utiliser l'antémémoire pendant le temps convenable si beaucoup de ressource est nécessaire pour représenter les données ou l'information d'autre serveur.
La valeur 0 signifie de ne pas utiliser antémémoire."; + $lang->opage_mobile_path = 'Location of External Document for Mobile View'; + $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; +?> diff --git a/modules/opage/lang/jp.lang.php b/modules/opage/lang/jp.lang.php index b9cdeac72..d6cd56919 100644 --- a/modules/opage/lang/jp.lang.php +++ b/modules/opage/lang/jp.lang.php @@ -1,17 +1,17 @@ -opage = '外部ページ'; - $lang->opage_path = '外部ドキュメントの場所'; - $lang->opage_caching_interval = 'キャッシング時間設定'; - - $lang->about_opage = '外部のHTMLまたはPHPファイルをXE内部で使用出来るようにするモジュールです。
絶対パス、相対パスで指定出来、「http://」で始まるサーバの外部ページも表示出来ます。'; - $lang->about_opage_path= '外部ドキュメントの場所を入力して下さい。
「/path1/path2/sample.php」のような絶対パス、「../path2/sample.php」のような相対パスが使用出来ます。
「http://URL/sample.php」のように使用すると結果を読み込んで表示します。
現在XEがインストールされている絶対パスは次のようになっています。
'; - $lang->about_opage_caching_interval = '分単位で指定出来、設定された時間の間は、臨時保存されたデータを出力します。
他のサーバの情報を出力したり、データを出力する際、リソースが多く使われるため、数分単位でキャッシングすることをお勧めします。
「0」に指定するとキャッシングされません。'; - $lang->opage_mobile_path = 'Location of External Document for Mobile View'; - $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; -?> +opage = '外部ページ'; + $lang->opage_path = '外部ドキュメントの場所'; + $lang->opage_caching_interval = 'キャッシング時間設定'; + + $lang->about_opage = '外部のHTMLまたはPHPファイルをXE内部で使用出来るようにするモジュールです。
絶対パス、相対パスで指定出来、「http://」で始まるサーバの外部ページも表示出来ます。'; + $lang->about_opage_path= '外部ドキュメントの場所を入力して下さい。
「/path1/path2/sample.php」のような絶対パス、「../path2/sample.php」のような相対パスが使用出来ます。
「http://URL/sample.php」のように使用すると結果を読み込んで表示します。
現在XEがインストールされている絶対パスは次のようになっています。
'; + $lang->about_opage_caching_interval = '分単位で指定出来、設定された時間の間は、臨時保存されたデータを出力します。
他のサーバの情報を出力したり、データを出力する際、リソースが多く使われるため、数分単位でキャッシングすることをお勧めします。
「0」に指定するとキャッシングされません。'; + $lang->opage_mobile_path = 'Location of External Document for Mobile View'; + $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; +?> diff --git a/modules/opage/lang/ko.lang.php b/modules/opage/lang/ko.lang.php index d9e8b79fe..72e5b2ebc 100644 --- a/modules/opage/lang/ko.lang.php +++ b/modules/opage/lang/ko.lang.php @@ -1,18 +1,18 @@ -opage = '외부 페이지'; - $lang->opage_path = '외부 문서 위치'; - $lang->opage_caching_interval = '캐싱 시간 설정'; - - $lang->about_opage = 'XE가 아닌 외부 HTML 또는 PHP파일을 XE에서 사용할 수 있도록 하는 모듈입니다.
절대경로, 상대경로를 이용할 수 있으며 http:// 로 시작할 경우 서버 외부의 페이지도 표시할 수 있습니다'; - $lang->about_opage_path= '외부문서의 위치를 입력해주세요.
/path1/path2/sample.php 와 같이 절대경로나 ../path2/sample.php와 같은 상대경로 모두 사용가능합니다.
http://url/sample.php 와 같이 사용하면 해당 페이지를 웹으로 전송 받아 출력 하게 됩니다.
현재 XE가 설치된 절대경로는 다음과 같습니다.
'; - $lang->about_opage_caching_interval = '분 단위이며 정해진 시간동안은 임시 저장한 데이터를 출력합니다.
다른 서버의 정보를 출력하거나, 데이터 출력하는데 많은 자원이 필요한 경우, 원하시는 분 단위 시간 간격으로 캐싱하는 것을 추천합니다.
0 으로 하시면 캐싱을 하지 않습니다.'; - - $lang->opage_mobile_path = '모바일용 외부 문서 위치'; - $lang->about_opage_mobile_path= '모바일용 외부문서의 위치를 입력해주세요. 입력하지 않으면 위에서 지정한 외부문서 위치의 페이지를 이용합니다.
/path1/path2/sample.php 와 같이 절대경로나 ../path2/sample.php와 같은 상대경로 모두 사용가능합니다.
http://url/sample.php 와 같이 사용하면 해당 페이지를 웹으로 전송 받아 출력 하게 됩니다.
현재 XE가 설치된 절대경로는 다음과 같습니다.
'; -?> +opage = '외부 페이지'; + $lang->opage_path = '외부 문서 위치'; + $lang->opage_caching_interval = '캐싱 시간 설정'; + + $lang->about_opage = 'XE가 아닌 외부 HTML 또는 PHP파일을 XE에서 사용할 수 있도록 하는 모듈입니다.
절대경로, 상대경로를 이용할 수 있으며 http:// 로 시작할 경우 서버 외부의 페이지도 표시할 수 있습니다'; + $lang->about_opage_path= '외부문서의 위치를 입력해주세요.
/path1/path2/sample.php 와 같이 절대경로나 ../path2/sample.php와 같은 상대경로 모두 사용가능합니다.
http://url/sample.php 와 같이 사용하면 해당 페이지를 웹으로 전송 받아 출력 하게 됩니다.
현재 XE가 설치된 절대경로는 다음과 같습니다.
'; + $lang->about_opage_caching_interval = '분 단위이며 정해진 시간동안은 임시 저장한 데이터를 출력합니다.
다른 서버의 정보를 출력하거나, 데이터 출력하는데 많은 자원이 필요한 경우, 원하시는 분 단위 시간 간격으로 캐싱하는 것을 추천합니다.
0 으로 하시면 캐싱을 하지 않습니다.'; + + $lang->opage_mobile_path = '모바일용 외부 문서 위치'; + $lang->about_opage_mobile_path= '모바일용 외부문서의 위치를 입력해주세요. 입력하지 않으면 위에서 지정한 외부문서 위치의 페이지를 이용합니다.
/path1/path2/sample.php 와 같이 절대경로나 ../path2/sample.php와 같은 상대경로 모두 사용가능합니다.
http://url/sample.php 와 같이 사용하면 해당 페이지를 웹으로 전송 받아 출력 하게 됩니다.
현재 XE가 설치된 절대경로는 다음과 같습니다.
'; +?> diff --git a/modules/opage/lang/ru.lang.php b/modules/opage/lang/ru.lang.php index d7cfa1128..a9d3600c1 100644 --- a/modules/opage/lang/ru.lang.php +++ b/modules/opage/lang/ru.lang.php @@ -1,17 +1,17 @@ - | translation by Maslennikov Evgeny aka X-[Vr]bL1s5 | e-mail: x-bliss[a]tut.by; ICQ: 225035467; - * @brief Russian basic language pack - **/ - - $lang->opage = "Внешняя страница"; - $lang->opage_path = "Расположение внешнего документа"; - $lang->opage_caching_interval = "Установить время кеширования"; - - $lang->about_opage = "Этот модуль позволяет использовать внешние HTML или PHP файлы в XE.
Требует ввода абсолютного или относительного пути. Если URL начинается с 'http://', внешняя страница с другого сервера будет показана."; - $lang->about_opage_path= "Пожалуйста, введите размещение внешнего документа.
Абсолютный путь как '/path1/path2/sample.php', так и относительный как '../path2/sample.php' могут быть использованы.
Если Вы введете путь как 'http://url/sample.php', результат будет сначала получен и затем показан.
Это текущий абсолютный путь к XE.
"; - $lang->about_opage_caching_interval = "Единица измерения равна одной минуте. Это отображает временно сохраненные данные для присвоенного времени.
Рекомендуется устанавливать разумное время кеширования, если множество ресурсов нуждаются в показе данных с других серверов.
Значение 0 отключает кеширование."; - $lang->opage_mobile_path = 'Location of External Document for Mobile View'; - $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; -?> +opage = "Внешняя страница"; + $lang->opage_path = "Расположение внешнего документа"; + $lang->opage_caching_interval = "Установить время кеширования"; + + $lang->about_opage = "Этот модуль позволяет использовать внешние HTML или PHP файлы в XE.
Требует ввода абсолютного или относительного пути. Если URL начинается с 'http://', внешняя страница с другого сервера будет показана."; + $lang->about_opage_path= "Пожалуйста, введите размещение внешнего документа.
Абсолютный путь как '/path1/path2/sample.php', так и относительный как '../path2/sample.php' могут быть использованы.
Если Вы введете путь как 'http://url/sample.php', результат будет сначала получен и затем показан.
Это текущий абсолютный путь к XE.
"; + $lang->about_opage_caching_interval = "Единица измерения равна одной минуте. Это отображает временно сохраненные данные для присвоенного времени.
Рекомендуется устанавливать разумное время кеширования, если множество ресурсов нуждаются в показе данных с других серверов.
Значение 0 отключает кеширование."; + $lang->opage_mobile_path = 'Location of External Document for Mobile View'; + $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; +?> diff --git a/modules/opage/lang/vi.lang.php b/modules/opage/lang/vi.lang.php index 1dc1bca5c..cc4d772c4 100644 --- a/modules/opage/lang/vi.lang.php +++ b/modules/opage/lang/vi.lang.php @@ -1,19 +1,19 @@ -opage = "Trang ngoài"; - $lang->opage_path = "Đường dẫn thư mục"; - $lang->opage_caching_interval = "Thời gian lưu trữ"; - - $lang->about_opage = "Module này tạo ra một trang từ bên ngoài tại XE thông qua File HTML hoặc PHP.
Nó cho phép đường dẫn tuyệt đối hay tương đối, nếu bắt đầu bằng 'http://' , nó sẽ hiển thị một trang từ bên ngoài Server."; - $lang->about_opage_path= "Xin hãy nhập đường dẫn của thư mục.
Có thể sử dụng đường dẫn tuyệt đối dạng '/path1/path2/sample.php' hay tương đối dạng '../path2/sample.php'.
Nếu nhập đường dẫn dạng 'http://url/sample.php', nó sẽ nhận và hiển thị nội dung của File đó.
Đây là đường dẫn tuyệt đối thư mục cài đặt XE.
"; - $lang->about_opage_caching_interval = "Đơn vị được tính bằng phút, nó sẽ là thời gian lưu trữ tạm thời.
Đó là khuyến cáo thời gian lưu trữ tạm thời thích hợp khi cần để hiển thị.
Nhập 0 nếu không sử dụng tính năng này."; - $lang->opage_mobile_path = 'Location of External Document for Mobile View'; - $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; -?> +opage = "Trang ngoài"; + $lang->opage_path = "Đường dẫn thư mục"; + $lang->opage_caching_interval = "Thời gian lưu trữ"; + + $lang->about_opage = "Module này tạo ra một trang từ bên ngoài tại XE thông qua File HTML hoặc PHP.
Nó cho phép đường dẫn tuyệt đối hay tương đối, nếu bắt đầu bằng 'http://' , nó sẽ hiển thị một trang từ bên ngoài Server."; + $lang->about_opage_path= "Xin hãy nhập đường dẫn của thư mục.
Có thể sử dụng đường dẫn tuyệt đối dạng '/path1/path2/sample.php' hay tương đối dạng '../path2/sample.php'.
Nếu nhập đường dẫn dạng 'http://url/sample.php', nó sẽ nhận và hiển thị nội dung của File đó.
Đây là đường dẫn tuyệt đối thư mục cài đặt XE.
"; + $lang->about_opage_caching_interval = "Đơn vị được tính bằng phút, nó sẽ là thời gian lưu trữ tạm thời.
Đó là khuyến cáo thời gian lưu trữ tạm thời thích hợp khi cần để hiển thị.
Nhập 0 nếu không sử dụng tính năng này."; + $lang->opage_mobile_path = 'Location of External Document for Mobile View'; + $lang->about_opage_mobile_path= "Please input the location of external document for mobile view. If not inputted, it uses the the external document specified above.
Both absolute path such as '/path1/path2/sample.php' or relative path such as '../path2/sample.php' can be used.
If you input the path like 'http://url/sample.php' , the result will be received and then displayed.
This is current XE's absolute path.
"; +?> diff --git a/modules/opage/lang/zh-CN.lang.php b/modules/opage/lang/zh-CN.lang.php index 857e30a62..e15e8bb3f 100644 --- a/modules/opage/lang/zh-CN.lang.php +++ b/modules/opage/lang/zh-CN.lang.php @@ -1,18 +1,18 @@ -opage = "外部页面"; - $lang->opage_path = "外部页面路径"; - $lang->opage_caching_interval = "缓冲时间设置"; - - $lang->about_opage = "此模块是一种可以把外部html或php文件插入到XE内部的模块。
可以使用绝对路径及相对路径。而且使用以http:// 开头的地址时,可以把外部服务器中的页面插入到XE当中。"; - $lang->about_opage_path= "请输入外部文件路径。
可以使用如同 /path1/path2/sample.php的绝对路径或如 ../path2/sample.php的相对路径。
如使用http://url/sample.php之类的地址,可以把此页面的输出结果显示到XE内部的指定位置。
现安装的XE绝对路径如下:
"; - $lang->about_opage_caching_interval = "单位为分。缓冲时间内页面将输出临时储存的数据。
输出外部服务器信息或数据时,如消耗资源很大,尽量把缓冲时间设置为大一点的相应值。
0 表示无缓冲。"; - - $lang->opage_mobile_path = '移动版外部页面路径'; - $lang->about_opage_mobile_path= '请输入移动版外部文件路径。留空默认使用上面指定的的普通外部页面。
可以使用如同 /path1/path2/sample.php的绝对路径或如 ../path2/sample.php的相对路径。
如使用http://url/sample.php之类的地址,可以把此页面的输出结果显示到XE内部的指定位置。
现安装的XE绝对路径如下:
'; -?> +opage = "外部页面"; + $lang->opage_path = "外部页面路径"; + $lang->opage_caching_interval = "缓冲时间设置"; + + $lang->about_opage = "此模块是一种可以把外部html或php文件插入到XE内部的模块。
可以使用绝对路径及相对路径。而且使用以http:// 开头的地址时,可以把外部服务器中的页面插入到XE当中。"; + $lang->about_opage_path= "请输入外部文件路径。
可以使用如同 /path1/path2/sample.php的绝对路径或如 ../path2/sample.php的相对路径。
如使用http://url/sample.php之类的地址,可以把此页面的输出结果显示到XE内部的指定位置。
现安装的XE绝对路径如下:
"; + $lang->about_opage_caching_interval = "单位为分。缓冲时间内页面将输出临时储存的数据。
输出外部服务器信息或数据时,如消耗资源很大,尽量把缓冲时间设置为大一点的相应值。
0 表示无缓冲。"; + + $lang->opage_mobile_path = '移动版外部页面路径'; + $lang->about_opage_mobile_path= '请输入移动版外部文件路径。留空默认使用上面指定的的普通外部页面。
可以使用如同 /path1/path2/sample.php的绝对路径或如 ../path2/sample.php的相对路径。
如使用http://url/sample.php之类的地址,可以把此页面的输出结果显示到XE内部的指定位置。
现安装的XE绝对路径如下:
'; +?> diff --git a/modules/opage/lang/zh-TW.lang.php b/modules/opage/lang/zh-TW.lang.php index e4bc8ae47..5e3145b8e 100644 --- a/modules/opage/lang/zh-TW.lang.php +++ b/modules/opage/lang/zh-TW.lang.php @@ -1,7 +1,7 @@ module = 'opage'; - $args->mid = $args->opage_name; - unset($args->opage_name); - - // module_srl이 넘어오면 원 모듈이 있는지 확인 - if($args->module_srl) { - $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); - if($module_info->module_srl != $args->module_srl) unset($args->module_srl); - } - - // module_srl의 값에 따라 insert/update - if(!$args->module_srl) { - $args->module_srl = getNextSequence(); - $output = $oModuleController->insertModule($args); - $msg_code = 'success_registed'; - } else { - $output = $oModuleController->updateModule($args); - $msg_code = 'success_updated'; - - // 캐시 파일 삭제 - $cache_file = sprintf("./files/cache/opage/%d.cache.php", $module_info->module_srl); - if(file_exists($cache_file)) FileHandler::removeFile($cache_file); - } - - if(!$output->toBool()) return $output; - - // 등록 성공후 return될 메세지 정리 - $this->add("module_srl", $output->get('module_srl')); - $this->add("opage", Context::get('opage')); - $this->setMessage($msg_code); - } - - /** - * @brief 외부페이지 삭제 - **/ - function procOpageAdminDelete() { - $module_srl = Context::get('module_srl'); - - // 원본을 구해온다 - $oModuleController = &getController('module'); - $output = $oModuleController->deleteModule($module_srl); - if(!$output->toBool()) return $output; - - $this->add('module','opage'); - $this->add('opage',Context::get('opage')); - $this->setMessage('success_deleted'); - } - - /** - * @brief 외부페이지 기본 정보의 추가 - **/ - function procOpageAdminInsertConfig() { - // 기본 정보를 받음 - $args = Context::gets('test'); - - } - - } -?> +module = 'opage'; + $args->mid = $args->opage_name; + unset($args->opage_name); + + // module_srl이 넘어오면 원 모듈이 있는지 확인 + if($args->module_srl) { + $module_info = $oModuleModel->getModuleInfoByModuleSrl($args->module_srl); + if($module_info->module_srl != $args->module_srl) unset($args->module_srl); + } + + // module_srl의 값에 따라 insert/update + if(!$args->module_srl) { + $args->module_srl = getNextSequence(); + $output = $oModuleController->insertModule($args); + $msg_code = 'success_registed'; + } else { + $output = $oModuleController->updateModule($args); + $msg_code = 'success_updated'; + + // 캐시 파일 삭제 + $cache_file = sprintf("./files/cache/opage/%d.cache.php", $module_info->module_srl); + if(file_exists($cache_file)) FileHandler::removeFile($cache_file); + } + + if(!$output->toBool()) return $output; + + // 등록 성공후 return될 메세지 정리 + $this->add("module_srl", $output->get('module_srl')); + $this->add("opage", Context::get('opage')); + $this->setMessage($msg_code); + } + + /** + * @brief 외부페이지 삭제 + **/ + function procOpageAdminDelete() { + $module_srl = Context::get('module_srl'); + + // 원본을 구해온다 + $oModuleController = &getController('module'); + $output = $oModuleController->deleteModule($module_srl); + if(!$output->toBool()) return $output; + + $this->add('module','opage'); + $this->add('opage',Context::get('opage')); + $this->setMessage('success_deleted'); + } + + /** + * @brief 외부페이지 기본 정보의 추가 + **/ + function procOpageAdminInsertConfig() { + // 기본 정보를 받음 + $args = Context::gets('test'); + + } + + } +?> diff --git a/modules/opage/opage.admin.view.php b/modules/opage/opage.admin.view.php index 6c5eeb17c..8f982248e 100644 --- a/modules/opage/opage.admin.view.php +++ b/modules/opage/opage.admin.view.php @@ -1,7 +1,7 @@ + diff --git a/modules/opage/opage.controller.php b/modules/opage/opage.controller.php index c9b24e53b..9d2a179a5 100644 --- a/modules/opage/opage.controller.php +++ b/modules/opage/opage.controller.php @@ -1,105 +1,105 @@ -]*)>(.*?)<\/title>!is', $content, $buff); - return trim($buff[2]); - } - - /** - * @brief header script 추출 - **/ - function getHeadScript($content) { - // title 태그 제거 - $content = preg_replace('!]*)>(.*?)<\/title>!is','', $content); - - // meta 태그 제거 - $content = preg_replace('!<(\/){0,1}meta([^>]*)>!is','', $content); - - // ]*)>!is', $content, $link_buff); - for($i=0;$i!is', $content, $script_buff); - for($i=0;$i]*)>(.*?)<\/body>!is', $content, $body_buff); - $body_script = $body_buff[2]; - - // link, style, script등 제거 - $body_script = preg_replace('!]*)>!is', '', $body_script); - $body_script = preg_replace('!<(style|script)(.*?)<\/(style|script)>!is', '', $body_script); - return $body_script; - } - - /** - * @brief 내용에 포함된 src, href의 값을 변경 - **/ - function replaceSrc($content, $path) { - $url_info = parse_url($path); - $host = sprintf("%s://%s%s",$url_info['scheme'],$url_info['host'],$url_info['port']?':'.$url_info['port']:''); - $this->host = $host.'/'; - $path = $url_info['path']; - if(substr($path,-1)=='/') $path = substr($path,-1); - $t = explode('/',$path); - $_t = array(); - for($i=0,$c=count($t)-1;$i<$c;$i++) { - $v = trim($t[$i]); - if(!$v) continue; - $_t[] = $v; - } - $path = $host.'/'.implode('/',$_t); - if(substr($path,-1)!='/') $path .= '/'; - $this->path = $path; - $content = preg_replace_callback('/(src=|href=|url\()("|\')?([^"\'\)]+)("|\'\))?/is',array($this,'_replacePath'),$content); - - return $content; - } - - function _replacePath($matches) { - $val = trim($matches[3]); - if(preg_match('/^(http|https|ftp|telnet|mms|mailto)/i',$val)) return $matches[0]; - if(substr($val,0,2)=='./') { - $path = $this->path.substr($val,2); - } elseif(substr($val,0,1)=='/') { - $path = $this->host.substr($val,1); - } else { - $path = $this->path.$val; - } - return sprintf("%s%s%s%s", $matches[1], $matches[2], $path, $matches[4]); - } - - } -?> +]*)>(.*?)<\/title>!is', $content, $buff); + return trim($buff[2]); + } + + /** + * @brief header script 추출 + **/ + function getHeadScript($content) { + // title 태그 제거 + $content = preg_replace('!]*)>(.*?)<\/title>!is','', $content); + + // meta 태그 제거 + $content = preg_replace('!<(\/){0,1}meta([^>]*)>!is','', $content); + + // ]*)>!is', $content, $link_buff); + for($i=0;$i!is', $content, $script_buff); + for($i=0;$i]*)>(.*?)<\/body>!is', $content, $body_buff); + $body_script = $body_buff[2]; + + // link, style, script등 제거 + $body_script = preg_replace('!]*)>!is', '', $body_script); + $body_script = preg_replace('!<(style|script)(.*?)<\/(style|script)>!is', '', $body_script); + return $body_script; + } + + /** + * @brief 내용에 포함된 src, href의 값을 변경 + **/ + function replaceSrc($content, $path) { + $url_info = parse_url($path); + $host = sprintf("%s://%s%s",$url_info['scheme'],$url_info['host'],$url_info['port']?':'.$url_info['port']:''); + $this->host = $host.'/'; + $path = $url_info['path']; + if(substr($path,-1)=='/') $path = substr($path,-1); + $t = explode('/',$path); + $_t = array(); + for($i=0,$c=count($t)-1;$i<$c;$i++) { + $v = trim($t[$i]); + if(!$v) continue; + $_t[] = $v; + } + $path = $host.'/'.implode('/',$_t); + if(substr($path,-1)!='/') $path .= '/'; + $this->path = $path; + $content = preg_replace_callback('/(src=|href=|url\()("|\')?([^"\'\)]+)("|\'\))?/is',array($this,'_replacePath'),$content); + + return $content; + } + + function _replacePath($matches) { + $val = trim($matches[3]); + if(preg_match('/^(http|https|ftp|telnet|mms|mailto)/i',$val)) return $matches[0]; + if(substr($val,0,2)=='./') { + $path = $this->path.substr($val,2); + } elseif(substr($val,0,1)=='/') { + $path = $this->host.substr($val,1); + } else { + $path = $this->path.$val; + } + return sprintf("%s%s%s%s", $matches[1], $matches[2], $path, $matches[4]); + } + + } +?> diff --git a/modules/opage/opage.model.php b/modules/opage/opage.model.php index 63e9fdfe6..99a2254f6 100644 --- a/modules/opage/opage.model.php +++ b/modules/opage/opage.model.php @@ -1,33 +1,33 @@ -getModuleInfoByModuleSrl($module_srl); - if($module_info->module_srl != $module_srl) return; - - $extra_vars = unserialize($module_info->extra_vars); - if($extra_vars) { - foreach($extra_vars as $key => $val) $module_info->{$key} = $val; - unset($module_info->extra_vars); - } - return $module_info; - } - - } -?> +getModuleInfoByModuleSrl($module_srl); + if($module_info->module_srl != $module_srl) return; + + $extra_vars = unserialize($module_info->extra_vars); + if($extra_vars) { + foreach($extra_vars as $key => $val) $module_info->{$key} = $val; + unset($module_info->extra_vars); + } + return $module_info; + } + + } +?> diff --git a/modules/opage/opage.view.php b/modules/opage/opage.view.php index 0082ddd93..db544f3d0 100644 --- a/modules/opage/opage.view.php +++ b/modules/opage/opage.view.php @@ -1,164 +1,164 @@ -setTemplatePath($this->module_path.'tpl'); - - // 외부 페이지 모듈의 정보를 구함 - $oOpageModel = &getModel('opage'); - $module_info = $oOpageModel->getOpage($this->module_srl); - Context::set('module_info', $module_info); - - // 외부 페이지에서 명시된 외부 페이지 경로/ 캐싱 간격을 를 구함 - $this->path = $module_info->path; - $this->caching_interval = $module_info->caching_interval; - - // 캐시 파일 지정 - $this->cache_file = sprintf("./files/cache/opage/%d.cache.php", $module_info->module_srl); - } - - /** - * @brief 일반 요청시 출력 - **/ - function dispOpageIndex() { - - // http 인지 내부 파일인지 점검 - if($this->path) { - if(preg_match("/^([a-z]+):\/\//i",$this->path)) $content = $this->getHtmlPage($this->path, $this->caching_interval, $this->cache_file); - else $content = $this->executeFile($this->path, $this->caching_interval, $this->cache_file); - } - - Context::set('opage_content', $content); - - // 결과 출력 템플릿 지정 - $this->setTemplateFile('content'); - } - - /** - * @brief 외부 http로 요청되는 파일일 경우 파일을 받아와서 저장 후 return - **/ - function getHtmlPage($path, $caching_interval, $cache_file) { - - // 캐시 검사 - if($caching_interval > 0 && file_exists($cache_file) && filemtime($cache_file) + $caching_interval*60 > time()) { - - $content = FileHandler::readFile($cache_file); - - } else { - - FileHandler::getRemoteFile($path, $cache_file); - $content = FileHandler::readFile($cache_file); - - } - - // opage controller 생성 - $oOpageController = &getController('opage'); - - // 외부 서버의 페이지 일 경우 이미지, css, javascript등의 url을 변경 - $content = $oOpageController->replaceSrc($content, $path); - - // 해당 문서를 utf-8로 변경 - $buff->content = $content; - $buff = Context::convertEncoding($buff); - $content = $buff->content; - - // title 추출 - $title = $oOpageController->getTitle($content); - if($title) Context::setBrowserTitle($title); - - // header script 추출 - $head_script = $oOpageController->getHeadScript($content); - if($head_script) Context::addHtmlHeader($head_script); - - // body 내용 추출 - $body_script = $oOpageController->getBodyScript($content); - if(!$body_script) $body_script = $content; - - return $content; - } - - /** - * @brief 내부 파일일 경우 include하도록 캐시파일을 만들고 처리 - **/ - function executeFile($path, $caching_interval, $cache_file) { - // 파일이 없으면 취소 - if(!file_exists($path)) return; - - // 경로와 파일이름을 구함 - $tmp_path = explode('/',$cache_file); - $filename = $tmp_path[count($tmp_path)-1]; - $filepath = preg_replace('/'.$filename."$/i","",$cache_file); - - // 캐시 검사 - if($caching_interval <1 || !file_exists($cache_file) || filemtime($cache_file) + $caching_interval*60 <= time() || filemtime($cache_file)path = str_replace('\\', '/', realpath($path_info['dirname'])).'/'; - $content = preg_replace_callback('/(src=|href=|url\()("|\')?([^"\'\)]+)("|\'\))?/is',array($this,'_replacePath'),$content); - $content = preg_replace_callback('/("); - var cssfile = tmp.substr(9,eos-9); - if(cssfile.indexOf('.js')>-1) { - tmp = tmp.substr(eos); - continue; - } - if(!cssfile) break; - tmp = tmp.substr(eos); - - var cssfile = request_uri+'/'+cssfile; - if(typeof(document.createStyleSheet)=='undefined') { - var css =''; - var dummy = xCreateElement("DIV"); - xInnerHtml(dummy , css); - document.body.appendChild(dummy); - } else { - document.createStyleSheet(cssfile,0); - } - } - - // widget 코드에서 javascript 부분을 빼서 eval후 결과값을 대체함 - checkDocumentWrite = true; ///< document.write(ln)등의 함수값을 바로 사용하기 위한 check flag - - // widget_code의 javascript 부분 수정 - var tmp = widget_code.toLowerCase(); - while(tmp.indexOf("-1) { - - var pos = tmp.indexOf("")+9; - - var script = widget_code.substr(pos,length); - script = script.replace(/^]*)>/i,'').replace(/<\/script>$/i,''); - - writedText = null; - eval(script); - widget_code = widget_code.substr(0,pos)+writedText+widget_code.substr(pos+length); - tmp = widget_code.toLowerCase(); - } - - - - // html 추가 - var dummy = xCreateElement('div'); - xInnerHtml(dummy, widget_code); - var obj = dummy.childNodes[0]; - - if(selectedWidget && selectedWidget.getAttribute("widget")) { - var o = jQuery('div.widget_inner',selectedWidget); - var n = jQuery('div.widget_inner',obj); - - if(n.size()==0) n = jQuery('div.nullWidget',obj); - if(o.size()==0) o = jQuery('div.nullWidget',selectedWidget); - - n.html(o.html()); - - - selectedWidget.parentNode.insertBefore(obj, selectedWidget); - selectedWidget.parentNode.removeChild(selectedWidget); - } else { - xGetElementById('zonePageContent').appendChild(obj); - } - checkDocumentWrite = false; - selectedWidget = null; - - /* - //zoneObj.style.visibility = 'hidden'; - zoneObj.style.opacity = 0.2; - zoneObj.style.filter = "alpha(opacity=20)"; - - // 위젯 추가후 페이지 리로딩 - var tpl = getWidgetContent(); - - var fo_obj = xGetElementById('pageFo'); - fo_obj.content.value = tpl; - fo_obj.mid.value = current_mid; - fo_obj.submit(); - */ -} - -// 클릭 이벤트시 위젯의 수정/제거/이벤트 무효화 처리 -function doCheckWidget(e) { - var evt = new xEvent(e); if(!evt.target) return; - var obj = evt.target; - - selectedWidget = null; - - var pObj = obj.parentNode; - while(pObj) { - if(pObj.id == "pageSizeLayer") return; - pObj = pObj.parentNode; - } - - doHideWidgetSizeSetup(); - // 위젯 설정 - if(obj.className == 'widgetSetup') { - var p_obj = obj.parentNode.parentNode; - var widget = p_obj.getAttribute("widget"); - if(!widget) return; - selectedWidget = p_obj; - if(widget == 'widgetContent') popopen(request_uri+"?module=widget&act=dispWidgetAdminAddContent&module_srl="+zoneModuleSrl+"&document_srl="+p_obj.getAttribute("document_srl"), "addContent"); - else popopen(request_uri+"?module=widget&act=dispWidgetGenerateCodeInPage&selected_widget="+widget+"&widgetstyle="+widgetstyle,'GenerateCodeInPage'); - return; - - // 위젯 스타일 - } else if(obj.className == 'widgetStyle') { - var p_obj = obj.parentNode.parentNode; - var widget = p_obj.getAttribute("widget"); - var widgetstyle = p_obj.getAttribute("widgetstyle"); - if(!widget) return; - selectedWidget = p_obj; - popopen(request_uri+"?module=widget&act=dispWidgetStyleGenerateCodeInPage&selected_widget="+widget+"&widgetstyle="+widgetstyle,'GenerateCodeInPage'); - return; - - // 위젯 복사 - } else if(obj.className == 'widgetCopy' && obj.parentNode.parentNode.className == 'widgetOutput') { - p_obj = obj.parentNode.parentNode; - restoreWidgetButtons(); - - if(p_obj.getAttribute('widget')=='widgetContent' && p_obj.getAttribute('document_srl') ) { - var response_tags = new Array('error','message','document_srl'); - var params = new Array(); - params['document_srl'] =p_obj.getAttribute('document_srl'); - exec_xml('widget','procWidgetCopyDocument', params, completeCopyWidgetContent, response_tags, params, p_obj); - return; - } else { - var dummy = xCreateElement("DIV"); - xInnerHtml(dummy,xInnerHtml(p_obj)); - - dummy.widget_sequence = ''; - dummy.className = "widgetOutput"; - for(var i=0;i 0) return; - - doHideWidgetSizeSetup(); - - if(obj.className == 'widgetSetup' || obj.className == 'widgetStyle' || obj.className == 'widgetCopy' || obj.className == 'widgetBoxCopy' || obj.className == 'widgetSize' || obj.className == 'widgetBoxSize' || obj.className == 'widgetRemove' || obj.className == 'widgetBoxRemove') return; - - p_obj = obj; - while(p_obj) { - if(p_obj.className == 'widgetOutput' || p_obj.className == 'widgetResize' || p_obj.className == 'widgetResizeLeft' || p_obj.className == 'widgetBoxResize' || p_obj.className == 'widgetBoxResizeLeft') { - widgetDragEnable(p_obj, widgetDragStart, widgetDrag, widgetDragEnd); - widgetMouseDown(e); - return; - } - p_obj = p_obj.parentNode; - } -} - -function _getInt(val) { - if(!val || val == "null") return 0; - if(parseInt(val,10)==NaN) return 0; - return parseInt(val,10); -} - -// 위젯 크기 조절 레이어를 보여줌 -var selectedSizeWidget = null; -function doShowWidgetSizeSetup(px, py, obj) { - var layer = jQuery('#pageSizeLayer'); - var form = layer.find('>form:first'); - var obj = jQuery(obj); - - if (!form.length) return; - - selectedSizeWidget = obj[0]; - - var opts = { - widget_align : obj.css('float'), - - width : obj[0].style.width, - height : obj[0].style.height, - - padding_left : _getInt(obj.attr('widget_padding_left')), - padding_right : _getInt(obj.attr('widget_padding_right')), - padding_top : _getInt(obj.attr('widget_padding_top')), - padding_bottom : _getInt(obj.attr('widget_padding_bottom')), - - margin_left : _getInt(obj[0].style.marginLeft), - margin_right : _getInt(obj[0].style.marginRight), - margin_top : _getInt(obj[0].style.marginTop), - margin_bottom : _getInt(obj[0].style.marginBottom), - - border_top_color : transRGB2Hex(obj[0].style.borderTopColor), - border_top_thick : obj[0].style.borderTopWidth.replace(/px$/i, ''), - border_top_type : obj[0].style.borderTopStyle, - - border_bottom_color : transRGB2Hex(obj[0].style.borderBottomColor), - border_bottom_thick : obj[0].style.borderBottomWidth.replace(/px$/i, ''), - border_bottom_type : obj[0].style.borderBottomStyle, - - border_right_color : transRGB2Hex(obj[0].style.borderRightColor), - border_right_thick : obj[0].style.borderRightWidth.replace(/px$/i, ''), - border_right_type : obj[0].style.borderRightStyle, - - border_left_color : transRGB2Hex(obj[0].style.borderLeftColor), - border_left_thick : obj[0].style.borderLeftWidth.replace(/px$/i, ''), - border_left_type : obj[0].style.borderLeftStyle, - - background_color : transRGB2Hex(obj[0].style.backgroundColor), - background_image_url : obj[0].style.backgroundImage.replace(/^url\(/i,'').replace(/\)$/i,''), - - background_x : 0, - background_y : 0, - - background_repeat : obj[0].style.backgroundRepeat - }; - - // background position - var pos = obj[0].style.backgroundPosition; - if(pos) { - pos = pos.split(' '); - if(pos.length == 2) { - opts.background_x = pos[0]; - opts.background_y = pos[1]; - } - } - - layer.css('top', py+'px').show(); - var _zonePageObj = jQuery(zonePageObj) - var zoneOffsetLeft = _zonePageObj.offset().left; - var zoneWidth = _zonePageObj.width(); - if (px + layer.width() > zoneOffsetLeft + zoneWidth) px = zoneOffsetLeft + zoneWidth - layer.width() - 5; - layer.css('left', px+'px'); - - jQuery.each(opts, function(key, val){ - var el = form[0].elements[key]; - if (el) el.value = val; - if (el.tagName.toLowerCase() == "select") - { - if(el.selectedIndex == -1) { - el.selectedIndex = 0; - } - } - }); - - try { form[0].elements[0].focus() } catch(e) {}; -} - -function doHideWidgetSizeSetup() { - jQuery('#pageSizeLayer').hide(); - //var layer = xGetElementById("pageSizeLayer"); - //layer.style.visibility = "hidden"; - //layer.style.display = "none"; -} - -function _getSize(value) { - if(!value) return 0; - var type = "px"; - if(value.lastIndexOf("%")>=0) type = "%"; - var num = parseInt(value,10); - if(num<1) return 0; - if(type == "%" && num > 100) num = 100; - return ""+num+type; -} - -function _getBorderStyle(fld_color, fld_thick, fld_type) { - var color = fld_color.value; - color = color.replace(/^#/,''); - if(!color) color = '#FFFFFF'; - else color = '#'+color; - var width = fld_thick.value; - if(!width) width = '0px'; - else width = parseInt(width,10)+'px'; - var style = fld_type.options[fld_type.selectedIndex].value; - if(!style) style = 'solid'; - - var str = color+' '+width+' '+style; - return str; -} - -function _getBGColorStyle(fld_color) { - var color = fld_color.replace(/^#/,''); - if(!color) color = '#FFFFFF'; - else color = '#'+color; - return color; -} - -function doApplyWidgetSize(fo_obj) { - if(selectedSizeWidget) { - if(fo_obj.widget_align.selectedIndex == 1) setFloat(selectedSizeWidget, 'right'); - else setFloat(selectedSizeWidget, 'left'); - - var width = _getSize(fo_obj.width.value); - if(width) selectedSizeWidget.style.width = width; - - var height = _getSize(fo_obj.height.value); - if(height && height != "100%") selectedSizeWidget.style.height = height; - else { - selectedSizeWidget.style.height = ''; - var widgetBorder = xGetElementsByClassName('widgetBorder',selectedSizeWidget); - for(var i=0;i 0) return; - if(jQuery(obj).is('.buttonBox') || jQuery(obj).parents('.buttonBox').size() > 0) return; - - - var o = jQuery(obj).parents('.widgetOutput'); - if(o.size() == 0){ - restoreWidgetButtons(); - return; - } - /* - if(!obj || typeof(obj.className)=='undefined' || obj.className != 'widgetOutput') { - restoreWidgetButtons(); - return; - } -*/ - - obj = o.get(0); - var widget = o.attr('widget'); - if(!widget) return; - - if(widget == 'widgetBox') { - restoreWidgetButtons(); - showWidgetButton('widgetBoxButton', obj); - } else { - restoreWidgetButtons(); - showWidgetButton('widgetButton', obj); - - var p_obj = obj.parentNode; - if(p_obj) { - while(p_obj) { - if(p_obj.nodeName == 'DIV' && p_obj.getAttribute('widget')=='widgetBox') { - showWidgetButton('widgetBoxButton', p_obj); - break; - } - p_obj = p_obj.parentNode; - } - } - } -} - -/* 위젯 드래그 */ -// 드래그 중이라는 상황을 간직할 변수 -var widgetDragManager = {obj:null, isDrag:false} -var widgetTmpObject = new Array(); -var widgetDisappear = 0; - -function widgetCreateTmpObject(obj) { - var id = obj.getAttribute('id'); - - tmpObj = xCreateElement('DIV'); - tmpObj.id = id + '_tmp'; - tmpObj.className = obj.className; - tmpObj.style.overflow = 'hidden'; - tmpObj.style.margin= '0px'; - tmpObj.style.padding = '0px'; - tmpObj.style.width = obj.style.width; - - tmpObj.style.display = 'none'; - tmpObj.style.position = 'absolute'; - tmpObj.style.opacity = 1; - tmpObj.style.filter = 'alpha(opacity=100)'; - - xLeft(tmpObj, xPageX(obj)); - xTop(tmpObj, xPageY(obj)); - - document.body.appendChild(tmpObj); - widgetTmpObject[obj.id] = tmpObj; - return tmpObj; -} - -// 기생성된 임시 object를 찾아서 return, 없으면 만들어서 return -var idStep = 0; -function widgetGetTmpObject(obj) { - if(!obj.id) obj.id = 'widget_'+idStep++; - var tmpObj = widgetTmpObject[obj.id]; - if(!tmpObj) tmpObj = widgetCreateTmpObject(obj); - return tmpObj; -} - -// 메뉴에 마우스 클릭이 일어난 시점에 드래그를 위한 제일 첫 동작 (해당 object에 각종 함수나 상태변수 설정) -function widgetDragEnable(obj, funcDragStart, funcDrag, funcDragEnd) { - - // 상위 object에 드래그 가능하다는 상태와 각 드래그 관련 함수를 설정 - obj.draggable = true; - obj.dragStart = funcDragStart; - obj.drag = funcDrag; - obj.dragEnd = funcDragEnd; - - // 드래그 가능하지 않다면 드래그 가능하도록 상태 지정하고 mousemove이벤트 등록 - if (!widgetDragManager.isDrag) { - widgetDragManager.isDrag = true; - xAddEventListener(document, 'mousemove', widgetDragMouseMove, false); - } -} - -// 드래그를 시작할때 호출되는 함수 (이동되는 형태를 보여주기 위한 작업을 함) -function widgetDragStart(tobj, px, py) { - if(tobj.className == 'widgetResize' || tobj.className == 'widgetResizeLeft' || tobj.className == 'widgetBoxResize' || tobj.className == 'widgetBoxResizeLeft') return; - var obj = widgetGetTmpObject(tobj); - - xInnerHtml(obj, xInnerHtml(tobj)); - - xLeft(obj, xPageX(tobj)); - xTop(obj, xPageY(tobj)); - xWidth(obj, xWidth(tobj)); - xHeight(obj, xHeight(tobj)); - - xDisplay(obj, 'block'); -} - -// 드래그 시작후 마우스를 이동할때 발생되는 이벤트에 의해 실행되는 함수 -function widgetDrag(tobj, dx, dy) { - var minWidth = 40; - var minHeight = 10; - - var sx = xPageX(tobj.parentNode); - var sy = xPageY(tobj.parentNode); - - var nx = tobj.xDPX; - var ny = tobj.xDPY; - - var zoneWidth = xWidth(zonePageObj); - var zoneLeft = xPageX(zonePageObj); - var zoneRight = zoneLeft + zoneWidth; - - var pWidth = xWidth(tobj.parentNode); - - var cssFloat = getFloat(tobj.parentNode); - if(!cssFloat) cssFloat = 'left'; - - // 위젯 리사이즈 (우측) - if(tobj.className == 'widgetResize' || tobj.className == 'widgetBoxResize') { - if(nx < sx+minWidth) nx = sx+minWidth; - if(nx > zoneRight) nx = zoneRight; - - if(cssFloat == 'right') nx = sx + pWidth; - - var new_width = nx - sx; - if(new_width < minWidth) new_width = minWidth; - - var new_height = ny - sy; - if(new_height < minHeight) new_height = minHeight; - - if( zoneRight < sx+new_width) new_width = zoneRight - sx; - - // 위젯의 크기 조절 - xWidth(tobj.nextSibling.nextSibling, new_width); - xHeight(tobj.nextSibling.nextSibling, new_height); - - xWidth(tobj.parentNode, new_width); - xHeight(tobj.parentNode, new_height); - - // 위젯 리사이즈 (좌측) - } else if(tobj.className == 'widgetResizeLeft' || tobj.className == 'widgetBoxResizeLeft') { - - if(nx < zoneLeft) nx = zoneLeft; - - if(cssFloat == 'left') nx = sx; - - var new_width = pWidth + (sx - nx); - if(new_width < minWidth) new_width = minWidth; - - var new_height = ny - sy; - if(new_height < minHeight) new_height = minHeight; - - // 위젯의 크기 조절 - xWidth(tobj.nextSibling, new_width); - xHeight(tobj.nextSibling, new_height); - - xWidth(tobj.parentNode, new_width); - xHeight(tobj.parentNode, new_height); - - // 위젯 드래그 - } else { - var obj = widgetGetTmpObject(tobj); - - xLeft(obj, parseInt(xPageX(obj),10) + parseInt(dx,10)); - xTop(obj, parseInt(xPageY(obj),10) + parseInt(dy,10)); - - // 박스 안에 있을 경우에는 박스내의 위젯하고 자리를 바꾸고 그 외의 경우에는 박스를 빠져 나간다 - if(tobj.parentNode != zonePageObj) { - // 박스내에 있는 위젯들을 구함 - var widgetList = xGetElementsByClassName("widgetOutput",tobj.parentNode); - - for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt && tobj.parentNode == target_obj.parentNode) { - var next1 = target_obj.nextSibling; - if(!next1) { - next1 = xCreateElement("DIV"); - target_obj.parentNode.appendChild(next1); - } - var next2 = tobj.nextSibling; - if(!next2) { - next2 = xCreateElement("DIV"); - tobj.parentNode.appendChild(next2); - } - - if(next1) next1.parentNode.insertBefore(tobj, next1); - if(next2) next2.parentNode.insertBefore(target_obj, next2); - doFitBorderSize(); - widgetList = null; - return; - } - } - widgetList = null; - - // 만약 다른 위젯과 자리를 바꾸지 못하였는데 자기 부모창밖에 있는게 확인이 되면 박스 밖으로 내보낸다. - var p_tobj = jQuery(tobj).parents('div.nullWidget').get(0); - var l = xPageX(p_tobj); - var t = xPageY(p_tobj); - var ll = parseInt(l,10) + parseInt(xWidth(p_tobj),10); - var tt = parseInt(t,10) + parseInt(xHeight(p_tobj),10); - if( (tobj.xDPX < l || tobj.xDPX > ll) || (tobj.xDPY < t || tobj.xDPY > tt) ) { - -// zonePageObj.insertBefore(tobj, tobj.parentNode.parentNode.parentNode); - zonePageObj.insertBefore(tobj, jQuery(tobj).parents('div.widgetOutput[widget=widgetBox]').get(0)); - - doFitBorderSize(); - return; - } - - // 박스 밖에 있을 경우에는 다른 위젯과 자리를 바꾸거나 박스내에 들어가도록 한다 - } else { - // 이동하려는 위젯이 박스 위젯이 아니라면 박스 위젯들을 구해서 입력 유무를 검사한다 - if(tobj.getAttribute("widget")!="widgetBox") { - - var boxList = xGetElementsByClassName("nullWidget", zonePageObj); - for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt) { - - //박스 위젯이다 - if(target_obj.className == "nullWidget") { - - var wb_ws = jQuery('div.widget_inner',jQuery(target_obj)); - - //박스 위젯에 위젯스타일이 적용 안된경우 - if(wb_ws.size() == 0){ - target_obj.appendChild(tobj); - - //박스 위젯에 위젯스타일이 적용된경우 또는 박스안에 위젯이 위젯스타일이 적용된겅우 - }else{ - wb_ws.get(0).appendChild(tobj); - } - - // 이동을 멈춤 - widgetManualEnd(); - - doFitBorderSize(); - boxList = null; - return; - } - } - } - boxList = null; - } - - // 다른 위젯들을 구해서 자리를 바꿈 - var widgetList = xGetElementsByClassName("widgetOutput",zonePageObj); - for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt && tobj.parentNode == target_obj.parentNode) { - var next1 = target_obj.nextSibling; - if(!next1) next1 = target_obj.parentNode.lastChild; - if(!next1) { - next1 = xCreateElement("DIV"); - target_obj.parentNode.appendChild(next1); - } - var next2 = tobj.nextSibling; - if(!next2) { - next2 = xCreateElement("DIV"); - tobj.parentNode.appendChild(next2); - } - - if(next1) next1.parentNode.insertBefore(tobj, next1); - if(next2) next2.parentNode.insertBefore(target_obj, next2); - doFitBorderSize(); - widgetList = null; - return; - } - } - widgetList = null; - } - } -} - -// 드래그 종료 (이동되는 object가 이동할 곳에 서서히 이동되는 것처럼 보이는 효과) -function widgetDragEnd(tobj, px, py) { - var obj = widgetGetTmpObject(tobj); - widgetDisapear = widgetDisapearObject(obj, tobj); - widgetDragDisable(tobj.getAttribute('id')); -} - -// 스르르 사라지게 함 (일단 사라지게 하는 기능을 제거.. 속도 문제) -function widgetDisapearObject(obj, tobj) { - xInnerHtml(tobj,xInnerHtml(obj)); - xInnerHtml(obj,''); - xDisplay(obj, 'none'); - obj.parentNode.removeChild(obj); - widgetTmpObject[tobj.id] = null; - return; - - /* - var it = 5; - var ib = 1; - - var x = parseInt(xPageX(obj),10); - var y = parseInt(xPageY(obj),10); - var ldt = (x - parseInt(xPageX(tobj),10)) / ib; - var tdt = (y - parseInt(xPageY(tobj),10)) / ib; - - return setInterval(function() { - if(ib < 1) { - clearInterval(widgetDisapear); - xInnerHtml(tobj,xInnerHtml(obj)); - xInnerHtml(obj,''); - xDisplay(obj, 'none'); - obj.parentNode.removeChild(obj); - widgetTmpObject[tobj.id] = null; - return; - } - ib -= 5; - x-=ldt; - y-=tdt; - xLeft(obj, x); - xTop(obj, y); - }, it/ib); - */ -} - -// 마우스다운 이벤트 발생시 호출됨 -function widgetMouseDown(e) { - var evt = new xEvent(e); - var obj = evt.target; - - while(obj && !obj.draggable) { - obj = xParent(obj, true); - } - if(obj) { - xPreventDefault(e); - obj.xDPX = evt.pageX; - obj.xDPY = evt.pageY; - widgetDragManager.obj = obj; - xAddEventListener(document, 'mouseup', widgetMouseUp, false); - if (obj.dragStart) obj.dragStart(obj, evt.pageX, evt.pageY); - } -} - -// 마우스 버튼을 놓았을때 동작될 함수 (각종 이벤트 해제 및 변수 설정 초기화) -function widgetMouseUp(e) { - if (widgetDragManager.obj) { - xPreventDefault(e); - xRemoveEventListener(document, 'mouseup', widgetMouseUp, false); - - if (widgetDragManager.obj.dragEnd) { - var evt = new xEvent(e); - widgetDragManager.obj.dragEnd(widgetDragManager.obj, evt.pageX, evt.pageY); - } - - widgetDragManager.obj = null; - widgetDragManager.isDrag = false; - } -} - -// 드래그할때의 object이동등을 담당 -function widgetDragMouseMove(e) { - var evt = new xEvent(e); - if(widgetDragManager.obj) { - xPreventDefault(e); - - var obj = widgetDragManager.obj; - var dx = evt.pageX - obj.xDPX; - var dy = evt.pageY - obj.xDPY; - - obj.xDPX = evt.pageX; - obj.xDPY = evt.pageY; - - if (obj.drag) { - obj.drag(obj, dx, dy); - } else { - xMoveTo(obj, xLeft(obj) + dx, xTop(obj) + dy); - } - } -} - -// 해당 object 에 더 이상 drag가 되지 않도록 설정 -function widgetDragDisable(id) { - if (!widgetDragManager) return; - var obj = xGetElementById(id); - obj.draggable = false; - obj.dragStart = null; - obj.drag = null; - obj.dragEnd = null; - //obj.style.backgroundColor = obj.getAttribute('source_color'); - - xRemoveEventListener(obj, 'mousedown', widgetMouseDown, false); - - return; -} - -// 강제로 드래그를 종료시킴 -function widgetManualEnd() { - var tobj = widgetDragManager.obj; - if(!tobj) return; - - xRemoveEventListener(document, 'mouseup', widgetMouseUp, false); - xAddEventListener(document, 'mousemove', widgetDragMouseMove, false); - - var obj = widgetGetTmpObject(tobj); - widgetDisapear = widgetDisapearObject(obj, tobj); - widgetDragDisable(tobj.getAttribute('id')); - - widgetDragManager.obj = null; - widgetDragManager.isDrag = false; -} +/** + * @file modules/widget/js/widget.js + * @author NHN (developers@xpressengine.com) + * @brief 위젯 관리용 자바스크립트 + **/ + +/* DOM 속성을 구하기 위한 몇가지 함수들.. */ +// style의 값을 구하는게 IE랑 그외가 다름. +function getStyle(obj) { + var style = obj.getAttribute("style"); + if(!style) + { + style = obj.style; + } + if(typeof(style)=="object") style = style["cssText"]; + return style; +} + +// float: 값을 구하는게 IE랑 그외가 다름 +function getFloat(obj) { + var cssFloat = xIE4Up?obj.style.styleFloat:obj.style.cssFloat; + if(!cssFloat) cssFloat = 'left'; + return cssFloat; +} +function setFloat(obj, fl) { + if(xIE4Up) obj.style.styleFloat = fl; + else obj.style.cssFloat = fl; +} + +// padding값을 구하는 함수 (없을 경우 0으로 세팅), zbxe의 위젯에서만 사용 +function getPadding(obj, direct) { + var padding = obj.getAttribute("widget_padding_"+direct); + if(!padding || padding == null) padding = 0; + return padding; +} + + +/* 위젯 핸들링 시작 */ +var zonePageObj = null; +var zoneModuleSrl = 0; +function doStartPageModify(zoneID, module_srl) { + zonePageObj = xGetElementById(zoneID); + zoneModuleSrl = module_srl; + + // 위젯 크기/여백 조절 레이어를 가장 밖으로 뺌 + jQuery('#tmpPageSizeLayer') + .attr('id', 'pageSizeLayer') + .css({position:'absolute',left:0,top:0}) + .hide() + .appendTo('body') + .find('>form') + .submit(function(){ doApplyWidgetSize(this); return false; }); + + // 모든 위젯들의 크기를 정해진 크기로 맞춤 + doFitBorderSize(); + + // 드래그와 리사이즈와 관련된 이벤트 리스너 생성 + xAddEventListener(document,"click",doCheckWidget); + xAddEventListener(document,"mousedown",doCheckWidgetDrag); + xAddEventListener(document,'mouseover',widgetSetup); +} + + +// 내용 모두 삭제 +function removeAllWidget() { + if(!confirm(confirm_delete_msg)) return; + restoreWidgetButtons(); + xInnerHtml(zonePageObj,''); +} + +/** + * 특정 영역에 편집된 위젯들을 약속된 태그로 변환하여 return + **/ +function getWidgetContent(obj) { + var html = ""; + if(typeof(obj)=='undefined' || !obj) obj = zonePageObj; + + var widget = null; + jQuery('div.widgetOutput',obj).each(function(){ + if(jQuery(this).parent().get(0) != obj) return; + widget = jQuery(this).attr('widget'); + switch(widget) { + case 'widgetBox' : + html += getWidgetBoxCode(this, widget); + break; + case 'widgetContent' : + html += getContentWidgetCode(this, widget); + break; + default : + html += getWidgetCode(this, widget); + break; + } + }); + + return html; +} + +// 컨텐츠 위젯 코드 구함 +function getContentWidgetCode(childObj, widget) { + var cobj = childObj.firstChild; + + var widgetContent = jQuery('div.widgetContent',childObj); + var body = ''; + var document_srl = 0; + var attrs =''; + + if(widgetContent.size() > 0){ + document_srl = jQuery(childObj).attr('document_srl'); + if(document_srl>0){ + body = ''; + }else{ + body = widgetContent.html(); + } + + + for(var i=0;i'; + }else{ + return ''; + } +} + +// 위젯 박스 코드 구함 +function getWidgetBoxCode(childObj, widget) { + + var attrs = ""; + for(var i=0;i0){ + o = jQuery('.widget_inner',childObj); + o = o.get(0); + }else{ + o = jQuery('.nullWidget',childObj).get(0); + } + + var body = getWidgetContent(o); + return '
'+body+'
'; + +/* + var cobj = childObj.firstChild; + while(cobj) { + if(cobj.className == "widgetBorder" || cobj.className == "widgetBoxBorder") { + var c2obj = cobj.firstChild; + while(c2obj) { + if(c2obj.className == "nullWidget") { + var body = getWidgetContent(c2obj); + return '
'+body+'
'; + } + c2obj = c2obj.nextSibling; + } + } + cobj = cobj.nextSibling; + } +*/ +} + + + + +// 일반 위젯 컨텐츠 코드 구함 +function getWidgetCode(childObj, widget) { + var attrs = ""; + var code = ""; + for(var i=0;i'; +} + +/** + * 직접 내용을 입력하는 위젯을 추가 + **/ +// 팝업 띄움 +function doAddContent(mid) { + var url = request_uri.setQuery('module','widget').setQuery('act','dispWidgetAdminAddContent').setQuery('module_srl',zoneModuleSrl); + popopen(url, "addContent"); +} + +// 직접 내용을 입력하기 위한 에디터 활성화 작업 및 form 데이터 입력 +function doSyncPageContent() { + if(opener && opener.selectedWidget) { + + var fo_obj = xGetElementById("content_fo"); + var sel_obj = opener.selectedWidget; + fo_obj.style.value = getStyle(opener.selectedWidget); + fo_obj.widget_padding_left.value = getPadding(sel_obj, 'left'); + fo_obj.widget_padding_right.value = getPadding(sel_obj,'right'); + fo_obj.widget_padding_bottom.value = getPadding(sel_obj,'bottom'); + fo_obj.widget_padding_top.value = getPadding(sel_obj,'top'); + + var obj = sel_obj.firstChild; + while(obj && obj.className != "widgetContent") obj = obj.nextSibling; + if(obj && obj.className == "widgetContent") { + if(!fo_obj.document_srl || fo_obj.document_srl.value == 0) { + try { + var content = Base64.decode(xInnerHtml(obj)); + content = editorReplacePath(content); + xGetElementById("content_fo").content.value = content; + xe.Editors["1"].exec("SET_IR", [content]); + } + catch(e) + { + } + } + } + } + + if(typeof(editorStart)!='undefined') editorStart(1, "module_srl", "content", false, 400 ); + //editor_upload_start(1); + + setFixedPopupSize(); +} + +// 부모창에 위젯을 추가 +function addContentWidget(fo_obj) { + var editor_sequence = fo_obj.getAttribute('editor_sequence'); + var mid = fo_obj.mid.value; + var module_srl = fo_obj.module_srl.value; + var document_srl = fo_obj.document_srl.value; + var content = editorGetContent(editor_sequence); + var response_tags = new Array('error','message','document_srl'); + var params = new Array(); + params['editor_sequence'] = editor_sequence; + params['content'] = content; + params['module_srl'] = module_srl; + params['document_srl'] = document_srl; + exec_xml('widget',"procWidgetInsertDocument",params,completeAddContent,response_tags,params,fo_obj); + return false; + +} + +function completeAddContent(ret_obj, response_tags, params, fo_obj) { + var document_srl = ret_obj['document_srl']; + + var contentWidget = opener.jQuery('div.widgetOutput[widget=widgetContent][document_srl='+document_srl+']'); + var attr = null; + if(contentWidget.size()>0) { + attr = contentWidget.get(0).attributes; + } + + var editor_sequence = params['editor_sequence']; + var content = editorGetContent(editor_sequence); + + var tpl = ''+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+content+'
'+ + '
'+ + ''+ + '
'; + + var oTpl = jQuery(tpl); + if(attr) { + jQuery.each(attr,function(i){ + if(!oTpl.attr(attr[i].name)){ + oTpl.attr(attr[i].name,attr[i].value); + } + }); + } + + oTpl = jQuery('
').append(oTpl); + tpl = oTpl.html(); + opener.doAddWidgetCode(tpl); + window.close(); +} + +/* 박스 위젯 추가 */ +function doAddWidgetBox() { + var tpl = ''+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'+ + '
'; + xInnerHtml(zonePageObj, xInnerHtml(zonePageObj)+tpl); + doFitBorderSize(); +} + + +/* 일반 위젯을 추가하기 위해 위젯 팝업창을 띄움 */ +function doAddWidget(fo) { + var sel = fo.widget_list; + var idx = sel.selectedIndex; + var val = sel.options[idx].value; + var module_srl = fo.module_srl.value; + + var url = request_uri.setQuery('module','widget').setQuery('act','dispWidgetGenerateCodeInPage').setQuery('selected_widget', val).setQuery('module_srl', module_srl); + popopen(url,'GenerateWidgetCode'); +} + + + +// widgetBorder에 height를 widgetOutput와 맞춰줌 +function doFitBorderSize() { + var obj_list = xGetElementsByClassName('widgetBorder', zonePageObj); + for(var i=0;i-1) { + var pos = tmp.indexOf(""); + var cssfile = tmp.substr(9,eos-9); + if(cssfile.indexOf('.js')>-1) { + tmp = tmp.substr(eos); + continue; + } + if(!cssfile) break; + tmp = tmp.substr(eos); + + var cssfile = request_uri+'/'+cssfile; + if(typeof(document.createStyleSheet)=='undefined') { + var css =''; + var dummy = xCreateElement("DIV"); + xInnerHtml(dummy , css); + document.body.appendChild(dummy); + } else { + document.createStyleSheet(cssfile,0); + } + } + + // widget 코드에서 javascript 부분을 빼서 eval후 결과값을 대체함 + checkDocumentWrite = true; ///< document.write(ln)등의 함수값을 바로 사용하기 위한 check flag + + // widget_code의 javascript 부분 수정 + var tmp = widget_code.toLowerCase(); + while(tmp.indexOf("-1) { + + var pos = tmp.indexOf("")+9; + + var script = widget_code.substr(pos,length); + script = script.replace(/^]*)>/i,'').replace(/<\/script>$/i,''); + + writedText = null; + eval(script); + widget_code = widget_code.substr(0,pos)+writedText+widget_code.substr(pos+length); + tmp = widget_code.toLowerCase(); + } + + + + // html 추가 + var dummy = xCreateElement('div'); + xInnerHtml(dummy, widget_code); + var obj = dummy.childNodes[0]; + + if(selectedWidget && selectedWidget.getAttribute("widget")) { + var o = jQuery('div.widget_inner',selectedWidget); + var n = jQuery('div.widget_inner',obj); + + if(n.size()==0) n = jQuery('div.nullWidget',obj); + if(o.size()==0) o = jQuery('div.nullWidget',selectedWidget); + + n.html(o.html()); + + + selectedWidget.parentNode.insertBefore(obj, selectedWidget); + selectedWidget.parentNode.removeChild(selectedWidget); + } else { + xGetElementById('zonePageContent').appendChild(obj); + } + checkDocumentWrite = false; + selectedWidget = null; + + /* + //zoneObj.style.visibility = 'hidden'; + zoneObj.style.opacity = 0.2; + zoneObj.style.filter = "alpha(opacity=20)"; + + // 위젯 추가후 페이지 리로딩 + var tpl = getWidgetContent(); + + var fo_obj = xGetElementById('pageFo'); + fo_obj.content.value = tpl; + fo_obj.mid.value = current_mid; + fo_obj.submit(); + */ +} + +// 클릭 이벤트시 위젯의 수정/제거/이벤트 무효화 처리 +function doCheckWidget(e) { + var evt = new xEvent(e); if(!evt.target) return; + var obj = evt.target; + + selectedWidget = null; + + var pObj = obj.parentNode; + while(pObj) { + if(pObj.id == "pageSizeLayer") return; + pObj = pObj.parentNode; + } + + doHideWidgetSizeSetup(); + // 위젯 설정 + if(obj.className == 'widgetSetup') { + var p_obj = obj.parentNode.parentNode; + var widget = p_obj.getAttribute("widget"); + if(!widget) return; + selectedWidget = p_obj; + if(widget == 'widgetContent') popopen(request_uri+"?module=widget&act=dispWidgetAdminAddContent&module_srl="+zoneModuleSrl+"&document_srl="+p_obj.getAttribute("document_srl"), "addContent"); + else popopen(request_uri+"?module=widget&act=dispWidgetGenerateCodeInPage&selected_widget="+widget+"&widgetstyle="+widgetstyle,'GenerateCodeInPage'); + return; + + // 위젯 스타일 + } else if(obj.className == 'widgetStyle') { + var p_obj = obj.parentNode.parentNode; + var widget = p_obj.getAttribute("widget"); + var widgetstyle = p_obj.getAttribute("widgetstyle"); + if(!widget) return; + selectedWidget = p_obj; + popopen(request_uri+"?module=widget&act=dispWidgetStyleGenerateCodeInPage&selected_widget="+widget+"&widgetstyle="+widgetstyle,'GenerateCodeInPage'); + return; + + // 위젯 복사 + } else if(obj.className == 'widgetCopy' && obj.parentNode.parentNode.className == 'widgetOutput') { + p_obj = obj.parentNode.parentNode; + restoreWidgetButtons(); + + if(p_obj.getAttribute('widget')=='widgetContent' && p_obj.getAttribute('document_srl') ) { + var response_tags = new Array('error','message','document_srl'); + var params = new Array(); + params['document_srl'] =p_obj.getAttribute('document_srl'); + exec_xml('widget','procWidgetCopyDocument', params, completeCopyWidgetContent, response_tags, params, p_obj); + return; + } else { + var dummy = xCreateElement("DIV"); + xInnerHtml(dummy,xInnerHtml(p_obj)); + + dummy.widget_sequence = ''; + dummy.className = "widgetOutput"; + for(var i=0;i 0) return; + + doHideWidgetSizeSetup(); + + if(obj.className == 'widgetSetup' || obj.className == 'widgetStyle' || obj.className == 'widgetCopy' || obj.className == 'widgetBoxCopy' || obj.className == 'widgetSize' || obj.className == 'widgetBoxSize' || obj.className == 'widgetRemove' || obj.className == 'widgetBoxRemove') return; + + p_obj = obj; + while(p_obj) { + if(p_obj.className == 'widgetOutput' || p_obj.className == 'widgetResize' || p_obj.className == 'widgetResizeLeft' || p_obj.className == 'widgetBoxResize' || p_obj.className == 'widgetBoxResizeLeft') { + widgetDragEnable(p_obj, widgetDragStart, widgetDrag, widgetDragEnd); + widgetMouseDown(e); + return; + } + p_obj = p_obj.parentNode; + } +} + +function _getInt(val) { + if(!val || val == "null") return 0; + if(parseInt(val,10)==NaN) return 0; + return parseInt(val,10); +} + +// 위젯 크기 조절 레이어를 보여줌 +var selectedSizeWidget = null; +function doShowWidgetSizeSetup(px, py, obj) { + var layer = jQuery('#pageSizeLayer'); + var form = layer.find('>form:first'); + var obj = jQuery(obj); + + if (!form.length) return; + + selectedSizeWidget = obj[0]; + + var opts = { + widget_align : obj.css('float'), + + width : obj[0].style.width, + height : obj[0].style.height, + + padding_left : _getInt(obj.attr('widget_padding_left')), + padding_right : _getInt(obj.attr('widget_padding_right')), + padding_top : _getInt(obj.attr('widget_padding_top')), + padding_bottom : _getInt(obj.attr('widget_padding_bottom')), + + margin_left : _getInt(obj[0].style.marginLeft), + margin_right : _getInt(obj[0].style.marginRight), + margin_top : _getInt(obj[0].style.marginTop), + margin_bottom : _getInt(obj[0].style.marginBottom), + + border_top_color : transRGB2Hex(obj[0].style.borderTopColor), + border_top_thick : obj[0].style.borderTopWidth.replace(/px$/i, ''), + border_top_type : obj[0].style.borderTopStyle, + + border_bottom_color : transRGB2Hex(obj[0].style.borderBottomColor), + border_bottom_thick : obj[0].style.borderBottomWidth.replace(/px$/i, ''), + border_bottom_type : obj[0].style.borderBottomStyle, + + border_right_color : transRGB2Hex(obj[0].style.borderRightColor), + border_right_thick : obj[0].style.borderRightWidth.replace(/px$/i, ''), + border_right_type : obj[0].style.borderRightStyle, + + border_left_color : transRGB2Hex(obj[0].style.borderLeftColor), + border_left_thick : obj[0].style.borderLeftWidth.replace(/px$/i, ''), + border_left_type : obj[0].style.borderLeftStyle, + + background_color : transRGB2Hex(obj[0].style.backgroundColor), + background_image_url : obj[0].style.backgroundImage.replace(/^url\(/i,'').replace(/\)$/i,''), + + background_x : 0, + background_y : 0, + + background_repeat : obj[0].style.backgroundRepeat + }; + + // background position + var pos = obj[0].style.backgroundPosition; + if(pos) { + pos = pos.split(' '); + if(pos.length == 2) { + opts.background_x = pos[0]; + opts.background_y = pos[1]; + } + } + + layer.css('top', py+'px').show(); + var _zonePageObj = jQuery(zonePageObj) + var zoneOffsetLeft = _zonePageObj.offset().left; + var zoneWidth = _zonePageObj.width(); + if (px + layer.width() > zoneOffsetLeft + zoneWidth) px = zoneOffsetLeft + zoneWidth - layer.width() - 5; + layer.css('left', px+'px'); + + jQuery.each(opts, function(key, val){ + var el = form[0].elements[key]; + if (el) el.value = val; + if (el.tagName.toLowerCase() == "select") + { + if(el.selectedIndex == -1) { + el.selectedIndex = 0; + } + } + }); + + try { form[0].elements[0].focus() } catch(e) {}; +} + +function doHideWidgetSizeSetup() { + jQuery('#pageSizeLayer').hide(); + //var layer = xGetElementById("pageSizeLayer"); + //layer.style.visibility = "hidden"; + //layer.style.display = "none"; +} + +function _getSize(value) { + if(!value) return 0; + var type = "px"; + if(value.lastIndexOf("%")>=0) type = "%"; + var num = parseInt(value,10); + if(num<1) return 0; + if(type == "%" && num > 100) num = 100; + return ""+num+type; +} + +function _getBorderStyle(fld_color, fld_thick, fld_type) { + var color = fld_color.value; + color = color.replace(/^#/,''); + if(!color) color = '#FFFFFF'; + else color = '#'+color; + var width = fld_thick.value; + if(!width) width = '0px'; + else width = parseInt(width,10)+'px'; + var style = fld_type.options[fld_type.selectedIndex].value; + if(!style) style = 'solid'; + + var str = color+' '+width+' '+style; + return str; +} + +function _getBGColorStyle(fld_color) { + var color = fld_color.replace(/^#/,''); + if(!color) color = '#FFFFFF'; + else color = '#'+color; + return color; +} + +function doApplyWidgetSize(fo_obj) { + if(selectedSizeWidget) { + if(fo_obj.widget_align.selectedIndex == 1) setFloat(selectedSizeWidget, 'right'); + else setFloat(selectedSizeWidget, 'left'); + + var width = _getSize(fo_obj.width.value); + if(width) selectedSizeWidget.style.width = width; + + var height = _getSize(fo_obj.height.value); + if(height && height != "100%") selectedSizeWidget.style.height = height; + else { + selectedSizeWidget.style.height = ''; + var widgetBorder = xGetElementsByClassName('widgetBorder',selectedSizeWidget); + for(var i=0;i 0) return; + if(jQuery(obj).is('.buttonBox') || jQuery(obj).parents('.buttonBox').size() > 0) return; + + + var o = jQuery(obj).parents('.widgetOutput'); + if(o.size() == 0){ + restoreWidgetButtons(); + return; + } + /* + if(!obj || typeof(obj.className)=='undefined' || obj.className != 'widgetOutput') { + restoreWidgetButtons(); + return; + } +*/ + + obj = o.get(0); + var widget = o.attr('widget'); + if(!widget) return; + + if(widget == 'widgetBox') { + restoreWidgetButtons(); + showWidgetButton('widgetBoxButton', obj); + } else { + restoreWidgetButtons(); + showWidgetButton('widgetButton', obj); + + var p_obj = obj.parentNode; + if(p_obj) { + while(p_obj) { + if(p_obj.nodeName == 'DIV' && p_obj.getAttribute('widget')=='widgetBox') { + showWidgetButton('widgetBoxButton', p_obj); + break; + } + p_obj = p_obj.parentNode; + } + } + } +} + +/* 위젯 드래그 */ +// 드래그 중이라는 상황을 간직할 변수 +var widgetDragManager = {obj:null, isDrag:false} +var widgetTmpObject = new Array(); +var widgetDisappear = 0; + +function widgetCreateTmpObject(obj) { + var id = obj.getAttribute('id'); + + tmpObj = xCreateElement('DIV'); + tmpObj.id = id + '_tmp'; + tmpObj.className = obj.className; + tmpObj.style.overflow = 'hidden'; + tmpObj.style.margin= '0px'; + tmpObj.style.padding = '0px'; + tmpObj.style.width = obj.style.width; + + tmpObj.style.display = 'none'; + tmpObj.style.position = 'absolute'; + tmpObj.style.opacity = 1; + tmpObj.style.filter = 'alpha(opacity=100)'; + + xLeft(tmpObj, xPageX(obj)); + xTop(tmpObj, xPageY(obj)); + + document.body.appendChild(tmpObj); + widgetTmpObject[obj.id] = tmpObj; + return tmpObj; +} + +// 기생성된 임시 object를 찾아서 return, 없으면 만들어서 return +var idStep = 0; +function widgetGetTmpObject(obj) { + if(!obj.id) obj.id = 'widget_'+idStep++; + var tmpObj = widgetTmpObject[obj.id]; + if(!tmpObj) tmpObj = widgetCreateTmpObject(obj); + return tmpObj; +} + +// 메뉴에 마우스 클릭이 일어난 시점에 드래그를 위한 제일 첫 동작 (해당 object에 각종 함수나 상태변수 설정) +function widgetDragEnable(obj, funcDragStart, funcDrag, funcDragEnd) { + + // 상위 object에 드래그 가능하다는 상태와 각 드래그 관련 함수를 설정 + obj.draggable = true; + obj.dragStart = funcDragStart; + obj.drag = funcDrag; + obj.dragEnd = funcDragEnd; + + // 드래그 가능하지 않다면 드래그 가능하도록 상태 지정하고 mousemove이벤트 등록 + if (!widgetDragManager.isDrag) { + widgetDragManager.isDrag = true; + xAddEventListener(document, 'mousemove', widgetDragMouseMove, false); + } +} + +// 드래그를 시작할때 호출되는 함수 (이동되는 형태를 보여주기 위한 작업을 함) +function widgetDragStart(tobj, px, py) { + if(tobj.className == 'widgetResize' || tobj.className == 'widgetResizeLeft' || tobj.className == 'widgetBoxResize' || tobj.className == 'widgetBoxResizeLeft') return; + var obj = widgetGetTmpObject(tobj); + + xInnerHtml(obj, xInnerHtml(tobj)); + + xLeft(obj, xPageX(tobj)); + xTop(obj, xPageY(tobj)); + xWidth(obj, xWidth(tobj)); + xHeight(obj, xHeight(tobj)); + + xDisplay(obj, 'block'); +} + +// 드래그 시작후 마우스를 이동할때 발생되는 이벤트에 의해 실행되는 함수 +function widgetDrag(tobj, dx, dy) { + var minWidth = 40; + var minHeight = 10; + + var sx = xPageX(tobj.parentNode); + var sy = xPageY(tobj.parentNode); + + var nx = tobj.xDPX; + var ny = tobj.xDPY; + + var zoneWidth = xWidth(zonePageObj); + var zoneLeft = xPageX(zonePageObj); + var zoneRight = zoneLeft + zoneWidth; + + var pWidth = xWidth(tobj.parentNode); + + var cssFloat = getFloat(tobj.parentNode); + if(!cssFloat) cssFloat = 'left'; + + // 위젯 리사이즈 (우측) + if(tobj.className == 'widgetResize' || tobj.className == 'widgetBoxResize') { + if(nx < sx+minWidth) nx = sx+minWidth; + if(nx > zoneRight) nx = zoneRight; + + if(cssFloat == 'right') nx = sx + pWidth; + + var new_width = nx - sx; + if(new_width < minWidth) new_width = minWidth; + + var new_height = ny - sy; + if(new_height < minHeight) new_height = minHeight; + + if( zoneRight < sx+new_width) new_width = zoneRight - sx; + + // 위젯의 크기 조절 + xWidth(tobj.nextSibling.nextSibling, new_width); + xHeight(tobj.nextSibling.nextSibling, new_height); + + xWidth(tobj.parentNode, new_width); + xHeight(tobj.parentNode, new_height); + + // 위젯 리사이즈 (좌측) + } else if(tobj.className == 'widgetResizeLeft' || tobj.className == 'widgetBoxResizeLeft') { + + if(nx < zoneLeft) nx = zoneLeft; + + if(cssFloat == 'left') nx = sx; + + var new_width = pWidth + (sx - nx); + if(new_width < minWidth) new_width = minWidth; + + var new_height = ny - sy; + if(new_height < minHeight) new_height = minHeight; + + // 위젯의 크기 조절 + xWidth(tobj.nextSibling, new_width); + xHeight(tobj.nextSibling, new_height); + + xWidth(tobj.parentNode, new_width); + xHeight(tobj.parentNode, new_height); + + // 위젯 드래그 + } else { + var obj = widgetGetTmpObject(tobj); + + xLeft(obj, parseInt(xPageX(obj),10) + parseInt(dx,10)); + xTop(obj, parseInt(xPageY(obj),10) + parseInt(dy,10)); + + // 박스 안에 있을 경우에는 박스내의 위젯하고 자리를 바꾸고 그 외의 경우에는 박스를 빠져 나간다 + if(tobj.parentNode != zonePageObj) { + // 박스내에 있는 위젯들을 구함 + var widgetList = xGetElementsByClassName("widgetOutput",tobj.parentNode); + + for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt && tobj.parentNode == target_obj.parentNode) { + var next1 = target_obj.nextSibling; + if(!next1) { + next1 = xCreateElement("DIV"); + target_obj.parentNode.appendChild(next1); + } + var next2 = tobj.nextSibling; + if(!next2) { + next2 = xCreateElement("DIV"); + tobj.parentNode.appendChild(next2); + } + + if(next1) next1.parentNode.insertBefore(tobj, next1); + if(next2) next2.parentNode.insertBefore(target_obj, next2); + doFitBorderSize(); + widgetList = null; + return; + } + } + widgetList = null; + + // 만약 다른 위젯과 자리를 바꾸지 못하였는데 자기 부모창밖에 있는게 확인이 되면 박스 밖으로 내보낸다. + var p_tobj = jQuery(tobj).parents('div.nullWidget').get(0); + var l = xPageX(p_tobj); + var t = xPageY(p_tobj); + var ll = parseInt(l,10) + parseInt(xWidth(p_tobj),10); + var tt = parseInt(t,10) + parseInt(xHeight(p_tobj),10); + if( (tobj.xDPX < l || tobj.xDPX > ll) || (tobj.xDPY < t || tobj.xDPY > tt) ) { + +// zonePageObj.insertBefore(tobj, tobj.parentNode.parentNode.parentNode); + zonePageObj.insertBefore(tobj, jQuery(tobj).parents('div.widgetOutput[widget=widgetBox]').get(0)); + + doFitBorderSize(); + return; + } + + // 박스 밖에 있을 경우에는 다른 위젯과 자리를 바꾸거나 박스내에 들어가도록 한다 + } else { + // 이동하려는 위젯이 박스 위젯이 아니라면 박스 위젯들을 구해서 입력 유무를 검사한다 + if(tobj.getAttribute("widget")!="widgetBox") { + + var boxList = xGetElementsByClassName("nullWidget", zonePageObj); + for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt) { + + //박스 위젯이다 + if(target_obj.className == "nullWidget") { + + var wb_ws = jQuery('div.widget_inner',jQuery(target_obj)); + + //박스 위젯에 위젯스타일이 적용 안된경우 + if(wb_ws.size() == 0){ + target_obj.appendChild(tobj); + + //박스 위젯에 위젯스타일이 적용된경우 또는 박스안에 위젯이 위젯스타일이 적용된겅우 + }else{ + wb_ws.get(0).appendChild(tobj); + } + + // 이동을 멈춤 + widgetManualEnd(); + + doFitBorderSize(); + boxList = null; + return; + } + } + } + boxList = null; + } + + // 다른 위젯들을 구해서 자리를 바꿈 + var widgetList = xGetElementsByClassName("widgetOutput",zonePageObj); + for(var i=0;i= l && tobj.xDPX <= ll && tobj.xDPY >= t && tobj.xDPY <= tt && tobj.parentNode == target_obj.parentNode) { + var next1 = target_obj.nextSibling; + if(!next1) next1 = target_obj.parentNode.lastChild; + if(!next1) { + next1 = xCreateElement("DIV"); + target_obj.parentNode.appendChild(next1); + } + var next2 = tobj.nextSibling; + if(!next2) { + next2 = xCreateElement("DIV"); + tobj.parentNode.appendChild(next2); + } + + if(next1) next1.parentNode.insertBefore(tobj, next1); + if(next2) next2.parentNode.insertBefore(target_obj, next2); + doFitBorderSize(); + widgetList = null; + return; + } + } + widgetList = null; + } + } +} + +// 드래그 종료 (이동되는 object가 이동할 곳에 서서히 이동되는 것처럼 보이는 효과) +function widgetDragEnd(tobj, px, py) { + var obj = widgetGetTmpObject(tobj); + widgetDisapear = widgetDisapearObject(obj, tobj); + widgetDragDisable(tobj.getAttribute('id')); +} + +// 스르르 사라지게 함 (일단 사라지게 하는 기능을 제거.. 속도 문제) +function widgetDisapearObject(obj, tobj) { + xInnerHtml(tobj,xInnerHtml(obj)); + xInnerHtml(obj,''); + xDisplay(obj, 'none'); + obj.parentNode.removeChild(obj); + widgetTmpObject[tobj.id] = null; + return; + + /* + var it = 5; + var ib = 1; + + var x = parseInt(xPageX(obj),10); + var y = parseInt(xPageY(obj),10); + var ldt = (x - parseInt(xPageX(tobj),10)) / ib; + var tdt = (y - parseInt(xPageY(tobj),10)) / ib; + + return setInterval(function() { + if(ib < 1) { + clearInterval(widgetDisapear); + xInnerHtml(tobj,xInnerHtml(obj)); + xInnerHtml(obj,''); + xDisplay(obj, 'none'); + obj.parentNode.removeChild(obj); + widgetTmpObject[tobj.id] = null; + return; + } + ib -= 5; + x-=ldt; + y-=tdt; + xLeft(obj, x); + xTop(obj, y); + }, it/ib); + */ +} + +// 마우스다운 이벤트 발생시 호출됨 +function widgetMouseDown(e) { + var evt = new xEvent(e); + var obj = evt.target; + + while(obj && !obj.draggable) { + obj = xParent(obj, true); + } + if(obj) { + xPreventDefault(e); + obj.xDPX = evt.pageX; + obj.xDPY = evt.pageY; + widgetDragManager.obj = obj; + xAddEventListener(document, 'mouseup', widgetMouseUp, false); + if (obj.dragStart) obj.dragStart(obj, evt.pageX, evt.pageY); + } +} + +// 마우스 버튼을 놓았을때 동작될 함수 (각종 이벤트 해제 및 변수 설정 초기화) +function widgetMouseUp(e) { + if (widgetDragManager.obj) { + xPreventDefault(e); + xRemoveEventListener(document, 'mouseup', widgetMouseUp, false); + + if (widgetDragManager.obj.dragEnd) { + var evt = new xEvent(e); + widgetDragManager.obj.dragEnd(widgetDragManager.obj, evt.pageX, evt.pageY); + } + + widgetDragManager.obj = null; + widgetDragManager.isDrag = false; + } +} + +// 드래그할때의 object이동등을 담당 +function widgetDragMouseMove(e) { + var evt = new xEvent(e); + if(widgetDragManager.obj) { + xPreventDefault(e); + + var obj = widgetDragManager.obj; + var dx = evt.pageX - obj.xDPX; + var dy = evt.pageY - obj.xDPY; + + obj.xDPX = evt.pageX; + obj.xDPY = evt.pageY; + + if (obj.drag) { + obj.drag(obj, dx, dy); + } else { + xMoveTo(obj, xLeft(obj) + dx, xTop(obj) + dy); + } + } +} + +// 해당 object 에 더 이상 drag가 되지 않도록 설정 +function widgetDragDisable(id) { + if (!widgetDragManager) return; + var obj = xGetElementById(id); + obj.draggable = false; + obj.dragStart = null; + obj.drag = null; + obj.dragEnd = null; + //obj.style.backgroundColor = obj.getAttribute('source_color'); + + xRemoveEventListener(obj, 'mousedown', widgetMouseDown, false); + + return; +} + +// 강제로 드래그를 종료시킴 +function widgetManualEnd() { + var tobj = widgetDragManager.obj; + if(!tobj) return; + + xRemoveEventListener(document, 'mouseup', widgetMouseUp, false); + xAddEventListener(document, 'mousemove', widgetDragMouseMove, false); + + var obj = widgetGetTmpObject(tobj); + widgetDisapear = widgetDisapearObject(obj, tobj); + widgetDragDisable(tobj.getAttribute('id')); + + widgetDragManager.obj = null; + widgetDragManager.isDrag = false; +} diff --git a/modules/widget/tpl/js/widget_admin.js b/modules/widget/tpl/js/widget_admin.js index cab29a5ce..8c5e312ff 100644 --- a/modules/widget/tpl/js/widget_admin.js +++ b/modules/widget/tpl/js/widget_admin.js @@ -1,470 +1,470 @@ -/** - * @file modules/widget/js/widget_admin.js - * @author zero (zero@nzeo.com) - * @brief widget 모듈의 관리자용 javascript - **/ - -/* 생성된 코드를 textarea에 출력 */ -function completeGenerateCode(ret_obj) { - var widget_code = ret_obj["widget_code"]; - widget_code = widget_code.replace(/&/g, "&"); - widget_code = widget_code.replace(/\'/g, "'"); - var zone = xGetElementById("widget_code"); - zone.value = widget_code; -} - -/* 생성된 코드를 페이지 zone에 출력 */ -function completeGenerateCodeInPage(ret_obj,response_tags,params,fo_obj) { - var widget_code = ret_obj["widget_code"]; - if(!opener || !widget_code) { - window.close(); - return; - } - - opener.doAddWidgetCode(widget_code); - window.close(); -} - -/* 위젯 코드 생성시 스킨을 고르면 컬러셋의 정보를 표시 */ -function doDisplaySkinColorset(sel, colorset) { - var skin = sel.options[sel.selectedIndex].value; - if(!skin) { - xGetElementById("colorset_area").style.display = "none"; - setFixedPopupSize(); - return; - } - - var params = new Array(); - params["selected_widget"] = xGetElementById("fo_widget").selected_widget.value; - params["skin"] = skin; - params["colorset"] = colorset; - - var response_tags = new Array("error","message","colorset_list"); - - exec_xml("widget", "procWidgetGetColorsetList", params, completeGetSkinColorset, response_tags, params); -} - -/* 서버에서 받아온 컬러셋을 표시 */ -function completeGetSkinColorset(ret_obj, response_tags, params, fo_obj) { - var sel = jQuery("#fo_widget")[0].widget_colorset; - var length = sel.options.length; - var selected_colorset = params["colorset"]; - for(var i=0;i