From 81b1fd57527b945c1d416cdf36d9b46de8265d74 Mon Sep 17 00:00:00 2001 From: MinSoo Kim Date: Tue, 23 Feb 2016 00:56:05 +0900 Subject: [PATCH 001/318] support i18n jQuery-UI datepicker --- common/js/plugins/ui/i18n/datepicker-af.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ar-DZ.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ar.js | 38 ++++++++++ common/js/plugins/ui/i18n/datepicker-az.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-be.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-bg.js | 38 ++++++++++ common/js/plugins/ui/i18n/datepicker-bs.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ca.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-cs.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-cy-GB.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-da.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-de.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-el.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-en-AU.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-en-GB.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-en-NZ.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-eo.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-es.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-et.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-eu.js | 36 +++++++++ common/js/plugins/ui/i18n/datepicker-fa.js | 73 +++++++++++++++++++ common/js/plugins/ui/i18n/datepicker-fi.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-fo.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-fr-CA.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-fr-CH.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-fr.js | 39 ++++++++++ common/js/plugins/ui/i18n/datepicker-gl.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-he.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-hi.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-hr.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-hu.js | 36 +++++++++ common/js/plugins/ui/i18n/datepicker-hy.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-id.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-is.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-it-CH.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-it.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ja.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ka.js | 35 +++++++++ common/js/plugins/ui/i18n/datepicker-kk.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-km.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ko.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ky.js | 38 ++++++++++ common/js/plugins/ui/i18n/datepicker-lb.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-lt.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-lv.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-mk.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ml.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ms.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-nb.js | 36 +++++++++ common/js/plugins/ui/i18n/datepicker-nl-BE.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-nl.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-nn.js | 36 +++++++++ common/js/plugins/ui/i18n/datepicker-no.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-pl.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-pt-BR.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-pt.js | 36 +++++++++ common/js/plugins/ui/i18n/datepicker-rm.js | 35 +++++++++ common/js/plugins/ui/i18n/datepicker-ro.js | 40 ++++++++++ common/js/plugins/ui/i18n/datepicker-ru.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-sk.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-sl.js | 38 ++++++++++ common/js/plugins/ui/i18n/datepicker-sq.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-sr-SR.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-sr.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-sv.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-ta.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-th.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-tj.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-tr.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-uk.js | 38 ++++++++++ common/js/plugins/ui/i18n/datepicker-vi.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-zh-CN.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-zh-HK.js | 37 ++++++++++ common/js/plugins/ui/i18n/datepicker-zh-TW.js | 37 ++++++++++ common/js/plugins/ui/plugin.load | 2 +- common/js/plugins/ui/rx_datepicker.js | 7 ++ 76 files changed, 2783 insertions(+), 1 deletion(-) create mode 100644 common/js/plugins/ui/i18n/datepicker-af.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ar-DZ.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ar.js create mode 100644 common/js/plugins/ui/i18n/datepicker-az.js create mode 100644 common/js/plugins/ui/i18n/datepicker-be.js create mode 100644 common/js/plugins/ui/i18n/datepicker-bg.js create mode 100644 common/js/plugins/ui/i18n/datepicker-bs.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ca.js create mode 100644 common/js/plugins/ui/i18n/datepicker-cs.js create mode 100644 common/js/plugins/ui/i18n/datepicker-cy-GB.js create mode 100644 common/js/plugins/ui/i18n/datepicker-da.js create mode 100644 common/js/plugins/ui/i18n/datepicker-de.js create mode 100644 common/js/plugins/ui/i18n/datepicker-el.js create mode 100644 common/js/plugins/ui/i18n/datepicker-en-AU.js create mode 100644 common/js/plugins/ui/i18n/datepicker-en-GB.js create mode 100644 common/js/plugins/ui/i18n/datepicker-en-NZ.js create mode 100644 common/js/plugins/ui/i18n/datepicker-eo.js create mode 100644 common/js/plugins/ui/i18n/datepicker-es.js create mode 100644 common/js/plugins/ui/i18n/datepicker-et.js create mode 100644 common/js/plugins/ui/i18n/datepicker-eu.js create mode 100644 common/js/plugins/ui/i18n/datepicker-fa.js create mode 100644 common/js/plugins/ui/i18n/datepicker-fi.js create mode 100644 common/js/plugins/ui/i18n/datepicker-fo.js create mode 100644 common/js/plugins/ui/i18n/datepicker-fr-CA.js create mode 100644 common/js/plugins/ui/i18n/datepicker-fr-CH.js create mode 100644 common/js/plugins/ui/i18n/datepicker-fr.js create mode 100644 common/js/plugins/ui/i18n/datepicker-gl.js create mode 100644 common/js/plugins/ui/i18n/datepicker-he.js create mode 100644 common/js/plugins/ui/i18n/datepicker-hi.js create mode 100644 common/js/plugins/ui/i18n/datepicker-hr.js create mode 100644 common/js/plugins/ui/i18n/datepicker-hu.js create mode 100644 common/js/plugins/ui/i18n/datepicker-hy.js create mode 100644 common/js/plugins/ui/i18n/datepicker-id.js create mode 100644 common/js/plugins/ui/i18n/datepicker-is.js create mode 100644 common/js/plugins/ui/i18n/datepicker-it-CH.js create mode 100644 common/js/plugins/ui/i18n/datepicker-it.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ja.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ka.js create mode 100644 common/js/plugins/ui/i18n/datepicker-kk.js create mode 100644 common/js/plugins/ui/i18n/datepicker-km.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ko.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ky.js create mode 100644 common/js/plugins/ui/i18n/datepicker-lb.js create mode 100644 common/js/plugins/ui/i18n/datepicker-lt.js create mode 100644 common/js/plugins/ui/i18n/datepicker-lv.js create mode 100644 common/js/plugins/ui/i18n/datepicker-mk.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ml.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ms.js create mode 100644 common/js/plugins/ui/i18n/datepicker-nb.js create mode 100644 common/js/plugins/ui/i18n/datepicker-nl-BE.js create mode 100644 common/js/plugins/ui/i18n/datepicker-nl.js create mode 100644 common/js/plugins/ui/i18n/datepicker-nn.js create mode 100644 common/js/plugins/ui/i18n/datepicker-no.js create mode 100644 common/js/plugins/ui/i18n/datepicker-pl.js create mode 100644 common/js/plugins/ui/i18n/datepicker-pt-BR.js create mode 100644 common/js/plugins/ui/i18n/datepicker-pt.js create mode 100644 common/js/plugins/ui/i18n/datepicker-rm.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ro.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ru.js create mode 100644 common/js/plugins/ui/i18n/datepicker-sk.js create mode 100644 common/js/plugins/ui/i18n/datepicker-sl.js create mode 100644 common/js/plugins/ui/i18n/datepicker-sq.js create mode 100644 common/js/plugins/ui/i18n/datepicker-sr-SR.js create mode 100644 common/js/plugins/ui/i18n/datepicker-sr.js create mode 100644 common/js/plugins/ui/i18n/datepicker-sv.js create mode 100644 common/js/plugins/ui/i18n/datepicker-ta.js create mode 100644 common/js/plugins/ui/i18n/datepicker-th.js create mode 100644 common/js/plugins/ui/i18n/datepicker-tj.js create mode 100644 common/js/plugins/ui/i18n/datepicker-tr.js create mode 100644 common/js/plugins/ui/i18n/datepicker-uk.js create mode 100644 common/js/plugins/ui/i18n/datepicker-vi.js create mode 100644 common/js/plugins/ui/i18n/datepicker-zh-CN.js create mode 100644 common/js/plugins/ui/i18n/datepicker-zh-HK.js create mode 100644 common/js/plugins/ui/i18n/datepicker-zh-TW.js create mode 100644 common/js/plugins/ui/rx_datepicker.js diff --git a/common/js/plugins/ui/i18n/datepicker-af.js b/common/js/plugins/ui/i18n/datepicker-af.js new file mode 100644 index 000000000..c75688884 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-af.js @@ -0,0 +1,37 @@ +/* Afrikaans initialisation for the jQuery UI date picker plugin. */ +/* Written by Renier Pretorius. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.af = { + closeText: "Selekteer", + prevText: "Vorige", + nextText: "Volgende", + currentText: "Vandag", + monthNames: [ "Januarie","Februarie","Maart","April","Mei","Junie", + "Julie","Augustus","September","Oktober","November","Desember" ], + monthNamesShort: [ "Jan", "Feb", "Mrt", "Apr", "Mei", "Jun", + "Jul", "Aug", "Sep", "Okt", "Nov", "Des" ], + dayNames: [ "Sondag", "Maandag", "Dinsdag", "Woensdag", "Donderdag", "Vrydag", "Saterdag" ], + dayNamesShort: [ "Son", "Maa", "Din", "Woe", "Don", "Vry", "Sat" ], + dayNamesMin: [ "So","Ma","Di","Wo","Do","Vr","Sa" ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.af ); + +return datepicker.regional.af; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ar-DZ.js b/common/js/plugins/ui/i18n/datepicker-ar-DZ.js new file mode 100644 index 000000000..6035ce292 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ar-DZ.js @@ -0,0 +1,37 @@ +/* Algerian Arabic Translation for jQuery UI date picker plugin. (can be used for Tunisia)*/ +/* Mohamed Cherif BOUCHELAGHEM -- cherifbouchelaghem@yahoo.fr */ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "ar-DZ" ] = { + closeText: "إغلاق", + prevText: "<السابق", + nextText: "التالي>", + currentText: "اليوم", + monthNames: [ "جانفي", "فيفري", "مارس", "أفريل", "ماي", "جوان", + "جويلية", "أوت", "سبتمبر","أكتوبر", "نوفمبر", "ديسمبر" ], + monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ], + dayNames: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], + dayNamesShort: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], + dayNamesMin: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], + weekHeader: "أسبوع", + dateFormat: "dd/mm/yy", + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "ar-DZ" ] ); + +return datepicker.regional[ "ar-DZ" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ar.js b/common/js/plugins/ui/i18n/datepicker-ar.js new file mode 100644 index 000000000..025d98484 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ar.js @@ -0,0 +1,38 @@ +/* Arabic Translation for jQuery UI date picker plugin. */ +/* Used in most of Arab countries, primarily in Bahrain, Kuwait, Oman, Qatar, Saudi Arabia and the United Arab Emirates, Egypt, Sudan and Yemen. */ +/* Written by Mohammed Alshehri -- m@dralshehri.com */ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ar = { + closeText: "إغلاق", + prevText: "<السابق", + nextText: "التالي>", + currentText: "اليوم", + monthNames: [ "يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", + "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر" ], + monthNamesShort: [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" ], + dayNames: [ "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" ], + dayNamesShort: [ "أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت" ], + dayNamesMin: [ "ح", "ن", "ث", "ر", "خ", "ج", "س" ], + weekHeader: "أسبوع", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ar ); + +return datepicker.regional.ar; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-az.js b/common/js/plugins/ui/i18n/datepicker-az.js new file mode 100644 index 000000000..2ebdcfa8b --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-az.js @@ -0,0 +1,37 @@ +/* Azerbaijani (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Jamil Najafov (necefov33@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.az = { + closeText: "Bağla", + prevText: "<Geri", + nextText: "İrəli>", + currentText: "Bugün", + monthNames: [ "Yanvar","Fevral","Mart","Aprel","May","İyun", + "İyul","Avqust","Sentyabr","Oktyabr","Noyabr","Dekabr" ], + monthNamesShort: [ "Yan","Fev","Mar","Apr","May","İyun", + "İyul","Avq","Sen","Okt","Noy","Dek" ], + dayNames: [ "Bazar","Bazar ertəsi","Çərşənbə axşamı","Çərşənbə","Cümə axşamı","Cümə","Şənbə" ], + dayNamesShort: [ "B","Be","Ça","Ç","Ca","C","Ş" ], + dayNamesMin: [ "B","B","Ç","С","Ç","C","Ş" ], + weekHeader: "Hf", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.az ); + +return datepicker.regional.az; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-be.js b/common/js/plugins/ui/i18n/datepicker-be.js new file mode 100644 index 000000000..7d96dd1da --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-be.js @@ -0,0 +1,37 @@ +/* Belarusian initialisation for the jQuery UI date picker plugin. */ +/* Written by Pavel Selitskas */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.be = { + closeText: "Зачыніць", + prevText: "←Папяр.", + nextText: "Наст.→", + currentText: "Сёньня", + monthNames: [ "Студзень","Люты","Сакавік","Красавік","Травень","Чэрвень", + "Ліпень","Жнівень","Верасень","Кастрычнік","Лістапад","Сьнежань" ], + monthNamesShort: [ "Сту","Лют","Сак","Кра","Тра","Чэр", + "Ліп","Жні","Вер","Кас","Ліс","Сьн" ], + dayNames: [ "нядзеля","панядзелак","аўторак","серада","чацьвер","пятніца","субота" ], + dayNamesShort: [ "ндз","пнд","аўт","срд","чцв","птн","сбт" ], + dayNamesMin: [ "Нд","Пн","Аў","Ср","Чц","Пт","Сб" ], + weekHeader: "Тд", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.be ); + +return datepicker.regional.be; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-bg.js b/common/js/plugins/ui/i18n/datepicker-bg.js new file mode 100644 index 000000000..cb066a4c9 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-bg.js @@ -0,0 +1,38 @@ +/* Bulgarian initialisation for the jQuery UI date picker plugin. */ +/* Written by Stoyan Kyosev (http://svest.org). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.bg = { + closeText: "затвори", + prevText: "<назад", + nextText: "напред>", + nextBigText: ">>", + currentText: "днес", + monthNames: [ "Януари","Февруари","Март","Април","Май","Юни", + "Юли","Август","Септември","Октомври","Ноември","Декември" ], + monthNamesShort: [ "Яну","Фев","Мар","Апр","Май","Юни", + "Юли","Авг","Сеп","Окт","Нов","Дек" ], + dayNames: [ "Неделя","Понеделник","Вторник","Сряда","Четвъртък","Петък","Събота" ], + dayNamesShort: [ "Нед","Пон","Вто","Сря","Чет","Пет","Съб" ], + dayNamesMin: [ "Не","По","Вт","Ср","Че","Пе","Съ" ], + weekHeader: "Wk", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.bg ); + +return datepicker.regional.bg; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-bs.js b/common/js/plugins/ui/i18n/datepicker-bs.js new file mode 100644 index 000000000..b9f2e2869 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-bs.js @@ -0,0 +1,37 @@ +/* Bosnian i18n for the jQuery UI date picker plugin. */ +/* Written by Kenan Konjo. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.bs = { + closeText: "Zatvori", + prevText: "<", + nextText: ">", + currentText: "Danas", + monthNames: [ "Januar","Februar","Mart","April","Maj","Juni", + "Juli","August","Septembar","Oktobar","Novembar","Decembar" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun", + "Jul","Aug","Sep","Okt","Nov","Dec" ], + dayNames: [ "Nedelja","Ponedeljak","Utorak","Srijeda","Četvrtak","Petak","Subota" ], + dayNamesShort: [ "Ned","Pon","Uto","Sri","Čet","Pet","Sub" ], + dayNamesMin: [ "Ne","Po","Ut","Sr","Če","Pe","Su" ], + weekHeader: "Wk", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.bs ); + +return datepicker.regional.bs; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ca.js b/common/js/plugins/ui/i18n/datepicker-ca.js new file mode 100644 index 000000000..9febd90ee --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ca.js @@ -0,0 +1,37 @@ +/* Inicialització en català per a l'extensió 'UI date picker' per jQuery. */ +/* Writers: (joan.leon@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ca = { + closeText: "Tanca", + prevText: "Anterior", + nextText: "Següent", + currentText: "Avui", + monthNames: [ "gener","febrer","març","abril","maig","juny", + "juliol","agost","setembre","octubre","novembre","desembre" ], + monthNamesShort: [ "gen","feb","març","abr","maig","juny", + "jul","ag","set","oct","nov","des" ], + dayNames: [ "diumenge","dilluns","dimarts","dimecres","dijous","divendres","dissabte" ], + dayNamesShort: [ "dg","dl","dt","dc","dj","dv","ds" ], + dayNamesMin: [ "dg","dl","dt","dc","dj","dv","ds" ], + weekHeader: "Set", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ca ); + +return datepicker.regional.ca; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-cs.js b/common/js/plugins/ui/i18n/datepicker-cs.js new file mode 100644 index 000000000..c2f79cf9e --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-cs.js @@ -0,0 +1,37 @@ +/* Czech initialisation for the jQuery UI date picker plugin. */ +/* Written by Tomas Muller (tomas@tomas-muller.net). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.cs = { + closeText: "Zavřít", + prevText: "<Dříve", + nextText: "Později>", + currentText: "Nyní", + monthNames: [ "leden","únor","březen","duben","květen","červen", + "červenec","srpen","září","říjen","listopad","prosinec" ], + monthNamesShort: [ "led","úno","bře","dub","kvě","čer", + "čvc","srp","zář","říj","lis","pro" ], + dayNames: [ "neděle", "pondělí", "úterý", "středa", "čtvrtek", "pátek", "sobota" ], + dayNamesShort: [ "ne", "po", "út", "st", "čt", "pá", "so" ], + dayNamesMin: [ "ne","po","út","st","čt","pá","so" ], + weekHeader: "Týd", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.cs ); + +return datepicker.regional.cs; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-cy-GB.js b/common/js/plugins/ui/i18n/datepicker-cy-GB.js new file mode 100644 index 000000000..26643b50c --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-cy-GB.js @@ -0,0 +1,37 @@ +/* Welsh/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by William Griffiths. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "cy-GB" ] = { + closeText: "Done", + prevText: "Prev", + nextText: "Next", + currentText: "Today", + monthNames: [ "Ionawr","Chwefror","Mawrth","Ebrill","Mai","Mehefin", + "Gorffennaf","Awst","Medi","Hydref","Tachwedd","Rhagfyr" ], + monthNamesShort: [ "Ion", "Chw", "Maw", "Ebr", "Mai", "Meh", + "Gor", "Aws", "Med", "Hyd", "Tac", "Rha" ], + dayNames: [ "Dydd Sul", "Dydd Llun", "Dydd Mawrth", "Dydd Mercher", "Dydd Iau", "Dydd Gwener", "Dydd Sadwrn" ], + dayNamesShort: [ "Sul", "Llu", "Maw", "Mer", "Iau", "Gwe", "Sad" ], + dayNamesMin: [ "Su","Ll","Ma","Me","Ia","Gw","Sa" ], + weekHeader: "Wy", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "cy-GB" ] ); + +return datepicker.regional[ "cy-GB" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-da.js b/common/js/plugins/ui/i18n/datepicker-da.js new file mode 100644 index 000000000..273f0e3ff --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-da.js @@ -0,0 +1,37 @@ +/* Danish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jan Christensen ( deletestuff@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.da = { + closeText: "Luk", + prevText: "<Forrige", + nextText: "Næste>", + currentText: "Idag", + monthNames: [ "Januar","Februar","Marts","April","Maj","Juni", + "Juli","August","September","Oktober","November","December" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun", + "Jul","Aug","Sep","Okt","Nov","Dec" ], + dayNames: [ "Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag" ], + dayNamesShort: [ "Søn","Man","Tir","Ons","Tor","Fre","Lør" ], + dayNamesMin: [ "Sø","Ma","Ti","On","To","Fr","Lø" ], + weekHeader: "Uge", + dateFormat: "dd-mm-yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.da ); + +return datepicker.regional.da; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-de.js b/common/js/plugins/ui/i18n/datepicker-de.js new file mode 100644 index 000000000..a67790844 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-de.js @@ -0,0 +1,37 @@ +/* German initialisation for the jQuery UI date picker plugin. */ +/* Written by Milian Wolff (mail@milianw.de). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.de = { + closeText: "Schließen", + prevText: "<Zurück", + nextText: "Vor>", + currentText: "Heute", + monthNames: [ "Januar","Februar","März","April","Mai","Juni", + "Juli","August","September","Oktober","November","Dezember" ], + monthNamesShort: [ "Jan","Feb","Mär","Apr","Mai","Jun", + "Jul","Aug","Sep","Okt","Nov","Dez" ], + dayNames: [ "Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag","Samstag" ], + dayNamesShort: [ "So","Mo","Di","Mi","Do","Fr","Sa" ], + dayNamesMin: [ "So","Mo","Di","Mi","Do","Fr","Sa" ], + weekHeader: "KW", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.de ); + +return datepicker.regional.de; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-el.js b/common/js/plugins/ui/i18n/datepicker-el.js new file mode 100644 index 000000000..f08d6f27d --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-el.js @@ -0,0 +1,37 @@ +/* Greek (el) initialisation for the jQuery UI date picker plugin. */ +/* Written by Alex Cicovic (http://www.alexcicovic.com) */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.el = { + closeText: "Κλείσιμο", + prevText: "Προηγούμενος", + nextText: "Επόμενος", + currentText: "Σήμερα", + monthNames: [ "Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάιος","Ιούνιος", + "Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος" ], + monthNamesShort: [ "Ιαν","Φεβ","Μαρ","Απρ","Μαι","Ιουν", + "Ιουλ","Αυγ","Σεπ","Οκτ","Νοε","Δεκ" ], + dayNames: [ "Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Σάββατο" ], + dayNamesShort: [ "Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ" ], + dayNamesMin: [ "Κυ","Δε","Τρ","Τε","Πε","Πα","Σα" ], + weekHeader: "Εβδ", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.el ); + +return datepicker.regional.el; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-en-AU.js b/common/js/plugins/ui/i18n/datepicker-en-AU.js new file mode 100644 index 000000000..f15277c37 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-en-AU.js @@ -0,0 +1,37 @@ +/* English/Australia initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "en-AU" ] = { + closeText: "Done", + prevText: "Prev", + nextText: "Next", + currentText: "Today", + monthNames: [ "January","February","March","April","May","June", + "July","August","September","October","November","December" ], + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], + dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "en-AU" ] ); + +return datepicker.regional[ "en-AU" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-en-GB.js b/common/js/plugins/ui/i18n/datepicker-en-GB.js new file mode 100644 index 000000000..c961c1865 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-en-GB.js @@ -0,0 +1,37 @@ +/* English/UK initialisation for the jQuery UI date picker plugin. */ +/* Written by Stuart. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "en-GB" ] = { + closeText: "Done", + prevText: "Prev", + nextText: "Next", + currentText: "Today", + monthNames: [ "January","February","March","April","May","June", + "July","August","September","October","November","December" ], + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], + dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "en-GB" ] ); + +return datepicker.regional[ "en-GB" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-en-NZ.js b/common/js/plugins/ui/i18n/datepicker-en-NZ.js new file mode 100644 index 000000000..704636225 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-en-NZ.js @@ -0,0 +1,37 @@ +/* English/New Zealand initialisation for the jQuery UI date picker plugin. */ +/* Based on the en-GB initialisation. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "en-NZ" ] = { + closeText: "Done", + prevText: "Prev", + nextText: "Next", + currentText: "Today", + monthNames: [ "January","February","March","April","May","June", + "July","August","September","October","November","December" ], + monthNamesShort: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ], + dayNames: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], + dayNamesShort: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], + dayNamesMin: [ "Su","Mo","Tu","We","Th","Fr","Sa" ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "en-NZ" ] ); + +return datepicker.regional[ "en-NZ" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-eo.js b/common/js/plugins/ui/i18n/datepicker-eo.js new file mode 100644 index 000000000..25f6162b5 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-eo.js @@ -0,0 +1,37 @@ +/* Esperanto initialisation for the jQuery UI date picker plugin. */ +/* Written by Olivier M. (olivierweb@ifrance.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.eo = { + closeText: "Fermi", + prevText: "<Anta", + nextText: "Sekv>", + currentText: "Nuna", + monthNames: [ "Januaro","Februaro","Marto","Aprilo","Majo","Junio", + "Julio","Aŭgusto","Septembro","Oktobro","Novembro","Decembro" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun", + "Jul","Aŭg","Sep","Okt","Nov","Dec" ], + dayNames: [ "Dimanĉo","Lundo","Mardo","Merkredo","Ĵaŭdo","Vendredo","Sabato" ], + dayNamesShort: [ "Dim","Lun","Mar","Mer","Ĵaŭ","Ven","Sab" ], + dayNamesMin: [ "Di","Lu","Ma","Me","Ĵa","Ve","Sa" ], + weekHeader: "Sb", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.eo ); + +return datepicker.regional.eo; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-es.js b/common/js/plugins/ui/i18n/datepicker-es.js new file mode 100644 index 000000000..ea7116e0b --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-es.js @@ -0,0 +1,37 @@ +/* Inicialización en español para la extensión 'UI date picker' para jQuery. */ +/* Traducido por Vester (xvester@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.es = { + closeText: "Cerrar", + prevText: "<Ant", + nextText: "Sig>", + currentText: "Hoy", + monthNames: [ "enero","febrero","marzo","abril","mayo","junio", + "julio","agosto","septiembre","octubre","noviembre","diciembre" ], + monthNamesShort: [ "ene","feb","mar","abr","may","jun", + "jul","ago","sep","oct","nov","dic" ], + dayNames: [ "domingo","lunes","martes","miércoles","jueves","viernes","sábado" ], + dayNamesShort: [ "dom","lun","mar","mié","jue","vie","sáb" ], + dayNamesMin: [ "D","L","M","X","J","V","S" ], + weekHeader: "Sm", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.es ); + +return datepicker.regional.es; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-et.js b/common/js/plugins/ui/i18n/datepicker-et.js new file mode 100644 index 000000000..691675a98 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-et.js @@ -0,0 +1,37 @@ +/* Estonian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mart Sõmermaa (mrts.pydev at gmail com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.et = { + closeText: "Sulge", + prevText: "Eelnev", + nextText: "Järgnev", + currentText: "Täna", + monthNames: [ "Jaanuar","Veebruar","Märts","Aprill","Mai","Juuni", + "Juuli","August","September","Oktoober","November","Detsember" ], + monthNamesShort: [ "Jaan", "Veebr", "Märts", "Apr", "Mai", "Juuni", + "Juuli", "Aug", "Sept", "Okt", "Nov", "Dets" ], + dayNames: [ "Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev" ], + dayNamesShort: [ "Pühap", "Esmasp", "Teisip", "Kolmap", "Neljap", "Reede", "Laup" ], + dayNamesMin: [ "P","E","T","K","N","R","L" ], + weekHeader: "näd", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.et ); + +return datepicker.regional.et; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-eu.js b/common/js/plugins/ui/i18n/datepicker-eu.js new file mode 100644 index 000000000..8ea1ef9e5 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-eu.js @@ -0,0 +1,36 @@ +/* Karrikas-ek itzulia (karrikas@karrikas.com) */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.eu = { + closeText: "Egina", + prevText: "<Aur", + nextText: "Hur>", + currentText: "Gaur", + monthNames: [ "urtarrila","otsaila","martxoa","apirila","maiatza","ekaina", + "uztaila","abuztua","iraila","urria","azaroa","abendua" ], + monthNamesShort: [ "urt.","ots.","mar.","api.","mai.","eka.", + "uzt.","abu.","ira.","urr.","aza.","abe." ], + dayNames: [ "igandea","astelehena","asteartea","asteazkena","osteguna","ostirala","larunbata" ], + dayNamesShort: [ "ig.","al.","ar.","az.","og.","ol.","lr." ], + dayNamesMin: [ "ig","al","ar","az","og","ol","lr" ], + weekHeader: "As", + dateFormat: "yy-mm-dd", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.eu ); + +return datepicker.regional.eu; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-fa.js b/common/js/plugins/ui/i18n/datepicker-fa.js new file mode 100644 index 000000000..71da4981d --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-fa.js @@ -0,0 +1,73 @@ +/* Persian (Farsi) Translation for the jQuery UI date picker plugin. */ +/* Javad Mowlanezhad -- jmowla@gmail.com */ +/* Jalali calendar should supported soon! (Its implemented but I have to test it) */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.fa = { + closeText: "بستن", + prevText: "<قبلی", + nextText: "بعدی>", + currentText: "امروز", + monthNames: [ + "ژانویه", + "فوریه", + "مارس", + "آوریل", + "مه", + "ژوئن", + "ژوئیه", + "اوت", + "سپتامبر", + "اکتبر", + "نوامبر", + "دسامبر" + ], + monthNamesShort: [ "1","2","3","4","5","6","7","8","9","10","11","12" ], + dayNames: [ + "يکشنبه", + "دوشنبه", + "سه‌شنبه", + "چهارشنبه", + "پنجشنبه", + "جمعه", + "شنبه" + ], + dayNamesShort: [ + "ی", + "د", + "س", + "چ", + "پ", + "ج", + "ش" + ], + dayNamesMin: [ + "ی", + "د", + "س", + "چ", + "پ", + "ج", + "ش" + ], + weekHeader: "هف", + dateFormat: "yy/mm/dd", + firstDay: 6, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.fa ); + +return datepicker.regional.fa; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-fi.js b/common/js/plugins/ui/i18n/datepicker-fi.js new file mode 100644 index 000000000..a8386ff62 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-fi.js @@ -0,0 +1,37 @@ +/* Finnish initialisation for the jQuery UI date picker plugin. */ +/* Written by Harri Kilpiö (harrikilpio@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.fi = { + closeText: "Sulje", + prevText: "«Edellinen", + nextText: "Seuraava»", + currentText: "Tänään", + monthNames: [ "Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu", + "Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu" ], + monthNamesShort: [ "Tammi","Helmi","Maalis","Huhti","Touko","Kesä", + "Heinä","Elo","Syys","Loka","Marras","Joulu" ], + dayNamesShort: [ "Su","Ma","Ti","Ke","To","Pe","La" ], + dayNames: [ "Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai" ], + dayNamesMin: [ "Su","Ma","Ti","Ke","To","Pe","La" ], + weekHeader: "Vk", + dateFormat: "d.m.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.fi ); + +return datepicker.regional.fi; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-fo.js b/common/js/plugins/ui/i18n/datepicker-fo.js new file mode 100644 index 000000000..df1e08951 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-fo.js @@ -0,0 +1,37 @@ +/* Faroese initialisation for the jQuery UI date picker plugin */ +/* Written by Sverri Mohr Olsen, sverrimo@gmail.com */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.fo = { + closeText: "Lat aftur", + prevText: "<Fyrra", + nextText: "Næsta>", + currentText: "Í dag", + monthNames: [ "Januar","Februar","Mars","Apríl","Mei","Juni", + "Juli","August","September","Oktober","November","Desember" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Mei","Jun", + "Jul","Aug","Sep","Okt","Nov","Des" ], + dayNames: [ "Sunnudagur","Mánadagur","Týsdagur","Mikudagur","Hósdagur","Fríggjadagur","Leyardagur" ], + dayNamesShort: [ "Sun","Mán","Týs","Mik","Hós","Frí","Ley" ], + dayNamesMin: [ "Su","Má","Tý","Mi","Hó","Fr","Le" ], + weekHeader: "Vk", + dateFormat: "dd-mm-yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.fo ); + +return datepicker.regional.fo; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-fr-CA.js b/common/js/plugins/ui/i18n/datepicker-fr-CA.js new file mode 100644 index 000000000..b590277d4 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-fr-CA.js @@ -0,0 +1,37 @@ +/* Canadian-French initialisation for the jQuery UI date picker plugin. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "fr-CA" ] = { + closeText: "Fermer", + prevText: "Précédent", + nextText: "Suivant", + currentText: "Aujourd'hui", + monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre" ], + monthNamesShort: [ "janv.", "févr.", "mars", "avril", "mai", "juin", + "juil.", "août", "sept.", "oct.", "nov.", "déc." ], + dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ], + dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ], + dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ], + weekHeader: "Sem.", + dateFormat: "yy-mm-dd", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" +}; +datepicker.setDefaults( datepicker.regional[ "fr-CA" ] ); + +return datepicker.regional[ "fr-CA" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-fr-CH.js b/common/js/plugins/ui/i18n/datepicker-fr-CH.js new file mode 100644 index 000000000..d2f0584d6 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-fr-CH.js @@ -0,0 +1,37 @@ +/* Swiss-French initialisation for the jQuery UI date picker plugin. */ +/* Written Martin Voelkle (martin.voelkle@e-tc.ch). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "fr-CH" ] = { + closeText: "Fermer", + prevText: "<Préc", + nextText: "Suiv>", + currentText: "Courant", + monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre" ], + monthNamesShort: [ "janv.", "févr.", "mars", "avril", "mai", "juin", + "juil.", "août", "sept.", "oct.", "nov.", "déc." ], + dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ], + dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ], + dayNamesMin: [ "D", "L", "M", "M", "J", "V", "S" ], + weekHeader: "Sm", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "fr-CH" ] ); + +return datepicker.regional[ "fr-CH" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-fr.js b/common/js/plugins/ui/i18n/datepicker-fr.js new file mode 100644 index 000000000..9e39fbd68 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-fr.js @@ -0,0 +1,39 @@ +/* French initialisation for the jQuery UI date picker plugin. */ +/* Written by Keith Wood (kbwood{at}iinet.com.au), + Stéphane Nahmani (sholby@sholby.net), + Stéphane Raimbault */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.fr = { + closeText: "Fermer", + prevText: "Précédent", + nextText: "Suivant", + currentText: "Aujourd'hui", + monthNames: [ "janvier", "février", "mars", "avril", "mai", "juin", + "juillet", "août", "septembre", "octobre", "novembre", "décembre" ], + monthNamesShort: [ "janv.", "févr.", "mars", "avr.", "mai", "juin", + "juil.", "août", "sept.", "oct.", "nov.", "déc." ], + dayNames: [ "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" ], + dayNamesShort: [ "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." ], + dayNamesMin: [ "D","L","M","M","J","V","S" ], + weekHeader: "Sem.", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.fr ); + +return datepicker.regional.fr; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-gl.js b/common/js/plugins/ui/i18n/datepicker-gl.js new file mode 100644 index 000000000..276523074 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-gl.js @@ -0,0 +1,37 @@ +/* Galician localization for 'UI date picker' jQuery extension. */ +/* Translated by Jorge Barreiro . */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.gl = { + closeText: "Pechar", + prevText: "<Ant", + nextText: "Seg>", + currentText: "Hoxe", + monthNames: [ "Xaneiro","Febreiro","Marzo","Abril","Maio","Xuño", + "Xullo","Agosto","Setembro","Outubro","Novembro","Decembro" ], + monthNamesShort: [ "Xan","Feb","Mar","Abr","Mai","Xuñ", + "Xul","Ago","Set","Out","Nov","Dec" ], + dayNames: [ "Domingo","Luns","Martes","Mércores","Xoves","Venres","Sábado" ], + dayNamesShort: [ "Dom","Lun","Mar","Mér","Xov","Ven","Sáb" ], + dayNamesMin: [ "Do","Lu","Ma","Mé","Xo","Ve","Sá" ], + weekHeader: "Sm", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.gl ); + +return datepicker.regional.gl; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-he.js b/common/js/plugins/ui/i18n/datepicker-he.js new file mode 100644 index 000000000..fb6238fda --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-he.js @@ -0,0 +1,37 @@ +/* Hebrew initialisation for the UI Datepicker extension. */ +/* Written by Amir Hardon (ahardon at gmail dot com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.he = { + closeText: "סגור", + prevText: "<הקודם", + nextText: "הבא>", + currentText: "היום", + monthNames: [ "ינואר","פברואר","מרץ","אפריל","מאי","יוני", + "יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר" ], + monthNamesShort: [ "ינו","פבר","מרץ","אפר","מאי","יוני", + "יולי","אוג","ספט","אוק","נוב","דצמ" ], + dayNames: [ "ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת" ], + dayNamesShort: [ "א'","ב'","ג'","ד'","ה'","ו'","שבת" ], + dayNamesMin: [ "א'","ב'","ג'","ד'","ה'","ו'","שבת" ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: true, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.he ); + +return datepicker.regional.he; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-hi.js b/common/js/plugins/ui/i18n/datepicker-hi.js new file mode 100644 index 000000000..3b1209724 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-hi.js @@ -0,0 +1,37 @@ +/* Hindi initialisation for the jQuery UI date picker plugin. */ +/* Written by Michael Dawart. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.hi = { + closeText: "बंद", + prevText: "पिछला", + nextText: "अगला", + currentText: "आज", + monthNames: [ "जनवरी ","फरवरी","मार्च","अप्रेल","मई","जून", + "जूलाई","अगस्त ","सितम्बर","अक्टूबर","नवम्बर","दिसम्बर" ], + monthNamesShort: [ "जन", "फर", "मार्च", "अप्रेल", "मई", "जून", + "जूलाई", "अग", "सित", "अक्ट", "नव", "दि" ], + dayNames: [ "रविवार", "सोमवार", "मंगलवार", "बुधवार", "गुरुवार", "शुक्रवार", "शनिवार" ], + dayNamesShort: [ "रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि" ], + dayNamesMin: [ "रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि" ], + weekHeader: "हफ्ता", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.hi ); + +return datepicker.regional.hi; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-hr.js b/common/js/plugins/ui/i18n/datepicker-hr.js new file mode 100644 index 000000000..5e218c12d --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-hr.js @@ -0,0 +1,37 @@ +/* Croatian i18n for the jQuery UI date picker plugin. */ +/* Written by Vjekoslav Nesek. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.hr = { + closeText: "Zatvori", + prevText: "<", + nextText: ">", + currentText: "Danas", + monthNames: [ "Siječanj","Veljača","Ožujak","Travanj","Svibanj","Lipanj", + "Srpanj","Kolovoz","Rujan","Listopad","Studeni","Prosinac" ], + monthNamesShort: [ "Sij","Velj","Ožu","Tra","Svi","Lip", + "Srp","Kol","Ruj","Lis","Stu","Pro" ], + dayNames: [ "Nedjelja","Ponedjeljak","Utorak","Srijeda","Četvrtak","Petak","Subota" ], + dayNamesShort: [ "Ned","Pon","Uto","Sri","Čet","Pet","Sub" ], + dayNamesMin: [ "Ne","Po","Ut","Sr","Če","Pe","Su" ], + weekHeader: "Tje", + dateFormat: "dd.mm.yy.", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.hr ); + +return datepicker.regional.hr; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-hu.js b/common/js/plugins/ui/i18n/datepicker-hu.js new file mode 100644 index 000000000..22bbe7031 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-hu.js @@ -0,0 +1,36 @@ +/* Hungarian initialisation for the jQuery UI date picker plugin. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.hu = { + closeText: "bezár", + prevText: "vissza", + nextText: "előre", + currentText: "ma", + monthNames: [ "Január", "Február", "Március", "Április", "Május", "Június", + "Július", "Augusztus", "Szeptember", "Október", "November", "December" ], + monthNamesShort: [ "Jan", "Feb", "Már", "Ápr", "Máj", "Jún", + "Júl", "Aug", "Szep", "Okt", "Nov", "Dec" ], + dayNames: [ "Vasárnap", "Hétfő", "Kedd", "Szerda", "Csütörtök", "Péntek", "Szombat" ], + dayNamesShort: [ "Vas", "Hét", "Ked", "Sze", "Csü", "Pén", "Szo" ], + dayNamesMin: [ "V", "H", "K", "Sze", "Cs", "P", "Szo" ], + weekHeader: "Hét", + dateFormat: "yy.mm.dd.", + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.hu ); + +return datepicker.regional.hu; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-hy.js b/common/js/plugins/ui/i18n/datepicker-hy.js new file mode 100644 index 000000000..95638b310 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-hy.js @@ -0,0 +1,37 @@ +/* Armenian(UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Levon Zakaryan (levon.zakaryan@gmail.com)*/ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.hy = { + closeText: "Փակել", + prevText: "<Նախ.", + nextText: "Հաջ.>", + currentText: "Այսօր", + monthNames: [ "Հունվար","Փետրվար","Մարտ","Ապրիլ","Մայիս","Հունիս", + "Հուլիս","Օգոստոս","Սեպտեմբեր","Հոկտեմբեր","Նոյեմբեր","Դեկտեմբեր" ], + monthNamesShort: [ "Հունվ","Փետր","Մարտ","Ապր","Մայիս","Հունիս", + "Հուլ","Օգս","Սեպ","Հոկ","Նոյ","Դեկ" ], + dayNames: [ "կիրակի","եկուշաբթի","երեքշաբթի","չորեքշաբթի","հինգշաբթի","ուրբաթ","շաբաթ" ], + dayNamesShort: [ "կիր","երկ","երք","չրք","հնգ","ուրբ","շբթ" ], + dayNamesMin: [ "կիր","երկ","երք","չրք","հնգ","ուրբ","շբթ" ], + weekHeader: "ՇԲՏ", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.hy ); + +return datepicker.regional.hy; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-id.js b/common/js/plugins/ui/i18n/datepicker-id.js new file mode 100644 index 000000000..5aef348af --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-id.js @@ -0,0 +1,37 @@ +/* Indonesian initialisation for the jQuery UI date picker plugin. */ +/* Written by Deden Fathurahman (dedenf@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.id = { + closeText: "Tutup", + prevText: "<mundur", + nextText: "maju>", + currentText: "hari ini", + monthNames: [ "Januari","Februari","Maret","April","Mei","Juni", + "Juli","Agustus","September","Oktober","Nopember","Desember" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Mei","Jun", + "Jul","Agus","Sep","Okt","Nop","Des" ], + dayNames: [ "Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu" ], + dayNamesShort: [ "Min","Sen","Sel","Rab","kam","Jum","Sab" ], + dayNamesMin: [ "Mg","Sn","Sl","Rb","Km","jm","Sb" ], + weekHeader: "Mg", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.id ); + +return datepicker.regional.id; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-is.js b/common/js/plugins/ui/i18n/datepicker-is.js new file mode 100644 index 000000000..f977de326 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-is.js @@ -0,0 +1,37 @@ +/* Icelandic initialisation for the jQuery UI date picker plugin. */ +/* Written by Haukur H. Thorsson (haukur@eskill.is). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.is = { + closeText: "Loka", + prevText: "< Fyrri", + nextText: "Næsti >", + currentText: "Í dag", + monthNames: [ "Janúar","Febrúar","Mars","Apríl","Maí","Júní", + "Júlí","Ágúst","September","Október","Nóvember","Desember" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maí","Jún", + "Júl","Ágú","Sep","Okt","Nóv","Des" ], + dayNames: [ "Sunnudagur","Mánudagur","Þriðjudagur","Miðvikudagur","Fimmtudagur","Föstudagur","Laugardagur" ], + dayNamesShort: [ "Sun","Mán","Þri","Mið","Fim","Fös","Lau" ], + dayNamesMin: [ "Su","Má","Þr","Mi","Fi","Fö","La" ], + weekHeader: "Vika", + dateFormat: "dd.mm.yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.is ); + +return datepicker.regional.is; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-it-CH.js b/common/js/plugins/ui/i18n/datepicker-it-CH.js new file mode 100644 index 000000000..9895da4cc --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-it-CH.js @@ -0,0 +1,37 @@ +/* Italian initialisation for the jQuery UI date picker plugin. */ +/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "it-CH" ] = { + closeText: "Chiudi", + prevText: "<Prec", + nextText: "Succ>", + currentText: "Oggi", + monthNames: [ "Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno", + "Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre" ], + monthNamesShort: [ "Gen","Feb","Mar","Apr","Mag","Giu", + "Lug","Ago","Set","Ott","Nov","Dic" ], + dayNames: [ "Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato" ], + dayNamesShort: [ "Dom","Lun","Mar","Mer","Gio","Ven","Sab" ], + dayNamesMin: [ "Do","Lu","Ma","Me","Gi","Ve","Sa" ], + weekHeader: "Sm", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "it-CH" ] ); + +return datepicker.regional[ "it-CH" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-it.js b/common/js/plugins/ui/i18n/datepicker-it.js new file mode 100644 index 000000000..d67cb6c24 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-it.js @@ -0,0 +1,37 @@ +/* Italian initialisation for the jQuery UI date picker plugin. */ +/* Written by Antonello Pasella (antonello.pasella@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.it = { + closeText: "Chiudi", + prevText: "<Prec", + nextText: "Succ>", + currentText: "Oggi", + monthNames: [ "Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno", + "Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre" ], + monthNamesShort: [ "Gen","Feb","Mar","Apr","Mag","Giu", + "Lug","Ago","Set","Ott","Nov","Dic" ], + dayNames: [ "Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato" ], + dayNamesShort: [ "Dom","Lun","Mar","Mer","Gio","Ven","Sab" ], + dayNamesMin: [ "Do","Lu","Ma","Me","Gi","Ve","Sa" ], + weekHeader: "Sm", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.it ); + +return datepicker.regional.it; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ja.js b/common/js/plugins/ui/i18n/datepicker-ja.js new file mode 100644 index 000000000..52b10583c --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ja.js @@ -0,0 +1,37 @@ +/* Japanese initialisation for the jQuery UI date picker plugin. */ +/* Written by Kentaro SATO (kentaro@ranvis.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ja = { + closeText: "閉じる", + prevText: "<前", + nextText: "次>", + currentText: "今日", + monthNames: [ "1月","2月","3月","4月","5月","6月", + "7月","8月","9月","10月","11月","12月" ], + monthNamesShort: [ "1月","2月","3月","4月","5月","6月", + "7月","8月","9月","10月","11月","12月" ], + dayNames: [ "日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日" ], + dayNamesShort: [ "日","月","火","水","木","金","土" ], + dayNamesMin: [ "日","月","火","水","木","金","土" ], + weekHeader: "週", + dateFormat: "yy/mm/dd", + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "年" }; +datepicker.setDefaults( datepicker.regional.ja ); + +return datepicker.regional.ja; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ka.js b/common/js/plugins/ui/i18n/datepicker-ka.js new file mode 100644 index 000000000..6a4aa392f --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ka.js @@ -0,0 +1,35 @@ +/* Georgian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Lado Lomidze (lado.lomidze@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ka = { + closeText: "დახურვა", + prevText: "< წინა", + nextText: "შემდეგი >", + currentText: "დღეს", + monthNames: [ "იანვარი","თებერვალი","მარტი","აპრილი","მაისი","ივნისი", "ივლისი","აგვისტო","სექტემბერი","ოქტომბერი","ნოემბერი","დეკემბერი" ], + monthNamesShort: [ "იან","თებ","მარ","აპრ","მაი","ივნ", "ივლ","აგვ","სექ","ოქტ","ნოე","დეკ" ], + dayNames: [ "კვირა","ორშაბათი","სამშაბათი","ოთხშაბათი","ხუთშაბათი","პარასკევი","შაბათი" ], + dayNamesShort: [ "კვ","ორშ","სამ","ოთხ","ხუთ","პარ","შაბ" ], + dayNamesMin: [ "კვ","ორშ","სამ","ოთხ","ხუთ","პარ","შაბ" ], + weekHeader: "კვირა", + dateFormat: "dd-mm-yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ka ); + +return datepicker.regional.ka; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-kk.js b/common/js/plugins/ui/i18n/datepicker-kk.js new file mode 100644 index 000000000..fa0121f8c --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-kk.js @@ -0,0 +1,37 @@ +/* Kazakh (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Dmitriy Karasyov (dmitriy.karasyov@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.kk = { + closeText: "Жабу", + prevText: "<Алдыңғы", + nextText: "Келесі>", + currentText: "Бүгін", + monthNames: [ "Қаңтар","Ақпан","Наурыз","Сәуір","Мамыр","Маусым", + "Шілде","Тамыз","Қыркүйек","Қазан","Қараша","Желтоқсан" ], + monthNamesShort: [ "Қаң","Ақп","Нау","Сәу","Мам","Мау", + "Шіл","Там","Қыр","Қаз","Қар","Жел" ], + dayNames: [ "Жексенбі","Дүйсенбі","Сейсенбі","Сәрсенбі","Бейсенбі","Жұма","Сенбі" ], + dayNamesShort: [ "жкс","дсн","ссн","срс","бсн","жма","снб" ], + dayNamesMin: [ "Жк","Дс","Сс","Ср","Бс","Жм","Сн" ], + weekHeader: "Не", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.kk ); + +return datepicker.regional.kk; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-km.js b/common/js/plugins/ui/i18n/datepicker-km.js new file mode 100644 index 000000000..d8a4596bc --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-km.js @@ -0,0 +1,37 @@ +/* Khmer initialisation for the jQuery calendar extension. */ +/* Written by Chandara Om (chandara.teacher@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.km = { + closeText: "ធ្វើ​រួច", + prevText: "មុន", + nextText: "បន្ទាប់", + currentText: "ថ្ងៃ​នេះ", + monthNames: [ "មករា","កុម្ភៈ","មីនា","មេសា","ឧសភា","មិថុនា", + "កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ" ], + monthNamesShort: [ "មករា","កុម្ភៈ","មីនា","មេសា","ឧសភា","មិថុនា", + "កក្កដា","សីហា","កញ្ញា","តុលា","វិច្ឆិកា","ធ្នូ" ], + dayNames: [ "អាទិត្យ", "ចន្ទ", "អង្គារ", "ពុធ", "ព្រហស្បតិ៍", "សុក្រ", "សៅរ៍" ], + dayNamesShort: [ "អា", "ច", "អ", "ពុ", "ព្រហ", "សុ", "សៅ" ], + dayNamesMin: [ "អា", "ច", "អ", "ពុ", "ព្រហ", "សុ", "សៅ" ], + weekHeader: "សប្ដាហ៍", + dateFormat: "dd-mm-yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.km ); + +return datepicker.regional.km; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ko.js b/common/js/plugins/ui/i18n/datepicker-ko.js new file mode 100644 index 000000000..8879a9950 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ko.js @@ -0,0 +1,37 @@ +/* Korean initialisation for the jQuery calendar extension. */ +/* Written by DaeKwon Kang (ncrash.dk@gmail.com), Edited by Genie and Myeongjin Lee. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ko = { + closeText: "닫기", + prevText: "이전달", + nextText: "다음달", + currentText: "오늘", + monthNames: [ "1월","2월","3월","4월","5월","6월", + "7월","8월","9월","10월","11월","12월" ], + monthNamesShort: [ "1월","2월","3월","4월","5월","6월", + "7월","8월","9월","10월","11월","12월" ], + dayNames: [ "일요일","월요일","화요일","수요일","목요일","금요일","토요일" ], + dayNamesShort: [ "일","월","화","수","목","금","토" ], + dayNamesMin: [ "일","월","화","수","목","금","토" ], + weekHeader: "주", + dateFormat: "yy. m. d.", + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "년" }; +datepicker.setDefaults( datepicker.regional.ko ); + +return datepicker.regional.ko; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ky.js b/common/js/plugins/ui/i18n/datepicker-ky.js new file mode 100644 index 000000000..f748bc606 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ky.js @@ -0,0 +1,38 @@ +/* Kyrgyz (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Sergey Kartashov (ebishkek@yandex.ru). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ky = { + closeText: "Жабуу", + prevText: "<Мур", + nextText: "Кий>", + currentText: "Бүгүн", + monthNames: [ "Январь","Февраль","Март","Апрель","Май","Июнь", + "Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь" ], + monthNamesShort: [ "Янв","Фев","Мар","Апр","Май","Июн", + "Июл","Авг","Сен","Окт","Ноя","Дек" ], + dayNames: [ "жекшемби", "дүйшөмбү", "шейшемби", "шаршемби", "бейшемби", "жума", "ишемби" ], + dayNamesShort: [ "жек", "дүй", "шей", "шар", "бей", "жум", "ише" ], + dayNamesMin: [ "Жк","Дш","Шш","Шр","Бш","Жм","Иш" ], + weekHeader: "Жум", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" +}; +datepicker.setDefaults( datepicker.regional.ky ); + +return datepicker.regional.ky; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-lb.js b/common/js/plugins/ui/i18n/datepicker-lb.js new file mode 100644 index 000000000..a8fa03b8f --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-lb.js @@ -0,0 +1,37 @@ +/* Luxembourgish initialisation for the jQuery UI date picker plugin. */ +/* Written by Michel Weimerskirch */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.lb = { + closeText: "Fäerdeg", + prevText: "Zréck", + nextText: "Weider", + currentText: "Haut", + monthNames: [ "Januar","Februar","Mäerz","Abrëll","Mee","Juni", + "Juli","August","September","Oktober","November","Dezember" ], + monthNamesShort: [ "Jan", "Feb", "Mäe", "Abr", "Mee", "Jun", + "Jul", "Aug", "Sep", "Okt", "Nov", "Dez" ], + dayNames: [ "Sonndeg", "Méindeg", "Dënschdeg", "Mëttwoch", "Donneschdeg", "Freideg", "Samschdeg" ], + dayNamesShort: [ "Son", "Méi", "Dën", "Mët", "Don", "Fre", "Sam" ], + dayNamesMin: [ "So","Mé","Dë","Më","Do","Fr","Sa" ], + weekHeader: "W", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.lb ); + +return datepicker.regional.lb; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-lt.js b/common/js/plugins/ui/i18n/datepicker-lt.js new file mode 100644 index 000000000..35554764f --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-lt.js @@ -0,0 +1,37 @@ +/* Lithuanian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.lt = { + closeText: "Uždaryti", + prevText: "<Atgal", + nextText: "Pirmyn>", + currentText: "Šiandien", + monthNames: [ "Sausis","Vasaris","Kovas","Balandis","Gegužė","Birželis", + "Liepa","Rugpjūtis","Rugsėjis","Spalis","Lapkritis","Gruodis" ], + monthNamesShort: [ "Sau","Vas","Kov","Bal","Geg","Bir", + "Lie","Rugp","Rugs","Spa","Lap","Gru" ], + dayNames: [ "sekmadienis","pirmadienis","antradienis","trečiadienis","ketvirtadienis","penktadienis","šeštadienis" ], + dayNamesShort: [ "sek","pir","ant","tre","ket","pen","šeš" ], + dayNamesMin: [ "Se","Pr","An","Tr","Ke","Pe","Še" ], + weekHeader: "SAV", + dateFormat: "yy-mm-dd", + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.lt ); + +return datepicker.regional.lt; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-lv.js b/common/js/plugins/ui/i18n/datepicker-lv.js new file mode 100644 index 000000000..ec49c43a6 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-lv.js @@ -0,0 +1,37 @@ +/* Latvian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* @author Arturas Paleicikas */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.lv = { + closeText: "Aizvērt", + prevText: "Iepr.", + nextText: "Nāk.", + currentText: "Šodien", + monthNames: [ "Janvāris","Februāris","Marts","Aprīlis","Maijs","Jūnijs", + "Jūlijs","Augusts","Septembris","Oktobris","Novembris","Decembris" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Mai","Jūn", + "Jūl","Aug","Sep","Okt","Nov","Dec" ], + dayNames: [ "svētdiena","pirmdiena","otrdiena","trešdiena","ceturtdiena","piektdiena","sestdiena" ], + dayNamesShort: [ "svt","prm","otr","tre","ctr","pkt","sst" ], + dayNamesMin: [ "Sv","Pr","Ot","Tr","Ct","Pk","Ss" ], + weekHeader: "Ned.", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.lv ); + +return datepicker.regional.lv; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-mk.js b/common/js/plugins/ui/i18n/datepicker-mk.js new file mode 100644 index 000000000..97864ab15 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-mk.js @@ -0,0 +1,37 @@ +/* Macedonian i18n for the jQuery UI date picker plugin. */ +/* Written by Stojce Slavkovski. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.mk = { + closeText: "Затвори", + prevText: "<", + nextText: ">", + currentText: "Денес", + monthNames: [ "Јануари","Февруари","Март","Април","Мај","Јуни", + "Јули","Август","Септември","Октомври","Ноември","Декември" ], + monthNamesShort: [ "Јан","Фев","Мар","Апр","Мај","Јун", + "Јул","Авг","Сеп","Окт","Ное","Дек" ], + dayNames: [ "Недела","Понеделник","Вторник","Среда","Четврток","Петок","Сабота" ], + dayNamesShort: [ "Нед","Пон","Вто","Сре","Чет","Пет","Саб" ], + dayNamesMin: [ "Не","По","Вт","Ср","Че","Пе","Са" ], + weekHeader: "Сед", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.mk ); + +return datepicker.regional.mk; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ml.js b/common/js/plugins/ui/i18n/datepicker-ml.js new file mode 100644 index 000000000..440e09e03 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ml.js @@ -0,0 +1,37 @@ +/* Malayalam (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Saji Nediyanchath (saji89@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ml = { + closeText: "ശരി", + prevText: "മുന്നത്തെ", + nextText: "അടുത്തത് ", + currentText: "ഇന്ന്", + monthNames: [ "ജനുവരി","ഫെബ്രുവരി","മാര്‍ച്ച്","ഏപ്രില്‍","മേയ്","ജൂണ്‍", + "ജൂലൈ","ആഗസ്റ്റ്","സെപ്റ്റംബര്‍","ഒക്ടോബര്‍","നവംബര്‍","ഡിസംബര്‍" ], + monthNamesShort: [ "ജനു", "ഫെബ്", "മാര്‍", "ഏപ്രി", "മേയ്", "ജൂണ്‍", + "ജൂലാ", "ആഗ", "സെപ്", "ഒക്ടോ", "നവം", "ഡിസ" ], + dayNames: [ "ഞായര്‍", "തിങ്കള്‍", "ചൊവ്വ", "ബുധന്‍", "വ്യാഴം", "വെള്ളി", "ശനി" ], + dayNamesShort: [ "ഞായ", "തിങ്ക", "ചൊവ്വ", "ബുധ", "വ്യാഴം", "വെള്ളി", "ശനി" ], + dayNamesMin: [ "ഞാ","തി","ചൊ","ബു","വ്യാ","വെ","ശ" ], + weekHeader: "ആ", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ml ); + +return datepicker.regional.ml; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ms.js b/common/js/plugins/ui/i18n/datepicker-ms.js new file mode 100644 index 000000000..58bc4f579 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ms.js @@ -0,0 +1,37 @@ +/* Malaysian initialisation for the jQuery UI date picker plugin. */ +/* Written by Mohd Nawawi Mohamad Jamili (nawawi@ronggeng.net). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ms = { + closeText: "Tutup", + prevText: "<Sebelum", + nextText: "Selepas>", + currentText: "hari ini", + monthNames: [ "Januari","Februari","Mac","April","Mei","Jun", + "Julai","Ogos","September","Oktober","November","Disember" ], + monthNamesShort: [ "Jan","Feb","Mac","Apr","Mei","Jun", + "Jul","Ogo","Sep","Okt","Nov","Dis" ], + dayNames: [ "Ahad","Isnin","Selasa","Rabu","Khamis","Jumaat","Sabtu" ], + dayNamesShort: [ "Aha","Isn","Sel","Rab","kha","Jum","Sab" ], + dayNamesMin: [ "Ah","Is","Se","Ra","Kh","Ju","Sa" ], + weekHeader: "Mg", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ms ); + +return datepicker.regional.ms; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-nb.js b/common/js/plugins/ui/i18n/datepicker-nb.js new file mode 100644 index 000000000..128f6836d --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-nb.js @@ -0,0 +1,36 @@ +/* Norwegian Bokmål initialisation for the jQuery UI date picker plugin. */ +/* Written by Bjørn Johansen (post@bjornjohansen.no). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.nb = { + closeText: "Lukk", + prevText: "«Forrige", + nextText: "Neste»", + currentText: "I dag", + monthNames: [ "januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember" ], + monthNamesShort: [ "jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des" ], + dayNamesShort: [ "søn","man","tir","ons","tor","fre","lør" ], + dayNames: [ "søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag" ], + dayNamesMin: [ "sø","ma","ti","on","to","fr","lø" ], + weekHeader: "Uke", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" +}; +datepicker.setDefaults( datepicker.regional.nb ); + +return datepicker.regional.nb; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-nl-BE.js b/common/js/plugins/ui/i18n/datepicker-nl-BE.js new file mode 100644 index 000000000..9ea22002d --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-nl-BE.js @@ -0,0 +1,37 @@ +/* Dutch (Belgium) initialisation for the jQuery UI date picker plugin. */ +/* David De Sloovere @DavidDeSloovere */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "nl-BE" ] = { + closeText: "Sluiten", + prevText: "←", + nextText: "→", + currentText: "Vandaag", + monthNames: [ "januari", "februari", "maart", "april", "mei", "juni", + "juli", "augustus", "september", "oktober", "november", "december" ], + monthNamesShort: [ "jan", "feb", "mrt", "apr", "mei", "jun", + "jul", "aug", "sep", "okt", "nov", "dec" ], + dayNames: [ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" ], + dayNamesShort: [ "zon", "maa", "din", "woe", "don", "vri", "zat" ], + dayNamesMin: [ "zo", "ma", "di", "wo", "do", "vr", "za" ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "nl-BE" ] ); + +return datepicker.regional[ "nl-BE" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-nl.js b/common/js/plugins/ui/i18n/datepicker-nl.js new file mode 100644 index 000000000..7fcbff1ac --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-nl.js @@ -0,0 +1,37 @@ +/* Dutch (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Mathias Bynens */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.nl = { + closeText: "Sluiten", + prevText: "←", + nextText: "→", + currentText: "Vandaag", + monthNames: [ "januari", "februari", "maart", "april", "mei", "juni", + "juli", "augustus", "september", "oktober", "november", "december" ], + monthNamesShort: [ "jan", "feb", "mrt", "apr", "mei", "jun", + "jul", "aug", "sep", "okt", "nov", "dec" ], + dayNames: [ "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" ], + dayNamesShort: [ "zon", "maa", "din", "woe", "don", "vri", "zat" ], + dayNamesMin: [ "zo", "ma", "di", "wo", "do", "vr", "za" ], + weekHeader: "Wk", + dateFormat: "dd-mm-yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.nl ); + +return datepicker.regional.nl; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-nn.js b/common/js/plugins/ui/i18n/datepicker-nn.js new file mode 100644 index 000000000..dfaec387b --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-nn.js @@ -0,0 +1,36 @@ +/* Norwegian Nynorsk initialisation for the jQuery UI date picker plugin. */ +/* Written by Bjørn Johansen (post@bjornjohansen.no). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.nn = { + closeText: "Lukk", + prevText: "«Førre", + nextText: "Neste»", + currentText: "I dag", + monthNames: [ "januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember" ], + monthNamesShort: [ "jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des" ], + dayNamesShort: [ "sun","mån","tys","ons","tor","fre","lau" ], + dayNames: [ "sundag","måndag","tysdag","onsdag","torsdag","fredag","laurdag" ], + dayNamesMin: [ "su","må","ty","on","to","fr","la" ], + weekHeader: "Veke", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" +}; +datepicker.setDefaults( datepicker.regional.nn ); + +return datepicker.regional.nn; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-no.js b/common/js/plugins/ui/i18n/datepicker-no.js new file mode 100644 index 000000000..559aa111b --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-no.js @@ -0,0 +1,37 @@ +/* Norwegian initialisation for the jQuery UI date picker plugin. */ +/* Written by Naimdjon Takhirov (naimdjon@gmail.com). */ + +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.no = { + closeText: "Lukk", + prevText: "«Forrige", + nextText: "Neste»", + currentText: "I dag", + monthNames: [ "januar","februar","mars","april","mai","juni","juli","august","september","oktober","november","desember" ], + monthNamesShort: [ "jan","feb","mar","apr","mai","jun","jul","aug","sep","okt","nov","des" ], + dayNamesShort: [ "søn","man","tir","ons","tor","fre","lør" ], + dayNames: [ "søndag","mandag","tirsdag","onsdag","torsdag","fredag","lørdag" ], + dayNamesMin: [ "sø","ma","ti","on","to","fr","lø" ], + weekHeader: "Uke", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" +}; +datepicker.setDefaults( datepicker.regional.no ); + +return datepicker.regional.no; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-pl.js b/common/js/plugins/ui/i18n/datepicker-pl.js new file mode 100644 index 000000000..c2fddc132 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-pl.js @@ -0,0 +1,37 @@ +/* Polish initialisation for the jQuery UI date picker plugin. */ +/* Written by Jacek Wysocki (jacek.wysocki@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.pl = { + closeText: "Zamknij", + prevText: "<Poprzedni", + nextText: "Następny>", + currentText: "Dziś", + monthNames: [ "Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec", + "Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień" ], + monthNamesShort: [ "Sty","Lu","Mar","Kw","Maj","Cze", + "Lip","Sie","Wrz","Pa","Lis","Gru" ], + dayNames: [ "Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota" ], + dayNamesShort: [ "Nie","Pn","Wt","Śr","Czw","Pt","So" ], + dayNamesMin: [ "N","Pn","Wt","Śr","Cz","Pt","So" ], + weekHeader: "Tydz", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.pl ); + +return datepicker.regional.pl; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-pt-BR.js b/common/js/plugins/ui/i18n/datepicker-pt-BR.js new file mode 100644 index 000000000..c4c0d541c --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-pt-BR.js @@ -0,0 +1,37 @@ +/* Brazilian initialisation for the jQuery UI date picker plugin. */ +/* Written by Leonildo Costa Silva (leocsilva@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "pt-BR" ] = { + closeText: "Fechar", + prevText: "<Anterior", + nextText: "Próximo>", + currentText: "Hoje", + monthNames: [ "Janeiro","Fevereiro","Março","Abril","Maio","Junho", + "Julho","Agosto","Setembro","Outubro","Novembro","Dezembro" ], + monthNamesShort: [ "Jan","Fev","Mar","Abr","Mai","Jun", + "Jul","Ago","Set","Out","Nov","Dez" ], + dayNames: [ "Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado" ], + dayNamesShort: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ], + dayNamesMin: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ], + weekHeader: "Sm", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "pt-BR" ] ); + +return datepicker.regional[ "pt-BR" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-pt.js b/common/js/plugins/ui/i18n/datepicker-pt.js new file mode 100644 index 000000000..baed7f3de --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-pt.js @@ -0,0 +1,36 @@ +/* Portuguese initialisation for the jQuery UI date picker plugin. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.pt = { + closeText: "Fechar", + prevText: "Anterior", + nextText: "Seguinte", + currentText: "Hoje", + monthNames: [ "Janeiro","Fevereiro","Março","Abril","Maio","Junho", + "Julho","Agosto","Setembro","Outubro","Novembro","Dezembro" ], + monthNamesShort: [ "Jan","Fev","Mar","Abr","Mai","Jun", + "Jul","Ago","Set","Out","Nov","Dez" ], + dayNames: [ "Domingo","Segunda-feira","Terça-feira","Quarta-feira","Quinta-feira","Sexta-feira","Sábado" ], + dayNamesShort: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ], + dayNamesMin: [ "Dom","Seg","Ter","Qua","Qui","Sex","Sáb" ], + weekHeader: "Sem", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.pt ); + +return datepicker.regional.pt; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-rm.js b/common/js/plugins/ui/i18n/datepicker-rm.js new file mode 100644 index 000000000..856c8c254 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-rm.js @@ -0,0 +1,35 @@ +/* Romansh initialisation for the jQuery UI date picker plugin. */ +/* Written by Yvonne Gienal (yvonne.gienal@educa.ch). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.rm = { + closeText: "Serrar", + prevText: "<Suandant", + nextText: "Precedent>", + currentText: "Actual", + monthNames: [ "Schaner","Favrer","Mars","Avrigl","Matg","Zercladur", "Fanadur","Avust","Settember","October","November","December" ], + monthNamesShort: [ "Scha","Fev","Mar","Avr","Matg","Zer", "Fan","Avu","Sett","Oct","Nov","Dec" ], + dayNames: [ "Dumengia","Glindesdi","Mardi","Mesemna","Gievgia","Venderdi","Sonda" ], + dayNamesShort: [ "Dum","Gli","Mar","Mes","Gie","Ven","Som" ], + dayNamesMin: [ "Du","Gl","Ma","Me","Gi","Ve","So" ], + weekHeader: "emna", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.rm ); + +return datepicker.regional.rm; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ro.js b/common/js/plugins/ui/i18n/datepicker-ro.js new file mode 100644 index 000000000..b26665c25 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ro.js @@ -0,0 +1,40 @@ +/* Romanian initialisation for the jQuery UI date picker plugin. + * + * Written by Edmond L. (ll_edmond@walla.com) + * and Ionut G. Stan (ionut.g.stan@gmail.com) + */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ro = { + closeText: "Închide", + prevText: "« Luna precedentă", + nextText: "Luna următoare »", + currentText: "Azi", + monthNames: [ "Ianuarie","Februarie","Martie","Aprilie","Mai","Iunie", + "Iulie","August","Septembrie","Octombrie","Noiembrie","Decembrie" ], + monthNamesShort: [ "Ian", "Feb", "Mar", "Apr", "Mai", "Iun", + "Iul", "Aug", "Sep", "Oct", "Nov", "Dec" ], + dayNames: [ "Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă" ], + dayNamesShort: [ "Dum", "Lun", "Mar", "Mie", "Joi", "Vin", "Sâm" ], + dayNamesMin: [ "Du","Lu","Ma","Mi","Jo","Vi","Sâ" ], + weekHeader: "Săpt", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ro ); + +return datepicker.regional.ro; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ru.js b/common/js/plugins/ui/i18n/datepicker-ru.js new file mode 100644 index 000000000..223e77645 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ru.js @@ -0,0 +1,37 @@ +/* Russian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Andrew Stromnov (stromnov@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ru = { + closeText: "Закрыть", + prevText: "<Пред", + nextText: "След>", + currentText: "Сегодня", + monthNames: [ "Январь","Февраль","Март","Апрель","Май","Июнь", + "Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь" ], + monthNamesShort: [ "Янв","Фев","Мар","Апр","Май","Июн", + "Июл","Авг","Сен","Окт","Ноя","Дек" ], + dayNames: [ "воскресенье","понедельник","вторник","среда","четверг","пятница","суббота" ], + dayNamesShort: [ "вск","пнд","втр","срд","чтв","птн","сбт" ], + dayNamesMin: [ "Вс","Пн","Вт","Ср","Чт","Пт","Сб" ], + weekHeader: "Нед", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ru ); + +return datepicker.regional.ru; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-sk.js b/common/js/plugins/ui/i18n/datepicker-sk.js new file mode 100644 index 000000000..16d8bdfe4 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-sk.js @@ -0,0 +1,37 @@ +/* Slovak initialisation for the jQuery UI date picker plugin. */ +/* Written by Vojtech Rinik (vojto@hmm.sk). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.sk = { + closeText: "Zavrieť", + prevText: "<Predchádzajúci", + nextText: "Nasledujúci>", + currentText: "Dnes", + monthNames: [ "január","február","marec","apríl","máj","jún", + "júl","august","september","október","november","december" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Máj","Jún", + "Júl","Aug","Sep","Okt","Nov","Dec" ], + dayNames: [ "nedeľa","pondelok","utorok","streda","štvrtok","piatok","sobota" ], + dayNamesShort: [ "Ned","Pon","Uto","Str","Štv","Pia","Sob" ], + dayNamesMin: [ "Ne","Po","Ut","St","Št","Pia","So" ], + weekHeader: "Ty", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.sk ); + +return datepicker.regional.sk; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-sl.js b/common/js/plugins/ui/i18n/datepicker-sl.js new file mode 100644 index 000000000..689162492 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-sl.js @@ -0,0 +1,38 @@ +/* Slovenian initialisation for the jQuery UI date picker plugin. */ +/* Written by Jaka Jancar (jaka@kubje.org). */ +/* c = č, s = š z = ž C = Č S = Š Z = Ž */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.sl = { + closeText: "Zapri", + prevText: "<Prejšnji", + nextText: "Naslednji>", + currentText: "Trenutni", + monthNames: [ "Januar","Februar","Marec","April","Maj","Junij", + "Julij","Avgust","September","Oktober","November","December" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun", + "Jul","Avg","Sep","Okt","Nov","Dec" ], + dayNames: [ "Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota" ], + dayNamesShort: [ "Ned","Pon","Tor","Sre","Čet","Pet","Sob" ], + dayNamesMin: [ "Ne","Po","To","Sr","Če","Pe","So" ], + weekHeader: "Teden", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.sl ); + +return datepicker.regional.sl; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-sq.js b/common/js/plugins/ui/i18n/datepicker-sq.js new file mode 100644 index 000000000..34fe66a59 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-sq.js @@ -0,0 +1,37 @@ +/* Albanian initialisation for the jQuery UI date picker plugin. */ +/* Written by Flakron Bytyqi (flakron@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.sq = { + closeText: "mbylle", + prevText: "<mbrapa", + nextText: "Përpara>", + currentText: "sot", + monthNames: [ "Janar","Shkurt","Mars","Prill","Maj","Qershor", + "Korrik","Gusht","Shtator","Tetor","Nëntor","Dhjetor" ], + monthNamesShort: [ "Jan","Shk","Mar","Pri","Maj","Qer", + "Kor","Gus","Sht","Tet","Nën","Dhj" ], + dayNames: [ "E Diel","E Hënë","E Martë","E Mërkurë","E Enjte","E Premte","E Shtune" ], + dayNamesShort: [ "Di","Hë","Ma","Më","En","Pr","Sh" ], + dayNamesMin: [ "Di","Hë","Ma","Më","En","Pr","Sh" ], + weekHeader: "Ja", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.sq ); + +return datepicker.regional.sq; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-sr-SR.js b/common/js/plugins/ui/i18n/datepicker-sr-SR.js new file mode 100644 index 000000000..e9db26a42 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-sr-SR.js @@ -0,0 +1,37 @@ +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "sr-SR" ] = { + closeText: "Zatvori", + prevText: "<", + nextText: ">", + currentText: "Danas", + monthNames: [ "Januar","Februar","Mart","April","Maj","Jun", + "Jul","Avgust","Septembar","Oktobar","Novembar","Decembar" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun", + "Jul","Avg","Sep","Okt","Nov","Dec" ], + dayNames: [ "Nedelja","Ponedeljak","Utorak","Sreda","Četvrtak","Petak","Subota" ], + dayNamesShort: [ "Ned","Pon","Uto","Sre","Čet","Pet","Sub" ], + dayNamesMin: [ "Ne","Po","Ut","Sr","Če","Pe","Su" ], + weekHeader: "Sed", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional[ "sr-SR" ] ); + +return datepicker.regional[ "sr-SR" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-sr.js b/common/js/plugins/ui/i18n/datepicker-sr.js new file mode 100644 index 000000000..fa8827aa1 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-sr.js @@ -0,0 +1,37 @@ +/* Serbian i18n for the jQuery UI date picker plugin. */ +/* Written by Dejan Dimić. */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.sr = { + closeText: "Затвори", + prevText: "<", + nextText: ">", + currentText: "Данас", + monthNames: [ "Јануар","Фебруар","Март","Април","Мај","Јун", + "Јул","Август","Септембар","Октобар","Новембар","Децембар" ], + monthNamesShort: [ "Јан","Феб","Мар","Апр","Мај","Јун", + "Јул","Авг","Сеп","Окт","Нов","Дец" ], + dayNames: [ "Недеља","Понедељак","Уторак","Среда","Четвртак","Петак","Субота" ], + dayNamesShort: [ "Нед","Пон","Уто","Сре","Чет","Пет","Суб" ], + dayNamesMin: [ "Не","По","Ут","Ср","Че","Пе","Су" ], + weekHeader: "Сед", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.sr ); + +return datepicker.regional.sr; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-sv.js b/common/js/plugins/ui/i18n/datepicker-sv.js new file mode 100644 index 000000000..92686efa4 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-sv.js @@ -0,0 +1,37 @@ +/* Swedish initialisation for the jQuery UI date picker plugin. */ +/* Written by Anders Ekdahl ( anders@nomadiz.se). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.sv = { + closeText: "Stäng", + prevText: "«Förra", + nextText: "Nästa»", + currentText: "Idag", + monthNames: [ "Januari","Februari","Mars","April","Maj","Juni", + "Juli","Augusti","September","Oktober","November","December" ], + monthNamesShort: [ "Jan","Feb","Mar","Apr","Maj","Jun", + "Jul","Aug","Sep","Okt","Nov","Dec" ], + dayNamesShort: [ "Sön","Mån","Tis","Ons","Tor","Fre","Lör" ], + dayNames: [ "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag" ], + dayNamesMin: [ "Sö","Må","Ti","On","To","Fr","Lö" ], + weekHeader: "Ve", + dateFormat: "yy-mm-dd", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.sv ); + +return datepicker.regional.sv; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-ta.js b/common/js/plugins/ui/i18n/datepicker-ta.js new file mode 100644 index 000000000..e3f09b00c --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-ta.js @@ -0,0 +1,37 @@ +/* Tamil (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by S A Sureshkumar (saskumar@live.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.ta = { + closeText: "மூடு", + prevText: "முன்னையது", + nextText: "அடுத்தது", + currentText: "இன்று", + monthNames: [ "தை","மாசி","பங்குனி","சித்திரை","வைகாசி","ஆனி", + "ஆடி","ஆவணி","புரட்டாசி","ஐப்பசி","கார்த்திகை","மார்கழி" ], + monthNamesShort: [ "தை","மாசி","பங்","சித்","வைகா","ஆனி", + "ஆடி","ஆவ","புர","ஐப்","கார்","மார்" ], + dayNames: [ "ஞாயிற்றுக்கிழமை","திங்கட்கிழமை","செவ்வாய்க்கிழமை","புதன்கிழமை","வியாழக்கிழமை","வெள்ளிக்கிழமை","சனிக்கிழமை" ], + dayNamesShort: [ "ஞாயிறு","திங்கள்","செவ்வாய்","புதன்","வியாழன்","வெள்ளி","சனி" ], + dayNamesMin: [ "ஞா","தி","செ","பு","வி","வெ","ச" ], + weekHeader: "Не", + dateFormat: "dd/mm/yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.ta ); + +return datepicker.regional.ta; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-th.js b/common/js/plugins/ui/i18n/datepicker-th.js new file mode 100644 index 000000000..6de48cf96 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-th.js @@ -0,0 +1,37 @@ +/* Thai initialisation for the jQuery UI date picker plugin. */ +/* Written by pipo (pipo@sixhead.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.th = { + closeText: "ปิด", + prevText: "« ย้อน", + nextText: "ถัดไป »", + currentText: "วันนี้", + monthNames: [ "มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน", + "กรกฎาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม" ], + monthNamesShort: [ "ม.ค.","ก.พ.","มี.ค.","เม.ย.","พ.ค.","มิ.ย.", + "ก.ค.","ส.ค.","ก.ย.","ต.ค.","พ.ย.","ธ.ค." ], + dayNames: [ "อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัสบดี","ศุกร์","เสาร์" ], + dayNamesShort: [ "อา.","จ.","อ.","พ.","พฤ.","ศ.","ส." ], + dayNamesMin: [ "อา.","จ.","อ.","พ.","พฤ.","ศ.","ส." ], + weekHeader: "Wk", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.th ); + +return datepicker.regional.th; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-tj.js b/common/js/plugins/ui/i18n/datepicker-tj.js new file mode 100644 index 000000000..8ede4ddcb --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-tj.js @@ -0,0 +1,37 @@ +/* Tajiki (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Abdurahmon Saidov (saidovab@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.tj = { + closeText: "Идома", + prevText: "<Қафо", + nextText: "Пеш>", + currentText: "Имрӯз", + monthNames: [ "Январ","Феврал","Март","Апрел","Май","Июн", + "Июл","Август","Сентябр","Октябр","Ноябр","Декабр" ], + monthNamesShort: [ "Янв","Фев","Мар","Апр","Май","Июн", + "Июл","Авг","Сен","Окт","Ноя","Дек" ], + dayNames: [ "якшанбе","душанбе","сешанбе","чоршанбе","панҷшанбе","ҷумъа","шанбе" ], + dayNamesShort: [ "якш","душ","сеш","чор","пан","ҷум","шан" ], + dayNamesMin: [ "Як","Дш","Сш","Чш","Пш","Ҷм","Шн" ], + weekHeader: "Хф", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.tj ); + +return datepicker.regional.tj; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-tr.js b/common/js/plugins/ui/i18n/datepicker-tr.js new file mode 100644 index 000000000..8328e2199 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-tr.js @@ -0,0 +1,37 @@ +/* Turkish initialisation for the jQuery UI date picker plugin. */ +/* Written by Izzet Emre Erkan (kara@karalamalar.net). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.tr = { + closeText: "kapat", + prevText: "<geri", + nextText: "ileri>", + currentText: "bugün", + monthNames: [ "Ocak","Şubat","Mart","Nisan","Mayıs","Haziran", + "Temmuz","Ağustos","Eylül","Ekim","Kasım","Aralık" ], + monthNamesShort: [ "Oca","Şub","Mar","Nis","May","Haz", + "Tem","Ağu","Eyl","Eki","Kas","Ara" ], + dayNames: [ "Pazar","Pazartesi","Salı","Çarşamba","Perşembe","Cuma","Cumartesi" ], + dayNamesShort: [ "Pz","Pt","Sa","Ça","Pe","Cu","Ct" ], + dayNamesMin: [ "Pz","Pt","Sa","Ça","Pe","Cu","Ct" ], + weekHeader: "Hf", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.tr ); + +return datepicker.regional.tr; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-uk.js b/common/js/plugins/ui/i18n/datepicker-uk.js new file mode 100644 index 000000000..c82501ad2 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-uk.js @@ -0,0 +1,38 @@ +/* Ukrainian (UTF-8) initialisation for the jQuery UI date picker plugin. */ +/* Written by Maxim Drogobitskiy (maxdao@gmail.com). */ +/* Corrected by Igor Milla (igor.fsp.milla@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.uk = { + closeText: "Закрити", + prevText: "<", + nextText: ">", + currentText: "Сьогодні", + monthNames: [ "Січень","Лютий","Березень","Квітень","Травень","Червень", + "Липень","Серпень","Вересень","Жовтень","Листопад","Грудень" ], + monthNamesShort: [ "Січ","Лют","Бер","Кві","Тра","Чер", + "Лип","Сер","Вер","Жов","Лис","Гру" ], + dayNames: [ "неділя","понеділок","вівторок","середа","четвер","п’ятниця","субота" ], + dayNamesShort: [ "нед","пнд","вів","срд","чтв","птн","сбт" ], + dayNamesMin: [ "Нд","Пн","Вт","Ср","Чт","Пт","Сб" ], + weekHeader: "Тиж", + dateFormat: "dd.mm.yy", + firstDay: 1, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.uk ); + +return datepicker.regional.uk; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-vi.js b/common/js/plugins/ui/i18n/datepicker-vi.js new file mode 100644 index 000000000..2c208ab71 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-vi.js @@ -0,0 +1,37 @@ +/* Vietnamese initialisation for the jQuery UI date picker plugin. */ +/* Translated by Le Thanh Huy (lthanhhuy@cit.ctu.edu.vn). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional.vi = { + closeText: "Đóng", + prevText: "<Trước", + nextText: "Tiếp>", + currentText: "Hôm nay", + monthNames: [ "Tháng Một", "Tháng Hai", "Tháng Ba", "Tháng Tư", "Tháng Năm", "Tháng Sáu", + "Tháng Bảy", "Tháng Tám", "Tháng Chín", "Tháng Mười", "Tháng Mười Một", "Tháng Mười Hai" ], + monthNamesShort: [ "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", + "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12" ], + dayNames: [ "Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy" ], + dayNamesShort: [ "CN", "T2", "T3", "T4", "T5", "T6", "T7" ], + dayNamesMin: [ "CN", "T2", "T3", "T4", "T5", "T6", "T7" ], + weekHeader: "Tu", + dateFormat: "dd/mm/yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: false, + yearSuffix: "" }; +datepicker.setDefaults( datepicker.regional.vi ); + +return datepicker.regional.vi; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-zh-CN.js b/common/js/plugins/ui/i18n/datepicker-zh-CN.js new file mode 100644 index 000000000..91f99b4ed --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-zh-CN.js @@ -0,0 +1,37 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Cloudream (cloudream@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "zh-CN" ] = { + closeText: "关闭", + prevText: "<上月", + nextText: "下月>", + currentText: "今天", + monthNames: [ "一月","二月","三月","四月","五月","六月", + "七月","八月","九月","十月","十一月","十二月" ], + monthNamesShort: [ "一月","二月","三月","四月","五月","六月", + "七月","八月","九月","十月","十一月","十二月" ], + dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ], + dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ], + dayNamesMin: [ "日","一","二","三","四","五","六" ], + weekHeader: "周", + dateFormat: "yy-mm-dd", + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "年" }; +datepicker.setDefaults( datepicker.regional[ "zh-CN" ] ); + +return datepicker.regional[ "zh-CN" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-zh-HK.js b/common/js/plugins/ui/i18n/datepicker-zh-HK.js new file mode 100644 index 000000000..27f02bc65 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-zh-HK.js @@ -0,0 +1,37 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by SCCY (samuelcychan@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "zh-HK" ] = { + closeText: "關閉", + prevText: "<上月", + nextText: "下月>", + currentText: "今天", + monthNames: [ "一月","二月","三月","四月","五月","六月", + "七月","八月","九月","十月","十一月","十二月" ], + monthNamesShort: [ "一月","二月","三月","四月","五月","六月", + "七月","八月","九月","十月","十一月","十二月" ], + dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ], + dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ], + dayNamesMin: [ "日","一","二","三","四","五","六" ], + weekHeader: "周", + dateFormat: "dd-mm-yy", + firstDay: 0, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "年" }; +datepicker.setDefaults( datepicker.regional[ "zh-HK" ] ); + +return datepicker.regional[ "zh-HK" ]; + +} ) ); diff --git a/common/js/plugins/ui/i18n/datepicker-zh-TW.js b/common/js/plugins/ui/i18n/datepicker-zh-TW.js new file mode 100644 index 000000000..c20754bd5 --- /dev/null +++ b/common/js/plugins/ui/i18n/datepicker-zh-TW.js @@ -0,0 +1,37 @@ +/* Chinese initialisation for the jQuery UI date picker plugin. */ +/* Written by Ressol (ressol@gmail.com). */ +( function( factory ) { + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "../widgets/datepicker" ], factory ); + } else { + + // Browser globals + factory( jQuery.datepicker ); + } +}( function( datepicker ) { + +datepicker.regional[ "zh-TW" ] = { + closeText: "關閉", + prevText: "<上月", + nextText: "下月>", + currentText: "今天", + monthNames: [ "一月","二月","三月","四月","五月","六月", + "七月","八月","九月","十月","十一月","十二月" ], + monthNamesShort: [ "一月","二月","三月","四月","五月","六月", + "七月","八月","九月","十月","十一月","十二月" ], + dayNames: [ "星期日","星期一","星期二","星期三","星期四","星期五","星期六" ], + dayNamesShort: [ "周日","周一","周二","周三","周四","周五","周六" ], + dayNamesMin: [ "日","一","二","三","四","五","六" ], + weekHeader: "周", + dateFormat: "yy/mm/dd", + firstDay: 1, + isRTL: false, + showMonthAfterYear: true, + yearSuffix: "年" }; +datepicker.setDefaults( datepicker.regional[ "zh-TW" ] ); + +return datepicker.regional[ "zh-TW" ]; + +} ) ); diff --git a/common/js/plugins/ui/plugin.load b/common/js/plugins/ui/plugin.load index 49fcfdc53..73e7053a1 100644 --- a/common/js/plugins/ui/plugin.load +++ b/common/js/plugins/ui/plugin.load @@ -1,3 +1,3 @@ jquery-ui.min.js jquery-ui.min.css -jquery.ui.datepicker-ko.js +rx_datepicker.js diff --git a/common/js/plugins/ui/rx_datepicker.js b/common/js/plugins/ui/rx_datepicker.js new file mode 100644 index 000000000..8c9c4d455 --- /dev/null +++ b/common/js/plugins/ui/rx_datepicker.js @@ -0,0 +1,7 @@ +/** + * @brief Load i18n file of datepicker + * @author MinSoo Kim + **/ +if(typeof current_lang !== "undefined" && current_lang !== 'en') { + jQuery.getScript(request_uri + "./common/js/plugins/ui/i18n/datepicker-"+ current_lang.replace("jp", "ja") +".js"); +} \ No newline at end of file From fab9e43c16b4fb8653f054beeec497374fea2346 Mon Sep 17 00:00:00 2001 From: MinSoo Kim Date: Tue, 23 Feb 2016 01:15:13 +0900 Subject: [PATCH 002/318] Clean up admin i18n css MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit element has the lang attribute as a default. so, we can clean up css files. 요소는 lang 속성을 가지고 있습니다. 이를 이용하면 css 파일을 정리할 수 있습니다. {$lang_type} 에 따른 css 를 불러오도록 HTMLDisplayHandler.php 에 정의되어 있지만, 한국어, 영어 외에는 파일이 존재하지 않습니다. (일본어도 _ja.css 파일은 부재) 언어별로 파일을 만들지 않아도 충분히 표현할 수 있기 때문에 이를 하나의 파일로 합칩니다. --- classes/display/HTMLDisplayHandler.php | 1 - modules/admin/tpl/css/admin.css | 33 +++++++++++++++++++ modules/admin/tpl/css/admin_en.css | 5 --- modules/admin/tpl/css/admin_jp.css | 5 --- modules/admin/tpl/css/admin_ko.css | 5 --- .../tpl/widget_generate_code_in_page.html | 2 -- .../widget_style_generate_code_in_page.html | 2 -- 7 files changed, 33 insertions(+), 20 deletions(-) delete mode 100644 modules/admin/tpl/css/admin_en.css delete mode 100644 modules/admin/tpl/css/admin_jp.css delete mode 100644 modules/admin/tpl/css/admin_ko.css diff --git a/classes/display/HTMLDisplayHandler.php b/classes/display/HTMLDisplayHandler.php index 2254c2694..cf2556c27 100644 --- a/classes/display/HTMLDisplayHandler.php +++ b/classes/display/HTMLDisplayHandler.php @@ -394,7 +394,6 @@ class HTMLDisplayHandler if(Context::get('module') == 'admin' || strpos(Context::get('act'), 'Admin') > 0) { Context::loadFile(array('./modules/admin/tpl/css/admin.css', '', '', 10), true); - Context::loadFile(array("./modules/admin/tpl/css/admin_{$lang_type}.css", '', '', 10), true); Context::loadFile(array("./modules/admin/tpl/css/admin.iefix.css", '', 'ie', 10), true); Context::loadFile('./modules/admin/tpl/js/admin.js', true); Context::loadFile(array('./modules/admin/tpl/css/admin.bootstrap.css', '', '', 1), true); diff --git a/modules/admin/tpl/css/admin.css b/modules/admin/tpl/css/admin.css index b0180e4c0..efe7a46fd 100644 --- a/modules/admin/tpl/css/admin.css +++ b/modules/admin/tpl/css/admin.css @@ -2389,3 +2389,36 @@ html[lang="mn"] .x .g11n.active>[disabled], height: 1px; overflow: hidden; } + +/* language specific styles */ +/* English admin_en.css */ +html:lang(en) body>.x, +html:lang(en) .x table, +html:lang(en) .x input, +html:lang(en) .x textarea, +html:lang(en) .x select, +html:lang(en) .x button{font-family:Arial,Helvetica,sans-serif} +@media all and (max-width:980px){ + html:lang(en) body>.x, + html:lang(en) .x table, + html:lang(en) .x input, + html:lang(en) .x textarea, + html:lang(en) .x select, + html:lang(en) .x button{font-family:sans-serif} +} + +/* Korean admin_ko.css */ +html:lang(ko) body>.x, +html:lang(ko) .x table, +html:lang(ko) .x input, +html:lang(ko) .x textarea, +html:lang(ko) .x select, +html:lang(ko) .x button{font-family:'나눔고딕',NanumGothic,'맑은 고딕','Apple SD Gothic Neo','돋움',Dotum,Arial,Helvetica,sans-serif} + +/* Japanese admin_jp.css */ +html:lang(ja) body>.x, +html:lang(ja) .x table, +html:lang(ja) .x input, +html:lang(ja) .x textarea, +html:lang(ja) .x select, +html:lang(ja) .x button{font-family:'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック',sans-serif} \ No newline at end of file diff --git a/modules/admin/tpl/css/admin_en.css b/modules/admin/tpl/css/admin_en.css deleted file mode 100644 index 6cbb6efe0..000000000 --- a/modules/admin/tpl/css/admin_en.css +++ /dev/null @@ -1,5 +0,0 @@ -@charset "utf-8"; -body>.x,.x table,.x input,.x textarea,.x select,.x button{font-family:Arial,Helvetica,sans-serif} -@media all and (max-width:980px){ -body>.x,.x table,.x input,.x textarea,.x select,.x button{font-family:sans-serif} -} \ No newline at end of file diff --git a/modules/admin/tpl/css/admin_jp.css b/modules/admin/tpl/css/admin_jp.css deleted file mode 100644 index 178114846..000000000 --- a/modules/admin/tpl/css/admin_jp.css +++ /dev/null @@ -1,5 +0,0 @@ -@charset "utf-8"; -body>.x,.x table,.x input,.x textarea,.x select,.x button{font-family:'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック',sans-serif} -@media all and (max-width:980px){ -body>.x,.x table,.x input,.x textarea,.x select,.x button{font-family:'ヒラギノ角ゴ Pro W3','Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック',sans-serif} -} \ No newline at end of file diff --git a/modules/admin/tpl/css/admin_ko.css b/modules/admin/tpl/css/admin_ko.css deleted file mode 100644 index d16de3ca5..000000000 --- a/modules/admin/tpl/css/admin_ko.css +++ /dev/null @@ -1,5 +0,0 @@ -@charset "utf-8"; -body>.x,.x table,.x input,.x textarea,.x select,.x button{font-family:나눔고딕,NanumGothic,돋움,Dotum,Arial,Helvetica,sans-serif} -@media all and (max-width:980px){ -body>.x,.x table,.x input,.x textarea,.x select,.x button{font-family:sans-serif} -} \ No newline at end of file diff --git a/modules/widget/tpl/widget_generate_code_in_page.html b/modules/widget/tpl/widget_generate_code_in_page.html index 1780a887d..d6cf20908 100644 --- a/modules/widget/tpl/widget_generate_code_in_page.html +++ b/modules/widget/tpl/widget_generate_code_in_page.html @@ -1,7 +1,5 @@ - - diff --git a/modules/widget/tpl/widget_style_generate_code_in_page.html b/modules/widget/tpl/widget_style_generate_code_in_page.html index ab3d1327e..25c6b0f01 100644 --- a/modules/widget/tpl/widget_style_generate_code_in_page.html +++ b/modules/widget/tpl/widget_style_generate_code_in_page.html @@ -1,7 +1,5 @@ - - From c9ed1f08e97d6fb84aeba20a261b71e9cd5dc6bf Mon Sep 17 00:00:00 2001 From: MinSoo Kim Date: Tue, 23 Feb 2016 04:13:14 +0900 Subject: [PATCH 003/318] =?UTF-8?q?datepicker=20=EA=B0=80=20=EB=82=B4?= =?UTF-8?q?=EC=9E=A5=EB=90=9C=20=EB=B8=8C=EB=9D=BC=EC=9A=B0=EC=A0=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=EB=8A=94=20=EB=82=B4=EC=9E=A5=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/counter/tpl/index.html | 2 +- modules/member/member.admin.view.php | 4 +- modules/member/member.controller.php | 142 +++++++++++++++++- modules/member/skins/default/modify_info.html | 31 +++- modules/member/skins/default/signup_form.html | 35 +++-- modules/member/tpl/insert_member.html | 32 +++- modules/poll/poll.controller.php | 2 +- 7 files changed, 213 insertions(+), 35 deletions(-) diff --git a/modules/counter/tpl/index.html b/modules/counter/tpl/index.html index 04884cbc7..e8c58f4b7 100644 --- a/modules/counter/tpl/index.html +++ b/modules/counter/tpl/index.html @@ -47,7 +47,7 @@ } }; - $.extend(option,$.datepicker.regional['{$lang_type}']); + $.extend($.datepicker.regional['{$lang_type}'],option); $(".inputDate").datepicker(option); }); })(jQuery); diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index 21e3d6ba8..04ba47687 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -486,7 +486,7 @@ class memberAdminView extends member else if($formInfo->name == 'birthday') { $formTag->type = 'date'; - $inputTag = sprintf(' ', + $inputTag = sprintf(' ', $memberInfo['birthday'], zdate($memberInfo['birthday'], 'Y-m-d', false), $lang->cmd_delete); @@ -627,7 +627,7 @@ class memberAdminView extends member else if($extendForm->column_type == 'date') { $extentionReplace = array('date' => zdate($extendForm->value, 'Y-m-d'), 'cmd_delete' => $lang->cmd_delete); - $template = ' '; + $template = ' '; } $replace = array_merge($extentionReplace, $replace); diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index c99dc0062..c9829021b 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -301,7 +301,16 @@ class memberController extends member $args->{$val} = Context::get($val); if($val == 'birthday') $args->birthday_ui = Context::get('birthday_ui'); } - $args->birthday = intval(strtr($args->birthday, array('-'=>'', '/'=>'', '.'=>'', ' '=>''))); + + // mobile input date format can be different + if($args->birthday !== intval($args->birthday)) + { + $args->birthday = date('Ymd', strtotime($args->birthday)); + } + else + { + $args->birthday = intval($args->birthday); + } if(!$args->birthday && $args->birthday_ui) $args->birthday = intval(strtr($args->birthday_ui, array('-'=>'', '/'=>'', '.'=>'', ' '=>''))); $args->find_account_answer = Context::get('find_account_answer'); @@ -535,8 +544,18 @@ class memberController extends member // Login Information $logged_info = Context::get('logged_info'); $args->member_srl = $logged_info->member_srl; - $args->birthday = intval(strtr($args->birthday, array('-'=>'', '/'=>'', '.'=>'', ' '=>''))); + + // mobile input date format can be different + if($args->birthday !== intval($args->birthday)) + { + $args->birthday = date('Ymd', strtotime($args->birthday)); + } + else + { + $args->birthday = intval($args->birthday); + } if(!$args->birthday && $args->birthday_ui) $args->birthday = intval(strtr($args->birthday_ui, array('-'=>'', '/'=>'', '.'=>'', ' '=>''))); + // Remove some unnecessary variables from all the vars $all_args = Context::getRequestVars(); unset($all_args->module); @@ -1938,10 +1957,23 @@ class memberController extends member $output = ModuleHandler::triggerCall('member.insertMember', 'before', $args); if(!$output->toBool()) return $output; // Terms and Conditions portion of the information set up by members reaffirmed - $oModuleModel = getModel('module'); - $config = $oModuleModel->getModuleConfig('member'); + $oMemberModel = getModel('member'); + $config = $oMemberModel->getMemberConfig(); $logged_info = Context::get('logged_info'); + // limit_date format is YYYYMMDD + if($args->limit_date) + { + // mobile input date format can be different + if($args->limit_date !== intval($args->limit_date)) + { + $args->limit_date = date('Ymd', strtotime($args->limit_date)); + } + else + { + $args->limit_date = intval($args->limit_date); + } + } // If the date of the temporary restrictions limit further information on the date of if($config->limit_day) $args->limit_date = date("YmdHis", $_SERVER['REQUEST_TIME']+$config->limit_day*60*60*24); @@ -1980,6 +2012,49 @@ class memberController extends member 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; + + $extend_form_list = $oMemberModel->getCombineJoinForm($memberInfo); + $security = new Security($extend_form_list); + $security->encodeHTML('..column_title', '..description', '..default_value.'); + if($config->signupForm) { + foreach($config->signupForm as $no => $formInfo) + { + if(!$formInfo->isUse) continue; + if($formInfo->isDefaultForm) + { + // birthday format is YYYYMMDD + if($formInfo->name === 'birthday' && $args->{$formInfo->name}) + { + // mobile input date format can be different + if($args->{$formInfo->name} !== intval($args->{$formInfo->name})) + { + $args->{$formInfo->name} = date('Ymd', strtotime($args->{$formInfo->name})); + } + else + { + $args->{$formInfo->name} = intval($args->{$formInfo->name}); + } + } + } + else + { + $extendForm = $extend_form_list[$formInfo->member_join_form_srl]; + // date format is YYYYMMDD + if($extendForm->column_type == 'date' && $args->{$formInfo->name}) + { + if($args->{$formInfo->name} !== intval($args->{$formInfo->name})) + { + $args->{$formInfo->name} = date('Ymd', strtotime($args->{$formInfo->name})); + } + else + { + $args->{$formInfo->name} = intval($args->{$formInfo->name}); + } + } + } + } + } + // Create a model object $oMemberModel = getModel('member'); @@ -2096,7 +2171,6 @@ class memberController extends member } } - $member_config = $oModuleModel->getModuleConfig('member'); // When using email authentication mode (when you subscribed members denied a) certified mail sent if($args->denied == 'Y') { @@ -2146,6 +2220,7 @@ class memberController extends member if(!$output->toBool()) return $output; // Create a model object $oMemberModel = getModel('member'); + $config = $oMemberModel->getMemberConfig(); $logged_info = Context::get('logged_info'); // Get what you want to modify the original information @@ -2180,7 +2255,62 @@ class memberController extends member if($args->blog && !preg_match("/^[a-z]+:\/\//is",$args->blog)) $args->blog = 'http://'.$args->blog; // check member identifier form - $config = $oMemberModel->getMemberConfig(); + + // limit_date format is YYYYMMDD + if($args->limit_date) + { + // mobile input date format can be different + if($args->limit_date !== intval($args->limit_date)) + { + $args->limit_date = date('Ymd', strtotime($args->limit_date)); + } + else + { + $args->limit_date = intval($args->limit_date); + } + } + + $extend_form_list = $oMemberModel->getCombineJoinForm($memberInfo); + $security = new Security($extend_form_list); + $security->encodeHTML('..column_title', '..description', '..default_value.'); + if($config->signupForm){ + foreach($config->signupForm as $no => $formInfo) + { + if(!$formInfo->isUse) continue; + + if($formInfo->isDefaultForm) + { + // birthday format is YYYYMMDD + if($formInfo->name === 'birthday' && $args->{$formInfo->name}) + { + if($args->{$formInfo->name} !== intval($args->{$formInfo->name})) + { + $args->{$formInfo->name} = date('Ymd', strtotime($args->{$formInfo->name})); + } + else + { + $args->{$formInfo->name} = intval($args->{$formInfo->name}); + } + } + } + else + { + $extendForm = $extend_form_list[$formInfo->member_join_form_srl]; + // date format is YYYYMMDD + if($extendForm->column_type == 'date' && $args->{$formInfo->name}) + { + if($args->{$formInfo->name} !== intval($args->{$formInfo->name})) + { + $args->{$formInfo->name} = date('Ymd', strtotime($args->{$formInfo->name})); + } + else + { + $args->{$formInfo->name} = intval($args->{$formInfo->name}); + } + } + } + } + } $output = executeQuery('member.getMemberInfoByMemberSrl', $args); $orgMemberInfo = $output->data; diff --git a/modules/member/skins/default/modify_info.html b/modules/member/skins/default/modify_info.html index f09eefd3a..ced6dae08 100644 --- a/modules/member/skins/default/modify_info.html +++ b/modules/member/skins/default/modify_info.html @@ -66,16 +66,33 @@ jQuery(function($){ }); }); (function($){ - $(function(){ - var option = { changeMonth: true, changeYear: true, gotoCurrent: false,yearRange:'-100:+10', dateFormat:'yy-mm-dd', onSelect:function(){ - $(this).prev('input[type="hidden"]').val(this.value.replace(/-/g,""))} - }; - $.extend(option,$.datepicker.regional['{$lang_type}']); - $(".inputDate").datepicker(option); + $(function(){ + // check if the browser support type date. + if ( $(".inputDate").prop('type') != 'date' ) { + var option = { + changeMonth: true, + changeYear: true, + gotoCurrent: false, + yearRange:'-200:+10', + dateFormat:'yy-mm-dd', + defaultDate: new Date("{date('Y-m-d',time())}"), + minDate: new Date("{date('Y-m-d',strtotime('-200 years'))}"), + + onSelect:function(){ + $(this).prev('input[type="hidden"]').val(this.value.replace(/-/g,"")) + } + }; + $.extend($.datepicker.regional['{$lang_type}'],option); + + //if the browser does not support type date input, start datepicker. If it does, brower's UI will show their datepicker. + $(".inputDate").datepicker(option); + } else { + $(".inputDate").prop('readonly', false); + } $(".dateRemover").click(function() { $(this).prevAll('input').val(''); return false;}); - }); + }); })(jQuery); diff --git a/modules/member/skins/default/signup_form.html b/modules/member/skins/default/signup_form.html index cc6788c4e..b3d464d38 100644 --- a/modules/member/skins/default/signup_form.html +++ b/modules/member/skins/default/signup_form.html @@ -72,7 +72,7 @@ - + \ No newline at end of file diff --git a/modules/member/tpl/insert_member.html b/modules/member/tpl/insert_member.html index e76df5070..552c3d62d 100644 --- a/modules/member/tpl/insert_member.html +++ b/modules/member/tpl/insert_member.html @@ -88,7 +88,7 @@
- + {$lang->about_limit_date}
@@ -124,15 +124,31 @@ \ No newline at end of file diff --git a/modules/member/m.skins/default/signup_form.html b/modules/member/m.skins/default/signup_form.html index 62e0c1669..fffc40e05 100644 --- a/modules/member/m.skins/default/signup_form.html +++ b/modules/member/m.skins/default/signup_form.html @@ -1,5 +1,7 @@ + +

{$lang->cmd_signup}

@@ -58,3 +60,34 @@
+ \ No newline at end of file From e335aa477e7f35826fb90b25a691b6c5af19bf6b Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 23 Feb 2016 21:37:44 +0900 Subject: [PATCH 005/318] Initial implementation of blacklist function --- classes/context/Context.class.php | 25 +++++++++++++++++++++++++ common/defaults/blacklist.php | 11 +++++++++++ 2 files changed, 36 insertions(+) create mode 100644 common/defaults/blacklist.php diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index d3f6914ea..19e321bce 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -157,6 +157,11 @@ class Context */ public $isSuccessInit = TRUE; + /** + * Plugin blacklist cache + */ + private static $_blacklist = null; + /** * Singleton instance * @var object @@ -2566,6 +2571,26 @@ class Context return self::$_instance->allow_rewrite; } + /** + * Check whether an addon, module, or widget is blacklisted + * + * @param string $plugin_name + * @return bool + */ + public static function isBlacklistedPlugin($plugin_name) + { + if (self::$_blacklist === null) + { + self::$_blacklist = (include RX_BASEDIR . 'common/defaults/blacklist.php'); + if (!is_array(self::$_blacklist)) + { + self::$_blacklist = array(); + } + } + + return isset(self::$_blacklist[$plugin_name]); + } + /** * Converts a local path into an URL * diff --git a/common/defaults/blacklist.php b/common/defaults/blacklist.php new file mode 100644 index 000000000..ce91d5571 --- /dev/null +++ b/common/defaults/blacklist.php @@ -0,0 +1,11 @@ + true, + 'zipperupper' => true, +); From e0dba3a340dd05c28bb7ab82f42778eee24c52ea Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 23 Feb 2016 21:51:18 +0900 Subject: [PATCH 006/318] Do not activate blacklisted addons --- modules/addon/addon.admin.model.php | 14 ++++++++++++-- modules/addon/addon.class.php | 1 - modules/addon/addon.controller.php | 2 +- modules/addon/tpl/addon_list.html | 18 ++++++++++++------ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/modules/addon/addon.admin.model.php b/modules/addon/addon.admin.model.php index c49dbabd1..15ae24c50 100644 --- a/modules/addon/addon.admin.model.php +++ b/modules/addon/addon.admin.model.php @@ -46,13 +46,23 @@ class addonAdminModel extends addon $oAutoinstallModel = getModel('autoinstall'); foreach($addonList as $key => $addon) { + // check blacklist + $addonList[$key]->isBlacklisted = Context::isBlacklistedPlugin($addon->addon); + // get easyinstall remove url $packageSrl = $oAutoinstallModel->getPackageSrlByPath($addon->path); $addonList[$key]->remove_url = $oAutoinstallModel->getRemoveUrlByPackageSrl($packageSrl); // get easyinstall need update - $package = $oAutoinstallModel->getInstalledPackages($packageSrl); - $addonList[$key]->need_update = $package[$packageSrl]->need_update; + if($addonList[$key]->isBlacklisted) + { + $addonList[$key]->need_update = 'N'; + } + else + { + $package = $oAutoinstallModel->getInstalledPackages($packageSrl); + $addonList[$key]->need_update = $package[$packageSrl]->need_update; + } // get easyinstall update url if($addonList[$key]->need_update == 'Y') diff --git a/modules/addon/addon.class.php b/modules/addon/addon.class.php index bb605cd77..8eb142106 100644 --- a/modules/addon/addon.class.php +++ b/modules/addon/addon.class.php @@ -19,7 +19,6 @@ class addon extends ModuleObject $oAddonController = getAdminController('addon'); $oAddonController->doInsert('autolink', 0, 'site', 'Y'); $oAddonController->doInsert('blogapi'); - $oAddonController->doInsert('member_communication', 0, 'site', 'Y'); $oAddonController->doInsert('member_extra_info', 0, 'site', 'Y'); $oAddonController->doInsert('mobile', 0, 'site', 'Y'); $oAddonController->doInsert('resize_image', 0, 'site', 'Y'); diff --git a/modules/addon/addon.controller.php b/modules/addon/addon.controller.php index d647f62a2..2fd699187 100644 --- a/modules/addon/addon.controller.php +++ b/modules/addon/addon.controller.php @@ -84,7 +84,7 @@ class addonController extends addon $addon_list = $oAddonModel->getInsertedAddons($site_srl, $gtype); foreach($addon_list as $addon => $val) { - if($val->addon == "smartphone" + if($val->addon == "smartphone" || Context::isBlacklistedPlugin($addon) || ($type == "pc" && $val->is_used != 'Y') || ($type == "mobile" && $val->is_used_m != 'Y') || ($gtype == 'global' && $val->is_fixed != 'Y') diff --git a/modules/addon/tpl/addon_list.html b/modules/addon/tpl/addon_list.html index 11d746c9e..bed17e82a 100644 --- a/modules/addon/tpl/addon_list.html +++ b/modules/addon/tpl/addon_list.html @@ -34,23 +34,29 @@ -

{$addon->title}

+

{$addon->title}

{$addon->description}

{$lang->msg_avail_easy_update} {$lang->msg_do_you_like_update}

- {$addon->version} + {$addon->version} {$author->name} {$author->name} - {$addon->path} - {$lang->cmd_setup} - - + {$addon->path} + + + {$lang->cmd_setup} + + {$lang->cmd_setup} + + + + {$lang->cmd_delete} From 38b7a9201587bc3a033ae186d7c01fec98554564 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 23 Feb 2016 21:52:08 +0900 Subject: [PATCH 007/318] Remove [DEPRECATED] message from member_communication addon --- addons/member_communication/conf/info.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/addons/member_communication/conf/info.xml b/addons/member_communication/conf/info.xml index d9419aec7..3ae24aac0 100644 --- a/addons/member_communication/conf/info.xml +++ b/addons/member_communication/conf/info.xml @@ -1,16 +1,16 @@ - [DEPRECATED] 커뮤니케이션 - [DEPRECATED] コミュニケーション - [DEPRECATED] 会员交流 - [DEPRECATED] Communication - [DEPRECATED] Truyền thông - [DEPRECATED] Communication - [DEPRECATED] Communication - [DEPRECATED] Общение - [DEPRECATED] 交流 + 커뮤니케이션 + コミュニケーション + 会员交流 + Communication + Truyền thông + Communication + Communication + Общение + 交流 - [DEPRECATED] 이 애드온은 빈 애드온입니다. 모든 기능은 커뮤니케이션 모듈로 이전되었습니다. + 이 애드온은 빈 애드온입니다. 모든 기능은 커뮤니케이션 모듈로 이전되었습니다. 1.7 2013-11-27 @@ -28,4 +28,4 @@ - \ No newline at end of file + From 18c57787891b1362b84002131bbd4d6e588052f3 Mon Sep 17 00:00:00 2001 From: MinSoo Kim Date: Tue, 23 Feb 2016 21:58:59 +0900 Subject: [PATCH 008/318] =?UTF-8?q?=ED=95=9C=EA=B5=AD=EC=96=B4=20=EA=B8=80?= =?UTF-8?q?=EA=BC=B4=20=EC=9D=B4=EB=A6=84=EC=9D=84=20=EC=95=8C=ED=8C=8C?= =?UTF-8?q?=EB=B2=B3=20=EC=9D=B4=EB=A6=84=EC=9C=BC=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/admin/tpl/css/admin.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/admin/tpl/css/admin.css b/modules/admin/tpl/css/admin.css index efe7a46fd..a0d16fea2 100644 --- a/modules/admin/tpl/css/admin.css +++ b/modules/admin/tpl/css/admin.css @@ -2413,7 +2413,7 @@ html:lang(ko) .x table, html:lang(ko) .x input, html:lang(ko) .x textarea, html:lang(ko) .x select, -html:lang(ko) .x button{font-family:'나눔고딕',NanumGothic,'맑은 고딕','Apple SD Gothic Neo','돋움',Dotum,Arial,Helvetica,sans-serif} +html:lang(ko) .x button{font-family: 'NanumGothic', 'Malgun Gothic', 'Apple SD Gothic Neo', 'Dotum', Arial, Helvetica, sans-serif} /* Japanese admin_jp.css */ html:lang(ja) body>.x, From 87a3128af643790ddb4465fbdd33d41abfe5284d Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 24 Feb 2016 09:58:47 +0900 Subject: [PATCH 009/318] Fix #303 Unable to disable rewrite --- classes/context/Context.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index d3f6914ea..a7f99da66 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -482,7 +482,7 @@ class Context // Copy to old format for backward compatibility. self::$_instance->db_info = self::convertDBInfo($config); - self::$_instance->allow_rewrite = self::$_instance->db_info->use_rewrite; + self::$_instance->allow_rewrite = self::$_instance->db_info->use_rewrite === 'Y'; self::set('_http_port', self::$_instance->db_info->http_port ?: null); self::set('_https_port', self::$_instance->db_info->https_port ?: null); self::set('_use_ssl', self::$_instance->db_info->use_ssl); From 0b339a94502d52cd5f42e8a27394b715320a4fb0 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 24 Feb 2016 10:37:16 +0900 Subject: [PATCH 010/318] Fix #277 Incorrect priority when loading old lang files --- common/framework/compat/langparser.php | 2 +- common/framework/lang.php | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/common/framework/compat/langparser.php b/common/framework/compat/langparser.php index 6f4c299da..582019c81 100644 --- a/common/framework/compat/langparser.php +++ b/common/framework/compat/langparser.php @@ -70,7 +70,7 @@ class LangParser unset($xml); // Save the array as a cache file. - $buff = " $value) { if (is_array($value)) diff --git a/common/framework/lang.php b/common/framework/lang.php index ae6021a1b..ffbaa86cb 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -102,25 +102,21 @@ class Lang { $filename = $dir . '/' . $this->_language . '.php'; } - elseif (file_exists($dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php')) - { - $filename = $dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php'; - } elseif (($hyphen = strpos($this->_language, '-')) !== false) { if (file_exists($dir . '/' . substr($this->_language, 0, $hyphen) . '.php')) { $filename = $dir . '/' . substr($this->_language, 0, $hyphen) . '.php'; } - elseif (file_exists($dir . '/' . substr($this->_language, 0, $hyphen) . '.lang.php')) - { - $filename = $dir . '/' . substr($this->_language, 0, $hyphen) . '.lang.php'; - } } elseif (file_exists("$dir/lang.xml")) { $filename = Compat\LangParser::compileXMLtoPHP("$dir/lang.xml", $this->_language === 'ja' ? 'jp' : $this->_language); } + elseif (file_exists($dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php')) + { + $filename = $dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php'; + } // Load the language file. if ($filename) From d4a7b921d0ecc667a720ab75952420251180d2f9 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 25 Feb 2016 11:26:00 +0900 Subject: [PATCH 011/318] Do not call trigger for blacklisted modules --- classes/module/ModuleHandler.class.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index 1567df78b..9feee0660 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -1191,6 +1191,12 @@ class ModuleHandler extends Handler $type = $item->type; $called_method = $item->called_method; + // do not call if module is blacklisted + if (Context::isBlacklistedPlugin($module)) + { + continue; + } + // todo why don't we call a normal class object ? $oModule = getModule($module, $type); if(!$oModule || !method_exists($oModule, $called_method)) From ac1e86cf3992a224ed96a66de899a6d727ab5347 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 25 Feb 2016 14:26:00 +0900 Subject: [PATCH 012/318] Fix incorrect passing of SSL action list --- common/tpl/common_layout.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/tpl/common_layout.html b/common/tpl/common_layout.html index 264683074..d2859c612 100644 --- a/common/tpl/common_layout.html +++ b/common/tpl/common_layout.html @@ -51,7 +51,7 @@ var http_port = {Context::get("_http_port") ?: 'null'}; var https_port = {Context::get("_https_port") ?: 'null'}; var enforce_ssl = {Context::get('_use_ssl') === 'always' ? 'true' : 'false'}; - var ssl_actions = {json_encode(array_values(Context::getSSLActions()))}; + var ssl_actions = {json_encode(array_keys(Context::getSSLActions()))}; var xeVid = {json_encode($vid ?: null)}; From b94027bf1c451857d915fd2fdc4d3d6f78f670af Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 25 Feb 2016 14:52:07 +0900 Subject: [PATCH 013/318] Display more information if an AJAX request fails --- common/js/xml_handler.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index 2b049bdfe..5d0d9a940 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -134,8 +134,13 @@ // Hide the waiting message and display an error notice. clearTimeout(wfsr_timeout); waiting_obj.hide().trigger("cancel_confirm"); - var error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")"; - alert("AJAX communication error while requesting " + params.module + "." + params.act + "\n\n" + error_info); + if ($(".x_modal-body").size()) { + var error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "

" + xhr.responseText + "
"; + alert("AJAX communication error while requesting " + params.module + "." + params.act + "

" + error_info); + } else { + var error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "\n\n" + xhr.responseText; + alert("AJAX communication error while requesting " + params.module + "." + params.act + "\n\n" + error_info); + } }; // Send the AJAX request. From 4b81e32e22e028e9c76958ae400942e40afb3b45 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 25 Feb 2016 15:05:30 +0900 Subject: [PATCH 014/318] Do not display alert if Virtual XML request was successful --- classes/display/VirtualXMLDisplayHandler.php | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/classes/display/VirtualXMLDisplayHandler.php b/classes/display/VirtualXMLDisplayHandler.php index aa67ee21d..0d41f8bbe 100644 --- a/classes/display/VirtualXMLDisplayHandler.php +++ b/classes/display/VirtualXMLDisplayHandler.php @@ -24,11 +24,6 @@ class VirtualXMLDisplayHandler if($error === 0) { - if($message != 'success') - { - $output->message = $message; - } - if($redirect_url) { $output->url = $redirect_url; @@ -40,10 +35,7 @@ class VirtualXMLDisplayHandler } else { - if($message != 'fail') - { - $output->message = $message; - } + $output->message = $message; } $html = array(); @@ -52,12 +44,12 @@ class VirtualXMLDisplayHandler if($output->message) { - $html[] = 'alert("' . $output->message . '");'; + $html[] = 'alert(' . json_encode($output->message) . ');'; } if($output->url) { - $url = preg_replace('/#(.+)$/i', '', $output->url); + $url = preg_replace('/#(.+)$/', '', $output->url); $html[] = 'self.location.href = "' . $request_url . 'common/tpl/redirect.html?redirect_url=' . urlencode($url) . '";'; } $html[] = '//]]>'; From 892aa58540d2480180086ca1cfde9424f0bbe432 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 25 Feb 2016 15:11:51 +0900 Subject: [PATCH 015/318] Eliminate redundant redirect through redirect.html --- classes/display/VirtualXMLDisplayHandler.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/classes/display/VirtualXMLDisplayHandler.php b/classes/display/VirtualXMLDisplayHandler.php index 0d41f8bbe..124818aaa 100644 --- a/classes/display/VirtualXMLDisplayHandler.php +++ b/classes/display/VirtualXMLDisplayHandler.php @@ -39,8 +39,9 @@ class VirtualXMLDisplayHandler } $html = array(); - $html[] = ''; - + $html[] = ''; + return join(PHP_EOL, $html); } From 134c6f6ec130c36f123ba904f546dd2d939df569 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 25 Feb 2016 15:34:02 +0900 Subject: [PATCH 016/318] Fix jshint warnings and also apply patches to exec_json() --- common/js/xml_handler.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index 5d0d9a940..c5a54d6d5 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -134,11 +134,13 @@ // Hide the waiting message and display an error notice. clearTimeout(wfsr_timeout); waiting_obj.hide().trigger("cancel_confirm"); + var error_info; + if ($(".x_modal-body").size()) { - var error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "

" + xhr.responseText + "
"; + error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "

" + xhr.responseText + "
"; alert("AJAX communication error while requesting " + params.module + "." + params.act + "

" + error_info); } else { - var error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "\n\n" + xhr.responseText; + error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "\n\n" + xhr.responseText; alert("AJAX communication error while requesting " + params.module + "." + params.act + "\n\n" + error_info); } }; @@ -232,8 +234,15 @@ var errorHandler = function(xhr, textStatus) { clearTimeout(wfsr_timeout); waiting_obj.hide().trigger("cancel_confirm"); - var error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")"; - alert("AJAX communication error while requesting " + params.module + "." + params.act + "\n\n" + error_info); + var error_info; + + if ($(".x_modal-body").size()) { + error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "

" + xhr.responseText + "
"; + alert("AJAX communication error while requesting " + params.module + "." + params.act + "

" + error_info); + } else { + error_info = xhr.status + " " + xhr.statusText + " (" + textStatus + ")" + "\n\n" + xhr.responseText; + alert("AJAX communication error while requesting " + params.module + "." + params.act + "\n\n" + error_info); + } }; // Send the AJAX request. From fd690059ab8413a7b406726954fbf9c030e098c0 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 25 Feb 2016 16:31:33 +0900 Subject: [PATCH 017/318] =?UTF-8?q?$lang=5Fcode=5Fargs=20=EC=B4=88?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=80=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=EC=A0=90=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/document/document.controller.php | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 569cbc022..9b4146aa8 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -647,6 +647,7 @@ class documentController extends document // Change not extra vars but language code of the original document if document's lang_code doesn't exist. if(!$source_obj->get('lang_code')) { + $lang_code_args = new stdClass(); $lang_code_args->document_srl = $source_obj->get('document_srl'); $lang_code_args->lang_code = Context::getLangType(); $output = executeQuery('document.updateDocumentsLangCode', $lang_code_args); From 3d2b3792bff1d489d700c31d879cb4a9cd755bf4 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 25 Feb 2016 22:32:41 +0900 Subject: [PATCH 018/318] =?UTF-8?q?=EB=B2=88=EC=97=AD=20=EC=98=A4=EB=A5=98?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/member/lang/en.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/member/lang/en.php b/modules/member/lang/en.php index f4c4940cd..e98843ecc 100644 --- a/modules/member/lang/en.php +++ b/modules/member/lang/en.php @@ -206,7 +206,7 @@ $lang->about_profile_image = 'Members will be able to use profile images'; $lang->about_signature_max_height = 'You can limit the signature max height. Set this as 0 or leave it blank not to limit it.'; $lang->about_accept_agreement = 'I have read the agreement and agree with it'; $lang->about_member_default = 'It will be set as the default group on sign up'; -$lang->about_find_member_account = 'lease input the email address you have entered during the registration and we will send your account info to this email address.'; +$lang->about_find_member_account = 'Please input the email address you have entered during the registration and we will send your account info to this email address.'; $lang->about_ssl_port = 'Please enter if you are using non-default SSL port'; $lang->about_resend_auth_mail = 'You can request for the activation email if you have not activated yet.'; $lang->no_article = 'No articles'; From e4077ad324e959a413fed2a4c672043215a840f2 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 26 Feb 2016 09:20:35 +0900 Subject: [PATCH 019/318] Add 'smartphone' add-on to common blacklist --- common/defaults/blacklist.php | 1 + modules/addon/addon.controller.php | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/defaults/blacklist.php b/common/defaults/blacklist.php index ce91d5571..bcbe7904f 100644 --- a/common/defaults/blacklist.php +++ b/common/defaults/blacklist.php @@ -7,5 +7,6 @@ */ return array( 'member_communication' => true, + 'smartphone' => true, 'zipperupper' => true, ); diff --git a/modules/addon/addon.controller.php b/modules/addon/addon.controller.php index 2fd699187..3eceacc89 100644 --- a/modules/addon/addon.controller.php +++ b/modules/addon/addon.controller.php @@ -1,4 +1,4 @@ - */ /** @@ -84,7 +84,7 @@ class addonController extends addon $addon_list = $oAddonModel->getInsertedAddons($site_srl, $gtype); foreach($addon_list as $addon => $val) { - if($val->addon == "smartphone" || Context::isBlacklistedPlugin($addon) + if(Context::isBlacklistedPlugin($addon) || ($type == "pc" && $val->is_used != 'Y') || ($type == "mobile" && $val->is_used_m != 'Y') || ($gtype == 'global' && $val->is_fixed != 'Y') From 26db6901c30ca642d87647b881301b28286fe57b Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 26 Feb 2016 09:28:49 +0900 Subject: [PATCH 020/318] Fix typo --- modules/addon/addon.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/addon/addon.controller.php b/modules/addon/addon.controller.php index 3eceacc89..c66e74338 100644 --- a/modules/addon/addon.controller.php +++ b/modules/addon/addon.controller.php @@ -1,4 +1,4 @@ -s */ /** From 74fcee987e31ce7582045fc67c3c572544a78c2d Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 12:01:32 +0900 Subject: [PATCH 021/318] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EB=82=B4=EC=97=AD=EC=9D=84=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=ED=95=98=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/board/board.controller.php | 5 ++++ modules/board/board.view.php | 18 +++++++++++++ modules/board/conf/module.xml | 1 + modules/board/lang/ko.php | 2 ++ modules/board/skins/xedition/_read.html | 3 ++- modules/board/tpl/board_insert.html | 6 +++++ modules/document/document.controller.php | 26 +++++++++++++++++++ modules/document/queries/insertUpdateLog.xml | 21 +++++++++++++++ .../document/schemas/document_update_list.xml | 16 ++++++++++++ 9 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 modules/document/queries/insertUpdateLog.xml create mode 100644 modules/document/schemas/document_update_list.xml diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index e1646246c..40fa93cd1 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -147,6 +147,11 @@ class boardController extends board $obj->update_order = $obj->list_order = (getNextSequence() * -1); } + if($this->module_info->update_log == 'Y') + { + $obj->update_log_setting = 'Y'; + } + $output = $oDocumentController->updateDocument($oDocument, $obj); $msg_code = 'success_updated'; diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 015241e69..6cb76b237 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -1140,6 +1140,24 @@ class boardView extends board $this->setTemplateFile('message'); } + function dispBoardUpdateLog() + { + $document_srl = Context::get('document_srl'); + $logged_info = Context::get('logged_info'); + $oDocumentModel = getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + if($logged_info->member_srl != $oDocument->get('member_srl') || !$this->grant->manager) + { + return new Object(-1, 'msg_not_permitted'); + } + + $updatelog = $oDocumentModel->getDocumentUpdateLog($document_srl); + Context::set('updatelog', $updatelog); + + $this->setTemplateFile('update_list'); + } + /** * @brief the method for displaying the warning messages * display an error message if it has not a special design diff --git a/modules/board/conf/module.xml b/modules/board/conf/module.xml index 72002fed7..30e6b92d7 100644 --- a/modules/board/conf/module.xml +++ b/modules/board/conf/module.xml @@ -63,6 +63,7 @@ + diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index ce76b6e86..cc9b914c7 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -14,6 +14,7 @@ $lang->consultation = '상담 기능'; $lang->secret = '비밀글 기능'; $lang->thisissecret = '비밀글입니다.'; $lang->admin_mail = '관리자 메일'; +$lang->update_log = '게시글 수정 내역'; $lang->cmd_board_list = '게시판 목록'; $lang->cmd_module_config = '게시판 공통 설정'; $lang->cmd_board_info = '게시판 정보'; @@ -31,6 +32,7 @@ $lang->about_admin_mail = '글이나 댓글이 등록될때 등록된 메일주 $lang->about_list_config = '게시판의 목록형식 사용시 원하는 항목들로 배치를 할 수 있습니다. 단 스킨에서 지원하지 않는 경우 불가능합니다. 대상항목/ 표시항목의 항목을 더블클릭하면 추가/ 제거가 됩니다.'; $lang->about_use_status = '글 작성 시 선택할 수 있는 상태를 지정해주세요.'; $lang->about_protect_comment = '댓글의 댓글이 있을경우 해당댓글을 삭제 및 수정을 할 수 없도록 합니다.'; +$lang->about_update_log = '게시글을 수정할 경우 수정한 내역을 저장하도록 합니다.'; $lang->msg_not_enough_point = '포인트가 부족합니다'; $lang->write_comment = '댓글 쓰기'; $lang->msg_not_allow_comment = '해당 글의 댓글 쓰기가 잠겨있습니다.'; diff --git a/modules/board/skins/xedition/_read.html b/modules/board/skins/xedition/_read.html index 7c3e6030b..4a8cfa54e 100644 --- a/modules/board/skins/xedition/_read.html +++ b/modules/board/skins/xedition/_read.html @@ -114,7 +114,8 @@ Profile
{$oDocument->getSignature()}
-
+
+ {$lang->update_log} {$lang->cmd_modify} {$lang->cmd_delete} diff --git a/modules/board/tpl/board_insert.html b/modules/board/tpl/board_insert.html index ad2e7c176..03e2d7762 100644 --- a/modules/board/tpl/board_insert.html +++ b/modules/board/tpl/board_insert.html @@ -199,6 +199,12 @@
+
+ +
+ +
+
diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 569cbc022..34a8baa36 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -683,6 +683,32 @@ class documentController extends document $oDB->rollback(); return $output; } + // update Document Log + else + { + if($obj->update_log_setting === 'Y') + { + $update_args = new stdClass(); + $update_args->document_srl = $obj->document_srl; + $update_args->member_srl = $source_obj->get('member_srl'); + $update_args->module_srl = $source_obj->get('module_srl'); + $update_args->update_member_srl = $logged_info->member_srl; + $update_args->nick_name = $source_obj->get('nick_name'); + $update_args->title = $obj->title; + $update_args->title_bold = $obj->title_bold; + $update_args->title_color = $obj->title_color; + $update_args->content = $obj->content; + $update_args->update_nick_name = $logged_info->nick_name; + $update_args->tags = $obj->tags; + $update_args->extra_vars = $obj->extra_vars; + $update_output = executeQuery('document.insertUpdateLog', $update_args); + if(!$update_output->toBool()) + { + $oDB->rollback(); + return $update_output; + } + } + } // Remove all extra variables if(Context::get('act')!='procFileDelete') { diff --git a/modules/document/queries/insertUpdateLog.xml b/modules/document/queries/insertUpdateLog.xml new file mode 100644 index 000000000..b6a471d84 --- /dev/null +++ b/modules/document/queries/insertUpdateLog.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/document/schemas/document_update_list.xml b/modules/document/schemas/document_update_list.xml new file mode 100644 index 000000000..8aa0cb9d1 --- /dev/null +++ b/modules/document/schemas/document_update_list.xml @@ -0,0 +1,16 @@ +
+ + + + + + + + + + + + + + +
From 9a60af1871ed71413c36ca71eb6cdd7c00db8dcc Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 13:10:25 +0900 Subject: [PATCH 022/318] =?UTF-8?q?=EB=82=B4=EC=97=AD=EC=9D=84=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../board/skins/xedition/board.default.css | 13 +++++++++++ modules/board/skins/xedition/update_list.html | 23 +++++++++++++++++++ modules/document/document.controller.php | 10 +++++++- modules/document/document.model.php | 10 ++++++++ .../document/queries/getDocumentUpdateLog.xml | 11 +++++++++ ...ateLog.xml => insertDocumentUpdateLog.xml} | 3 ++- .../document/schemas/document_update_list.xml | 1 + 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 modules/board/skins/xedition/update_list.html create mode 100644 modules/document/queries/getDocumentUpdateLog.xml rename modules/document/queries/{insertUpdateLog.xml => insertDocumentUpdateLog.xml} (89%) diff --git a/modules/board/skins/xedition/board.default.css b/modules/board/skins/xedition/board.default.css index 866a9f86f..30022f34c 100644 --- a/modules/board/skins/xedition/board.default.css +++ b/modules/board/skins/xedition/board.default.css @@ -263,6 +263,16 @@ right:0; border-radius: 0 2px 2px 0; } + +.update-log { + width:100%; + border-bottom:1px solid #dbdbdb; + margin: 5px auto 5px auto; + + padding:5px; + +} + /* Board Write */ /* write_form.html */ @@ -463,6 +473,9 @@ white-space: nowrap; color : #666; } +.update-log .read_header .meta { + border-bottom:0; +} .read_header .meta > span { margin-left: 8px ;} .read_header .meta > span:first-child {margin-left:0;} .read_header .meta:after { diff --git a/modules/board/skins/xedition/update_list.html b/modules/board/skins/xedition/update_list.html new file mode 100644 index 000000000..41ab36ec2 --- /dev/null +++ b/modules/board/skins/xedition/update_list.html @@ -0,0 +1,23 @@ + +
+
+ +
+

+ {$category_list[$val->category_srl]->title} + {$val->title} +

+

+ + {zdate($val->regdate,'Y.m.d H:i:s')} + +

+
+ + +
+ {$val->content} +
+ +
+
diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 34a8baa36..040891fad 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -689,6 +689,14 @@ class documentController extends document if($obj->update_log_setting === 'Y') { $update_args = new stdClass(); + if($obj->category_srl) + { + $update_args->category_srl = $obj->category_srl; + } + else + { + $update_args->category_srl = $source_obj->get('category_srl'); + } $update_args->document_srl = $obj->document_srl; $update_args->member_srl = $source_obj->get('member_srl'); $update_args->module_srl = $source_obj->get('module_srl'); @@ -701,7 +709,7 @@ class documentController extends document $update_args->update_nick_name = $logged_info->nick_name; $update_args->tags = $obj->tags; $update_args->extra_vars = $obj->extra_vars; - $update_output = executeQuery('document.insertUpdateLog', $update_args); + $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); if(!$update_output->toBool()) { $oDB->rollback(); diff --git a/modules/document/document.model.php b/modules/document/document.model.php index 2420eebb0..d99046470 100644 --- a/modules/document/document.model.php +++ b/modules/document/document.model.php @@ -1548,6 +1548,16 @@ class documentModel extends document return $document_list; } + + function getDocumentUpdateLog($document_srl) + { + $args = new stdClass(); + $args->document_srl = $document_srl; + $output = executeQueryArray('document.getDocumentUpdateLog', $args); + $update_list = $output->data; + + return $update_list; + } } /* End of file document.model.php */ /* Location: ./modules/document/document.model.php */ diff --git a/modules/document/queries/getDocumentUpdateLog.xml b/modules/document/queries/getDocumentUpdateLog.xml new file mode 100644 index 000000000..379a56e51 --- /dev/null +++ b/modules/document/queries/getDocumentUpdateLog.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/document/queries/insertUpdateLog.xml b/modules/document/queries/insertDocumentUpdateLog.xml similarity index 89% rename from modules/document/queries/insertUpdateLog.xml rename to modules/document/queries/insertDocumentUpdateLog.xml index b6a471d84..c90d898b0 100644 --- a/modules/document/queries/insertUpdateLog.xml +++ b/modules/document/queries/insertDocumentUpdateLog.xml @@ -1,4 +1,4 @@ - +
@@ -7,6 +7,7 @@ + diff --git a/modules/document/schemas/document_update_list.xml b/modules/document/schemas/document_update_list.xml index 8aa0cb9d1..1a944e88d 100644 --- a/modules/document/schemas/document_update_list.xml +++ b/modules/document/schemas/document_update_list.xml @@ -3,6 +3,7 @@ + From 301861e35a69a6bf6db786ee99495dd9845ca4a8 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 13:35:41 +0900 Subject: [PATCH 023/318] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EC=8B=9C=EC=97=90=20=EC=9B=90=EB=B3=B8=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EB=93=B1=EB=A1=9D=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/board/board.controller.php | 10 ++++----- modules/board/lang/ko.php | 3 ++- modules/document/document.controller.php | 27 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index 40fa93cd1..f84555fbd 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -106,6 +106,11 @@ class boardController extends board } } + if($this->module_info->update_log == 'Y') + { + $obj->update_log_setting = 'Y'; + } + // update the document if it is existed if($is_update) { @@ -147,11 +152,6 @@ class boardController extends board $obj->update_order = $obj->list_order = (getNextSequence() * -1); } - if($this->module_info->update_log == 'Y') - { - $obj->update_log_setting = 'Y'; - } - $output = $oDocumentController->updateDocument($oDocument, $obj); $msg_code = 'success_updated'; diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index cc9b914c7..91060481e 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -54,4 +54,5 @@ $lang->msg_admin_comment_no_modify = '최고관리자의 댓글을 수정할 권 $lang->msg_board_delete_protect_comment = '댓글이 작성된 댓글의 글을 삭제할 수 없습니다.'; $lang->msg_board_update_protect_comment = '댓글이 작성된 댓글의 글을 수정할 수 없습니다.'; $lang->msg_protect_regdate_document = '%s일 이전의 게시글은 수정 또는 삭제 할 수 없습니다.'; -$lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 삭제 할 수 없습니다.'; \ No newline at end of file +$lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 삭제 할 수 없습니다.'; +$lang->original_letter = '원본글'; \ No newline at end of file diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 040891fad..31ce0a961 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -438,6 +438,33 @@ class documentController extends document $oDB->rollback(); return $output; } + // update Document Log + else + { + if($obj->update_log_setting === 'Y') + { + $update_args = new stdClass(); + $update_args->category_srl = $obj->category_srl; + $update_args->document_srl = $obj->document_srl; + $update_args->member_srl = $obj->member_srl; + $update_args->module_srl = $obj->module_srl; + $update_args->update_member_srl = $logged_info->member_srl; + $update_args->nick_name = $obj->nick_name; + $update_args->title = $obj->title; + $update_args->title_bold = $obj->title_bold; + $update_args->title_color = $obj->title_color; + $update_args->content = $obj->content.'

'.Context::getLang('original_letter'); + $update_args->update_nick_name = $logged_info->nick_name; + $update_args->tags = $obj->tags; + $update_args->extra_vars = $obj->extra_vars; + $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); + if(!$update_output->toBool()) + { + $oDB->rollback(); + return $update_output; + } + } + } // Insert extra variables if the document successfully inserted. $extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl); if(count($extra_keys)) From 16f7a76471e60dfd860cfd1d33c23b9db83502ae Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 13:54:09 +0900 Subject: [PATCH 024/318] =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=EA=B8=B0=EB=A1=9D=EC=9D=B4=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=EA=B2=BD=EC=9A=B0=20=EC=97=86=EB=8B=A4=EA=B3=A0=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/board/lang/ko.php | 3 ++- modules/board/skins/xedition/update_list.html | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index 91060481e..608af476c 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -55,4 +55,5 @@ $lang->msg_board_delete_protect_comment = '댓글이 작성된 댓글의 글을 $lang->msg_board_update_protect_comment = '댓글이 작성된 댓글의 글을 수정할 수 없습니다.'; $lang->msg_protect_regdate_document = '%s일 이전의 게시글은 수정 또는 삭제 할 수 없습니다.'; $lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 삭제 할 수 없습니다.'; -$lang->original_letter = '원본글'; \ No newline at end of file +$lang->msg_dont_have_update_log = '업데이트 로그가 기록되어 있지 않은 게시글입니다.'; +$lang->original_letter = '원본글'; diff --git a/modules/board/skins/xedition/update_list.html b/modules/board/skins/xedition/update_list.html index 41ab36ec2..7d0556244 100644 --- a/modules/board/skins/xedition/update_list.html +++ b/modules/board/skins/xedition/update_list.html @@ -1,5 +1,5 @@ -
+
@@ -21,3 +21,7 @@
+ +
+ {$lang->msg_dont_have_update_log} +
\ No newline at end of file From 940862312011fcca74dbc67630c02ad4c9f97c4d Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 13:54:38 +0900 Subject: [PATCH 025/318] =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=EC=9D=84=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=ED=95=A0=20=EB=95=8C=20=EC=A0=80=EC=9E=A5?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=EB=8F=84=20=ED=95=A8=EA=BB=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/document/document.controller.php | 6 ++++++ modules/document/queries/deleteDocumentUpdateLog.xml | 8 ++++++++ 2 files changed, 14 insertions(+) create mode 100644 modules/document/queries/deleteDocumentUpdateLog.xml diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 31ce0a961..4624d4e01 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -890,6 +890,7 @@ class documentController extends document $this->_deleteDeclaredDocuments($args); $this->_deleteDocumentReadedLog($args); $this->_deleteDocumentVotedLog($args); + $this->_deleteDocumentUpdateLog($args); // Remove the thumbnail file FileHandler::removeDir(sprintf('files/thumbnails/%s',getNumberingPath($document_srl, 3))); @@ -939,6 +940,11 @@ class documentController extends document executeQuery('document.deleteDocumentVotedLog', $documentSrls); } + function _deleteDocumentUpdateLog($document_srl) + { + executeQuery('document.deleteDocumentUpdateLog', $document_srl); + } + /** * Move the doc into the trash * @param object $obj diff --git a/modules/document/queries/deleteDocumentUpdateLog.xml b/modules/document/queries/deleteDocumentUpdateLog.xml new file mode 100644 index 000000000..8856a7712 --- /dev/null +++ b/modules/document/queries/deleteDocumentUpdateLog.xml @@ -0,0 +1,8 @@ + + +
+ + + + + From b392ba70f9bcfaf80228034d223283ad5d2b18ed Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 14:53:50 +0900 Subject: [PATCH 026/318] rename to update log --- .../queries/deleteDocumentUpdateLog.xml | 2 +- .../document/queries/getDocumentUpdateLog.xml | 2 +- .../queries/insertDocumentUpdateLog.xml | 2 +- .../document/schemas/document_update_list.xml | 17 ----------------- .../document/schemas/document_update_log.xml | 17 +++++++++++++++++ 5 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 modules/document/schemas/document_update_list.xml create mode 100644 modules/document/schemas/document_update_log.xml diff --git a/modules/document/queries/deleteDocumentUpdateLog.xml b/modules/document/queries/deleteDocumentUpdateLog.xml index 8856a7712..6f0ee246c 100644 --- a/modules/document/queries/deleteDocumentUpdateLog.xml +++ b/modules/document/queries/deleteDocumentUpdateLog.xml @@ -1,6 +1,6 @@ -
+
diff --git a/modules/document/queries/getDocumentUpdateLog.xml b/modules/document/queries/getDocumentUpdateLog.xml index 379a56e51..161d87b55 100644 --- a/modules/document/queries/getDocumentUpdateLog.xml +++ b/modules/document/queries/getDocumentUpdateLog.xml @@ -1,6 +1,6 @@ -
+
diff --git a/modules/document/queries/insertDocumentUpdateLog.xml b/modules/document/queries/insertDocumentUpdateLog.xml index c90d898b0..eef2045ba 100644 --- a/modules/document/queries/insertDocumentUpdateLog.xml +++ b/modules/document/queries/insertDocumentUpdateLog.xml @@ -1,6 +1,6 @@ -
+
diff --git a/modules/document/schemas/document_update_list.xml b/modules/document/schemas/document_update_list.xml deleted file mode 100644 index 1a944e88d..000000000 --- a/modules/document/schemas/document_update_list.xml +++ /dev/null @@ -1,17 +0,0 @@ -
- - - - - - - - - - - - - - - -
diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml new file mode 100644 index 000000000..92a84f284 --- /dev/null +++ b/modules/document/schemas/document_update_log.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + +
From 379bed000d22304b2a363d08a36c4a656ddc155c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 26 Feb 2016 14:58:42 +0900 Subject: [PATCH 027/318] Fix JSON encoding to be fully XE-compatible --- classes/display/JSONDisplayHandler.php | 37 +++++++++++++++++++------- common/js/xml_handler.js | 6 +---- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/classes/display/JSONDisplayHandler.php b/classes/display/JSONDisplayHandler.php index 069b6464e..3be23d3d7 100644 --- a/classes/display/JSONDisplayHandler.php +++ b/classes/display/JSONDisplayHandler.php @@ -15,20 +15,37 @@ class JSONDisplayHandler $variables['error'] = $oModule->getError(); $variables['message'] = $oModule->getMessage(); - $temp = array(); - foreach ($variables as $key => $value) + self::_convertCompat($variables, Context::getRequestMethod()); + return json_encode($variables); + } + + /** + * Convert arrays in a format that is compatible with XE. + * + * @param array $array + * @param string $compat_type + * @return array + */ + protected static function _convertCompat(&$array, $compat_type = 'JSON') + { + foreach ($array as $key => &$value) { - if (self::_isNumericArray($value)) + if (is_array($value)) { - $temp[$key] = array_values($value); - } - else - { - $temp[$key] = $value; + self::_convertCompat($value, $compat_type); + if (self::_isNumericArray($value)) + { + if ($compat_type === 'XMLRPC') + { + $value = array('item' => array_values($value)); + } + else + { + $value = array_values($value); + } + } } } - - return json_encode($temp); } /** diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index c5a54d6d5..0b4f03775 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -69,11 +69,7 @@ var result = {}; $.each(data, function(key, val) { if ($.inArray(key, ["error", "message", "act", "redirect_url"]) >= 0 || $.inArray(key, return_fields) >= 0) { - if ($.isArray(val)) { - result[key] = { item: val }; - } else { - result[key] = val; - } + result[key] = val; } }); From 66b8268df962d3f403f46db7265e6274a2cbd90f Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 15:09:23 +0900 Subject: [PATCH 028/318] add auto_increment db column --- modules/document/schemas/document_update_log.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index 92a84f284..b0cead1ca 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -1,4 +1,5 @@ + From b3e5596934209f007c4ce4c6c02ad05c899b6ed7 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 15:14:07 +0900 Subject: [PATCH 029/318] rename update id column --- modules/document/schemas/document_update_log.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index b0cead1ca..546735298 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -1,5 +1,5 @@
- + From 226d70a304476d2ecf05c0c598cd62e18ad2a2a3 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 15:27:35 +0900 Subject: [PATCH 030/318] =?UTF-8?q?=EC=98=A4=ED=83=80=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/member/queries/getMemberModifyNickName.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/member/queries/getMemberModifyNickName.xml b/modules/member/queries/getMemberModifyNickName.xml index 3dea7f6bb..c3162f109 100644 --- a/modules/member/queries/getMemberModifyNickName.xml +++ b/modules/member/queries/getMemberModifyNickName.xml @@ -12,6 +12,6 @@ - + \ No newline at end of file From 705ad34c49bb4f3efa18bbb7fc47780bc2d35046 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 27 Feb 2016 14:27:46 +0900 Subject: [PATCH 031/318] Also fix JSON encoding when the result contains objects not arrays --- classes/display/JSONDisplayHandler.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/classes/display/JSONDisplayHandler.php b/classes/display/JSONDisplayHandler.php index 3be23d3d7..7e7fc61a1 100644 --- a/classes/display/JSONDisplayHandler.php +++ b/classes/display/JSONDisplayHandler.php @@ -30,6 +30,10 @@ class JSONDisplayHandler { foreach ($array as $key => &$value) { + if (is_object($value)) + { + $value = get_object_vars($value); + } if (is_array($value)) { self::_convertCompat($value, $compat_type); From 60c46901c6f4ce4e1e64a0d0ac1d2ee621a1fb9b Mon Sep 17 00:00:00 2001 From: conory Date: Mon, 29 Feb 2016 15:53:28 +0900 Subject: [PATCH 032/318] =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EC=A4=91?= =?UTF-8?q?=EB=B3=B5=20=EC=84=A4=EC=A0=95=EC=9D=84=20=EC=98=AC=EB=B0=94?= =?UTF-8?q?=EB=A5=B4=EA=B2=8C=20=EA=B3=A0=EC=B9=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/point_level_icon/conf/info.xml | 24 ++++++------------- .../point_level_icon/point_level_icon.lib.php | 8 +++---- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/addons/point_level_icon/conf/info.xml b/addons/point_level_icon/conf/info.xml index 6bbe48857..3597262b9 100644 --- a/addons/point_level_icon/conf/info.xml +++ b/addons/point_level_icon/conf/info.xml @@ -62,25 +62,15 @@ - 아이콘 중복 설정 - 아이콘 중복 설정을 적용할 경우 그룹아이콘이 있을때 포인트 레벨 아이콘은 띄우지 않도록 합니다. + 아이콘 중복 방지 + 그룹아이콘이 있을 경우 중복으로 레벨 아이콘을 달지 않습니다. - 적용하지 않음 - 不启用 - 적용하지 않음 - 關閉 - Not apply - Not apply - Không áp dụng + 사용함 + Enabled - - 적용 - 启用 - 적용 - 開啟 - Apply - Apply - Áp dụng + + 사용하지 않음 + Disabled diff --git a/addons/point_level_icon/point_level_icon.lib.php b/addons/point_level_icon/point_level_icon.lib.php index f72b46359..2e6c6ff7c 100644 --- a/addons/point_level_icon/point_level_icon.lib.php +++ b/addons/point_level_icon/point_level_icon.lib.php @@ -13,18 +13,18 @@ function pointLevelIconTrans($matches, $addon_info) return $matches[0]; } - $orig_text = preg_replace('/' . preg_quote($matches[5], '/') . '<\/' . $matches[6] . '>$/', '', $matches[0]); - - if($addon_info->icon_duplication != 'Y') + if($addon_info->icon_duplication != 'N') { // Check Group Image Mark $oMemberModel = getModel('member'); if($oMemberModel->getGroupImageMark($member_srl)) { - return $orig_text . $matches[5] . ''; + return $matches[0]; } } + $orig_text = preg_replace('/' . preg_quote($matches[5], '/') . '<\/' . $matches[6] . '>$/', '', $matches[0]); + if(!isset($GLOBALS['_pointLevelIcon'][$member_srl])) { // Get point configuration From 08f2dcb0be18234dcb42c98ed7ba2642d4f0acbf Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 26 Feb 2016 15:26:49 +0900 Subject: [PATCH 033/318] Add page navigation --- modules/document/queries/getDocumentUpdateLog.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/document/queries/getDocumentUpdateLog.xml b/modules/document/queries/getDocumentUpdateLog.xml index 161d87b55..e48e787ee 100644 --- a/modules/document/queries/getDocumentUpdateLog.xml +++ b/modules/document/queries/getDocumentUpdateLog.xml @@ -8,4 +8,10 @@ + + + + + + From 7fa5684af69dd425ab714fa336a7686f80183704 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 09:50:09 +0900 Subject: [PATCH 034/318] member srl column deleted --- modules/document/queries/insertDocumentUpdateLog.xml | 1 - modules/document/schemas/document_update_log.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/modules/document/queries/insertDocumentUpdateLog.xml b/modules/document/queries/insertDocumentUpdateLog.xml index eef2045ba..087c9150c 100644 --- a/modules/document/queries/insertDocumentUpdateLog.xml +++ b/modules/document/queries/insertDocumentUpdateLog.xml @@ -4,7 +4,6 @@ - diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index 546735298..aeb89bafe 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -1,7 +1,6 @@
- From 577ea49b926f958dc3dced5d84fe6ca728ef9b53 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 09:51:17 +0900 Subject: [PATCH 035/318] add insertDocumentUpdateLog Method --- modules/document/document.controller.php | 79 +++++++++++++----------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 4624d4e01..8d9d3bec4 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -443,21 +443,7 @@ class documentController extends document { if($obj->update_log_setting === 'Y') { - $update_args = new stdClass(); - $update_args->category_srl = $obj->category_srl; - $update_args->document_srl = $obj->document_srl; - $update_args->member_srl = $obj->member_srl; - $update_args->module_srl = $obj->module_srl; - $update_args->update_member_srl = $logged_info->member_srl; - $update_args->nick_name = $obj->nick_name; - $update_args->title = $obj->title; - $update_args->title_bold = $obj->title_bold; - $update_args->title_color = $obj->title_color; - $update_args->content = $obj->content.'

'.Context::getLang('original_letter'); - $update_args->update_nick_name = $logged_info->nick_name; - $update_args->tags = $obj->tags; - $update_args->extra_vars = $obj->extra_vars; - $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); + $update_output = $this->insertDocumentUpdateLog($obj); if(!$update_output->toBool()) { $oDB->rollback(); @@ -715,28 +701,7 @@ class documentController extends document { if($obj->update_log_setting === 'Y') { - $update_args = new stdClass(); - if($obj->category_srl) - { - $update_args->category_srl = $obj->category_srl; - } - else - { - $update_args->category_srl = $source_obj->get('category_srl'); - } - $update_args->document_srl = $obj->document_srl; - $update_args->member_srl = $source_obj->get('member_srl'); - $update_args->module_srl = $source_obj->get('module_srl'); - $update_args->update_member_srl = $logged_info->member_srl; - $update_args->nick_name = $source_obj->get('nick_name'); - $update_args->title = $obj->title; - $update_args->title_bold = $obj->title_bold; - $update_args->title_color = $obj->title_color; - $update_args->content = $obj->content; - $update_args->update_nick_name = $logged_info->nick_name; - $update_args->tags = $obj->tags; - $update_args->extra_vars = $obj->extra_vars; - $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); + $update_output = $this->insertDocumentUpdateLog($obj, $source_obj); if(!$update_output->toBool()) { $oDB->rollback(); @@ -807,6 +772,46 @@ class documentController extends document return $output; } + function insertDocumentUpdateLog($obj, $source_obj = null) + { + $update_args = new stdClass(); + $logged_info = Context::get('logged_info'); + if($source_obj === null) + { + $update_args->category_srl = $obj->category_srl; + $update_args->member_srl = $logged_info->member_srl; + $update_args->module_srl = $obj->module_srl; + $update_args->nick_name = $obj->nick_name; + } + else + { + if($obj->category_srl) + { + $update_args->category_srl = $obj->category_srl; + } + else + { + $update_args->category_srl = $source_obj->get('category_srl'); + } + $update_args->member_srl = $source_obj->get('member_srl'); + $update_args->module_srl = $source_obj->get('module_srl'); + $update_args->nick_name = $source_obj->get('nick_name'); + } + + $update_args->document_srl = $obj->document_srl; + $update_args->update_member_srl = $logged_info->member_srl; + $update_args->title = $obj->title; + $update_args->title_bold = $obj->title_bold; + $update_args->title_color = $obj->title_color; + $update_args->content = $obj->content; + $update_args->update_nick_name = $logged_info->nick_name; + $update_args->tags = $obj->tags; + $update_args->extra_vars = $obj->extra_vars; + $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); + + return $update_output; + } + /** * Deleting Documents * @param int $document_srl From e7b8c1d1df5d42df4f71eb4df8a727c8420752a2 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 11:04:48 +0900 Subject: [PATCH 036/318] modify DB Queries --- modules/board/board.view.php | 6 +- modules/board/lang/ko.php | 1 + modules/board/skins/xedition/update_list.html | 65 ++++++++++++------- modules/document/document.model.php | 3 +- .../document/queries/getDocumentUpdateLog.xml | 7 +- 5 files changed, 53 insertions(+), 29 deletions(-) diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 6cb76b237..07fd2d8f8 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -1147,12 +1147,16 @@ class boardView extends board $oDocumentModel = getModel('document'); $oDocument = $oDocumentModel->getDocument($document_srl); - if($logged_info->member_srl != $oDocument->get('member_srl') || !$this->grant->manager) + if($logged_info->member_srl != $oDocument->get('member_srl') && $this->grant->manager !== true) { return new Object(-1, 'msg_not_permitted'); } $updatelog = $oDocumentModel->getDocumentUpdateLog($document_srl); + Context::set('total_count', $updatelog->page_navigation->total_count); + Context::set('total_page', $updatelog->page_navigation->total_page); + Context::set('page', $updatelog->page); + Context::set('page_navigation', $updatelog->page_navigation); Context::set('updatelog', $updatelog); $this->setTemplateFile('update_list'); diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index 608af476c..d29eec6be 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -15,6 +15,7 @@ $lang->secret = '비밀글 기능'; $lang->thisissecret = '비밀글입니다.'; $lang->admin_mail = '관리자 메일'; $lang->update_log = '게시글 수정 내역'; +$lang->last_updater = '수정한사람'; $lang->cmd_board_list = '게시판 목록'; $lang->cmd_module_config = '게시판 공통 설정'; $lang->cmd_board_info = '게시판 정보'; diff --git a/modules/board/skins/xedition/update_list.html b/modules/board/skins/xedition/update_list.html index 7d0556244..b629c6bcb 100644 --- a/modules/board/skins/xedition/update_list.html +++ b/modules/board/skins/xedition/update_list.html @@ -1,27 +1,42 @@ -
-
- -
-

- {$category_list[$val->category_srl]->title} - {$val->title} -

-

- - {zdate($val->regdate,'Y.m.d H:i:s')} - -

-
- - -
- {$val->content} -
- -
+
+
+ + + + + + + + + + + + + + + + + + + + + +
{$lang->title}{$lang->writer}{$lang->last_updater}{$lang->last_post}
+ {$val->title} + + {$val->update_nick_name} + + {$val->nick_name} + + {zdate($val->regdate, 'Y.m.d H:i:s')} +
{$lang->msg_dont_have_update_log}
+
+ - -
- {$lang->msg_dont_have_update_log} -
\ No newline at end of file diff --git a/modules/document/document.model.php b/modules/document/document.model.php index d99046470..8c7668804 100644 --- a/modules/document/document.model.php +++ b/modules/document/document.model.php @@ -1554,9 +1554,8 @@ class documentModel extends document $args = new stdClass(); $args->document_srl = $document_srl; $output = executeQueryArray('document.getDocumentUpdateLog', $args); - $update_list = $output->data; - return $update_list; + return $output; } } /* End of file document.model.php */ diff --git a/modules/document/queries/getDocumentUpdateLog.xml b/modules/document/queries/getDocumentUpdateLog.xml index e48e787ee..c7ceeedc0 100644 --- a/modules/document/queries/getDocumentUpdateLog.xml +++ b/modules/document/queries/getDocumentUpdateLog.xml @@ -3,7 +3,12 @@ - + + + + + + From 1dcf523450595764ebbf62928efaf65b18242735 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 11:48:40 +0900 Subject: [PATCH 037/318] add modify permissions --- modules/board/board.view.php | 6 ++---- modules/board/conf/module.xml | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 07fd2d8f8..22740fa6d 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -1142,12 +1142,10 @@ class boardView extends board function dispBoardUpdateLog() { - $document_srl = Context::get('document_srl'); - $logged_info = Context::get('logged_info'); $oDocumentModel = getModel('document'); - $oDocument = $oDocumentModel->getDocument($document_srl); + $document_srl = Context::get('document_srl'); - if($logged_info->member_srl != $oDocument->get('member_srl') && $this->grant->manager !== true) + if($this->grant->update_view !== true) { return new Object(-1, 'msg_not_permitted'); } diff --git a/modules/board/conf/module.xml b/modules/board/conf/module.xml index 30e6b92d7..2069ad1e8 100644 --- a/modules/board/conf/module.xml +++ b/modules/board/conf/module.xml @@ -21,6 +21,9 @@ 檢視 görüş + + 수정내역 조회 + 글 작성 发表新主题 From 5d550920ee2edbe6ce217f40756feb085c3c23b8 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 12:21:25 +0900 Subject: [PATCH 038/318] update template permissions --- modules/board/board.view.php | 2 ++ modules/board/skins/xedition/_read.html | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 22740fa6d..6aa308221 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -333,6 +333,8 @@ class boardView extends board } } + Context::set('update_view', $this->grant->update_view); + // setup the document oject on context $oDocument->add('module_srl', $this->module_srl); Context::set('oDocument', $oDocument); diff --git a/modules/board/skins/xedition/_read.html b/modules/board/skins/xedition/_read.html index 4a8cfa54e..f0102cb25 100644 --- a/modules/board/skins/xedition/_read.html +++ b/modules/board/skins/xedition/_read.html @@ -115,7 +115,7 @@
{$oDocument->getSignature()}
- {$lang->update_log} + {$lang->update_log} {$lang->cmd_modify} {$lang->cmd_delete} From d25432a2c68b03345d5ff63d22830d18d9ddf22c Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 12:29:11 +0900 Subject: [PATCH 039/318] add warning message --- modules/board/lang/ko.php | 1 + modules/board/tpl/board_insert.html | 1 + 2 files changed, 2 insertions(+) diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index d29eec6be..e4be63ea5 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -58,3 +58,4 @@ $lang->msg_protect_regdate_document = '%s일 이전의 게시글은 수정 또 $lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 삭제 할 수 없습니다.'; $lang->msg_dont_have_update_log = '업데이트 로그가 기록되어 있지 않은 게시글입니다.'; $lang->original_letter = '원본글'; +$lang->msg_warning_update_log = '주의! 사용시 디비가 많이 늘어날 수 있습니다.'; \ No newline at end of file diff --git a/modules/board/tpl/board_insert.html b/modules/board/tpl/board_insert.html index 03e2d7762..457b8a550 100644 --- a/modules/board/tpl/board_insert.html +++ b/modules/board/tpl/board_insert.html @@ -203,6 +203,7 @@
+

{$lang->msg_warning_update_log}

From acb48cb1d26bad547b3be23cee925aa585646518 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 12:34:42 +0900 Subject: [PATCH 040/318] enter next line --- modules/board/lang/ko.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index e4be63ea5..289851a1b 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -58,4 +58,4 @@ $lang->msg_protect_regdate_document = '%s일 이전의 게시글은 수정 또 $lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 삭제 할 수 없습니다.'; $lang->msg_dont_have_update_log = '업데이트 로그가 기록되어 있지 않은 게시글입니다.'; $lang->original_letter = '원본글'; -$lang->msg_warning_update_log = '주의! 사용시 디비가 많이 늘어날 수 있습니다.'; \ No newline at end of file +$lang->msg_warning_update_log = '주의! 사용시 디비가 많이 늘어날 수 있습니다.'; From 2a824e150c25d7b6828448c97ecaa74e72dd87ca Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 16:32:54 +0900 Subject: [PATCH 041/318] add reason_update DB column. --- modules/board/board.controller.php | 6 ++++-- modules/board/skins/xedition/write_form.html | 7 ++++++- modules/document/document.controller.php | 1 + modules/document/queries/insertDocumentUpdateLog.xml | 1 + modules/document/schemas/document_update_log.xml | 1 + 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index f84555fbd..b70f9ee7c 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -151,12 +151,14 @@ class boardController extends board $obj->last_update = $obj->regdate = date('YmdHis'); $obj->update_order = $obj->list_order = (getNextSequence() * -1); } - + $obj->reason_update = escape($obj->reason_update); $output = $oDocumentController->updateDocument($oDocument, $obj); $msg_code = 'success_updated'; // insert a new document otherwise - } else { + } + else + { $output = $oDocumentController->insertDocument($obj, $bAnonymous); $msg_code = 'success_registed'; $obj->document_srl = $output->get('document_srl'); diff --git a/modules/board/skins/xedition/write_form.html b/modules/board/skins/xedition/write_form.html index e9a197a07..edbec4d8b 100644 --- a/modules/board/skins/xedition/write_form.html +++ b/modules/board/skins/xedition/write_form.html @@ -43,6 +43,7 @@ + get('status') == $key || ($key == 'PUBLIC' && !$document_srl))-->checked="checked" /> @@ -66,7 +67,11 @@ - + + + + +
diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index b137e8c37..fd4eb9f1d 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -808,6 +808,7 @@ class documentController extends document $update_args->update_nick_name = $logged_info->nick_name; $update_args->tags = $obj->tags; $update_args->extra_vars = $obj->extra_vars; + $update_args->reason_update = $obj->reason_update; $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); return $update_output; diff --git a/modules/document/queries/insertDocumentUpdateLog.xml b/modules/document/queries/insertDocumentUpdateLog.xml index 087c9150c..921dd1b51 100644 --- a/modules/document/queries/insertDocumentUpdateLog.xml +++ b/modules/document/queries/insertDocumentUpdateLog.xml @@ -16,6 +16,7 @@ + diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index aeb89bafe..64104396b 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -14,4 +14,5 @@ +
From d38a4fd987c65e79211bc246c9b8c2e752012a19 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 17:19:23 +0900 Subject: [PATCH 042/318] Enhanced to create a modified reason. --- modules/board/board.view.php | 15 +++++++++++ modules/board/conf/module.xml | 1 + modules/board/lang/ko.php | 1 + modules/board/skins/xedition/update_list.html | 2 +- modules/board/skins/xedition/update_view.html | 27 +++++++++++++++++++ modules/document/document.model.php | 10 +++++++ modules/document/queries/getUpdateLog.xml | 11 ++++++++ 7 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 modules/board/skins/xedition/update_view.html create mode 100644 modules/document/queries/getUpdateLog.xml diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 6aa308221..54e634521 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -1162,6 +1162,21 @@ class boardView extends board $this->setTemplateFile('update_list'); } + function dispBoardUpdateLogView() + { + $oDocumentModel = getModel('document'); + $update_id = Context::get('update_id'); + + if($this->grant->update_view !== true) + { + return new Object(-1, 'msg_not_permitted'); + } + $update_log = $oDocumentModel->getUpdateLog($update_id); + Context::set('update_log', $update_log); + + $this->setTemplateFile('update_view'); + } + /** * @brief the method for displaying the warning messages * display an error message if it has not a special design diff --git a/modules/board/conf/module.xml b/modules/board/conf/module.xml index 2069ad1e8..9643ceff0 100644 --- a/modules/board/conf/module.xml +++ b/modules/board/conf/module.xml @@ -77,6 +77,7 @@ + diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index 289851a1b..9f8334b92 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -59,3 +59,4 @@ $lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 $lang->msg_dont_have_update_log = '업데이트 로그가 기록되어 있지 않은 게시글입니다.'; $lang->original_letter = '원본글'; $lang->msg_warning_update_log = '주의! 사용시 디비가 많이 늘어날 수 있습니다.'; +$lang->reason_update = '수정한 이유'; diff --git a/modules/board/skins/xedition/update_list.html b/modules/board/skins/xedition/update_list.html index b629c6bcb..09d962bbc 100644 --- a/modules/board/skins/xedition/update_list.html +++ b/modules/board/skins/xedition/update_list.html @@ -12,7 +12,7 @@ - {$val->title} + {$val->title} {$val->update_nick_name} diff --git a/modules/board/skins/xedition/update_view.html b/modules/board/skins/xedition/update_view.html new file mode 100644 index 000000000..7a546b8e3 --- /dev/null +++ b/modules/board/skins/xedition/update_view.html @@ -0,0 +1,27 @@ + +
+
+ +
+

+ {$category_list[$update_log->category_srl]->title} + {$update_log->title} +

+

+ + {zdate($update_log->regdate,'Y.m.d H:i:s')} + +

+
+ + +
+ {$update_log->content} +
+
+ {$lang->reason_update} : + {$update_log->reason_update} +
+ +
+
diff --git a/modules/document/document.model.php b/modules/document/document.model.php index 8c7668804..673d4f416 100644 --- a/modules/document/document.model.php +++ b/modules/document/document.model.php @@ -1557,6 +1557,16 @@ class documentModel extends document return $output; } + + function getUpdateLog($update_id) + { + $args = new stdClass(); + $args->update_id = $update_id; + $output = exeCuteQuery('document.getUpdateLog', $args); + $updage_log = $output->data; + + return $updage_log; + } } /* End of file document.model.php */ /* Location: ./modules/document/document.model.php */ diff --git a/modules/document/queries/getUpdateLog.xml b/modules/document/queries/getUpdateLog.xml new file mode 100644 index 000000000..daae71601 --- /dev/null +++ b/modules/document/queries/getUpdateLog.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + From 23de45ebefdcce61fdfac28de629e0658319828e Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 1 Mar 2016 17:39:34 +0900 Subject: [PATCH 043/318] tab to space --- modules/document/schemas/document_update_log.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index 64104396b..85a99283a 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -14,5 +14,5 @@ - +
From 216da1ed2b6be45319960706ef792c73f9b3226b Mon Sep 17 00:00:00 2001 From: bjrambo Date: Tue, 1 Mar 2016 23:42:41 +0900 Subject: [PATCH 044/318] Don't expose to modify anonymous nickname. --- modules/document/document.controller.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 9b4146aa8..00f407a18 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -517,6 +517,16 @@ class documentController extends document $oModuleModel = getModel('module'); if(!$obj->module_srl) $obj->module_srl = $source_obj->get('module_srl'); $module_srl = $obj->module_srl; + $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); + if($module_info->use_anonymous == 'Y') + { + $obj->notify_message = 'N'; + $obj->member_srl = -1*$logged_info->member_srl; + $obj->email_address = $obj->homepage = $obj->user_id = ''; + $obj->user_name = $obj->nick_name = 'anonymous'; + debugPrint($obj); + } + $document_config = $oModuleModel->getModulePartConfig('document', $module_srl); if(!$document_config) { @@ -588,7 +598,7 @@ class documentController extends document $obj->password = getModel('member')->hashPassword($obj->password); } // If an author is identical to the modifier or history is used, use the logged-in user's information. - if(Context::get('is_logged')) + if(Context::get('is_logged') && $module_info->use_anonymous != 'Y') { $logged_info = Context::get('logged_info'); if($source_obj->get('member_srl')==$logged_info->member_srl) From 1e14d7219d0a4848d892984223dc8f7a8d2ac803 Mon Sep 17 00:00:00 2001 From: bjrambo Date: Tue, 1 Mar 2016 23:51:48 +0900 Subject: [PATCH 045/318] delete debug code --- modules/document/document.controller.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 00f407a18..baaceb576 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -524,7 +524,6 @@ class documentController extends document $obj->member_srl = -1*$logged_info->member_srl; $obj->email_address = $obj->homepage = $obj->user_id = ''; $obj->user_name = $obj->nick_name = 'anonymous'; - debugPrint($obj); } $document_config = $oModuleModel->getModulePartConfig('document', $module_srl); From 7a71ac93031a034d7db436a8bbff723c57d11df4 Mon Sep 17 00:00:00 2001 From: bjrambo Date: Wed, 2 Mar 2016 01:04:01 +0900 Subject: [PATCH 046/318] delete unneeded cide. --- modules/document/document.controller.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index baaceb576..086b35028 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -518,13 +518,6 @@ class documentController extends document if(!$obj->module_srl) $obj->module_srl = $source_obj->get('module_srl'); $module_srl = $obj->module_srl; $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); - if($module_info->use_anonymous == 'Y') - { - $obj->notify_message = 'N'; - $obj->member_srl = -1*$logged_info->member_srl; - $obj->email_address = $obj->homepage = $obj->user_id = ''; - $obj->user_name = $obj->nick_name = 'anonymous'; - } $document_config = $oModuleModel->getModulePartConfig('document', $module_srl); if(!$document_config) From 34a86defb6161aa5b476f55a83704795b79d6587 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 2 Mar 2016 09:40:14 +0900 Subject: [PATCH 047/318] Fix #321 incorrect display of objects in debugPrint() --- common/framework/debug.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/framework/debug.php b/common/framework/debug.php index 0ed9bfb59..ea1dec766 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -137,7 +137,7 @@ class Debug $entry = (object)array( 'type' => 'Debug', 'time' => microtime(true), - 'message' => $message, + 'message' => unserialize(serialize($message)), 'file' => isset($backtrace[0]['file']) ? $backtrace[0]['file'] : null, 'line' => isset($backtrace[0]['line']) ? $backtrace[0]['line'] : 0, 'backtrace' => $backtrace, From 27cfa4aeba0121f55884ab054537aeb30afcb0c2 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 2 Mar 2016 10:03:48 +0900 Subject: [PATCH 048/318] Redirect to short URL after insertDocument, insertComment, etc. --- classes/module/ModuleObject.class.php | 2 +- modules/board/board.controller.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/classes/module/ModuleObject.class.php b/classes/module/ModuleObject.class.php index b6e994f30..5a656854c 100644 --- a/classes/module/ModuleObject.class.php +++ b/classes/module/ModuleObject.class.php @@ -60,7 +60,7 @@ class ModuleObject extends Object function setRedirectUrl($url = './', $output = NULL) { $ajaxRequestMethod = array_flip($this->ajaxRequestMethod); - if(!isset($ajaxRequestMethod[Context::getRequestMethod()])) + if(isset($ajaxRequestMethod[Context::getRequestMethod()])) { $this->add('redirect_url', $url); } diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index e1646246c..9a6660d1f 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -191,6 +191,7 @@ class boardController extends board } // return the results + $this->setRedirectUrl(getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', '', 'document_srl', $output->get('document_srl'))); $this->add('mid', Context::get('mid')); $this->add('document_srl', $output->get('document_srl')); @@ -399,6 +400,7 @@ class boardController extends board } $this->setMessage('success_registed'); + $this->setRedirectUrl(getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', '', 'document_srl', $obj->document_srl) . '#comment_' . $obj->comment_srl); $this->add('mid', Context::get('mid')); $this->add('document_srl', $obj->document_srl); $this->add('comment_srl', $obj->comment_srl); @@ -449,6 +451,7 @@ class boardController extends board $this->add('page', Context::get('page')); $this->add('document_srl', $output->get('document_srl')); $this->setMessage('success_deleted'); + $this->setRedirectUrl(getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', '', 'page', Context::get('page'), 'document_srl', $output->get('document_srl'))); } /** @@ -473,6 +476,7 @@ class boardController extends board $this->add('page', Context::get('page')); $this->add('document_srl', $output->get('document_srl')); $this->setMessage('success_deleted'); + $this->setRedirectUrl(getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', '', 'page', Context::get('page'), 'document_srl', $output->get('document_srl'))); } /** From 1b372375a4629a5e0616137908a4fba607ffbe3e Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 2 Mar 2016 10:10:10 +0900 Subject: [PATCH 049/318] Always set redirect_url if a module calls setRedirectUrl() --- classes/module/ModuleObject.class.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/classes/module/ModuleObject.class.php b/classes/module/ModuleObject.class.php index 5a656854c..99ee0b6a7 100644 --- a/classes/module/ModuleObject.class.php +++ b/classes/module/ModuleObject.class.php @@ -59,11 +59,7 @@ class ModuleObject extends Object * */ function setRedirectUrl($url = './', $output = NULL) { - $ajaxRequestMethod = array_flip($this->ajaxRequestMethod); - if(isset($ajaxRequestMethod[Context::getRequestMethod()])) - { - $this->add('redirect_url', $url); - } + $this->add('redirect_url', $url); if($output !== NULL && is_object($output)) { From 5f563af9846be76a4e9bb5a0be65ba47ee5a3565 Mon Sep 17 00:00:00 2001 From: conory Date: Wed, 2 Mar 2016 23:53:49 +0900 Subject: [PATCH 050/318] =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=96=B8=EC=96=B4=EC=97=90=20=EC=96=B8=EC=96=B4=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EA=B0=80=20=EC=97=86=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B8=20=EC=96=B8=EC=96=B4=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=B0=BE=EC=95=84=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0=20?= =?UTF-8?q?=EB=B2=88=EC=97=AD=EB=90=98=EC=A7=80=EC=95=8A=EC=9D=80=20?= =?UTF-8?q?=EB=AC=B8=EC=9E=A5=EC=9D=B4=20=EC=9E=88=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20=EB=8B=AC=EB=9E=91=20=EC=96=B8=EC=96=B4=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EB=A7=8C=EC=9D=84=20=EC=B6=9C=EB=A0=A5=ED=95=98?= =?UTF-8?q?=EC=A7=80=EB=A7=90=EA=B3=A0,=20=EB=8B=A4=EB=A5=B8=20=EC=96=B8?= =?UTF-8?q?=EC=96=B4=EB=A1=9C=20=EB=8C=80=EC=B2=B4=ED=95=98=EA=B8=B0=20(?= =?UTF-8?q?=EC=98=81=EC=96=B4=20=EC=9A=B0=EC=84=A0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 101 ++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 20 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index ffbaa86cb..b674948b3 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -16,6 +16,7 @@ class Lang * Configuration. */ protected $_language; + protected $_other_lang = array(); protected $_loaded_directories = array(); protected $_loaded_plugins = array(); protected $_search_priority = array(); @@ -85,6 +86,7 @@ class Lang * Load translations from a directory. * * @param string $dir + * @param string $plugin_name * @return bool */ public function loadDirectory($dir, $plugin_name = null) @@ -97,34 +99,34 @@ class Lang return true; } - // Look for language files. - if (file_exists($dir . '/' . $this->_language . '.php')) + $default_lang = array('en', 'ko'); + if (!in_array($this->_language, $default_lang)) { - $filename = $dir . '/' . $this->_language . '.php'; + $default_lang[] = $this->_language; } - elseif (($hyphen = strpos($this->_language, '-')) !== false) + + foreach ($default_lang as $val) { - if (file_exists($dir . '/' . substr($this->_language, 0, $hyphen) . '.php')) + $lang = $this->getPluginLang($dir, $val); + if (empty($lang)) { - $filename = $dir . '/' . substr($this->_language, 0, $hyphen) . '.php'; + continue; + } + + if ($this->_language === $val) + { + $this->_loaded_plugins[$plugin_name] = $lang; + } + else + { + $this->_other_lang[$plugin_name][$val] = $lang; } - } - elseif (file_exists("$dir/lang.xml")) - { - $filename = Compat\LangParser::compileXMLtoPHP("$dir/lang.xml", $this->_language === 'ja' ? 'jp' : $this->_language); - } - elseif (file_exists($dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php')) - { - $filename = $dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php'; } // Load the language file. - if ($filename) + if (isset($this->_loaded_plugins[$plugin_name])) { - $lang = new \stdClass; - include $filename; $this->_loaded_directories[$dir] = true; - $this->_loaded_plugins[$plugin_name] = $lang; array_unshift($this->_search_priority, $plugin_name); return true; } @@ -136,6 +138,48 @@ class Lang } } + /** + * get the language file from plugin. + * + * @param string $dir + * @param string $language + * @return object + */ + public function getPluginLang($dir, $language = null) + { + if (!$language) + { + $language = $this->_language; + } + + if (file_exists($dir . '/' . $language . '.php')) + { + $filename = $dir . '/' . $language . '.php'; + } + elseif (($hyphen = strpos($language, '-')) !== false && file_exists($dir . '/' . substr($language, 0, $hyphen) . '.php')) + { + $filename = $dir . '/' . substr($language, 0, $hyphen) . '.php'; + } + elseif (file_exists("$dir/lang.xml")) + { + $filename = Compat\LangParser::compileXMLtoPHP("$dir/lang.xml", $language === 'ja' ? 'jp' : $language); + } + elseif (file_exists($dir . '/' . ($language === 'ja' ? 'jp' : $language) . '.lang.php')) + { + $filename = $dir . '/' . ($language === 'ja' ? 'jp' : $language) . '.lang.php'; + } + + if (!$filename) + { + return new \stdClass; + } + + $lang = new \stdClass; + include $filename; + + return $lang; + } + /** * Get the list of supported languages. * @@ -179,10 +223,15 @@ class Lang { return $this->_loaded_plugins[$plugin_name]->{$key}; } - else + foreach ($this->_other_lang[$plugin_name] as $lang) { - return $key; + if (isset($lang->{$key})) + { + return $lang->{$key}; + } } + + return $key; } // Search custom translations first. @@ -213,6 +262,18 @@ class Lang } } } + + // Search other language. + foreach ($this->_other_lang as $plugin_name => $val) + { + foreach ($this->_other_lang[$plugin_name] as $lang) + { + if (isset($lang->{$key})) + { + return $lang->{$key}; + } + } + } // If no translation is found, return the key. return $key; From b9a8b15fe986a1052e9b2c88bec3b9b9c24fafd5 Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 11:56:19 +0900 Subject: [PATCH 051/318] =?UTF-8?q?=EC=9D=B8=EC=8A=A4=ED=84=B4=EC=8A=A4=20?= =?UTF-8?q?=ED=99=9C=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 77 ++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 29 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index b674948b3..c24dcb040 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -16,7 +16,6 @@ class Lang * Configuration. */ protected $_language; - protected $_other_lang = array(); protected $_loaded_directories = array(); protected $_loaded_plugins = array(); protected $_search_priority = array(); @@ -87,9 +86,10 @@ class Lang * * @param string $dir * @param string $plugin_name + * @param array $default_lang * @return bool */ - public function loadDirectory($dir, $plugin_name = null) + public function loadDirectory($dir, $plugin_name = null, $default_lang = null) { // Do not load the same directory twice. $dir = rtrim($dir, '/'); @@ -99,27 +99,31 @@ class Lang return true; } - $default_lang = array('en', 'ko'); + if (!is_array($default_lang)) + { + $default_lang = array('en', 'ko'); + } if (!in_array($this->_language, $default_lang)) { $default_lang[] = $this->_language; } - foreach ($default_lang as $val) + foreach ($default_lang as $language) { - $lang = $this->getPluginLang($dir, $val); - if (empty($lang)) - { - continue; - } - - if ($this->_language === $val) + if ($this->_language === $language) { + $lang = $this->getPluginLang($dir, $language); + if (empty($lang)) + { + continue; + } + $this->_loaded_plugins[$plugin_name] = $lang; } else { - $this->_other_lang[$plugin_name][$val] = $lang; + $other_lang = self::getInstance($language); + $other_lang->loadDirectory($dir, $plugin_name, array()); } } @@ -139,7 +143,7 @@ class Lang } /** - * get the language file from plugin. + * Get the language file from plugin. * * @param string $dir * @param string $language @@ -204,12 +208,13 @@ class Lang } /** - * Magic method for translations without arguments. + * Get lang from key * * @param string $key + * @param bool $other_lang * @return string */ - public function __get($key) + protected function _getLang($key, $other_lang = true) { // Separate the plugin name from the key. if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key, 2)) && count($keys) === 2) @@ -223,15 +228,8 @@ class Lang { return $this->_loaded_plugins[$plugin_name]->{$key}; } - foreach ($this->_other_lang[$plugin_name] as $lang) - { - if (isset($lang->{$key})) - { - return $lang->{$key}; - } - } - return $key; + goto end_other_lang; } // Search custom translations first. @@ -262,16 +260,26 @@ class Lang } } } - + + end_other_lang: + // Search other language. - foreach ($this->_other_lang as $plugin_name => $val) + if ($other_lang) { - foreach ($this->_other_lang[$plugin_name] as $lang) + foreach (self::$_instances as $language => $instance) { - if (isset($lang->{$key})) + if ($this->_language === $language) { - return $lang->{$key}; + continue; } + + $lang = $instance->_getLang($key, false); + if ($lang === $key) + { + continue; + } + + return $lang; } } @@ -279,6 +287,17 @@ class Lang return $key; } + /** + * Magic method for translations without arguments. + * + * @param string $key + * @return string + */ + public function __get($key) + { + return $this->_getLang($key); + } + /** * Magic method for setting a new custom translation. * @@ -339,7 +358,7 @@ class Lang if ($key !== '' && $key[0] === ':') $key = substr($key, 1); // Find the translation. - $translation = $this->__get($key); + $translation = $this->_getLang($key); // If there are no arguments, return the translation. if (!count($args)) return $translation; From 6a351265ff74b787c04dbaa194a9add711edd441 Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 12:32:31 +0900 Subject: [PATCH 052/318] =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=20=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index c24dcb040..aa68c0ca5 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -219,14 +219,14 @@ class Lang // Separate the plugin name from the key. if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key, 2)) && count($keys) === 2) { - list($plugin_name, $key) = $keys; + list($plugin_name, $lang_key) = $keys; if (!isset($this->_loaded_plugins[$plugin_name])) { $this->loadPlugin($plugin_name); } - if (isset($this->_loaded_plugins[$plugin_name]->{$key})) + if (isset($this->_loaded_plugins[$plugin_name]->{$lang_key})) { - return $this->_loaded_plugins[$plugin_name]->{$key}; + return $this->_loaded_plugins[$plugin_name]->{$lang_key}; } goto end_other_lang; From e5ae4a828a893d5648806dc06697ca260f334f4d Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 12:45:35 +0900 Subject: [PATCH 053/318] unit test --- tests/unit/framework/LangTest.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/unit/framework/LangTest.php b/tests/unit/framework/LangTest.php index d4059690b..cbe4c4ab0 100644 --- a/tests/unit/framework/LangTest.php +++ b/tests/unit/framework/LangTest.php @@ -14,17 +14,17 @@ class LangTest extends \Codeception\TestCase\Test $jp = Rhymix\Framework\Lang::getInstance('jp'); $this->assertTrue($ja === $jp); + $this->assertEquals('help', $ja->help); + $ja->loadPlugin('common'); + $this->assertEquals('ヘルプ', $ja->help); + $this->assertEquals('도움말', $ko->get('common.help')); $this->assertEquals('Help', $en->get('common.help')); $this->assertEquals('도움말', $ko->help); $this->assertEquals('Help', $en->help); - $this->assertEquals('nonexistent', $ko->get('common.nonexistent')); - $this->assertEquals('nonexistent', $ko->get('common.nonexistent', 'foo', 'bar')); - - $this->assertEquals('help', $ja->help); - $ja->loadPlugin('common'); - $this->assertEquals('ヘルプ', $ja->help); + $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent')); + $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent', 'foo', 'bar')); $ko->foobartestlang = '%s님 안녕하세요?'; $this->assertEquals('Travis님 안녕하세요?', $ko->foobartestlang('Travis')); From 39a4c14e7831cd3457c71d8ca70c4ce5aeb39a7e Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 3 Mar 2016 13:56:36 +0900 Subject: [PATCH 054/318] delete member_srl code --- modules/document/document.controller.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index fd4eb9f1d..ce434b29d 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -780,7 +780,6 @@ class documentController extends document if($source_obj === null) { $update_args->category_srl = $obj->category_srl; - $update_args->member_srl = $logged_info->member_srl; $update_args->module_srl = $obj->module_srl; $update_args->nick_name = $obj->nick_name; } @@ -794,7 +793,6 @@ class documentController extends document { $update_args->category_srl = $source_obj->get('category_srl'); } - $update_args->member_srl = $source_obj->get('member_srl'); $update_args->module_srl = $source_obj->get('module_srl'); $update_args->nick_name = $source_obj->get('nick_name'); } From f847db6ff40cbc9966469ff84ad591208fda475b Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 3 Mar 2016 14:13:48 +0900 Subject: [PATCH 055/318] History logs that adminstrator moves the documents. --- modules/document/document.admin.controller.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/modules/document/document.admin.controller.php b/modules/document/document.admin.controller.php index 8e6de0410..f1f77d00b 100644 --- a/modules/document/document.admin.controller.php +++ b/modules/document/document.admin.controller.php @@ -145,11 +145,20 @@ class documentAdminController extends document $obj->module_srl = $module_srl; $obj->category_srl = $category_srl; $output = executeQuery('document.updateDocumentModule', $obj); - if(!$output->toBool()) { + if(!$output->toBool()) + { $oDB->rollback(); return $output; } - + else + { + $update_output = $oDocumentController->insertDocumentUpdateLog($obj); + if(!$update_output->toBool()) + { + $oDB->rollback(); + return $update_output; + } + } //Move a module of the extra vars $output = executeQuery('document.moveDocumentExtraVars', $obj); if(!$output->toBool()) { From b727466e61764a9ed858385fde0ff916ebaeca54 Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 14:46:19 +0900 Subject: [PATCH 056/318] unit test2 --- tests/unit/framework/LangTest.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/unit/framework/LangTest.php b/tests/unit/framework/LangTest.php index cbe4c4ab0..2ca57cb61 100644 --- a/tests/unit/framework/LangTest.php +++ b/tests/unit/framework/LangTest.php @@ -14,10 +14,6 @@ class LangTest extends \Codeception\TestCase\Test $jp = Rhymix\Framework\Lang::getInstance('jp'); $this->assertTrue($ja === $jp); - $this->assertEquals('help', $ja->help); - $ja->loadPlugin('common'); - $this->assertEquals('ヘルプ', $ja->help); - $this->assertEquals('도움말', $ko->get('common.help')); $this->assertEquals('Help', $en->get('common.help')); $this->assertEquals('도움말', $ko->help); @@ -26,6 +22,12 @@ class LangTest extends \Codeception\TestCase\Test $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent')); $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent', 'foo', 'bar')); + $this->assertEquals('admin.help', $ko->get('admin.help')); + $this->assertEquals('admin.help', $en->get('admin.help')); + + $ja->loadPlugin('common'); + $this->assertEquals('ヘルプ', $ja->help); + $ko->foobartestlang = '%s님 안녕하세요?'; $this->assertEquals('Travis님 안녕하세요?', $ko->foobartestlang('Travis')); $en->foobartestlang = 'Hello, %s!'; From ea2cc89d463667d425340c6d06e3b05beaf9d96e Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 14:57:03 +0900 Subject: [PATCH 057/318] unit test3 --- tests/unit/framework/LangTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/framework/LangTest.php b/tests/unit/framework/LangTest.php index 2ca57cb61..2d44b1e50 100644 --- a/tests/unit/framework/LangTest.php +++ b/tests/unit/framework/LangTest.php @@ -25,6 +25,7 @@ class LangTest extends \Codeception\TestCase\Test $this->assertEquals('admin.help', $ko->get('admin.help')); $this->assertEquals('admin.help', $en->get('admin.help')); + $this->assertEquals('Help', $ja->help); $ja->loadPlugin('common'); $this->assertEquals('ヘルプ', $ja->help); From 79209bf2af6f5f9a3eacdd7c123e79ef024dc3db Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 16:47:57 +0900 Subject: [PATCH 058/318] unit test4 --- tests/unit/framework/LangTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/framework/LangTest.php b/tests/unit/framework/LangTest.php index 2d44b1e50..2ca57cb61 100644 --- a/tests/unit/framework/LangTest.php +++ b/tests/unit/framework/LangTest.php @@ -25,7 +25,6 @@ class LangTest extends \Codeception\TestCase\Test $this->assertEquals('admin.help', $ko->get('admin.help')); $this->assertEquals('admin.help', $en->get('admin.help')); - $this->assertEquals('Help', $ja->help); $ja->loadPlugin('common'); $this->assertEquals('ヘルプ', $ja->help); From 9f9fa6e65340d52fa5ed6fb9611591b24481408f Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 18:19:44 +0900 Subject: [PATCH 059/318] =?UTF-8?q?#327=20=EC=96=B8=EC=96=B4=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/lang/de.php | 1 - common/lang/en.php | 1 - common/lang/es.php | 4 ---- common/lang/fr.php | 4 ---- common/lang/mn.php | 2 -- common/lang/ru.php | 6 ------ common/lang/tr.php | 1 - common/lang/vi.php | 2 -- common/lang/zh-CN.php | 2 -- common/lang/zh-TW.php | 1 - modules/admin/lang/fr.php | 1 - modules/admin/lang/ru.php | 14 -------------- modules/admin/lang/vi.php | 2 -- modules/admin/lang/zh-CN.php | 5 ----- modules/admin/lang/zh-TW.php | 7 +------ modules/board/lang/es.php | 1 - modules/board/lang/fr.php | 2 -- modules/board/lang/ru.php | 6 +----- modules/board/lang/zh-CN.php | 1 - modules/communication/lang/es.php | 1 - modules/document/lang/es.php | 4 ---- modules/document/lang/fr.php | 2 -- modules/document/lang/ru.php | 1 - modules/editor/lang/en.php | 1 - modules/editor/lang/es.php | 16 ---------------- modules/editor/lang/fr.php | 15 --------------- modules/editor/lang/ru.php | 12 ------------ modules/editor/lang/tr.php | 12 ------------ modules/editor/lang/vi.php | 12 ------------ modules/editor/lang/zh-CN.php | 12 ------------ modules/editor/lang/zh-TW.php | 12 ------------ modules/file/lang/es.php | 2 -- modules/file/lang/fr.php | 6 ------ modules/importer/lang/es.php | 2 -- modules/install/lang/es.php | 1 - modules/install/lang/fr.php | 8 -------- modules/install/lang/ru.php | 2 -- modules/layout/lang/de.php | 20 -------------------- modules/layout/lang/es.php | 13 ------------- modules/layout/lang/fr.php | 13 ------------- modules/layout/lang/ru.php | 9 --------- modules/layout/lang/vi.php | 1 - modules/layout/lang/zh-TW.php | 1 - modules/member/lang/en.php | 1 - modules/member/lang/es.php | 15 --------------- modules/member/lang/fr.php | 5 ----- modules/member/lang/ja.php | 3 --- modules/member/lang/ru.php | 1 - modules/member/lang/zh-CN.php | 5 ----- modules/member/lang/zh-TW.php | 10 ---------- modules/menu/lang/en.php | 11 ----------- modules/module/lang/es.php | 8 -------- modules/module/lang/fr.php | 7 ------- modules/module/lang/ja.php | 1 - modules/module/lang/ru.php | 9 --------- modules/module/lang/zh-TW.php | 4 ---- modules/page/lang/ru.php | 3 +-- modules/page/lang/vi.php | 3 +-- modules/point/lang/es.php | 5 ----- modules/point/lang/fr.php | 4 ---- modules/point/lang/ja.php | 2 -- modules/point/lang/ru.php | 5 ----- modules/point/lang/zh-CN.php | 2 -- modules/point/lang/zh-TW.php | 3 --- modules/widget/lang/fr.php | 1 - modules/widget/lang/ru.php | 1 - modules/widget/lang/vi.php | 1 - modules/widget/lang/zh-CN.php | 1 - modules/widget/lang/zh-TW.php | 1 - 69 files changed, 4 insertions(+), 349 deletions(-) diff --git a/common/lang/de.php b/common/lang/de.php index ad9200ee7..0288caff9 100644 --- a/common/lang/de.php +++ b/common/lang/de.php @@ -280,7 +280,6 @@ $lang->filter['invalid_korean_number'] = 'Das Format von% s ist ungültig. Bitte $lang->filter['invalid_alpha'] = 'Das Format von% s ist ungültig. Bitte nur Alphabete eingeben.'; $lang->filter['invalid_alpha_number'] = 'Das Format von% s ist ungültig. Bitte nur Alphabete oder Zahlen eingeben.'; $lang->filter['invalid_number'] = 'Das Format von% s ist ungültig. Bitte nur Zahlen eingeben.'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $lang->security_warning_embed = 'Aus Sicherheitsgründen ist es nicht erlaubt, dass der Administrator den eingebetteten Teil sehen. Wenn Sie das sehen möchten, loggen Sie sich mit einem anderen ID ein.'; $lang->msg_pc_to_mobile = 'Möchten Sie Mobile-Look?'; $lang->cmd_yes = 'Ja'; diff --git a/common/lang/en.php b/common/lang/en.php index 9e40662e0..7a5942434 100644 --- a/common/lang/en.php +++ b/common/lang/en.php @@ -298,7 +298,6 @@ $lang->filter['invalid_alpha_number'] = 'The format of %s is invalid. Please ent $lang->filter['invalid_mid'] = 'The format of %s is invalid. Module ID should be begun with a letter. Subsequent characters may be letters, digits or underscore characters.'; $lang->filter['invalid_number'] = 'The format of %s is invalid. Please enter numbers only.'; $lang->filter['invalid_extension'] = 'The format of %s is invalid. e.g.) *.* or *.jpg;*.gif;.'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $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.'; $lang->msg_pc_to_mobile = 'View mobile optimized version of this page'; $lang->cmd_yes = 'Yes'; diff --git a/common/lang/es.php b/common/lang/es.php index def7d71cd..c7dfc634b 100644 --- a/common/lang/es.php +++ b/common/lang/es.php @@ -228,7 +228,3 @@ $lang->filter['invalid_korean_number'] = 'Sólo puede introducir los caracteres $lang->filter['invalid_alpha'] = 'Sólo puede introducir los alfabetos en el %s'; $lang->filter['invalid_alpha_number'] = 'Sólo puede introducir los alfanuméricos en el %s es inválido'; $lang->filter['invalid_number'] = 'Sólo puede introducir los dígitos numéricos en el %s'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; -$lang->msg_pc_to_mobile = '이 페이지는 모바일 보기가 있습니다. 모바일 보기로 이동하시겠습니까?'; -$lang->mobile_view = 'Use Mobile View'; -$lang->about_mobile_view = 'If accessing with a smartphone, display content with mobile layout.'; diff --git a/common/lang/fr.php b/common/lang/fr.php index b39285ade..53b803ef2 100644 --- a/common/lang/fr.php +++ b/common/lang/fr.php @@ -224,7 +224,3 @@ $lang->filter['invalid_korean_number'] = 'La format de %s n\'est pas convenable. $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.'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; -$lang->msg_pc_to_mobile = '이 페이지는 모바일 보기가 있습니다. 모바일 보기로 이동하시겠습니까?'; -$lang->mobile_view = 'Use Mobile View'; -$lang->about_mobile_view = 'If accessing with a smartphone, display content with mobile layout.'; diff --git a/common/lang/mn.php b/common/lang/mn.php index 9cedc9242..937ddb473 100644 --- a/common/lang/mn.php +++ b/common/lang/mn.php @@ -245,5 +245,3 @@ $lang->filter['invalid_korean_number'] = '%s-ын хэлбэр буруу бай $lang->filter['invalid_alpha'] = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсгээр оруулах ёстой'; $lang->filter['invalid_alpha_number'] = '%s-ын хэлбэр буруу байна. Зөвхөн латин үсэг болон тоогоор л оруулах ёстой.'; $lang->filter['invalid_number'] = '%s-ын хэлбэр буруу байна. Зөвхөн тоогоор оруулах ёстой.'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; -$lang->msg_pc_to_mobile = '이 페이지는 모바일 보기가 있습니다. 모바일 보기로 이동하시겠습니까?'; diff --git a/common/lang/ru.php b/common/lang/ru.php index 37fa62c14..594fdd5ba 100644 --- a/common/lang/ru.php +++ b/common/lang/ru.php @@ -228,9 +228,3 @@ $lang->default_value = 'Стандартное значение'; $lang->is_active = 'Активация'; $lang->is_required = 'Обязательные данные'; $lang->eid = 'Имя экстра переменных'; -$lang->filter['invalid_email'] = 'The format of %s is invalid.'; -$lang->filter['invalid_userid'] = 'The format of %s is invalid. All values should consist of alphabets, numbers or underscore(_) and the first letter should be alphabet'; -$lang->filter['invalid_user_id'] = 'The format of %s is invalid. All values should consist of alphabets, numbers or underscore(_) and the first letter should be alphabet'; -$lang->msg_pc_to_mobile = '이 페이지는 모바일 보기가 있습니다. 모바일 보기로 이동하시겠습니까?'; -$lang->mobile_view = 'Use Mobile View'; -$lang->about_mobile_view = 'If accessing with a smartphone, display content with mobile layout.'; diff --git a/common/lang/tr.php b/common/lang/tr.php index ca1223da7..5e98a373f 100644 --- a/common/lang/tr.php +++ b/common/lang/tr.php @@ -273,7 +273,6 @@ $lang->filter['invalid_alpha'] = '%s biçimi geçersiz. Lütfen sadece harfleri $lang->filter['invalid_alpha_number'] = ' %s biçimi geçersiz. Lütfen harfleri ve sayıları kullanınız.'; $lang->filter['invalid_mid'] = '%s formatı geçersizdir. Modülün ID\'si harf ile başlaması gerekmektedir.'; $lang->filter['invalid_number'] = '%s bicimi geçersizdir . Lütfen sadece numaraları kullanın.'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $lang->security_warning_embed = 'Güvenlik nedeniyle, yöneticiler yerleşik öğeleri görüntülemeye yetkili değildirler.
Yerleşik öğeleri görüntüleyebilmek için, lütfen yönetici olmayan bir hesap kullanın.'; $lang->msg_pc_to_mobile = 'Bu sayfanın mobil versiyonu bulunmaktadır. Mobil sayfaya geçiş yapmak istiyor musunuz?'; $lang->cmd_yes = 'Evet'; diff --git a/common/lang/vi.php b/common/lang/vi.php index ca6b82432..015d6b707 100644 --- a/common/lang/vi.php +++ b/common/lang/vi.php @@ -230,9 +230,7 @@ $lang->filter['invalid_korean_number'] = 'Định dạng của %s không hợp l $lang->filter['invalid_alpha'] = 'Định dạng của %s không hợp lệ. Chỉ sử dụng các kí tự từ a-z'; $lang->filter['invalid_alpha_number'] = 'Định dạng của %s không hợp lệ. Chỉ sử dụng các kí tự từ a-z và các chữ số'; $lang->filter['invalid_number'] = 'Định dạng của %s không hợp lệ. Chỉ sử dụng các chữ số'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $lang->security_warning_embed = 'Vì vấn đề bảo mật, nên Administrator không được phép xem các mục đã nhúng mã.
Để xem được chúng, hãy sử dụng một tên truy cập khác không có quyền quản trị.'; -$lang->msg_pc_to_mobile = '이 페이지는 모바일 보기가 있습니다. 모바일 보기로 이동하시겠습니까?'; $lang->mobile_view = 'Xem bằng di động'; $lang->about_mobile_view = 'Nếu truy cập bằng thiết bị di động, nội dung sẽ được bố trí theo từng loại thiết bị.'; $lang->more = 'Xem thêm'; diff --git a/common/lang/zh-CN.php b/common/lang/zh-CN.php index 7830681e2..a634fff47 100644 --- a/common/lang/zh-CN.php +++ b/common/lang/zh-CN.php @@ -276,9 +276,7 @@ $lang->filter['invalid_alpha'] = '%s只能输入英文字母'; $lang->filter['invalid_alpha_number'] = '%s只能输入英文或数字'; $lang->filter['invalid_mid'] = '%s 格式错误。 模块名称只能用英文、数字及下划线,开头必须是英文。'; $lang->filter['invalid_number'] = '%s只能输入数字'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $lang->security_warning_embed = '由于安全问题,不允许用系统管理员ID操作embed对象,请使用其他拥有管理权限的ID操作。'; -$lang->msg_pc_to_mobile = '이 페이지는 모바일 보기가 있습니다. 모바일 보기로 이동하시겠습니까?'; $lang->cmd_yes = '是'; $lang->cmd_no = '否'; $lang->cmd_set_multilingual = '选择语言'; diff --git a/common/lang/zh-TW.php b/common/lang/zh-TW.php index cc14d4c13..18562b202 100644 --- a/common/lang/zh-TW.php +++ b/common/lang/zh-TW.php @@ -275,7 +275,6 @@ $lang->filter['invalid_alpha'] = '%s只能輸入英文字母'; $lang->filter['invalid_alpha_number'] = '%s只能輸入英文或數字'; $lang->filter['invalid_mid'] = '%s 格式錯誤。 模組名稱只能使用英文、數字及底線,開頭必須是英文。'; $lang->filter['invalid_number'] = '%s只能輸入數字'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $lang->security_warning_embed = '基於安全因素,管理員無法檢視嵌入的物件。
請使用其他非管理員帳號檢視。'; $lang->msg_pc_to_mobile = '此頁面有手機頁面,要移至手機頁面嗎?'; $lang->cmd_yes = '是'; diff --git a/modules/admin/lang/fr.php b/modules/admin/lang/fr.php index 908fc55e9..808d4862b 100644 --- a/modules/admin/lang/fr.php +++ b/modules/admin/lang/fr.php @@ -44,6 +44,5 @@ $lang->trash = 'Poubelle'; $lang->timezone = 'Fuseau horaire'; $lang->about_use_sso = 'SSO will enable users to sign in just once for both default and virtual site. You will need this only if you are using virtual sites.'; $lang->modify = 'Modifier'; -$lang->ftp_form_title = 'FTP 정보 입력'; $lang->ftp = 'FTP'; $lang->msg_ftp_no_directory = 'Succeed to connect to the host via FTP. However, can not read any directory list informaiton. Check the server configurations.'; diff --git a/modules/admin/lang/ru.php b/modules/admin/lang/ru.php index 1d799b358..6548c7ae7 100644 --- a/modules/admin/lang/ru.php +++ b/modules/admin/lang/ru.php @@ -4,14 +4,6 @@ $lang->admin_index = 'Индексная страница администрат $lang->control_panel = 'Контрольная панель'; $lang->start_module = 'Homepage'; $lang->about_start_module = 'Вы можете указать модуль запуска по умолчанию.'; -$lang->select_site = 'Site'; -$lang->select_module_type = 'Module Type'; -$lang->select_module_instance = 'Page'; -$lang->module_category_title['service'] = 'Service Setting'; -$lang->module_category_title['member'] = 'Member Setting'; -$lang->module_category_title['content'] = 'Content Setting'; -$lang->module_category_title['utility'] = 'Utility Setting'; -$lang->module_category_title['interlock'] = 'Interlock Setting'; $lang->newest_news = 'Последние новости'; $lang->env_setup = 'Настройка'; $lang->default_url = 'Основной URL'; @@ -40,15 +32,9 @@ $lang->today = 'Сегодня'; $lang->ssl_options['none'] = 'Никогда'; $lang->ssl_options['optional'] = 'На выбор'; $lang->ssl_options['always'] = 'Всегда'; -$lang->about_use_ssl = 'In case of "Optional", SSL will be used for actions such as signing up / changing information. And for "Always", your site will be served only via https SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.'; -$lang->about_db_session = 'It will use php session with DB when authenticating. Websites with infrequent usage of web server may expect faster response when this function is disabled. However session DB will make it unable to get current users, so you cannot use related functions'; -$lang->ftp_remove_info = 'Remove FTP Info'; $lang->trash = 'мусор'; $lang->timezone = 'Часовой пояс'; -$lang->about_use_sso = 'SSO will enable users to sign in just once for both default and virtual site. You will need this only if you are using virtual sites.'; $lang->move = 'Перейти'; $lang->modify = 'Изменить'; $lang->ftp_form_title = 'Введите данные FTP'; $lang->ftp = 'FTP'; -$lang->msg_ftp_no_directory = 'Succeed to connect to the host via FTP. However, can not read any directory list informaiton. Check the server configurations.'; -$lang->msg_ftp_chmod_fail = 'Chmod failed. Please check the permission and configuration of FTP server.'; diff --git a/modules/admin/lang/vi.php b/modules/admin/lang/vi.php index e50d361ba..45da587f1 100644 --- a/modules/admin/lang/vi.php +++ b/modules/admin/lang/vi.php @@ -58,7 +58,6 @@ $lang->msg_self_restart_cache_engine = 'Hãy thiết lập lại bộ nhớ Cach $lang->autoinstall = 'Cập nhật tự động'; $lang->trash = 'Thùng rác'; $lang->timezone = 'Múi giờ'; -$lang->about_use_sso = 'SSO will enable users to sign in just once for both default and virtual site. You will need this only if you are using virtual sites.'; $lang->move = 'Di chuyển'; $lang->modify = 'Thay đổi'; $lang->ftp_form_title = 'Thông tin FTP'; @@ -68,7 +67,6 @@ $lang->ftp_port = 'Cổng kết nối'; $lang->about_ftp_password = 'Mật khẩu của FTP sẽ không lưu lại'; $lang->cmd_check_ftp_connect = 'Kiểm tra kết nối bằng FTP'; $lang->msg_safe_mode_ftp_needed = 'Nếu safe_mode của PHP mở, bạn có thể cài đặt các thành phần bổ xung cho Rhymix một cách tự động qua FTP.'; -$lang->msg_ftp_no_directory = 'Succeed to connect to the host via FTP. However, can not read any directory list informaiton. Check the server configurations.'; $lang->msg_ftp_mkdir_fail = 'Lỗi khi tạo thư mục. Xin vui lòng kiểm tra lại quyền truy cập FTP.'; $lang->msg_ftp_chmod_fail = 'CHMOD thất bại. Xin vui lòng kiểm tra lại.'; $lang->msg_ftp_connect_success = 'Đã xác nhận và kết nối thành công tới máy chủ bằng FTP.'; diff --git a/modules/admin/lang/zh-CN.php b/modules/admin/lang/zh-CN.php index b7ea84e8a..a2232ec92 100644 --- a/modules/admin/lang/zh-CN.php +++ b/modules/admin/lang/zh-CN.php @@ -12,11 +12,7 @@ $lang->favorites = '收藏'; $lang->admin_info = '管理员信息'; $lang->admin_index = '管理首页'; $lang->control_panel = '控制面板'; -$lang->start_module = 'Homepage'; $lang->about_start_module = '可指定用户访问网站时的默认首页模块。'; -$lang->select_site = 'Site'; -$lang->select_module_type = 'Module Type'; -$lang->select_module_instance = 'Page'; $lang->module_category_title['service'] = '应用管理'; $lang->module_category_title['member'] = '用户管理'; $lang->module_category_title['content'] = '资源管理'; @@ -101,7 +97,6 @@ $lang->about_use_favicon = '请上传16*16像素的*.ico文件.'; $lang->allow_use_mobile_icon = '是否启用移动版屏幕图标?'; $lang->detail_use_mobile_icon = '请上传57*57像素或者114*114像素的*.png文件.'; $lang->use_sso = '是否启用通行证SSO?'; -$lang->about_use_sso = 'SSO will enable users to sign in just once for both default and virtual site. You will need this only if you are using virtual sites.'; $lang->about_arrange_session = '你想要整理session吗?'; $lang->cmd_clear_session = '整理sessioon'; $lang->save = '保存'; diff --git a/modules/admin/lang/zh-TW.php b/modules/admin/lang/zh-TW.php index 48ebb29a2..6a517cfbd 100644 --- a/modules/admin/lang/zh-TW.php +++ b/modules/admin/lang/zh-TW.php @@ -2,11 +2,7 @@ $lang->admin_info = '管理員資訊'; $lang->admin_index = '管理頁面'; $lang->control_panel = '控制介面'; -$lang->start_module = 'Homepage'; $lang->about_start_module = '可將所選擇的模組作為預設首頁。'; -$lang->select_site = 'Site'; -$lang->select_module_type = 'Module Type'; -$lang->select_module_instance = 'Page'; $lang->module_category_title['service'] = '服務設定'; $lang->module_category_title['member'] = '會員管理'; $lang->module_category_title['content'] = '內容管理'; @@ -45,7 +41,7 @@ $lang->today = '今天'; $lang->ssl_options['none'] = '關閉'; $lang->ssl_options['optional'] = '手動'; $lang->ssl_options['always'] = '開啟'; -$lang->about_use_ssl = '選擇手動時,在會員註冊或修改資料等動作時才會使用 SSL功能。 選擇開啟時,所有的服務都會使用 SSL功能。 SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.'; +$lang->about_use_ssl = '選擇手動時,在會員註冊或修改資料等動作時才會使用 SSL功能。 選擇開啟時,所有的服務都會使用 SSL功能。 '; $lang->server_ports = '主機埠口'; $lang->about_server_ports = 'HTTP、HTTPS預設埠口分別是『80』、『443』 如果想使用其他的埠口的話,請自行設定。'; $lang->use_db_session = 'DB session認證'; @@ -73,7 +69,6 @@ $lang->cmd_check_ftp_connect = '檢查 FTP 連線'; $lang->msg_safe_mode_ftp_needed = '當 PHP 的安全模式(safe_mode)開啟時,請輸入相關 FTP 資訊,否則無法正常安裝或使用程式。'; $lang->msg_safe_mode_ftp_needed2 = '可用的安裝或更新。'; $lang->msg_safe_mode_ftp_config = '此資料會儲存在files/config/ftp.config.php 檔案中。 安裝後可在設定頁面中新增、更改或刪除此資訊。'; -$lang->msg_ftp_no_directory = 'Succeed to connect to the host via FTP. However, can not read any directory list informaiton. Check the server configurations.'; $lang->msg_ftp_mkdir_fail = '新增資料夾失敗。請確認 FTP 主機設置。'; $lang->msg_ftp_chmod_fail = '修改資料夾權限失敗。請確認 FTP 主機設置。'; $lang->msg_ftp_connect_success = 'FTP連線成功。'; diff --git a/modules/board/lang/es.php b/modules/board/lang/es.php index 3799f7ce2..40fbda476 100644 --- a/modules/board/lang/es.php +++ b/modules/board/lang/es.php @@ -13,7 +13,6 @@ $lang->cmd_board_info = 'Información del Tablero'; $lang->about_layout_setup = 'Puede modificar manualmente el código del diseño de tableros. Insertar o modificar el código de widget.'; $lang->about_board_category = 'Puede crear las categorias de tableros. Cuando no funciona la categoría de tableros, rehacer el archivo caché manualmente para solucionar.'; $lang->about_except_notice = 'Aviso de los artículos no se mostrará en la lista normal.'; -$lang->about_use_anonymous = '글쓴이의 정보를 없애고 익명으로 게시판 사용을 할 수 있게 합니다. 스킨설정에서 글쓴이 정보등을 보이지 않도록 하시면 더욱 유용합니다'; $lang->about_board = 'Este módulo es para crear y manejar los tableros.'; $lang->about_consultation = 'No administrador de los miembros que consideran que su propia artocles. \\ NNon miembros no serían capaces de escribir artículos al utilizar la consulta.'; $lang->about_secret = 'Boletín y los comentarios de bimilgeul utilizar.'; diff --git a/modules/board/lang/fr.php b/modules/board/lang/fr.php index 30497e469..4fd5a7566 100644 --- a/modules/board/lang/fr.php +++ b/modules/board/lang/fr.php @@ -10,8 +10,6 @@ $lang->cmd_board_info = 'Information des Panneaux'; $lang->about_layout_setup = 'Vous pouvez manuellement modifier le code de Mise en Page du blogue. Insérez ou administrez le code de Gadget n\'importe où vous voulez.'; $lang->about_board_category = 'Vous pouvez créer des catégories de Panneau d\'Affichage. Quand la catégorie d\'affichage est cassé, essayez manuellement rétablir l\'antémémoire du fichier.'; $lang->about_except_notice = 'Le titre de Notice dont l\'article se représentera toujours en tête de la liste ne sera exposé sur la liste générale.'; -$lang->about_use_anonymous = '글쓴이의 정보를 없애고 익명으로 게시판 사용을 할 수 있게 합니다. 스킨설정에서 글쓴이 정보등을 보이지 않도록 하시면 더욱 유용합니다'; $lang->about_board = 'Ce module se sert à créer et à administrer des Panneaux d\'Affichage.'; $lang->about_consultation = 'Les membres non-administratifs verront seulement les ariticles d\'eux-même. Non-membres ne pourraient pas écrire des articles quand la Consultation est appliqué.'; $lang->about_admin_mail = 'Un message éléctronique sera envoyé à l\'adresse inscrite quand un article ou commentaire se soumet. On peut inscrire multiple adresses délimité par les virgules.'; -$lang->about_list_config = '게시판의 목록형식 사용시 원하는 항목들로 배치를 할 수 있습니다. 단 스킨에서 지원하지 않는 경우 지원되지 않을 수 있습니다 대상항목/ 표시항목의 항목을 더블클릭하면 추가/ 제거가 됩니다.'; diff --git a/modules/board/lang/ru.php b/modules/board/lang/ru.php index 3db404004..e51067ae9 100644 --- a/modules/board/lang/ru.php +++ b/modules/board/lang/ru.php @@ -7,8 +7,4 @@ $lang->cmd_module_config = 'Общие настройки форума'; $lang->cmd_board_info = 'Информация форума'; $lang->about_layout_setup = 'Вы можете вручную изменять лейаут код блога. Вставляйте или управляйте кодом виджетов везде, где хотите'; $lang->about_board_category = 'Вы можете сделать категории блога. Когда категория блога испорчена, попробуйте перепостроить файл кеша вручную.'; -$lang->about_use_anonymous = '글쓴이의 정보를 없애고 익명으로 게시판 사용을 할 수 있게 합니다. 스킨설정에서 글쓴이 정보등을 보이지 않도록 하시면 더욱 유용합니다'; -$lang->about_board = 'Этот модуль служит для создания и управления форумами.'; -$lang->about_consultation = '상담 기능은 관리권한이 없는 회원은 자신이 쓴 글만 보이도록 하는 기능입니다. 단 상담기능 사용시 비회원 글쓰기는 자동으로 금지됩니다.'; -$lang->about_admin_mail = '글이나 댓글이 등록될때 등록된 메일주소로 메일이 발송됩니다 ,(콤마)로 연결시 다수의 메일주소로 발송할 수 있습니다.'; -$lang->about_list_config = '게시판의 목록형식 사용시 원하는 항목들로 배치를 할 수 있습니다. 단 스킨에서 지원하지 않는 경우 지원되지 않을 수 있습니다 대상항목/ 표시항목의 항목을 더블클릭하면 추가/ 제거가 됩니다.'; +$lang->about_board = 'Этот модуль служит для создания и управления форумами.'; \ No newline at end of file diff --git a/modules/board/lang/zh-CN.php b/modules/board/lang/zh-CN.php index 9fab19e2e..47ad27694 100644 --- a/modules/board/lang/zh-CN.php +++ b/modules/board/lang/zh-CN.php @@ -16,7 +16,6 @@ $lang->cmd_list_setting = '列表设置'; $lang->about_layout_setup = '可直接编辑博客布局代码。可以把控件代码插入到您喜欢的位置。'; $lang->about_board_category = '可以添加/删除分类项 分类有异常情况时,可以尝试重新生成缓冲文件。'; $lang->about_except_notice = '设置公告目录项不再重复显示到普通目录当中。'; -$lang->about_use_anonymous = '글쓴이의 정보를 없애고 익명으로 게시판 사용을 할 수 있게 합니다. 스킨설정에서 글쓴이 정보등을 보이지 않도록 하시면 더욱 유용합니다'; $lang->about_board = '可生成及管理版面的模块。'; $lang->about_consultation = '咨询功能是指除有管理权限的会员以外,其他会员只能浏览自己发表的主题。使用咨询功能时系统将自动禁止非会员的发表主题权限。'; $lang->about_secret = '设置主题及评论当中使用密帖与否。'; diff --git a/modules/communication/lang/es.php b/modules/communication/lang/es.php index 789ed1c77..55de5ace5 100644 --- a/modules/communication/lang/es.php +++ b/modules/communication/lang/es.php @@ -1,5 +1,4 @@ about_communication = '회원간의 쪽지나 친구 관리 등 커뮤니케이션 기능을 수행합니다'; $lang->allow_message = 'Permitir la recepción del mensaje'; $lang->allow_message_type['Y'] = 'Recibir todo'; $lang->allow_message_type['N'] = 'Rechazar'; diff --git a/modules/document/lang/es.php b/modules/document/lang/es.php index 42ed4364a..d69d8bf4d 100644 --- a/modules/document/lang/es.php +++ b/modules/document/lang/es.php @@ -1,6 +1,5 @@ document_list = 'Document list'; -$lang->new_document_count = '새글'; $lang->parent_category_title = 'Categoría Superior'; $lang->category_title = 'Nombre de la categoría'; $lang->expand = 'Expandir'; @@ -9,8 +8,6 @@ $lang->cmd_make_child = 'Agregar sub categoría'; $lang->cmd_enable_move_category = 'Cambiar la posición de la categoría. (arrastrar y soltar luego de haber selecionado)'; $lang->about_category_title = 'Ingresar el nombre de la categoría.'; $lang->about_expand = 'Si seleccionas esta opción, siempre estará expandido.'; -$lang->about_category_group_srls = '선택한 그룹만 현재 카테고리를 지정할 수 있도록 합니다'; -$lang->about_category_color = '분류 폰트색깔을 지정합니다.'; $lang->cmd_search_next = 'Buscar siguiente'; $lang->cmd_temp_save = 'Guardar Temporales'; $lang->cmd_toggle_checked_document = 'Invertir los elementos seleccionados'; @@ -40,5 +37,4 @@ $lang->search_target_list['uploaded_count'] = 'Número de archivos adjuntos (sob $lang->search_target_list['regdate'] = 'Día del registro'; $lang->search_target_list['last_update'] = 'Día de la última actualización'; $lang->search_target_list['ipaddress'] = 'Dirección IP'; -$lang->about_use_history = '히스토리 기능의 사용여부를 지정합니다. 히스토리 기능을 사용할 경우 문서 수정시 이전 리비전을 기록하고 복원할 수 있습니다.'; $lang->trash_nick_name = 'Person who deleted'; diff --git a/modules/document/lang/fr.php b/modules/document/lang/fr.php index ff4ced221..2fa9e8831 100644 --- a/modules/document/lang/fr.php +++ b/modules/document/lang/fr.php @@ -6,7 +6,6 @@ $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->expand = 'Etendre'; @@ -44,5 +43,4 @@ $lang->search_target_list['uploaded_count'] = 'Fichiers Attachés (surplus)'; $lang->search_target_list['regdate'] = 'Enrégistré'; $lang->search_target_list['last_update'] = 'La Dernière Mise à Jour'; $lang->search_target_list['ipaddress'] = 'Adresse IP'; -$lang->about_use_history = '히스토리 기능의 사용여부를 지정합니다. 히스토리 기능을 사용할 경우 문서 수정시 이전 리비전을 기록하고 복원할 수 있습니다.'; $lang->trash_nick_name = 'Person who deleted'; diff --git a/modules/document/lang/ru.php b/modules/document/lang/ru.php index 22d0bc01d..6421d2f0e 100644 --- a/modules/document/lang/ru.php +++ b/modules/document/lang/ru.php @@ -16,7 +16,6 @@ $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 = 'Перевернуть выбранные объекты'; diff --git a/modules/editor/lang/en.php b/modules/editor/lang/en.php index 75e711140..cbdbe5a99 100644 --- a/modules/editor/lang/en.php +++ b/modules/editor/lang/en.php @@ -1,5 +1,4 @@ editor_now = '현재 설정 상태'; $lang->editor_component = 'Editor Component'; $lang->main_editor = 'Main editor'; $lang->comment_editor = 'Comment editor'; diff --git a/modules/editor/lang/es.php b/modules/editor/lang/es.php index 12d6c149d..02e2166a3 100644 --- a/modules/editor/lang/es.php +++ b/modules/editor/lang/es.php @@ -10,7 +10,6 @@ $lang->component_description = 'Descripción'; $lang->component_extra_vars = 'Varibles Extras'; $lang->component_grant = 'Ajuste de las atribuciones'; $lang->about_component = 'Presentación del componente'; -$lang->about_component_mid = '에디터 컴포넌트가 사용될 대상을 지정할 수 있습니다.(모두 해제시 모든 대상에서 사용 가능합니다)'; $lang->msg_component_is_not_founded = 'No se puede encontrar el componente del editor %s'; $lang->msg_component_is_inserted = 'El componente seleccionado ya esta insertado'; $lang->msg_component_is_first_order = 'El componente seleccionado se localiza en la primera posición'; @@ -28,8 +27,6 @@ $lang->enable_html_grant = 'La autorización de uso de HTML'; $lang->enable_autosave = 'Utilice función de guardado automático,'; $lang->height_resizable = 'Altura cambiar de tamaño'; $lang->editor_height = 'Altura de Editor'; -$lang->about_content_font = '콤마(,)로 여러 폰트를 지정할 수 있습니다.'; -$lang->about_content_font_size = '12px, 1em등 단위까지 포함해서 입력해주세요.'; $lang->about_enable_autosave = 'Usted puede permitir que la función de guardado automático, en tanto que función de la redacción de artículos'; $lang->edit['fontname'] = 'Fuente'; $lang->edit['fontsize'] = 'Tamaño'; @@ -68,17 +65,4 @@ $lang->edit['icon_align_left'] = 'Margen izquierdo'; $lang->edit['icon_align_middle'] = 'Margen central'; $lang->edit['icon_align_right'] = 'Margen derecho'; $lang->edit['lineheight'] = 'Line Height'; -$lang->edit['target_blank'] = '새창으로'; -$lang->edit['add_one_row'] = '1행추가'; -$lang->edit['del_one_row'] = '1행삭제'; -$lang->edit['add_one_col'] = '1열추가'; -$lang->edit['del_one_col'] = '1열삭제'; -$lang->edit['search_color'] = '색상찾기'; -$lang->edit['circle_bracket'] = '원,괄호'; -$lang->edit['replace_all'] = '모두바꾸기'; -$lang->edit['search_words'] = '찾을단어'; -$lang->edit['replace_words'] = '바꿀단어'; -$lang->edit['next_search_words'] = '다음찾기'; -$lang->edit['materials'] = '글감보관함'; -$lang->edit['temporary_savings'] = '임시저장목록'; $lang->about_dblclick_in_editor = 'Para la configuracion más detallada debera hacer dobleclick sobre el texto, imagen, fondo, etc.'; diff --git a/modules/editor/lang/fr.php b/modules/editor/lang/fr.php index 987139e9f..59f26ea7f 100644 --- a/modules/editor/lang/fr.php +++ b/modules/editor/lang/fr.php @@ -27,8 +27,6 @@ $lang->enable_html_grant = 'Permission d\'utiliser HTML'; $lang->enable_autosave = 'Valider à conserver automatiquement'; $lang->height_resizable = 'Permettre de remettre l\'hauteur'; $lang->editor_height = 'Hauteur de l\'Editeur'; -$lang->about_content_font = '콤마(,)로 여러 폰트를 지정할 수 있습니다.'; -$lang->about_content_font_size = '12px, 1em등 단위까지 포함해서 입력해주세요.'; $lang->about_enable_autosave = 'Vous pouvez valider la fonction à Conserver Automatiquement pendant écrire des articles.'; $lang->edit['fontname'] = 'Police de caractères'; $lang->edit['fontsize'] = 'Mesure'; @@ -69,17 +67,4 @@ $lang->edit['icon_align_left'] = 'Placer à gauche du texte'; $lang->edit['icon_align_middle'] = 'Placer au centre'; $lang->edit['icon_align_right'] = 'Placer à droite du texte'; $lang->edit['lineheight'] = 'Line Height'; -$lang->edit['target_blank'] = '새창으로'; -$lang->edit['add_one_row'] = '1행추가'; -$lang->edit['del_one_row'] = '1행삭제'; -$lang->edit['add_one_col'] = '1열추가'; -$lang->edit['del_one_col'] = '1열삭제'; -$lang->edit['search_color'] = '색상찾기'; -$lang->edit['circle_bracket'] = '원,괄호'; -$lang->edit['replace_all'] = '모두바꾸기'; -$lang->edit['search_words'] = '찾을단어'; -$lang->edit['replace_words'] = '바꿀단어'; -$lang->edit['next_search_words'] = '다음찾기'; -$lang->edit['materials'] = '글감보관함'; -$lang->edit['temporary_savings'] = '임시저장목록'; $lang->about_dblclick_in_editor = 'Vous pouvez configurer en détail des composants par double-clic sur un arrière-plan, un texte, une image ou une citation'; diff --git a/modules/editor/lang/ru.php b/modules/editor/lang/ru.php index 28dd7e72e..43a17ecc1 100644 --- a/modules/editor/lang/ru.php +++ b/modules/editor/lang/ru.php @@ -1,16 +1,4 @@ editor_now = '현재 설정 상태'; -$lang->editor_component = 'Editor Component'; -$lang->main_editor = 'Main editor'; -$lang->comment_editor = 'Comment editor'; -$lang->editor_option = 'Editor Option'; -$lang->guide_choose_main_editor = 'Main editor.'; -$lang->guide_set_height_main_editor = 'Height of the main editor.'; -$lang->guide_choose_comment_editor = 'Comment editor.'; -$lang->guide_set_height_comment_editor = 'Height of the comment editor.'; -$lang->guide_choose_text_formatting = 'Text formatting.'; -$lang->guide_choose_font_body = 'Font body.'; -$lang->guide_choose_font_size_body = 'Font size body.'; $lang->editor = 'WYSIWYG-Редактор'; $lang->component_name = 'Компонент'; $lang->component_version = 'Версия'; diff --git a/modules/editor/lang/tr.php b/modules/editor/lang/tr.php index 12e1eadaf..9cafab0fd 100644 --- a/modules/editor/lang/tr.php +++ b/modules/editor/lang/tr.php @@ -1,16 +1,4 @@ editor_now = '현재 설정 상태'; -$lang->editor_component = 'Editor Component'; -$lang->main_editor = 'Main editor'; -$lang->comment_editor = 'Comment editor'; -$lang->editor_option = 'Editor Option'; -$lang->guide_choose_main_editor = 'Main editor.'; -$lang->guide_set_height_main_editor = 'Height of the main editor.'; -$lang->guide_choose_comment_editor = 'Comment editor.'; -$lang->guide_set_height_comment_editor = 'Height of the comment editor.'; -$lang->guide_choose_text_formatting = 'Text formatting.'; -$lang->guide_choose_font_body = 'Font body.'; -$lang->guide_choose_font_size_body = 'Font size body.'; $lang->component_name = 'Bileşen'; $lang->component_version = 'Sürüm'; $lang->component_author = 'Geliştirici'; diff --git a/modules/editor/lang/vi.php b/modules/editor/lang/vi.php index 7b3c69df8..468c08e81 100644 --- a/modules/editor/lang/vi.php +++ b/modules/editor/lang/vi.php @@ -1,16 +1,4 @@ editor_now = '현재 설정 상태'; -$lang->editor_component = 'Editor Component'; -$lang->main_editor = 'Main editor'; -$lang->comment_editor = 'Comment editor'; -$lang->editor_option = 'Editor Option'; -$lang->guide_choose_main_editor = 'Main editor.'; -$lang->guide_set_height_main_editor = 'Height of the main editor.'; -$lang->guide_choose_comment_editor = 'Comment editor.'; -$lang->guide_set_height_comment_editor = 'Height of the comment editor.'; -$lang->guide_choose_text_formatting = 'Text formatting.'; -$lang->guide_choose_font_body = 'Font body.'; -$lang->guide_choose_font_size_body = 'Font size body.'; $lang->editor = 'WYSIWYG toàn diện'; $lang->component_name = 'Thành phần'; $lang->component_version = 'Phiên bản'; diff --git a/modules/editor/lang/zh-CN.php b/modules/editor/lang/zh-CN.php index 4ff949d03..b8b9d5393 100644 --- a/modules/editor/lang/zh-CN.php +++ b/modules/editor/lang/zh-CN.php @@ -1,16 +1,4 @@ editor_now = '현재 설정 상태'; -$lang->editor_component = 'Editor Component'; -$lang->main_editor = 'Main editor'; -$lang->comment_editor = 'Comment editor'; -$lang->editor_option = 'Editor Option'; -$lang->guide_choose_main_editor = 'Main editor.'; -$lang->guide_set_height_main_editor = 'Height of the main editor.'; -$lang->guide_choose_comment_editor = 'Comment editor.'; -$lang->guide_set_height_comment_editor = 'Height of the comment editor.'; -$lang->guide_choose_text_formatting = 'Text formatting.'; -$lang->guide_choose_font_body = 'Font body.'; -$lang->guide_choose_font_size_body = 'Font size body.'; $lang->editor = '网页编辑器'; $lang->component_name = '组件'; $lang->component_version = '版本'; diff --git a/modules/editor/lang/zh-TW.php b/modules/editor/lang/zh-TW.php index d9db8a058..f4f3f03a8 100644 --- a/modules/editor/lang/zh-TW.php +++ b/modules/editor/lang/zh-TW.php @@ -1,16 +1,4 @@ editor_now = '현재 설정 상태'; -$lang->editor_component = 'Editor Component'; -$lang->main_editor = 'Main editor'; -$lang->comment_editor = 'Comment editor'; -$lang->editor_option = 'Editor Option'; -$lang->guide_choose_main_editor = 'Main editor.'; -$lang->guide_set_height_main_editor = 'Height of the main editor.'; -$lang->guide_choose_comment_editor = 'Comment editor.'; -$lang->guide_set_height_comment_editor = 'Height of the comment editor.'; -$lang->guide_choose_text_formatting = 'Text formatting.'; -$lang->guide_choose_font_body = 'Font body.'; -$lang->guide_choose_font_size_body = 'Font size body.'; $lang->editor = '網頁編輯器'; $lang->component_name = '組件'; $lang->component_version = '版本'; diff --git a/modules/file/lang/es.php b/modules/file/lang/es.php index ab7d83d72..1b3286f9b 100644 --- a/modules/file/lang/es.php +++ b/modules/file/lang/es.php @@ -28,8 +28,6 @@ $lang->msg_exceeds_limit_size = 'Ha excedido el límite del tamaño total de los $lang->file_search_target_list['filename'] = 'Nombre del archivo'; $lang->file_search_target_list['filesize_more'] = 'Tamaño del archivo(Byte, sobre)'; $lang->file_search_target_list['filesize_mega_more'] = 'Tamaño del archivo(Mb, o mb)'; -$lang->file_search_target_list['filesize_less'] = '파일크기(byte, 이하)'; -$lang->file_search_target_list['filesize_mega_less'] = '파일크기(Mb, 이하)'; $lang->file_search_target_list['download_count'] = 'Descargados(Sobre)'; $lang->file_search_target_list['user_id'] = 'ID'; $lang->file_search_target_list['user_name'] = 'Nombre'; diff --git a/modules/file/lang/fr.php b/modules/file/lang/fr.php index 0ba07d70f..c0629cd88 100644 --- a/modules/file/lang/fr.php +++ b/modules/file/lang/fr.php @@ -7,13 +7,10 @@ $lang->status = 'Statut'; $lang->is_valid = 'Valide'; $lang->is_stand_by = 'Attente'; $lang->file_list = 'Liste des Annexes'; -$lang->allow_outlink_site = '파일 외부 허용 사이트'; $lang->allowed_filesize = 'Mesure du Fichier Maximum'; $lang->allowed_attach_size = 'Somme des Annexes Maximum'; $lang->allowed_filetypes = 'Extensions consentis seulement peuvent etre attaches.'; $lang->enable_download_group = 'Groupe permis de telecharger'; -$lang->about_allow_outlink = '리퍼러에 따라 파일 외부 링크를 차단할 수 있습니다.(*.wmv, *.mp3등 미디어 파일 제외)'; -$lang->about_allow_outlink_site = '파일 외부 링크 설정에 관계 없이 허용하는 사이트 주소입니다. 여러개 입력시에 줄을 바꿔서 구분해주세요. ex)https://www.rhymix.org/'; $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 = 'Pour consentir une extension, utilisez "*.[extention]". Pour consentir plusieurs extensions, utilisez ";" entre chaque extension. ex) *.* ou *.jpg;*.gif;'; @@ -26,9 +23,6 @@ $lang->msg_checked_file_is_deleted = '%d Annexe(s) est(sont) supprime(s)'; $lang->msg_exceeds_limit_size = 'La mesure de l\'(des) Annexe(s) est plus grande que celle consentie.'; $lang->file_search_target_list['filename'] = 'Nom de Fichier'; $lang->file_search_target_list['filesize_more'] = 'Mesure de Fichier(octet, surplus)'; -$lang->file_search_target_list['filesize_mega_more'] = '파일크기(Mb, 이상)'; -$lang->file_search_target_list['filesize_less'] = '파일크기(byte, 이하)'; -$lang->file_search_target_list['filesize_mega_less'] = '파일크기(Mb, 이하)'; $lang->file_search_target_list['download_count'] = 'Telecharges(surplus)'; $lang->file_search_target_list['regdate'] = 'Enrgistre'; $lang->file_search_target_list['ipaddress'] = 'Adresse IP'; diff --git a/modules/importer/lang/es.php b/modules/importer/lang/es.php index cc8b0cf41..a7a65d535 100644 --- a/modules/importer/lang/es.php +++ b/modules/importer/lang/es.php @@ -1,7 +1,6 @@ cmd_sync_member = 'Sincronizar'; $lang->cmd_continue = 'Continuar'; -$lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; $lang->importer = 'Transferir los datos de Rhymix'; $lang->source_type = 'Objetivo a transferir'; $lang->type_member = 'Información del usuario'; @@ -21,7 +20,6 @@ $lang->import_step_desc['13'] = 'Seleccione la categoría para transferir los da $lang->import_step_desc['2'] = 'Ingrese la ubicación del archivo XML para transfer los datos. Puede ser ruta absoluto o relativo.'; $lang->import_step_desc['3'] = 'La información del usuario y del documento podría ser incorrecto luego de la transferencia. Si ese es el caso, sincroniza para la corrección basado a la ID del usuario.'; -$lang->import_step_desc['99'] = '데이터를 이전중입니다'; $lang->msg_sync_member = 'Al presionar el botón sincronizar comenzará a sincronizar la información del usuario y la del artículo.'; $lang->msg_no_xml_file = 'No se puede encontrar el archivo XML. Verifique su ruta.'; $lang->msg_invalid_xml_file = 'Tipo de archivo XML inválido.'; diff --git a/modules/install/lang/es.php b/modules/install/lang/es.php index 294d415dd..ac0ed2a5f 100644 --- a/modules/install/lang/es.php +++ b/modules/install/lang/es.php @@ -68,4 +68,3 @@ $lang->msg_ftp_invalid_auth_info = 'Los datos de login para el FTP no son correc $lang->msg_ftp_mkdir_fail = 'Ha fallado el comando de FTP para la creación de directorio. Verifique la configuración del servicio FTP en el servidor'; $lang->msg_ftp_chmod_fail = 'Ha fallado el comando de FTP para la modificación de atributos de directorio. Verifique la configuración del servicio FTP en el servidor.'; $lang->msg_ftp_connect_success = 'conexión con éxito al FTP'; -$lang->msg_ftp_installed_ftp_realpath = '설치된 Rhymix의 FTP 절대경로'; diff --git a/modules/install/lang/fr.php b/modules/install/lang/fr.php index 4d5a64573..dbc97e419 100644 --- a/modules/install/lang/fr.php +++ b/modules/install/lang/fr.php @@ -59,12 +59,4 @@ $lang->msg_dbconnect_failed = 'Erreur a lieu en essayant connecter à la Base de $lang->msg_table_is_exists = 'La Table est déjà créée dans la Base de Données. Le fichier de Configuration est recréé.'; $lang->msg_install_completed = 'Installation a complété. Merci pour choisir Rhymix.'; $lang->msg_install_failed = 'Une erreur a lieu en créant le fichier d\'installation.'; -$lang->ftp_form_title = 'FTP 정보 입력'; $lang->ftp = 'FTP'; -$lang->msg_safe_mode_ftp_needed = 'PHP의 safe_mode가 On일 경우 FTP 정보를 꼭 입력해야 Rhymix의 설치 및 사용이 가능합니다'; -$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->msg_ftp_installed_ftp_realpath = '설치된 Rhymix의 FTP 절대경로'; diff --git a/modules/install/lang/ru.php b/modules/install/lang/ru.php index 041ee560d..22cc1d90c 100644 --- a/modules/install/lang/ru.php +++ b/modules/install/lang/ru.php @@ -61,5 +61,3 @@ $lang->msg_install_completed = 'Установка завершена. Спас $lang->msg_install_failed = 'Произошла ошибка при создании файла конфигурации.'; $lang->ftp_form_title = 'Введите данные FTP'; $lang->ftp = 'FTP'; -$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_chmod_fail = 'Chmod failed. Please check the permission and configuration of FTP server.'; diff --git a/modules/layout/lang/de.php b/modules/layout/lang/de.php index 11ebb2963..eaa712107 100644 --- a/modules/layout/lang/de.php +++ b/modules/layout/lang/de.php @@ -1,23 +1,3 @@ cmd_layout_edit = 'Layout bearbeiten'; $lang->about_layout = 'Layouts schmücken das Aussehen Ihrer Module. Sie können sie von Layout-Menü am oberen Rand '; -$lang->layout_manager['0'] = 'L'; -$lang->layout_manager['1'] = 'a'; -$lang->layout_manager['2'] = 'y'; -$lang->layout_manager['3'] = 'o'; -$lang->layout_manager['4'] = 'u'; -$lang->layout_manager['5'] = 't'; -$lang->layout_manager['6'] = '-'; -$lang->layout_manager['7'] = 'E'; -$lang->layout_manager['8'] = 'i'; -$lang->layout_manager['9'] = 'n'; -$lang->layout_manager['10'] = 's'; -$lang->layout_manager['11'] = 't'; -$lang->layout_manager['12'] = 'e'; -$lang->layout_manager['13'] = 'l'; -$lang->layout_manager['14'] = 'l'; -$lang->layout_manager['15'] = 'u'; -$lang->layout_manager['16'] = 'n'; -$lang->layout_manager['17'] = 'g'; -$lang->layout_manager['18'] = 'e'; -$lang->layout_manager['19'] = 'n'; diff --git a/modules/layout/lang/es.php b/modules/layout/lang/es.php index 9247e495d..2740a312c 100644 --- a/modules/layout/lang/es.php +++ b/modules/layout/lang/es.php @@ -16,16 +16,3 @@ $lang->about_title = 'Ingresar un nombre fácil de distinguir cuando conecta al $lang->about_not_apply_menu = 'Al seleccionar esta opción, cambia todos los diseños conectados.'; $lang->about_layout = 'Módulo del diseño ayuda a usted para crear el diseño de la página web fácilmente. Por usar la configuración del diseño y el menú de conección, completa con varios módulos la forma de la página web que a ser mostrados Esos diseños que no pueden ser modificados ni eliminados son propios de blog y de otros módulos, por lo cual para la configuración de ellos debe hacerse en los modulos correspondientes.'; $lang->about_layout_code = 'El diseño sera aplicado al servicio cuando usted guarda el código del diseño luego de haber editado. Primero visualiza previamente tus códigos y luego guardalos. Referente al código de planillas de XE dirijirse aXE Pamphlet(Ingles) '; -$lang->about_layout_import = '가져오기를 할 경우 기존 수정된 레이아웃을 삭제가 됩니다. 가져오기를 하기전에 내보내기를 통해 백업을 하세요.'; -$lang->layout_manager['30'] = '가로 너비'; -$lang->layout_manager['31'] = '높이'; -$lang->about_layout_image_repository = '선택된 레이아웃에 사용될 이미지/플래시파일등을 올릴 수 있습니다. 내보내기에 같이 포함이 됩니다'; -$lang->msg_layout_image_target = 'gif, png, jpg, swf, flv파일만 가능합니다'; -$lang->layout_migration = '레이아웃 내보내기/ 들이기'; -$lang->about_layout_migration = '수정된 레이아웃을 tar 파일로 내보내거나 tar 파일로 저장된 것을 불러올 수 있습니다 -(아직은 faceOff레이아웃만 내보내기/들이기가 됩니다'; -$lang->about_faceoff['description'] = 'FaceOff Layout관리자는 웹상에서 쉽게 레이아웃을 꾸밀 수 있습니다.
아래 그림을 보고 구성요소와 기능을 이용하여 원하는 레이아웃을 만드세요'; -$lang->about_faceoff['layout'] = 'FaceOff는 위와 같은 HTML 구조로 되어 있습니다.
이 구조에서 CSS를 이용하여 형태/배열/정렬을 할 수 있고 또 Style을 이용하여 꾸밀 수 있습니다.
위젯 추가는 Extension(e1, e2)와 Neck, Knee에서 가능합니다.
이 외 Body, Layout, Header, Body, Footer는 Style을 꾸밀 수 있고 Content는 내용이 출력됩니다.'; -$lang->about_faceoff['setting'] = '좌측 상단의 메뉴에 대해 설명 드립니다.
  • 저장 : 설정된 내용을 저장합니다.
  • 취소 : 설정한 내용을 저장하지 않고 돌아갑니다.
  • 초기화 : 아무 설정도 되어 있지 않은 백지 상태로 돌립니다
  • 형태 : 고정/ 가변/ 고정+가변(내용)의 형태를 지정합니다.
  • 배열 : Extension 2개와 Content를 배열합니다.
  • 정렬 : 레이아웃의 위치를 정렬시킬 수 있습니다.
'; -$lang->about_faceoff['hotkey'] = '마우스로 각 영역을 선택하면서 Hot Key를 이용하면 더 쉽게 꾸밀 수 있습니다.
  • tab 키 : 위젯이 선택되어 있지 않으면 Header, Body, Footer 순으로 선택됩니다. 위젯이 선택되어 있다면 다음 위젯으로 선택이 이동됩니다.
  • Shift + tab키 : tab키와 반대 역할을 합니다.
  • Esc : 아무것도 선택되어 있지 않을때 Esc를 누르면 Neck, Extension(e1,e2),Knee 순서대로 선택이 되며 위젯이 선택되어 있다면 선택된 위젯을 감싸는 영역이 선택됩니다.
  • 방향키 : 위젯이 선택되어 있을때 방향키를 이용하여 위젯을 다른 영역으로 이동시킬 수 있습니다.
'; -$lang->about_apply_mobile_view = 'All connected module use mobile view to display when accessing with mobile device.'; diff --git a/modules/layout/lang/fr.php b/modules/layout/lang/fr.php index 88c0fd147..2ec0bedde 100644 --- a/modules/layout/lang/fr.php +++ b/modules/layout/lang/fr.php @@ -16,16 +16,3 @@ $lang->about_title = 'Entrez le titre pour distinguer facilement quand vous le l $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->about_layout_import = '가져오기를 할 경우 기존 수정된 레이아웃을 삭제가 됩니다. 가져오기를 하기전에 내보내기를 통해 백업을 하세요.'; -$lang->layout_manager['30'] = '가로 너비'; -$lang->layout_manager['31'] = '높이'; -$lang->about_layout_image_repository = '선택된 레이아웃에 사용될 이미지/플래시파일등을 올릴 수 있습니다. 내보내기에 같이 포함이 됩니다'; -$lang->msg_layout_image_target = 'gif, png, jpg, swf, flv파일만 가능합니다'; -$lang->layout_migration = '레이아웃 내보내기/ 들이기'; -$lang->about_layout_migration = '수정된 레이아웃을 tar 파일로 내보내거나 tar 파일로 저장된 것을 불러올 수 있습니다 -(아직은 faceOff레이아웃만 내보내기/들이기가 됩니다'; -$lang->about_faceoff['description'] = 'FaceOff Layout관리자는 웹상에서 쉽게 레이아웃을 꾸밀 수 있습니다.
아래 그림을 보고 구성요소와 기능을 이용하여 원하는 레이아웃을 만드세요'; -$lang->about_faceoff['layout'] = 'FaceOff는 위와 같은 HTML 구조로 되어 있습니다.
이 구조에서 CSS를 이용하여 형태/배열/정렬을 할 수 있고 또 Style을 이용하여 꾸밀 수 있습니다.
위젯 추가는 Extension(e1, e2)와 Neck, Knee에서 가능합니다.
이 외 Body, Layout, Header, Body, Footer는 Style을 꾸밀 수 있고 Content는 내용이 출력됩니다.'; -$lang->about_faceoff['setting'] = '좌측 상단의 메뉴에 대해 설명 드립니다.
  • 저장 : 설정된 내용을 저장합니다.
  • 취소 : 설정한 내용을 저장하지 않고 돌아갑니다.
  • 초기화 : 아무 설정도 되어 있지 않은 백지 상태로 돌립니다
  • 형태 : 고정/ 가변/ 고정+가변(내용)의 형태를 지정합니다.
  • 배열 : Extension 2개와 Content를 배열합니다.
  • 정렬 : 레이아웃의 위치를 정렬시킬 수 있습니다.
'; -$lang->about_faceoff['hotkey'] = '마우스로 각 영역을 선택하면서 Hot Key를 이용하면 더 쉽게 꾸밀 수 있습니다.
  • tab 키 : 위젯이 선택되어 있지 않으면 Header, Body, Footer 순으로 선택됩니다. 위젯이 선택되어 있다면 다음 위젯으로 선택이 이동됩니다.
  • Shift + tab키 : tab키와 반대 역할을 합니다.
  • Esc : 아무것도 선택되어 있지 않을때 Esc를 누르면 Neck, Extension(e1,e2),Knee 순서대로 선택이 되며 위젯이 선택되어 있다면 선택된 위젯을 감싸는 영역이 선택됩니다.
  • 방향키 : 위젯이 선택되어 있을때 방향키를 이용하여 위젯을 다른 영역으로 이동시킬 수 있습니다.
'; -$lang->about_apply_mobile_view = 'All connected module use mobile view to display when accessing with mobile device.'; diff --git a/modules/layout/lang/ru.php b/modules/layout/lang/ru.php index bfc6385f6..74aa07a09 100644 --- a/modules/layout/lang/ru.php +++ b/modules/layout/lang/ru.php @@ -16,12 +16,3 @@ $lang->about_title = 'Пожалуйста, введите название, к $lang->about_not_apply_menu = 'Все подключенные лейауты модулей будут изменены при включении это опции.'; $lang->about_layout = 'Модуль лейаутов помогает Вам создать лейаут сайта с легкостью. Используя настройки лейаута и подключение меню, полная форма сайта будет отображена множеством модулей. Теми лейаутами, которые невозможно удалить или изменить, являются лейауты блога и лейауты других модулей.'; $lang->about_layout_code = 'Применения к службе будут проиведены, когда Вы сохраните код лейаут после редактирование. Пожалуйста, сначала используйте предпросмотр кода и затем сохраните его. Вы можете обратиться к грамматике шаблонов XE с XE Template.'; -$lang->about_layout_export = 'Export currently editted layout.'; -$lang->about_layout_import = 'Original layout will be deleted when you import. Please export current layout before importing.'; -$lang->about_layout_image_repository = 'You can upload images/flash files for selected layout. They will be included in exports'; -$lang->about_layout_migration = 'You can export or import editted layout as tar file -(So far only FaceOff supports exports/imports)'; -$lang->about_faceoff['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.
'; -$lang->about_faceoff['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.
'; -$lang->about_faceoff['attribute'] = 'You can set background color/image to every area except widget, and font color(include tag).'; -$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.php b/modules/layout/lang/vi.php index 7f4d6e73f..f9a5a38d3 100644 --- a/modules/layout/lang/vi.php +++ b/modules/layout/lang/vi.php @@ -88,4 +88,3 @@ $lang->about_faceoff['layout'] = 'FaceOff có cấu trúc HTML như trên.
b $lang->about_faceoff['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.
'; $lang->about_faceoff['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.
'; $lang->about_faceoff['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->about_apply_mobile_view = 'All connected module use mobile view to display when accessing with mobile device.'; diff --git a/modules/layout/lang/zh-TW.php b/modules/layout/lang/zh-TW.php index cdec0df1d..8fb73d324 100644 --- a/modules/layout/lang/zh-TW.php +++ b/modules/layout/lang/zh-TW.php @@ -91,7 +91,6 @@ $lang->about_faceoff['attribute'] = '除了 Widget 以外的各個區域都可 $lang->mobile_layout_list = '手機版面列表'; $lang->mobile_downloaded_list = '下載手機版面'; $lang->apply_mobile_view = '使用手機面板'; -$lang->about_apply_mobile_view = 'All connected module use mobile view to display when accessing with mobile device.'; $lang->installed_layout = '已安裝版面'; $lang->instance_layout = '已安裝版面'; $lang->faceoff_export = '匯出 FaceOff 版面'; diff --git a/modules/member/lang/en.php b/modules/member/lang/en.php index e98843ecc..e21f18402 100644 --- a/modules/member/lang/en.php +++ b/modules/member/lang/en.php @@ -63,7 +63,6 @@ $lang->allow_message_type['F'] = 'Allow for Friends only'; $lang->allow_message_type['N'] = 'Reject All'; $lang->about_allow_message = 'You may allow or reject messages.'; $lang->logged_users = 'Logged on Users'; -$lang->msg_mail_authorization = '메일 인증을 사용하려면 웸마스터의 이름과 메일주소가 유효해야 합니다.'; $lang->webmaster_name = 'Webmaster Name'; $lang->webmaster_email = 'Webmaster Email'; $lang->column_id = 'The column id'; diff --git a/modules/member/lang/es.php b/modules/member/lang/es.php index 45557fec6..b8901be12 100644 --- a/modules/member/lang/es.php +++ b/modules/member/lang/es.php @@ -42,18 +42,14 @@ $lang->agreement = 'Acuerdo del registro del usuario'; $lang->accept_agreement = 'Acepto'; $lang->member_info = 'Información del Usuario'; $lang->current_password = 'Contraseña actual'; -$lang->about_allow_message = '쪽지 허용 방법 및 대상을 지정할 수 있습니다'; $lang->logged_users = 'Logged Users'; $lang->webmaster_name = 'Nombre del Webmaster'; $lang->webmaster_email = 'Correo electrónico Webmaster'; -$lang->about_keep_signed = '브라우저를 닫더라도 로그인이 계속 유지될 수 있습니다.\\n\\n로그인 유지 기능을 사용할 경우 다음 접속부터는 로그인할 필요가 없습니다.\\n\\n단, 게임방, 학교 등 공공장소에서 이용시 개인정보가 유출될 수 있으니 꼭 로그아웃을 해주세요'; $lang->about_webmaster_name = 'Por favor, webmaster de entrada el nombre que se utilizará para la autenticación de los correos u otros sitio de la administración. (Por defecto: webmaster)'; $lang->about_webmaster_email = 'Introduzca la dirección de correo electrónico webmaster.'; $lang->search_target_list['email_address'] = 'Dirección de Email'; $lang->search_target_list['regdate'] = 'Fecha del registro'; $lang->search_target_list['last_login'] = 'Fecha de su última conección'; -$lang->search_target_list['last_login_more'] = '최근로그인일시(이상)'; -$lang->search_target_list['last_login_less'] = '최근로그인일시(이하)'; $lang->search_target_list['birthday'] = 'Fecha de Nacimiento'; $lang->search_target_list['extra_vars'] = 'Variables Extra'; $lang->cmd_login = 'Conectar'; @@ -80,10 +76,7 @@ $lang->msg_cart_is_null = 'Seleciona el objetivo'; $lang->msg_checked_file_is_deleted = '%d archivos adjuntos son eliminados'; $lang->msg_find_account_info = 'Esto se solicita la información de la cuenta'; $lang->msg_find_account_comment = 'La contraseña se modificará para arriba al hacer clic en un enlace a continuación.
Por favor, después de modificar la contraseña de acceso.'; -$lang->msg_confirm_account_title = '가입 인증 메일입니다'; -$lang->msg_confirm_account_info = '가입한 계정 정보는 아래와 같습니다'; $lang->msg_auth_mail_sent = 'La autenticación de correo ha sido enviado a% s. Por favor, compruebe su correo.'; -$lang->msg_invalid_auth_key = '잘못된 계정 인증 요청입니다.
아이디/비밀번호 찾기를 다시 하거나 사이트 관리자에게 계정 정보를 문의해주세요'; $lang->msg_success_authed = 'Esto no es válido solicitud de autenticación.
Por favor, inténtelo encontrar información de la cuenta o póngase en contacto con el administrador.'; $lang->msg_new_member = 'Agregar usuario'; $lang->msg_update_member = 'Modificar información del usuario'; @@ -102,10 +95,8 @@ $lang->msg_insert_group_name = 'Por favor ingresar el nombre del grupo'; $lang->msg_check_group = 'Introduce nombre de grupo'; $lang->msg_not_uploaded_image_name = 'Imagen del nombre no puede ser registrado'; $lang->msg_not_uploaded_image_mark = 'Imagen de marca no puede ser resistrado'; -$lang->msg_not_uploaded_group_image_mark = '그룹 이미지 마크를 등록할 수가 없습니다'; $lang->msg_accept_agreement = 'Usted primero debe aceptar el acuerdo'; $lang->msg_user_denied = 'ID ingresado ha sido prohibido para su uso'; -$lang->msg_user_not_confirmed = '아직 메일 인증이 이루어지지 않았습니다. 메일을 확인해 주세요'; $lang->msg_user_limited = 'ID ingresado puede ser usado luego de %s'; $lang->msg_admin_ip_not_allowed = 'Su dirección IP no se puede iniciar la sesión como administrador.'; $lang->about_user_id = 'ID del usuario debe ser entre 3-20 letras que consiste en alfabetos+número con alfabeto como primera letra.'; @@ -129,20 +120,14 @@ $lang->about_active = 'Si selecciona "Activar" los artículos seran mostrados en $lang->about_form_description = 'Si Usted ingresa la forma de la descripción, será mostrado en el momento de registrar'; $lang->about_required = 'Si selecciona esta opción, será artículo esencial para el registro'; $lang->about_enable_join = 'Debe seleccionar esta opción para permitir el registro de los usuarios'; -$lang->about_enable_confirm = '입력된 메일 주소로 인증 메일을 보내 회원 가입을 확인합니다'; $lang->about_enable_find_account_question = 'Compruebe si desea permitir a los miembros a recuperar sus cuentas utilizando una pregunta y respuesta de seguridad.'; -$lang->about_enable_ssl = '서버에서 SSL지원이 될 경우 회원가입/정보수정/로그인등의 개인정보가 서버로 보내질때 SSL(https)를 이용하도록 할 수 있습니다'; $lang->about_limit_day = 'Usted puede limitar la fecha de la certificación luego de registrar'; $lang->about_limit_date = 'Usuario no podra conectarse hasta la fecha indicada'; $lang->about_redirect_url = 'Ingresar la URL que va a abrir luego de registrar los usuarios. Cuando esto esta vacío, se habrirá la página anterior a la del registro.'; $lang->about_agreement = 'Acuerdo del registro no será mostrado si esta vacío'; $lang->about_image_name = 'Permitir a los usuarios el uso de imagen del nombre en ves del nombre del usuario'; $lang->about_image_mark = 'Permitir a los usuarios el uso de imagen de marca delante de sus nombres'; -$lang->about_group_image_mark = '회원의 이름앞에 그룹 마크를 달 수 있습니다'; $lang->about_profile_image = 'Permitir a los usuarios a utilizar nombre de la imagen en lugar de texto nombre'; $lang->about_accept_agreement = 'Yo he leído todo el acuerdo y acepto'; $lang->about_member_default = 'Al registrar se configura como grupo predefinido'; $lang->about_find_member_account = 'Su información de la cuenta será observado por dirección de correo electrónico registrada. Introduce la dirección de correo electrónico que usted tiene de entrada en el registro, y pulse "Buscar" Información de la cuenta ".
'; -$lang->about_ssl_port = 'Please input if you are using different SSL port with default one'; -$lang->about_resend_auth_mail = 'You can request for authentication mail if you have failed before.'; -$lang->no_article = 'There exists no article'; diff --git a/modules/member/lang/fr.php b/modules/member/lang/fr.php index d3674d841..3f0dba7b0 100644 --- a/modules/member/lang/fr.php +++ b/modules/member/lang/fr.php @@ -46,7 +46,6 @@ $lang->agreement = 'Accord de l\'Inscription comme Membre'; $lang->accept_agreement = 'D\'accord'; $lang->member_info = 'Information de Membre'; $lang->current_password = 'Mot de Passe courant'; -$lang->about_allow_message = '쪽지 허용 방법 및 대상을 지정할 수 있습니다'; $lang->logged_users = 'Logged Users'; $lang->webmaster_name = 'Nom de Webmestre'; $lang->webmaster_email = 'Mél de Webmestre'; @@ -57,8 +56,6 @@ $lang->about_webmaster_email = 'Entrez l\'adresse du mél de webmestre, S.V.P.'; $lang->search_target_list['email_address'] = 'Mél'; $lang->search_target_list['regdate'] = 'Jour d\'Inscription'; $lang->search_target_list['last_login'] = 'Jour de la connexion dernière'; -$lang->search_target_list['last_login_more'] = '최근로그인일시(이상)'; -$lang->search_target_list['last_login_less'] = '최근로그인일시(이하)'; $lang->search_target_list['birthday'] = 'Anniversaire'; $lang->search_target_list['extra_vars'] = 'Variables additionnels '; $lang->cmd_login = 'Connexion'; @@ -115,7 +112,6 @@ $lang->msg_check_group = 'Choisissez le groupe'; $lang->msg_not_uploaded_profile_image = 'L\'image de Profil n\'a pas pu être enrégistré'; $lang->msg_not_uploaded_image_name = 'Le nom d\'image n\'a pas pu être enrégistré'; $lang->msg_not_uploaded_image_mark = 'La marque en image n\'a pas pu être enrégistrée'; -$lang->msg_not_uploaded_group_image_mark = '그룹 이미지 마크를 등록할 수가 없습니다'; $lang->msg_accept_agreement = 'Vous devez agréer l\'accord'; $lang->msg_user_denied = 'Le compte que vous avez entré est suspendu'; $lang->msg_user_not_confirmed = 'Vous n\'avez pas encore authentifié. Verifiez votre mél, S.V.P.'; @@ -153,7 +149,6 @@ $lang->about_redirect_url = 'Entrez URL où l\'utilisateur irra après l\'inscri $lang->about_agreement = 'L\'Accord d\'Inscription comme Membre sera exposé seulement quand il n\'est pas vide.'; $lang->about_image_name = 'Permettre aux utilisateurs d\'utiliser une image pour présenter leurs noms au lieu des lettres'; $lang->about_image_mark = 'Permettre aux utilisateurs d\'utiliser une marque devent leurs noms'; -$lang->about_group_image_mark = '회원의 이름앞에 그룹 마크를 달 수 있습니다'; $lang->about_profile_image = 'Permettre aux utilisateurs d\'utiliser une image de profil'; $lang->about_accept_agreement = 'J\'ai lu l\'Accord et je suis d\'accord.'; $lang->about_member_default = 'On sera par défaut dans ce groupe après l\'inscription'; diff --git a/modules/member/lang/ja.php b/modules/member/lang/ja.php index 2338a3d7f..95a0165b8 100644 --- a/modules/member/lang/ja.php +++ b/modules/member/lang/ja.php @@ -190,7 +190,6 @@ $lang->about_column_name = 'テンプレートで使用できる英文字の名 $lang->about_column_title = '登録または情報修正・閲覧時に表示されるタイトルです。'; $lang->about_default_value = 'デフォルトで入力される値を指定することができます。'; $lang->about_active = '有効項目にチェックを入れないと加入時に正常に表示されません。'; -$lang->about_emailhost_check = 'Empty value will allow almost all email account providers.
You can set new member\'s e-mail address providers. You can allow or prohibit some e-mail hosts(eg.: naver.com, gmail.com).'; $lang->about_form_description = '説明欄に入力すると登録時に表示されます。'; $lang->about_required = 'チェックを入れると会員登録時に必須入力項目として設定されます。'; $lang->about_enable_join = 'チェックを入れないとユーザーが会員に登録できません。'; @@ -260,7 +259,6 @@ $lang->cmd_input_extend_form = '会員拡張項目入力'; $lang->about_multi_type = '多重または単一項目の選択値を入力してください。(改行で区別)'; $lang->msg_delete_extend_form = '選択した項目を削除します。'; $lang->set_manage_id = '改行で区別'; -$lang->count_manage_email_host = 'There are %s %s e-mail address providers below.'; $lang->count_manage_id = '%s個の禁止IDがあります。'; $lang->count_manage_nick_name = '%s個の禁止ニックネームがあります。'; $lang->user_list = '会員リスト'; @@ -281,7 +279,6 @@ $lang->multi_line_input = '複数の項目は、改行して入力してくだ $lang->add_extend_form = 'ユーザー定義項目追加'; $lang->msg_null_prohibited_id = '追加する禁止IDを入力してください。'; $lang->msg_null_prohibited_nick_name = '追加するニックネームを入力してください。'; -$lang->msg_null_managed_emailhost = 'Please enter email address providers to manage. (eg.: gmail.com)'; $lang->identifier = 'ログインアカウント'; $lang->about_identifier = 'ログインに使用するアカウントを選択してください。'; $lang->about_public_item = '本人以外に他の会員にも露出される情報なのか選択します。'; diff --git a/modules/member/lang/ru.php b/modules/member/lang/ru.php index 0b1497fbf..b9df8e47a 100644 --- a/modules/member/lang/ru.php +++ b/modules/member/lang/ru.php @@ -48,7 +48,6 @@ $lang->allow_message = 'Сообщения разрешены'; $lang->allow_message_type['Y'] = 'Разрешено всем'; $lang->allow_message_type['F'] = 'Разрешено только зарегистрированным друзьям'; $lang->allow_message_type['N'] = 'Запрещено всем'; -$lang->about_allow_message = '쪽지 허용 방법 및 대상을 지정할 수 있습니다'; $lang->logged_users = 'Logged Users'; $lang->webmaster_name = 'Имя веб-мастера'; $lang->webmaster_email = 'Email веб-мастера'; diff --git a/modules/member/lang/zh-CN.php b/modules/member/lang/zh-CN.php index cdc5fefd5..f9cf9e4b2 100644 --- a/modules/member/lang/zh-CN.php +++ b/modules/member/lang/zh-CN.php @@ -12,8 +12,6 @@ $lang->remember_user_id = '保存ID'; $lang->already_logged = '您已经登录!'; $lang->denied_user_id = '被禁止的用户名。'; $lang->denied_nick_name = '被禁止的昵称。'; -$lang->managed_email_host['allowed'] = 'Only %s e-mail accounts are allowed. (%s)'; -$lang->managed_email_host['prohibited'] = 'E-mail accounts at %s are not allowed. (%s)'; $lang->null_user_id = '请输入用户名。'; $lang->null_password = '请输入密码。'; $lang->invalid_authorization = '还没有认证!'; @@ -174,7 +172,6 @@ $lang->about_column_name = '请输入在模板中可以使用的英文名称。 $lang->about_column_title = '注册或修改/查看信息时要显示的标题。'; $lang->about_default_value = '可以设置缺省值。'; $lang->about_active = '必须选择此项后才可以正常启用。'; -$lang->about_emailhost_check = 'Empty value will allow almost all email account providers.
You can set new member\'s e-mail address providers. You can allow or prohibit some e-mail hosts(eg.: naver.com, gmail.com).'; $lang->about_form_description = '说明栏里输入的内容,注册时将会显示。'; $lang->about_required = '注册时成为必填项目。'; $lang->about_enable_join = '选择此项后用户才可以注册。'; @@ -237,7 +234,6 @@ $lang->cmd_input_extend_form = '使用者自定'; $lang->about_multi_type = '请输入单个或多个项目值。(用换行区分)'; $lang->msg_delete_extend_form = '删除所选项目'; $lang->set_manage_id = '用换行区分'; -$lang->count_manage_email_host = 'There are %s %s e-mail address providers below.'; $lang->count_manage_id = '已有 %s个禁止账号'; $lang->count_manage_nick_name = '已有 %s个禁止昵称'; $lang->user_list = '会员列表'; @@ -258,7 +254,6 @@ $lang->multi_line_input = '多各项请换行'; $lang->add_extend_form = '增加自定义项目'; $lang->msg_null_prohibited_id = '请输入禁止账号'; $lang->msg_null_prohibited_nick_name = '请输入禁止昵称'; -$lang->msg_null_managed_emailhost = 'Please enter email address providers to manage. (eg.: gmail.com)'; $lang->identifier = '登录账号'; $lang->about_identifier = '请选择账号登录方式'; $lang->about_public_item = '选择是不是除了本人别的会员也能看到'; diff --git a/modules/member/lang/zh-TW.php b/modules/member/lang/zh-TW.php index 8b168786e..3fcd0bb9c 100644 --- a/modules/member/lang/zh-TW.php +++ b/modules/member/lang/zh-TW.php @@ -10,8 +10,6 @@ $lang->keep_signed = '自動登入'; $lang->remember_user_id = '儲存帳號'; $lang->already_logged = '您已經登入!'; $lang->denied_user_id = '被禁止的帳號。'; -$lang->managed_email_host['allowed'] = 'Only %s e-mail accounts are allowed. (%s)'; -$lang->managed_email_host['prohibited'] = 'E-mail accounts at %s are not allowed. (%s)'; $lang->null_user_id = '請輸入帳號。'; $lang->null_password = '請輸入密碼。'; $lang->invalid_authorization = '還沒有認證!'; @@ -92,7 +90,6 @@ $lang->cmd_module_config = '基本設置'; $lang->cmd_member_group = '群組管理'; $lang->cmd_send_mail = '發送郵件'; $lang->cmd_manage_id = '禁止帳號'; -$lang->cmd_manage_email_host = 'E-mail provider check'; $lang->cmd_manage_form = '註冊表單管理'; $lang->cmd_view_own_document = '發表主題'; $lang->cmd_manage_member_info = '管理會員資料'; @@ -161,7 +158,6 @@ $lang->about_column_name = '請輸入在樣板中可以使用的英文名稱。( $lang->about_column_title = '註冊或修改/檢視資料時要顯示的標題。'; $lang->about_default_value = '可以設置預設值。'; $lang->about_active = '必須選擇此項後才可以正常啟用。'; -$lang->about_emailhost_check = 'Empty value will allow almost all email account providers.
You can set new member\'s e-mail address providers. You can allow or prohibit some e-mail hosts(eg.: naver.com, gmail.com).'; $lang->about_form_description = '說明欄裡輸入的內容,在註冊時會顯示。'; $lang->about_required = '註冊時成為必填項目。'; $lang->about_enable_join = '選擇此項後,用戶才可以註冊。'; @@ -206,7 +202,6 @@ $lang->msg_question_not_exists = '尚未輸入提示問答'; $lang->msg_answer_not_matches = '答案不正確'; $lang->change_password_date = '密碼更新'; $lang->about_change_password_date = '可設定密碼更新週期,將會定期通知更換密碼。 (設為零則不使用)'; -$lang->msg_kr_address = 'Search for the name of eup, myeon or dong of your address.'; $lang->msg_kr_address_etc = '請輸入住址。'; $lang->cmd_search_again = '再找一次'; $lang->msg_select_user = '請選擇一位會員進行管理。'; @@ -214,8 +209,6 @@ $lang->msg_delete_user = '刪除所選會員'; $lang->cmd_selected_user_manage = '管理所選會員'; $lang->about_change_user_group = '重新設定所選會員群組'; $lang->about_send_message = '向此會員發送通知信'; -$lang->cmd_allowed = 'Allowed'; -$lang->cmd_prohibited = 'Prohibited'; $lang->cmd_required = '必填'; $lang->cmd_optional = '選填'; $lang->cmd_image_max_width = '寬度限制'; @@ -224,7 +217,6 @@ $lang->cmd_input_extend_form = '使用者自訂'; $lang->about_multi_type = '請輸入單個或多個項目值。(換行區隔)'; $lang->msg_delete_extend_form = '刪除所選項目'; $lang->set_manage_id = '換行區隔'; -$lang->count_manage_email_host = 'There are %s %s e-mail address providers below.'; $lang->count_manage_id = '已有 %s 個禁止帳號'; $lang->user_list = '會員列表'; $lang->cmd_show_all_member = '所有會員'; @@ -238,11 +230,9 @@ $lang->add_group_image_mark = '新增群組圖標'; $lang->link_file_box = '前往檔案盒'; $lang->msg_group_delete = '刪除所選群組'; $lang->email = '電子郵件'; -$lang->add_managed_emailhost = 'Add E-mail Host'; $lang->add_prohibited_id = '新增禁止帳號'; $lang->add_extend_form = '新增自訂項目'; $lang->msg_null_prohibited_id = '請輸入禁止帳號'; -$lang->msg_null_managed_emailhost = 'Please enter email address providers to manage. (eg.: gmail.com)'; $lang->identifier = '登入帳號'; $lang->about_identifier = '請選擇帳號登入方式。'; $lang->cmd_add_group = '新增群組'; diff --git a/modules/menu/lang/en.php b/modules/menu/lang/en.php index 764a949aa..68dde004e 100644 --- a/modules/menu/lang/en.php +++ b/modules/menu/lang/en.php @@ -88,31 +88,24 @@ $lang->site_design = 'Site design'; $lang->use_site_design = 'Use site design'; $lang->full_settings = 'Full settings'; $lang->install_other_menu_types = 'Install other menu types'; -$lang->about_new_menu_id = 'URL을 사용할 필요가 없다면 생략 가능. 메뉴 생성 후 [메뉴 수정]에서 수정 가능.'; -$lang->about_menu_id = '페이지 URL로 사용(40자 이내).'; -$lang->skip_menu_id = '생략시 임의값 사용'; $lang->url_link = 'URL link'; $lang->menu_link = 'Menu link'; -$lang->about_menu_link = '메뉴를 선택하면 자동 입력됨'; $lang->view_zoom = 'Zoom'; $lang->use_site_default_layout = 'Use site default layout'; $lang->site_default_layout_settings = 'Site default layout settings'; $lang->no_use_layout = 'No use layout'; -$lang->about_apply_layout = '클릭하면 레이아웃이 적용됩니다.'; $lang->make_copy = 'Make copy'; $lang->install_other_layouts = 'Install other layouts'; $lang->layout_html_css_settings = 'HTML/CSS settings'; $lang->layout_settings = 'Settings'; $lang->use_site_default_skin = 'Use site default skin'; $lang->site_default_skin_settings = 'Site default skin settings'; -$lang->about_apply_skin = '클릭하면 스킨이 적용됩니다.'; $lang->install_other_skins = 'Install other themes'; $lang->no_downloadable_item = 'There are no downloadable item.'; $lang->confirm_sitemap_delete = 'Do you want to remove this sitemap?'; $lang->confirm_menu_delete = 'Do you want to remove this menu item?'; $lang->confirm_delete_all_contents = 'I understand that the contents will be deleted as well.'; $lang->confirm_shortcut_delete = 'Do you want to remove this shortcut item?'; -$lang->confirm_shortcut_desc = '바로가기를 삭제해도 실제 메뉴는 지워지지 않습니다.'; $lang->confirm_delete_all_sub_items_title = 'The menu has sub-menu(s)'; $lang->confirm_delete_all_sub_items = 'Do you want to delete all the sub-menu(s)?'; $lang->confirm_delete_all_item = 'I know delete all menu of sitemap.'; @@ -122,14 +115,10 @@ $lang->shortcut_desc = 'A shortcut is a link to a URL or to another menu'; $lang->msg_target_is_sub_of_origin = 'Target menu is sub of origin menu.'; $lang->target_of_view_menu = 'Target of view menu'; $lang->input_new_layout_name = 'Input new layout name'; -$lang->skip_new_layout_name = '생략 시 임의의 값이 사용 됩니다.'; $lang->need_to_ftp_setup = 'Need to FTP setup.'; $lang->go_to_ftp_setup = 'Redirecting to FTP Setup page.'; $lang->go_to_site_design_setup = 'Redirecting to Site Design page.'; $lang->about_menu_type_in_default = 'To change the menu type, you have to delete and recreate the menu.'; -$lang->how_to_modify_menu = '생성한 메뉴는 [메뉴 수정]에서 수정 할 수 있습니다.'; -$lang->can_drag_menu = '사이트 맵에서 메뉴를 드래그 해서도 위치를 변경 할 수 있습니다.'; -$lang->good_to_duplicate_layout = '레이아웃 설정 변경 시, [복사본 생성] 버튼을 눌러 복사본을 만들어 설정을 변경 하는 것이 좋습니다.'; $lang->img_uploaded = 'Button image is uploaded.'; $lang->img_deleted = 'Button image is deleted.'; $lang->do_not_display_again = 'Do not display again.'; diff --git a/modules/module/lang/es.php b/modules/module/lang/es.php index 3dcaae354..425fb2399 100644 --- a/modules/module/lang/es.php +++ b/modules/module/lang/es.php @@ -17,10 +17,7 @@ $lang->skin_author = 'Desarrollador de tema'; $lang->skin_history = 'Historia de actualización'; $lang->module_copy = 'Copy Module'; $lang->about_domain = 'Para crear un dominio privado de la site requiere. Independiente de dominio o subdominio, y Rhymix está instalado, el camino que en su conjunto. Ej.) www.rhymix.org/rx'; -$lang->about_vid = '별도의 도메인이 아닌 https://Rhymix주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다. 첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; -$lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; $lang->msg_already_registed_domain = 'Ya es de dominio registrado. Por favor, use un dominio diferente.'; -$lang->about_header_script = 'html의 <header>와 </header> 사이에 들어가는 코드를 직접 입력할 수 있습니다. <script>, <style>, <meta> 태그등을 이용할 수 있습니다'; $lang->grant_to_site_user = 'Joined users'; $lang->cmd_add_shortcut = 'añadir acceso directo'; $lang->cmd_install = 'Instalar'; @@ -37,8 +34,6 @@ $lang->msg_grant_is_null = 'No existe el objetivo de atribución registrado.'; $lang->msg_no_checked_document = 'No existe documento seleccionado.'; $lang->msg_move_failed = 'No pudo moverse'; $lang->msg_cannot_delete_for_child = 'No puede eliminar la categoría si posee subcategoría.'; -$lang->msg_limit_mid = '모듈이름은 영문+[영문+숫자+_] 만 가능합니다.'; -$lang->msg_extra_name_exists = '이미 존재하는 사용자 정의 이름입니다. 다른 이름을 입력해주세요.'; $lang->about_browser_title = 'Esto es el valor que se mostrará en el título del navegador. También es usado en RSS/Trackback.'; $lang->about_mid = 'El nombre del módulo será usado como http://direccion/?mid=NombreMódulo. (sólo alfabeto español+[alfabeto español, números y el gión abajo(_)] son permitidos. The maximum length is 40.)'; @@ -54,9 +49,6 @@ $lang->about_search_list_count = 'Usted puede configurar el número de artículo $lang->about_page_count = 'Usted puede definir el número de página enlazada para mover páginas en un botón de la página.(Predefinido es 10)'; $lang->about_mobile_page_count = 'Usted puede definir el número de página enlazada para mover páginas en un botón de la página.(Predefinido es 5)'; $lang->about_admin_id = 'Usted puede definir el administrador de atribuciones superiores al módulo.\\n Usted puede asignar múltiples IDs.'; -$lang->about_grant_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; $lang->about_module = 'Rhymix consiste de módulos excepto la librería básica. Módulo del Manejo del Módulo muestra todos los módulos instalados y ayuda el manejo de ellos.'; $lang->about_extra_vars_default_value = 'Si múltiples valores predefinidos son requeridos, usted puede enlazar con la coma(,).'; -$lang->about_search_virtual_site = '가상 사이트(카페XE등)의 도메인을 입력한 후 검색하세요. 가상 사이트이외의 모듈은 내용을 비우고 검색하면 됩니다. (http:// 는 제외)'; -$lang->about_langcode = '언어별로 다르게 설정하고 싶으면 언어코드 찾기를 이용해주세요'; diff --git a/modules/module/lang/fr.php b/modules/module/lang/fr.php index 13e8fab09..7f845b6b7 100644 --- a/modules/module/lang/fr.php +++ b/modules/module/lang/fr.php @@ -17,8 +17,6 @@ $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->about_vid = '별도의 도메인이 아닌 https://Rhymix주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다. 첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; -$lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; $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_to_site_user = 'Joined users'; @@ -37,8 +35,6 @@ $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. (alphabet anglais + [alphabet anglais, nombres, et soulignement(_)] sont seulement permis. The maximum length is 40.)'; @@ -54,9 +50,6 @@ $lang->about_search_list_count = 'Vous pouvez configurer combien d\'articles soi $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_mobile_page_count = 'Vous pouvez configurer combien de liens pour les Pages à Bouger en bas de chaque page.(5 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_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; $lang->about_module = 'Rhymix se compose des modules sauf la bibliothèque fondamental. Le 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 = '언어별로 다르게 설정하고 싶으면 언어코드 찾기를 이용해주세요'; diff --git a/modules/module/lang/ja.php b/modules/module/lang/ja.php index 4b0d74776..72b3dd67d 100644 --- a/modules/module/lang/ja.php +++ b/modules/module/lang/ja.php @@ -47,7 +47,6 @@ $lang->grant_manager = '管理権限'; $lang->grant_to_all = 'すべてのユーザー'; $lang->grant_to_login_user = 'ログインユーザー'; $lang->grant_to_site_user = '登録ユーザー'; -$lang->grant_to_admin = 'Administrator only'; $lang->grant_to_group = '特定グループのユーザー'; $lang->cmd_add_shortcut = 'ショートカット追加'; $lang->cmd_install = 'インストール'; diff --git a/modules/module/lang/ru.php b/modules/module/lang/ru.php index 1860b73c0..a7ca150cf 100644 --- a/modules/module/lang/ru.php +++ b/modules/module/lang/ru.php @@ -23,10 +23,7 @@ $lang->filebox = 'Файлбокс'; $lang->access_type = 'Способ соединения'; $lang->access_domain = 'Domain соединения'; $lang->access_vid = 'Site ID соединение'; -$lang->about_vid = '별도의 도메인이 아닌 https://Rhymix주소/ID 로 접속할 수 있습니다. 모듈명(mid)와 중복될 수 없습니다. 첫글자는 영문으로 시작해야 하고 영문과 숫자 그리고 _ 만 사용할 수 있습니다'; -$lang->msg_already_registed_vid = '이미 등록된 사이트 ID 입니다. 게시판등의 mid와도 중복이 되지 않습니다. 다른 ID를 입력해주세요.'; $lang->header_script = 'Скрипт Header'; -$lang->about_header_script = 'html의 <header>와 </header> 사이에 들어가는 코드를 직접 입력할 수 있습니다. <script>, <style>, <meta> 태그등을 이용할 수 있습니다'; $lang->grant_to_site_user = 'Joined users'; $lang->cmd_add_shortcut = 'Добавить ярлык'; $lang->cmd_install = 'Установить'; @@ -44,8 +41,6 @@ $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/Трекбеке.'; $lang->about_mid = 'Имя модуля будет использовано как http://address/?mid=Имя_модуля. (только латиница, цифры и символ подчеркивания(_) разрешены. The maximum length is 40.)'; @@ -57,13 +52,9 @@ $lang->about_footer_text = 'Это содержимое будет показа $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_mobile_page_count = 'Вы можете установить число страниц внизу. (по умолчанию: 5)'; $lang->about_admin_id = 'Вы можете разрешить менеджеру иметь полные права доступа к этому модулю.\\nВы можете ввести несколько ID, используя '; -$lang->about_grant_deatil = '가입한 사용자는 cafeXE등 분양형 가상 사이트에 가입을 한 로그인 사용자를 의미합니다'; $lang->about_module = 'Rhymix состоит из модулей, за исключением базовой библиотеки. Управление модулем покажет все установленные модули и поможет управлять ими.'; $lang->about_extra_vars_default_value = 'Если нужно несколько значений по умолчанию, разделите их запятыми(,).'; -$lang->about_search_virtual_site = '가상 사이트(카페XE등)의 도메인을 입력한 후 검색하세요. 가상 사이트이외의 모듈은 내용을 비우고 검색하면 됩니다. (http:// 는 제외)'; -$lang->about_langcode = '언어별로 다르게 설정하고 싶으면 언어코드 찾기를 이용해주세요'; diff --git a/modules/module/lang/zh-TW.php b/modules/module/lang/zh-TW.php index cf707b710..fc519a5a7 100644 --- a/modules/module/lang/zh-TW.php +++ b/modules/module/lang/zh-TW.php @@ -38,14 +38,12 @@ $lang->about_domain = '要建立網站必須要有個專屬域名。 頂級域 $lang->about_vid = '直接以 https://程式安裝位址/ID 的方式訪問。模組名稱(mid)不能重複。 必須要以英文字母開頭,只允許使用底線、英文及數字。'; $lang->msg_already_registed_vid = '已註冊的 Site ID。不可與討論板的 mid 相同。請輸入其他 ID 名稱。'; $lang->msg_already_registed_domain = '已註冊的域名。請使用其他的網域。'; -$lang->header_script = 'Header Script'; $lang->about_header_script = '可以直接輸入,並插入到 HTML 的<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_admin = 'Administrator only'; $lang->grant_to_group = '特定群組'; $lang->cmd_add_shortcut = '新增到快速選單'; $lang->cmd_install = '安裝'; @@ -99,5 +97,3 @@ $lang->msg_cannot_delete_startmodule = '無法刪除預設模組'; $lang->attribute_name = '變數名稱'; $lang->attribute_value = '變數值'; $lang->cmd_add = '新增'; -$lang->keep_existing_value = 'Keep existing value'; -$lang->about_maintain_existing = 'If content empty, maintain existing value.'; diff --git a/modules/page/lang/ru.php b/modules/page/lang/ru.php index dc85b7651..c07f88689 100644 --- a/modules/page/lang/ru.php +++ b/modules/page/lang/ru.php @@ -3,5 +3,4 @@ $lang->page = 'Страница'; $lang->about_page = 'Это модуль блога, который создает полную страницу. Используя последние и другие виджеты, Вы можете создавать динамические страницы. Посредством компонента редактора, Вы можете также создать различные вариации страницы. URL модуля следует тем же правилам, что и другие модули: mid=имя_модуля. Если он выбран как модуль по умолчанию, то он будет главной страницей сайта.'; $lang->cmd_page_modify = 'Изменить'; $lang->page_caching_interval = 'Установить время кеширования'; -$lang->about_page_caching_interval = 'Единица измерения равна одной минуте. Это отображает временно сохраненные данные для присвоенного времени. Рекомендуется устанавливать разумное время кеширования, если множество ресурсов нуждаются в показе данных с других серверов. Значение 0 отключает кеширование.'; -$lang->about_mcontent = 'This is the page for the mobile view. If you do not write this page, the mobile view display reoragnized PC view\'s page.'; +$lang->about_page_caching_interval = 'Единица измерения равна одной минуте. Это отображает временно сохраненные данные для присвоенного времени. Рекомендуется устанавливать разумное время кеширования, если множество ресурсов нуждаются в показе данных с других серверов. Значение 0 отключает кеширование.'; \ No newline at end of file diff --git a/modules/page/lang/vi.php b/modules/page/lang/vi.php index 2937b4538..ee161a573 100644 --- a/modules/page/lang/vi.php +++ b/modules/page/lang/vi.php @@ -3,5 +3,4 @@ $lang->page = 'Trang'; $lang->about_page = 'Là Module tạo ra một trang đầy đủ. Sử dụng Widget mới nhất hoặc những Widget khác giúp bạn có thể tạo một trang động. Thông qua trình bên tập Component, bạn có thể tạo ra sự phong phú cho những trang khác nhau. Địa chỉ của nó như một Module dạng \'mid=module name\'. Nếu chọn là mặc định, nó sẽ là trang chủ của Website.'; $lang->cmd_page_modify = 'Sửa đổi'; $lang->page_caching_interval = 'Thời gian lưu trữ'; -$lang->about_page_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->about_mcontent = 'This is the page for the mobile view. If you do not write this page, the mobile view display reoragnized PC view\'s page.'; +$lang->about_page_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.'; \ No newline at end of file diff --git a/modules/point/lang/es.php b/modules/point/lang/es.php index b6a016e6a..14300bab0 100644 --- a/modules/point/lang/es.php +++ b/modules/point/lang/es.php @@ -15,12 +15,10 @@ $lang->level_point = 'Nivel del punto'; $lang->about_level_point = 'El nivel sera ajustado cuando los puntos alcancen a cada nivel de puntos o cuando disminuyen a cada nivel de puntos'; $lang->disable_download = 'Prohibida la descarga'; $lang->about_disable_download = 'Se prohibe la descarga de archivos al tener los puntos insuficientes.. (Excepto los archivos de imagen)'; -$lang->about_disable_read_document = '포인트가 없을 경우 글 열람을 금지하게 됩니다'; $lang->level_point_calc = 'Punto por punto cálculo'; $lang->expression = 'Por favor, de entrada mediante el uso de Javascript fórmula nivel variable i . Ex) Math.pow (i, 2) * 90'; $lang->cmd_exp_calc = 'Calcular'; $lang->cmd_exp_reset = 'Restablecer'; -$lang->about_cmd_point_recal = '게시글/댓글/첨부파일/회원가입 점수만 이용하여 모든 포인트 점수를 초기화 합니다.
회원 가입 점수는 초기화 후 해당 회원이 활동을 하면 부여되고 그 전에는 부여되지 않습니다.
데이터 이전등을 하여 포인트를 완전히 초기화 해야 할 경우에만 사용하세요.'; $lang->point_link_group = 'Grupo de cambio de nivel'; $lang->about_point_link_group = 'Si especifica nivel para un grupo específico, a los usuarios se les asigna en el grupo cuando se adavnce al nivel por conseguir puntos.'; $lang->about_module_point = 'Usted puede definir los puntos para cada módulo y los módulos que no tengan ningun valor usarán punto predefinido.
Todos los puntos serán restituidos al actuar en forma contraria.'; @@ -38,13 +36,10 @@ $lang->cmd_point_module_config = 'Configuración del módulo'; $lang->cmd_point_act_config = 'Configuración de actos'; $lang->cmd_point_member_list = 'Lista de puntos del usuario'; $lang->msg_cannot_download = 'No tiene puntos suficientes para descagar'; -$lang->msg_disallow_by_point = '포인트가 부족하여 글을 읽을 수 없습니다 (필요포인트 : %d, 현재포인트 : %d)'; $lang->point_recal_message = 'Ajuste de Punto. (%d / %d)'; $lang->point_recal_finished = 'Punto cálculo está acabado.'; $lang->search_target_list['nick_name'] = 'Apodo'; $lang->search_target_list['user_name'] = 'Nombre del Usuario'; $lang->search_target_list['regdate'] = 'Fecha del registro'; $lang->search_target_list['last_login'] = 'Fecha de su última conección'; -$lang->search_target_list['last_login_more'] = '최근로그인일시(이상)'; -$lang->search_target_list['last_login_less'] = '최근로그인일시(이하)'; $lang->search_target_list['extra_vars'] = 'Variables Extra'; diff --git a/modules/point/lang/fr.php b/modules/point/lang/fr.php index 7b8949337..a16315b3b 100644 --- a/modules/point/lang/fr.php +++ b/modules/point/lang/fr.php @@ -12,7 +12,6 @@ $lang->level_point = 'Point de niveau'; $lang->about_level_point = 'Le Niveau sera ajusté quand le point devient les valeurs aux Points de Niveaux ci-dessous.'; $lang->disable_download = 'Interdire de télécharger'; $lang->about_disable_download = 'Il est impossible de télécharger quand il n\'y a pas de points suffisants. (Sauf les fichier d\'images)'; -$lang->about_disable_read_document = '포인트가 없을 경우 글 열람을 금지하게 됩니다'; $lang->level_point_calc = 'Calcul des Points par Niveau'; $lang->expression = 'Entrez la formule en Javascript en utilisant la Variable de Niveau i. ex) Math.pow(i, 2) * 90'; $lang->cmd_exp_calc = 'Calculer'; @@ -38,13 +37,10 @@ $lang->cmd_point_module_config = 'Configuration du Module'; $lang->cmd_point_act_config = 'Configuration des Actions de chaque fonction'; $lang->cmd_point_member_list = 'Liste des Points des Membres'; $lang->msg_cannot_download = 'Vous n\'avez pas assez de point pour télécharger'; -$lang->msg_disallow_by_point = '포인트가 부족하여 글을 읽을 수 없습니다 (필요포인트 : %d, 현재포인트 : %d)'; $lang->point_recal_message = 'En train d\'Adjuster le Point. (%d / %d)'; $lang->point_recal_finished = 'Recalcul des Points est fini.'; $lang->search_target_list['nick_name'] = 'Surnom'; $lang->search_target_list['user_name'] = 'Nom'; $lang->search_target_list['regdate'] = 'Jour d\'Inscription'; $lang->search_target_list['last_login'] = 'Jour de la connexion dernière'; -$lang->search_target_list['last_login_more'] = '최근로그인일시(이상)'; -$lang->search_target_list['last_login_less'] = '최근로그인일시(이하)'; $lang->search_target_list['extra_vars'] = 'Variables additionnels '; diff --git a/modules/point/lang/ja.php b/modules/point/lang/ja.php index 1c0085d8e..30d247080 100644 --- a/modules/point/lang/ja.php +++ b/modules/point/lang/ja.php @@ -3,8 +3,6 @@ $lang->point = 'ポイント'; $lang->level = 'レベル'; $lang->about_point_module = 'ポイントモジュールでは、書き込み作成/コメント作成/アップロード/ダウンロードなどのユーザーの活動に対してポイントの計算を行います。'; $lang->about_act_config = '掲示板、ブログなどのモジュールごとに「書き込み作成・削除/コメント作成・削除」などのアクションがあります。掲示板/ブログ以外のモジュールにポイントシステムを連動させたい場合は、各機能のアクションの「act値」を追加します。連動は半角「,(コンマ)」で区切って追加します。'; -$lang->point_io = 'Point module On'; -$lang->about_point_io = 'Point module can be on or off. If you OFF this module, every triggers will be deleted from database and will not be called by Rhymix Core. Point record would be preserved.'; $lang->max_level = '最高レベル'; $lang->about_max_level = '最高レベルを指定することができます。最高レベルは「1000」が最大値であるため、レベルアイコンに注意が必要です。'; $lang->level_icon = 'レベルアイコン'; diff --git a/modules/point/lang/ru.php b/modules/point/lang/ru.php index 6b3844e6f..83b2aa2ae 100644 --- a/modules/point/lang/ru.php +++ b/modules/point/lang/ru.php @@ -15,9 +15,6 @@ $lang->level_point = 'Уровень поинтов'; $lang->about_level_point = 'Уровень будет изменен, когда поинты достигают каждого уровня поинтов или падают ниже его'; $lang->disable_download = 'Запретить скачивание'; $lang->about_disable_download = 'Это запретит скачивание файлов, когда не хватает достаточного кол-ва поинтов. (За исключением файлов изображений)'; -$lang->about_disable_read_document = '포인트가 없을 경우 글 열람을 금지하게 됩니다'; -$lang->about_cmd_point_recal = '게시글/댓글/첨부파일/회원가입 점수만 이용하여 모든 포인트 점수를 초기화 합니다.
회원 가입 점수는 초기화 후 해당 회원이 활동을 하면 부여되고 그 전에는 부여되지 않습니다.
데이터 이전등을 하여 포인트를 완전히 초기화 해야 할 경우에만 사용하세요.'; -$lang->about_point_link_group = '그룹에 원하는 레벨을 지정하면 해당 레벨에 도달할때 그룹이 변경됩니다.'; $lang->about_module_point = 'Вы можете установть поинты для каждого модуля, а модули, не имеющие значения будут использовать значение по умолчанию для поинтов.
Все поинты будут восстановлены при обратном действии.'; $lang->point_signup = 'Присвоить'; $lang->point_insert_document = 'При написании'; @@ -32,8 +29,6 @@ $lang->cmd_point_module_config = 'Настройки модуля'; $lang->cmd_point_act_config = 'Настройки действий'; $lang->cmd_point_member_list = 'Список поинтов пользователей'; $lang->msg_cannot_download = 'У Вас нет достаточного количества поитов, чтобы иметь разрешение скачивать файлы.'; -$lang->msg_disallow_by_point = '포인트가 부족하여 글을 읽을 수 없습니다 (필요포인트 : %d, 현재포인트 : %d)'; -$lang->point_recal_finished = '포인트 재계산이 모두 완료되었습니다'; $lang->search_target_list['nick_name'] = 'Ник'; $lang->search_target_list['user_name'] = 'Имя пользователя'; $lang->search_target_list['regdate'] = 'Дата регистрации'; diff --git a/modules/point/lang/zh-CN.php b/modules/point/lang/zh-CN.php index 9ce042e7e..ada98e17d 100644 --- a/modules/point/lang/zh-CN.php +++ b/modules/point/lang/zh-CN.php @@ -3,8 +3,6 @@ $lang->point = '积分'; $lang->level = '级别'; $lang->about_point_module = '积分系统可以在发表新帖及评论,上传/下载文件等动作时,付与其相应的积分的模块。'; $lang->about_act_config = '版面,博客等模块都有发表/删除新帖,发表/删除评论等动作。
要想与版面/博客之外的模块关联积分功能时,添加与其各模块功能相适合的act值即可。'; -$lang->point_io = 'Point module On'; -$lang->about_point_io = 'Point module can be on or off. If you OFF this module, every triggers will be deleted from database and will not be called by Rhymix Core. Point record would be preserved.'; $lang->max_level = '最高级别'; $lang->about_max_level = '可以指定最高级别。级别共设1000级,因此制作级别图标时要好好考虑一下。'; $lang->level_icon = '级别图标'; diff --git a/modules/point/lang/zh-TW.php b/modules/point/lang/zh-TW.php index be20b4862..baec73b50 100644 --- a/modules/point/lang/zh-TW.php +++ b/modules/point/lang/zh-TW.php @@ -3,8 +3,6 @@ $lang->point = '點數'; $lang->level = '等級'; $lang->about_point_module = '點數系統可以在發表/刪除主題,發表/刪除評論,上傳/下載/刪除/檔案等動作時,付出相對應的點數。'; $lang->about_act_config = '討論板,部落格等模組都有發表/刪除主題,發表/刪除評論等動作。
想要與討論板/部落格之外的模組關聯點數功能時,新增與其各模組功能適合的act值即可。'; -$lang->point_io = 'Point module On'; -$lang->about_point_io = 'Point module can be on or off. If you OFF this module, every triggers will be deleted from database and will not be called by Rhymix Core. Point record would be preserved.'; $lang->max_level = '最高等級'; $lang->about_max_level = '可以指定最高等級。等級共設1000級,因此製作等級圖示時要好好考慮一下。'; $lang->level_icon = '等級圖示'; @@ -47,7 +45,6 @@ $lang->msg_cannot_download = '點數不足無法下載!'; $lang->msg_disallow_by_point = '點數不足無法閱讀文章 (需要 : %d, 目前 : %d)'; $lang->point_recal_message = '計算並套用中(%d / %d)。'; $lang->point_recal_finished = '點數重新計算並套用完畢。'; -$lang->point_update_desc = 'Insert + in front of the number to increase the point or - to decrease, and update the point. If you don\'t insert + or -, the point will be set as the value you entered.'; $lang->give_point = '給予點數'; $lang->search_target_list['nick_name'] = '暱稱'; $lang->search_target_list['user_name'] = '姓名'; diff --git a/modules/widget/lang/fr.php b/modules/widget/lang/fr.php index 6d7cf6014..ced2de80e 100644 --- a/modules/widget/lang/fr.php +++ b/modules/widget/lang/fr.php @@ -25,7 +25,6 @@ $lang->generated_code = 'Code généré'; $lang->msg_widget_is_not_exists = 'Le Gadget de(d\') \'%s\' n\'existe pas.'; $lang->msg_widget_object_is_null = 'L\'Objet de \'%s\' n\'a pas pu être créé.'; $lang->msg_widget_proc_is_null = 'proc() de \'%s\' n\'a pas pu être exécuté.'; -$lang->msg_widget_skin_is_null = '위젯의 스킨을 선택해야 정상적으로 동작할 수 있습니다'; $lang->about_widget_code = 'Entrez les valeurs qui sont requises par le gadget choisi, et puis cliquz le bouton [Générer le Code] pour générer le code. Le code à appliquer au fichier de modèl se présentera en bas.'; $lang->about_widget_code_in_page = 'Après entrer les valeurs requies, cliquez le bouton [Ajouter] pour insérer le gadjet dans la page.'; $lang->about_widget = 'Un gadjet est un petit application indépendant qui est utilisé dans une Mise en Page ou dans une module de Page. Un gajet peut être lié avec un module intérieur ou avec un API extérieur ouvert. L\'application divers est possible par la configuration. diff --git a/modules/widget/lang/ru.php b/modules/widget/lang/ru.php index c54ac65b9..c0e85b86b 100644 --- a/modules/widget/lang/ru.php +++ b/modules/widget/lang/ru.php @@ -26,6 +26,5 @@ $lang->generated_code = 'Сгенерированный код'; $lang->msg_widget_is_not_exists = '%s виджет не существует.'; $lang->msg_widget_object_is_null = '%s объектов виджета не могут быть созданы.'; $lang->msg_widget_proc_is_null = 'proc() %s виджета не может быть исполнена.'; -$lang->msg_widget_skin_is_null = '위젯의 스킨을 선택해야 정상적으로 동작할 수 있습니다'; $lang->about_widget_code = 'Пожалуйста, сначала введите требуемые значения, и затем щелкните кнопку [Генерировать Код] для генерации кода и добавления его в файл шаблона.'; $lang->about_widget_code_in_page = 'После ввода требуемых значений, нажмите пнопку [Добавить], чтобы вставить код виджета в страницу.'; diff --git a/modules/widget/lang/vi.php b/modules/widget/lang/vi.php index dfcf777e7..1c9d19a97 100644 --- a/modules/widget/lang/vi.php +++ b/modules/widget/lang/vi.php @@ -35,7 +35,6 @@ $lang->cmd_content_insert = 'Chèn nội dung của bạn'; $lang->cmd_box_widget_insert = 'Chèn khung Widget'; $lang->cmd_remove_all_widgets = 'Xóa tất cả Widget'; $lang->cmd_widget_size = 'Kích thước'; -$lang->cmd_widget_css_class = '위젯 CSS class'; $lang->cmd_widget_align = 'Căn chỉnh'; $lang->cmd_widget_align_left = 'Trái'; $lang->cmd_widget_align_right = 'Phải'; diff --git a/modules/widget/lang/zh-CN.php b/modules/widget/lang/zh-CN.php index 2dad8b717..e27fb2db1 100644 --- a/modules/widget/lang/zh-CN.php +++ b/modules/widget/lang/zh-CN.php @@ -38,7 +38,6 @@ $lang->cmd_content_insert = '添加内容'; $lang->cmd_box_widget_insert = '添加控件盒'; $lang->cmd_remove_all_widgets = '清空内容'; $lang->cmd_widget_size = '大小'; -$lang->cmd_widget_css_class = '위젯 CSS class'; $lang->cmd_widget_align = '对齐'; $lang->cmd_widget_align_left = '左对齐'; $lang->cmd_widget_align_right = '右对齐'; diff --git a/modules/widget/lang/zh-TW.php b/modules/widget/lang/zh-TW.php index 167f93748..106f63df0 100644 --- a/modules/widget/lang/zh-TW.php +++ b/modules/widget/lang/zh-TW.php @@ -38,7 +38,6 @@ $lang->cmd_content_insert = '新增內容'; $lang->cmd_box_widget_insert = '新增 Widget Box'; $lang->cmd_remove_all_widgets = '全部清空'; $lang->cmd_widget_size = '大小'; -$lang->cmd_widget_css_class = '위젯 CSS class'; $lang->cmd_widget_align = '對齊'; $lang->cmd_widget_align_left = '靠左'; $lang->cmd_widget_align_right = '靠右'; From 9290c5312225a18c9d54609b7c5f131deaf7deb1 Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 19:46:59 +0900 Subject: [PATCH 060/318] =?UTF-8?q?=20#327=20=EC=96=B8=EC=96=B4=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=95=EB=A6=AC2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/lang/ja.php | 1 - layouts/xedition/lang/ko.php | 2 + layouts/xedition/lang/lang.xml | 6 - modules/addon/lang/ru.php | 1 - modules/admin/lang/es.php | 2 +- modules/admin/lang/fr.php | 2 +- modules/admin/lang/mn.php | 3 +- modules/admin/lang/tr.php | 2 +- modules/autoinstall/lang/fr.php | 3 - modules/autoinstall/lang/ru.php | 8 - modules/comment/lang/lang.xml | 377 -------------------- modules/editor/skins/ckeditor/lang/en.php | 4 + modules/editor/skins/ckeditor/lang/ko.php | 4 + modules/editor/skins/ckeditor/lang/lang.xml | 33 -- 14 files changed, 14 insertions(+), 434 deletions(-) create mode 100644 layouts/xedition/lang/ko.php delete mode 100644 layouts/xedition/lang/lang.xml delete mode 100644 modules/comment/lang/lang.xml create mode 100644 modules/editor/skins/ckeditor/lang/en.php create mode 100644 modules/editor/skins/ckeditor/lang/ko.php delete mode 100644 modules/editor/skins/ckeditor/lang/lang.xml diff --git a/common/lang/ja.php b/common/lang/ja.php index 789706a53..949fda2f3 100644 --- a/common/lang/ja.php +++ b/common/lang/ja.php @@ -292,7 +292,6 @@ $lang->filter['invalid_alpha'] = '%sの形式が正しくありません。半 $lang->filter['invalid_alpha_number'] = '%sの形式が正しくありません。半角英数字で入力してください。'; $lang->filter['invalid_mid'] = '%sの形式が正しくありません。 最初の文字は英文から始め、「英文+数字+_」組合せで入力が必要です。'; $lang->filter['invalid_number'] = '%sの形式が正しくありません。半角数字で入力してください。'; -$lang->security_invalid_session = '바르지 않은 접근입니다. 인증을 위해 다시 로그인해야 합니다.'; $lang->security_warning_embed = 'セキュリティ問題のため、管理者IDではembedを見ることができません。
他のIDでログインしてください。'; $lang->msg_pc_to_mobile = 'このページは、モバイル表示が可能です。モバイル表示へ移動しますか?'; $lang->cmd_yes = 'はい'; diff --git a/layouts/xedition/lang/ko.php b/layouts/xedition/lang/ko.php new file mode 100644 index 000000000..b00f8c757 --- /dev/null +++ b/layouts/xedition/lang/ko.php @@ -0,0 +1,2 @@ +cmd_xedition_search_close = '검색창 닫기'; diff --git a/layouts/xedition/lang/lang.xml b/layouts/xedition/lang/lang.xml deleted file mode 100644 index 1ecfe33d3..000000000 --- a/layouts/xedition/lang/lang.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/modules/addon/lang/ru.php b/modules/addon/lang/ru.php index 4fb44230b..2b41a4490 100644 --- a/modules/addon/lang/ru.php +++ b/modules/addon/lang/ru.php @@ -3,5 +3,4 @@ $lang->addon = 'Аддон'; $lang->addon_info = 'Информация об аддоне'; $lang->addon_maker = 'Автор аддона'; $lang->addon_history = 'История аддона'; -$lang->about_addon_mid = '애드온이 사용될 대상을 지정할 수 있습니다.(모두 해제시 모든 대상에서 사용 가능합니다)'; $lang->about_addon = 'Аддон служит больше для контролирования действий, чем для отображения HTML-результатов.
Простым включением/выключением любых аддонов, Вы можете использовать очень полезные функции для администрирования Вашего веб-сайта'; diff --git a/modules/admin/lang/es.php b/modules/admin/lang/es.php index 8cc33e9d1..96978864e 100644 --- a/modules/admin/lang/es.php +++ b/modules/admin/lang/es.php @@ -37,7 +37,7 @@ $lang->xe_license = 'Rhymix está bajo la Licencia de GPL'; $lang->ssl_options['none'] = 'Desactivar'; $lang->ssl_options['optional'] = 'Opcionalmente el'; $lang->ssl_options['always'] = 'Utilice siempre el'; -$lang->about_use_ssl = 'Opcionalmente, la composición de suscripción / editar la información y el uso de SSL especificada en la acción es siempre el uso de SSL para todos los servicios que se utilizarán SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.'; +$lang->about_use_ssl = 'Opcionalmente, la composición de suscripción / editar la información y el uso de SSL especificada en la acción es siempre el uso de SSL para todos los servicios que se utilizarán.'; $lang->server_ports = 'Especifique el puerto del servidor'; $lang->about_server_ports = '80 de HTTP, HTTPS al puerto 443 si se utiliza otro que se especifique lo contrario, el puerto va a necesitar.'; $lang->about_db_session = 'This setting will use PHP session used for authentication as DB. For the Websites which do not use web server frequently, you can uncheck this setting to improve response time. However, session DB will make it difficult to get current users, so you cannot use related functions.'; diff --git a/modules/admin/lang/fr.php b/modules/admin/lang/fr.php index 808d4862b..bbe96bf6a 100644 --- a/modules/admin/lang/fr.php +++ b/modules/admin/lang/fr.php @@ -36,7 +36,7 @@ $lang->xe_license = 'Rhymix s\'applique la GPL'; $lang->ssl_options['none'] = 'Ne Pas utiliser'; $lang->ssl_options['optional'] = 'Optionnel'; $lang->ssl_options['always'] = 'Toujours'; -$lang->about_use_ssl = 'Si l\'on choisit \'Optionnel\' , on utilise protocole SSL seulement dans quelques services comme inscription ou modification. Si l\'on choisit \'Toujours\', on utilise protocole SSL dans tous les services. SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.'; +$lang->about_use_ssl = 'Si l\'on choisit \'Optionnel\' , on utilise protocole SSL seulement dans quelques services comme inscription ou modification. Si l\'on choisit \'Toujours\', on utilise protocole SSL dans tous les services.'; $lang->server_ports = 'déclarer le port de serveur'; $lang->about_server_ports = 'Si l\'on ne veut pas utiliser le port 80 pour HTTP mais un autre port, ou bien, si l\'on ne veut pas utiliser le port 443 pour HTTPS mais un autre port, on doit déclarer les ports.'; $lang->about_db_session = 'This setting will use PHP session used for authentication as DB. For the Websites which do not use web server frequently, you can uncheck this setting to improve response time. However, session DB will make it difficult to get current users, so you cannot use related functions.'; diff --git a/modules/admin/lang/mn.php b/modules/admin/lang/mn.php index e5f63b3dc..a677a766c 100644 --- a/modules/admin/lang/mn.php +++ b/modules/admin/lang/mn.php @@ -3,8 +3,7 @@ $lang->modify = 'Засах'; $lang->ftp_form_title = 'FTP мэдээлэл оруулах'; $lang->ftp = 'FTP'; $lang->cmd_check_ftp_connect = 'FTP холболт шалгах'; -$lang->msg_safe_mode_ftp_needed = 'PHP의 safe_mode가 Onбайх тохиолдолд , FTP мэдээллийг заавал оруулснаар Rhymix идэвжvvлэх болон хэрэглэх боломжтой болно.'; -$lang->msg_ftp_no_directory = 'Succeed to connect to the host via FTP. However, can not read any directory list informaiton. Check the server configurations.'; +$lang->msg_safe_mode_ftp_needed = 'PHP safe_mode Onбайх тохиолдолд , FTP мэдээллийг заавал оруулснаар Rhymix идэвжvvлэх болон хэрэглэх боломжтой болно.'; $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 холболт болон баталгаажуулалт хийгдлээ.'; diff --git a/modules/admin/lang/tr.php b/modules/admin/lang/tr.php index 77bd8f4ec..816980428 100644 --- a/modules/admin/lang/tr.php +++ b/modules/admin/lang/tr.php @@ -64,7 +64,7 @@ $lang->use_ssl = 'SSL\'i kullanmak ist $lang->ssl_options['none'] = 'Hiçbir zaman'; $lang->ssl_options['optional'] = 'İsteğe Bağlı'; $lang->ssl_options['always'] = 'Her zaman'; -$lang->about_use_ssl = '\'İsteği Bağlı\' seçiminde; SSL, kayıt olma/bilgi değiştirme gibi eylemler için kullanılacaktır. \'Her zaman\' seçiminde, siteniz sadece http yoluyla hizmet verecektir. SSL 환경이 갖춰지지 않은 상태에서 SSL을 사용할 경우 접속이 되지 않을 수 있으니 주의 바랍니다.'; +$lang->about_use_ssl = '\'İsteği Bağlı\' seçiminde; SSL, kayıt olma/bilgi değiştirme gibi eylemler için kullanılacaktır. \'Her zaman\' seçiminde, siteniz sadece http yoluyla hizmet verecektir.'; $lang->server_ports = 'Sunucu Bağlantı Noktası (port)'; $lang->about_server_ports = 'Eğer web sunucunuz, HTTP bağlantı noktaları için 80 ya da HTTPS 443 portunu kullanmıyorsa, sunucu bağlantı noktalarını belirtmeniz gerekmektedir.'; $lang->use_db_session = 'Oturum Veritabanı Kullanımı'; diff --git a/modules/autoinstall/lang/fr.php b/modules/autoinstall/lang/fr.php index 98d74fb32..b3d9bbc7f 100644 --- a/modules/autoinstall/lang/fr.php +++ b/modules/autoinstall/lang/fr.php @@ -1,4 +1 @@ current_version = 'Version Courante'; -$lang->msg_ftp_invalid_auth_info = 'Cannot log in with the FTP password you entered. Please check if it is correct.'; -$lang->msg_ftp_not_connected = 'Connection to the %s via FTP failed. Please check the port number and whether the FTP service is available.'; diff --git a/modules/autoinstall/lang/ru.php b/modules/autoinstall/lang/ru.php index aa4fc4661..dfe603e26 100644 --- a/modules/autoinstall/lang/ru.php +++ b/modules/autoinstall/lang/ru.php @@ -3,13 +3,5 @@ $lang->order_newest = 'Новый'; $lang->order_popular = 'Популярный'; $lang->order_download = 'Скачать'; $lang->success_installed = 'Установлено успешно'; -$lang->description_ftp_note = 'If %s is not set, installation would not work. Please configure FTP information'; -$lang->description_update = 'If you have upgraded or installed programs without EasyInstall module, please press %s to renew new information'; $lang->install = 'Инсталлировать'; $lang->update = 'Обновить'; -$lang->require_update = 'Update is required'; -$lang->require_installation = 'Installation is required'; -$lang->description_install = 'EasyInstall will also install/update all other programs which this program is depending on'; -$lang->description_download = 'If FTP is unavailable, you should manually download it and extract it into target path. (if target path is ./modules/board, extract it at ./modules)'; -$lang->rate = 'points'; -$lang->msg_ftp_not_connected = 'Connection to %s via FTP failed. Please check the port number and if FTP service is available.'; diff --git a/modules/comment/lang/lang.xml b/modules/comment/lang/lang.xml deleted file mode 100644 index 6fe6ea89d..000000000 --- a/modules/comment/lang/lang.xml +++ /dev/null @@ -1,377 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/modules/editor/skins/ckeditor/lang/en.php b/modules/editor/skins/ckeditor/lang/en.php new file mode 100644 index 000000000..11786b678 --- /dev/null +++ b/modules/editor/skins/ckeditor/lang/en.php @@ -0,0 +1,4 @@ +ckeditor_about_file_drop_area = 'Drag and drop your files here, or Click attach files button.'; +$lang->ckeditor_file_uploading = 'Uploading...'; +$lang->ckeditor_file_count = '0 file(s) attached'; diff --git a/modules/editor/skins/ckeditor/lang/ko.php b/modules/editor/skins/ckeditor/lang/ko.php new file mode 100644 index 000000000..0f9b6c0f1 --- /dev/null +++ b/modules/editor/skins/ckeditor/lang/ko.php @@ -0,0 +1,4 @@ +ckeditor_about_file_drop_area = '여기에 파일을 끌어 놓거나 파일 첨부 버튼을 클릭하세요.'; +$lang->ckeditor_file_uploading = '파일 업로드 중...'; +$lang->ckeditor_file_count = '0개 첨부 됨'; diff --git a/modules/editor/skins/ckeditor/lang/lang.xml b/modules/editor/skins/ckeditor/lang/lang.xml deleted file mode 100644 index 429479dbd..000000000 --- a/modules/editor/skins/ckeditor/lang/lang.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - 0개 첨부 됨]]> - 0 file(s) attached]]> - 0 file(s) attached]]> - 0 file(s) attached]]> - 0 file(s) attached]]> - 0 file(s) attached]]> - 0 file(s) attached]]> - 0 file(s) attached]]> - - From f3916c9535475b39ba041bdeeb79b1d4d3dcf6c4 Mon Sep 17 00:00:00 2001 From: conory Date: Thu, 3 Mar 2016 23:03:22 +0900 Subject: [PATCH 061/318] =?UTF-8?q?=EA=B0=9C=EC=9D=B8=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EB=B3=B4=ED=98=B8=20(=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=EC=A3=BC=EC=86=8C=20=EA=B0=80=EB=A6=AC=EA=B8=B0,=20?= =?UTF-8?q?=EC=B9=9C=EA=B5=AC=EB=A7=8C=20=EB=A9=94=EC=9D=BC=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/member/member.model.php | 10 +++++++--- modules/member/member.view.php | 6 +++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/member/member.model.php b/modules/member/member.model.php index fd72ef1ce..bae8da737 100644 --- a/modules/member/member.model.php +++ b/modules/member/member.model.php @@ -155,10 +155,14 @@ class memberModel extends member } // Send an email only if email address is public - if(($logged_info->is_admin == 'Y' || $email_config->isPublic == 'Y') && $member_info->email_address) + if($email_config->isPublic == 'Y' && $member_info->email_address) { - $url = 'mailto:'.htmlspecialchars($member_info->email_address, ENT_COMPAT | ENT_HTML401, 'UTF-8', false); - $oMemberController->addMemberPopupMenu($url,'cmd_send_email',$icon_path); + $oCommunicationModel = getModel('communication'); + if($logged_info->is_admin == 'Y' || $oCommunicationModel->isFriend($member_info->member_srl)) + { + $url = 'mailto:'.htmlspecialchars($member_info->email_address, ENT_COMPAT | ENT_HTML401, 'UTF-8', false); + $oMemberController->addMemberPopupMenu($url,'cmd_send_email',$icon_path); + } } } // View homepage info diff --git a/modules/member/member.view.php b/modules/member/member.view.php index 687dd1cc9..06bd6ac78 100644 --- a/modules/member/member.view.php +++ b/modules/member/member.view.php @@ -84,9 +84,9 @@ class memberView extends member if($logged_info->is_admin != 'Y' && ($member_info->member_srl != $logged_info->member_srl)) { - $start = strpos($member_info->email_address, '@')+1; - $replaceStr = str_repeat('*', (strlen($member_info->email_address) - $start)); - $member_info->email_address = substr_replace($member_info->email_address, $replaceStr, $start); + list($email_id, $email_host) = explode('@', $member_info->email_address); + $protect_id = substr($email_id, 0, 2) . str_repeat('*', strlen($email_id)-2); + $member_info->email_address = sprintf('%s@%s', $protect_id, $email_host); } if(!$member_info->member_srl) return $this->dispMemberSignUpForm(); From 9358b8543994065aadb76e53d17534d897765266 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 4 Mar 2016 10:40:32 +0900 Subject: [PATCH 062/318] insert extra_vars data --- modules/document/document.controller.php | 61 +++++++++++++----------- 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index ce434b29d..08179cda0 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -438,20 +438,8 @@ class documentController extends document $oDB->rollback(); return $output; } - // update Document Log - else - { - if($obj->update_log_setting === 'Y') - { - $update_output = $this->insertDocumentUpdateLog($obj); - if(!$update_output->toBool()) - { - $oDB->rollback(); - return $update_output; - } - } - } // Insert extra variables if the document successfully inserted. + $extra_vars = array(); $extra_keys = $oDocumentModel->getExtraKeys($obj->module_srl); if(count($extra_keys)) { @@ -462,13 +450,20 @@ class documentController extends document { $tmp = $obj->{'extra_vars'.$idx}; if(is_array($tmp)) + { $value = implode('|@|', $tmp); + } else + { $value = trim($tmp); + } + } + else if(isset($obj->{$extra_item->name})) + { + $value = trim($obj->{$extra_item->name}); } - else if(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); if($value == NULL) continue; - + $extra_vars[$extra_item->name] = $value; $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); } } @@ -477,6 +472,16 @@ class documentController extends document // Call a trigger (after) if($output->toBool()) { + if($obj->update_log_setting === 'Y') + { + $obj->extra_vars = serialize($extra_vars); + $update_output = $this->insertDocumentUpdateLog($obj); + if(!$update_output->toBool()) + { + $oDB->rollback(); + return $update_output; + } + } $trigger_output = ModuleHandler::triggerCall('document.insertDocument', 'after', $obj); if(!$trigger_output->toBool()) { @@ -697,20 +702,9 @@ class documentController extends document $oDB->rollback(); return $output; } - // update Document Log - else - { - if($obj->update_log_setting === 'Y') - { - $update_output = $this->insertDocumentUpdateLog($obj, $source_obj); - if(!$update_output->toBool()) - { - $oDB->rollback(); - return $update_output; - } - } - } + // Remove all extra variables + $extra_vars = array(); if(Context::get('act')!='procFileDelete') { $this->deleteDocumentExtraVars($source_obj->get('module_srl'), $obj->document_srl, null, Context::getLangType()); @@ -731,6 +725,7 @@ class documentController extends document } else if(isset($obj->{$extra_item->name})) $value = trim($obj->{$extra_item->name}); if($value == NULL) continue; + $extra_vars[$extra_item->name] = $value; $this->insertDocumentExtraVar($obj->module_srl, $obj->document_srl, $idx, $value, $extra_item->eid); } } @@ -747,6 +742,16 @@ class documentController extends document // Call a trigger (after) if($output->toBool()) { + if($obj->update_log_setting === 'Y') + { + $obj->extra_vars = serialize($extra_vars); + $update_output = $this->insertDocumentUpdateLog($obj, $source_obj); + if(!$update_output->toBool()) + { + $oDB->rollback(); + return $update_output; + } + } $trigger_output = ModuleHandler::triggerCall('document.updateDocument', 'after', $obj); if(!$trigger_output->toBool()) { From 816cc9f8417d0501ae239b06437c50aa2edf8bf7 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 4 Mar 2016 10:42:35 +0900 Subject: [PATCH 063/318] language setting --- modules/board/skins/xedition/write_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/board/skins/xedition/write_form.html b/modules/board/skins/xedition/write_form.html index edbec4d8b..d4dedf200 100644 --- a/modules/board/skins/xedition/write_form.html +++ b/modules/board/skins/xedition/write_form.html @@ -69,7 +69,7 @@ - +
From 54fc1da600f03784aaf790e3dc1d0dd86083174a Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 4 Mar 2016 10:57:56 +0900 Subject: [PATCH 064/318] Fix no redirect after writing a comment --- common/js/xml_handler.js | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index 0b4f03775..65eba4976 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -102,9 +102,18 @@ } // If the response contains a redirect URL, redirect immediately. - if (result.redirect_url) { - window.location = result.redirect_url.replace(/&/g, "&"); - return null; + if (data.redirect_url) { + data.redirect_url = data.redirect_url.replace(/&/g, "&"); + if (data.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) + { + window.location = data.redirect_url; + window.location.reload(); + } + else + { + window.location = data.redirect_url; + } + return; } // If there was a success callback, call it. @@ -220,6 +229,21 @@ } } + // If the response contains a redirect URL, redirect immediately. + if (data.redirect_url) { + data.redirect_url = data.redirect_url.replace(/&/g, "&"); + if (data.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) + { + window.location = data.redirect_url; + window.location.reload(); + } + else + { + window.location = data.redirect_url; + } + return; + } + // If there was a success callback, call it. if($.isFunction(callback_success)) { callback_success(data); From b141e69dbc69125557f049c9d282660675458b7f Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 4 Mar 2016 11:16:54 +0900 Subject: [PATCH 065/318] =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EA=B0=9C=EC=84=A0?= =?UTF-8?q?=20(=ED=95=9C=EA=B8=80=20=EB=8C=80=EC=B2=B4=20=ED=8F=AC?= =?UTF-8?q?=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 84 ++++++++++----------------------------- 1 file changed, 21 insertions(+), 63 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index aa68c0ca5..9c8a2ba16 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -86,10 +86,9 @@ class Lang * * @param string $dir * @param string $plugin_name - * @param array $default_lang * @return bool */ - public function loadDirectory($dir, $plugin_name = null, $default_lang = null) + public function loadDirectory($dir, $plugin_name = null) { // Do not load the same directory twice. $dir = rtrim($dir, '/'); @@ -99,38 +98,19 @@ class Lang return true; } - if (!is_array($default_lang)) + // Load the language file. + $lang = $this->getPluginLang($dir); + + // Load the default language file. + if ($this->_language !== 'en') { - $default_lang = array('en', 'ko'); - } - if (!in_array($this->_language, $default_lang)) - { - $default_lang[] = $this->_language; - } - - foreach ($default_lang as $language) - { - if ($this->_language === $language) - { - $lang = $this->getPluginLang($dir, $language); - if (empty($lang)) - { - continue; - } - - $this->_loaded_plugins[$plugin_name] = $lang; - } - else - { - $other_lang = self::getInstance($language); - $other_lang->loadDirectory($dir, $plugin_name, array()); - } + self::getInstance('en')->loadDirectory($dir, $plugin_name); } - // Load the language file. - if (isset($this->_loaded_plugins[$plugin_name])) + if (!empty($lang)) { $this->_loaded_directories[$dir] = true; + $this->_loaded_plugins[$plugin_name] = $lang; array_unshift($this->_search_priority, $plugin_name); return true; } @@ -208,13 +188,12 @@ class Lang } /** - * Get lang from key + * Magic method for translations without arguments. * * @param string $key - * @param bool $other_lang * @return string */ - protected function _getLang($key, $other_lang = true) + public function __get($key) { // Separate the plugin name from the key. if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key, 2)) && count($keys) === 2) @@ -229,7 +208,13 @@ class Lang return $this->_loaded_plugins[$plugin_name]->{$lang_key}; } - goto end_other_lang; + // Search other language. + if ($this->_language !== 'en') + { + return self::getInstance('en')->{$key}; + } + + return $key; } // Search custom translations first. @@ -261,43 +246,16 @@ class Lang } } - end_other_lang: - // Search other language. - if ($other_lang) + if ($this->_language !== 'en') { - foreach (self::$_instances as $language => $instance) - { - if ($this->_language === $language) - { - continue; - } - - $lang = $instance->_getLang($key, false); - if ($lang === $key) - { - continue; - } - - return $lang; - } + return self::getInstance('en')->{$key}; } // If no translation is found, return the key. return $key; } - /** - * Magic method for translations without arguments. - * - * @param string $key - * @return string - */ - public function __get($key) - { - return $this->_getLang($key); - } - /** * Magic method for setting a new custom translation. * @@ -358,7 +316,7 @@ class Lang if ($key !== '' && $key[0] === ':') $key = substr($key, 1); // Find the translation. - $translation = $this->_getLang($key); + $translation = $this->__get($key); // If there are no arguments, return the translation. if (!count($args)) return $translation; From 4c475b5b62edafd2989ebc9221f53e4f23643654 Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 4 Mar 2016 13:16:03 +0900 Subject: [PATCH 066/318] =?UTF-8?q?=EB=B0=B0=EC=97=B4=EB=A1=9C=20=EB=90=9C?= =?UTF-8?q?=20=EC=96=B8=EC=96=B4=EC=9D=B8=20=EA=B2=BD=EC=9A=B0=20=EC=9A=94?= =?UTF-8?q?=EC=86=8C=EA=B0=80=20=ED=95=98=EB=82=98=EB=9D=BC=EB=8F=84=20?= =?UTF-8?q?=EB=B9=A0=EC=A0=B8=EC=9E=88=EC=9C=BC=EB=A9=B4=20=EC=98=81?= =?UTF-8?q?=EC=96=B4=EB=A1=9C=20=EB=8C=80=EC=B2=B4=ED=95=98=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 89 ++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index 9c8a2ba16..f5f0cef56 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -195,6 +195,12 @@ class Lang */ public function __get($key) { + // Get default language + if ($this->_language !== 'en') + { + $lang_en = self::getInstance('en')->{$key}; + } + // Separate the plugin name from the key. if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key, 2)) && count($keys) === 2) { @@ -203,53 +209,66 @@ class Lang { $this->loadPlugin($plugin_name); } + if (isset($this->_loaded_plugins[$plugin_name]->{$lang_key})) { - return $this->_loaded_plugins[$plugin_name]->{$lang_key}; - } - - // Search other language. - if ($this->_language !== 'en') - { - return self::getInstance('en')->{$key}; - } - - return $key; - } - - // Search custom translations first. - if (isset($this->_loaded_plugins['_custom_']->{$key})) - { - if (is_array($this->_loaded_plugins['_custom_']->{$key})) - { - return new \ArrayObject($this->_loaded_plugins['_custom_']->{$key}, 3); - } - else - { - return $this->_loaded_plugins['_custom_']->{$key}; - } - } - - // Search other plugins. - foreach ($this->_search_priority as $plugin_name) - { - if (isset($this->_loaded_plugins[$plugin_name]->{$key})) - { - if (is_array($this->_loaded_plugins[$plugin_name]->{$key})) + $lang = $this->_loaded_plugins[$plugin_name]->{$lang_key}; + if (is_array($lang) && isset($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) { - return new \ArrayObject($this->_loaded_plugins[$plugin_name]->{$key}, 3); + return $lang_en; + } + + return $lang; + } + } + else + { + // Search custom translations first. + if (isset($this->_loaded_plugins['_custom_']->{$key})) + { + $lang = $this->_loaded_plugins['_custom_']->{$key}; + if (is_array($lang)) + { + if (isset($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) + { + return new \ArrayObject($lang_en, 3); + } + + return new \ArrayObject($lang, 3); } else { - return $this->_loaded_plugins[$plugin_name]->{$key}; + return $lang; + } + } + + // Search other plugins. + foreach ($this->_search_priority as $plugin_name) + { + if (isset($this->_loaded_plugins[$plugin_name]->{$key})) + { + $lang = $this->_loaded_plugins[$plugin_name]->{$key}; + if (is_array($lang)) + { + if (isset($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) + { + return new \ArrayObject($lang_en, 3); + } + + return new \ArrayObject($lang, 3); + } + else + { + return $lang; + } } } } // Search other language. - if ($this->_language !== 'en') + if (isset($lang_en)) { - return self::getInstance('en')->{$key}; + return $lang_en; } // If no translation is found, return the key. From 006474cb989c83dc2db53eefc52d350d18c2b058 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 4 Mar 2016 15:07:03 +0900 Subject: [PATCH 067/318] Fix unnecessary redirect on comment insertion in some skins --- common/js/xml_handler.js | 4 ++ modules/board/tpl/js/board.js | 93 ++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index 65eba4976..74173f756 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -104,6 +104,8 @@ // If the response contains a redirect URL, redirect immediately. if (data.redirect_url) { data.redirect_url = data.redirect_url.replace(/&/g, "&"); + } + if (data.redirect_url && !$.isFunction(callback_success)) { if (data.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) { window.location = data.redirect_url; @@ -232,6 +234,8 @@ // If the response contains a redirect URL, redirect immediately. if (data.redirect_url) { data.redirect_url = data.redirect_url.replace(/&/g, "&"); + } + if (data.redirect_url && !$.isFunction(callback_success)) { if (data.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) { window.location = data.redirect_url; diff --git a/modules/board/tpl/js/board.js b/modules/board/tpl/js/board.js index 9e344c435..a4fbc0621 100644 --- a/modules/board/tpl/js/board.js +++ b/modules/board/tpl/js/board.js @@ -13,19 +13,21 @@ function completeDocumentInserted(ret_obj) var document_srl = ret_obj.document_srl; var category_srl = ret_obj.category_srl; - //alert(message); - - var url; - if(!document_srl) - { - url = current_url.setQuery('mid',mid).setQuery('act',''); + if (ret_obj.redirect_url) { + location.href = ret_obj.redirect_url; + } else { + var url; + if(!document_srl) + { + url = current_url.setQuery('mid',mid).setQuery('act',''); + } + else + { + url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); + } + if(category_srl) url = url.setQuery('category',category_srl); + location.href = url; } - else - { - url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - } - if(category_srl) url = url.setQuery('category',category_srl); - location.href = url; } /* delete the document */ @@ -38,9 +40,6 @@ function completeDeleteDocument(ret_obj) var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); if(page) url = url.setQuery('page',page); - - //alert(message); - location.href = url; } @@ -75,13 +74,21 @@ function completeInsertComment(ret_obj) var mid = ret_obj.mid; var document_srl = ret_obj.document_srl; var comment_srl = ret_obj.comment_srl; - - var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(comment_srl) url = url.setQuery('rnd',comment_srl)+"#comment_"+comment_srl; - - //alert(message); - - location.href = url; + if (ret_obj.redirect_url) { + if (ret_obj.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) + { + window.location = ret_obj.redirect_url; + window.location.reload(); + } + else + { + window.location = ret_obj.redirect_url; + } + } else { + var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); + if (comment_srl) url = url.setQuery('rnd',comment_srl)+"#comment_"+comment_srl; + window.location.href = url; + } } /* delete the comment */ @@ -93,12 +100,21 @@ function completeDeleteComment(ret_obj) var document_srl = ret_obj.document_srl; var page = ret_obj.page; - var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url = url.setQuery('page',page); - - //alert(message); - - location.href = url; + if (ret_obj.redirect_url) { + if (ret_obj.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) + { + window.location = ret_obj.redirect_url; + window.location.reload(); + } + else + { + window.location = ret_obj.redirect_url; + } + } else { + var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); + if (page) url = url.setQuery('page',page); + window.location.href = url; + } } /* delete the trackback */ @@ -110,12 +126,21 @@ function completeDeleteTrackback(ret_obj) var document_srl = ret_obj.document_srl; var page = ret_obj.page; - var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url = url.setQuery('page',page); - - //alert(message); - - location.href = url; + if (ret_obj.redirect_url) { + if (ret_obj.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) + { + window.location = ret_obj.redirect_url; + window.location.reload(); + } + else + { + window.location = ret_obj.redirect_url; + } + } else { + var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); + if (page) url = url.setQuery('page',page); + window.location.href = url; + } } /* change category */ From 847ed92e1baed9f19ea4ceffce72fa1ef52f0dbf Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 4 Mar 2016 15:57:21 +0900 Subject: [PATCH 068/318] Fix double escape of document title --- modules/board/skins/default/write_form.html | 2 +- modules/board/skins/xedition/write_form.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/board/skins/default/write_form.html b/modules/board/skins/default/write_form.html index f3e13930e..62301dd1a 100644 --- a/modules/board/skins/default/write_form.html +++ b/modules/board/skins/default/write_form.html @@ -10,7 +10,7 @@ {str_repeat("  ",$val->depth)} {$val->title} ({$val->document_count}) - + diff --git a/modules/board/skins/xedition/write_form.html b/modules/board/skins/xedition/write_form.html index e9a197a07..c0ced47e9 100644 --- a/modules/board/skins/xedition/write_form.html +++ b/modules/board/skins/xedition/write_form.html @@ -10,7 +10,7 @@ {str_repeat("  ",$val->depth)} {$val->title} ({$val->document_count}) - + From f13b7bf999fd221d9c112231acd976d66cd026fe Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 4 Mar 2016 16:43:38 +0900 Subject: [PATCH 069/318] =?UTF-8?q?ArrayObject=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index f5f0cef56..fbddd57a9 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -213,7 +213,7 @@ class Lang if (isset($this->_loaded_plugins[$plugin_name]->{$lang_key})) { $lang = $this->_loaded_plugins[$plugin_name]->{$lang_key}; - if (is_array($lang) && isset($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) + if (is_array($lang) && is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) { return $lang_en; } @@ -229,7 +229,7 @@ class Lang $lang = $this->_loaded_plugins['_custom_']->{$key}; if (is_array($lang)) { - if (isset($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) + if (is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) { return new \ArrayObject($lang_en, 3); } @@ -250,7 +250,7 @@ class Lang $lang = $this->_loaded_plugins[$plugin_name]->{$key}; if (is_array($lang)) { - if (isset($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) + if (is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) { return new \ArrayObject($lang_en, 3); } From 4c4df273d1dbd8ae703128b0de5534f0f4fcd25a Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 4 Mar 2016 16:53:13 +0900 Subject: [PATCH 070/318] extra_vars viewer --- modules/board/board.view.php | 3 +++ modules/board/skins/xedition/update_view.html | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 54e634521..1e45f6978 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -1172,6 +1172,9 @@ class boardView extends board return new Object(-1, 'msg_not_permitted'); } $update_log = $oDocumentModel->getUpdateLog($update_id); + $extra_vars = unserialize($update_log->extra_vars); + + Context::set('extra_vars', $extra_vars); Context::set('update_log', $update_log); $this->setTemplateFile('update_view'); diff --git a/modules/board/skins/xedition/update_view.html b/modules/board/skins/xedition/update_view.html index 7a546b8e3..390c051a2 100644 --- a/modules/board/skins/xedition/update_view.html +++ b/modules/board/skins/xedition/update_view.html @@ -13,15 +13,17 @@

-
{$update_log->content}
-
+

+ {$key} : {$val} +

+

{$lang->reason_update} : {$update_log->reason_update} -

+

From f878b012f73270f7a0bc7112e5f45fa6ea9ac500 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Fri, 4 Mar 2016 16:53:52 +0900 Subject: [PATCH 071/318] status update_log settings --- modules/board/skins/xedition/write_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/board/skins/xedition/write_form.html b/modules/board/skins/xedition/write_form.html index d4dedf200..9d9cf21ba 100644 --- a/modules/board/skins/xedition/write_form.html +++ b/modules/board/skins/xedition/write_form.html @@ -68,7 +68,7 @@ - + From de98f804a328d77fb0b76f8a78365b30304bc5b7 Mon Sep 17 00:00:00 2001 From: bjrambo Date: Fri, 4 Mar 2016 17:04:34 +0900 Subject: [PATCH 072/318] ignore error_log files by cpanel. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 1ab6c7b20..f6d44c481 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ composer.phar *.sublime-workspace *.sublime-project .codeintel +error_log From a50695f047e3ef3aced7bfa4f413935644a815ea Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 4 Mar 2016 20:35:42 +0900 Subject: [PATCH 073/318] =?UTF-8?q?#331=20=EC=AA=BD=EC=A7=80=EB=B3=B4?= =?UTF-8?q?=EB=82=B4=EA=B8=B0=EC=99=80=20=EC=B9=9C=EA=B5=AC=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EB=A9=94=EB=89=B4=EA=B0=80=20=EB=82=98=EC=98=A4?= =?UTF-8?q?=EC=A7=80=EC=95=8A=EC=95=98=EB=8D=98=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/communication/communication.class.php | 60 +++------ .../communication.controller.php | 125 ++++++++++-------- 2 files changed, 85 insertions(+), 100 deletions(-) diff --git a/modules/communication/communication.class.php b/modules/communication/communication.class.php index 559e2f28b..a4b2518d3 100644 --- a/modules/communication/communication.class.php +++ b/modules/communication/communication.class.php @@ -9,8 +9,10 @@ class communication extends ModuleObject { private $triggers = array( - array('moduleHandler.init', 'communication', 'controller', 'triggerModuleHandlerAfter', 'after') + array('moduleHandler.init', 'communication', 'controller', 'triggerModuleHandlerBefore', 'before'), + array('member.getMemberMenu', 'communication', 'controller', 'triggerMemberMenu', 'before') ); + /** * Implement if additional tasks are necessary when installing * @return Object @@ -18,6 +20,7 @@ class communication extends ModuleObject function moduleInstall() { $oModuleController = getController('module'); + foreach($this->triggers as $trigger) { $oModuleController->insertTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); @@ -25,6 +28,7 @@ class communication extends ModuleObject // Create a temporary file storage for one new private message notification FileHandler::makeDir('./files/member_extra_info/new_message_flags'); + return new Object(); } @@ -34,28 +38,8 @@ class communication extends ModuleObject */ function checkUpdate() { - if(!is_dir("./files/member_extra_info/new_message_flags")) - { - return TRUE; - } - - $oModuleModel = getModel('module'); - $config = $oModuleModel->getModuleConfig('message'); - - if($config->skin) - { - $config_parse = explode('.', $config->skin); - if(count($config_parse) > 1) - { - $template_path = sprintf('./themes/%s/modules/communication/', $config_parse[0]); - if(is_dir($template_path)) - { - return TRUE; - } - } - } - $oModuleModel = getModel('module'); + foreach($this->triggers as $trigger) { if(!$oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) @@ -63,6 +47,12 @@ class communication extends ModuleObject return TRUE; } } + + if(!is_dir("./files/member_extra_info/new_message_flags")) + { + return TRUE; + } + return FALSE; } @@ -72,13 +62,9 @@ class communication extends ModuleObject */ function moduleUpdate() { - if(!is_dir("./files/member_extra_info/new_message_flags")) - { - FileHandler::makeDir('./files/member_extra_info/new_message_flags'); - } - $oModuleModel = getModel('module'); $oModuleController = getController('module'); + foreach($this->triggers as $trigger) { if(!$oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) @@ -86,24 +72,10 @@ class communication extends ModuleObject $oModuleController->insertTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); } } - $config = $oModuleModel->getModuleConfig('message'); - if(!is_object($config)) + + if(!is_dir("./files/member_extra_info/new_message_flags")) { - $config = new stdClass(); - } - - if($config->skin) - { - $config_parse = explode('.', $config->skin); - if(count($config_parse) > 1) - { - $template_path = sprintf('./themes/%s/modules/communication/', $config_parse[0]); - if(is_dir($template_path)) - { - $config->skin = implode('|@|', $config_parse); - $oModuleController->updateModuleConfig('communication', $config); - } - } + FileHandler::makeDir('./files/member_extra_info/new_message_flags'); } return new Object(0, 'success_updated'); diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 452c61afc..248f04632 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -777,14 +777,9 @@ class communicationController extends communication return executeQuery('communication.setMessageReaded', $args); } - function triggerModuleHandlerAfter($module) + function triggerModuleHandlerBefore($obj) { - if(!Context::get('is_logged') && isCrawler()) - { - return new Object(); - } - - if($module->module == 'admin') + if(!Context::get('is_logged') || $obj->module == 'member') { return new Object(); } @@ -796,60 +791,78 @@ class communicationController extends communication { return new Object(); } - $act = Context::get('act'); - if($module->module != 'member') - { - $oMemberController = getController('member'); - $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); - $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); + $logged_info = Context::get('logged_info'); + + // Add menus on the member login information + $oMemberController = getController('member'); + $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); + $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); + + $flag_file = './files/member_extra_info/new_message_flags/' . getNumberingPath($logged_info->member_srl) . $logged_info->member_srl; + if(file_exists($flag_file)) + { // Pop-up to display messages if a flag on new message is set - $new_message_count = $oCommunicationModel->getNewMessageCount(); - if($new_message_count > 0) - { - Context::loadFile('./modules/communication/tpl/js/member_communication.js'); - $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); - Context::addHtmlHeader(""); - } - + $new_message_count = (int) trim(FileHandler::readFile($flag_file)); + $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); + Context::addHtmlFooter(""); + Context::loadFile(array('./modules/communication/tpl/js/member_communication.js'), true); + + FileHandler::removeFile($flag_file); } - elseif($act == 'getMemberMenu') + } + + function triggerMemberMenu() + { + if(!Context::get('is_logged')) { - $member_srl = Context::get('target_srl'); - $oCommunicationModel = getModel('communication'); - $logged_info = Context::get('logged_info'); - // Add a feature to display own message box. - if($logged_info->member_srl == $member_srl) - { - $mid = Context::get('cur_mid'); - $oMemberController = getController('member'); - // Add your own viewing Note Template - $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationMessages'), 'cmd_view_message_box', '', 'self'); - // Display a list of friends - $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationFriend'), 'cmd_view_friend', '', 'self'); - // If not, Add menus to send message and to add friends - } - else - { - // Get member information - $oMemberModel = getModel('member'); - $target_member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); - if(!$target_member_info->member_srl) - { - return new Object(); - } + return new Object(); + } + + $oCommunicationModel = getModel('communication'); + $config = $oCommunicationModel->getConfig(); - $oMemberController = getController('member'); - // Add a menu for sending message - 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('', 'mid', Context::get('cur_mid'), 'act', 'dispCommunicationSendMessage', 'receiver_srl', $member_srl), 'cmd_send_message', '', 'popup'); - } - // Add a menu for listing friends (if a friend is new) - if(!$oCommunicationModel->isAddedFriend($member_srl)) - { - $oMemberController->addMemberPopupMenu(getUrl('', 'mid', Context::get('cur_mid'), 'act', 'dispCommunicationAddFriend', 'target_srl', $member_srl), 'cmd_add_friend', '', 'popup'); - } + if($config->member_menu != 'Y') + { + return new Object(); + } + + $mid = Context::get('cur_mid'); + $member_srl = Context::get('target_srl'); + $logged_info = Context::get('logged_info'); + $oMemberController = getController('member'); + + // Add a feature to display own message box. + if($logged_info->member_srl == $member_srl) + { + // Add your own viewing Note Template + $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationMessages'), 'cmd_view_message_box', '', 'self'); + + // Display a list of friends + $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationFriend'), 'cmd_view_friend', '', 'self'); + + } + // If not, Add menus to send message and to add friends + else + { + // Get member information + $oMemberModel = getModel('member'); + $target_member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + if(!$target_member_info->member_srl) + { + return new Object(); + } + + // Add a menu for sending message + 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('', 'mid', $mid, 'act', 'dispCommunicationSendMessage', 'receiver_srl', $member_srl), 'cmd_send_message', '', 'popup'); + } + + // Add a menu for listing friends (if a friend is new) + if(!$oCommunicationModel->isAddedFriend($member_srl)) + { + $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationAddFriend', 'target_srl', $member_srl), 'cmd_add_friend', '', 'popup'); } } } From b8b0e8978a1b08def7ba5b228eb9c6d057aafa7c Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 4 Mar 2016 22:50:31 +0900 Subject: [PATCH 074/318] =?UTF-8?q?=EC=AA=BD=EC=A7=80,=20=EC=B9=9C?= =?UTF-8?q?=EA=B5=AC=EC=97=90=20=EB=8C=80=ED=95=9C=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../communication.admin.controller.php | 2 +- .../communication.admin.view.php | 12 +-- .../communication.controller.php | 64 ++++++++------ modules/communication/communication.model.php | 86 ++++++++----------- modules/communication/lang/en.php | 4 +- modules/communication/lang/ko.php | 4 +- modules/communication/tpl/index.html | 66 ++++++++------ 7 files changed, 127 insertions(+), 111 deletions(-) diff --git a/modules/communication/communication.admin.controller.php b/modules/communication/communication.admin.controller.php index f0e7f0974..0b52ad2b2 100644 --- a/modules/communication/communication.admin.controller.php +++ b/modules/communication/communication.admin.controller.php @@ -24,7 +24,7 @@ class communicationAdminController extends communication function procCommunicationAdminInsertConfig() { // get the default information - $args = Context::gets('skin', 'colorset', 'editor_skin', 'sel_editor_colorset', 'mskin', 'mcolorset', 'layout_srl', 'mlayout_srl', 'grant_write_default','grant_write_group', 'member_menu'); + $args = Context::gets('enable_message', 'enable_friend', 'skin', 'colorset', 'editor_skin', 'sel_editor_colorset', 'mskin', 'mcolorset', 'layout_srl', 'mlayout_srl', 'grant_write_default','grant_write_group'); $args->editor_colorset = $args->sel_editor_colorset; unset($args->sel_editor_colorset); diff --git a/modules/communication/communication.admin.view.php b/modules/communication/communication.admin.view.php index 9fc91e73d..89dd8f498 100644 --- a/modules/communication/communication.admin.view.php +++ b/modules/communication/communication.admin.view.php @@ -30,7 +30,7 @@ class communicationAdminView extends communication $oCommunicationModel = getModel('communication'); // get the configurations of communication module - Context::set('communication_config', $oCommunicationModel->getConfig()); + Context::set('config', $oCommunicationModel->getConfig()); // get a list of layout Context::set('layout_list', $oLayoutModel->getLayoutList()); @@ -39,10 +39,10 @@ class communicationAdminView extends communication Context::set('editor_skin_list', $oEditorModel->getEditorSkinList()); // get a list of communication skins - Context::set('communication_skin_list', $oModuleModel->getSkins($this->module_path)); + Context::set('skin_list', $oModuleModel->getSkins($this->module_path)); // get a list of communication skins - Context::set('communication_mobile_skin_list', $oModuleModel->getSkins($this->module_path, 'm.skins')); + Context::set('mobile_skin_list', $oModuleModel->getSkins($this->module_path, 'm.skins')); // Get a layout list $layout_list = $oLayoutModel->getLayoutList(); @@ -52,11 +52,11 @@ class communicationAdminView extends communication Context::set('mlayout_list', $mlayout_list); $security = new Security(); - $security->encodeHTML('communication_config..'); + $security->encodeHTML('config..'); $security->encodeHTML('layout_list..'); $security->encodeHTML('editor_skin_list..'); - $security->encodeHTML('communication_skin_list..title'); - $security->encodeHTML('communication_mobile_skin_list..title'); + $security->encodeHTML('skin_list..title'); + $security->encodeHTML('mobile_skin_list..title'); $oMemberModel = getModel('member'); $group_list = $oMemberModel->getGroups($this->site_srl); diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 248f04632..65c4295cb 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -89,7 +89,7 @@ class communicationController extends communication $oCommunicationModel = getModel('communication'); $config = $oCommunicationModel->getConfig(); - if(!$oCommunicationModel->checkGrant($config->grant_write)) + if(!$oCommunicationModel->checkWriteGrant($config->grant_write)) { return new Object(-1, 'msg_not_permitted'); } @@ -784,31 +784,40 @@ class communicationController extends communication return new Object(); } + $logged_info = Context::get('logged_info'); $oCommunicationModel = getModel('communication'); $config = $oCommunicationModel->getConfig(); - - if($config->member_menu != 'Y') + + if($config->enable_message == 'N' && $config->enable_friend == 'N') { return new Object(); } - - $logged_info = Context::get('logged_info'); // Add menus on the member login information $oMemberController = getController('member'); - $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); - $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); - - $flag_file = './files/member_extra_info/new_message_flags/' . getNumberingPath($logged_info->member_srl) . $logged_info->member_srl; - if(file_exists($flag_file)) + if($config->enable_message == 'Y') { - // Pop-up to display messages if a flag on new message is set - $new_message_count = (int) trim(FileHandler::readFile($flag_file)); - $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); - Context::addHtmlFooter(""); - Context::loadFile(array('./modules/communication/tpl/js/member_communication.js'), true); - - FileHandler::removeFile($flag_file); + $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); + } + + if($config->enable_friend == 'Y') + { + $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); + } + + if($config->enable_message == 'Y') + { + $flag_file = './files/member_extra_info/new_message_flags/' . getNumberingPath($logged_info->member_srl) . $logged_info->member_srl; + if(file_exists($flag_file)) + { + // Pop-up to display messages if a flag on new message is set + $new_message_count = (int) trim(FileHandler::readFile($flag_file)); + $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); + Context::addHtmlFooter(""); + Context::loadFile(array('./modules/communication/tpl/js/member_communication.js'), true); + + FileHandler::removeFile($flag_file); + } } } @@ -821,12 +830,12 @@ class communicationController extends communication $oCommunicationModel = getModel('communication'); $config = $oCommunicationModel->getConfig(); - - if($config->member_menu != 'Y') + + if($config->enable_message == 'N' && $config->enable_friend == 'N') { return new Object(); } - + $mid = Context::get('cur_mid'); $member_srl = Context::get('target_srl'); $logged_info = Context::get('logged_info'); @@ -836,11 +845,16 @@ class communicationController extends communication if($logged_info->member_srl == $member_srl) { // Add your own viewing Note Template - $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationMessages'), 'cmd_view_message_box', '', 'self'); + if($config->enable_message == 'Y') + { + $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationMessages'), 'cmd_view_message_box', '', 'self'); + } // Display a list of friends - $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationFriend'), 'cmd_view_friend', '', 'self'); - + if($config->enable_friend == 'Y') + { + $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationFriend'), 'cmd_view_friend', '', 'self'); + } } // If not, Add menus to send message and to add friends else @@ -854,13 +868,13 @@ class communicationController extends communication } // Add a menu for sending message - if($logged_info->is_admin == 'Y' || $target_member_info->allow_message == 'Y' || ($target_member_info->allow_message == 'F' && $oCommunicationModel->isFriend($member_srl))) + if($config->enable_message == 'Y' && ($logged_info->is_admin == 'Y' || $target_member_info->allow_message == 'Y' || ($target_member_info->allow_message == 'F' && $oCommunicationModel->isFriend($member_srl)))) { $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationSendMessage', 'receiver_srl', $member_srl), 'cmd_send_message', '', 'popup'); } // Add a menu for listing friends (if a friend is new) - if(!$oCommunicationModel->isAddedFriend($member_srl)) + if($config->enable_friend == 'Y' && !$oCommunicationModel->isAddedFriend($member_srl)) { $oMemberController->addMemberPopupMenu(getUrl('', 'mid', $mid, 'act', 'dispCommunicationAddFriend', 'target_srl', $member_srl), 'cmd_add_friend', '', 'popup'); } diff --git a/modules/communication/communication.model.php b/modules/communication/communication.model.php index 753bb2132..0055b9421 100644 --- a/modules/communication/communication.model.php +++ b/modules/communication/communication.model.php @@ -25,44 +25,44 @@ class communicationModel extends communication function getConfig() { $oModuleModel = getModel('module'); - $communication_config = $oModuleModel->getModuleConfig('communication'); + $config = $oModuleModel->getModuleConfig('communication'); - if(!is_object($communication_config)) + if(!$config->skin) { - $communication_config = new stdClass(); + $config->skin = 'default'; } - if(!$communication_config->skin) + if(!$config->colorset) { - $communication_config->skin = 'default'; + $config->colorset = 'white'; } - if(!$communication_config->colorset) + if(!$config->editor_skin) { - $communication_config->colorset = 'white'; + $config->editor_skin = 'ckeditor'; } - if(!$communication_config->editor_skin) + if(!$config->mskin) { - $communication_config->editor_skin = 'ckeditor'; + $config->mskin = 'default'; } - if(!$communication_config->mskin) + if(!$config->grant_write) { - $communication_config->mskin = 'default'; + $config->grant_write = array('default_grant' => 'member'); } - if(!$communication_config->grant_write) + if(!$config->enable_message) { - $communication_config->grant_write = array('default_grant' => 'member'); + $config->enable_message = 'Y'; + } + + if(!$config->enable_friend) + { + $config->enable_friend = 'Y'; } - if(!$communication_config->member_menu) - { - $communication_config->member_menu = 'Y'; - } - - return $communication_config; + return $config; } /** @@ -74,7 +74,7 @@ class communicationModel extends communication function getGrantArray($default, $group) { $grant = array(); - if($default!="") + if($default) { switch($default) { @@ -91,65 +91,51 @@ class communicationModel extends communication } else if(is_array($group)) { - $oMemberModel = getModel('member'); - $group_list = $oMemberModel->getGroups($this->site_srl); - $group_grant = array(); foreach($group as $group_srl) { - $group_grant[$group_srl] = $group_list[$group_srl]->title; + $group_grant[$group_srl] = true; } - $grant = array('group_grant'=>$group_grant); + + $grant = array('group_grant' => $group_grant); } + return $grant; } /** - * @brief check member's grant - * @param object $member_info + * @brief Check Write Grant * @param array $arrGrant * @return boolean */ - function checkGrant($arrGrant) + function checkWriteGrant($arrGrant) { - if(!$arrGrant) - return false; - - if(!Context::get('is_logged')) - return false; + if(!$arrGrant) return false; $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == "Y") - return true; + if($logged_info->is_admin == "Y") return true; if($arrGrant['default_grant']) { - if($arrGrant['default_grant'] == "member" && $logged_info) - return true; - - if($arrGrant['default_grant'] == "site" && $this->site_srl == $logged_info->site_srl) - return true; - - if($arrGrant['default_grant'] == "manager" && $logged_info->is_admin == "Y") - return true; + if($arrGrant['default_grant'] == "member" && Context::get('is_logged')) return true; + + if($arrGrant['default_grant'] == "site" && $this->site_srl == $logged_info->site_srl) return true; + + if($arrGrant['default_grant'] == "manager" && $logged_info->is_admin == "Y") return true; } if($arrGrant['group_grant']) { $group_grant = $arrGrant['group_grant']; - if(!is_array($group_grant)) - return false; + if(!is_array($group_grant)) return false; - foreach($logged_info->group_list as $group_srl=>$title) + foreach($logged_info->group_list as $group_srl => $title) { - if(isset($group_grant[$group_srl])&&$group_grant[$group_srl]==$title) - return true; + if($group_grant[$group_srl]) return true; } - } return false; - } /** diff --git a/modules/communication/lang/en.php b/modules/communication/lang/en.php index 4289cec4c..2c323f412 100644 --- a/modules/communication/lang/en.php +++ b/modules/communication/lang/en.php @@ -32,6 +32,8 @@ $lang->msg_disallow_message = 'Failed to send a message because the recipient bl $lang->about_allow_message = 'You can set whether to receive messages or not.'; $lang->message_notice = 'Send a message to the author about this. If you don\'t write a message, it is not sent.'; $lang->friends_page_does_not_support = 'Friends in a mobile environment is not supported. Please go to the PC page.'; -$lang->cmd_write_communication = 'Write Grant'; +$lang->communication_send_message_grant = 'Send Message Grant'; $lang->cmd_manage_base = 'Basic infomation'; $lang->alert_new_message_arrived = 'You have %d new message(s). Do you want to check it now?'; +$lang->enable_communication_friend = 'Friend Enable'; +$lang->enable_communication_message = 'Message Enable'; \ No newline at end of file diff --git a/modules/communication/lang/ko.php b/modules/communication/lang/ko.php index fc7b22f74..fa0be5d8d 100644 --- a/modules/communication/lang/ko.php +++ b/modules/communication/lang/ko.php @@ -32,6 +32,8 @@ $lang->msg_disallow_message = '쪽지 수신을 거부한 사용자라서 쪽지 $lang->about_allow_message = '쪽지 수신 여부를 결정할 수 있습니다.'; $lang->message_notice = '저작자에게 쪽지를 발송해서 이 사실을 알립니다. 작성하지 않으면 발송하지 않습니다.'; $lang->friends_page_does_not_support = '모바일 환경에서는 친구 보기 페이지를 지원하지 않습니다. PC 화면으로 이동하세요.'; -$lang->cmd_write_communication = '작성 권한'; +$lang->communication_send_message_grant = '쪽지 발송 권한'; $lang->cmd_manage_base = '기본 정보'; $lang->alert_new_message_arrived = '%d개의 새로운 메시지가 도착하였습니다. 확인하시겠습니까?'; +$lang->enable_communication_friend = '친구기능 사용'; +$lang->enable_communication_message = '쪽지기능 사용'; \ No newline at end of file diff --git a/modules/communication/tpl/index.html b/modules/communication/tpl/index.html index da496c9b0..c89cbd30d 100644 --- a/modules/communication/tpl/index.html +++ b/modules/communication/tpl/index.html @@ -20,18 +20,37 @@ +
+
{$lang->enable_communication_message}
+
+ + +
+
+
+
{$lang->enable_communication_friend}
+
+ + +
+
- +
@@ -40,7 +59,7 @@
@@ -48,7 +67,7 @@
@@ -63,7 +82,7 @@
@@ -71,7 +90,7 @@
@@ -81,39 +100,32 @@
-
- +
-
- -
- -
-
From 5d3389a6ff0fe1c7d902ed79e2fb6427e465faca Mon Sep 17 00:00:00 2001 From: conory Date: Sat, 5 Mar 2016 14:18:50 +0900 Subject: [PATCH 075/318] =?UTF-8?q?=EC=AA=BD=EC=A7=80=20=EB=B0=9C=EC=86=A1?= =?UTF-8?q?=20=EA=B6=8C=ED=95=9C=20=EC=84=A4=EC=A0=95=20=EB=8B=A4=EB=93=AC?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../communication.admin.controller.php | 33 ++-------- .../communication.controller.php | 2 +- modules/communication/communication.model.php | 60 ++++++++----------- modules/communication/tpl/index.html | 29 +++++---- 4 files changed, 50 insertions(+), 74 deletions(-) diff --git a/modules/communication/communication.admin.controller.php b/modules/communication/communication.admin.controller.php index 0b52ad2b2..fd05dcb35 100644 --- a/modules/communication/communication.admin.controller.php +++ b/modules/communication/communication.admin.controller.php @@ -24,39 +24,14 @@ class communicationAdminController extends communication function procCommunicationAdminInsertConfig() { // get the default information - $args = Context::gets('enable_message', 'enable_friend', 'skin', 'colorset', 'editor_skin', 'sel_editor_colorset', 'mskin', 'mcolorset', 'layout_srl', 'mlayout_srl', 'grant_write_default','grant_write_group'); + $args = Context::gets('enable_message', 'enable_friend', 'skin', 'colorset', 'editor_skin', 'sel_editor_colorset', 'mskin', 'mcolorset', 'layout_srl', 'mlayout_srl', 'grant_send_default','grant_send_group'); $args->editor_colorset = $args->sel_editor_colorset; unset($args->sel_editor_colorset); - if(!$args->skin) - { - $args->skin = 'default'; - } - - if(!$args->colorset) - { - $args->colorset = 'white'; - } - - if(!$args->editor_skin) - { - $args->editor_skin = 'default'; - } - - if(!$args->mskin) - { - $args->mskin = 'default'; - } - - if(!$args->layout_srl) - { - $args->layout_srl = NULL; - } - $oCommunicationModel = getModel('communication'); - $args->grant_write = $oCommunicationModel->getGrantArray($args->grant_write_default, $args->grant_write_group); - unset($args->grant_write_default); - unset($args->grant_write_group); + $args->grant_send = $oCommunicationModel->getGrantArray($args->grant_send_default, $args->grant_send_group); + unset($args->grant_send_default); + unset($args->grant_send_group); // create the module module Controller object $oModuleController = getController('module'); diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 65c4295cb..b45dd42e6 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -89,7 +89,7 @@ class communicationController extends communication $oCommunicationModel = getModel('communication'); $config = $oCommunicationModel->getConfig(); - if(!$oCommunicationModel->checkWriteGrant($config->grant_write)) + if(!$oCommunicationModel->checkGrant($config->grant_send)) { return new Object(-1, 'msg_not_permitted'); } diff --git a/modules/communication/communication.model.php b/modules/communication/communication.model.php index 0055b9421..b4bb6974c 100644 --- a/modules/communication/communication.model.php +++ b/modules/communication/communication.model.php @@ -46,10 +46,10 @@ class communicationModel extends communication { $config->mskin = 'default'; } - - if(!$config->grant_write) + + if(!$config->grant_send) { - $config->grant_write = array('default_grant' => 'member'); + $config->grant_send = array('default' => 'member'); } if(!$config->enable_message) @@ -76,62 +76,54 @@ class communicationModel extends communication $grant = array(); if($default) { - switch($default) - { - case "-2": - $grant = array("default_grant"=>"site"); - break; - case "-3": - $grant = array("default_grant"=>"manager"); - break; - default : - $grant = array("default_grant"=>"member"); - break; - } - } + $grant = array('default' => $default); + } else if(is_array($group)) { - $group_grant = array(); + $grant_group = array(); foreach($group as $group_srl) { - $group_grant[$group_srl] = true; + $grant_group[$group_srl] = true; } - $grant = array('group_grant' => $group_grant); + $grant = array('group' => $grant_group); } return $grant; } /** - * @brief Check Write Grant + * @brief Check Grant * @param array $arrGrant * @return boolean */ - function checkWriteGrant($arrGrant) + function checkGrant($arrGrant) { if(!$arrGrant) return false; $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == "Y") return true; + if($logged_info->is_admin == 'Y') return true; - if($arrGrant['default_grant']) + if($arrGrant['default']) { - if($arrGrant['default_grant'] == "member" && Context::get('is_logged')) return true; - - if($arrGrant['default_grant'] == "site" && $this->site_srl == $logged_info->site_srl) return true; - - if($arrGrant['default_grant'] == "manager" && $logged_info->is_admin == "Y") return true; + if($arrGrant['default'] == 'member') + { + if(Context::get('is_logged')) return true; + } + else if($arrGrant['default'] == 'site') + { + if($this->site_srl == $logged_info->site_srl) return true; + } + else if($arrGrant['default'] == 'manager') + { + if($logged_info->is_admin == 'Y') return true; + } } - - if($arrGrant['group_grant']) + else if(is_array($arrGrant['group'])) { - $group_grant = $arrGrant['group_grant']; - if(!is_array($group_grant)) return false; - foreach($logged_info->group_list as $group_srl => $title) { - if($group_grant[$group_srl]) return true; + if(isset($arrGrant['group'][$group_srl])) return true; } } diff --git a/modules/communication/tpl/index.html b/modules/communication/tpl/index.html index c89cbd30d..4f3909820 100644 --- a/modules/communication/tpl/index.html +++ b/modules/communication/tpl/index.html @@ -101,18 +101,27 @@
+
+ +
+ + + + + + + +
+
- +

{$lang->about_debug_log_filename}

From 96154c8430595edcbe5b6f3aae01a2fc5c7627a3 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 6 Mar 2016 14:50:55 +0900 Subject: [PATCH 081/318] Add option to auto-select the language --- classes/context/Context.class.php | 29 +++++++++++++++++------- common/defaults/config.php | 1 + modules/admin/admin.admin.controller.php | 1 + modules/admin/admin.admin.view.php | 1 + modules/admin/lang/en.php | 6 +++-- modules/admin/lang/ko.php | 2 ++ modules/admin/tpl/config_general.html | 15 ++++++++++++ 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 3be9dc4d9..4b920d2fa 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -275,7 +275,7 @@ class Context if($this->lang_type = self::get('l')) { - if($_COOKIE['lang_type'] != $this->lang_type) + if($_COOKIE['lang_type'] !== $this->lang_type) { setcookie('lang_type', $this->lang_type, $_SERVER['REQUEST_TIME'] + 3600 * 24 * 1000, '/'); } @@ -284,18 +284,31 @@ class Context { $this->lang_type = $_COOKIE['lang_type']; } - elseif($site_module_info->default_language) + elseif(config('locale.auto_select_lang') && count($enabled_langs) > 1) { - $this->lang_type = $this->db_info->lang_type = $site_module_info->default_language; - } - else - { - $this->lang_type = $this->db_info->lang_type; + if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) + { + foreach($enabled_langs as $lang_code => $lang_name) + { + if(!strncasecmp($lang_code, $_SERVER['HTTP_ACCEPT_LANGUAGE'], strlen($lang_code))) + { + $this->lang_type = $lang_code; + setcookie('lang_type', $this->lang_type, $_SERVER['REQUEST_TIME'] + 3600 * 24 * 1000, '/'); + } + } + } } if(!$this->lang_type || !isset($enabled_langs[$this->lang_type])) { - $this->lang_type = 'ko'; + if($site_module_info->default_language) + { + $this->lang_type = $this->db_info->lang_type = $site_module_info->default_language; + } + else + { + $this->lang_type = $this->db_info->lang_type ?: 'ko'; + } } self::setLangType($this->lang_type); diff --git a/common/defaults/config.php b/common/defaults/config.php index 2262d7be6..0fc4fe801 100644 --- a/common/defaults/config.php +++ b/common/defaults/config.php @@ -38,6 +38,7 @@ return array( 'locale' => array( 'default_lang' => 'ko', 'enabled_lang' => array('ko'), + 'auto_select_lang' => false, 'default_timezone' => 'Asia/Seoul', 'internal_timezone' => 32400, ), diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index ac1a17e96..ba86b8776 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -529,6 +529,7 @@ class adminAdminController extends admin } Rhymix\Framework\Config::set('locale.default_lang', $vars->default_lang); Rhymix\Framework\Config::set('locale.enabled_lang', array_values($enabled_lang)); + Rhymix\Framework\Config::set('locale.auto_select_lang', $vars->auto_select_lang === 'Y'); // Default time zone Rhymix\Framework\Config::set('locale.default_timezone', $vars->default_timezone); diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index 8823175fd..fbe68f961 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -376,6 +376,7 @@ class adminAdminView extends admin Context::set('supported_lang', Rhymix\Framework\Lang::getSupportedList()); Context::set('default_lang', Rhymix\Framework\Config::get('locale.default_lang')); Context::set('enabled_lang', Rhymix\Framework\Config::get('locale.enabled_lang')); + Context::set('auto_select_lang', Rhymix\Framework\Config::get('locale.auto_select_lang')); // Site title and HTML footer $oModuleModel = getModel('module'); diff --git a/modules/admin/lang/en.php b/modules/admin/lang/en.php index 74b9d76f3..56f8880cf 100644 --- a/modules/admin/lang/en.php +++ b/modules/admin/lang/en.php @@ -65,8 +65,10 @@ $lang->about_lang_env = 'If you want to make the language setting same for first $lang->xe_license = 'Rhymix complies with the GPL.'; $lang->yesterday = 'Yesterday'; $lang->today = 'Today'; -$lang->default_lang = 'Select default language.'; -$lang->lang_select = 'Select the supporting language(s).'; +$lang->default_lang = 'Default Language'; +$lang->lang_select = 'Supported Languages'; +$lang->auto_select_lang = 'Auto-select Language'; +$lang->about_auto_select_lang = 'Automatically select the language based on the language of each visitor\'s browser.'; $lang->about_recompile_cache = 'Delete useless or invalid cache files?'; $lang->confirm_run = 'It may take a long time. Do you want to run?'; $lang->use_ssl = 'Use SSL'; diff --git a/modules/admin/lang/ko.php b/modules/admin/lang/ko.php index 0c3f720cb..e48a7a977 100644 --- a/modules/admin/lang/ko.php +++ b/modules/admin/lang/ko.php @@ -67,6 +67,8 @@ $lang->yesterday = '어제'; $lang->today = '오늘'; $lang->default_lang = '기본 언어 선택'; $lang->lang_select = '지원 언어 선택'; +$lang->auto_select_lang = '언어 자동 선택'; +$lang->about_auto_select_lang = '방문자의 브라우저 언어에 따라 자동으로 언어를 선택하는 기능입니다.'; $lang->about_recompile_cache = '쓸모 없어졌거나 잘못된 캐시파일들을 지우시겠습니까?'; $lang->confirm_run = '오랜 시간이 걸릴 수 있습니다. 실행하시겠습니까?'; $lang->use_ssl = 'SSL 사용'; diff --git a/modules/admin/tpl/config_general.html b/modules/admin/tpl/config_general.html index 3fa98f0d6..b8ec076f2 100644 --- a/modules/admin/tpl/config_general.html +++ b/modules/admin/tpl/config_general.html @@ -45,6 +45,21 @@ +
+ +
+ + +
+

{$lang->about_auto_select_lang}

+
+
From c0210dc5248b40dd6081b79ad57964f28573393f Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 6 Mar 2016 14:57:40 +0900 Subject: [PATCH 082/318] Always treat member_communication addon as activated --- modules/addon/addon.admin.model.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/addon/addon.admin.model.php b/modules/addon/addon.admin.model.php index 15ae24c50..1769b445c 100644 --- a/modules/addon/addon.admin.model.php +++ b/modules/addon/addon.admin.model.php @@ -451,6 +451,21 @@ class addonAdminModel extends addon */ function isActivatedAddon($addon, $site_srl = 0, $type = "pc", $gtype = 'site') { + $always_return_true_for_compatibility = array( + 'member_communication' => true, + ); + $always_return_false_for_compatibility = array( + ); + + if(isset($always_return_true_for_compatibility[$addon])) + { + return true; + } + if(isset($always_return_false_for_compatibility[$addon])) + { + return false; + } + $args = new stdClass(); $args->addon = $addon; if($gtype == 'global') From fc09ea0d47466e8d6280ca1c2abc8f7373643248 Mon Sep 17 00:00:00 2001 From: conory Date: Sun, 6 Mar 2016 16:35:01 +0900 Subject: [PATCH 083/318] =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0?= =?UTF-8?q?=EC=97=86=EC=9D=B4=20lang()=ED=95=A8=EC=88=98=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=20=ED=98=84=EC=9E=AC=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EA=B3=A0=20=EC=9E=88=EB=8A=94=20=EC=96=B8=EC=96=B4?= =?UTF-8?q?=ED=83=80=EC=9E=85=20=EB=B0=98=ED=99=98=20lang=20=EC=97=90=20se?= =?UTF-8?q?t=20=EB=A9=94=EC=86=8C=EB=93=9C=EB=A5=BC=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=A8=20(=EC=8B=A4=EC=A0=9C=EB=A1=9C=20set=EC=9D=B4=20?= =?UTF-8?q?=EB=90=98=EC=A7=80=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=EC=88=98=EC=A0=95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/framework/lang.php | 22 ++++++++++++++++++++++ common/functions.php | 10 +++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index fbddd57a9..d8c678cf0 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -50,6 +50,16 @@ class Lang $this->_loaded_plugins['_custom_'] = new \stdClass(); } + /** + * Return language type. + * + * @return string + */ + public function langType() + { + return $this->_language; + } + /** * Load translations from a plugin (module, addon). * @@ -187,6 +197,18 @@ class Lang return $this->__call($key, $args); } + /** + * Generic setter. + * + * @param string $key + * @param string $value + * @return void + */ + public function set($key, $value) + { + $this->__set($key, $value); + } + /** * Magic method for translations without arguments. * diff --git a/common/functions.php b/common/functions.php index 154d60455..388e8d78e 100644 --- a/common/functions.php +++ b/common/functions.php @@ -32,7 +32,7 @@ function config($key, $value = null) * @param string $value `$code`s value * @return mixed */ -function lang($code, $value = null) +function lang($code = null, $value = null) { if (!$GLOBALS['lang'] instanceof Rhymix\Framework\Lang) { @@ -40,14 +40,18 @@ function lang($code, $value = null) $GLOBALS['lang']->loadDirectory(RX_BASEDIR . 'common/lang', 'common'); } - if ($value === null) + if ($code !== null && $value === null) { return $GLOBALS['lang']->get($code); } - else + else if ($code !== null && $value !== null) { $GLOBALS['lang']->set($code, $value); } + else + { + return $GLOBALS['lang']->langType(); + } } /** From 90400e2b5f8dbd7480008b8b5f943de8e856cd42 Mon Sep 17 00:00:00 2001 From: conory Date: Sun, 6 Mar 2016 17:01:15 +0900 Subject: [PATCH 084/318] =?UTF-8?q?=EB=AA=A8=EB=91=90=20lang()=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/captcha/captcha.addon.php | 14 ++--- .../captcha_member/captcha_member.addon.php | 14 ++--- addons/mobile/classes/hdml.class.php | 2 +- addons/mobile/classes/mhtml.class.php | 4 +- addons/mobile/classes/mobile.class.php | 18 +++--- addons/mobile/classes/wml.class.php | 4 +- .../point_level_icon/point_level_icon.lib.php | 4 +- classes/extravar/Extravar.class.php | 2 +- classes/module/ModuleHandler.class.php | 2 +- classes/object/Object.class.php | 2 +- classes/validator/Validator.class.php | 4 +- common/framework/debug.php | 4 +- common/legacy.php | 8 +-- layouts/xedition/layout.html | 2 +- modules/admin/admin.admin.controller.php | 10 ++-- modules/admin/admin.admin.model.php | 4 +- modules/autoinstall/autoinstall.lib.php | 14 ++--- modules/board/board.admin.model.php | 6 +- modules/board/board.admin.view.php | 8 +-- modules/board/board.controller.php | 8 +-- modules/board/board.mobile.php | 2 +- modules/board/board.model.php | 4 +- modules/board/board.view.php | 18 +++--- modules/board/board.wap.php | 14 ++--- modules/comment/comment.admin.controller.php | 2 +- modules/comment/comment.controller.php | 6 +- modules/comment/comment.item.php | 6 +- modules/comment/comment.model.php | 4 +- .../communication.controller.php | 2 +- .../skins/default/common_header.html | 2 +- .../document/document.admin.controller.php | 2 +- modules/document/document.admin.view.php | 2 +- modules/document/document.controller.php | 12 ++-- modules/document/document.item.php | 6 +- modules/document/document.model.php | 4 +- modules/editor/editor.controller.php | 4 +- modules/editor/editor.model.php | 4 +- modules/editor/editor.view.php | 2 +- modules/file/file.admin.controller.php | 2 +- modules/file/file.model.php | 6 +- .../importer/importer.admin.controller.php | 4 +- modules/install/install.controller.php | 4 +- modules/install/install.model.php | 2 +- modules/install/install.view.php | 2 +- modules/layout/layout.admin.controller.php | 10 ++-- modules/layout/layout.admin.view.php | 2 +- modules/layout/layout.model.php | 4 +- modules/layout/layout.view.php | 12 ++-- .../member/m.skins/default/common_header.html | 2 +- .../member/m.skins/default/leave_form.html | 2 +- .../m.skins/default/modify_password.html | 2 +- modules/member/member.admin.controller.php | 2 +- modules/member/member.admin.view.php | 2 +- modules/member/member.class.php | 10 ++-- modules/member/member.controller.php | 60 +++++++++---------- modules/member/member.model.php | 4 +- modules/member/member.view.php | 6 +- .../member/skins/default/common_header.html | 2 +- modules/member/skins/default/leave_form.html | 2 +- .../member/skins/default/modify_password.html | 2 +- modules/menu/menu.admin.controller.php | 4 +- modules/menu/menu.admin.model.php | 4 +- modules/module/module.admin.controller.php | 2 +- modules/module/module.admin.model.php | 12 ++-- modules/module/module.admin.view.php | 4 +- modules/module/module.model.php | 2 +- modules/page/page.wap.php | 2 +- modules/point/point.admin.controller.php | 4 +- modules/point/point.controller.php | 2 +- modules/point/tpl/member_list.html | 6 +- modules/poll/poll.admin.controller.php | 2 +- modules/poll/poll.model.php | 4 +- modules/rss/rss.admin.controller.php | 2 +- modules/rss/rss.view.php | 2 +- modules/session/session.admin.controller.php | 2 +- .../spamfilter.admin.controller.php | 12 ++-- modules/spamfilter/spamfilter.model.php | 6 +- modules/widget/widget.controller.php | 14 ++--- .../skins/xe_global/login_info.html | 2 +- .../skins/xe_globalTwo/login_info.html | 2 +- .../skins/xe_official/login_info.html | 2 +- .../xe_solid_enterprise_login/login_info.html | 2 +- 82 files changed, 234 insertions(+), 234 deletions(-) diff --git a/addons/captcha/captcha.addon.php b/addons/captcha/captcha.addon.php index 128aa917d..9c12f9b01 100644 --- a/addons/captcha/captcha.addon.php +++ b/addons/captcha/captcha.addon.php @@ -62,7 +62,7 @@ if(!class_exists('AddonCaptcha', false)) { Context::loadLang(_XE_PATH_ . 'addons/captcha/lang'); $_SESSION['XE_VALIDATOR_ERROR'] = -1; - $_SESSION['XE_VALIDATOR_MESSAGE'] = Context::getLang('captcha_denied'); + $_SESSION['XE_VALIDATOR_MESSAGE'] = lang('captcha_denied'); $_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = 'error'; $_SESSION['XE_VALIDATOR_RETURN_URL'] = Context::get('error_return_url'); $ModuleHandler->_setInputValueToSession(); @@ -113,7 +113,7 @@ if(!class_exists('AddonCaptcha', false)) // Generate keywords $this->createKeyword(); - $target = Context::getLang('target_captcha'); + $target = lang('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"); @@ -121,11 +121,11 @@ if(!class_exists('AddonCaptcha', false)) 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') + , lang('about_captcha') + , lang('captcha_reload') + , lang('captcha_play') + , lang('cmd_input') + , lang('cmd_cancel') ); Context::close(); exit(); diff --git a/addons/captcha_member/captcha_member.addon.php b/addons/captcha_member/captcha_member.addon.php index 3d5471a13..feeded237 100644 --- a/addons/captcha_member/captcha_member.addon.php +++ b/addons/captcha_member/captcha_member.addon.php @@ -73,7 +73,7 @@ if(!class_exists('AddonMemberCaptcha', false)) { Context::loadLang(_XE_PATH_ . 'addons/captcha_member/lang'); $_SESSION['XE_VALIDATOR_ERROR'] = -1; - $_SESSION['XE_VALIDATOR_MESSAGE'] = Context::getLang('captcha_denied'); + $_SESSION['XE_VALIDATOR_MESSAGE'] = lang('captcha_denied'); $_SESSION['XE_VALIDATOR_MESSAGE_TYPE'] = 'error'; $_SESSION['XE_VALIDATOR_RETURN_URL'] = Context::get('error_return_url'); $ModuleHandler->_setInputValueToSession(); @@ -124,7 +124,7 @@ if(!class_exists('AddonMemberCaptcha', false)) // Generate keywords $this->createKeyword(); - $target = Context::getLang('target_captcha'); + $target = lang('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"); @@ -132,11 +132,11 @@ if(!class_exists('AddonMemberCaptcha', false)) 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') + , lang('about_captcha') + , lang('captcha_reload') + , lang('captcha_play') + , lang('cmd_input') + , lang('cmd_cancel') ); Context::close(); exit(); diff --git a/addons/mobile/classes/hdml.class.php b/addons/mobile/classes/hdml.class.php index 7e67ce3f5..69205f741 100644 --- a/addons/mobile/classes/hdml.class.php +++ b/addons/mobile/classes/hdml.class.php @@ -55,7 +55,7 @@ class wap extends mobileXE { foreach($this->getChilds() as $key => $val) { if(!$val['link']) continue; - printf('%s%s',Context::getLang('cmd_select'), $val['href'], $val['text'], "\n"); + printf('%s%s',lang('cmd_select'), $val['href'], $val['text'], "\n"); } } else diff --git a/addons/mobile/classes/mhtml.class.php b/addons/mobile/classes/mhtml.class.php index 250878d11..34a9fe19b 100644 --- a/addons/mobile/classes/mhtml.class.php +++ b/addons/mobile/classes/mhtml.class.php @@ -71,11 +71,11 @@ class wap extends mobileXE 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"); + printf('%s
%s', $url, 'Language : '.lang('select_lang'), "\n"); } else { - printf('%s
%s', Context::get('return_uri'), Context::getLang('lang_return'), "\n"); + printf('%s
%s', Context::get('return_uri'), lang('lang_return'), "\n"); } if($this->upperUrl) { diff --git a/addons/mobile/classes/mobile.class.php b/addons/mobile/classes/mobile.class.php index 53951e99e..946e5d7ea 100644 --- a/addons/mobile/classes/mobile.class.php +++ b/addons/mobile/classes/mobile.class.php @@ -168,12 +168,12 @@ class mobileXE if($parent_srl && $listed_items[$parent_srl]) { $parent_item = $listed_items[$parent_srl]; - if($parent_item) $this->setUpperUrl(getUrl('','mid',$parent_item['mid']), Context::getLang('cmd_go_upper')); + if($parent_item) $this->setUpperUrl(getUrl('','mid',$parent_item['mid']), lang('cmd_go_upper')); } } elseif (!$this->isNavigationMode()) { - $this->setUpperUrl(getUrl('','mid',$this->index_mid,'nm','1','cmid',0), Context::getLang('cmd_view_sitemap')); + $this->setUpperUrl(getUrl('','mid',$this->index_mid,'nm','1','cmid',0), lang('cmd_view_sitemap')); } } @@ -247,14 +247,14 @@ class mobileXE if($this->mobilePage>1) { $url = getUrl('mid',$_GET['mid'],'mpage',$this->mobilePage-1); - $text = sprintf('%s (%d/%d)', Context::getLang('cmd_prev'), $this->mobilePage-1, $this->totalPage); + $text = sprintf('%s (%d/%d)', lang('cmd_prev'), $this->mobilePage-1, $this->totalPage); $this->setPrevUrl($url, $text); } if($this->mobilePage<$this->totalPage) { $url = getUrl('mid',$_GET['mid'],'mpage',$this->mobilePage+1); - $text = sprintf('%s (%d/%d)', Context::getLang('cmd_next'), $this->mobilePage+1, $this->totalPage); + $text = sprintf('%s (%d/%d)', lang('cmd_next'), $this->mobilePage+1, $this->totalPage); $this->setNextUrl($url, $text); } } @@ -353,14 +353,14 @@ class mobileXE if($this->mobilePage>1) { $url = getUrl('mid',$_GET['mid'],'mpage',$this->mobilePage-1); - $text = sprintf('%s (%d/%d)', Context::getLang('cmd_prev'), $this->mobilePage-1, $this->totalPage); + $text = sprintf('%s (%d/%d)', lang('cmd_prev'), $this->mobilePage-1, $this->totalPage); $this->setPrevUrl($url, $text); } if($this->mobilePage<$this->totalPage) { $url = getUrl('mid',$_GET['mid'],'mpage',$this->mobilePage+1); - $text = sprintf('%s (%d/%d)', Context::getLang('cmd_next'), $this->mobilePage+1, $this->totalPage); + $text = sprintf('%s (%d/%d)', lang('cmd_next'), $this->mobilePage+1, $this->totalPage); $this->setNextUrl($url, $text); } @@ -442,7 +442,7 @@ class mobileXE function display() { // Home button assignments - $this->setHomeUrl(getUrl(), Context::getLang('cmd_go_home')); + $this->setHomeUrl(getUrl(), lang('cmd_go_home')); // Specify the title if(!$this->title) $this->setTitle(Context::getBrowserTitle()); @@ -520,7 +520,7 @@ class mobileXE $cur_item = $this->listed_items[$this->cmid]; $upper_srl = $cur_item['parent_srl'];; $list = $cur_item['list'];; - $this->setUpperUrl(getUrl('cmid',$upper_srl), Context::getLang('cmd_go_upper')); + $this->setUpperUrl(getUrl('cmid',$upper_srl), lang('cmd_go_upper')); if(preg_match('/^([a-zA-Z0-9\_\-]+)$/', $cur_item['url'])) { $obj = array(); @@ -575,7 +575,7 @@ class mobileXE $lang_supported = Context::get('lang_supported'); $lang_type = Context::getLangType(); $obj = array(); - $obj['link'] = $obj['text'] = Context::getLang('president_lang').' : '.$lang_supported[$lang_type]; + $obj['link'] = $obj['text'] = lang('president_lang').' : '.$lang_supported[$lang_type]; $obj['href'] = getUrl('sel_lang',$lang_type); $childs[] = $obj; diff --git a/addons/mobile/classes/wml.class.php b/addons/mobile/classes/wml.class.php index d46c976a7..644e5d4b9 100644 --- a/addons/mobile/classes/wml.class.php +++ b/addons/mobile/classes/wml.class.php @@ -87,11 +87,11 @@ class wap extends mobileXE 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"); + printf('%s', 'Language : '.lang('select_lang'), $url, "\n"); } else { - printf('%s', Context::getLang('lang_return'), Context::get('return_uri'), "\n"); + printf('%s', lang('lang_return'), Context::get('return_uri'), "\n"); } if($this->homeUrl) { diff --git a/addons/point_level_icon/point_level_icon.lib.php b/addons/point_level_icon/point_level_icon.lib.php index 2e6c6ff7c..97b40f98b 100644 --- a/addons/point_level_icon/point_level_icon.lib.php +++ b/addons/point_level_icon/point_level_icon.lib.php @@ -70,8 +70,8 @@ function pointLevelIconTrans($matches, $addon_info) } } - $title = sprintf('%s:%s%s%s, %s:%s/%s', Context::getLang('point'), $point, $config->point_name, $per ? ' (' . $per . ')' : '', Context::getLang('level'), $level, $config->max_level); - $alt = sprintf('[%s:%s]', Context::getLang('level'), $level); + $title = sprintf('%s:%s%s%s, %s:%s/%s', lang('point'), $point, $config->point_name, $per ? ' (' . $per . ')' : '', lang('level'), $level, $config->max_level); + $alt = sprintf('[%s:%s]', lang('level'), $level); $GLOBALS['_pointLevelIcon'][$member_srl] = sprintf('%s', $level_icon, $alt, $title); } diff --git a/classes/extravar/Extravar.class.php b/classes/extravar/Extravar.class.php index 3960d4d94..ee70691f4 100644 --- a/classes/extravar/Extravar.class.php +++ b/classes/extravar/Extravar.class.php @@ -445,7 +445,7 @@ class ExtraItem $buff[] = ''; $buff[] = ''; - $buff[] = ''; + $buff[] = ''; $buff[] = '', Context::getLang($message)); + $script = sprintf('', lang($message)); Context::addHtmlHeader( $script ); } } diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index b70f9ee7c..bfcaca55c 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -131,7 +131,7 @@ class boardController extends board { if($oDocument->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_document'); + $format = lang('msg_protect_regdate_document'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -234,7 +234,7 @@ class boardController extends board { if($oDocument->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_document'); + $format = lang('msg_protect_regdate_document'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -385,7 +385,7 @@ class boardController extends board { if($comment->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_comment'); + $format = lang('msg_protect_regdate_comment'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -438,7 +438,7 @@ class boardController extends board { if($comment->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_comment'); + $format = lang('msg_protect_regdate_comment'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } diff --git a/modules/board/board.mobile.php b/modules/board/board.mobile.php index 6223d2d6a..a036a0156 100644 --- a/modules/board/board.mobile.php +++ b/modules/board/board.mobile.php @@ -105,7 +105,7 @@ class boardMobile extends boardView function dispBoardMessage($msg_code) { - $msg = Context::getLang($msg_code); + $msg = lang($msg_code); $oMessageObject = &ModuleHandler::getModuleInstance('message','mobile'); $oMessageObject->setError(-1); $oMessageObject->setMessage($msg); diff --git a/modules/board/board.model.php b/modules/board/board.model.php index 002632f2e..ef2fa52d3 100644 --- a/modules/board/board.model.php +++ b/modules/board/board.model.php @@ -48,7 +48,7 @@ class boardModel extends module } else { - $output[$key] = new ExtraItem($module_srl, -1, Context::getLang($key), $key, 'N', 'N', 'N', null); + $output[$key] = new ExtraItem($module_srl, -1, lang($key), $key, 'N', 'N', 'N', null); } } return $output; @@ -64,7 +64,7 @@ class boardModel extends module 'user_id', 'user_name', 'readed_count', 'voted_count', 'blamed_count', 'thumbnail', 'summary', 'comment_status'); foreach($virtual_vars as $key) { - $extra_vars[$key] = new ExtraItem($module_srl, -1, Context::getLang($key), $key, 'N', 'N', 'N', null); + $extra_vars[$key] = new ExtraItem($module_srl, -1, lang($key), $key, 'N', 'N', 'N', null); } // get the extra variables from the document model diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 1e45f6978..b28836f1d 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -160,7 +160,7 @@ class boardView extends board * add extra vaiables to the search options **/ // use search options on the template (the search options key has been declared, based on the language selected) - foreach($this->search_option as $opt) $search_option[$opt] = Context::getLang($opt); + foreach($this->search_option as $opt) $search_option[$opt] = lang($opt); $extra_keys = Context::get('extra_keys'); if($extra_keys) { @@ -328,7 +328,7 @@ class boardView extends board // disappear the document if it is secret if($oDocument->isSecret() && !$oDocument->isGranted()) { - $oDocument->add('content',Context::getLang('thisissecret')); + $oDocument->add('content',lang('thisissecret')); } } } @@ -432,7 +432,7 @@ class boardView extends board { if(!$val->isAccessible()) { - $val->add('content',Context::getLang('thisissecret')); + $val->add('content',lang('thisissecret')); } } } @@ -700,7 +700,7 @@ class boardView extends board { if($oDocument->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_document'); + $format = lang('msg_protect_regdate_document'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -827,7 +827,7 @@ class boardView extends board { if($oDocument->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_document'); + $format = lang('msg_protect_regdate_document'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -989,7 +989,7 @@ class boardView extends board { if($oComment->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_comment'); + $format = lang('msg_protect_regdate_comment'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -1057,7 +1057,7 @@ class boardView extends board { if($oComment->get('regdate') < date('YmdHis', strtotime('-'.$this->module_info->protect_document_regdate.' day'))) { - $format = Context::getLang('msg_protect_regdate_comment'); + $format = lang('msg_protect_regdate_comment'); $massage = sprintf($format, $this->module_info->protect_document_regdate); return new Object(-1, $massage); } @@ -1136,7 +1136,7 @@ class boardView extends board **/ function dispBoardMessage($msg_code) { - $msg = Context::getLang($msg_code); + $msg = lang($msg_code); if(!$msg) $msg = $msg_code; Context::set('message', $msg); $this->setTemplateFile('message'); @@ -1186,7 +1186,7 @@ class boardView extends board **/ function alertMessage($message) { - $script = sprintf('', Context::getLang($message)); + $script = sprintf('', lang($message)); Context::addHtmlFooter( $script ); } diff --git a/modules/board/board.wap.php b/modules/board/board.wap.php index 53e64ac96..10d06f85f 100644 --- a/modules/board/board.wap.php +++ b/modules/board/board.wap.php @@ -17,7 +17,7 @@ class boardWAP extends board // check grant if(!$this->grant->list || $this->module_info->consultation == 'Y') { - return $oMobile->setContent(Context::getLang('msg_not_permitted')); + return $oMobile->setContent(lang('msg_not_permitted')); } // generate document model object @@ -33,7 +33,7 @@ class boardWAP extends board // check the grant if(!$this->grant->view) { - return $oMobile->setContent(Context::getLang('msg_not_permitted')); + return $oMobile->setContent(lang('msg_not_permitted')); } // setup the browser title @@ -64,7 +64,7 @@ class boardWAP extends board $oMobile->setContent( $content ); // setup upper URL - $oMobile->setUpperUrl( getUrl('act',''), Context::getLang('cmd_go_upper') ); + $oMobile->setUpperUrl( getUrl('act',''), lang('cmd_go_upper') ); // display the document if the act is not display the comment list } else { @@ -74,14 +74,14 @@ class boardWAP extends board // setup content information(include the comments link) - $content = Context::getLang('replies').' : '.$oDocument->getCommentCount().'
'."\r\n".$content; + $content = lang('replies').' : '.$oDocument->getCommentCount().'
'."\r\n".$content; $content = ''.$oDocument->getNickName().' ('.$oDocument->getRegdate("Y-m-d").")
\r\n".$content; // setup mobile contents $oMobile->setContent( $content ); // setup upper URL - $oMobile->setUpperUrl( getUrl('document_srl',''), Context::getLang('cmd_list') ); + $oMobile->setUpperUrl( getUrl('document_srl',''), lang('cmd_list') ); } @@ -124,12 +124,12 @@ class boardWAP extends board // next/prevUrl specification if($page > 1) { - $oMobile->setPrevUrl(getUrl('mid',$_GET['mid'],'page',$page-1), sprintf('%s (%d/%d)', Context::getLang('cmd_prev'), $page-1, $totalPage)); + $oMobile->setPrevUrl(getUrl('mid',$_GET['mid'],'page',$page-1), sprintf('%s (%d/%d)', lang('cmd_prev'), $page-1, $totalPage)); } if($page < $totalPage) { - $oMobile->setNextUrl(getUrl('mid',$_GET['mid'],'page',$page+1), sprintf('%s (%d/%d)', Context::getLang('cmd_next'), $page+1, $totalPage)); + $oMobile->setNextUrl(getUrl('mid',$_GET['mid'],'page',$page+1), sprintf('%s (%d/%d)', lang('cmd_next'), $page+1, $totalPage)); } $oMobile->mobilePage = $page; diff --git a/modules/comment/comment.admin.controller.php b/modules/comment/comment.admin.controller.php index da6d95a78..40fd69af3 100644 --- a/modules/comment/comment.admin.controller.php +++ b/modules/comment/comment.admin.controller.php @@ -267,7 +267,7 @@ class commentAdminController extends comment { $msgCode = 'success_deleted'; } - //$this->setMessage( sprintf(Context::getLang('msg_checked_comment_is_deleted'), $deleted_count) ); + //$this->setMessage( sprintf(lang('msg_checked_comment_is_deleted'), $deleted_count) ); $this->setMessage($msgCode, 'info'); //set url params diff --git a/modules/comment/comment.controller.php b/modules/comment/comment.controller.php index 5ba090ca2..5c073722b 100644 --- a/modules/comment/comment.controller.php +++ b/modules/comment/comment.controller.php @@ -207,7 +207,7 @@ class commentController extends comment // if an user select message from options, message would be the option. $message_option = strval(Context::get('message_option')); - $improper_comment_reasons = Context::getLang('improper_comment_reasons'); + $improper_comment_reasons = lang('improper_comment_reasons'); $declare_message = ($message_option !== 'others' && isset($improper_comment_reasons[$message_option]))? $improper_comment_reasons[$message_option] : trim(Context::get('declare_message')); @@ -594,7 +594,7 @@ class commentController extends comment if(!$manual_inserted) { // send a message if notify_message option in enabled in the original article - $oDocument->notify(Context::getLang('comment'), $obj->content); + $oDocument->notify(lang('comment'), $obj->content); // send a message if notify_message option in enabled in the original comment if($obj->parent_srl) @@ -602,7 +602,7 @@ class commentController extends comment $oParent = $oCommentModel->getComment($obj->parent_srl); if($oParent->get('member_srl') != $oDocument->get('member_srl')) { - $oParent->notify(Context::getLang('comment'), $obj->content); + $oParent->notify(lang('comment'), $obj->content); } } } diff --git a/modules/comment/comment.item.php b/modules/comment/comment.item.php index 744d17994..4b1906f4a 100644 --- a/modules/comment/comment.item.php +++ b/modules/comment/comment.item.php @@ -312,7 +312,7 @@ class commentItem extends Object { if($this->isSecret() && !$this->isAccessible()) { - return Context::getLang('msg_is_secret'); + return lang('msg_is_secret'); } $content = $this->get('content'); @@ -333,7 +333,7 @@ class commentItem extends Object { if($this->isSecret() && !$this->isAccessible()) { - return Context::getLang('msg_is_secret'); + return lang('msg_is_secret'); } $content = $this->get('content'); @@ -343,7 +343,7 @@ class commentItem extends Object if($add_popup_menu && Context::get('is_logged')) { $content = sprintf( - '%s', $content, $this->comment_srl, Context::getLang('cmd_comment_do') + '%s', $content, $this->comment_srl, lang('cmd_comment_do') ); } diff --git a/modules/comment/comment.model.php b/modules/comment/comment.model.php index 09ca6be0f..1a2def9d5 100644 --- a/modules/comment/comment.model.php +++ b/modules/comment/comment.model.php @@ -77,7 +77,7 @@ class commentModel extends comment ModuleHandler::triggerCall('comment.getCommentMenu', 'after', $menu_list); if($this->grant->manager){ - $str_confirm = Context::getLang('confirm_move'); + $str_confirm = lang('confirm_move'); $url = sprintf("if(!confirm('%s')) return; var params = new Array(); params['comment_srl']='%s'; params['mid']=current_mid;params['cur_url']=current_url; exec_xml('comment', 'procCommentAdminMoveToTrash', params)", $str_confirm, $comment_srl); $oCommentController->addCommentPopupMenu($url,'cmd_trash','','javascript'); @@ -106,7 +106,7 @@ class commentModel extends comment for($i = 0; $i < $menus_count; $i++) { - $menus[$i]->str = Context::getLang($menus[$i]->str); + $menus[$i]->str = lang($menus[$i]->str); } // get a list of final organized pop-up menus diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 452c61afc..585e92722 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -808,7 +808,7 @@ class communicationController extends communication if($new_message_count > 0) { Context::loadFile('./modules/communication/tpl/js/member_communication.js'); - $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); + $text = preg_replace('@\r?\n@', '\\n', addslashes(lang('alert_new_message_arrived'))); Context::addHtmlHeader(""); } diff --git a/modules/communication/skins/default/common_header.html b/modules/communication/skins/default/common_header.html index 5113f50d2..8e504c290 100644 --- a/modules/communication/skins/default/common_header.html +++ b/modules/communication/skins/default/common_header.html @@ -3,6 +3,6 @@
diff --git a/modules/document/document.admin.controller.php b/modules/document/document.admin.controller.php index f1f77d00b..9ccb1c869 100644 --- a/modules/document/document.admin.controller.php +++ b/modules/document/document.admin.controller.php @@ -41,7 +41,7 @@ class documentAdminController extends document $oDocumentController->deleteDocument($document_srl, true); } - $this->setMessage(sprintf(Context::getLang('msg_checked_document_is_deleted'), $document_count) ); + $this->setMessage(sprintf(lang('msg_checked_document_is_deleted'), $document_count) ); } /** diff --git a/modules/document/document.admin.view.php b/modules/document/document.admin.view.php index 4efa55613..5e322fc38 100644 --- a/modules/document/document.admin.view.php +++ b/modules/document/document.admin.view.php @@ -68,7 +68,7 @@ class documentAdminView extends document $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]); + $search_option[$this->search_option[$i]] = lang($this->search_option[$i]); } Context::set('search_option', $search_option); diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index 5478d0d11..81d2685b4 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -205,7 +205,7 @@ class documentController extends document // if an user select message from options, message would be the option. $message_option = strval(Context::get('message_option')); - $improper_document_reasons = Context::getLang('improper_document_reasons'); + $improper_document_reasons = lang('improper_document_reasons'); $declare_message = ($message_option !== 'others' && isset($improper_document_reasons[$message_option]))? $improper_document_reasons[$message_option] : trim(Context::get('declare_message')); @@ -1814,9 +1814,9 @@ class documentController extends document $prev_category = $val; } // Return if the previous category doesn't exist - if(!$prev_category) return new Object(-1,Context::getLang('msg_category_not_moved')); + if(!$prev_category) return new Object(-1,lang('msg_category_not_moved')); // Return if the selected category is the top level - if($category_srl_list[0]==$category_srl) return new Object(-1,Context::getLang('msg_category_not_moved')); + if($category_srl_list[0]==$category_srl) return new Object(-1,lang('msg_category_not_moved')); // Information of the selected category $cur_args = new stdClass; $cur_args->category_srl = $category_srl; @@ -1860,7 +1860,7 @@ class documentController extends document } $next_category_srl = $category_srl_list[$i+1]; - if(!$category_list[$next_category_srl]) return new Object(-1,Context::getLang('msg_category_not_moved')); + if(!$category_list[$next_category_srl]) return new Object(-1,lang('msg_category_not_moved')); $next_category = $category_list[$next_category_srl]; // Information of the selected category $cur_args = new stdClass; @@ -2529,10 +2529,10 @@ class documentController extends document { $logged_info = Context::get('logged_info'); $message_content = ''; - $default_message_verbs = Context::getLang('default_message_verbs'); + $default_message_verbs = lang('default_message_verbs'); if(isset($default_message_verbs[$type]) && is_string($default_message_verbs[$type])) { - $message_content = sprintf(Context::getLang('default_message_format'), $logged_info->nick_name, $default_message_verbs[$type]); + $message_content = sprintf(lang('default_message_format'), $logged_info->nick_name, $default_message_verbs[$type]); } } else diff --git a/modules/document/document.item.php b/modules/document/document.item.php index abb9e9614..3990506bd 100644 --- a/modules/document/document.item.php +++ b/modules/document/document.item.php @@ -411,7 +411,7 @@ class documentItem extends Object { if(!$this->document_srl) return; - if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return Context::getLang('msg_is_secret'); + if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return lang('msg_is_secret'); $result = $this->_checkAccessibleFromStatus(); if($result && Context::getSessionStatus()) @@ -475,7 +475,7 @@ class documentItem extends Object { if(!$this->document_srl) return; - if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return Context::getLang('msg_is_secret'); + if($this->isSecret() && !$this->isGranted() && !$this->isAccessible()) return lang('msg_is_secret'); $result = $this->_checkAccessibleFromStatus(); if($result && Context::getSessionStatus()) @@ -498,7 +498,7 @@ class documentItem extends Object $content = sprintf( '%s', $content, - $this->document_srl, Context::getLang('cmd_document_do') + $this->document_srl, lang('cmd_document_do') ); } // If additional content information is set diff --git a/modules/document/document.model.php b/modules/document/document.model.php index 673d4f416..ac5df7e32 100644 --- a/modules/document/document.model.php +++ b/modules/document/document.model.php @@ -528,7 +528,7 @@ class documentModel extends document ModuleHandler::triggerCall('document.getDocumentMenu', 'after', $menu_list); if($this->grant->manager) { - $str_confirm = Context::getLang('confirm_move'); + $str_confirm = lang('confirm_move'); $url = sprintf("if(!confirm('%s')) return; var params = new Array(); params['document_srl']='%s'; params['mid']=current_mid;params['cur_url']=current_url; exec_xml('document', 'procDocumentAdminMoveToTrash', params)", $str_confirm, $document_srl); $oDocumentController->addDocumentPopupMenu($url,'cmd_trash','','javascript'); } @@ -554,7 +554,7 @@ class documentModel extends document $menus_count = count($menus); for($i=0;$i<$menus_count;$i++) { - $menus[$i]->str = Context::getLang($menus[$i]->str); + $menus[$i]->str = lang($menus[$i]->str); } // Wanted to finally clean pop-up menu list $this->add('menus', $menus); diff --git a/modules/editor/editor.controller.php b/modules/editor/editor.controller.php index b4782b307..b1a97de71 100644 --- a/modules/editor/editor.controller.php +++ b/modules/editor/editor.controller.php @@ -47,13 +47,13 @@ class editorController extends editor { $component = Context::get('component'); $method = Context::get('method'); - if(!$component) return new Object(-1, sprintf(Context::getLang('msg_component_is_not_founded'), $component)); + if(!$component) return new Object(-1, sprintf(lang('msg_component_is_not_founded'), $component)); $oEditorModel = getModel('editor'); $oComponent = &$oEditorModel->getComponentObject($component); if(!$oComponent->toBool()) return $oComponent; - if(!method_exists($oComponent, $method)) return new Object(-1, sprintf(Context::getLang('msg_component_is_not_founded'), $component)); + if(!method_exists($oComponent, $method)) return new Object(-1, sprintf(lang('msg_component_is_not_founded'), $component)); //$output = call_user_method($method, $oComponent); //$output = call_user_func(array($oComponent, $method)); diff --git a/modules/editor/editor.model.php b/modules/editor/editor.model.php index 2dcbe26fd..5a95186b5 100644 --- a/modules/editor/editor.model.php +++ b/modules/editor/editor.model.php @@ -547,11 +547,11 @@ class editorModel extends editor // Create an object of the component and execute $class_path = sprintf('%scomponents/%s/', $this->module_path, $component); $class_file = sprintf('%s%s.class.php', $class_path, $component); - if(!file_exists($class_file)) return new Object(-1, sprintf(Context::getLang('msg_component_is_not_founded'), $component)); + if(!file_exists($class_file)) return new Object(-1, sprintf(lang('msg_component_is_not_founded'), $component)); // Create an object after loading the class file require_once($class_file); $oComponent = new $component($editor_sequence, $class_path); - if(!$oComponent) return new Object(-1, sprintf(Context::getLang('msg_component_is_not_founded'), $component)); + if(!$oComponent) return new Object(-1, sprintf(lang('msg_component_is_not_founded'), $component)); // Add configuration information $component_info = $this->getComponent($component, $site_srl); $oComponent->setInfo($component_info); diff --git a/modules/editor/editor.view.php b/modules/editor/editor.view.php index cbe3edacf..d0dd2777b 100644 --- a/modules/editor/editor.view.php +++ b/modules/editor/editor.view.php @@ -33,7 +33,7 @@ class editorView extends editor $oComponent = &$oEditorModel->getComponentObject($component, $editor_sequence, $site_srl); if(!$oComponent->toBool()) { - Context::set('message', sprintf(Context::getLang('msg_component_is_not_founded'), $component)); + Context::set('message', sprintf(lang('msg_component_is_not_founded'), $component)); $this->setTemplatePath($this->module_path.'tpl'); $this->setTemplateFile('component_not_founded'); } diff --git a/modules/file/file.admin.controller.php b/modules/file/file.admin.controller.php index af453c707..212800d70 100644 --- a/modules/file/file.admin.controller.php +++ b/modules/file/file.admin.controller.php @@ -78,7 +78,7 @@ class fileAdminController extends file $oFileController->deleteFile($file_srl); } - $this->setMessage( sprintf(Context::getLang('msg_checked_file_is_deleted'), $file_count) ); + $this->setMessage( sprintf(lang('msg_checked_file_is_deleted'), $file_count) ); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispFileAdminList'); $this->setRedirectUrl($returnUrl); diff --git a/modules/file/file.model.php b/modules/file/file.model.php index cd8deb2e7..a58a0f411 100644 --- a/modules/file/file.model.php +++ b/modules/file/file.model.php @@ -271,12 +271,12 @@ class fileModel extends file // Display upload status $upload_status = sprintf( '%s : %s/ %s
%s : %s (%s : %s)', - Context::getLang('allowed_attach_size'), + lang('allowed_attach_size'), FileHandler::filesize($attached_size), FileHandler::filesize($file_config->allowed_attach_size*1024*1024), - Context::getLang('allowed_filesize'), + lang('allowed_filesize'), FileHandler::filesize($file_config->allowed_filesize*1024*1024), - Context::getLang('allowed_filetypes'), + lang('allowed_filetypes'), $file_config->allowed_filetypes ); return $upload_status; diff --git a/modules/importer/importer.admin.controller.php b/modules/importer/importer.admin.controller.php index f0ac7f915..a442c80bb 100644 --- a/modules/importer/importer.admin.controller.php +++ b/modules/importer/importer.admin.controller.php @@ -328,10 +328,10 @@ class importerAdminController extends importer // When completing, success message appears and remove the cache files if($total <= $cur) { - $this->setMessage( sprintf(Context::getLang('msg_import_finished'), $cur, $total) ); + $this->setMessage( sprintf(lang('msg_import_finished'), $cur, $total) ); FileHandler::removeDir('./files/cache/importer/'.$key); } - else $this->setMessage( sprintf(Context::getLang('msg_importing'), $total, $cur) ); + else $this->setMessage( sprintf(lang('msg_importing'), $total, $cur) ); } /** diff --git a/modules/install/install.controller.php b/modules/install/install.controller.php index 90d608952..6b33b4229 100644 --- a/modules/install/install.controller.php +++ b/modules/install/install.controller.php @@ -284,7 +284,7 @@ class installController extends install if(!$ftp_info->ftp_user || !$ftp_info->ftp_password) return new Object(-1,'msg_safe_mode_ftp_needed'); $oFtp = new ftp(); - if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), $ftp_info->ftp_host)); + if(!$oFtp->ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port)) return new Object(-1, sprintf(lang('msg_ftp_not_connected'), $ftp_info->ftp_host)); if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) { @@ -342,7 +342,7 @@ class installController extends install else { $oFtp = new ftp(); - if(!$oFtp->ftp_connect('127.0.0.1', $ftp_info->ftp_port)) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), 'localhost')); + if(!$oFtp->ftp_connect('127.0.0.1', $ftp_info->ftp_port)) return new Object(-1, sprintf(lang('msg_ftp_not_connected'), 'localhost')); if(!$oFtp->ftp_login($ftp_info->ftp_user, $ftp_info->ftp_password)) { diff --git a/modules/install/install.model.php b/modules/install/install.model.php index f4b854a50..b9d749b67 100644 --- a/modules/install/install.model.php +++ b/modules/install/install.model.php @@ -54,7 +54,7 @@ class installModel extends install if(function_exists('ftp_connect')) { $connection = ftp_connect($ftp_info->ftp_host, $ftp_info->ftp_port); - if(!$connection) return new Object(-1, sprintf(Context::getLang('msg_ftp_not_connected'), $ftp_info->ftp_host)); + if(!$connection) return new Object(-1, sprintf(lang('msg_ftp_not_connected'), $ftp_info->ftp_host)); if(! @ftp_login($connection, $ftp_info->ftp_user, $ftp_info->ftp_password)) { ftp_close($connection); diff --git a/modules/install/install.view.php b/modules/install/install.view.php index 752208b80..0d8c0498f 100644 --- a/modules/install/install.view.php +++ b/modules/install/install.view.php @@ -23,7 +23,7 @@ class installView extends install } // Set the browser title. - Context::setBrowserTitle(Context::getLang('introduce_title')); + Context::setBrowserTitle(lang('introduce_title')); // Specify the template path. $this->setTemplatePath($this->module_path.'tpl'); diff --git a/modules/layout/layout.admin.controller.php b/modules/layout/layout.admin.controller.php index 1e571a24f..6a3342021 100644 --- a/modules/layout/layout.admin.controller.php +++ b/modules/layout/layout.admin.controller.php @@ -927,13 +927,13 @@ class layoutAdminController extends layout if(!$img['tmp_name'] || !is_uploaded_file($img['tmp_name']) || !checkUploadedFile($img['tmp_name'])) { - Context::set('msg', Context::getLang('upload failed')); + Context::set('msg', lang('upload failed')); return; } if(!preg_match('/\.(jpg|jpeg|gif|png|swf)$/i', $img['name'])) { - Context::set('msg', Context::getLang('msg_layout_image_target')); + Context::set('msg', lang('msg_layout_image_target')); return; } @@ -941,7 +941,7 @@ class layoutAdminController extends layout $tmpPath = $path . 'tmp/'; if(!FileHandler::makeDir($tmpPath)) { - Context::set('msg', Context::getLang('make directory failed')); + Context::set('msg', lang('make directory failed')); return; } @@ -952,7 +952,7 @@ class layoutAdminController extends layout if(!move_uploaded_file($img['tmp_name'], $tmpFileName)) { - Context::set('msg', Context::getLang('move file failed')); + Context::set('msg', lang('move file failed')); return; } @@ -990,7 +990,7 @@ class layoutAdminController extends layout $output = $this->updateLayout($args); if(!$output->toBool()) { - Context::set('msg', Context::getLang($output->getMessage())); + Context::set('msg', lang($output->getMessage())); return $output; } diff --git a/modules/layout/layout.admin.view.php b/modules/layout/layout.admin.view.php index 33d9ff6b8..75a384088 100644 --- a/modules/layout/layout.admin.view.php +++ b/modules/layout/layout.admin.view.php @@ -324,7 +324,7 @@ class layoutAdminView extends layout } Context::set('layout_info', $layout_info); - Context::set('content', Context::getLang('layout_preview_content')); + Context::set('content', lang('layout_preview_content')); // Temporary save the codes $edited_layout_file = sprintf('./files/cache/layout/tmp.tpl'); FileHandler::writeFile($edited_layout_file, $code); diff --git a/modules/layout/layout.model.php b/modules/layout/layout.model.php index 7797edf4d..0ea869c7b 100644 --- a/modules/layout/layout.model.php +++ b/modules/layout/layout.model.php @@ -58,7 +58,7 @@ class layoutModel extends layout $siteDefaultLayoutInfo = $this->getlayout($siteDefaultLayoutSrl); $newLayout = sprintf('%s, %s', $siteDefaultLayoutInfo->title, $siteDefaultLayoutInfo->layout); $siteDefaultLayoutInfo->layout_srl = -1; - $siteDefaultLayoutInfo->title = Context::getLang('use_site_default_layout'); + $siteDefaultLayoutInfo->title = lang('use_site_default_layout'); $siteDefaultLayoutInfo->layout = $newLayout; array_unshift($output->data, $siteDefaultLayoutInfo); @@ -1030,7 +1030,7 @@ class layoutModel extends layout // Display edit button for faceoff layout if(Context::get('module')!='admin' && strpos(Context::get('act'),'Admin')===false && ($logged_info->is_admin == 'Y' || $logged_info->is_site_admin)) { - Context::addHtmlFooter(''); + Context::addHtmlFooter(''); } // Display menu when editing the faceOff page if(Context::get('act')=='dispLayoutAdminLayoutModify' && ($logged_info->is_admin == 'Y' || $logged_info->is_site_admin)) diff --git a/modules/layout/layout.view.php b/modules/layout/layout.view.php index 50b134560..acacca938 100644 --- a/modules/layout/layout.view.php +++ b/modules/layout/layout.view.php @@ -55,7 +55,7 @@ class layoutView extends layout $logged_info = Context::get('logged_info'); if($logged_info->is_admin != 'Y') { - throw new Exception(Context::getLang('msg_invalid_request')); + throw new Exception(lang('msg_invalid_request')); } // if module is 'ARTiCLE' and from site design setting, make content directly @@ -64,7 +64,7 @@ class layoutView extends layout $oDocumentModel = getModel('document'); $oDocument = $oDocumentModel->getDocument(0, true); - $t = Context::getLang('article_preview_title'); + $t = lang('article_preview_title'); $c = ''; for($i = 0; $i < 4; $i++) @@ -72,7 +72,7 @@ class layoutView extends layout $c .= '

'; for($j = 0; $j < 20; $j++) { - $c .= Context::getLang('article_preview_content') . ' '; + $c .= lang('article_preview_content') . ' '; } $c .= '

'; } @@ -259,7 +259,7 @@ class layoutView extends layout // if there is no module instance, error... if(!$output->data) { - throw new Exception(Context::getLang('msg_unabled_preview')); + throw new Exception(lang('msg_unabled_preview')); } $mid = current($output->data)->mid; @@ -301,7 +301,7 @@ class layoutView extends layout $oModule = $oModuleHandler->procModule(); if(!$oModule->toBool()) { - throw new Exception(Context::getLang('not_support_layout_preview')); + throw new Exception(lang('not_support_layout_preview')); } // get module html @@ -361,7 +361,7 @@ class layoutView extends layout } Context::set('layout_info', $layout_info); - Context::set('content', Context::getLang('layout_preview_content')); + Context::set('content', lang('layout_preview_content')); // Temporary save the codes $edited_layout_file = _XE_PATH_ . 'files/cache/layout/tmp.tpl'; FileHandler::writeFile($edited_layout_file, $code); diff --git a/modules/member/m.skins/default/common_header.html b/modules/member/m.skins/default/common_header.html index 5d824928b..f882e2d41 100644 --- a/modules/member/m.skins/default/common_header.html +++ b/modules/member/m.skins/default/common_header.html @@ -3,7 +3,7 @@ \ No newline at end of file diff --git a/modules/member/m.skins/default/leave_form.html b/modules/member/m.skins/default/leave_form.html index b81eb1ee7..77698aabd 100644 --- a/modules/member/m.skins/default/leave_form.html +++ b/modules/member/m.skins/default/leave_form.html @@ -12,7 +12,7 @@
  • - +

    {$formValue}

  • diff --git a/modules/member/m.skins/default/modify_password.html b/modules/member/m.skins/default/modify_password.html index df0e96976..9a466f847 100644 --- a/modules/member/m.skins/default/modify_password.html +++ b/modules/member/m.skins/default/modify_password.html @@ -14,7 +14,7 @@
    • - +
    • diff --git a/modules/member/member.admin.controller.php b/modules/member/member.admin.controller.php index ddfb69ba8..918838a72 100644 --- a/modules/member/member.admin.controller.php +++ b/modules/member/member.admin.controller.php @@ -1296,7 +1296,7 @@ class memberAdminController extends member $default_args->group_srl = $defaultGroupSrl; $output = $this->updateGroup($default_args); - $this->setMessage(Context::getLang('success_updated').' ('.Context::getLang('msg_insert_group_name_detail').')'); + $this->setMessage(lang('success_updated').' ('.lang('msg_insert_group_name_detail').')'); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispMemberAdminGroupList'); $this->setRedirectUrl($returnUrl); diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index 21e3d6ba8..93619b3c4 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -506,7 +506,7 @@ class memberAdminView extends member $val); } $inputTag = sprintf($inputTag, implode('', $optionTag)); - $inputTag .= ''; + $inputTag .= ''; } else if($formInfo->name == 'email_address') { diff --git a/modules/member/member.class.php b/modules/member/member.class.php index 84328637d..b2a63f159 100644 --- a/modules/member/member.class.php +++ b/modules/member/member.class.php @@ -110,19 +110,19 @@ class member extends ModuleObject { { // Set an administrator, regular member(group1), and associate member(group2) $group_args = new stdClass; - $group_args->title = Context::getLang('admin_group'); + $group_args->title = lang('admin_group'); $group_args->is_default = 'N'; $group_args->is_admin = 'Y'; $output = $oMemberAdminController->insertGroup($group_args); $group_args = new stdClass; - $group_args->title = Context::getLang('default_group_1'); + $group_args->title = lang('default_group_1'); $group_args->is_default = 'Y'; $group_args->is_admin = 'N'; $output = $oMemberAdminController->insertGroup($group_args); $group_args = new stdClass; - $group_args->title = Context::getLang('default_group_2'); + $group_args->title = lang('default_group_2'); $group_args->is_default = 'N'; $group_args->is_admin = 'N'; $oMemberAdminController->insertGroup($group_args); @@ -455,14 +455,14 @@ class member extends ModuleObject { { //update $content = unserialize($output->data->content); - $content[] = array($_SERVER['REMOTE_ADDR'],Context::getLang($message),$_SERVER['REQUEST_TIME']); + $content[] = array($_SERVER['REMOTE_ADDR'],lang($message),$_SERVER['REQUEST_TIME']); $args->content = serialize($content); $output = executeQuery('member.updateLoginCountHistoryByMemberSrl', $args); } else { //insert - $content[0] = array($_SERVER['REMOTE_ADDR'],Context::getLang($message),$_SERVER['REQUEST_TIME']); + $content[0] = array($_SERVER['REMOTE_ADDR'],lang($message),$_SERVER['REQUEST_TIME']); $args->content = serialize($content); $output = executeQuery('member.insertLoginCountHistoryByMemberSrl', $args); } diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index c99dc0062..c6bb4c134 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -67,7 +67,7 @@ class memberController extends member $oMemberModel = getModel('member'); if($this->memberInfo->change_password_date < date ('YmdHis', strtotime ('-' . $limit_date . ' day'))) { - $msg = sprintf(Context::getLang('msg_change_password_date'), $limit_date); + $msg = sprintf(lang('msg_change_password_date'), $limit_date); return $this->setRedirectUrl(getNotEncodedUrl('','vid',Context::get('vid'),'mid',Context::get('mid'),'act','dispMemberModifyPassword'), new Object(-1, $msg)); } } @@ -245,7 +245,7 @@ class memberController extends member $config = $oMemberModel->getMemberConfig(); $emailhost_check = $config->emailhost_check; - $managed_email_host = Context::getLang('managed_email_host'); + $managed_email_host = lang('managed_email_host'); $email_hosts = $oMemberModel->getManagedEmailHosts(); foreach ($email_hosts as $host) @@ -313,7 +313,7 @@ class memberController extends member // check password strength if(!$oMemberModel->checkPasswordStrength($args->password, $config->password_strength)) { - $message = Context::getLang('about_password_strength'); + $message = lang('about_password_strength'); return new Object(-1, $message[$config->password_strength]); } @@ -412,7 +412,7 @@ class memberController extends member 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); + $msg = sprintf(lang('msg_confirm_mail_sent'), $args->email_address); $this->setMessage($msg); return $this->setRedirectUrl(getUrl('', 'act', 'dispMemberLoginForm'), new Object(-12, $msg)); } @@ -1048,13 +1048,13 @@ class memberController extends member $member_config = $oModuleModel->getModuleConfig('member'); // Send a mail $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_find_account_title') ); + $oMail->setTitle( lang('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 message - $msg = sprintf(Context::getLang('msg_auth_mail_sent'), $member_info->email_address); + $msg = sprintf(lang('msg_auth_mail_sent'), $member_info->email_address); if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) { $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', 'dispMemberFindAccount'); @@ -1273,13 +1273,13 @@ class memberController extends member $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); // Send a mail $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); + $oMail->setTitle( lang('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(); - $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $args->email_address); + $msg = sprintf(lang('msg_confirm_mail_sent'), $args->email_address); $this->setMessage($msg); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', ''); @@ -1349,7 +1349,7 @@ class memberController extends member // resend auth mail. $this->_sendAuthMail($auth_args, $memberInfo); - $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $memberInfo->email_address); + $msg = sprintf(lang('msg_confirm_mail_sent'), $memberInfo->email_address); $this->setMessage($msg); $returnUrl = getUrl(''); @@ -1401,7 +1401,7 @@ class memberController extends member $content = $oTemplate->compile($tpl_path, 'confirm_member_account_mail'); // Send a mail $oMail = new Mail(); - $oMail->setTitle( Context::getLang('msg_confirm_account_title') ); + $oMail->setTitle( lang('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 ); @@ -1720,12 +1720,12 @@ class memberController extends member if($term < $config->max_error_count_time) { $term = $config->max_error_count_time - $term; - if($term < 60) $term = intval($term).Context::getLang('unit_sec'); - elseif(60 <= $term && $term < 3600) $term = intval($term/60).Context::getLang('unit_min'); - elseif(3600 <= $term && $term < 86400) $term = intval($term/3600).Context::getLang('unit_hour'); - else $term = intval($term/86400).Context::getLang('unit_day'); + if($term < 60) $term = intval($term).lang('unit_sec'); + elseif(60 <= $term && $term < 3600) $term = intval($term/60).lang('unit_min'); + elseif(3600 <= $term && $term < 86400) $term = intval($term/3600).lang('unit_hour'); + else $term = intval($term/86400).lang('unit_day'); - return new Object(-1, sprintf(Context::getLang('excess_ip_access_count'),$term)); + return new Object(-1, sprintf(lang('excess_ip_access_count'),$term)); } else { @@ -1751,13 +1751,13 @@ class memberController extends member $redirectUrl = getUrl('', 'act', 'dispMemberResendAuthMail'); return $this->setRedirectUrl($redirectUrl, new Object(-1,'msg_user_not_confirmed')); } - return new Object(-1, ($this->memberInfo->refused_reason)? Context::getLang('msg_user_denied') . "\n" . $this->memberInfo->refused_reason : 'msg_user_denied'); + return new Object(-1, ($this->memberInfo->refused_reason)? lang('msg_user_denied') . "\n" . $this->memberInfo->refused_reason : 'msg_user_denied'); } // Notify if user is limited if($this->memberInfo->limit_date && substr($this->memberInfo->limit_date,0,8) >= date("Ymd")) { - return new Object(-9,sprintf(Context::getLang('msg_user_limited'),zdate($this->memberInfo->limit_date,"Y-m-d"))); + return new Object(-9,sprintf(lang('msg_user_limited'),zdate($this->memberInfo->limit_date,"Y-m-d"))); } // Do not allow login as admin if not in allowed IP list @@ -1785,17 +1785,17 @@ class memberController extends member $output = executeQuery('member.getLoginCountHistoryByMemberSrl', $args); if($output->data && $output->data->content) { - $title = Context::getLang('login_fail_report'); + $title = lang('login_fail_report'); $message = '
        '; $content = unserialize($output->data->content); if(count($content) > $config->max_error_count) { foreach($content as $val) { - $message .= '
      • '.Context::getLang('regdate').': '.date('Y-m-d h:i:sa',$val[2]).'
        • '.Context::getLang('ipaddress').': '.$val[0].'
        • '.Context::getLang('message').': '.$val[1].'
      • '; + $message .= '
      • '.lang('regdate').': '.date('Y-m-d h:i:sa',$val[2]).'
        • '.lang('ipaddress').': '.$val[0].'
        • '.lang('message').': '.$val[1].'
      • '; } $message .= '
      '; - $content = sprintf(Context::getLang('login_fail_report_contents'),$message,date('Y-m-d h:i:sa')); + $content = sprintf(lang('login_fail_report_contents'),$message,date('Y-m-d h:i:sa')); //send message $oCommunicationController = getController('communication'); @@ -1906,7 +1906,7 @@ class memberController extends member { $logged_info = Context::get('logged_info'); - $logged_info->menu_list[$act] = Context::getLang($str); + $logged_info->menu_list[$act] = lang($str); Context::set('logged_info', $logged_info); } @@ -1988,7 +1988,7 @@ class memberController extends member { if(!$oMemberModel->checkPasswordStrength($args->password, $config->password_strength)) { - $message = Context::getLang('about_password_strength'); + $message = lang('about_password_strength'); return new Object(-1, $message[$config->password_strength]); } $args->password = $oMemberModel->hashPassword($args->password); @@ -2030,7 +2030,7 @@ class memberController extends member $config = $oMemberModel->getMemberConfig(); $emailhost_check = $config->emailhost_check; - $managed_email_host = Context::getLang('managed_email_host'); + $managed_email_host = lang('managed_email_host'); $email_hosts = $oMemberModel->getManagedEmailHosts(); foreach ($email_hosts as $host) { @@ -2191,7 +2191,7 @@ class memberController extends member $config = $oMemberModel->getMemberConfig(); $emailhost_check = $config->emailhost_check; - $managed_email_host = Context::getLang('managed_email_host'); + $managed_email_host = lang('managed_email_host'); $email_hosts = $oMemberModel->getManagedEmailHosts(); foreach ($email_hosts as $host) { @@ -2261,7 +2261,7 @@ class memberController extends member { if(!$oMemberModel->checkPasswordStrength($args->password, $config->password_strength)) { - $message = Context::getLang('about_password_strength'); + $message = lang('about_password_strength'); return new Object(-1, $message[$config->password_strength]); } $args->password = $oMemberModel->hashPassword($args->password); @@ -2364,7 +2364,7 @@ class memberController extends member if(!$oMemberModel->checkPasswordStrength($args->password, $config->password_strength)) { - $message = Context::getLang('about_password_strength'); + $message = lang('about_password_strength'); return new Object(-1, $message[$config->password_strength]); } @@ -2542,7 +2542,7 @@ class memberController extends member $config = $oMemberModel->getMemberConfig(); $emailhost_check = $config->emailhost_check; - $managed_email_host = Context::getLang('managed_email_host'); + $managed_email_host = lang('managed_email_host'); $email_hosts = $oMemberModel->getManagedEmailHosts(); foreach ($email_hosts as $host) { @@ -2601,13 +2601,13 @@ class memberController extends member $content = $oTemplate->compile($tpl_path, 'confirm_member_new_email'); $oMail = new Mail(); - $oMail->setTitle( Context::getLang('title_modify_email_address') ); + $oMail->setTitle( lang('title_modify_email_address') ); $oMail->setContent($content); $oMail->setSender( $member_config->webmaster_name?$member_config->webmaster_name:'webmaster', $member_config->webmaster_email); $oMail->setReceiptor( $member_info->nick_name, $newEmail ); $result = $oMail->send(); - $msg = sprintf(Context::getLang('msg_confirm_mail_sent'), $newEmail); + $msg = sprintf(lang('msg_confirm_mail_sent'), $newEmail); $this->setMessage($msg); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', ''); @@ -2803,7 +2803,7 @@ class memberController extends member $args->description = trim( $member_info->description ); if( $args->description != "" ) $args->description .= "\n"; // add new line - $args->description .= Context::getLang('cmd_spammer') . "[" . date("Y-m-d H:i:s") . " from:" . $logged_info->user_id . " info:" . $spam_description . " docuemnts count:" . $total_count . "]"; + $args->description .= lang('cmd_spammer') . "[" . date("Y-m-d H:i:s") . " from:" . $logged_info->user_id . " info:" . $spam_description . " docuemnts count:" . $total_count . "]"; $output = $this->updateMember($args, true); diff --git a/modules/member/member.model.php b/modules/member/member.model.php index fd72ef1ce..7b26ef013 100644 --- a/modules/member/member.model.php +++ b/modules/member/member.model.php @@ -44,7 +44,7 @@ class memberModel extends member //for multi language foreach($config->signupForm AS $key=>$value) { - $config->signupForm[$key]->title = ($value->isDefaultForm) ? Context::getLang($value->name) : $value->title; + $config->signupForm[$key]->title = ($value->isDefaultForm) ? lang($value->name) : $value->title; if($config->signupForm[$key]->isPublic != 'N') $config->signupForm[$key]->isPublic = 'Y'; if($value->name == 'find_account_question') $config->signupForm[$key]->isPublic = 'N'; } @@ -186,7 +186,7 @@ class memberModel extends member $menus_count = count($menus); for($i=0;$i<$menus_count;$i++) { - $menus[$i]->str = Context::getLang($menus[$i]->str); + $menus[$i]->str = lang($menus[$i]->str); } // Get a list of finalized pop-up menu $this->add('menus', $menus); diff --git a/modules/member/member.view.php b/modules/member/member.view.php index 687dd1cc9..b54f40144 100644 --- a/modules/member/member.view.php +++ b/modules/member/member.view.php @@ -128,7 +128,7 @@ class memberView extends member if($formInfo->isDefaultForm) { - $item->title = Context::getLang($formInfo->name); + $item->title = lang($formInfo->name); $item->value = $memberInfo->{$formInfo->name}; if($formInfo->name == 'profile_image' && $memberInfo->profile_image) @@ -265,12 +265,12 @@ class memberView extends member if ($this->member_config->identifier == 'email_address') { - Context::set('identifierTitle', Context::getLang('email_address')); + Context::set('identifierTitle', lang('email_address')); Context::set('identifierValue', $logged_info->email_address); } else { - Context::set('identifierTitle', Context::getLang('user_id')); + Context::set('identifierTitle', lang('user_id')); Context::set('identifierValue', $logged_info->user_id); } diff --git a/modules/member/skins/default/common_header.html b/modules/member/skins/default/common_header.html index 7a755d48d..6d930eaf4 100644 --- a/modules/member/skins/default/common_header.html +++ b/modules/member/skins/default/common_header.html @@ -4,6 +4,6 @@
      diff --git a/modules/member/skins/default/leave_form.html b/modules/member/skins/default/leave_form.html index db2653ed4..839f941e5 100644 --- a/modules/member/skins/default/leave_form.html +++ b/modules/member/skins/default/leave_form.html @@ -11,7 +11,7 @@
      - +
      diff --git a/modules/member/skins/default/modify_password.html b/modules/member/skins/default/modify_password.html index ff1940b9b..09fbb12b2 100644 --- a/modules/member/skins/default/modify_password.html +++ b/modules/member/skins/default/modify_password.html @@ -12,7 +12,7 @@
      - +
      diff --git a/modules/menu/menu.admin.controller.php b/modules/menu/menu.admin.controller.php index 011b09128..c007af59b 100644 --- a/modules/menu/menu.admin.controller.php +++ b/modules/menu/menu.admin.controller.php @@ -1517,12 +1517,12 @@ class menuAdminController extends menu // Error occurs when the target is neither a uploaded file nor a valid file if(!$menu_srl || !$menu_item_srl) { - Context::set('error_messge', Context::getLang('msg_invalid_request')); + Context::set('error_messge', lang('msg_invalid_request')); } else if(!$target_file || !is_uploaded_file($target_file['tmp_name']) || !preg_match('/\.(gif|jpeg|jpg|png)$/i',$target_file['name']) || !checkUploadedFile($target_file['tmp_name'])) { - Context::set('error_messge', Context::getLang('msg_invalid_request')); + Context::set('error_messge', lang('msg_invalid_request')); } // Move the file to a specific director if the uploaded file meets requirement diff --git a/modules/menu/menu.admin.model.php b/modules/menu/menu.admin.model.php index 06878c186..d9efeb90b 100644 --- a/modules/menu/menu.admin.model.php +++ b/modules/menu/menu.admin.model.php @@ -366,7 +366,7 @@ class menuAdminModel extends menu if($module_name == 'page') { - $pageTypeName = Context::getLang('page_type_name'); + $pageTypeName = lang('page_type_name'); $module->title = $pageTypeName['ARTICLE']; $allModules['ARTICLE'] = $module; $wModuleInfo = clone $module; @@ -451,7 +451,7 @@ class menuAdminModel extends menu if($value == 'page') { - $pageTypeName = Context::getLang('page_type_name'); + $pageTypeName = lang('page_type_name'); $moduleInfo->title = $pageTypeName['ARTICLE']; $moduleInfoList['ARTICLE'] = $moduleInfo; $wModuleInfo = clone $moduleInfo; diff --git a/modules/module/module.admin.controller.php b/modules/module/module.admin.controller.php index 671a86027..25319d5b8 100644 --- a/modules/module/module.admin.controller.php +++ b/modules/module/module.admin.controller.php @@ -826,7 +826,7 @@ class moduleAdminController extends module } else { - $mid_list[$module]->list[$key]->module_category_srl = Context::getLang('none_category'); + $mid_list[$module]->list[$key]->module_category_srl = lang('none_category'); } } } diff --git a/modules/module/module.admin.model.php b/modules/module/module.admin.model.php index 5fbaf1f95..66282e3fc 100644 --- a/modules/module/module.admin.model.php +++ b/modules/module/module.admin.model.php @@ -90,7 +90,7 @@ class moduleAdminModel extends module $grantList =new stdClass(); } $grantList->access = new stdClass(); - $grantList->access->title = Context::getLang('grant_access'); + $grantList->access->title = lang('grant_access'); $grantList->access->default = 'guest'; if(count($grantList)) { @@ -102,7 +102,7 @@ class moduleAdminModel extends module } } $grant_list->manager = new stdClass(); - $grant_list->manager->title = Context::getLang('grant_manager'); + $grant_list->manager->title = lang('grant_manager'); $grant_list->manager->default = 'manager'; Context::set('grant_list', $grant_list); @@ -152,7 +152,7 @@ class moduleAdminModel extends module // Grant virtual permission for access and manager $grant_list = new stdClass(); $grant_list->access = new stdClass(); - $grant_list->access->title = Context::getLang('grant_access'); + $grant_list->access->title = lang('grant_access'); $grant_list->access->default = 'guest'; if(count($source_grant_list)) { @@ -164,7 +164,7 @@ class moduleAdminModel extends module } } $grant_list->manager = new stdClass(); - $grant_list->manager->title = Context::getLang('grant_manager'); + $grant_list->manager->title = lang('grant_manager'); $grant_list->manager->default = 'manager'; Context::set('grant_list', $grant_list); // Get a permission group granted to the current module @@ -229,7 +229,7 @@ class moduleAdminModel extends module // Grant virtual permission for access and manager $grantList = new stdClass(); $grantList->access = new stdClass(); - $grantList->access->title = Context::getLang('grant_access'); + $grantList->access->title = lang('grant_access'); $grantList->access->default = 'guest'; if(count($xmlInfo->grant)) { @@ -241,7 +241,7 @@ class moduleAdminModel extends module } } $grantList->manager = new stdClass(); - $grantList->manager->title = Context::getLang('grant_manager'); + $grantList->manager->title = lang('grant_manager'); $grantList->manager->default = 'manager'; // Get a permission group granted to the current module diff --git a/modules/module/module.admin.view.php b/modules/module/module.admin.view.php index 26544c456..70057bdb7 100644 --- a/modules/module/module.admin.view.php +++ b/modules/module/module.admin.view.php @@ -232,7 +232,7 @@ class moduleAdminView extends module $xml_info = $oModuleModel->getModuleActionXml($module_info->module); $source_grant_list = $xml_info->grant; // Grant virtual permissions for access and manager - $grant_list->access->title = Context::getLang('grant_access'); + $grant_list->access->title = lang('grant_access'); $grant_list->access->default = 'guest'; if(count($source_grant_list)) { @@ -243,7 +243,7 @@ class moduleAdminView extends module $grant_list->{$key} = $val; } } - $grant_list->manager->title = Context::getLang('grant_manager'); + $grant_list->manager->title = lang('grant_manager'); $grant_list->manager->default = 'manager'; Context::set('grant_list', $grant_list); // Get a list of groups diff --git a/modules/module/module.model.php b/modules/module/module.model.php index 62ceba564..f1785a715 100644 --- a/modules/module/module.model.php +++ b/modules/module/module.model.php @@ -1129,7 +1129,7 @@ class moduleModel extends module $defaultSkinInfo = $this->loadSkinInfo($path, $defaultSkinName, $dir); $useDefault = new stdClass(); - $useDefault->title = Context::getLang('use_site_default_skin') . ' (' . $defaultSkinInfo->title . ')'; + $useDefault->title = lang('use_site_default_skin') . ' (' . $defaultSkinInfo->title . ')'; $useDefaultList['/USE_DEFAULT/'] = $useDefault; diff --git a/modules/page/page.wap.php b/modules/page/page.wap.php index ea30a524b..ad60f0999 100644 --- a/modules/page/page.wap.php +++ b/modules/page/page.wap.php @@ -15,7 +15,7 @@ class pageWap extends page function procWAP(&$oMobile) { // Check permissions - if(!$this->grant->access) return $oMobile->setContent(Context::getLang('msg_not_permitted')); + if(!$this->grant->access) return $oMobile->setContent(lang('msg_not_permitted')); // The contents of the widget chuchulham $oWidgetController = getController('widget'); $content = $oWidgetController->transWidgetCode($this->module_info->content); diff --git a/modules/point/point.admin.controller.php b/modules/point/point.admin.controller.php index 4727e7242..77fa68645 100644 --- a/modules/point/point.admin.controller.php +++ b/modules/point/point.admin.controller.php @@ -332,7 +332,7 @@ class pointAdminController extends point $this->add('total', count($member)); $this->add('position', 0); - $this->setMessage( sprintf(Context::getLang('point_recal_message'), 0, $this->get('total')) ); + $this->setMessage( sprintf(lang('point_recal_message'), 0, $this->get('total')) ); } /** @@ -376,7 +376,7 @@ class pointAdminController extends point $this->add('total', $total); $this->add('position', $idx); - $this->setMessage(sprintf(Context::getLang('point_recal_message'), $idx, $total)); + $this->setMessage(sprintf(lang('point_recal_message'), $idx, $total)); } diff --git a/modules/point/point.controller.php b/modules/point/point.controller.php index 9fef9fe5f..21ca270ea 100644 --- a/modules/point/point.controller.php +++ b/modules/point/point.controller.php @@ -436,7 +436,7 @@ class pointController extends point $_SESSION['banned_document'][$obj->document_srl] = false; if($config->disable_read_document == 'Y' && $point < 0 && abs($point)>$cur_point) { - $message = sprintf(Context::getLang('msg_disallow_by_point'), abs($point), $cur_point); + $message = sprintf(lang('msg_disallow_by_point'), abs($point), $cur_point); $obj->add('content', $message); $_SESSION['banned_document'][$obj->document_srl] = true; return new Object(-1, $message); diff --git a/modules/point/tpl/member_list.html b/modules/point/tpl/member_list.html index 447944c6d..cfb81364f 100644 --- a/modules/point/tpl/member_list.html +++ b/modules/point/tpl/member_list.html @@ -22,7 +22,7 @@ @@ -36,7 +36,7 @@ {$lang->no} - {Context::getLang($identifier)} + {lang($identifier)} {$lang->nick_name} {$lang->point} {$lang->level} @@ -125,7 +125,7 @@ diff --git a/modules/poll/poll.admin.controller.php b/modules/poll/poll.admin.controller.php index a4c023e62..7cf9d47ae 100644 --- a/modules/poll/poll.admin.controller.php +++ b/modules/poll/poll.admin.controller.php @@ -55,7 +55,7 @@ class pollAdminController extends poll if(!$output->toBool()) return $output; } - $this->setMessage( sprintf(Context::getLang('msg_checked_poll_is_deleted'), $poll_count) ); + $this->setMessage( sprintf(lang('msg_checked_poll_is_deleted'), $poll_count) ); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispPollAdminList'); $this->setRedirectUrl($returnUrl); diff --git a/modules/poll/poll.model.php b/modules/poll/poll.model.php index 7c42be029..f34170c8c 100644 --- a/modules/poll/poll.model.php +++ b/modules/poll/poll.model.php @@ -139,7 +139,7 @@ class pollModel extends poll $ip = md5($value->ip_address); $poll->member[$ip] = new stdClass(); $poll->member[$ip]->member_srl = 0; - $poll->member[$ip]->nick_name = Context::getLang("anonymous") . ' IP: ' . $value->ip_address; + $poll->member[$ip]->nick_name = lang("anonymous") . ' IP: ' . $value->ip_address; $poll->member[$ip]->profile_image = ""; } else @@ -147,7 +147,7 @@ class pollModel extends poll $ip = md5($value->ip_address); $poll->member[$ip] = new stdClass(); $poll->member[$ip]->member_srl = 0; - $poll->member[$ip]->nick_name = Context::getLang("anonymous"); + $poll->member[$ip]->nick_name = lang("anonymous"); $poll->member[$ip]->profile_image = ""; } } diff --git a/modules/rss/rss.admin.controller.php b/modules/rss/rss.admin.controller.php index 6d1de7db3..cb7e9c5bd 100644 --- a/modules/rss/rss.admin.controller.php +++ b/modules/rss/rss.admin.controller.php @@ -76,7 +76,7 @@ class rssAdminController extends rss if(!$alt_message) $alt_message = 'success_updated'; - $alt_message = Context::getLang($alt_message); + $alt_message = lang($alt_message); $this->setMessage($alt_message, 'info'); //$this->setLayoutPath('./common/tpl'); diff --git a/modules/rss/rss.view.php b/modules/rss/rss.view.php index f37823cd9..1e7258089 100644 --- a/modules/rss/rss.view.php +++ b/modules/rss/rss.view.php @@ -227,7 +227,7 @@ class rssView extends rss function dispError() { // Prepare the output message - $this->rss(null, null, Context::getLang('msg_rss_is_disabled') ); + $this->rss(null, null, lang('msg_rss_is_disabled') ); } /** diff --git a/modules/session/session.admin.controller.php b/modules/session/session.admin.controller.php index 627043b4a..5dbc28e92 100644 --- a/modules/session/session.admin.controller.php +++ b/modules/session/session.admin.controller.php @@ -22,7 +22,7 @@ class sessionAdminController extends session $oSessionController = getController('session'); $oSessionController->gc(0); - $this->add('result',Context::getLang('session_cleared')); + $this->add('result',lang('session_cleared')); } } /* End of file session.admin.controller.php */ diff --git a/modules/spamfilter/spamfilter.admin.controller.php b/modules/spamfilter/spamfilter.admin.controller.php index af1969ffa..d2e78244c 100644 --- a/modules/spamfilter/spamfilter.admin.controller.php +++ b/modules/spamfilter/spamfilter.admin.controller.php @@ -41,8 +41,8 @@ class spamfilterAdminController extends spamfilter $output = $oSpamfilterController->insertIP($ipaddress_list); if(!$output->toBool() && !$output->get('fail_list')) return $output; - if($output->get('fail_list')) $message_fail = ''.sprintf(Context::getLang('msg_faillist'),$output->get('fail_list')).''; - $this->setMessage(Context::getLang('success_registed').$message_fail); + if($output->get('fail_list')) $message_fail = ''.sprintf(lang('msg_faillist'),$output->get('fail_list')).''; + $this->setMessage(lang('success_registed').$message_fail); } @@ -59,8 +59,8 @@ class spamfilterAdminController extends spamfilter $output = $this->insertWord($word_list); if(!$output->toBool() && !$output->get('fail_list')) return $output; - if($output->get('fail_list')) $message_fail = ''.sprintf(Context::getLang('msg_faillist'),$output->get('fail_list')).''; - $this->setMessage(Context::getLang('success_registed').$message_fail); + if($output->get('fail_list')) $message_fail = ''.sprintf(lang('msg_faillist'),$output->get('fail_list')).''; + $this->setMessage(lang('success_registed').$message_fail); } $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispSpamfilterAdminDeniedWordList'); @@ -75,7 +75,7 @@ class spamfilterAdminController extends spamfilter $ipAddressList = Context::get('ipaddress'); if($ipAddressList) $this->deleteIP($ipAddressList); - $this->setMessage(Context::getLang('success_deleted')); + $this->setMessage(lang('success_deleted')); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispSpamfilterAdminDeniedIPList'); return $this->setRedirectUrl($returnUrl); @@ -89,7 +89,7 @@ class spamfilterAdminController extends spamfilter $wordList = Context::get('word'); $this->deleteWord($wordList); - $this->setMessage(Context::getLang('success_deleted')); + $this->setMessage(lang('success_deleted')); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispSpamfilterAdminDeniedWordList','active','word'); return $this->setRedirectUrl($returnUrl); diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index a521e0bb0..e29bf0494 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -87,7 +87,7 @@ class spamfilterModel extends spamfilter { $args->word = $word; $output = executeQuery('spamfilter.updateDeniedWordHit', $args); - return new Object(-1,sprintf(Context::getLang('msg_alert_denied_word'), $word)); + return new Object(-1,sprintf(lang('msg_alert_denied_word'), $word)); } } @@ -120,11 +120,11 @@ class spamfilterModel extends spamfilter { if($isMessage) { - $message = sprintf(Context::getLang('msg_alert_limited_message_by_config'), $interval); + $message = sprintf(lang('msg_alert_limited_message_by_config'), $interval); } else { - $message = sprintf(Context::getLang('msg_alert_limited_by_config'), $interval); + $message = sprintf(lang('msg_alert_limited_by_config'), $interval); } $oSpamFilterController = getController('spamfilter'); diff --git a/modules/widget/widget.controller.php b/modules/widget/widget.controller.php index 1cd42c78c..bc0154136 100644 --- a/modules/widget/widget.controller.php +++ b/modules/widget/widget.controller.php @@ -51,7 +51,7 @@ class widgetController extends widget { $widget = Context::get('selected_widget'); if(!$widget) return new Object(-1,'msg_invalid_request'); - if(!Context::get('skin')) return new Object(-1,Context::getLang('msg_widget_skin_is_null')); + if(!Context::get('skin')) return new Object(-1,lang('msg_widget_skin_is_null')); $attribute = $this->arrangeWidgetVars($widget, Context::getRequestVars(), $vars); @@ -68,7 +68,7 @@ class widgetController extends widget $widget = Context::get('selected_widget'); if(!$widget) return new Object(-1,'msg_invalid_request'); - if(!in_array($widget,array('widgetBox','widgetContent')) && !Context::get('skin')) return new Object(-1,Context::getLang('msg_widget_skin_is_null')); + if(!in_array($widget,array('widgetBox','widgetContent')) && !Context::get('skin')) return new Object(-1,lang('msg_widget_skin_is_null')); $attribute = $this->arrangeWidgetVars($widget, Context::getRequestVars(), $vars); // Wanted results @@ -660,7 +660,7 @@ class widgetController extends widget { if(!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $widget)) { - return Context::getLang('msg_invalid_request'); + return lang('msg_invalid_request'); } if(!$GLOBALS['_xe_loaded_widgets_'][$widget]) @@ -670,20 +670,20 @@ class widgetController extends widget $path = $oWidgetModel->getWidgetPath($widget); // If you do not find the class file error output widget (html output) $class_file = sprintf('%s%s.class.php', $path, $widget); - if(!file_exists($class_file)) return sprintf(Context::getLang('msg_widget_is_not_exists'), $widget); + if(!file_exists($class_file)) return sprintf(lang('msg_widget_is_not_exists'), $widget); // Widget classes include require_once($class_file); // Creating Objects if(!class_exists($widget, false)) { - return sprintf(Context::getLang('msg_widget_object_is_null'), $widget); + return sprintf(lang('msg_widget_object_is_null'), $widget); } $oWidget = new $widget(); - if(!is_object($oWidget)) return sprintf(Context::getLang('msg_widget_object_is_null'), $widget); + if(!is_object($oWidget)) return sprintf(lang('msg_widget_object_is_null'), $widget); - if(!method_exists($oWidget, 'proc')) return sprintf(Context::getLang('msg_widget_proc_is_null'), $widget); + if(!method_exists($oWidget, 'proc')) return sprintf(lang('msg_widget_proc_is_null'), $widget); $oWidget->widget_path = $path; diff --git a/widgets/login_info/skins/xe_global/login_info.html b/widgets/login_info/skins/xe_global/login_info.html index f49cabf56..71f0c9781 100644 --- a/widgets/login_info/skins/xe_global/login_info.html +++ b/widgets/login_info/skins/xe_global/login_info.html @@ -19,7 +19,7 @@
        -
      • {Context::getLang($val)}
      • +
      • {lang($val)}
      • diff --git a/widgets/login_info/skins/xe_globalTwo/login_info.html b/widgets/login_info/skins/xe_globalTwo/login_info.html index 57e104dff..b3d8e882e 100644 --- a/widgets/login_info/skins/xe_globalTwo/login_info.html +++ b/widgets/login_info/skins/xe_globalTwo/login_info.html @@ -19,7 +19,7 @@
        -
      • {Context::getLang($val)}
      • +
      • {lang($val)}
      • diff --git a/widgets/login_info/skins/xe_official/login_info.html b/widgets/login_info/skins/xe_official/login_info.html index 5911eca27..d9cb71874 100644 --- a/widgets/login_info/skins/xe_official/login_info.html +++ b/widgets/login_info/skins/xe_official/login_info.html @@ -10,7 +10,7 @@

        {$lang->last_login}: {zDate($logged_info->last_login, "Y-m-d")}

diff --git a/widgets/login_info/skins/xe_solid_enterprise_login/login_info.html b/widgets/login_info/skins/xe_solid_enterprise_login/login_info.html index 738f4983d..30cf7c434 100644 --- a/widgets/login_info/skins/xe_solid_enterprise_login/login_info.html +++ b/widgets/login_info/skins/xe_solid_enterprise_login/login_info.html @@ -15,7 +15,7 @@
  • - {Context::getLang($val)}
  • + {lang($val)} {@ $i++;}
  • {$lang->cmd_management}
  • From f36724a96f9a94485b66b6a456bfb5a72fe4f4d2 Mon Sep 17 00:00:00 2001 From: YJSoft Date: Sun, 6 Mar 2016 18:14:25 +0900 Subject: [PATCH 085/318] =?UTF-8?q?=EB=B2=84=EC=A0=84=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/nfl/jquery-oembed-all 에서 가져옴. 코어에서 가져왔던 버전은 조금 구버전이라 2015년 8월 버전으로 가져옵니다. --- addons/oembed/jquery.oembed.js | 1969 ++++++++++++++++---------------- 1 file changed, 957 insertions(+), 1012 deletions(-) diff --git a/addons/oembed/jquery.oembed.js b/addons/oembed/jquery.oembed.js index dd17f4841..07ed993a5 100755 --- a/addons/oembed/jquery.oembed.js +++ b/addons/oembed/jquery.oembed.js @@ -5,1054 +5,999 @@ * Licensed under the MIT license * * Orignal Author: Richard Chamorro - * Forked by Andrew Mee to Provide a slightly diffent kind of embedding - * experience - * - * Modified : NAVER Corp. + * Forked by Andrew Mee to Provide a slightly diffent kind of embedding experience */ (function ($) { - $.fn.oembed = function (url, options, embedAction) { - settings = $.extend(true, $.fn.oembed.defaults, options); - var shortURLList = ["0rz.tw", "1link.in", "1url.com", "2.gp", "2big.at", "2tu.us", "3.ly", "307.to", "4ms.me", "4sq.com", "4url.cc", "6url.com", "7.ly", "a.gg", "a.nf", "aa.cx", "abcurl.net", - "ad.vu", "adf.ly", "adjix.com", "afx.cc", "all.fuseurl.com", "alturl.com", "amzn.to", "ar.gy", "arst.ch", "atu.ca", "azc.cc", "b23.ru", "b2l.me", "bacn.me", "bcool.bz", "binged.it", - "bit.ly", "bizj.us", "bloat.me", "bravo.ly", "bsa.ly", "budurl.com", "canurl.com", "chilp.it", "chzb.gr", "cl.lk", "cl.ly", "clck.ru", "cli.gs", "cliccami.info", - "clickthru.ca", "clop.in", "conta.cc", "cort.as", "cot.ag", "crks.me", "ctvr.us", "cutt.us", "dai.ly", "decenturl.com", "dfl8.me", "digbig.com", - "http:\/\/digg\.com\/[^\/]+$", "disq.us", "dld.bz", "dlvr.it", "do.my", "doiop.com", "dopen.us", "easyuri.com", "easyurl.net", "eepurl.com", "eweri.com", - "fa.by", "fav.me", "fb.me", "fbshare.me", "ff.im", "fff.to", "fire.to", "firsturl.de", "firsturl.net", "flic.kr", "flq.us", "fly2.ws", "fon.gs", "freak.to", - "fuseurl.com", "fuzzy.to", "fwd4.me", "fwib.net", "g.ro.lt", "gizmo.do", "gl.am", "go.9nl.com", "go.ign.com", "go.usa.gov", "goo.gl", "goshrink.com", "gurl.es", - "hex.io", "hiderefer.com", "hmm.ph", "href.in", "hsblinks.com", "htxt.it", "huff.to", "hulu.com", "hurl.me", "hurl.ws", "icanhaz.com", "idek.net", "ilix.in", "is.gd", - "its.my", "ix.lt", "j.mp", "jijr.com", "kl.am", "klck.me", "korta.nu", "krunchd.com", "l9k.net", "lat.ms", "liip.to", "liltext.com", "linkbee.com", "linkbun.ch", - "liurl.cn", "ln-s.net", "ln-s.ru", "lnk.gd", "lnk.ms", "lnkd.in", "lnkurl.com", "lru.jp", "lt.tl", "lurl.no", "macte.ch", "mash.to", "merky.de", "migre.me", "miniurl.com", - "minurl.fr", "mke.me", "moby.to", "moourl.com", "mrte.ch", "myloc.me", "myurl.in", "n.pr", "nbc.co", "nblo.gs", "nn.nf", "not.my", "notlong.com", "nsfw.in", - "nutshellurl.com", "nxy.in", "nyti.ms", "o-x.fr", "oc1.us", "om.ly", "omf.gd", "omoikane.net", "on.cnn.com", "on.mktw.net", "onforb.es", "orz.se", "ow.ly", "ping.fm", - "pli.gs", "pnt.me", "politi.co", "post.ly", "pp.gg", "profile.to", "ptiturl.com", "pub.vitrue.com", "qlnk.net", "qte.me", "qu.tc", "qy.fi", "r.ebay.com", "r.im", "rb6.me", "read.bi", - "readthis.ca", "reallytinyurl.com", "redir.ec", "redirects.ca", "redirx.com", "retwt.me", "ri.ms", "rickroll.it", "riz.gd", "rt.nu", "ru.ly", "rubyurl.com", "rurl.org", - "rww.tw", "s4c.in", "s7y.us", "safe.mn", "sameurl.com", "sdut.us", "shar.es", "shink.de", "shorl.com", "short.ie", "short.to", "shortlinks.co.uk", "shorturl.com", - "shout.to", "show.my", "shrinkify.com", "shrinkr.com", "shrt.fr", "shrt.st", "shrten.com", "shrunkin.com", "simurl.com", "slate.me", "smallr.com", "smsh.me", "smurl.name", - "sn.im", "snipr.com", "snipurl.com", "snurl.com", "sp2.ro", "spedr.com", "srnk.net", "srs.li", "starturl.com", "stks.co", "su.pr", "surl.co.uk", "surl.hu", "t.cn", "t.co", "t.lh.com", - "ta.gd", "tbd.ly", "tcrn.ch", "tgr.me", "tgr.ph", "tighturl.com", "tiniuri.com", "tiny.cc", "tiny.ly", "tiny.pl", "tinylink.in", "tinyuri.ca", "tinyurl.com", "tk.", "tl.gd", - "tmi.me", "tnij.org", "tnw.to", "tny.com", "to.ly", "togoto.us", "totc.us", "toysr.us", "tpm.ly", "tr.im", "tra.kz", "trunc.it", "twhub.com", "twirl.at", - "twitclicks.com", "twitterurl.net", "twitterurl.org", "twiturl.de", "twurl.cc", "twurl.nl", "u.mavrev.com", "u.nu", "u76.org", "ub0.cc", "ulu.lu", "updating.me", "ur1.ca", - "url.az", "url.co.uk", "url.ie", "url360.me", "url4.eu", "urlborg.com", "urlbrief.com", "urlcover.com", "urlcut.com", "urlenco.de", "urli.nl", "urls.im", - "urlshorteningservicefortwitter.com", "urlx.ie", "urlzen.com", "usat.ly", "use.my", "vb.ly", "vevo.ly", "vgn.am", "vl.am", "vm.lc", "w55.de", "wapo.st", "wapurl.co.uk", "wipi.es", - "wp.me", "x.vu", "xr.com", "xrl.in", "xrl.us", "xurl.es", "xurl.jp", "y.ahoo.it", "yatuc.com", "ye.pe", "yep.it", "yfrog.com", "yhoo.it", "yiyd.com", "youtu.be", "yuarel.com", - "z0p.de", "zi.ma", "zi.mu", "zipmyurl.com", "zud.me", "zurl.ws", "zz.gd", "zzang.kr", "›.ws", "✩.ws", "✿.ws", "❥.ws", "➔.ws", "➞.ws", "➡.ws", "➨.ws", "➯.ws", "➹.ws", "➽.ws" - ]; + $.fn.oembed = function (url, options, embedAction) { - if($('#jqoembeddata').length === 0) $('').appendTo('body'); + settings = $.extend(true, $.fn.oembed.defaults, options); + var shortURLList = ["0rz.tw", "1link.in", "1url.com", "2.gp", "2big.at", "2tu.us", "3.ly", "307.to", "4ms.me", "4sq.com", "4url.cc", "6url.com", "7.ly", "a.gg", "a.nf", "aa.cx", "abcurl.net", + "ad.vu", "adf.ly", "adjix.com", "afx.cc", "all.fuseurl.com", "alturl.com", "amzn.to", "ar.gy", "arst.ch", "atu.ca", "azc.cc", "b23.ru", "b2l.me", "bacn.me", "bcool.bz", "binged.it", + "bit.ly", "bizj.us", "bloat.me", "bravo.ly", "bsa.ly", "budurl.com", "canurl.com", "chilp.it", "chzb.gr", "cl.lk", "cl.ly", "clck.ru", "cli.gs", "cliccami.info", + "clickthru.ca", "clop.in", "conta.cc", "cort.as", "cot.ag", "crks.me", "ctvr.us", "cutt.us", "dai.ly", "decenturl.com", "dfl8.me", "digbig.com", + "http:\/\/digg\.com\/[^\/]+$", "disq.us", "dld.bz", "dlvr.it", "do.my", "doiop.com", "dopen.us", "easyuri.com", "easyurl.net", "eepurl.com", "eweri.com", + "fa.by", "fav.me", "fb.me", "fbshare.me", "ff.im", "fff.to", "fire.to", "firsturl.de", "firsturl.net", "flic.kr", "flq.us", "fly2.ws", "fon.gs", "freak.to", + "fuseurl.com", "fuzzy.to", "fwd4.me", "fwib.net", "g.ro.lt", "gizmo.do", "gl.am", "go.9nl.com", "go.ign.com", "go.usa.gov", "goo.gl", "goshrink.com", "gurl.es", + "hex.io", "hiderefer.com", "hmm.ph", "href.in", "hsblinks.com", "htxt.it", "huff.to", "hulu.com", "hurl.me", "hurl.ws", "icanhaz.com", "idek.net", "ilix.in", "is.gd", + "its.my", "ix.lt", "j.mp", "jijr.com", "kl.am", "klck.me", "korta.nu", "krunchd.com", "l9k.net", "lat.ms", "liip.to", "liltext.com", "linkbee.com", "linkbun.ch", + "liurl.cn", "ln-s.net", "ln-s.ru", "lnk.gd", "lnk.ms", "lnkd.in", "lnkurl.com", "lru.jp", "lt.tl", "lurl.no", "macte.ch", "mash.to", "merky.de", "migre.me", "miniurl.com", + "minurl.fr", "mke.me", "moby.to", "moourl.com", "mrte.ch", "myloc.me", "myurl.in", "n.pr", "nbc.co", "nblo.gs", "nn.nf", "not.my", "notlong.com", "nsfw.in", + "nutshellurl.com", "nxy.in", "nyti.ms", "o-x.fr", "oc1.us", "om.ly", "omf.gd", "omoikane.net", "on.cnn.com", "on.mktw.net", "onforb.es", "orz.se", "ow.ly", "ping.fm", + "pli.gs", "pnt.me", "politi.co", "post.ly", "pp.gg", "profile.to", "ptiturl.com", "pub.vitrue.com", "qlnk.net", "qte.me", "qu.tc", "qy.fi", "r.ebay.com", "r.im", "rb6.me", "read.bi", + "readthis.ca", "reallytinyurl.com", "redir.ec", "redirects.ca", "redirx.com", "retwt.me", "ri.ms", "rickroll.it", "riz.gd", "rt.nu", "ru.ly", "rubyurl.com", "rurl.org", + "rww.tw", "s4c.in", "s7y.us", "safe.mn", "sameurl.com", "sdut.us", "shar.es", "shink.de", "shorl.com", "short.ie", "short.to", "shortlinks.co.uk", "shorturl.com", + "shout.to", "show.my", "shrinkify.com", "shrinkr.com", "shrt.fr", "shrt.st", "shrten.com", "shrunkin.com", "simurl.com", "slate.me", "smallr.com", "smsh.me", "smurl.name", + "sn.im", "snipr.com", "snipurl.com", "snurl.com", "sp2.ro", "spedr.com", "srnk.net", "srs.li", "starturl.com", "stks.co", "su.pr", "surl.co.uk", "surl.hu", "t.cn", "t.co", "t.lh.com", + "ta.gd", "tbd.ly", "tcrn.ch", "tgr.me", "tgr.ph", "tighturl.com", "tiniuri.com", "tiny.cc", "tiny.ly", "tiny.pl", "tinylink.in", "tinyuri.ca", "tinyurl.com", "tk.", "tl.gd", + "tmi.me", "tnij.org", "tnw.to", "tny.com", "to.ly", "togoto.us", "totc.us", "toysr.us", "tpm.ly", "tr.im", "tra.kz", "trunc.it", "twhub.com", "twirl.at", + "twitclicks.com", "twitterurl.net", "twitterurl.org", "twiturl.de", "twurl.cc", "twurl.nl", "u.mavrev.com", "u.nu", "u76.org", "ub0.cc", "ulu.lu", "updating.me", "ur1.ca", + "url.az", "url.co.uk", "url.ie", "url360.me", "url4.eu", "urlborg.com", "urlbrief.com", "urlcover.com", "urlcut.com", "urlenco.de", "urli.nl", "urls.im", + "urlshorteningservicefortwitter.com", "urlx.ie", "urlzen.com", "usat.ly", "use.my", "vb.ly", "vevo.ly", "vgn.am", "vl.am", "vm.lc", "w55.de", "wapo.st", "wapurl.co.uk", "wipi.es", + "wp.me", "x.vu", "xr.com", "xrl.in", "xrl.us", "xurl.es", "xurl.jp", "y.ahoo.it", "yatuc.com", "ye.pe", "yep.it", "yfrog.com", "yhoo.it", "yiyd.com", "youtu.be", "yuarel.com", + "z0p.de", "zi.ma", "zi.mu", "zipmyurl.com", "zud.me", "zurl.ws", "zz.gd", "zzang.kr", "›.ws", "✩.ws", "✿.ws", "❥.ws", "➔.ws", "➞.ws", "➡.ws", "➨.ws", "➯.ws", "➹.ws", "➽.ws"]; - return this.each(function () { - var container = $(this), - resourceURL = (url && (!url.indexOf('http://') || !url.indexOf('https://'))) ? url : container.attr("href"), - provider; + if ($('#jqoembeddata').length === 0) $('').appendTo('body'); - if(embedAction) { - settings.onEmbed = embedAction; - } else if(!settings.onEmbed) { - settings.onEmbed = function (oembedData) { - $.fn.oembed.insertCode(this, settings.embedMethod, oembedData); - }; - } + return this.each(function () { + var container = $(this), + resourceURL = (url && (!url.indexOf('http://') || !url.indexOf('https://'))) ? url : container.attr("href"), + provider; - if(resourceURL !== null && resourceURL !== undefined) { - //Check if shorten URL - for(var j = 0, l = shortURLList.length; j < l; j++) { - var regExp = new RegExp('://' + shortURLList[j] + '/', "i"); - if(resourceURL.match(regExp) !== null) { - //AJAX to http://api.longurl.org/v2/expand?url=http://bit.ly/JATvIs&format=json&callback=hhh - var ajaxopts = $.extend({ - url: "http://api.longurl.org/v2/expand", - dataType: 'jsonp', - data: { - url: resourceURL, - format: "json" - //callback: "?" - }, - success: function (data) { - //this = $.fn.oembed; - resourceURL = data['long-url']; - provider = $.fn.oembed.getOEmbedProvider(data['long-url']); + if (embedAction) { + settings.onEmbed = embedAction; + } + else if (!settings.onEmbed) { + settings.onEmbed = function (oembedData) { + $.fn.oembed.insertCode(this, settings.embedMethod, oembedData); + }; + } - if(provider !== null) { - provider.params = getNormalizedParams(settings[provider.name]) || {}; - provider.maxWidth = settings.maxWidth; - provider.maxHeight = settings.maxHeight; - embedCode(container, resourceURL, provider); - } else { - settings.onProviderNotFound.call(container, resourceURL); - } - } - }, settings.ajaxOptions || {}); + if (resourceURL !== null && resourceURL !== undefined) { + //Check if shorten URL + for (var j = 0, l = shortURLList.length; j < l; j++) { + var regExp = new RegExp('://' + shortURLList[j] + '/', "i"); - $.ajax(ajaxopts); + if (resourceURL.match(regExp) !== null) { + //AJAX to http://api.longurl.org/v2/expand?url=http://bit.ly/JATvIs&format=json&callback=hhh + var ajaxopts = $.extend({ + url: "http://api.longurl.org/v2/expand", + dataType: 'jsonp', + data: { + url: resourceURL, + format: "json" + //callback: "?" + }, + success: function (data) { + //this = $.fn.oembed; + resourceURL = data['long-url']; + provider = $.fn.oembed.getOEmbedProvider(data['long-url']); - return container; - } - } - provider = $.fn.oembed.getOEmbedProvider(resourceURL); + //remove fallback + if (!!settings.fallback === false) { + provider = provider.name.toLowerCase() === 'opengraph' ? null : provider; + } - if(provider !== null) { - provider.params = getNormalizedParams(settings[provider.name]) || {}; - provider.maxWidth = settings.maxWidth; - provider.maxHeight = settings.maxHeight; - embedCode(container, resourceURL, provider); - } else { - settings.onProviderNotFound.call(container, resourceURL); - } - } + if (provider !== null) { + provider.params = getNormalizedParams(settings[provider.name]) || {}; + provider.maxWidth = settings.maxWidth; + provider.maxHeight = settings.maxHeight; + embedCode(container, resourceURL, provider); + } else { + settings.onProviderNotFound.call(container, resourceURL); + } + }, + error: function () { + settings.onError.call(container, resourceURL) + } + }, settings.longUrlAjaxOptions || settings.ajaxOptions || {}); - return container; - }); + $.ajax(ajaxopts); + + return container; + } + } + provider = $.fn.oembed.getOEmbedProvider(resourceURL); + + //remove fallback + if (!!settings.fallback === false) { + provider = provider.name.toLowerCase() === 'opengraph' ? null : provider; + } + if (provider !== null) { + provider.params = getNormalizedParams(settings[provider.name]) || {}; + provider.maxWidth = settings.maxWidth; + provider.maxHeight = settings.maxHeight; + embedCode(container, resourceURL, provider); + } else { + settings.onProviderNotFound.call(container, resourceURL); + } + } + return container; + }); + }; + + var settings; + + // Plugin defaults + $.fn.oembed.defaults = { + fallback: true, + maxWidth: null, + maxHeight: null, + includeHandle: true, + embedMethod: 'auto', + // "auto", "append", "fill" + onProviderNotFound: function () { + }, + beforeEmbed: function () { + }, + afterEmbed: function () { + }, + onEmbed: false, + onError: function (a, b, c, d) { + console.log('err:', a, b, c, d) + }, + ajaxOptions: {}, + longUrlAjaxOptions: {} + }; + + /* Private functions */ + function rand(length, current) { //Found on http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript + current = current ? current : ''; + return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current; + } + + function getRequestUrl(provider, externalUrl) { + var url = provider.apiendpoint, + qs = "", + i; + url += (url.indexOf("?") <= 0) ? "?" : "&"; + url = url.replace('#', '%23'); + + if (provider.maxWidth !== null && (typeof provider.params.maxwidth === 'undefined' || provider.params.maxwidth === null)) { + provider.params.maxwidth = provider.maxWidth; + } + + if (provider.maxHeight !== null && (typeof provider.params.maxheight === 'undefined' || provider.params.maxheight === null)) { + provider.params.maxheight = provider.maxHeight; + } + + for (i in provider.params) { + // We don't want them to jack everything up by changing the callback parameter + if (i == provider.callbackparameter) + continue; + + // allows the options to be set to null, don't send null values to the server as parameters + if (provider.params[i] !== null) + qs += "&" + escape(i) + "=" + provider.params[i]; + } + + url += "format=" + provider.format + "&url=" + escape(externalUrl) + qs; + if (provider.dataType != 'json') + url += "&" + provider.callbackparameter + "=?"; + + return url; + } + + function success(oembedData, externalUrl, container) { + $('#jqoembeddata').data(externalUrl, oembedData.code); + settings.beforeEmbed.call(container, oembedData); + settings.onEmbed.call(container, oembedData); + settings.afterEmbed.call(container, oembedData); + } + + function embedCode(container, externalUrl, embedProvider) { + if ($('#jqoembeddata').data(externalUrl) != undefined && embedProvider.embedtag.tag != 'iframe') { + var oembedData = {code: $('#jqoembeddata').data(externalUrl)}; + success(oembedData, externalUrl, container); + } else if (embedProvider.yql) { + var from = embedProvider.yql.from || 'htmlstring'; + var url = embedProvider.yql.url ? embedProvider.yql.url(externalUrl) : externalUrl; + var query = 'SELECT * FROM ' + from + + ' WHERE url="' + (url) + '"' + + " and " + (/html/.test(from) ? 'xpath' : 'itemPath') + "='" + (embedProvider.yql.xpath || '/') + "'"; + if (from == 'html') + query += " and compat='html5'"; + var ajaxopts = $.extend({ + url: "//query.yahooapis.com/v1/public/yql", + dataType: 'jsonp', + data: { + q: query, + format: "json", + env: 'store://datatables.org/alltableswithkeys', + callback: "?" + }, + success: function (data) { + var result; + + if (embedProvider.yql.xpath && embedProvider.yql.xpath == '//meta|//title|//link') { + var meta = {}; + + if (data.query == null) { + data.query = {}; + } + if (data.query.results == null) { + data.query.results = {"meta": []}; + } + for (var i = 0, l = data.query.results.meta.length; i < l; i++) { + var name = data.query.results.meta[i].name || data.query.results.meta[i].property || null; + if (name == null)continue; + meta[name.toLowerCase()] = data.query.results.meta[i].content; + } + if (!meta.hasOwnProperty("title") || !meta.hasOwnProperty("og:title")) { + if (data.query.results.title != null) { + meta.title = data.query.results.title; + } + } + if (!meta.hasOwnProperty("og:image") && data.query.results.hasOwnProperty("link")) { + for (var i = 0, l = data.query.results.link.length; i < l; i++) { + if (data.query.results.link[i].hasOwnProperty("rel")) { + if (data.query.results.link[i].rel == "apple-touch-icon") { + if (data.query.results.link[i].href.charAt(0) == "/") { + meta["og:image"] = url.match(/^(([a-z]+:)?(\/\/)?[^\/]+\/).*$/)[1] + data.query.results.link[i].href; + } else { + meta["og:image"] = data.query.results.link[i].href; + } + } + } + } + } + result = embedProvider.yql.datareturn(meta); + } else { + result = embedProvider.yql.datareturn ? embedProvider.yql.datareturn(data.query.results) : data.query.results.result; + } + if (result === false)return; + var oembedData = $.extend({}, result); + oembedData.code = result; + success(oembedData, externalUrl, container); + }, + error: settings.onError.call(container, externalUrl, embedProvider) + }, settings.ajaxOptions || {}); + $.ajax(ajaxopts); + } else if (embedProvider.templateRegex) { + if (embedProvider.embedtag.tag !== '') { + var flashvars = embedProvider.embedtag.flashvars || ''; + var tag = embedProvider.embedtag.tag || 'embed'; + var width = embedProvider.embedtag.width || 'auto'; + var height = embedProvider.embedtag.height || 'auto'; + var src = externalUrl.replace(embedProvider.templateRegex, embedProvider.apiendpoint); + + if (!embedProvider.nocache) { + src += '&jqoemcache=' + rand(5); + } + + if (embedProvider.apikey) { + src = src.replace('_APIKEY_', settings.apikeys[embedProvider.name]); + } + + var code = $('<' + tag + '/>').attr('src', src).attr('width', width) + .attr('height', height) + .attr('allowfullscreen', embedProvider.embedtag.allowfullscreen || 'true') + .attr('allowscriptaccess', embedProvider.embedtag.allowfullscreen || 'always') + .css('max-height', settings.maxHeight || 'auto') + .css('max-width', settings.maxWidth || 'auto'); + + if (tag == 'embed') { + code.attr('type', embedProvider.embedtag.type || "application/x-shockwave-flash") + .attr('flashvars', externalUrl.replace(embedProvider.templateRegex, flashvars)); + } + + if (tag == 'iframe') { + code.attr('scrolling', embedProvider.embedtag.scrolling || "no") + .attr('frameborder', embedProvider.embedtag.frameborder || "0"); + + } + + success({code: code}, externalUrl, container); + } else if (embedProvider.apiendpoint) { + //Add APIkey if true + if (embedProvider.apikey) + embedProvider.apiendpoint = embedProvider.apiendpoint.replace('_APIKEY_', settings.apikeys[embedProvider.name]); + + ajaxopts = $.extend({ + url: externalUrl.replace(embedProvider.templateRegex, embedProvider.apiendpoint), + dataType: 'jsonp', + success: function (data) { + var oembedData = $.extend({}, data); + oembedData.code = embedProvider.templateData(data); + success(oembedData, externalUrl, container); + }, + error: settings.onError.call(container, externalUrl, embedProvider) + }, settings.ajaxOptions || {}); + $.ajax(ajaxopts); + } else { + success({code: externalUrl.replace(embedProvider.templateRegex, embedProvider.template)}, externalUrl, container); + } + } else { + + var requestUrl = getRequestUrl(embedProvider, externalUrl); + ajaxopts = $.extend({ + url: requestUrl, + dataType: embedProvider.dataType || 'jsonp', + success: function (data) { + var oembedData = $.extend({}, data); + switch (oembedData.type) { + case "file": //Deviant Art has this + case "photo": + oembedData.code = $.fn.oembed.getPhotoCode(externalUrl, oembedData); + break; + case "video": + case "rich": + oembedData.code = $.fn.oembed.getRichCode(externalUrl, oembedData); + break; + default: + oembedData.code = $.fn.oembed.getGenericCode(externalUrl, oembedData); + break; + } + success(oembedData, externalUrl, container); + }, + error: settings.onError.call(container, externalUrl, embedProvider) + }, settings.ajaxOptions || {}); + $.ajax(ajaxopts); + } + } + + function getNormalizedParams(params) { + if (params === null) return null; + var key, normalizedParams = {}; + for (key in params) { + if (key !== null) normalizedParams[key.toLowerCase()] = params[key]; + } + return normalizedParams; + } + + /* Public functions */ + $.fn.oembed.insertCode = function (container, embedMethod, oembedData) { + if (oembedData === null) + return; + + if (embedMethod === 'auto' && container.attr('href') !== null) { + embedMethod = 'append'; + } else if (embedMethod == 'auto') { + embedMethod = 'replace'; + } + + switch (embedMethod) { + case "replace": + container.replaceWith(oembedData.code); + break; + case "fill": + container.html(oembedData.code); + break; + case "append": + container.wrap('
    '); + var oembedContainer = container.parent(); + if (settings.includeHandle) { + $('').insertBefore(container).click(function () { + var encodedString = encodeURIComponent($(this).text()); + $(this).html((encodedString == '%E2%86%91') ? '↓' : '↑'); + $(this).parent().children().last().toggle(); + }); + } + oembedContainer.append('
    '); + try { + oembedData.code.clone().appendTo(oembedContainer); + } catch (e) { + oembedContainer.append(oembedData.code); + } + /* Make videos semi-responsive + * If parent div width less than embeded iframe video then iframe gets shrunk to fit smaller width + * If parent div width greater thans embed iframe use the max widht + * - works on youtubes and vimeo + */ + if (settings.maxWidth) { + var post_width = oembedContainer.parent().width(); + if (post_width < settings.maxWidth) { + var iframe_width_orig = $('iframe', oembedContainer).width(); + var iframe_height_orig = $('iframe', oembedContainer).height(); + var ratio = iframe_width_orig / post_width; + $('iframe', oembedContainer).width(iframe_width_orig / ratio); + $('iframe', oembedContainer).height(iframe_height_orig / ratio); + } else { + if (settings.maxWidth) { + $('iframe', oembedContainer).width(settings.maxWidth); + } + if (settings.maxHeight) { + $('iframe', oembedContainer).height(settings.maxHeight); + } + } + } + break; + } + }; + + $.fn.oembed.getPhotoCode = function (url, oembedData) { + var code; + var alt = oembedData.title ? oembedData.title : ''; + alt += oembedData.author_name ? ' - ' + oembedData.author_name : ''; + alt += oembedData.provider_name ? ' - ' + oembedData.provider_name : ''; + + if (oembedData.url) { + code = '
    ' + alt + '
    '; + } else if (oembedData.thumbnail_url) { + var newURL = oembedData.thumbnail_url.replace('_s', '_b'); + code = '
    ' + alt + '
    '; + } else { + code = '
    Error loading this picture
    '; + } + + if (oembedData.html) { + code += "
    " + oembedData.html + "
    "; + } + + return code; + }; + + $.fn.oembed.getRichCode = function (url, oembedData) { + return oembedData.html; + }; + + $.fn.oembed.getGenericCode = function (url, oembedData) { + var title = ((oembedData.title) && (oembedData.title !== null)) ? oembedData.title : url; + var code = '' + title + ''; + + if (oembedData.html) { + code += "
    " + oembedData.html + "
    "; + } + + return code; + }; + + $.fn.oembed.getOEmbedProvider = function (url) { + for (var i = 0; i < $.fn.oembed.providers.length; i++) { + for (var j = 0, l = $.fn.oembed.providers[i].urlschemes.length; j < l; j++) { + var regExp = new RegExp($.fn.oembed.providers[i].urlschemes[j], "i"); + + if (url.match(regExp) !== null) + return $.fn.oembed.providers[i]; + } + } + return null; + }; + + // Constructor Function for OEmbedProvider Class. + $.fn.oembed.OEmbedProvider = function (name, type, urlschemesarray, apiendpoint, extraSettings) { + this.name = name; + this.type = type; // "photo", "video", "link", "rich", null + this.urlschemes = urlschemesarray; + this.apiendpoint = apiendpoint; + this.maxWidth = 500; + this.maxHeight = 400; + extraSettings = extraSettings || {}; + + if (extraSettings.useYQL) { + + if (extraSettings.useYQL == 'xml') { + extraSettings.yql = { + xpath: "//oembed/html", + from: 'xml', + apiendpoint: this.apiendpoint, + url: function (externalurl) { + return this.apiendpoint + '?format=xml&url=' + externalurl + }, + datareturn: function (results) { + return results.html.replace(/.*\[CDATA\[(.*)\]\]>$/, '$1') || '' + } + }; + } else { + extraSettings.yql = { + from: 'json', + apiendpoint: this.apiendpoint, + url: function (externalurl) { + return this.apiendpoint + '?format=json&url=' + externalurl + }, + datareturn: function (results) { + if (results.json.type != 'video' && (results.json.url || results.json.thumbnail_url)) { + return ''; + } + return results.json.html || '' + } + }; + } + this.apiendpoint = null; + } - }; + for (var property in extraSettings) { + this[property] = extraSettings[property]; + } - var settings; + this.format = this.format || 'json'; + this.callbackparameter = this.callbackparameter || "callback"; + this.embedtag = this.embedtag || {tag: ""}; - // Plugin defaults - $.fn.oembed.defaults = { - maxWidth: null, - maxHeight: null, - includeHandle: true, - embedMethod: 'auto', - // "auto", "append", "fill" - onProviderNotFound: function () {}, - beforeEmbed: function () {}, - afterEmbed: function () {}, - onEmbed: false, - onError: function () {}, - ajaxOptions: {} - }; - /* Private functions */ - function rand(length, current) { //Found on http://stackoverflow.com/questions/1349404/generate-a-string-of-5-random-characters-in-javascript - current = current ? current : ''; - return length ? rand(--length, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random() * 60)) + current) : current; - } + }; - function getRequestUrl(provider, externalUrl) { - var url = provider.apiendpoint, - qs = "", - i; - url += (url.indexOf("?") <= 0) ? "?" : "&"; - url = url.replace('#', '%23'); + /* + * Function to update existing providers + * + * @param {String} name The name of the provider + * @param {String} type The type of the provider can be "file", "photo", "video", "rich" + * @param {String} urlshemesarray Array of url of the provider + * @param {String} apiendpoint The endpoint of the provider + * @param {String} extraSettings Extra settings of the provider + */ + $.fn.updateOEmbedProvider = function (name, type, urlschemesarray, apiendpoint, extraSettings) { + for (var i = 0; i < $.fn.oembed.providers.length; i++) { + if ($.fn.oembed.providers[i].name === name) { + if (type !== null) { + $.fn.oembed.providers[i].type = type; + } + if (urlschemesarray !== null) { + $.fn.oembed.providers[i].urlschemes = urlschemesarray; + } + if (apiendpoint !== null) { + $.fn.oembed.providers[i].apiendpoint = apiendpoint; + } + if (extraSettings !== null) { + $.fn.oembed.providers[i].extraSettings = extraSettings; + for (var property in extraSettings) { + if (property !== null && extraSettings[property] !== null) { + $.fn.oembed.providers[i][property] = extraSettings[property]; + } + } + } + } + } + }; - if(provider.maxWidth !== null && (typeof provider.params.maxwidth === 'undefined' || provider.params.maxwidth === null)) { - provider.params.maxwidth = provider.maxWidth; - } + /* Native & common providers */ + $.fn.oembed.providers = [ - if(provider.maxHeight !== null && (typeof provider.params.maxheight === 'undefined' || provider.params.maxheight === null)) { - provider.params.maxheight = provider.maxHeight; - } + //Video + new $.fn.oembed.OEmbedProvider("youtube", "video", ["youtube\\.com/watch.+v=[\\w-]+&?", "youtu\\.be/[\\w-]+", "youtube.com/embed"], '//www.youtube.com/embed/$1?wmode=transparent', { + templateRegex: /.*(?:v\=|be\/|embed\/)([\w\-]+)&?.*/, embedtag: {tag: 'iframe', width: '425', height: '349'} + }), - for(i in provider.params) { - // We don't want them to jack everything up by changing the callback parameter - if(i == provider.callbackparameter) continue; + //new $.fn.oembed.OEmbedProvider("youtube", "video", ["youtube\\.com/watch.+v=[\\w-]+&?", "youtu\\.be/[\\w-]+"], 'http://www.youtube.com/oembed', {useYQL:'json'}), + //new $.fn.oembed.OEmbedProvider("youtubeiframe", "video", ["youtube.com/embed"], "$1?wmode=transparent", + // {templateRegex:/(.*)/,embedtag : {tag: 'iframe', width:'425',height: '349'}}), + new $.fn.oembed.OEmbedProvider("wistia", "video", ["wistia.com/medias/.+", "wistia.com/m/.+", "wistia.com/embed/.+", "wi.st/m/.+", "wi.st/embed/.+"], 'http://fast.wistia.com/oembed', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("xtranormal", "video", ["xtranormal\\.com/watch/.+"], "http://www.xtranormal.com/xtraplayr/$1/$2", { + templateRegex: /.*com\/watch\/([\w\-]+)\/([\w\-]+).*/, embedtag: {tag: 'iframe', width: '320', height: '269'}}), + new $.fn.oembed.OEmbedProvider("scivee", "video", ["scivee.tv/node/.+"], "http://www.scivee.tv/flash/embedCast.swf?", { + templateRegex: /.*tv\/node\/(.+)/, embedtag: {width: '480', height: '400', flashvars: "id=$1&type=3"}}), + new $.fn.oembed.OEmbedProvider("veoh", "video", ["veoh.com/watch/.+"], "http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1337&permalinkId=$1&player=videodetailsembedded&videoAutoPlay=0&id=anonymous", { + templateRegex: /.*watch\/([^\?]+).*/, embedtag: {width: '410', height: '341'}}), + new $.fn.oembed.OEmbedProvider("gametrailers", "video", ["gametrailers\\.com/video/.+"], "http://media.mtvnservices.com/mgid:moses:video:gametrailers.com:$2", { + templateRegex: /.*com\/video\/([\w\-]+)\/([\w\-]+).*/, embedtag: {width: '512', height: '288' }}), + new $.fn.oembed.OEmbedProvider("funnyordie", "video", ["funnyordie\\.com/videos/.+"], "http://player.ordienetworks.com/flash/fodplayer.swf?", { + templateRegex: /.*videos\/([^\/]+)\/([^\/]+)?/, embedtag: {width: 512, height: 328, flashvars: "key=$1"}}), + new $.fn.oembed.OEmbedProvider("colledgehumour", "video", ["collegehumor\\.com/video/.+"], "http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=$1&use_node_id=true&fullscreen=1", + {templateRegex: /.*video\/([^\/]+).*/, embedtag: {width: 600, height: 338}}), + new $.fn.oembed.OEmbedProvider("metacafe", "video", ["metacafe\\.com/watch/.+"], "http://www.metacafe.com/fplayer/$1/$2.swf", + {templateRegex: /.*watch\/(\d+)\/(\w+)\/.*/, embedtag: {width: 400, height: 345}}), + new $.fn.oembed.OEmbedProvider("bambuser", "video", ["bambuser\\.com\/channel\/.*\/broadcast\/.*"], "http://static.bambuser.com/r/player.swf?vid=$1", + {templateRegex: /.*bambuser\.com\/channel\/.*\/broadcast\/(\w+).*/, embedtag: {width: 512, height: 339 }}), + new $.fn.oembed.OEmbedProvider("twitvid", "video", ["twitvid\\.com/.+"], "http://www.twitvid.com/embed.php?guid=$1&autoplay=0", + {templateRegex: /.*twitvid\.com\/(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }}), + new $.fn.oembed.OEmbedProvider("aniboom", "video", ["aniboom\\.com/animation-video/.+"], "http://api.aniboom.com/e/$1", + {templateRegex: /.*animation-video\/(\d+).*/, embedtag: {width: 594, height: 334}}), + new $.fn.oembed.OEmbedProvider("vzaar", "video", ["vzaar\\.com/videos/.+", "vzaar.tv/.+"], "http://view.vzaar.com/$1/player?", + {templateRegex: /.*\/(\d+).*/, embedtag: {tag: 'iframe', width: 576, height: 324 }}), + new $.fn.oembed.OEmbedProvider("snotr", "video", ["snotr\\.com/video/.+"], "http://www.snotr.com/embed/$1", + {templateRegex: /.*\/(\d+).*/, embedtag: {tag: 'iframe', width: 400, height: 330}, nocache: 1 }), + new $.fn.oembed.OEmbedProvider("youku", "video", ["v.youku.com/v_show/id_.+"], "http://player.youku.com/player.php/sid/$1/v.swf", + {templateRegex: /.*id_(.+)\.html.*/, embedtag: {width: 480, height: 400}, nocache: 1 }), + new $.fn.oembed.OEmbedProvider("tudou", "video", ["tudou.com/programs/view/.+\/"], "http://www.tudou.com/v/$1/v.swf", + {templateRegex: /.*view\/(.+)\//, embedtag: {width: 480, height: 400}, nocache: 1 }), + new $.fn.oembed.OEmbedProvider("embedr", "video", ["embedr\\.com/playlist/.+"], "http://embedr.com/swf/slider/$1/425/520/default/false/std?", + {templateRegex: /.*playlist\/([^\/]+).*/, embedtag: {width: 425, height: 520}}), + new $.fn.oembed.OEmbedProvider("blip", "video", ["blip\\.tv/.+"], "//blip.tv/oembed/"), + new $.fn.oembed.OEmbedProvider("minoto-video", "video", ["http://api.minoto-video.com/publishers/.+/videos/.+", "http://dashboard.minoto-video.com/main/video/details/.+", "http://embed.minoto-video.com/.+"], "http://api.minoto-video.com/services/oembed.json", {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("animoto", "video", ["animoto.com/play/.+"], "http://animoto.com/services/oembed"), + new $.fn.oembed.OEmbedProvider("hulu", "video", ["hulu\\.com/watch/.*"], "//www.hulu.com/api/oembed.json"), + new $.fn.oembed.OEmbedProvider("ustream", "video", ["ustream\\.tv/recorded/.*"], "http://www.ustream.tv/oembed", {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("videojug", "video", ["videojug\\.com/(film|payer|interview).*"], "http://www.videojug.com/oembed.json", {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("sapo", "video", ["videos\\.sapo\\.pt/.*"], "http://videos.sapo.pt/oembed", {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("vodpod", "video", ["vodpod.com/watch/.*"], "http://vodpod.com/oembed.js", {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("vimeo", "video", ["www\.vimeo\.com\/groups\/.*\/videos\/.*", "www\.vimeo\.com\/.*", "vimeo\.com\/groups\/.*\/videos\/.*", "vimeo\.com\/.*"], "//vimeo.com/api/oembed.json"), + new $.fn.oembed.OEmbedProvider("dailymotion", "video", ["dailymotion\\.com/.+"], '//www.dailymotion.com/services/oembed'), + new $.fn.oembed.OEmbedProvider("5min", "video", ["www\\.5min\\.com/.+"], 'http://api.5min.com/oembed.xml', {useYQL: 'xml'}), + new $.fn.oembed.OEmbedProvider("National Film Board of Canada", "video", ["nfb\\.ca/film/.+"], 'http://www.nfb.ca/remote/services/oembed/', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("qik", "video", ["qik\\.com/\\w+"], 'http://qik.com/api/oembed.json', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("revision3", "video", ["revision3\\.com"], "http://revision3.com/api/oembed/"), + new $.fn.oembed.OEmbedProvider("dotsub", "video", ["dotsub\\.com/view/.+"], "http://dotsub.com/services/oembed", {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("clikthrough", "video", ["clikthrough\\.com/theater/video/\\d+"], "http://clikthrough.com/services/oembed"), + new $.fn.oembed.OEmbedProvider("Kinomap", "video", ["kinomap\\.com/.+"], "http://www.kinomap.com/oembed"), + new $.fn.oembed.OEmbedProvider("VHX", "video", ["vhx.tv/.+"], "http://vhx.tv/services/oembed.json"), + new $.fn.oembed.OEmbedProvider("bambuser", "video", ["bambuser.com/.+"], "http://api.bambuser.com/oembed/iframe.json"), + new $.fn.oembed.OEmbedProvider("justin.tv", "video", ["justin.tv/.+"], 'http://api.justin.tv/api/embed/from_url.json', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("vine", "video", ["vine.co/v/.*"], null, + { + templateRegex: /https?:\/\/w?w?w?.?vine\.co\/v\/([a-zA-Z0-9]*).*/, + template: '' + + '', + nocache: 1 + }), + new $.fn.oembed.OEmbedProvider("boxofficebuz", "video", ["boxofficebuz\\.com\\/embed/.+"], "http://boxofficebuz.com/embed/$1/$2", {templateRegex: [/.*boxofficebuz\.com\/embed\/(\w+)\/([\w*\-*]+)/], embedtag: {tag: 'iframe', width: 480, height: 360 }}), + new $.fn.oembed.OEmbedProvider("clipsyndicate", "video", ["clipsyndicate\\.com/video/play/.+", "clipsyndicate\\.com/embed/iframe\?.+"], "http://eplayer.clipsyndicate.com/embed/iframe?pf_id=1&show_title=0&va_id=$1&windows=1", {templateRegex: [/.*www\.clipsyndicate\.com\/video\/play\/(\w+)\/.*/, /.*eplayer\.clipsyndicate\.com\/embed\/iframe\?.*va_id=(\w+).*.*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("coub", "video", ["coub\\.com/.+"], "http://www.coub.com/embed/$1?muted=false&autostart=false&originalSize=false&hideTopBar=false&noSiteButtons=false&startWithHD=false", {templateRegex: [/.*coub\.com\/embed\/(\w+)\?*.*/, /.*coub\.com\/view\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("discoverychannel", "video", ["snagplayer\\.video\\.dp\\.discovery\\.com/.+"], "http://snagplayer.video.dp.discovery.com/$1/snag-it-player.htm?auto=no", {templateRegex: [/.*snagplayer\.video\.dp\.discovery\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }}), + new $.fn.oembed.OEmbedProvider("telly", "video", ["telly\\.com/.+"], "http://www.telly.com/embed.php?guid=$1&autoplay=0", {templateRegex: [/.*telly\.com\/embed\.php\?guid=(\w+).*/, /.*telly\.com\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }}), + new $.fn.oembed.OEmbedProvider("minilogs", "video", ["minilogs\\.com/.+"], "http://www.minilogs.com/e/$1", {templateRegex: [/.*minilogs\.com\/e\/(\w+).*/, /.*minilogs\.com\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("viddy", "video", ["viddy\\.com/.+"], "http://www.viddy.com/embed/video/$1", {templateRegex: [/.*viddy\.com\/embed\/video\/(\.*)/, /.*viddy\.com\/video\/(\.*)/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("worldstarhiphop", "video", ["worldstarhiphop\\.com\/embed/.+"], "http://www.worldstarhiphop.com/embed/$1", {templateRegex: /.*worldstarhiphop\.com\/embed\/(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("zapiks", "video", ["zapiks\\.fr\/.+"], "http://www.zapiks.fr/index.php?action=playerIframe&media_id=$1&autoStart=fals", {templateRegex: /.*zapiks\.fr\/index.php\?[\w\=\&]*media_id=(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), - // allows the options to be set to null, don't send null values to the server as parameters - if(provider.params[i] !== null) qs += "&" + escape(i) + "=" + provider.params[i]; - } + //Audio + new $.fn.oembed.OEmbedProvider("official.fm", "rich", ["official.fm/.+"], 'http://official.fm/services/oembed', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("chirbit", "rich", ["chirb.it/.+"], 'http://chirb.it/oembed.json', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("chirbit", "audio", ["chirb\\.it/.+"], "http://chirb.it/wp/$1", {templateRegex: [/.*chirb\.it\/wp\/(\w+).*/, /.*chirb\.it\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("Huffduffer", "rich", ["huffduffer.com/[-.\\w@]+/\\d+"], "http://huffduffer.com/oembed"), + new $.fn.oembed.OEmbedProvider("Spotify", "rich", ["open.spotify.com/(track|album|user)/"], "https://embed.spotify.com/oembed/"), + new $.fn.oembed.OEmbedProvider("shoudio", "rich", ["shoudio.com/.+", "shoud.io/.+"], "http://shoudio.com/api/oembed"), + new $.fn.oembed.OEmbedProvider("mixcloud", "rich", ["mixcloud.com/.+"], 'http://www.mixcloud.com/oembed/', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("rdio.com", "rich", ["rd.io/.+", "rdio.com"], "http://www.rdio.com/api/oembed/"), + new $.fn.oembed.OEmbedProvider("Soundcloud", "rich", ["soundcloud.com/.+", "snd.sc/.+"], "//soundcloud.com/oembed", {format: 'js'}), + new $.fn.oembed.OEmbedProvider("bandcamp", "rich", ["bandcamp\\.com/album/.+"], null, + { + yql: { + xpath: "//meta[contains(@content, \\'EmbeddedPlayer\\')]", + from: 'html', + datareturn: function (results) { + return results.meta ? '' : false; + } + } + }), - url += "format=" + provider.format + "&url=" + escape(externalUrl) + qs; - if(provider.dataType != 'json') url += "&" + provider.callbackparameter + "=?"; + //Photo + new $.fn.oembed.OEmbedProvider("deviantart", "photo", ["deviantart.com/.+", "fav.me/.+", "deviantart.com/.+"], "//backend.deviantart.com/oembed", {format: 'jsonp'}), + new $.fn.oembed.OEmbedProvider("skitch", "photo", ["skitch.com/.+"], null, + { + yql: { + xpath: "json", + from: 'json', + url: function (externalurl) { + return 'http://skitch.com/oembed/?format=json&url=' + externalurl + }, + datareturn: function (data) { + return $.fn.oembed.getPhotoCode(data.json.url, data.json); + } + } + }), + new $.fn.oembed.OEmbedProvider("mobypicture", "photo", ["mobypicture.com/user/.+/view/.+", "moby.to/.+"], "http://api.mobypicture.com/oEmbed"), + new $.fn.oembed.OEmbedProvider("flickr", "photo", ["flickr\\.com/photos/.+"], "//flickr.com/services/oembed", {callbackparameter: 'jsoncallback'}), + new $.fn.oembed.OEmbedProvider("photobucket", "photo", ["photobucket\\.com/(albums|groups)/.+"], "http://photobucket.com/oembed/"), + new $.fn.oembed.OEmbedProvider("instagram", "photo", ["instagr\\.?am(\\.com)?/.+"], "//api.instagram.com/oembed"), + //new $.fn.oembed.OEmbedProvider("yfrog", "photo", ["yfrog\\.(com|ru|com\\.tr|it|fr|co\\.il|co\\.uk|com\\.pl|pl|eu|us)/.+"], "http://www.yfrog.com/api/oembed",{useYQL:"json"}), + new $.fn.oembed.OEmbedProvider("SmugMug", "photo", ["smugmug.com/[-.\\w@]+/.+"], "http://api.smugmug.com/services/oembed/"), + new $.fn.oembed.OEmbedProvider("dribbble", "photo", ["dribbble.com/shots/.+"], "http://api.dribbble.com/shots/$1?callback=?", + { + templateRegex: /.*shots\/([\d]+).*/, + templateData: function (data) { + if (!data.image_teaser_url) { + return false; + } + return ''; + } + }), + new $.fn.oembed.OEmbedProvider("chart.ly", "photo", ["chart\\.ly/[a-z0-9]{6,8}"], "http://chart.ly/uploads/large_$1.png", + {templateRegex: /.*ly\/([^\/]+).*/, embedtag: {tag: 'img'}, nocache: 1}), + //new $.fn.oembed.OEmbedProvider("stocktwits.com", "photo", ["stocktwits\\.com/message/.+"], "http://charts.stocktwits.com/production/original_$1.png?", + // { templateRegex: /.*message\/([^\/]+).*/, embedtag: { tag: 'img'},nocache:1 }), + new $.fn.oembed.OEmbedProvider("circuitlab", "photo", ["circuitlab.com/circuit/.+"], "https://www.circuitlab.com/circuit/$1/screenshot/540x405/", + {templateRegex: /.*circuit\/([^\/]+).*/, embedtag: {tag: 'img'}, nocache: 1}), + new $.fn.oembed.OEmbedProvider("23hq", "photo", ["23hq.com/[-.\\w@]+/photo/.+"], "http://www.23hq.com/23/oembed", {useYQL: "json"}), + new $.fn.oembed.OEmbedProvider("img.ly", "photo", ["img\\.ly/.+"], "//img.ly/show/thumb/$1", + {templateRegex: /.*ly\/([^\/]+).*/, embedtag: {tag: 'img'}, nocache: 1}), + new $.fn.oembed.OEmbedProvider("twitgoo.com", "photo", ["twitgoo\\.com/.+"], "http://twitgoo.com/show/thumb/$1", + {templateRegex: /.*com\/([^\/]+).*/, embedtag: {tag: 'img'}, nocache: 1}), + new $.fn.oembed.OEmbedProvider("imgur.com", "photo", ["imgur\\.com/gallery/.+"], "http://imgur.com/$1l.jpg", + {templateRegex: /.*gallery\/([^\/]+).*/, embedtag: {tag: 'img'}, nocache: 1}), + new $.fn.oembed.OEmbedProvider("visual.ly", "rich", ["visual\\.ly/.+"], null, + { + yql: { + xpath: "//a[@id=\\'gc_article_graphic_image\\']/img", + from: 'htmlstring' + } + }), + new $.fn.oembed.OEmbedProvider("achewood", "photo", ["achewood\\.com\\/index.php\\?date=.+"], "http://www.achewood.com/comic.php?date=$1", {templateRegex: /.*achewood\.com\/index.php\?date=(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("fotokritik", "photo", ["fotokritik\\.com/.+"], "http://www.fotokritik.com/embed/$1", {templateRegex: [/.*fotokritik\.com\/embed\/(\w+).*/, /.*fotokritik\.com\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("giflike", "photo", ["giflike\\.com/.+"], "http://www.giflike.com/embed/$1", {templateRegex: [/.*giflike\.com\/embed\/(\w+).*/, /.*giflike\.com\/a\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), - return url; - } + //Rich + new $.fn.oembed.OEmbedProvider("twitter", "rich", ["twitter.com/.+"], "https://api.twitter.com/1/statuses/oembed.json"), + new $.fn.oembed.OEmbedProvider("gmep", "rich", ["gmep.imeducate.com/.*", "gmep.org/.*"], "http://gmep.org/oembed.json"), + new $.fn.oembed.OEmbedProvider("urtak", "rich", ["urtak.com/(u|clr)/.+"], "http://oembed.urtak.com/1/oembed"), + new $.fn.oembed.OEmbedProvider("cacoo", "rich", ["cacoo.com/.+"], "http://cacoo.com/oembed.json"), + new $.fn.oembed.OEmbedProvider("dailymile", "rich", ["dailymile.com/people/.*/entries/.*"], "http://api.dailymile.com/oembed"), + new $.fn.oembed.OEmbedProvider("documentcloud", "rich", ["documentcloud.org/documents/.+"], "https://www.documentcloud.org/api/oembed.json"), + new $.fn.oembed.OEmbedProvider("dipity", "rich", ["dipity.com/timeline/.+"], 'http://www.dipity.com/oembed/timeline/', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("sketchfab", "rich", ["sketchfab.com/show/.+"], 'http://sketchfab.com/oembed', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("speakerdeck", "rich", ["speakerdeck.com/.+"], 'http://speakerdeck.com/oembed.json', {useYQL: 'json'}), + new $.fn.oembed.OEmbedProvider("popplet", "rich", ["popplet.com/app/.*"], "http://popplet.com/app/Popplet_Alpha.swf?page_id=$1&em=1", + { + templateRegex: /.*#\/([^\/]+).*/, + embedtag: { + width: 460, + height: 460 + } + }), - function success(oembedData, externalUrl, container) { - $('#jqoembeddata').data(externalUrl, oembedData.code); - settings.beforeEmbed.call(container, oembedData); - settings.onEmbed.call(container, oembedData); - settings.afterEmbed.call(container, oembedData); - } + new $.fn.oembed.OEmbedProvider("pearltrees", "rich", ["pearltrees.com/.*"], "http://cdn.pearltrees.com/s/embed/getApp?", + { + templateRegex: /.*N-f=1_(\d+).*N-p=(\d+).*/, + embedtag: { + width: 460, + height: 460, + flashvars: "lang=en_US&embedId=pt-embed-$1-693&treeId=$1&pearlId=$2&treeTitle=Diagrams%2FVisualization&site=www.pearltrees.com%2FF" + } + }), - function embedCode(container, externalUrl, embedProvider) { - if($('#jqoembeddata').data(externalUrl) != undefined && embedProvider.embedtag.tag != 'iframe') { - var oembedData = { - code: $('#jqoembeddata').data(externalUrl) - }; - success(oembedData, externalUrl, container); - } else if(embedProvider.yql) { - var from = embedProvider.yql.from || 'htmlstring'; - var url = embedProvider.yql.url ? embedProvider.yql.url(externalUrl) : externalUrl; - var query = 'SELECT * FROM ' + from + ' WHERE url="' + (url) + '"' + " and " + (/html/.test(from) ? 'xpath' : 'itemPath') + "='" + (embedProvider.yql.xpath || '/') + "'"; - if(from == 'html') query += " and compat='html5'"; - var ajaxopts = $.extend({ - url: "http://query.yahooapis.com/v1/public/yql", - dataType: 'jsonp', - data: { - q: query, - format: "json", - env: 'store://datatables.org/alltableswithkeys', - callback: "?" - }, - success: function (data) { - var result; - if(embedProvider.yql.xpath && embedProvider.yql.xpath == '//meta|//title|//link') { - var meta = {}; - if(data.query.results == null) { - data.query.results = { - "meta": [] - }; - } - for(var i = 0, l = data.query.results.meta.length; i < l; i++) { - var name = data.query.results.meta[i].name || data.query.results.meta[i].property || null; - if(name == null) continue; - meta[name.toLowerCase()] = data.query.results.meta[i].content; - } - if(!meta.hasOwnProperty("title") || !meta.hasOwnProperty("og:title")) { - if(data.query.results.title != null) { - meta.title = data.query.results.title; - } - } - result = embedProvider.yql.datareturn(meta); - } else { - result = embedProvider.yql.datareturn ? embedProvider.yql.datareturn(data.query.results) : data.query.results.result; - } - if(result === false) return; - var oembedData = $.extend({}, result); - oembedData.code = result; - success(oembedData, externalUrl, container); - }, - error: settings.onError.call(container, externalUrl, embedProvider) - }, settings.ajaxOptions || {}); + new $.fn.oembed.OEmbedProvider("prezi", "rich", ["prezi.com/.*"], "//prezi.com/bin/preziloader.swf?", + { + templateRegex: /.*com\/([^\/]+)\/.*/, + embedtag: { + width: 550, + height: 400, + flashvars: "prezi_id=$1&lock_to_path=0&color=ffffff&autoplay=no&autohide_ctrls=0" + } + }), - $.ajax(ajaxopts); - } else if(embedProvider.templateRegex) { - if(embedProvider.embedtag.tag !== '') { - var flashvars = embedProvider.embedtag.flashvars || ''; - var tag = embedProvider.embedtag.tag || 'embed'; - var width = embedProvider.embedtag.width || 'auto'; - var nocache = embedProvider.embedtag.nocache || 0; - var height = embedProvider.embedtag.height || 'auto'; - var src = externalUrl.replace(embedProvider.templateRegex, embedProvider.apiendpoint); - if(!embedProvider.nocache) src += '&jqoemcache=' + rand(5); - if(embedProvider.apikey) src = src.replace('_APIKEY_', settings.apikeys[embedProvider.name]); + new $.fn.oembed.OEmbedProvider("tourwrist", "rich", ["tourwrist.com/tours/.+"], null, + { + templateRegex: /.*tours.([\d]+).*/, + template: function (wm, tourid) { + setTimeout(function () { + if (loadEmbeds)loadEmbeds(); + }, 2000); + return "
    "; + } + }), - var code = $('<' + tag + '/>') - .attr('src', src) - .attr('width', width) - .attr('height', height) - .attr('allowfullscreen', embedProvider.embedtag.allowfullscreen || 'true') - .attr('allowscriptaccess', embedProvider.embedtag.allowfullscreen || 'always') - .css('max-height', settings.maxHeight || 'auto') - .css('max-width', settings.maxWidth || 'auto'); - if(tag == 'embed') { - code - .attr('type', embedProvider.embedtag.type || "application/x-shockwave-flash") - .attr('flashvars', externalUrl.replace(embedProvider.templateRegex, flashvars)); - } - if(tag == 'iframe'){ - code - .attr('scrolling', embedProvider.embedtag.scrolling || "no") - .attr('frameborder', embedProvider.embedtag.frameborder || "0"); - } + new $.fn.oembed.OEmbedProvider("meetup", "rich", ["meetup\\.(com|ps)/.+"], "http://api.meetup.com/oembed"), + new $.fn.oembed.OEmbedProvider("ebay", "rich", ["ebay\\.*"], "http://togo.ebay.com/togo/togo.swf?2008013100", + { + templateRegex: /.*\/([^\/]+)\/(\d{10,13}).*/, + embedtag: { + width: 355, + height: 300, + flashvars: "base=http://togo.ebay.com/togo/&lang=en-us&mode=normal&itemid=$2&query=$1" + } + }), + new $.fn.oembed.OEmbedProvider("wikipedia", "rich", ["wikipedia.org/wiki/.+"], "http://$1.wikipedia.org/w/api.php?action=parse&page=$2&format=json§ion=0&callback=?", { + templateRegex: /.*\/\/([\w]+).*\/wiki\/([^\/]+).*/, + templateData: function (data) { + if (!data.parse) + return false; + var text = data.parse['text']['*'].replace(/href="\/wiki/g, 'href="http://en.wikipedia.org/wiki'); + return ''; + } + }), + new $.fn.oembed.OEmbedProvider("imdb", "rich", ["imdb.com/title/.+"], "http://www.imdbapi.com/?i=$1&callback=?", + { + templateRegex: /.*\/title\/([^\/]+).*/, + templateData: function (data) { + if (!data.Title) + return false; + return '

    ' + data.Title + ' (' + data.Year + ')

    Rating: ' + data.imdbRating + '
    Genre: ' + data.Genre + '
    Starring: ' + data.Actors + '

    ' + data.Plot + '
    '; + } + }), + new $.fn.oembed.OEmbedProvider("livejournal", "rich", ["livejournal.com/"], "http://ljpic.seacrow.com/json/$2$4?jsonp=?" + , { + templateRegex: /(http:\/\/(((?!users).)+)\.livejournal\.com|.*users\.livejournal\.com\/([^\/]+)).*/, + templateData: function (data) { + if (!data.username) + return false; + return '
    [info]' + data.username + '
    ' + data.name + '
    '; + } + }), + new $.fn.oembed.OEmbedProvider("circuitbee", "rich", ["circuitbee\\.com/circuit/view/.+"], "http://c.circuitbee.com/build/r/schematic-embed.html?id=$1", + { + templateRegex: /.*circuit\/view\/(\d+).*/, + embedtag: { + tag: 'iframe', + width: '500', + height: '350' + } + }), - var oembedData = { - code: code - }; - success(oembedData, externalUrl, container); - } else if(embedProvider.apiendpoint) { - //Add APIkey if true - if(embedProvider.apikey) embedProvider.apiendpoint = embedProvider.apiendpoint.replace('_APIKEY_', settings.apikeys[embedProvider.name]); - ajaxopts = $.extend({ - url: externalUrl.replace(embedProvider.templateRegex, embedProvider.apiendpoint), - dataType: 'jsonp', - success: function (data) { - var oembedData = $.extend({}, data); - oembedData.code = embedProvider.templateData(data); - if(oembedData.code) success(oembedData, externalUrl, container); - }, - error: settings.onError.call(container, externalUrl, embedProvider) - }, settings.ajaxOptions || {}); + new $.fn.oembed.OEmbedProvider("googlecalendar", "rich", ["www.google.com/calendar/embed?.+"], "$1", + {templateRegex: /(.*)/, embedtag: {tag: 'iframe', width: '800', height: '600' }}), + new $.fn.oembed.OEmbedProvider("jsfiddle", "rich", ["jsfiddle.net/[^/]+/?"], "http://jsfiddle.net/$1/embedded/result,js,resources,html,css/?", + {templateRegex: /.*net\/([^\/]+).*/, embedtag: {tag: 'iframe', width: '100%', height: '300' }}), + new $.fn.oembed.OEmbedProvider("jsbin", "rich", ["jsbin.com/.+"], "http://jsbin.com/$1/?", + {templateRegex: /.*com\/([^\/]+).*/, embedtag: {tag: 'iframe', width: '100%', height: '300' }}), + new $.fn.oembed.OEmbedProvider("jotform", "rich", ["form.jotform.co/form/.+"], "$1?", + {templateRegex: /(.*)/, embedtag: {tag: 'iframe', width: '100%', height: '507' }}), + new $.fn.oembed.OEmbedProvider("reelapp", "rich", ["reelapp\\.com/.+"], "http://www.reelapp.com/$1/embed", + {templateRegex: /.*com\/(\S{6}).*/, embedtag: {tag: 'iframe', width: '400', height: '338'}}), + new $.fn.oembed.OEmbedProvider("linkedin", "rich", ["linkedin.com/pub/.+"], "https://www.linkedin.com/cws/member/public_profile?public_profile_url=$1&format=inline&isFramed=true", + {templateRegex: /(.*)/, embedtag: {tag: 'iframe', width: '368px', height: 'auto'}}), + new $.fn.oembed.OEmbedProvider("timetoast", "rich", ["timetoast.com/timelines/[0-9]+"], "http://www.timetoast.com/flash/TimelineViewer.swf?passedTimelines=$1", + {templateRegex: /.*timelines\/([0-9]*)/, embedtag: { width: 550, height: 400}, nocache: 1}), + new $.fn.oembed.OEmbedProvider("pastebin", "rich", ["pastebin\\.com/[\\S]{8}"], "http://pastebin.com/embed_iframe.php?i=$1", + {templateRegex: /.*\/(\S{8}).*/, embedtag: {tag: 'iframe', width: '100%', height: 'auto'}}), + new $.fn.oembed.OEmbedProvider("mixlr", "rich", ["mixlr.com/.+"], "http://mixlr.com/embed/$1?autoplay=ae", + {templateRegex: /.*com\/([^\/]+).*/, embedtag: {tag: 'iframe', width: '100%', height: 'auto' }}), + new $.fn.oembed.OEmbedProvider("pastie", "rich", ["pastie\\.org/pastes/.+"], null, {yql: {xpath: '//pre[@class="textmate-source"]'}}), + new $.fn.oembed.OEmbedProvider("github", "rich", ["gist.github.com/.+"], "https://github.com/api/oembed"), + new $.fn.oembed.OEmbedProvider("github", "rich", ["github.com/[-.\\w@]+/[-.\\w@]+"], "https://api.github.com/repos/$1/$2?callback=?" + , {templateRegex: /.*\/([^\/]+)\/([^\/]+).*/, + templateData: function (data) { + if (!data.data.html_url)return false; + return '

    ' + data.data.name + '

    ' + data.data.description + '

    ' + + '

    Last updated: ' + data.data.pushed_at + '

    '; + } + }), + new $.fn.oembed.OEmbedProvider("facebook", "rich", ["facebook.com"], null + , {templateRegex: /.*\/([^\/]+)\/([^\/]+).*/, + template: function (url) { + // adding script directly to DOM to make sure that it is loaded correctly. + if (!$.fn.oembed.facebokScriptHasBeenAdded) { + $('
    ').appendTo('body'); + var script = document.createElement('script'); + script.type = 'text/javascript'; + script.text = '(function(d, s, id) {var js, fjs = d.getElementsByTagName(s)[0];if (d.getElementById(id)) return;js = d.createElement(s); js.id = id;js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.0";fjs.parentNode.insertBefore(js, fjs);}(document, "script", "facebook-jssdk"));'; + document.body.appendChild(script); + $.fn.oembed.facebokScriptHasBeenAdded = true; + } - $.ajax(ajaxopts); - } else { - var oembedData = { - code: externalUrl.replace(embedProvider.templateRegex, embedProvider.template) - }; - success(oembedData, externalUrl, container); - } - } else { + // returning template with url of facebook post. + return '
    '; - var requestUrl = getRequestUrl(embedProvider, externalUrl), - ajaxopts = $.extend({ - url: requestUrl, - dataType: embedProvider.dataType || 'jsonp', - success: function (data) { - var oembedData = $.extend({}, data); - switch(oembedData.type) { - case "file": //Deviant Art has this - case "photo": - oembedData.code = $.fn.oembed.getPhotoCode(externalUrl, oembedData); - break; - case "video": - case "rich": - oembedData.code = $.fn.oembed.getRichCode(externalUrl, oembedData); - break; - default: - oembedData.code = $.fn.oembed.getGenericCode(externalUrl, oembedData); - break; - } - success(oembedData, externalUrl, container); - }, - error: settings.onError.call(container, externalUrl, embedProvider) - }, settings.ajaxOptions || {}); + } + }), + /* + // Saving old implementation of Facebook in case we will need it as example in the future. + new $.fn.oembed.OEmbedProvider("facebook", "rich", ["facebook.com/(people/[^\\/]+/\\d+|[^\\/]+$)"], "https://graph.facebook.com/$2$3/?callback=?" + ,{templateRegex:/.*facebook.com\/(people\/[^\/]+\/(\d+).*|([^\/]+$))/, + templateData : function(data){ if(!data.id)return false; + var out = '
    facebook '; + if(data.from) out += ''+data.from.name+''; + else if(data.link) out += ''+data.name+''; + else if(data.username) out += ''+data.name+''; + else out += ''+data.name+''; + out += '
    '; + if(data.picture) out += ''; + else out += ''; + if(data.from) out += ''+data.name+''; + if(data.founded) out += 'Founded: '+data.founded+'
    '; + if(data.category) out += 'Category: '+data.category+'
    '; + if(data.website) out += 'Website: '+data.website+'
    '; + if(data.gender) out += 'Gender: '+data.gender+'
    '; + if(data.description) out += data.description + '
    '; + out += '
    '; + return out; + } + }), + */ + new $.fn.oembed.OEmbedProvider("stackoverflow", "rich", ["stackoverflow.com/questions/[\\d]+"], "http://api.stackoverflow.com/1.1/questions/$1?body=true&jsonp=?" + , {templateRegex: /.*questions\/([\d]+).*/, + templateData: function (data) { + if (!data.questions) + return false; + var q = data.questions[0]; + var body = $(q.body).text(); + var out = '
    ' + + '' + (q.up_vote_count - q.down_vote_count) + '
    vote(s)
    ' + + '
    ' + q.answer_count + 'answer
    ' + q.view_count + ' view(s)
    ' + + '

    ' + q.title + '

    ' + + '
    ' + body.substring(0, 100) + '...
    '; + for (i in q.tags) { + out += ''; + } - $.ajax(ajaxopts); - } - }; + out += '
    '; + return out; + } + }), + new $.fn.oembed.OEmbedProvider("wordpress", "rich", ["wordpress\\.com/.+", "blogs\\.cnn\\.com/.+", "techcrunch\\.com/.+", "wp\\.me/.+"], "http://public-api.wordpress.com/oembed/1.0/?for=jquery-oembed-all"), + new $.fn.oembed.OEmbedProvider("screenr", "rich", ["screenr\.com"], "http://www.screenr.com/embed/$1", + {templateRegex: /.*\/([^\/]+).*/, embedtag: {tag: 'iframe', width: '650', height: 396}}) , + new $.fn.oembed.OEmbedProvider("gigpans", "rich", ["gigapan\\.org/[-.\\w@]+/\\d+"], "http://gigapan.org/gigapans/$1/options/nosnapshots/iframe/flash.html", + {templateRegex: /.*\/(\d+)\/?.*/, embedtag: {tag: 'iframe', width: '100%', height: 400 }}), + new $.fn.oembed.OEmbedProvider("scribd", "rich", ["scribd\\.com/.+"], "http://www.scribd.com/embeds/$1/content?start_page=1&view_mode=list", + {templateRegex: /.*doc\/([^\/]+).*/, embedtag: {tag: 'iframe', width: '100%', height: 600}}), + new $.fn.oembed.OEmbedProvider("kickstarter", "rich", ["kickstarter\\.com/projects/.+"], "$1/widget/card.html", + {templateRegex: /([^\?]+).*/, embedtag: {tag: 'iframe', width: '220', height: 380}}), + new $.fn.oembed.OEmbedProvider("amazon", "rich", ["amzn.com/B+", "amazon.com.*/(B\\S+)($|\\/.*)"], "http://rcm.amazon.com/e/cm?t=_APIKEY_&o=1&p=8&l=as1&asins=$1&ref=qf_br_asin_til&fc1=000000&IS2=1<1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr", + { + apikey: true, + templateRegex: /.*\/(B[0-9A-Z]+)($|\/.*)/, + embedtag: { + tag: 'iframe', + width: '120px', + height: '240px'} + }), + new $.fn.oembed.OEmbedProvider("slideshare", "rich", ["slideshare\.net"], "//www.slideshare.net/api/oembed/2", {format: 'jsonp'}), + new $.fn.oembed.OEmbedProvider("roomsharejp", "rich", ["roomshare\\.jp/(en/)?post/.*"], "http://roomshare.jp/oembed.json"), + new $.fn.oembed.OEmbedProvider("lanyard", "rich", ["lanyrd.com/\\d+/.+"], null, + { + yql: { + xpath: '(//div[@class="primary"])[1]', + from: 'htmlstring', + datareturn: function (results) { + if (!results.result) + return false; + return '
    ' + results.result + '
    '; + } + } + }), + new $.fn.oembed.OEmbedProvider("asciiartfarts", "rich", ["asciiartfarts.com/\\d+.html"], null, + { + yql: { + xpath: '//pre/font', + from: 'htmlstring', + datareturn: function (results) { + if (!results.result) + return false; + return '
    ' + results.result + '
    '; + } + } + }), + new $.fn.oembed.OEmbedProvider("coveritlive", "rich", ["coveritlive.com/"], null, { + templateRegex: /(.*)/, + template: ''}), + new $.fn.oembed.OEmbedProvider("polldaddy", "rich", ["polldaddy.com/"], null, { + templateRegex: /(?:https?:\/\/w?w?w?.?polldaddy.com\/poll\/)([0-9]*)\//, + template: '', + nocache: 1 + }), + new $.fn.oembed.OEmbedProvider("360io", "rich", ["360\\.io/.+"], "http://360.io/$1", {templateRegex: /.*360\.io\/(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("bubbli", "rich", ["on\\.bubb\\.li/.+"], "http://on.bubb.li/$1", {templateRegex: /.*on\.bubb\.li\/(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360}, nocache: 1 }), + new $.fn.oembed.OEmbedProvider("cloudup", "rich", ["cloudup\\.com/.+"], "http://cloudup.com/$1?chromeless", {templateRegex: [/.*cloudup\.com\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }}), + new $.fn.oembed.OEmbedProvider("codepen", "rich", ["codepen.io/.+"], "http://codepen.io/$1/embed/$2", {templateRegex: [/.*io\/(\w+)\/pen\/(\w+).*/, /.*io\/(\w+)\/full\/(\w+).*/], embedtag: {tag: 'iframe', width: '100%', height: '300'}, nocache: 1 }), + new $.fn.oembed.OEmbedProvider("googleviews", "rich", ["(.*maps\\.google\\.com\\/maps\\?).+(output=svembed).+(cbp=(.*)).*"], "https://maps.google.com/maps?layer=c&panoid=$3&ie=UTF8&source=embed&output=svembed&cbp=$5", {templateRegex: /(.*maps\.google\.com\/maps\?).+(panoid=(\w+)&).*(cbp=(.*)).*/, embedtag: {tag: 'iframe', width: 480, height: 360}, nocache: 1 }), + new $.fn.oembed.OEmbedProvider("googlemaps", "rich", ["google\\.com\/maps\/place/.+"], "http://maps.google.com/maps?t=m&q=$1&output=embed", {templateRegex: /.*google\.com\/maps\/place\/([\w\+]*)\/.*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("imajize", "rich", ["embed\\.imajize\\.com/.+"], "http://embed.imajize.com/$1", {templateRegex: /.*embed\.imajize\.com\/(.*)/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("mapjam", "rich", ["mapjam\\.com/.+"], "http://www.mapjam.com/$1", {templateRegex: /.*mapjam\.com\/(.*)/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("polar", "rich", ["polarb\\.com/.+"], "http://assets-polarb-com.a.ssl.fastly.net/api/v4/publishers/unknown/embedded_polls/iframe?poll_id=$1", {templateRegex: /.*polarb\.com\/polls\/(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), + new $.fn.oembed.OEmbedProvider("ponga", "rich", ["ponga\\.com/.+"], "https://www.ponga.com/embedded?id=$1", {templateRegex: [/.*ponga\.com\/embedded\?id=(\w+).*/, /.*ponga\.com\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), - function getNormalizedParams(params) { - if(params === null) return null; - var key, normalizedParams = {}; - for(key in params) { - if(key !== null) normalizedParams[key.toLowerCase()] = params[key]; - } - return normalizedParams; - } + //Use Open Graph Where applicable + new $.fn.oembed.OEmbedProvider("opengraph", "rich", [".*"], null, + { + yql: { + xpath: "//meta|//title|//link", + from: 'html', + datareturn: function (results) { + if (!results['og:title'] && results['title'] && results['description']) + results['og:title'] = results['title']; - /* Public functions */ - $.fn.oembed.insertCode = function (container, embedMethod, oembedData) { - if(oembedData === null) return; - if(embedMethod == 'auto' && container.attr("href") !== null) embedMethod = 'append'; - else if(embedMethod == 'auto') embedMethod = 'replace'; - switch(embedMethod) { - case "replace": - container.replaceWith(oembedData.code); - break; - case "fill": - container.html(oembedData.code); - break; - case "append": - container.wrap('
    '); - var oembedContainer = container.parent(); - if(settings.includeHandle) { - $('').insertBefore(container).click(function () { - var encodedString = encodeURIComponent($(this).text()); - $(this).html((encodedString == '%E2%86%91') ? '↓' : '↑'); - $(this).parent().children().last().toggle(); - }); - } - oembedContainer.append('
    '); - try { - oembedData.code.clone().appendTo(oembedContainer); - } catch(e) { - oembedContainer.append(oembedData.code); - } - /* Make videos semi-responsive - * If parent div width less than embeded iframe video then iframe gets shrunk to fit smaller width - * If parent div width greater thans embed iframe use the max widht - * - works on youtubes and vimeo - */ - if(settings.maxWidth) { - var post_width = oembedContainer.parent().width(); - if(post_width < settings.maxWidth) { - var iframe_width_orig = $('iframe', oembedContainer).width(); - var iframe_height_orig = $('iframe', oembedContainer).height(); - var ratio = iframe_width_orig / post_width; - $('iframe', oembedContainer).width(iframe_width_orig / ratio); - $('iframe', oembedContainer).height(iframe_height_orig / ratio); - } else { - if(settings.maxWidth) { - $('iframe', oembedContainer).width(settings.maxWidth); - } - if(settings.maxHeight) { - $('iframe', oembedContainer).height(settings.maxHeight); - } - } - } - break; - } - }; + if (!results['og:title'] && !results['title']) + return false; - $.fn.oembed.getPhotoCode = function (url, oembedData) { - var code, alt = oembedData.title ? oembedData.title : ''; - alt += oembedData.author_name ? ' - ' + oembedData.author_name : ''; - alt += oembedData.provider_name ? ' - ' + oembedData.provider_name : ''; - if(oembedData.url) { - code = '
    ' + alt + '
    '; - } else if(oembedData.thumbnail_url) { - var newURL = oembedData.thumbnail_url.replace('_s', '_b'); - code = '
    ' + alt + '
    '; - } else { - code = '
    Error loading this picture
    '; - } - if(oembedData.html) code += "
    " + oembedData.html + "
    "; - return code; - }; + var code = $('

    '); + if (results['og:video']) { + var embed = $(''); + embed.attr('type', results['og:video:type'] || "application/x-shockwave-flash") + .css('max-height', settings.maxHeight || 'auto') + .css('max-width', settings.maxWidth || 'auto'); + if (results['og:video:width']) + embed.attr('width', results['og:video:width']); + if (results['og:video:height']) + embed.attr('height', results['og:video:height']); + code.append(embed); + } else if (results['og:image']) { + var img = $(''); + img.css('max-height', settings.maxHeight || 'auto').css('max-width', settings.maxWidth || 'auto'); + if (results['og:image:width']) + img.attr('width', results['og:image:width']); + if (results['og:image:height']) + img.attr('height', results['og:image:height']); + code.append(img); + } - $.fn.oembed.getRichCode = function (url, oembedData) { - var code = oembedData.html; - return code; - }; + if (results['og:title']) + code.append('' + results['og:title'] + '
    '); - $.fn.oembed.getGenericCode = function (url, oembedData) { - var title = (oembedData.title !== null) ? oembedData.title : url, - code = ''; - if(oembedData.html) code += '

    ' + title + '
    ' + jQuery(oembedData.html).text().substring(0,200) + '... more
    '; - return code; - }; + if (results['og:description']) + code.append(results['og:description'] + '
    '); + else if (results['description']) + code.append(results['description'] + '
    '); - $.fn.oembed.getOEmbedProvider = function (url) { - for(var i = 0; i < $.fn.oembed.providers.length; i++) { - for(var j = 0, l = $.fn.oembed.providers[i].urlschemes.length; j < l; j++) { - var regExp = new RegExp($.fn.oembed.providers[i].urlschemes[j], "i"); - if(url.match(regExp) !== null) return $.fn.oembed.providers[i]; - } - } - return null; - }; + return code; + } + } + } + ) - $.fn.oembed.OEmbedProvider = function (name, type, urlschemesarray, apiendpoint, extraSettings) { - this.name = name; - this.type = type; // "photo", "video", "link", "rich", null - this.urlschemes = urlschemesarray; - this.apiendpoint = apiendpoint; - this.maxWidth = 500; - this.maxHeight = 400; - extraSettings = extraSettings || {}; - - if(extraSettings.useYQL) { - if(extraSettings.useYQL == 'xml') { - extraSettings.yql = { - xpath: "//oembed/html", - from: 'xml', - apiendpoint: this.apiendpoint, - url: function (externalurl) { - return this.apiendpoint + '?format=xml&url=' + externalurl - }, - datareturn: function (results) { - return results.html.replace(/.*\[CDATA\[(.*)\]\]>$/, '$1') || '' - } - }; - } else { - extraSettings.yql = { - from: 'json', - apiendpoint: this.apiendpoint, - url: function (externalurl) { - return this.apiendpoint + '?format=json&url=' + externalurl - }, - datareturn: function (results) { - if(results.json.type != 'video' && (results.json.url || results.json.thumbnail_url)) { - return ''; - } - return results.json.html || '' - } - }; - } - this.apiendpoint = null; - } - - for(var property in extraSettings) { - this[property] = extraSettings[property]; - } - - this.format = this.format || 'json'; - this.callbackparameter = this.callbackparameter || "callback"; - this.embedtag = this.embedtag || { - tag: "" - }; - }; - - /* - * Function to update existing providers - * - * @param {String} name The name of the provider - * @param {String} type The type of the provider can be "file", "photo", "video", "rich" - * @param {String} urlshemesarray Array of url of the provider - * @param {String} apiendpoint The endpoint of the provider - * @param {String} extraSettings Extra settings of the provider - */ - $.fn.updateOEmbedProvider = function (name, type, urlschemesarray, apiendpoint, extraSettings) { - for(var i = 0; i < $.fn.oembed.providers.length; i++) { - if($.fn.oembed.providers[i].name === name) { - if(type !== null) { - $.fn.oembed.providers[i].type = type; - } - if(urlschemesarray !== null) { - $.fn.oembed.providers[i].urlschemes = urlschemesarray; - } - if(apiendpoint !== null) { - $.fn.oembed.providers[i].apiendpoint = apiendpoint; - } - if(extraSettings !== null) { - $.fn.oembed.providers[i].extraSettings = extraSettings; - for(var property in extraSettings) { - if(property !== null && extraSettings[property] !== null) { - $.fn.oembed.providers[i][property] = extraSettings[property]; - } - } - } - } - } - }; - - /* Native & common providers */ - $.fn.oembed.providers = [ - //Video - new $.fn.oembed.OEmbedProvider("youtube", "video", ["youtube\\.com/watch.+v=[\\w-]+&?", "youtu\\.be/[\\w-]+", "youtube.com/embed"], 'http://www.youtube.com/embed/$1?wmode=transparent', { - templateRegex: /.*(?:v\=|be\/|embed\/)([\w\-]+)&?.*/, - embedtag: { - tag: 'iframe', - width: '425', - height: '349' - } - }), - - // new $.fn.oembed.OEmbedProvider("youtube", "video", ["youtube\\.com/watch.+v=[\\w-]+&?", "youtu\\.be/[\\w-]+"], 'http://www.youtube.com/oembed', { - // useYQL: 'json' - // }), - // new $.fn.oembed.OEmbedProvider("youtubeiframe", "video", ["youtube.com/embed"], "$1?wmode=transparent", { - // templateRegex: /(.*)/, - // embedtag: { - // tag: 'iframe', - // width: '425', - // height: '349' - // } - // }), - new $.fn.oembed.OEmbedProvider("wistia", "video", ["wistia.com/m/.+", "wistia.com/embed/.+", "wi.st/m/.+", "wi.st/embed/.+"], 'http://fast.wistia.com/oembed', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("xtranormal", "video", ["xtranormal\\.com/watch/.+"], "http://www.xtranormal.com/xtraplayr/$1/$2", { - templateRegex: /.*com\/watch\/([\w\-]+)\/([\w\-]+).*/, - embedtag: { - tag: 'iframe', - width: '320', - height: '269' - } - }), - new $.fn.oembed.OEmbedProvider("scivee", "video", ["scivee.tv/node/.+"], "http://www.scivee.tv/flash/embedCast.swf?", { - templateRegex: /.*tv\/node\/(.+)/, - embedtag: { - width: '480', - height: '400', - flashvars: "id=$1&type=3" - } - }), - new $.fn.oembed.OEmbedProvider("veoh", "video", ["veoh.com/watch/.+"], "http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1337&permalinkId=$1&player=videodetailsembedded&videoAutoPlay=0&id=anonymous", { - templateRegex: /.*watch\/([^\?]+).*/, - embedtag: { - width: '410', - height: '341' - } - }), - new $.fn.oembed.OEmbedProvider("gametrailers", "video", ["gametrailers\\.com/video/.+"], "http://media.mtvnservices.com/mgid:moses:video:gametrailers.com:$2", { - templateRegex: /.*com\/video\/([\w\-]+)\/([\w\-]+).*/, - embedtag: { - width: '512', - height: '288' - } - }), - new $.fn.oembed.OEmbedProvider("funnyordie", "video", ["funnyordie\\.com/videos/.+"], "http://player.ordienetworks.com/flash/fodplayer.swf?", { - templateRegex: /.*videos\/([^\/]+)\/([^\/]+)?/, - embedtag: { - width: 512, - height: 328, - flashvars: "key=$1" - } - }), - new $.fn.oembed.OEmbedProvider("colledgehumour", "video", ["collegehumor\\.com/video/.+"], "http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=$1&use_node_id=true&fullscreen=1", { - templateRegex: /.*video\/([^\/]+).*/, - embedtag: { - width: 600, - height: 338 - } - }), - new $.fn.oembed.OEmbedProvider("metacafe", "video", ["metacafe\\.com/watch/.+"], "http://www.metacafe.com/fplayer/$1/$2.swf", { - templateRegex: /.*watch\/(\d+)\/(\w+)\/.*/, - embedtag: { - width: 400, - height: 345 - } - }), - new $.fn.oembed.OEmbedProvider("bambuser", "video", ["bambuser\\.com\/channel\/.*\/broadcast\/.*"], "http://static.bambuser.com/r/player.swf?vid=$1", { - templateRegex: /.*bambuser\.com\/channel\/.*\/broadcast\/(\w+).*/, - embedtag: { - width: 512, - height: 339 - } - }), - new $.fn.oembed.OEmbedProvider("twitvid", "video", ["twitvid\\.com/.+"], "http://www.twitvid.com/embed.php?guid=$1&autoplay=0", { - templateRegex: /.*twitvid\.com\/(\w+).*/, - embedtag: { - tag: 'iframe', - width: 480, - height: 360 - } - }), - new $.fn.oembed.OEmbedProvider("aniboom", "video", ["aniboom\\.com/animation-video/.+"], "http://api.aniboom.com/e/$1", { - templateRegex: /.*animation-video\/(\d+).*/, - embedtag: { - width: 594, - height: 334 - } - }), - new $.fn.oembed.OEmbedProvider("vzaar", "video", ["vzaar\\.com/videos/.+", "vzaar.tv/.+"], "http://view.vzaar.com/$1/player?", { - templateRegex: /.*\/(\d+).*/, - embedtag: { - tag: 'iframe', - width: 576, - height: 324 - } - }), - new $.fn.oembed.OEmbedProvider("snotr", "video", ["snotr\\.com/video/.+"], "http://www.snotr.com/embed/$1", { - templateRegex: /.*\/(\d+).*/, - embedtag: { - tag: 'iframe', - width: 400, - height: 330, - nocache: 1 - } - }), - new $.fn.oembed.OEmbedProvider("youku", "video", ["v.youku.com/v_show/id_.+"], "http://player.youku.com/player.php/sid/$1/v.swf", { - templateRegex: /.*id_(.+)\.html.*/, - embedtag: { - width: 480, - height: 400, - nocache: 1 - } - }), - new $.fn.oembed.OEmbedProvider("tudou", "video", ["tudou.com/programs/view/.+\/"], "http://www.tudou.com/v/$1/v.swf", { - templateRegex: /.*view\/(.+)\//, - embedtag: { - width: 480, - height: 400, - nocache: 1 - } - }), - new $.fn.oembed.OEmbedProvider("embedr", "video", ["embedr\\.com/playlist/.+"], "http://embedr.com/swf/slider/$1/425/520/default/false/std?", { - templateRegex: /.*playlist\/([^\/]+).*/, - embedtag: { - width: 425, - height: 520 - } - }), - new $.fn.oembed.OEmbedProvider("blip", "video", ["blip\\.tv/.+"], "http://blip.tv/oembed/"), - new $.fn.oembed.OEmbedProvider("minoto-video", "video", ["http://api.minoto-video.com/publishers/.+/videos/.+", "http://dashboard.minoto-video.com/main/video/details/.+", "http://embed.minoto-video.com/.+"], "http://api.minoto-video.com/services/oembed.json", { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("animoto", "video", ["animoto.com/play/.+"], "http://animoto.com/services/oembed"), - new $.fn.oembed.OEmbedProvider("hulu", "video", ["hulu\\.com/watch/.*"], "http://www.hulu.com/api/oembed.json"), - new $.fn.oembed.OEmbedProvider("ustream", "video", ["ustream\\.tv/recorded/.*"], "http://www.ustream.tv/oembed", { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("videojug", "video", ["videojug\\.com/(film|payer|interview).*"], "http://www.videojug.com/oembed.json", { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("sapo", "video", ["videos\\.sapo\\.pt/.*"], "http://videos.sapo.pt/oembed", { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("vodpod", "video", ["vodpod.com/watch/.*"], "http://vodpod.com/oembed.js", { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("vimeo", "video", ["www\.vimeo\.com\/groups\/.*\/videos\/.*", "www\.vimeo\.com\/.*", "vimeo\.com\/groups\/.*\/videos\/.*", "vimeo\.com\/.*"], "//vimeo.com/api/oembed.json"), - new $.fn.oembed.OEmbedProvider("dailymotion", "video", ["dailymotion\\.com/.+"], 'http://www.dailymotion.com/services/oembed'), - new $.fn.oembed.OEmbedProvider("5min", "video", ["www\\.5min\\.com/.+"], 'http://api.5min.com/oembed.xml', { - useYQL: 'xml' - }), - new $.fn.oembed.OEmbedProvider("National Film Board of Canada", "video", ["nfb\\.ca/film/.+"], 'http://www.nfb.ca/remote/services/oembed/', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("qik", "video", ["qik\\.com/\\w+"], 'http://qik.com/api/oembed.json', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("revision3", "video", ["revision3\\.com"], "http://revision3.com/api/oembed/"), - new $.fn.oembed.OEmbedProvider("dotsub", "video", ["dotsub\\.com/view/.+"], "http://dotsub.com/services/oembed", { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("clikthrough", "video", ["clikthrough\\.com/theater/video/\\d+"], "http://clikthrough.com/services/oembed"), - new $.fn.oembed.OEmbedProvider("Kinomap", "video", ["kinomap\\.com/.+"], "http://www.kinomap.com/oembed"), - new $.fn.oembed.OEmbedProvider("VHX", "video", ["vhx.tv/.+"], "http://vhx.tv/services/oembed.json"), - new $.fn.oembed.OEmbedProvider("bambuser", "video", ["bambuser.com/.+"], "http://api.bambuser.com/oembed/iframe.json"), - new $.fn.oembed.OEmbedProvider("justin.tv", "video", ["justin.tv/.+"], 'http://api.justin.tv/api/embed/from_url.json', { - useYQL: 'json' - }), - - //Audio - new $.fn.oembed.OEmbedProvider("official.fm", "rich", ["official.fm/.+"], 'http://official.fm/services/oembed', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("chirbit", "rich", ["chirb.it/.+"], 'http://chirb.it/oembed.json', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("Huffduffer", "rich", ["huffduffer.com/[-.\\w@]+/\\d+"], "http://huffduffer.com/oembed"), - new $.fn.oembed.OEmbedProvider("Spotify", "rich", ["open.spotify.com/(track|album|user)/"], "https://embed.spotify.com/oembed/"), - new $.fn.oembed.OEmbedProvider("shoudio", "rich", ["shoudio.com/.+", "shoud.io/.+"], "http://shoudio.com/api/oembed"), - new $.fn.oembed.OEmbedProvider("mixcloud", "rich", ["mixcloud.com/.+"], 'http://www.mixcloud.com/oembed/', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("rdio.com", "rich", ["rd.io/.+", "rdio.com"], "http://www.rdio.com/api/oembed/"), - new $.fn.oembed.OEmbedProvider("Soundcloud", "rich", ["soundcloud.com/.+", "snd.sc/.+"], "http://soundcloud.com/oembed", { - format: 'js' - }), - new $.fn.oembed.OEmbedProvider("bandcamp", "rich", ["bandcamp\\.com/album/.+"], null, { - yql: { - xpath: "//meta[contains(@content, \\'EmbeddedPlayer\\')]", - from: 'html', - datareturn: function (results) { - return results.meta ? '' : false; - } - } - }), - - //Photo - new $.fn.oembed.OEmbedProvider("deviantart", "photo", ["deviantart.com/.+", "fav.me/.+", "deviantart.com/.+"], "http://backend.deviantart.com/oembed", { - format: 'jsonp' - }), - new $.fn.oembed.OEmbedProvider("skitch", "photo", ["skitch.com/.+"], null, { - yql: { - xpath: "json", - from: 'json', - url: function (externalurl) { - return 'http://skitch.com/oembed/?format=json&url=' + externalurl - }, - datareturn: function (data) { - return $.fn.oembed.getPhotoCode(data.json.url, data.json); - } - } - }), - new $.fn.oembed.OEmbedProvider("mobypicture", "photo", ["mobypicture.com/user/.+/view/.+", "moby.to/.+"], "http://api.mobypicture.com/oEmbed"), - new $.fn.oembed.OEmbedProvider("flickr", "photo", ["flickr\\.com/photos/.+"], "http://flickr.com/services/oembed", { - callbackparameter: 'jsoncallback' - }), - new $.fn.oembed.OEmbedProvider("photobucket", "photo", ["photobucket\\.com/(albums|groups)/.+"], "http://photobucket.com/oembed/"), - new $.fn.oembed.OEmbedProvider("instagram", "photo", ["instagr\\.?am(\\.com)?/.+"], "http://api.instagram.com/oembed"), - // new $.fn.oembed.OEmbedProvider("yfrog", "photo", ["yfrog\\.(com|ru|com\\.tr|it|fr|co\\.il|co\\.uk|com\\.pl|pl|eu|us)/.+"], "http://www.yfrog.com/api/oembed", { - // useYQL: "json" - // }), - new $.fn.oembed.OEmbedProvider("SmugMug", "photo", ["smugmug.com/[-.\\w@]+/.+"], "http://api.smugmug.com/services/oembed/"), - - new $.fn.oembed.OEmbedProvider("dribbble", "photo", ["dribbble.com/shots/.+"], "http://api.dribbble.com/shots/$1?callback=?", { - templateRegex: /.*shots\/([\d]+).*/, - templateData: function (data) { - if(!data.image_teaser_url) return false; - return ''; - } - }), - new $.fn.oembed.OEmbedProvider("chart.ly", "photo", ["chart\\.ly/[a-z0-9]{6,8}"], "http://chart.ly/uploads/large_$1.png", { - templateRegex: /.*ly\/([^\/]+).*/, - embedtag: { - tag: 'img' - }, - nocache: 1 - }), - // new $.fn.oembed.OEmbedProvider("stocktwits.com", "photo", ["stocktwits\\.com/message/.+"], "http://charts.stocktwits.com/production/original_$1.png?", { - // templateRegex: /.*message\/([^\/]+).*/, - // embedtag: { - // tag: 'img' - // }, - // nocache: 1 - // }), - new $.fn.oembed.OEmbedProvider("circuitlab", "photo", ["circuitlab.com/circuit/.+"], "https://www.circuitlab.com/circuit/$1/screenshot/540x405/", { - templateRegex: /.*circuit\/([^\/]+).*/, - embedtag: { - tag: 'img' - }, - nocache: 1 - }), - new $.fn.oembed.OEmbedProvider("23hq", "photo", ["23hq.com/[-.\\w@]+/photo/.+"], "http://www.23hq.com/23/oembed", { - useYQL: "json" - }), - new $.fn.oembed.OEmbedProvider("img.ly", "photo", ["img\\.ly/.+"], "http://img.ly/show/thumb/$1", { - templateRegex: /.*ly\/([^\/]+).*/, - embedtag: { - tag: 'img' - }, - nocache: 1 - }), - new $.fn.oembed.OEmbedProvider("twitgoo.com", "photo", ["twitgoo\\.com/.+"], "http://twitgoo.com/show/thumb/$1", { - templateRegex: /.*com\/([^\/]+).*/, - embedtag: { - tag: 'img' - }, - nocache: 1 - }), - new $.fn.oembed.OEmbedProvider("imgur.com", "photo", ["imgur\\.com/gallery/.+"], "http://imgur.com/$1l.jpg", { - templateRegex: /.*gallery\/([^\/]+).*/, - embedtag: { - tag: 'img' - }, - nocache: 1 - }), - new $.fn.oembed.OEmbedProvider("visual.ly", "rich", ["visual\\.ly/.+"], null, { - yql: { - xpath: "//a[@id=\\'gc_article_graphic_image\\']/img", - from: 'htmlstring' - } - }), - - //Rich - new $.fn.oembed.OEmbedProvider("twitter", "rich", ["twitter.com/.+"], "https://api.twitter.com/1/statuses/oembed.json"), - new $.fn.oembed.OEmbedProvider("gmep", "rich", ["gmep.imeducate.com/.*", "gmep.org/.*"], "http://gmep.org/oembed.json"), - new $.fn.oembed.OEmbedProvider("urtak", "rich", ["urtak.com/(u|clr)/.+"], "http://oembed.urtak.com/1/oembed"), - new $.fn.oembed.OEmbedProvider("cacoo", "rich", ["cacoo.com/.+"], "http://cacoo.com/oembed.json"), - new $.fn.oembed.OEmbedProvider("dailymile", "rich", ["dailymile.com/people/.*/entries/.*"], "http://api.dailymile.com/oembed"), - new $.fn.oembed.OEmbedProvider("dipity", "rich", ["dipity.com/timeline/.+"], 'http://www.dipity.com/oembed/timeline/', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("sketchfab", "rich", ["sketchfab.com/show/.+"], 'http://sketchfab.com/oembed', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("speakerdeck", "rich", ["speakerdeck.com/.+"], 'http://speakerdeck.com/oembed.json', { - useYQL: 'json' - }), - new $.fn.oembed.OEmbedProvider("popplet", "rich", ["popplet.com/app/.*"], "http://popplet.com/app/Popplet_Alpha.swf?page_id=$1&em=1", { - templateRegex: /.*#\/([^\/]+).*/, - embedtag: { - width: 460, - height: 460 - } - }), - new $.fn.oembed.OEmbedProvider("pearltrees", "rich", ["pearltrees.com/.*"], "http://cdn.pearltrees.com/s/embed/getApp?", { - templateRegex: /.*N-f=1_(\d+).*N-p=(\d+).*/, - embedtag: { - width: 460, - height: 460, - flashvars: "lang=en_US&embedId=pt-embed-$1-693&treeId=$1&pearlId=$2&treeTitle=Diagrams%2FVisualization&site=www.pearltrees.com%2FF" - } - }), - new $.fn.oembed.OEmbedProvider("prezi", "rich", ["prezi.com/.*"], "http://prezi.com/bin/preziloader.swf?", { - templateRegex: /.*com\/([^\/]+)\/.*/, - embedtag: { - width: 550, - height: 400, - flashvars: "prezi_id=$1&lock_to_path=0&color=ffffff&autoplay=no&autohide_ctrls=0" - } - }), - new $.fn.oembed.OEmbedProvider("tourwrist", "rich", ["tourwrist.com/tours/.+"], null, { - templateRegex: /.*tours.([\d]+).*/, - template: function (wm, tourid) { - setTimeout(function () { - if(loadEmbeds) loadEmbeds(); - }, 2000); - return "
    "; - } - }), - new $.fn.oembed.OEmbedProvider("meetup", "rich", ["meetup\\.(com|ps)/.+"], "http://api.meetup.com/oembed"), - new $.fn.oembed.OEmbedProvider("ebay", "rich", ["ebay\\.*"], "http://togo.ebay.com/togo/togo.swf?2008013100", { - templateRegex: /.*\/([^\/]+)\/(\d{10,13}).*/, - embedtag: { - width: 355, - height: 300, - flashvars: "base=http://togo.ebay.com/togo/&lang=en-us&mode=normal&itemid=$2&query=$1" - } - }), - new $.fn.oembed.OEmbedProvider("wikipedia", "rich", ["wikipedia.org/wiki/.+"], "http://$1.wikipedia.org/w/api.php?action=parse&page=$2&format=json§ion=0&callback=?", { - templateRegex: /.*\/\/([\w]+).*\/wiki\/([^\/]+).*/, - templateData: function (data) { - if(!data.parse) return false; - var text = data.parse['text']['*'].replace(/href="\/wiki/g, 'href="http://en.wikipedia.org/wiki'); - return '
    ' + data.parse['displaytitle'] + '
    ' +jQuery(text).text().substring(0,200) + '...
    '; - } - }), - new $.fn.oembed.OEmbedProvider("imdb", "rich", ["imdb.com/title/.+"], "http://www.imdbapi.com/?i=$1&callback=?", { - templateRegex: /.*\/title\/([^\/]+).*/, - templateData: function (data) { - if(!data.Title) return false; - return '

    ' + data.Title + ' (' + data.Year + ')

    Rating: ' + data.imdbRating + '
    Genre: ' + data.Genre + '
    Starring: ' + data.Actors + '

    ' + data.Plot + '
    '; - } - }), - new $.fn.oembed.OEmbedProvider("livejournal", "rich", ["livejournal.com/"], "http://ljpic.seacrow.com/json/$2$4?jsonp=?", { - templateRegex: /(http:\/\/(((?!users).)+)\.livejournal\.com|.*users\.livejournal\.com\/([^\/]+)).*/, - templateData: function (data) { - if(!data.username) return false; - return '
    [info]' + data.username + '
    ' + data.name + '
    '; - } - }), - new $.fn.oembed.OEmbedProvider("circuitbee", "rich", ["circuitbee\\.com/circuit/view/.+"], "http://c.circuitbee.com/build/r/schematic-embed.html?id=$1", { - templateRegex: /.*circuit\/view\/(\d+).*/, - embedtag: { - tag: 'iframe', - width: '500', - height: '350' - } - }), - new $.fn.oembed.OEmbedProvider("googlecalendar", "rich", ["www.google.com/calendar/embed?.+"], "$1", { - templateRegex: /(.*)/, - embedtag: { - tag: 'iframe', - width: '800', - height: '600' - } - }), - new $.fn.oembed.OEmbedProvider("jsfiddle", "rich", ["jsfiddle.net/[^/]+/?"], "http://jsfiddle.net/$1/embedded/result,js,resources,html,css/?", { - templateRegex: /.*net\/([^\/]+).*/, - embedtag: { - tag: 'iframe', - width: '100%', - height: '300' - } - }), - new $.fn.oembed.OEmbedProvider("jsbin", "rich", ["jsbin.com/.+"], "http://jsbin.com/$1/?", { - templateRegex: /.*com\/([^\/]+).*/, - embedtag: { - tag: 'iframe', - width: '100%', - height: '300' - } - }), - new $.fn.oembed.OEmbedProvider("jotform", "rich", ["form.jotform.co/form/.+"], "$1?", { - templateRegex: /(.*)/, - embedtag: { - tag: 'iframe', - width: '100%', - height: '507' - } - }), - new $.fn.oembed.OEmbedProvider("reelapp", "rich", ["reelapp\\.com/.+"], "http://www.reelapp.com/$1/embed", { - templateRegex: /.*com\/(\S{6}).*/, - embedtag: { - tag: 'iframe', - width: '400', - height: '338' - } - }), - new $.fn.oembed.OEmbedProvider("linkedin", "rich", ["linkedin.com/pub/.+"], "https://www.linkedin.com/cws/member/public_profile?public_profile_url=$1&format=inline&isFramed=true", { - templateRegex: /(.*)/, - embedtag: { - tag: 'iframe', - width: '368px', - height: 'auto' - } - }), - new $.fn.oembed.OEmbedProvider("timetoast", "rich", ["timetoast.com/timelines/[0-9]+"], "http://www.timetoast.com/flash/TimelineViewer.swf?passedTimelines=$1", { - templateRegex: /.*timelines\/([0-9]*)/, - embedtag: { - width: 550, - height: 400, - nocache: 1 - } - }), - new $.fn.oembed.OEmbedProvider("pastebin", "rich", ["pastebin\\.com/[\\S]{8}"], "http://pastebin.com/embed_iframe.php?i=$1", { - templateRegex: /.*\/(\S{8}).*/, - embedtag: { - tag: 'iframe', - width: '100%', - height: 'auto' - } - }), - new $.fn.oembed.OEmbedProvider("mixlr", "rich", ["mixlr.com/.+"], "http://mixlr.com/embed/$1?autoplay=ae", { - templateRegex: /.*com\/([^\/]+).*/, - embedtag: { - tag: 'iframe', - width: '100%', - height: 'auto' - } - }), - new $.fn.oembed.OEmbedProvider("pastie", "rich", ["pastie\\.org/pastes/.+"], null, { - yql: { - xpath: '//pre[@class="textmate-source"]' - } - }), - new $.fn.oembed.OEmbedProvider("github", "rich", ["gist.github.com/.+"], "https://github.com/api/oembed"), - new $.fn.oembed.OEmbedProvider("github", "rich", ["github.com/[-.\\w@]+/[-.\\w@]+"], "https://api.github.com/repos/$1/$2?callback=?", { - templateRegex: /.*\/([^\/]+)\/([^\/]+).*/, - templateData: function (data) { - if(!data.data.html_url) return false; - return '

    ' + data.data.name + '

    ' + data.data.description + '

    ' + '

    Last updated: ' + data.data.pushed_at + '

    '; - } - }), - new $.fn.oembed.OEmbedProvider("facebook", "rich", ["facebook.com/(people/[^\\/]+/\\d+|[^\\/]+$)"], "https://graph.facebook.com/$2$3/?callback=?", { - templateRegex: /.*facebook.com\/(people\/[^\/]+\/(\d+).*|([^\/]+$))/, - templateData: function (data) { - if(!data.id) return false; - var out = '
    facebook '; - if(data.from) out += '' + data.from.name + ''; - else if(data.link) out += '' + data.name + ''; - else if(data.username) out += '' + data.name + ''; - else out += '' + data.name + ''; - out += '
    '; - if(data.picture) out += ''; - else out += ''; - if(data.from) out += '' + data.name + ''; - if(data.founded) out += 'Founded: ' + data.founded + '
    ' - if(data.category) out += 'Category: ' + data.category + '
    '; - if(data.website) out += 'Website: ' + data.website + '
    '; - if(data.gender) out += 'Gender: ' + data.gender + '
    '; - if(data.description) out += data.description + '
    '; - out += '
    '; - return out; - } - }), - new $.fn.oembed.OEmbedProvider("stackoverflow", "rich", ["stackoverflow.com/questions/[\\d]+"], "http://api.stackoverflow.com/1.1/questions/$1?body=true&jsonp=?", { - templateRegex: /.*questions\/([\d]+).*/, - templateData: function (data) { - if(!data.questions) return false; - var q = data.questions[0]; - var body = $(q.body).text(); - var out = '
    ' + '' + (q.up_vote_count - q.down_vote_count) + '
    vote(s)
    ' + '
    ' + q.answer_count + 'answer
    ' + q.view_count + ' view(s)
    ' + '

    ' + q.title + '

    ' + '
    ' + body.substring(0, 100) + '...
    '; - for(i in q.tags) - out += ''; - out += '
    '; - return out; - } - }), - new $.fn.oembed.OEmbedProvider("wordpress", "rich", ["wordpress\\.com/.+", "blogs\\.cnn\\.com/.+", "techcrunch\\.com/.+", "wp\\.me/.+"], "http://public-api.wordpress.com/oembed/1.0/?for=jquery-oembed-all"), - new $.fn.oembed.OEmbedProvider("screenr", "rich", ["screenr\.com"], "http://www.screenr.com/embed/$1", { - templateRegex: /.*\/([^\/]+).*/, - embedtag: { - tag: 'iframe', - width: '650', - height: 396 - } - }), - new $.fn.oembed.OEmbedProvider("gigpans", "rich", ["gigapan\\.org/[-.\\w@]+/\\d+"], "http://gigapan.org/gigapans/$1/options/nosnapshots/iframe/flash.html", { - templateRegex: /.*\/(\d+)\/?.*/, - embedtag: { - tag: 'iframe', - width: '100%', - height: 400 - } - }), - new $.fn.oembed.OEmbedProvider("scribd", "rich", ["scribd\\.com/.+"], "http://www.scribd.com/embeds/$1/content?start_page=1&view_mode=list", { - templateRegex: /.*doc\/([^\/]+).*/, - embedtag: { - tag: 'iframe', - width: '100%', - height: 600 - } - }), - new $.fn.oembed.OEmbedProvider("kickstarter", "rich", ["kickstarter\\.com/projects/.+"], "$1/widget/card.html", { - templateRegex: /([^\?]+).*/, - embedtag: { - tag: 'iframe', - width: '220', - height: 380 - } - }), - new $.fn.oembed.OEmbedProvider("amazon", "rich", ["amzn.com/B+", "amazon.com.*/(B\\S+)($|\\/.*)"], "http://rcm.amazon.com/e/cm?t=_APIKEY_&o=1&p=8&l=as1&asins=$1&ref=qf_br_asin_til&fc1=000000&IS2=1<1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr", { - apikey: true, - templateRegex: /.*\/(B[0-9A-Z]+)($|\/.*)/, - embedtag: { - tag: 'iframe', - width: '120px', - height: '240px' - } - }), - new $.fn.oembed.OEmbedProvider("slideshare", "rich", ["slideshare\.net"], "http://www.slideshare.net/api/oembed/2", { - format: 'jsonp' - }), - new $.fn.oembed.OEmbedProvider("roomsharejp", "rich", ["roomshare\\.jp/(en/)?post/.*"], "http://roomshare.jp/oembed.json"), - new $.fn.oembed.OEmbedProvider("lanyard", "rich", ["lanyrd.com/\\d+/.+"], null, { - yql: { - xpath: '(//div[@class="primary"])[1]', - from: 'htmlstring', - datareturn: function (results) { - if(!results.result) return false; - return '
    ' + results.result + '
    '; - } - } - }), - new $.fn.oembed.OEmbedProvider("asciiartfarts", "rich", ["asciiartfarts.com/\\d+.html"], null, { - yql: { - xpath: '//pre/font', - from: 'htmlstring', - datareturn: function (results) { - if(!results.result) return false; - return '
    ' + results.result + '
    '; - } - } - }) - ]; + ]; })(jQuery); +//This is needed for gravatar :( +String.prototype.md5=function(){var a=function(a,b){var c=(a&65535)+(b&65535);var d=(a>>16)+(b>>16)+(c>>16);return d<<16|c&65535};var b=function(a,b){return a<>>32-b};var c=function(c,d,e,f,g,h){return a(b(a(a(d,c),a(f,h)),g),e)};var d=function(a,b,d,e,f,g,h){return c(b&d|~b&e,a,b,f,g,h)};var e=function(a,b,d,e,f,g,h){return c(b&e|d&~e,a,b,f,g,h)};var f=function(a,b,d,e,f,g,h){return c(b^d^e,a,b,f,g,h)};var g=function(a,b,d,e,f,g,h){return c(d^(b|~e),a,b,f,g,h)};var h=function(b){var c,h,i,j,k,l=b.length;var m=1732584193;var n=-271733879;var o=-1732584194;var p=271733878;for(k=0;k>2]>>d%4*8+4&15)+b.charAt(a[d>>2]>>d%4*8&15)}return c};var j=function(a){var b=(a.length+8>>6)+1;var c=[],d,e=b*16,f,g=a.length;for(d=0;d>2]|=(a.charCodeAt(f)&255)<>2]|=128< Date: Sun, 6 Mar 2016 20:22:50 +0900 Subject: [PATCH 086/318] =?UTF-8?q?opengraph=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/oembed/jquery.oembed.js | 48 ---------------------------------- 1 file changed, 48 deletions(-) diff --git a/addons/oembed/jquery.oembed.js b/addons/oembed/jquery.oembed.js index 07ed993a5..496d689af 100755 --- a/addons/oembed/jquery.oembed.js +++ b/addons/oembed/jquery.oembed.js @@ -949,54 +949,6 @@ new $.fn.oembed.OEmbedProvider("polar", "rich", ["polarb\\.com/.+"], "http://assets-polarb-com.a.ssl.fastly.net/api/v4/publishers/unknown/embedded_polls/iframe?poll_id=$1", {templateRegex: /.*polarb\.com\/polls\/(\w+).*/, embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), new $.fn.oembed.OEmbedProvider("ponga", "rich", ["ponga\\.com/.+"], "https://www.ponga.com/embedded?id=$1", {templateRegex: [/.*ponga\.com\/embedded\?id=(\w+).*/, /.*ponga\.com\/(\w+).*/], embedtag: {tag: 'iframe', width: 480, height: 360 }, nocache: 1}), - //Use Open Graph Where applicable - new $.fn.oembed.OEmbedProvider("opengraph", "rich", [".*"], null, - { - yql: { - xpath: "//meta|//title|//link", - from: 'html', - datareturn: function (results) { - if (!results['og:title'] && results['title'] && results['description']) - results['og:title'] = results['title']; - - if (!results['og:title'] && !results['title']) - return false; - - var code = $('

    '); - if (results['og:video']) { - var embed = $(''); - embed.attr('type', results['og:video:type'] || "application/x-shockwave-flash") - .css('max-height', settings.maxHeight || 'auto') - .css('max-width', settings.maxWidth || 'auto'); - if (results['og:video:width']) - embed.attr('width', results['og:video:width']); - if (results['og:video:height']) - embed.attr('height', results['og:video:height']); - code.append(embed); - } else if (results['og:image']) { - var img = $(''); - img.css('max-height', settings.maxHeight || 'auto').css('max-width', settings.maxWidth || 'auto'); - if (results['og:image:width']) - img.attr('width', results['og:image:width']); - if (results['og:image:height']) - img.attr('height', results['og:image:height']); - code.append(img); - } - - if (results['og:title']) - code.append('' + results['og:title'] + '
    '); - - if (results['og:description']) - code.append(results['og:description'] + '
    '); - else if (results['description']) - code.append(results['description'] + '
    '); - - return code; - } - } - } - ) - ]; })(jQuery); //This is needed for gravatar :( From dff2578df315785d5490ef9b5c015ca669f78e5c Mon Sep 17 00:00:00 2001 From: YJSoft Date: Sun, 6 Mar 2016 21:08:16 +0900 Subject: [PATCH 087/318] =?UTF-8?q?HTTPS=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=EB=8A=94=20=EA=B8=B4=20=EC=A3=BC=EC=86=8C?= =?UTF-8?q?=EB=A5=BC=20=ED=92=80=EC=A7=80=20=EC=95=8A=EC=9D=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/oembed/jquery.oembed.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/oembed/jquery.oembed.js b/addons/oembed/jquery.oembed.js index 496d689af..1bafb620e 100755 --- a/addons/oembed/jquery.oembed.js +++ b/addons/oembed/jquery.oembed.js @@ -56,8 +56,10 @@ //Check if shorten URL for (var j = 0, l = shortURLList.length; j < l; j++) { var regExp = new RegExp('://' + shortURLList[j] + '/', "i"); + + provider = $.fn.oembed.getOEmbedProvider(resourceURL); - if (resourceURL.match(regExp) !== null) { + if (!provider && window.location.protocol !== "https:" && resourceURL.match(regExp) !== null) { //AJAX to http://api.longurl.org/v2/expand?url=http://bit.ly/JATvIs&format=json&callback=hhh var ajaxopts = $.extend({ url: "http://api.longurl.org/v2/expand", @@ -96,7 +98,6 @@ return container; } } - provider = $.fn.oembed.getOEmbedProvider(resourceURL); //remove fallback if (!!settings.fallback === false) { From 0e99f8eb4493ef8b765731b4edd1c20017d7514f Mon Sep 17 00:00:00 2001 From: conory Date: Sun, 6 Mar 2016 23:42:06 +0900 Subject: [PATCH 088/318] =?UTF-8?q?lang()=20=ED=95=A8=EC=88=98=EC=9D=98=20?= =?UTF-8?q?langType=20=EA=B8=B0=EB=8A=A5=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/functions.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/common/functions.php b/common/functions.php index 388e8d78e..154d60455 100644 --- a/common/functions.php +++ b/common/functions.php @@ -32,7 +32,7 @@ function config($key, $value = null) * @param string $value `$code`s value * @return mixed */ -function lang($code = null, $value = null) +function lang($code, $value = null) { if (!$GLOBALS['lang'] instanceof Rhymix\Framework\Lang) { @@ -40,17 +40,13 @@ function lang($code = null, $value = null) $GLOBALS['lang']->loadDirectory(RX_BASEDIR . 'common/lang', 'common'); } - if ($code !== null && $value === null) + if ($value === null) { return $GLOBALS['lang']->get($code); } - else if ($code !== null && $value !== null) - { - $GLOBALS['lang']->set($code, $value); - } else { - return $GLOBALS['lang']->langType(); + $GLOBALS['lang']->set($code, $value); } } From 9b5a17fb597e96cb83179fd22165e50cd18bd3d3 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 7 Mar 2016 08:34:06 +0900 Subject: [PATCH 089/318] Clean up repeating code and add redirect() function --- common/js/common.js | 17 ++++++++++++- common/js/xml_handler.js | 22 ++-------------- modules/board/tpl/js/board.js | 48 ++++++++--------------------------- 3 files changed, 29 insertions(+), 58 deletions(-) diff --git a/common/js/common.js b/common/js/common.js index 08b0d6688..a617209f6 100644 --- a/common/js/common.js +++ b/common/js/common.js @@ -377,6 +377,21 @@ function sendMailTo(to) { location.href="mailto:"+to; } +/** + * @brief url이동 (Rhymix 개선된 버전) + */ +function redirect(url) { + if (url === window.location.href || url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) + { + window.location.href = url; + window.location.reload(); + } + else + { + window.location.href = url; + } +} + /** * @brief url이동 (open_window 값이 N 가 아니면 새창으로 띄움) **/ @@ -394,7 +409,7 @@ function move_url(url, open_window) { if(open_window) { winopen(url); } else { - location.href=url; + redirect(url); } return false; diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index 74173f756..9d246a88b 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -106,16 +106,7 @@ data.redirect_url = data.redirect_url.replace(/&/g, "&"); } if (data.redirect_url && !$.isFunction(callback_success)) { - if (data.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) - { - window.location = data.redirect_url; - window.location.reload(); - } - else - { - window.location = data.redirect_url; - } - return; + return redirect(data.redirect_url); } // If there was a success callback, call it. @@ -236,16 +227,7 @@ data.redirect_url = data.redirect_url.replace(/&/g, "&"); } if (data.redirect_url && !$.isFunction(callback_success)) { - if (data.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) - { - window.location = data.redirect_url; - window.location.reload(); - } - else - { - window.location = data.redirect_url; - } - return; + return redirect(data.redirect_url); } // If there was a success callback, call it. diff --git a/modules/board/tpl/js/board.js b/modules/board/tpl/js/board.js index a4fbc0621..d0e7fa165 100644 --- a/modules/board/tpl/js/board.js +++ b/modules/board/tpl/js/board.js @@ -14,7 +14,7 @@ function completeDocumentInserted(ret_obj) var category_srl = ret_obj.category_srl; if (ret_obj.redirect_url) { - location.href = ret_obj.redirect_url; + redirect(ret_obj.redirect_url); } else { var url; if(!document_srl) @@ -26,7 +26,7 @@ function completeDocumentInserted(ret_obj) url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); } if(category_srl) url = url.setQuery('category',category_srl); - location.href = url; + redirect(url); } } @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); if(page) url = url.setQuery('page',page); - location.href = url; + redirect(url); } /* document search */ @@ -53,8 +53,7 @@ function completeVote(ret_obj) { var error = ret_obj.error; var message = ret_obj.message; - alert(message); - location.href = location.href; + redirect(window.location.href); } // current page reload @@ -62,8 +61,7 @@ function completeReload(ret_obj) { var error = ret_obj.error; var message = ret_obj.message; - - location.href = location.href; + redirect(window.location.href); } /* complete to insert comment*/ @@ -75,19 +73,11 @@ function completeInsertComment(ret_obj) var document_srl = ret_obj.document_srl; var comment_srl = ret_obj.comment_srl; if (ret_obj.redirect_url) { - if (ret_obj.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) - { - window.location = ret_obj.redirect_url; - window.location.reload(); - } - else - { - window.location = ret_obj.redirect_url; - } + redirect(ret_obj.redirect_url); } else { var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); if (comment_srl) url = url.setQuery('rnd',comment_srl)+"#comment_"+comment_srl; - window.location.href = url; + redirect(url); } } @@ -101,19 +91,11 @@ function completeDeleteComment(ret_obj) var page = ret_obj.page; if (ret_obj.redirect_url) { - if (ret_obj.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) - { - window.location = ret_obj.redirect_url; - window.location.reload(); - } - else - { - window.location = ret_obj.redirect_url; - } + redirect(ret_obj.redirect_url); } else { var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); if (page) url = url.setQuery('page',page); - window.location.href = url; + redirect(url); } } @@ -127,19 +109,11 @@ function completeDeleteTrackback(ret_obj) var page = ret_obj.page; if (ret_obj.redirect_url) { - if (ret_obj.redirect_url.indexOf(window.location.href.replace(/#.+$/, "") + "#") === 0) - { - window.location = ret_obj.redirect_url; - window.location.reload(); - } - else - { - window.location = ret_obj.redirect_url; - } + redirect(ret_obj.redirect_url); } else { var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); if (page) url = url.setQuery('page',page); - window.location.href = url; + redirect(url); } } From 145bdab6c62c22747b13fdabbff3a05db0e05b7a Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 7 Mar 2016 10:27:27 +0900 Subject: [PATCH 090/318] Allow more units in widget cache settings --- .../tpl/widget_generate_code.include.html | 9 ++++++++- modules/widget/widget.controller.php | 20 ++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/modules/widget/tpl/widget_generate_code.include.html b/modules/widget/tpl/widget_generate_code.include.html index 8d931af62..07e1daec0 100644 --- a/modules/widget/tpl/widget_generate_code.include.html +++ b/modules/widget/tpl/widget_generate_code.include.html @@ -25,7 +25,14 @@

    - {$lang->unit_min} + + +

    {$lang->about_widget_cache}

    diff --git a/modules/widget/widget.controller.php b/modules/widget/widget.controller.php index bc0154136..623c534ad 100644 --- a/modules/widget/widget.controller.php +++ b/modules/widget/widget.controller.php @@ -359,6 +359,16 @@ class widgetController extends widget // widget, the cache number and cache values are set $widget_sequence = $args->widget_sequence; $widget_cache = $args->widget_cache; + if (preg_match('/^([0-9\.]+)([smhd])$/i', $widget_cache, $matches)) + { + $multipliers = array('s' => 1, 'm' => 60, 'h' => 3600, 'd' => 86400); + $widget_cache = intval(floatval($matches[1]) * $multipliers[strtolower($matches[2])]); + } + else + { + $widget_cache = intval(floatval($widget_cache) * 60); + } + debugPrint($widget_cache); /** * Even if the cache number and value of the cache and return it to extract data @@ -400,7 +410,7 @@ class widgetController extends widget { $filemtime = filemtime($cache_file); // Should be modified compared to the time of the cache or in the future if creating more than widget.controller.php file a return value of the cache - if($filemtime + $widget_cache * 60 > $_SERVER['REQUEST_TIME'] && $filemtime > filemtime(_XE_PATH_.'modules/widget/widget.controller.php')) + if($filemtime + $widget_cache > $_SERVER['REQUEST_TIME'] && $filemtime > filemtime(_XE_PATH_.'modules/widget/widget.controller.php')) { $cache_body = FileHandler::readFile($cache_file); $cache_body = preg_replace('@<\!--#Meta:@', ' + +
    + + + + +
    diff --git a/modules/board/tpl/filter/update.xml b/modules/board/tpl/filter/update.xml new file mode 100644 index 000000000..a4ae8bb65 --- /dev/null +++ b/modules/board/tpl/filter/update.xml @@ -0,0 +1,7 @@ + +
    + + + + +
    diff --git a/modules/document/queries/getDocumentUpdateLog.xml b/modules/document/queries/getDocumentUpdateLog.xml index c7ceeedc0..db61979cb 100644 --- a/modules/document/queries/getDocumentUpdateLog.xml +++ b/modules/document/queries/getDocumentUpdateLog.xml @@ -9,6 +9,7 @@ + From 8b9bad458b0953fc99ec1b16bf0d1b4a1cf2364d Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 10 Mar 2016 18:05:20 +0900 Subject: [PATCH 114/318] delete debug code --- modules/board/board.controller.php | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index c936f3297..e2d38bd98 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -232,7 +232,6 @@ class boardController extends board { $oMemberModel = getModel('member'); $member_info = $oMemberModel->getMemberInfoByMemberSrl($val->update_member_srl); - debugPrint($val); if($member_info->is_admin === 'Y') { $isadminDocument = true; From b89818e13d724b62da83015d059b5f6f69327ae8 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 11 Mar 2016 15:29:42 +0900 Subject: [PATCH 115/318] Update HTMLPurifier configuration and allow HTML5 --- classes/security/Purifier.class.php | 155 +------------ common/framework/security/htmlfilter.php | 275 +++++++++++++++++++++++ common/legacy.php | 5 +- 3 files changed, 281 insertions(+), 154 deletions(-) create mode 100644 common/framework/security/htmlfilter.php diff --git a/classes/security/Purifier.class.php b/classes/security/Purifier.class.php index 6923e8cde..1664d87e0 100644 --- a/classes/security/Purifier.class.php +++ b/classes/security/Purifier.class.php @@ -3,161 +3,14 @@ class Purifier { - - private $_cacheDir; - private $_htmlPurifier; - private $_config; - private $_def; - - public function __construct() + public static function getInstance() { - $this->_checkCacheDir(); - $this->_setConfig(); + return new self(); } - - public function getInstance() - { - if(!isset($GLOBALS['__PURIFIER_INSTANCE__'])) - { - $GLOBALS['__PURIFIER_INSTANCE__'] = new Purifier(); - } - return $GLOBALS['__PURIFIER_INSTANCE__']; - } - - private function _setConfig() - { - $this->_config = HTMLPurifier_Config::createDefault(); - $this->_config->set('HTML.TidyLevel', 'light'); - $this->_config->set('Output.FlashCompat', TRUE); - $this->_config->set('HTML.SafeObject', TRUE); - $this->_config->set('HTML.SafeEmbed', TRUE); - $this->_config->set('HTML.SafeIframe', TRUE); - $this->_config->set('URI.SafeIframeRegexp', $this->_getWhiteDomainRegexp()); - $this->_config->set('Cache.SerializerPath', $this->_cacheDir); - $this->_config->set('Attr.AllowedFrameTargets', array('_blank')); - //$allowdClasses = array('emoticon'); - //$this->_config->set('Attr.AllowedClasses', $allowdClasses); - $this->_def = $this->_config->getHTMLDefinition(TRUE); - } - - private function _setDefinition(&$content) - { - // add attribute for edit component - $editComponentAttrs = $this->_searchEditComponent($content); - if(is_array($editComponentAttrs)) - { - foreach($editComponentAttrs AS $k => $v) - { - $this->_def->addAttribute('img', $v, 'CDATA'); - $this->_def->addAttribute('div', $v, 'CDATA'); - } - } - - // add attribute for widget component - $widgetAttrs = $this->_searchWidget($content); - if(is_array($widgetAttrs)) - { - foreach($widgetAttrs AS $k => $v) - { - $this->_def->addAttribute('img', $v, 'CDATA'); - } - } - } - - /** - * Search attribute of edit component tag - * @param string $content - * @return array - */ - private function _searchEditComponent($content) - { - preg_match_all('!<(?:(div)|img)([^>]*)editor_component=([^>]*)>(?(1)(.*?))!is', $content, $m); - - $attributeList = array(); - if(is_array($m[2])) - { - foreach($m[2] as $key => $value) - { - unset($script, $m2); - $script = " {$m[2][$key]} editor_component={$m[3][$key]}"; - - if(preg_match_all('/([a-z0-9_-]+)="([^"]+)"/is', $script, $m2)) - { - foreach($m2[1] as $value2) - { - //SECISSUE check style attr - if($value2 == 'style') - { - continue; - } - $attributeList[] = $value2; - } - } - } - } - - return array_unique($attributeList); - } - - /** - * Search edit component tag - * @param string $content - * @return array - */ - private function _searchWidget(&$content) - { - preg_match_all('!<(?:(div)|img)([^>]*)class="zbxe_widget_output"([^>]*)>(?(1)(.*?))!is', $content, $m); - - $attributeList = array(); - if(is_array($m[3])) - { - $content = str_replace(' $value) - { - if (preg_match_all('/([a-z0-9_-]+)="([^"]+)"/is', $m[3][$key], $m2)) - { - foreach($m2[1] as $value2) - { - //SECISSUE check style attr - if($value2 == 'style') - { - continue; - } - $attributeList[] = $value2; - } - } - } - } - return array_unique($attributeList); - } - - private function _getWhiteDomainRegexp() - { - $oEmbedFilter = EmbedFilter::getInstance(); - $whiteIframeUrlList = $oEmbedFilter->getWhiteIframeUrlList(); - - $whiteDomains = array(); - foreach($whiteIframeUrlList as $domain) - { - $whiteDomains[] = preg_quote($domain, '%'); - } - return '%^https?://(' . implode('|', $whiteDomains) . ')%'; - } - - private function _checkCacheDir() - { - // check htmlpurifier cache directory - $this->_cacheDir = _XE_PATH_ . 'files/cache/htmlpurifier'; - FileHandler::makeDir($this->_cacheDir); - } - + public function purify(&$content) { - $this->_setDefinition($content); - $this->_htmlPurifier = new HTMLPurifier($this->_config); - - $content = $this->_htmlPurifier->purify($content); + $content = Rhymix\Framework\Security\HTMLFilter::clean($content); } } diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php new file mode 100644 index 000000000..3c66e2d0a --- /dev/null +++ b/common/framework/security/htmlfilter.php @@ -0,0 +1,275 @@ +purify($input); + $output = self::_decodeWidgetsAndEditorComponents($output); + + foreach (self::$_postproc as $callback) + { + $output = $callback($output); + } + + return $output; + } + + /** + * Get an instance of HTMLPurifier. + * + * @return object + */ + public static function getHTMLPurifier() + { + // Create an instance with reasonable defaults. + if (self::$_htmlpurifier === null) + { + // Get the default configuration. + $config = \HTMLPurifier_Config::createDefault(); + + // Customize the default configuration. + $config->set('Attr.AllowedFrameTargets', array('_blank')); + $config->set('Attr.DefaultImageAlt', ''); + $config->set('Attr.EnableID', false); + $config->set('AutoFormat.AutoParagraph', false); + $config->set('AutoFormat.DisplayLinkURI', false); + $config->set('AutoFormat.Linkify', false); + $config->set('Core.Encoding', 'UTF-8'); + $config->set('HTML.Doctype', 'XHTML 1.0 Transitional'); + $config->set('HTML.FlashAllowFullScreen', true); + $config->set('HTML.MaxImgLength', null); + $config->set('CSS.MaxImgLength', null); + $config->set('CSS.Proprietary', true); + $config->set('Output.FlashCompat', true); + $config->set('Output.Newline', "\n"); + $config->set('URI.MakeAbsolute', false); + + // Allow embedding of external multimedia content. + $config->set('HTML.SafeEmbed', true); + $config->set('HTML.SafeIframe', true); + $config->set('HTML.SafeObject', true); + $config->set('URI.SafeIframeRegexp', self::_getIframeWhitelist()); + + // Set the serializer path. + $config->set('Cache.SerializerPath', RX_BASEDIR . 'files/cache/htmlpurifier'); + \FileHandler::makeDir(RX_BASEDIR . 'files/cache/htmlpurifier'); + + // Modify the HTML definition to support editor components and widgets. + $def = $config->getHTMLDefinition(true); + $def->addAttribute('img', 'editor_component', 'Text'); + $def->addAttribute('img', 'rx_encoded_properties', 'Text'); + $def->addAttribute('div', 'rx_encoded_properties', 'Text'); + + // Support HTML5: Based on https://github.com/xemlock/htmlpurifier-html5 + $def->addAttribute('img', 'srcset', 'Text'); + $def->addAttribute('iframe', 'allowfullscreen', 'Bool'); + $def->addElement('header', 'Block', 'Flow', 'Common'); + $def->addElement('footer', 'Block', 'Flow', 'Common'); + $def->addElement('nav', 'Block', 'Flow', 'Common'); + $def->addElement('main', 'Block', 'Flow', 'Common'); + $def->addElement('section', 'Block', 'Flow', 'Common'); + $def->addElement('article', 'Block', 'Flow', 'Common'); + $def->addElement('aside', 'Block', 'Flow', 'Common'); + $def->addElement('address', 'Block', 'Flow', 'Common'); + $def->addElement('figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'); + $def->addElement('figcaption', 'Inline', 'Flow', 'Common'); + $def->addElement('s', 'Inline', 'Inline', 'Common'); + $def->addElement('var', 'Inline', 'Inline', 'Common'); + $def->addElement('sub', 'Inline', 'Inline', 'Common'); + $def->addElement('sup', 'Inline', 'Inline', 'Common'); + $def->addElement('mark', 'Inline', 'Inline', 'Common'); + $def->addElement('wbr', 'Inline', 'Empty', 'Core'); + $def->addElement('ins', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text')); + $def->addElement('del', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text')); + $time = $def->addElement('time', 'Inline', 'Inline', 'Common', array('datetime' => 'Text', 'pubdate' => 'Bool')); + $time->excludes = array('time' => true); + $def->addElement('audio', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array( + 'src' => 'URI', + 'type' => 'Text', + 'preload' => 'Enum#auto,metadata,none', + 'controls' => 'Bool', + 'muted' => 'Bool', + 'loop' => 'Bool', + )); + $def->addElement('video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array( + 'src' => 'URI', + 'type' => 'Text', + 'width' => 'Length', + 'height' => 'Length', + 'poster' => 'URI', + 'preload' => 'Enum#auto,metadata,none', + 'controls' => 'Bool', + 'muted' => 'Bool', + 'loop' => 'Bool', + )); + $def->addElement('source', 'Block', 'Empty', 'Common', array( + 'src' => 'URI', + 'media' => 'Text', + 'type' => 'Text', + )); + $def->addElement('track', 'Block', 'Empty', 'Common', array( + 'src' => 'URI', + 'srclang' => 'Text', + 'label' => 'Text', + 'kind' => 'Enum#captions,chapters,descriptions,metadata,subtitles', + 'default' => 'Bool', + )); + + // Cache our instance of HTMLPurifier. + self::$_htmlpurifier = new \HTMLPurifier($config); + } + + // Return the cached instance. + return self::$_htmlpurifier; + } + + /** + * Get the iframe whitelist as a regular expression. + * + * @return string + */ + protected static function _getIframeWhitelist() + { + $domains = \EmbedFilter::getInstance()->getWhiteIframeUrlList(); + $result = array(); + foreach($domains as $domain) + { + $result[] = preg_quote($domain, '%'); + } + return '%^https?://(' . implode('|', $result) . ')%'; + } + + /** + * Encode widgets and editor components before processing. + * + * @param string $content + * @return string + */ + protected static function _encodeWidgetsAndEditorComponents($content) + { + preg_match_all('!<(div|img)([^>]*)(editor_component="[^"]+"|class="zbxe_widget_output")([^>]*)>!i', $content, $matches, \PREG_SET_ORDER); + foreach ($matches as $match) + { + $attrs = array(); + $html = $match[0]; + preg_match_all('/([a-zA-Z0-9_-]+)="([^"]+)"/', $match[2] . ' ' . $match[4], $found_attrs, \PREG_SET_ORDER); + foreach ($found_attrs as $attr) + { + $attrkey = strtolower($attr[1]); + if (strtolower($match[1]) === 'img' && ($attrkey === 'width' || $attrkey === 'height' || $attrkey === 'alt')) + { + continue; + } + if ($attrkey === 'src' || $attrkey === 'style' || substr($attrkey, 0, 2) === 'on') + { + continue; + } + $attrs[$attrkey] = htmlspecialchars_decode($attr[2]); + $html = str_replace($attr[0], '', $html); + } + if (strtolower($match[1]) === 'img' && !isset($attrs['src'])) + { + //$html = substr($html, 0, 4) . ' src=""' . substr($html, 4); + } + $encoded_properties = base64_encode(json_encode($attrs)); + $html = substr($html, 0, 4) . ' rx_encoded_properties="' . $encoded_properties . '"' . substr($html, 4); + $content = str_replace($match[0], $html, $content); + } + return $content; + } + + /** + * Decode widgets and editor components after processing. + * + * @param string $content + * @return string + */ + protected static function _decodeWidgetsAndEditorComponents($content) + { + preg_match_all('!<(div|img)([^>]*)(rx_encoded_properties="([^"]+)")!i', $content, $matches, \PREG_SET_ORDER); + foreach ($matches as $match) + { + $attrs = array(); + $decoded_properties = @json_decode(base64_decode($match[4])) ?: array(); + foreach ($decoded_properties as $key => $val) + { + $attrs[] = $key . '="' . htmlspecialchars($val) . '"'; + } + $content = str_replace($match[3], implode(' ', $attrs), $content); + } + return $content; + } +} diff --git a/common/legacy.php b/common/legacy.php index 9f07cf373..b37293abf 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -815,8 +815,7 @@ function url_decode($str) function purifierHtml(&$content) { - $oPurifier = Purifier::getInstance(); - $oPurifier->purify($content); + $content = Rhymix\Framework\Security\HTMLFilter::clean($content); } /** @@ -830,7 +829,7 @@ function removeHackTag($content) $oEmbedFilter = EmbedFilter::getInstance(); $oEmbedFilter->check($content); - purifierHtml($content); + $content = Rhymix\Framework\Security\HTMLFilter::clean($content); // change the specific tags to the common texts $content = preg_replace('@<(\/?(?:html|body|head|title|meta|base|link|script|style|applet)(/*).*?>)@i', '<$1', $content); From e405fc69acf5506aa7b4ec6b48100c6d84cd8983 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 11 Mar 2016 15:36:36 +0900 Subject: [PATCH 116/318] Update unit tests --- tests/unit/framework/DebugTest.php | 9 +-- tests/unit/framework/SecurityTest.php | 0 .../framework/security/HTMLFilterTest.php | 68 +++++++++++++++++++ tests/unit/functions/LegacyTest.php | 65 +----------------- 4 files changed, 74 insertions(+), 68 deletions(-) create mode 100644 tests/unit/framework/SecurityTest.php create mode 100644 tests/unit/framework/security/HTMLFilterTest.php diff --git a/tests/unit/framework/DebugTest.php b/tests/unit/framework/DebugTest.php index b6e4328d5..444ebac1f 100644 --- a/tests/unit/framework/DebugTest.php +++ b/tests/unit/framework/DebugTest.php @@ -45,10 +45,11 @@ class DebugTest extends \Codeception\TestCase\Test 'backtrace' => array(), )); $queries = Rhymix\Framework\Debug::getQueries(); - $this->assertEquals(1, count($queries)); - $this->assertEquals('SELECT foo FROM bar', $queries[0]->query_string); - $this->assertEquals('This is a unit test', $queries[0]->message); - $this->assertEquals(1234, $queries[0]->error_code); + $this->assertGreaterThanOrEqual(1, count($queries)); + $query = array_pop($queries); + $this->assertEquals('SELECT foo FROM bar', $query->query_string); + $this->assertEquals('This is a unit test', $query->message); + $this->assertEquals(1234, $query->error_code); } public function testDebugTranslateFilename() diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/framework/security/HTMLFilterTest.php b/tests/unit/framework/security/HTMLFilterTest.php new file mode 100644 index 000000000..d8fe40f28 --- /dev/null +++ b/tests/unit/framework/security/HTMLFilterTest.php @@ -0,0 +1,68 @@ +

    IFrame

    ', + '' + ), + // expression + array( + '
    ', + '
    ' + ), + // no quotes and no semicolon - http://ha.ckers.org/xss.html + array( + '', + '' + ), + // embedded encoded tab to break up XSS - http://ha.ckers.org/xss.html + array( + '', + '' + ), + // issue 178 + array( + '', + '' + ), + // issue 534 + array( + '*/" onerror="console.log(\'Yet another XSS\')">', + '*/" onerror="console.log(\'Yet another XSS\')">' + ), + // issue 602 + array( + 'test', + 'test' + ), + // issue #1813 https://github.com/xpressengine/xe-core/issues/1813 + array( + 'dummy', + 'dummy' + ), + array( + 'dummy', + 'dummy' + ), + array( + "\"dummy\"", + 'dummy' + ), + array( + "\"dummy\"", + 'dummy' + ) + ); + + foreach ($tests as $test) + { + $result = removeHackTag($test[0]); + $this->assertEquals($test[1], $result); + } + } +} diff --git a/tests/unit/functions/LegacyTest.php b/tests/unit/functions/LegacyTest.php index 65550545f..413b1f9cd 100644 --- a/tests/unit/functions/LegacyTest.php +++ b/tests/unit/functions/LegacyTest.php @@ -2,68 +2,5 @@ class LegacyTest extends \Codeception\TestCase\Test { - public function testRemoveHackTag() - { - $tests = array( - // remove iframe - array( - '', - // '
    <iframe src="path/to/file.html"></iframe>

    IFrame

    ' - '' - ), - // expression - array( - '
    ', - '
    ' - ), - // no quotes and no semicolon - http://ha.ckers.org/xss.html - array( - '', - '' - ), - // embedded encoded tab to break up XSS - http://ha.ckers.org/xss.html - array( - '', - 'jav ascript:alert(\'XSS\');' - ), - // issue 178 - array( - '', - 'invalid.jpg' - ), - // issue 534 - array( - '*/" onerror="console.log(\'Yet another XSS\')">', - 'as"df dummy=*/" onerror="console.log(\'Yet another XSS\')">' - ), - // issue 602 - array( - 'test', - 'test' - ), - // issue #1813 https://github.com/xpressengine/xe-core/issues/1813 - array( - 'dummy', - 'dummy' - ), - array( - 'dummy', - 'dummy' - ), - array( - "\"dummy\"", - 'dummy' - ), - array( - "\"dummy\"", - 'dummy' - ) - ); - - foreach ($tests as $test) - { - $result = removeHackTag($test[0]); - $this->assertEquals($test[1], $result); - } - } + } From 10e8962fa14b2cbfc77f57169915442433ea1c2d Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 11 Mar 2016 16:15:47 +0900 Subject: [PATCH 117/318] =?UTF-8?q?=EB=AC=B8=EC=84=9C=EA=B0=80=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=20=EA=B2=BD=EC=9A=B0=20404=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EB=A5=BC=20=EB=82=B4=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- classes/module/ModuleHandler.class.php | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index 14ea2e547..5f6990fad 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -168,12 +168,14 @@ class ModuleHandler extends Handler // Get module's information based on document_srl, if it's specified if($this->document_srl) { - $module_info = $oModuleModel->getModuleInfoByDocumentSrl($this->document_srl); - // If the document does not exist, remove document_srl + + // redirect, if the document does not exist if(!$module_info) { - unset($this->document_srl); + $this->error = 'The document does not exist'; + $this->httpStatusCode = '404'; + return true; } else { @@ -181,20 +183,17 @@ class ModuleHandler extends Handler // if mids are not matching, set it as the document's mid if(!$this->mid || ($this->mid != $module_info->mid)) { - if(Context::getRequestMethod() == 'GET') { Context::setCacheControl(0); - $this->mid = $module_info->mid; - header('location: ' . getNotEncodedSiteUrl($site_module_info->domain, 'mid', $this->mid, 'document_srl', $this->document_srl), true, 301); - return FALSE; + header('location: ' . getNotEncodedSiteUrl($site_module_info->domain, 'mid', $module_info->mid, 'document_srl', $this->document_srl), true, 301); + return false; } else { $this->mid = $module_info->mid; Context::set('mid', $this->mid); } - } // 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) @@ -202,7 +201,6 @@ class ModuleHandler extends Handler unset($module_info); } } - } // If module_info is not set yet, and there exists mid information, get module information based on the mid @@ -218,7 +216,7 @@ class ModuleHandler extends Handler Context::setCacheControl(0); $site_info = $oModuleModel->getSiteInfo($site_module_info->module_site_srl); header('location: ' . getNotEncodedSiteUrl($site_info->domain, 'mid', $site_module_info->mid), true, 301); - return FALSE; + return false; } // If module_info is not set still, and $module does not exist, find the default module @@ -249,7 +247,7 @@ class ModuleHandler extends Handler Context::setCacheControl(0); header("Location: $redirect_url", true, 301); - return FALSE; + return false; } // If module info was set, retrieve variables from the module information @@ -297,6 +295,7 @@ class ModuleHandler extends Handler { $this->error = 'msg_module_is_not_exists'; $this->httpStatusCode = '404'; + return true; } // If mid exists, set mid into context @@ -310,13 +309,13 @@ class ModuleHandler extends Handler if(!$output->toBool()) { $this->error = $output->getMessage(); - return TRUE; + return true; } // Set current module info into context Context::set('current_module_info', $this->module_info); - return TRUE; + return true; } /** From 4594c4032116fa96547165ceb5a4c31355762da5 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Fri, 11 Mar 2016 19:55:41 +0900 Subject: [PATCH 118/318] Disable useless UploadFileFilter --- classes/security/UploadFileFilter.class.php | 33 +-------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/classes/security/UploadFileFilter.class.php b/classes/security/UploadFileFilter.class.php index 56cfdb9bf..b19bd6889 100644 --- a/classes/security/UploadFileFilter.class.php +++ b/classes/security/UploadFileFilter.class.php @@ -3,40 +3,9 @@ class UploadFileFilter { - private static $_block_list = array ('exec', 'system', 'passthru', 'show_source', 'phpinfo', 'fopen', 'file_get_contents', 'file_put_contents', 'fwrite', 'proc_open', 'popen'); - public function check($file) { - // TODO: 기능개선후 enable - - return TRUE; // disable - if (! $file || ! FileHandler::exists($file)) return TRUE; - return self::_check ( $file ); - } - - private function _check($file) - { - if (! ($fp = fopen ( $file, 'r' ))) return FALSE; - - $has_php_tag = FALSE; - - while ( ! feof ( $fp ) ) - { - $content = fread ( $fp, 8192 ); - if (FALSE === $has_php_tag) $has_php_tag = strpos ( $content, ' Date: Fri, 11 Mar 2016 19:56:04 +0900 Subject: [PATCH 119/318] Add filename filter class --- common/framework/security/filenamefilter.php | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 common/framework/security/filenamefilter.php diff --git a/common/framework/security/filenamefilter.php b/common/framework/security/filenamefilter.php new file mode 100644 index 000000000..ff146230d --- /dev/null +++ b/common/framework/security/filenamefilter.php @@ -0,0 +1,49 @@ +', '{', '}', ':', ';', '|', '"', '~', '`', '@', '#', '$', '%', '^', '&', '*', '?'); + $replace = array('', '', '(', ')', '(', ')', '_', ',', '_', '', '_', '\'', '_', '_', '_', '_', '_', '_', '', ''); + $filename = str_replace($illegal, $replace, $filename); + + // Remove control characters. + $filename = preg_replace('/([\\x00-\\x1f\\x7f\\xff]+)/u', '', $filename); + + // Standardize whitespace characters. + $filename = trim(preg_replace('/[\\pZ\\pC]+/u', ' ', $filename)); + + // Remove excess spaces and replacement characters. + $filename = trim($filename, ' .-_'); + $filename = preg_replace('/__+/', '_', $filename); + + // Change .php files to .phps to make them non-executable. + if (strtolower(substr($filename, strlen($filename) - 4)) === '.php') + { + $filename = substr($filename, 0, strlen($filename) - 4) . '.phps'; + } + + // Truncate filenames over 127 chars long, or extensions over 16 chars long. + if (mb_strlen($filename, 'UTF-8') > 127) + { + $extension = strrchr($filename, '.'); + if (mb_strlen($extension, 'UTF-8') > 16) $extension = mb_substr($extension, 0, 16); + $filename = mb_substr($filename, 0, 127 - mb_strlen($extension)) . $extension; + } + + return $filename; + } +} From 8cbc3792809a056606914b532637579b79830d97 Mon Sep 17 00:00:00 2001 From: conory Date: Fri, 11 Mar 2016 22:19:04 +0900 Subject: [PATCH 120/318] =?UTF-8?q?GET=20=EC=9D=BC=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EC=97=90=EB=A7=8C=20404=20=EC=97=90=EB=9F=AC=EB=A5=BC=20?= =?UTF-8?q?=EB=82=B4=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- classes/module/ModuleHandler.class.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/classes/module/ModuleHandler.class.php b/classes/module/ModuleHandler.class.php index 5f6990fad..dcad62e66 100644 --- a/classes/module/ModuleHandler.class.php +++ b/classes/module/ModuleHandler.class.php @@ -170,12 +170,19 @@ class ModuleHandler extends Handler { $module_info = $oModuleModel->getModuleInfoByDocumentSrl($this->document_srl); - // redirect, if the document does not exist + // If the document does not exist, remove document_srl if(!$module_info) { - $this->error = 'The document does not exist'; - $this->httpStatusCode = '404'; - return true; + if(Context::getRequestMethod() == 'GET') + { + $this->error = 'The document does not exist'; + $this->httpStatusCode = '404'; + return true; + } + else + { + unset($this->document_srl); + } } else { @@ -471,7 +478,6 @@ class ModuleHandler extends Handler // 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()) { self::_setInputErrorToContext(); @@ -766,10 +772,6 @@ class ModuleHandler extends Handler } self::_setInputValueToSession(); } - else - { - - } if($error != 0) { @@ -945,13 +947,11 @@ class ModuleHandler extends Handler 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) { From f4e3d5762e1f8e4d5143218a091d4754e0de8524 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 14:37:54 +0900 Subject: [PATCH 121/318] Support more CSS2 and CSS3 properties --- common/framework/security/htmlfilter.php | 283 ++++++++++++++++++----- 1 file changed, 229 insertions(+), 54 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index 3c66e2d0a..562dd6644 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -133,60 +133,9 @@ class HTMLFilter $def->addAttribute('img', 'rx_encoded_properties', 'Text'); $def->addAttribute('div', 'rx_encoded_properties', 'Text'); - // Support HTML5: Based on https://github.com/xemlock/htmlpurifier-html5 - $def->addAttribute('img', 'srcset', 'Text'); - $def->addAttribute('iframe', 'allowfullscreen', 'Bool'); - $def->addElement('header', 'Block', 'Flow', 'Common'); - $def->addElement('footer', 'Block', 'Flow', 'Common'); - $def->addElement('nav', 'Block', 'Flow', 'Common'); - $def->addElement('main', 'Block', 'Flow', 'Common'); - $def->addElement('section', 'Block', 'Flow', 'Common'); - $def->addElement('article', 'Block', 'Flow', 'Common'); - $def->addElement('aside', 'Block', 'Flow', 'Common'); - $def->addElement('address', 'Block', 'Flow', 'Common'); - $def->addElement('figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'); - $def->addElement('figcaption', 'Inline', 'Flow', 'Common'); - $def->addElement('s', 'Inline', 'Inline', 'Common'); - $def->addElement('var', 'Inline', 'Inline', 'Common'); - $def->addElement('sub', 'Inline', 'Inline', 'Common'); - $def->addElement('sup', 'Inline', 'Inline', 'Common'); - $def->addElement('mark', 'Inline', 'Inline', 'Common'); - $def->addElement('wbr', 'Inline', 'Empty', 'Core'); - $def->addElement('ins', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text')); - $def->addElement('del', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text')); - $time = $def->addElement('time', 'Inline', 'Inline', 'Common', array('datetime' => 'Text', 'pubdate' => 'Bool')); - $time->excludes = array('time' => true); - $def->addElement('audio', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array( - 'src' => 'URI', - 'type' => 'Text', - 'preload' => 'Enum#auto,metadata,none', - 'controls' => 'Bool', - 'muted' => 'Bool', - 'loop' => 'Bool', - )); - $def->addElement('video', 'Block', 'Optional: (source, Flow) | (Flow, source) | Flow', 'Common', array( - 'src' => 'URI', - 'type' => 'Text', - 'width' => 'Length', - 'height' => 'Length', - 'poster' => 'URI', - 'preload' => 'Enum#auto,metadata,none', - 'controls' => 'Bool', - 'muted' => 'Bool', - 'loop' => 'Bool', - )); - $def->addElement('source', 'Block', 'Empty', 'Common', array( - 'src' => 'URI', - 'media' => 'Text', - 'type' => 'Text', - )); - $def->addElement('track', 'Block', 'Empty', 'Common', array( - 'src' => 'URI', - 'srclang' => 'Text', - 'label' => 'Text', - 'kind' => 'Enum#captions,chapters,descriptions,metadata,subtitles', - 'default' => 'Bool', - )); + // Support HTML5 and CSS3. + self::_supportHTML5($config); + self::_supportCSS3($config); // Cache our instance of HTMLPurifier. self::$_htmlpurifier = new \HTMLPurifier($config); @@ -196,6 +145,232 @@ class HTMLFilter return self::$_htmlpurifier; } + /** + * Patch HTMLPurifier to support some HTML5 tags and attributes. + * + * These changes are based on https://github.com/xemlock/htmlpurifier-html5 + * but modified to support even more tags and attributes. + * + * @param object $config + * @return void + */ + protected static function _supportHTML5($config) + { + // Get the HTML definition. + $def = $config->getHTMLDefinition(true); + + // Add various block-level tags. + $def->addElement('header', 'Block', 'Flow', 'Common'); + $def->addElement('footer', 'Block', 'Flow', 'Common'); + $def->addElement('nav', 'Block', 'Flow', 'Common'); + $def->addElement('main', 'Block', 'Flow', 'Common'); + $def->addElement('section', 'Block', 'Flow', 'Common'); + $def->addElement('article', 'Block', 'Flow', 'Common'); + $def->addElement('aside', 'Block', 'Flow', 'Common'); + $def->addElement('address', 'Block', 'Flow', 'Common'); + + // Add various inline tags. + $def->addElement('s', 'Inline', 'Inline', 'Common'); + $def->addElement('var', 'Inline', 'Inline', 'Common'); + $def->addElement('sub', 'Inline', 'Inline', 'Common'); + $def->addElement('sup', 'Inline', 'Inline', 'Common'); + $def->addElement('mark', 'Inline', 'Inline', 'Common'); + $def->addElement('wbr', 'Inline', 'Empty', 'Core'); + + // Support figures. + $def->addElement('figure', 'Block', 'Optional: (figcaption, Flow) | (Flow, figcaption) | Flow', 'Common'); + $def->addElement('figcaption', 'Inline', 'Flow', 'Common'); + + // Support insertions and deletions. + $def->addElement('ins', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text')); + $def->addElement('del', 'Block', 'Flow', 'Common', array('cite' => 'URI', 'datetime' => 'Text')); + + // Support the
    + diff --git a/modules/board/skins/xedition/update_view.html b/modules/board/skins/xedition/update_view.html index 27bd7220c..0b025ae7a 100644 --- a/modules/board/skins/xedition/update_view.html +++ b/modules/board/skins/xedition/update_view.html @@ -27,10 +27,11 @@
    -
    + - +
    + From 1c32e993abaefce4bdba93ee4cf221808039ec4a Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 17:42:28 +0900 Subject: [PATCH 127/318] Add unit tests for FilenameFilter class --- .../framework/security/FilenameFilterTest.php | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 tests/unit/framework/security/FilenameFilterTest.php diff --git a/tests/unit/framework/security/FilenameFilterTest.php b/tests/unit/framework/security/FilenameFilterTest.php new file mode 100644 index 000000000..935ffd473 --- /dev/null +++ b/tests/unit/framework/security/FilenameFilterTest.php @@ -0,0 +1,42 @@ + 'foo.bar', + 'foobar{baz}.jpg' => 'foobar(baz).jpg', + 'foobar^%.docx' => 'foobar_.docx', + + // Control characters + 'foobar' . chr(127) . '.gif' => 'foobar.gif', + 'foobar' . "\t\r\n" . '.gif' => 'foobar.gif', + + // Unicode whitepace characters + 'foobar' . html_entity_decode(' ') . ' space.gif' => 'foobar space.gif', + 'hello world.png' => 'hello world.png', + + // Extra symbols + '_foobar.jpg-' => 'foobar.jpg', + '.htaccess' => 'htaccess', + + // PHP extension + 'foobar.php' => 'foobar.phps', + 'foobar.php.jpg' => 'foobar.php.jpg', + + // Overlong filenames + str_repeat('f', 200) . '.' . str_repeat('b', 30) => str_repeat('f', 111) . '.' . str_repeat('b', 15), + str_repeat('한글', 100) . '.hwp' => str_repeat('한글', 61) . '한.hwp', + + ); + + foreach ($tests as $from => $to) + { + $result = Rhymix\Framework\Security\FilenameFilter::clean($from); + $this->assertEquals($to, $result); + } + } +} From 6d13142f30bfd4b5ca764f39f2333c93cd1e7a11 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 17:44:50 +0900 Subject: [PATCH 128/318] Use FilenameFilter in file module --- modules/file/file.controller.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 11b876063..78658ba80 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -732,10 +732,8 @@ class fileController extends file } } - // https://github.com/xpressengine/xe-core/issues/1713 - $file_info['name'] = preg_replace('/\.(php|phtm|phar|html?|cgi|pl|exe|jsp|asp|inc)/i', '$0-x',$file_info['name']); - $file_info['name'] = removeHackTag($file_info['name']); - $file_info['name'] = str_replace(array('<','>'),array('%3C','%3E'),$file_info['name']); + // Sanitize filename + $file_info['name'] = Rhymix\Framework\Security\FilenameFilter::clean($file_info['name']); // Get random number generator $random = new Password(); From 78238857d407dd60c4f193c5c8727d45a62570da Mon Sep 17 00:00:00 2001 From: BJRambo Date: Sat, 12 Mar 2016 17:52:38 +0900 Subject: [PATCH 129/318] add check alert. --- modules/board/lang/ko.php | 1 + modules/board/skins/xedition/update_view.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index c991091bb..0c627e9d1 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -64,3 +64,4 @@ $lang->msg_no_update_id = '업데이트 고유 번호는 필수입니다.'; $lang->msg_no_update_log = '업데이트 로그가 존재하지 않습니다.'; $lang->cmd_modify_by_update_log = '이 로그로 게시물을 수정하기'; $lang->msg_admin_update_log = '관리자가 수정한 적이 있는 게시물입니다. 관리자에게 문의하세요.'; +$lang->msg_update_log_revert = '정말로 이 게시물로 되돌리시겠습니까?'; diff --git a/modules/board/skins/xedition/update_view.html b/modules/board/skins/xedition/update_view.html index 0b025ae7a..487b11568 100644 --- a/modules/board/skins/xedition/update_view.html +++ b/modules/board/skins/xedition/update_view.html @@ -27,7 +27,7 @@ -
    + From b693c8cdadad1f854f5ed3a8912726342734719c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 19:44:05 +0900 Subject: [PATCH 130/318] Add unit tests for Security and URL classes --- common/framework/url.php | 4 +- tests/unit/framework/SecurityTest.php | 60 ++++++++++++++++++++++ tests/unit/framework/URLTest.php | 72 +++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 tests/unit/framework/URLTest.php diff --git a/common/framework/url.php b/common/framework/url.php index 5f55f4f76..1829fbe5c 100644 --- a/common/framework/url.php +++ b/common/framework/url.php @@ -44,7 +44,7 @@ class URL */ public static function getCanonicalURL($url) { - if (preg_match('#^\.?/([^/]|$)#', $url)) + if (preg_match('#^\.?/([^/]|$)#', $url) || !preg_match('#^(https?:|/)#', $url)) { $proto = \RX_SSL ? 'https://' : 'http://'; $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; @@ -89,7 +89,7 @@ class URL return true; } - if ($domain === self::getDomainFromURL($_SERVER['HTTP_HOST'])) + if ($domain === self::getDomainFromURL('http://' . $_SERVER['HTTP_HOST'])) { return true; } diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index e69de29bb..72b2e45a6 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -0,0 +1,60 @@ +assertEquals('foo<bar>', Rhymix\Framework\Security::sanitize('foo', 'escape')); + + // Strip + $this->assertEquals('foobar', Rhymix\Framework\Security::sanitize('foo

    bar

    ', 'strip')); + + // HTML (more thorough tests in HTMLFilterTest) + $this->assertEquals('

    safe

    ', Rhymix\Framework\Security::sanitize('

    safe

    ', 'html')); + + // Filename (more thorough tests in FilenameFilterTest) + $this->assertEquals('foo(bar).xls', Rhymix\Framework\Security::sanitize('foo.xls', 'filename')); + } + + public function testCheckCSRF() + { + $_SERVER['REQUEST_METHOD'] = 'GET'; + $_SERVER['HTTP_REFERER'] = ''; + $this->assertFalse(Rhymix\Framework\Security::checkCSRF()); + + $_SERVER['REQUEST_METHOD'] = 'POST'; + $this->assertTrue(Rhymix\Framework\Security::checkCSRF()); + + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + $_SERVER['HTTP_REFERER'] = 'http://www.foobar.com/'; + $this->assertFalse(Rhymix\Framework\Security::checkCSRF()); + + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + $this->assertTrue(Rhymix\Framework\Security::checkCSRF('http://www.rhymix.org/')); + } + + public function testCheckXEE() + { + $xml = ''; + $this->assertTrue(Rhymix\Framework\Security::checkXEE($xml)); + + $xml = ''; + $this->assertTrue(Rhymix\Framework\Security::checkXEE($xml)); + + $xml = ''; + $this->assertTrue(Rhymix\Framework\Security::checkXEE($xml)); + + $xml = ''; + $this->assertFalse(Rhymix\Framework\Security::checkXEE($xml)); + + $xml = ''; + $this->assertFalse(Rhymix\Framework\Security::checkXEE($xml)); + + $xml = ''; + $this->assertFalse(Rhymix\Framework\Security::checkXEE($xml)); + + $xml = ']>'; + $this->assertFalse(Rhymix\Framework\Security::checkXEE($xml)); + } +} diff --git a/tests/unit/framework/URLTest.php b/tests/unit/framework/URLTest.php new file mode 100644 index 000000000..93410ed58 --- /dev/null +++ b/tests/unit/framework/URLTest.php @@ -0,0 +1,72 @@ +assertEquals($full_url, Rhymix\Framework\URL::getCurrentURL()); + + // Adding items to the query string + $this->assertEquals($full_url . '&var=1&arr%5B0%5D=2&arr%5B1%5D=3', Rhymix\Framework\URL::getCurrentURL(array('var' => '1', 'arr' => array(2, 3)))); + + // Removing item from the query string + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks', Rhymix\Framework\URL::getCurrentURL(array('foo' => null))); + + // Adding and removing parameters at the same time + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks&l=ko', Rhymix\Framework\URL::getCurrentURL(array('l' => 'ko', 'foo' => null))); + } + + public function testGetCanonicalURL() + { + $protocol = \RX_SSL ? 'https://' : 'http://'; + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + + $tests = array( + 'foo/bar' => $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', + './foo/bar' => $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', + '/foo/bar' => $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', + '//www.example.com/foo' => $protocol . 'www.example.com/foo', + 'http://xn--cg4bkiv2oina.com/' => 'http://삼성전자.com/', + ); + + foreach ($tests as $from => $to) + { + $this->assertEquals($to, Rhymix\Framework\URL::getCanonicalURL($from)); + } + } + + public function testGetDomainFromURL() + { + $tests = array( + 'https://www.rhymix.org/foo/bar' => 'www.rhymix.org', + 'https://www.rhymix.org:8080/foo/bar' => 'www.rhymix.org', + 'http://xn--cg4bkiv2oina.com/' => '삼성전자.com', + ); + + foreach ($tests as $from => $to) + { + $this->assertEquals($to, Rhymix\Framework\URL::getDomainFromURL($from)); + } + } + + public function testIsInternalURL() + { + // This function is checked in Security::checkCSRF() + } + + public function testEncodeIdna() + { + $this->assertEquals('xn--9i1bl3b186bf9e.xn--3e0b707e', Rhymix\Framework\URL::encodeIdna('퓨니코드.한국')); + } + + public function testDecodeIdna() + { + $this->assertEquals('퓨니코드.한국', Rhymix\Framework\URL::decodeIdna('xn--9i1bl3b186bf9e.xn--3e0b707e')); + } +} From 37c07f7b6eebe1907727952ac7e44047a4f28b3e Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 19:59:10 +0900 Subject: [PATCH 131/318] Rename old SecurityTest class --- tests/unit/classes/{SecurityTest.php => OldSecurityTest.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/unit/classes/{SecurityTest.php => OldSecurityTest.php} (99%) diff --git a/tests/unit/classes/SecurityTest.php b/tests/unit/classes/OldSecurityTest.php similarity index 99% rename from tests/unit/classes/SecurityTest.php rename to tests/unit/classes/OldSecurityTest.php index f4cb7127d..f699b8d1b 100644 --- a/tests/unit/classes/SecurityTest.php +++ b/tests/unit/classes/OldSecurityTest.php @@ -1,7 +1,7 @@ Date: Sat, 12 Mar 2016 21:03:26 +0900 Subject: [PATCH 132/318] Remove all calls to checkUploadedFile() --- common/legacy.php | 2 +- modules/file/file.controller.php | 4 +-- .../integration_search.admin.controller.php | 2 +- modules/layout/layout.admin.controller.php | 7 ++--- modules/member/member.controller.php | 10 ------ modules/menu/menu.admin.controller.php | 31 +++++-------------- modules/module/module.admin.controller.php | 2 +- modules/module/module.controller.php | 6 ---- modules/rss/rss.admin.controller.php | 2 +- 9 files changed, 15 insertions(+), 51 deletions(-) diff --git a/common/legacy.php b/common/legacy.php index e2377b234..99a3bcd13 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -868,7 +868,7 @@ function blockWidgetCode($content) */ function checkUploadedFile($file) { - return UploadFileFilter::check($file); + return true; } /** diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 78658ba80..65a4720a1 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -763,12 +763,10 @@ class fileController extends file $filename = $path.$random->createSecureSalt(32, 'hex'); $direct_download = 'N'; } + // Create a directory if(!FileHandler::makeDir($path)) return new Object(-1,'msg_not_permitted_create'); - // Check uploaded file - if(!checkUploadedFile($file_info['tmp_name'])) return new Object(-1,'msg_file_upload_error'); - // Get random number generator $random = new Password(); diff --git a/modules/integration_search/integration_search.admin.controller.php b/modules/integration_search/integration_search.admin.controller.php index 232af8d62..3bd38c4e4 100644 --- a/modules/integration_search/integration_search.admin.controller.php +++ b/modules/integration_search/integration_search.admin.controller.php @@ -85,7 +85,7 @@ class integration_searchAdminController extends integration_search continue; } // Ignore if the file is not successfully uploaded, and check uploaded file - if(!is_uploaded_file($image_obj['tmp_name']) || !checkUploadedFile($image_obj['tmp_name'])) + if(!is_uploaded_file($image_obj['tmp_name'])) { unset($obj->{$vars->name}); continue; diff --git a/modules/layout/layout.admin.controller.php b/modules/layout/layout.admin.controller.php index 6a3342021..572d052ee 100644 --- a/modules/layout/layout.admin.controller.php +++ b/modules/layout/layout.admin.controller.php @@ -435,9 +435,6 @@ class layoutAdminController extends layout $ext = substr(strrchr($filename,'.'),1); $filename = sprintf('%s.%s', md5($filename), $ext); } - - // Check uploaded file - if(!checkUploadedFile($source['tmp_name'])) return false; if(file_exists($path .'/'. $filename)) @unlink($path . $filename); if(!move_uploaded_file($source['tmp_name'], $path . $filename )) return false; @@ -690,7 +687,7 @@ class layoutAdminController extends layout // check upload if(!Context::isUploaded()) exit(); $file = Context::get('file'); - if(!is_uploaded_file($file['tmp_name']) || !checkUploadedFile($file['tmp_name'])) exit(); + if(!is_uploaded_file($file['tmp_name'])) exit(); if(substr_compare($file['name'], '.tar', -4) !== 0) exit(); @@ -925,7 +922,7 @@ class layoutAdminController extends layout $this->setTemplatePath($this->module_path.'tpl'); $this->setTemplateFile("after_upload_config_image.html"); - if(!$img['tmp_name'] || !is_uploaded_file($img['tmp_name']) || !checkUploadedFile($img['tmp_name'])) + if(!$img['tmp_name'] || !is_uploaded_file($img['tmp_name'])) { Context::set('msg', lang('upload failed')); return; diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index c6bb4c134..a085d1c4e 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -729,10 +729,6 @@ class memberController extends member */ function insertProfileImage($member_srl, $target_file) { - - // Check uploaded file - if(!checkUploadedFile($target_file)) return; - $oMemberModel = getModel('member'); $config = $oMemberModel->getMemberConfig(); @@ -808,9 +804,6 @@ class memberController extends member */ function insertImageName($member_srl, $target_file) { - // Check uploaded file - if(!checkUploadedFile($target_file)) return; - $oModuleModel = getModel('module'); $config = $oModuleModel->getModuleConfig('member'); // Get an image size @@ -917,9 +910,6 @@ class memberController extends member */ function insertImageMark($member_srl, $target_file) { - // Check uploaded file - if(!checkUploadedFile($target_file)) return; - $oModuleModel = getModel('module'); $config = $oModuleModel->getModuleConfig('member'); // Get an image size diff --git a/modules/menu/menu.admin.controller.php b/modules/menu/menu.admin.controller.php index c007af59b..b22f8f39e 100644 --- a/modules/menu/menu.admin.controller.php +++ b/modules/menu/menu.admin.controller.php @@ -1520,7 +1520,7 @@ class menuAdminController extends menu Context::set('error_messge', lang('msg_invalid_request')); } - else if(!$target_file || !is_uploaded_file($target_file['tmp_name']) || !preg_match('/\.(gif|jpeg|jpg|png)$/i',$target_file['name']) || !checkUploadedFile($target_file['tmp_name'])) + else if(!$target_file || !is_uploaded_file($target_file['tmp_name']) || !preg_match('/\.(gif|jpeg|jpg|png)$/i',$target_file['name'])) { Context::set('error_messge', lang('msg_invalid_request')); } @@ -2132,19 +2132,15 @@ class menuAdminController extends menu $returnArray = array(); $date = date('YmdHis'); + // normal button if($args->menu_normal_btn) { $tmp_arr = explode('.',$args->menu_normal_btn['name']); $ext = $tmp_arr[count($tmp_arr)-1]; - $filename = sprintf('%s%d.%s.%s.%s', $path, $args->menu_item_srl, $date, 'menu_normal_btn', $ext); - - if(checkUploadedFile($args->menu_normal_btn['tmp_name'])) - { - move_uploaded_file ( $args->menu_normal_btn ['tmp_name'], $filename ); - $returnArray ['normal_btn'] = $filename; - } + move_uploaded_file($args->menu_normal_btn['tmp_name'], $filename); + $returnArray['normal_btn'] = $filename; } // hover button @@ -2152,14 +2148,9 @@ class menuAdminController extends menu { $tmp_arr = explode('.',$args->menu_hover_btn['name']); $ext = $tmp_arr[count($tmp_arr)-1]; - $filename = sprintf('%s%d.%s.%s.%s', $path, $args->menu_item_srl, $date, 'menu_hover_btn', $ext); - - if(checkUploadedFile($args->menu_hover_btn['tmp_name'])) - { - move_uploaded_file($args->menu_hover_btn['tmp_name'], $filename); - $returnArray['hover_btn'] = $filename; - } + move_uploaded_file($args->menu_hover_btn['tmp_name'], $filename); + $returnArray['hover_btn'] = $filename; } // active button @@ -2167,15 +2158,9 @@ class menuAdminController extends menu { $tmp_arr = explode('.',$args->menu_active_btn['name']); $ext = $tmp_arr[count($tmp_arr)-1]; - $filename = sprintf('%s%d.%s.%s.%s', $path, $args->menu_item_srl, $date, 'menu_active_btn', $ext); - - if(checkUploadedFile($args->menu_active_btn['tmp_name'])) - { - move_uploaded_file($args->menu_active_btn['tmp_name'], $filename); - $returnArray['active_btn'] = $filename; - } - + move_uploaded_file($args->menu_active_btn['tmp_name'], $filename); + $returnArray['active_btn'] = $filename; } return $returnArray; } diff --git a/modules/module/module.admin.controller.php b/modules/module/module.admin.controller.php index 25319d5b8..7eaddee2f 100644 --- a/modules/module/module.admin.controller.php +++ b/modules/module/module.admin.controller.php @@ -439,7 +439,7 @@ class moduleAdminController extends module continue; } // Ignore if the file is not successfully uploaded - if(!is_uploaded_file($image_obj['tmp_name']) || !checkUploadedFile($image_obj['tmp_name'])) + if(!is_uploaded_file($image_obj['tmp_name'])) { unset($obj->{$vars->name}); continue; diff --git a/modules/module/module.controller.php b/modules/module/module.controller.php index f70057d10..2943060c8 100644 --- a/modules/module/module.controller.php +++ b/modules/module/module.controller.php @@ -1303,9 +1303,6 @@ class moduleController extends module $save_filename = sprintf('%s%s.%s',$path, $vars->module_filebox_srl, $ext); $tmp = $vars->addfile['tmp_name']; - // Check uploaded file - if(!checkUploadedFile($tmp)) return false; - if(!@move_uploaded_file($tmp, $save_filename)) { return false; @@ -1340,9 +1337,6 @@ class moduleController extends module $save_filename = sprintf('%s%s.%s',$path, $vars->module_filebox_srl, $vars->ext); $tmp = $vars->addfile['tmp_name']; - // Check uploaded file - if(!checkUploadedFile($tmp)) return false; - // upload if(!@move_uploaded_file($tmp, $save_filename)) { diff --git a/modules/rss/rss.admin.controller.php b/modules/rss/rss.admin.controller.php index cb7e9c5bd..8368cb413 100644 --- a/modules/rss/rss.admin.controller.php +++ b/modules/rss/rss.admin.controller.php @@ -44,7 +44,7 @@ class rssAdminController extends rss $total_config->image = ''; } // Ignore if the file is not the one which has been successfully uploaded - if($image_obj['tmp_name'] && is_uploaded_file($image_obj['tmp_name']) && checkUploadedFile($image_obj['tmp_name'])) + if($image_obj['tmp_name'] && is_uploaded_file($image_obj['tmp_name'])) { // Ignore if the file is not an image (swf is accepted ~) $image_obj['name'] = Context::convertEncodingStr($image_obj['name']); From 1302d77cec0613149b9294b2abbdac4ac34ea6b5 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 21:05:09 +0900 Subject: [PATCH 133/318] Remove duplicate code from checkCSRF() --- common/legacy.php | 38 ++------------------------------------ 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/common/legacy.php b/common/legacy.php index 99a3bcd13..3c3bedf57 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -1183,42 +1183,8 @@ function requirePear() */ function checkCSRF() { - // If this is not a POST request, FAIL. - if ($_SERVER['REQUEST_METHOD'] != 'POST') - { - return false; - } - - // Get the referer. If the referer is empty, PASS. - $referer = strval($_SERVER['HTTP_REFERER']); - if ($referer === '') - { - return true; - } - if (strpos($referer, 'xn--') !== false) - { - $referer = Context::decodeIdna($referer); - } - $referer_host = parse_url($referer, PHP_URL_HOST); - - // If the referer is the same domain as the current host, PASS. - $current_host = $_SERVER['HTTP_HOST']; - if (strpos($current_host, 'xn--') !== false) - { - $current_host = Context::decodeIdna($current_host); - } - if ($referer_host === $current_host) - { - return true; - } - - // If the referer is the same domain as the default URL, PASS. - $default_url = Context::getDefaultUrl(); - if (strpos($default_url, 'xn--') !== false) - { - $default_url = Context::decodeIdna($default_url); - } - if ($referer_host === parse_url($default_url, PHP_URL_HOST)) + // Use Rhymix Security class first. + if (Rhymix\Framework\Security::checkCSRF()) { return true; } From be882d0c5cdc5fe7f93eebe3b809d29144214a1c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 21:11:53 +0900 Subject: [PATCH 134/318] Do not check allowscriptaccess because HTMLPurifier does it better --- classes/security/EmbedFilter.class.php | 53 -------------------------- 1 file changed, 53 deletions(-) diff --git a/classes/security/EmbedFilter.class.php b/classes/security/EmbedFilter.class.php index 2f90a753e..97b3866f1 100644 --- a/classes/security/EmbedFilter.class.php +++ b/classes/security/EmbedFilter.class.php @@ -3,18 +3,11 @@ class EmbedFilter { - /** * allow script access list * @var array */ var $allowscriptaccessList = array(); - - /** - * allow script access key - * @var int - */ - var $allowscriptaccessKey = 0; var $whiteUrlList = array(); var $whiteIframeUrlList = array(); var $mimeTypeList = array(); @@ -60,9 +53,6 @@ class EmbedFilter */ function check(&$content) { - $content = preg_replace_callback('/<(object|param|embed)[^>]*/is', array($this, '_checkAllowScriptAccess'), $content); - $content = preg_replace_callback('/]*>/is', array($this, '_addAllowScriptAccess'), $content); - $this->checkObjectTag($content); $this->checkEmbedTag($content); $this->checkParamTag($content); @@ -206,49 +196,6 @@ class EmbedFilter return FALSE; } - function _checkAllowScriptAccess($m) - { - if($m[1] == 'object') - { - $this->allowscriptaccessList[] = 1; - } - - if($m[1] == 'param') - { - if(stripos($m[0], 'allowscriptaccess')) - { - $m[0] = 'allowscriptaccessList[count($this->allowscriptaccessList) - 1]--; - } - } - else if($m[1] == 'embed') - { - if(stripos($m[0], 'allowscriptaccess')) - { - $m[0] = preg_replace('/always|samedomain/i', 'never', $m[0]); - } - else - { - $m[0] = preg_replace('/\allowscriptaccessList[$this->allowscriptaccessKey] == 1) - { - $m[0] = $m[0] . ''; - } - $this->allowscriptaccessKey++; - return $m[0]; - } - /** * Make white domain list cache file from xml config file. * @param $whitelist array From 598722b0cdd0e76e454c08d75054ae17cf5ac032 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 21:33:42 +0900 Subject: [PATCH 135/318] Remove checkXmpTag() and blockWidgetCode() because HTMLPurifier does it better --- common/framework/security/htmlfilter.php | 2 - common/legacy.php | 53 +++++++----------------- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index 562dd6644..75c1b3527 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -167,11 +167,9 @@ class HTMLFilter $def->addElement('section', 'Block', 'Flow', 'Common'); $def->addElement('article', 'Block', 'Flow', 'Common'); $def->addElement('aside', 'Block', 'Flow', 'Common'); - $def->addElement('address', 'Block', 'Flow', 'Common'); // Add various inline tags. $def->addElement('s', 'Inline', 'Inline', 'Common'); - $def->addElement('var', 'Inline', 'Inline', 'Common'); $def->addElement('sub', 'Inline', 'Inline', 'Common'); $def->addElement('sup', 'Inline', 'Inline', 'Common'); $def->addElement('mark', 'Inline', 'Inline', 'Common'); diff --git a/common/legacy.php b/common/legacy.php index 3c3bedf57..869f5a263 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -840,28 +840,33 @@ function removeHackTag($content) * - Issue reported by Sangwon Kim */ $content = preg_replace_callback('@<(/?)([a-z]+[0-9]?)((?>"[^"]*"|\'[^\']*\'|[^>])*?\b(?:on[a-z]+|data|style|background|href|(?:dyn|low)?src)\s*=[\s\S]*?)(/?)($|>|<)@i', 'removeSrcHack', $content); - - $content = checkXmpTag($content); - $content = blockWidgetCode($content); - return $content; } /** - * blocking widget code + * Check xmp tag (Deprecated) + * + * @param string $content Target content + * @return string + */ +function checkXmpTag($content) +{ + return $content; +} + +/** + * Block widget code (Deprecated) * * @param string $content Taget content * @return string **/ function blockWidgetCode($content) { - $content = preg_replace('/(<(?:img|div)(?:[^>]*))(widget)(?:(=([^>]*?)>))/is', '$1blocked-widget$3', $content); - - return $content; + return preg_replace('/(<(?:img|div)(?:[^>]*))(widget)(?:(=([^>]*?)>))/is', '$1blocked-widget$3', $content); } /** - * check uploaded file which may be hacking attempts + * Check uploaded file (Deprecated) * * @param string $file Taget file path * @return bool @@ -871,31 +876,6 @@ function checkUploadedFile($file) return true; } -/** - * Check xmp tag, close it. - * - * @param string $content Target content - * @return string - */ -function checkXmpTag($content) -{ - $content = preg_replace('@<(/?)xmp.*?>@i', '<\1xmp>', $content); - - if(($start_xmp = strrpos($content, '')) !== FALSE) - { - if(($close_xmp = strrpos($content, '')) === FALSE) - { - $content .= ''; - } - else if($close_xmp < $start_xmp) - { - $content .= ''; - } - } - - return $content; -} - /** * Remove src hack(preg_replace_callback) * @@ -906,11 +886,6 @@ function removeSrcHack($match) { $tag = strtolower($match[2]); - // xmp tag ?뺣━ - if($tag == 'xmp') - { - return "<{$match[1]}xmp>"; - } if($match[1]) { return $match[0]; From f577b456ec1897d60b7a18e41d6bb6d95327ff7c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 22:15:55 +0900 Subject: [PATCH 136/318] Absorb removeSrcHack() into HTMLFilter postprocessing method --- common/framework/security/htmlfilter.php | 61 ++++++++- common/legacy.php | 128 ++---------------- tests/unit/framework/SecurityTest.php | 2 +- .../framework/security/HTMLFilterTest.php | 8 +- 4 files changed, 72 insertions(+), 127 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index 75c1b3527..732b3c1d9 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -75,9 +75,9 @@ class HTMLFilter $input = $callback($input); } - $input = self::_encodeWidgetsAndEditorComponents($input); + $input = self::_preprocess($input); $output = self::getHTMLPurifier()->purify($input); - $output = self::_decodeWidgetsAndEditorComponents($output); + $output = self::_postprocess($output); foreach (self::$_postproc as $callback) { @@ -385,6 +385,55 @@ class HTMLFilter return '%^https?://(' . implode('|', $result) . ')%'; } + /** + * Rhymix-specific preprocessing method. + * + * @param string $content + * @return string + */ + protected static function _preprocess($content) + { + // Remove tags not supported in Rhymix. Some of these may also be removed by HTMLPurifier. + $content = preg_replace_callback('!]*>!i', function($matches) { + return htmlspecialchars($matches[0], ENT_QUOTES, 'UTF-8'); + }, $content); + + // Encode widget and editor component properties so that they are not removed by HTMLPurifier. + $content = self::_encodeWidgetsAndEditorComponents($content); + return $content; + } + + /** + * Rhymix-specific postprocessing method. + * + * @param string $content + * @return string + */ + protected static function _postprocess($content) + { + // Define acts to allow and deny. + $allow_acts = array('procFileDownload'); + $deny_acts = array('dispMemberLogout', 'dispLayoutPreview'); + + // Remove URLs that may be CSRF attempts. + $content = preg_replace_callback('!\b(src|href|data|value)="([^"]+)"!i', function($matches) use($allow_acts, $deny_acts) { + $url = preg_replace('!\s+!', '', htmlspecialchars_decode(rawurldecode($matches[2]))); + if (preg_match('!\bact=((disp|proc)[^&]+)!i', $url, $urlmatches)) + { + $act = $urlmatches[1]; + if (!in_array($act, $allow_acts) && (in_array($act, $deny_acts) || $urlmatches[2] === 'proc')) + { + return $matches[1] . '=""'; + } + } + return $matches[0]; + }, $content); + + // Restore widget and editor component properties. + $content = self::_decodeWidgetsAndEditorComponents($content); + return $content; + } + /** * Encode widgets and editor components before processing. * @@ -402,20 +451,20 @@ class HTMLFilter foreach ($found_attrs as $attr) { $attrkey = strtolower($attr[1]); - if (strtolower($match[1]) === 'img' && ($attrkey === 'width' || $attrkey === 'height' || $attrkey === 'alt')) + if (strtolower($match[1]) === 'img' && preg_match('/^(?:width|height|alt)$/', $attrkey)) { continue; } - if ($attrkey === 'src' || $attrkey === 'style' || substr($attrkey, 0, 2) === 'on') + if (preg_match('/^(?:on|data-|(?:src|style|class)$)/', $attrkey)) { continue; } $attrs[$attrkey] = htmlspecialchars_decode($attr[2]); $html = str_replace($attr[0], '', $html); } - if (strtolower($match[1]) === 'img' && !isset($attrs['src'])) + if (strtolower($match[1]) === 'img' && !preg_match('/\ssrc="/', $html)) { - //$html = substr($html, 0, 4) . ' src=""' . substr($html, 4); + $html = substr($html, 0, 4) . ' src=""' . substr($html, 4); } $encoded_properties = base64_encode(json_encode($attrs)); $html = substr($html, 0, 4) . ' rx_encoded_properties="' . $encoded_properties . '"' . substr($html, 4); diff --git a/common/legacy.php b/common/legacy.php index 869f5a263..3ff522350 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -830,17 +830,7 @@ function removeHackTag($content) $oEmbedFilter = EmbedFilter::getInstance(); $oEmbedFilter->check($content); - $content = Rhymix\Framework\Security\HTMLFilter::clean($content); - - // change the specific tags to the common texts - $content = preg_replace('@<(\/?(?:html|body|head|title|meta|base|link|script|style|applet)(/*).*?>)@i', '<$1', $content); - - /** - * Remove codes to abuse the admin session in src by tags of imaages and video postings - * - Issue reported by Sangwon Kim - */ - $content = preg_replace_callback('@<(/?)([a-z]+[0-9]?)((?>"[^"]*"|\'[^\']*\'|[^>])*?\b(?:on[a-z]+|data|style|background|href|(?:dyn|low)?src)\s*=[\s\S]*?)(/?)($|>|<)@i', 'removeSrcHack', $content); - return $content; + return Rhymix\Framework\Security\HTMLFilter::clean($content); } /** @@ -865,6 +855,17 @@ function blockWidgetCode($content) return preg_replace('/(<(?:img|div)(?:[^>]*))(widget)(?:(=([^>]*?)>))/is', '$1blocked-widget$3', $content); } +/** + * Remove src hack (Deprecated) + * + * @param array $match + * @return string + */ +function removeSrcHack($match) +{ + return $match[0]; +} + /** * Check uploaded file (Deprecated) * @@ -876,111 +877,6 @@ function checkUploadedFile($file) return true; } -/** - * Remove src hack(preg_replace_callback) - * - * @param array $match - * @return string - */ -function removeSrcHack($match) -{ - $tag = strtolower($match[2]); - - if($match[1]) - { - return $match[0]; - } - if($match[4]) - { - $match[4] = ' ' . $match[4]; - } - - $attrs = array(); - if(preg_match_all('/([\w:-]+)\s*=(?:\s*(["\']))?(?(2)(.*?)\2|([^ ]+))/s', $match[3], $m)) - { - foreach($m[1] as $idx => $name) - { - if(strlen($name) >= 2 && substr_compare($name, 'on', 0, 2) === 0) - { - continue; - } - - $val = preg_replace_callback('/&#(?:x([a-fA-F0-9]+)|0*(\d+));/', function($n) {return chr($n[1] ? ('0x00' . $n[1]) : ($n[2] + 0)); }, $m[3][$idx] . $m[4][$idx]); - $val = preg_replace('/^\s+|[\t\n\r]+/', '', $val); - - if(preg_match('/^[a-z]+script:/i', $val)) - { - continue; - } - - $attrs[$name] = $val; - } - } - - //Remove ACT URL (CSRF) - $except_act = array('procFileDownload'); - $block_act = array('dispMemberLogout', 'dispLayoutPreview'); - - $filter_arrts = array('style', 'src', 'href'); - if($tag === 'object') array_push($filter_arrts, 'data'); - if($tag === 'param') array_push($filter_arrts, 'value'); - - foreach($filter_arrts as $attr) - { - if(!isset($attrs[$attr])) continue; - - $attr_value = rawurldecode($attrs[$attr]); - $attr_value = htmlspecialchars_decode($attr_value, ENT_COMPAT); - $attr_value = preg_replace('/\s+|[\t\n\r]+/', '', $attr_value); - - preg_match('@(\?|&|;)act=(disp|proc)([^&]*)@i', $attr_value, $actmatch); - $url_action = $actmatch[2].$actmatch[3]; - - if(!empty($url_action) && !in_array($url_action, $except_act)) - { - if($actmatch[2] == 'proc' || in_array($url_action, $block_act)) - { - unset($attrs[$attr]); - } - } - } - - if(isset($attrs['style']) && preg_match('@(?:/\*|\*/|\n|:\s*expression\s*\()@i', $attrs['style'])) - { - unset($attrs['style']); - } - - $attr = array(); - foreach($attrs as $name => $val) - { - if($tag == 'object' || $tag == 'embed' || $tag == 'a') - { - $attribute = strtolower(trim($name)); - if($attribute == 'data' || $attribute == 'src' || $attribute == 'href') - { - if(stripos($val, 'data:') === 0) - { - continue; - } - } - } - - if($tag == 'img') - { - $attribute = strtolower(trim($name)); - if(stripos($val, 'data:') === 0) - { - continue; - } - } - $val = str_replace('"', '"', $val); - $attr[] = $name . "=\"{$val}\""; - } - $attr = count($attr) ? ' ' . implode(' ', $attr) : ''; - - return "<{$match[1]}{$tag}{$attr}{$match[4]}>"; -} - /** * Convert hexa value to RGB * diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index 72b2e45a6..3bf9b35c0 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -11,7 +11,7 @@ class SecurityTest extends \Codeception\TestCase\Test $this->assertEquals('foobar', Rhymix\Framework\Security::sanitize('foo

    bar

    ', 'strip')); // HTML (more thorough tests in HTMLFilterTest) - $this->assertEquals('

    safe

    ', Rhymix\Framework\Security::sanitize('

    safe

    ', 'html')); + $this->assertEquals('

    safe<script></script>

    ', Rhymix\Framework\Security::sanitize('

    safe

    ', 'html')); // Filename (more thorough tests in FilenameFilterTest) $this->assertEquals('foo(bar).xls', Rhymix\Framework\Security::sanitize('foo.xls', 'filename')); diff --git a/tests/unit/framework/security/HTMLFilterTest.php b/tests/unit/framework/security/HTMLFilterTest.php index d8fe40f28..e29ae9438 100644 --- a/tests/unit/framework/security/HTMLFilterTest.php +++ b/tests/unit/framework/security/HTMLFilterTest.php @@ -43,19 +43,19 @@ class HTMLFilterTest extends \Codeception\TestCase\Test // issue #1813 https://github.com/xpressengine/xe-core/issues/1813 array( 'dummy', - 'dummy' + 'dummy' ), array( 'dummy', - 'dummy' + 'dummy' ), array( "\"dummy\"", - 'dummy' + 'dummy' ), array( "\"dummy\"", - 'dummy' + 'dummy' ) ); From 143b65e84023bafc0383eaf33dc28cdbbe3a6dde Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 22:18:33 +0900 Subject: [PATCH 137/318] Perform tag filtering after HTMLPurifier is done with the content --- common/framework/security/htmlfilter.php | 12 ++++++------ tests/unit/framework/SecurityTest.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index 732b3c1d9..e791595eb 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -393,11 +393,6 @@ class HTMLFilter */ protected static function _preprocess($content) { - // Remove tags not supported in Rhymix. Some of these may also be removed by HTMLPurifier. - $content = preg_replace_callback('!]*>!i', function($matches) { - return htmlspecialchars($matches[0], ENT_QUOTES, 'UTF-8'); - }, $content); - // Encode widget and editor component properties so that they are not removed by HTMLPurifier. $content = self::_encodeWidgetsAndEditorComponents($content); return $content; @@ -415,7 +410,12 @@ class HTMLFilter $allow_acts = array('procFileDownload'); $deny_acts = array('dispMemberLogout', 'dispLayoutPreview'); - // Remove URLs that may be CSRF attempts. + // Remove tags not supported in Rhymix. Some of these may also have been removed by HTMLPurifier. + $content = preg_replace_callback('!]*>!i', function($matches) { + return htmlspecialchars($matches[0], ENT_QUOTES, 'UTF-8'); + }, $content); + + // Remove link URLs that may be CSRF attempts. $content = preg_replace_callback('!\b(src|href|data|value)="([^"]+)"!i', function($matches) use($allow_acts, $deny_acts) { $url = preg_replace('!\s+!', '', htmlspecialchars_decode(rawurldecode($matches[2]))); if (preg_match('!\bact=((disp|proc)[^&]+)!i', $url, $urlmatches)) diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index 3bf9b35c0..91e1f3740 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -11,7 +11,7 @@ class SecurityTest extends \Codeception\TestCase\Test $this->assertEquals('foobar', Rhymix\Framework\Security::sanitize('foo

    bar

    ', 'strip')); // HTML (more thorough tests in HTMLFilterTest) - $this->assertEquals('

    safe<script></script>

    ', Rhymix\Framework\Security::sanitize('

    safe

    ', 'html')); + $this->assertEquals('

    safe

    ', Rhymix\Framework\Security::sanitize('

    safe

    ', 'html')); // Filename (more thorough tests in FilenameFilterTest) $this->assertEquals('foo(bar).xls', Rhymix\Framework\Security::sanitize('foo.xls', 'filename')); From 6f53a3f0689bb4d4aba37e9927f9021048d627bc Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 22:35:43 +0900 Subject: [PATCH 138/318] Check object whitelist in HTMLFilter class, not EmbedFilter class --- classes/security/EmbedFilter.class.php | 54 +++--------------------- common/framework/security/htmlfilter.php | 31 ++++++++++++++ common/legacy.php | 3 -- 3 files changed, 36 insertions(+), 52 deletions(-) diff --git a/classes/security/EmbedFilter.class.php b/classes/security/EmbedFilter.class.php index 97b3866f1..382bf0fe0 100644 --- a/classes/security/EmbedFilter.class.php +++ b/classes/security/EmbedFilter.class.php @@ -53,9 +53,7 @@ class EmbedFilter */ function check(&$content) { - $this->checkObjectTag($content); - $this->checkEmbedTag($content); - $this->checkParamTag($content); + // This functionality has been moved to the HTMLFilter class. } /** @@ -64,8 +62,7 @@ class EmbedFilter */ function checkIframeTag(&$content) { - // check in Purifier class - return; + // This functionality has been moved to the HTMLFilter class. } /** @@ -74,21 +71,7 @@ class EmbedFilter */ function checkObjectTag(&$content) { - $content = preg_replace_callback('/<\s*object\s*[^>]+(?:\/?>?)/is', function($m) { - $html = Sunra\PhpSimple\HtmlDomParser::str_get_html($m[0]); - foreach ($html->find('object') as $element) - { - if ($element->data && !$this->isWhiteDomain($element->data)) - { - return escape($m[0], false); - } - if ($element->type && !$this->isWhiteMimetype($element->type)) - { - return escape($m[0], false); - } - } - return $m[0]; - }, $content); + // This functionality has been moved to the HTMLFilter class. } /** @@ -97,21 +80,7 @@ class EmbedFilter */ function checkEmbedTag(&$content) { - $content = preg_replace_callback('/<\s*embed\s*[^>]+(?:\/?>?)/is', function($m) { - $html = Sunra\PhpSimple\HtmlDomParser::str_get_html($m[0]); - foreach ($html->find('embed') as $element) - { - if ($element->src && !$this->isWhiteDomain($element->src)) - { - return escape($m[0], false); - } - if ($element->type && !$this->isWhiteMimetype($element->type)) - { - return escape($m[0], false); - } - } - return $m[0]; - }, $content); + // This functionality has been moved to the HTMLFilter class. } /** @@ -120,20 +89,7 @@ class EmbedFilter */ function checkParamTag(&$content) { - $content = preg_replace_callback('/<\s*param\s*[^>]+(?:\/?>?)/is', function($m) { - $html = Sunra\PhpSimple\HtmlDomParser::str_get_html($m[0]); - foreach ($html->find('param') as $element) - { - foreach (array('movie', 'src', 'href', 'url', 'source') as $attr) - { - if ($element->$attr && !$this->isWhiteDomain($element->$attr)) - { - return escape($m[0], false); - } - } - } - return $m[0]; - }, $content); + // This functionality has been moved to the HTMLFilter class. } /** diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index e791595eb..07fa31914 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -369,6 +369,22 @@ class HTMLFilter } } + /** + * Get the object whitelist as a regular expression. + * + * @return string + */ + protected static function _getObjectWhitelist() + { + $domains = \EmbedFilter::getInstance()->getWhiteUrlList(); + $result = array(); + foreach($domains as $domain) + { + $result[] = preg_quote($domain, '%'); + } + return '%^https?://(' . implode('|', $result) . ')%'; + } + /** * Get the iframe whitelist as a regular expression. * @@ -415,6 +431,21 @@ class HTMLFilter return htmlspecialchars($matches[0], ENT_QUOTES, 'UTF-8'); }, $content); + // Remove object and embed URLs that are not allowed. + $whitelist = self::_getObjectWhitelist(); + $content = preg_replace_callback('!<(object|embed|param)([^>]+)>!i', function($matches) use($whitelist) { + return preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use($whitelist) { + if (in_array($attr[1], array('data', 'src', 'href', 'url', 'movie', 'source'))) + { + if (!preg_match($whitelist, htmlspecialchars_decode($attr[2]))) + { + return $attr[1] . '=""'; + } + } + return $attr[0]; + }, $matches[0]); + }, $content); + // Remove link URLs that may be CSRF attempts. $content = preg_replace_callback('!\b(src|href|data|value)="([^"]+)"!i', function($matches) use($allow_acts, $deny_acts) { $url = preg_replace('!\s+!', '', htmlspecialchars_decode(rawurldecode($matches[2]))); diff --git a/common/legacy.php b/common/legacy.php index 3ff522350..1830d3a90 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -827,9 +827,6 @@ function purifierHtml(&$content) */ function removeHackTag($content) { - $oEmbedFilter = EmbedFilter::getInstance(); - $oEmbedFilter->check($content); - return Rhymix\Framework\Security\HTMLFilter::clean($content); } From 93629d1311d40fd1b58fd37c1ef7ae68b5b331e8 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 22:44:09 +0900 Subject: [PATCH 139/318] Refactor widget and editor component encoding with preg_replace_callback() --- common/framework/security/htmlfilter.php | 34 +++++++++--------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index 07fa31914..cad870bc5 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -473,35 +473,28 @@ class HTMLFilter */ protected static function _encodeWidgetsAndEditorComponents($content) { - preg_match_all('!<(div|img)([^>]*)(editor_component="[^"]+"|class="zbxe_widget_output")([^>]*)>!i', $content, $matches, \PREG_SET_ORDER); - foreach ($matches as $match) - { + return preg_replace_callback('!<(div|img)([^>]*)(editor_component="[^"]+"|class="zbxe_widget_output")([^>]*)>!i', function($match) { $attrs = array(); - $html = $match[0]; - preg_match_all('/([a-zA-Z0-9_-]+)="([^"]+)"/', $match[2] . ' ' . $match[4], $found_attrs, \PREG_SET_ORDER); - foreach ($found_attrs as $attr) - { + $html = preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use(&$attrs) { $attrkey = strtolower($attr[1]); if (strtolower($match[1]) === 'img' && preg_match('/^(?:width|height|alt)$/', $attrkey)) { - continue; + return $attr[0]; } - if (preg_match('/^(?:on|data-|(?:src|style|class)$)/', $attrkey)) + if (preg_match('/^(?:on|data-|(?:src|style|class|editor_component)$)/', $attrkey)) { - continue; + return $attr[0]; } $attrs[$attrkey] = htmlspecialchars_decode($attr[2]); - $html = str_replace($attr[0], '', $html); - } + return ''; + }, $match[0]); if (strtolower($match[1]) === 'img' && !preg_match('/\ssrc="/', $html)) { $html = substr($html, 0, 4) . ' src=""' . substr($html, 4); } $encoded_properties = base64_encode(json_encode($attrs)); - $html = substr($html, 0, 4) . ' rx_encoded_properties="' . $encoded_properties . '"' . substr($html, 4); - $content = str_replace($match[0], $html, $content); - } - return $content; + return substr($html, 0, 4) . ' rx_encoded_properties="' . $encoded_properties . '"' . substr($html, 4); + }, $content); } /** @@ -512,17 +505,14 @@ class HTMLFilter */ protected static function _decodeWidgetsAndEditorComponents($content) { - preg_match_all('!<(div|img)([^>]*)(rx_encoded_properties="([^"]+)")!i', $content, $matches, \PREG_SET_ORDER); - foreach ($matches as $match) - { + return preg_replace_callback('!<(div|img)([^>]*)(rx_encoded_properties="([^"]+)")!i', function($match) { $attrs = array(); $decoded_properties = @json_decode(base64_decode($match[4])) ?: array(); foreach ($decoded_properties as $key => $val) { $attrs[] = $key . '="' . htmlspecialchars($val) . '"'; } - $content = str_replace($match[3], implode(' ', $attrs), $content); - } - return $content; + return str_replace($match[3], implode(' ', $attrs), $match[0]); + }, $content); } } From 616d8940214a97872a55ba2e451f5a1f2b9ff9d1 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 22:48:05 +0900 Subject: [PATCH 140/318] Clean up deprecated functions in common/legacy.php --- common/legacy.php | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/common/legacy.php b/common/legacy.php index 1830d3a90..29cbd58e9 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -814,15 +814,10 @@ function url_decode($str) return htmlspecialchars(utf8RawUrlDecode($str), null, 'UTF-8'); } -function purifierHtml(&$content) -{ - $content = Rhymix\Framework\Security\HTMLFilter::clean($content); -} - /** - * Pre-block the codes which may be hacking attempts + * Sanitize HTML content. * - * @param string $content Taget content + * @param string $content Target content * @return string */ function removeHackTag($content) @@ -830,6 +825,17 @@ function removeHackTag($content) return Rhymix\Framework\Security\HTMLFilter::clean($content); } +/** + * HTMLPurifier wrapper (Deprecated) + * + * @param string &$content Target content + * @return string + */ +function purifierHtml(&$content) +{ + $content = Rhymix\Framework\Security\HTMLFilter::clean($content); +} + /** * Check xmp tag (Deprecated) * @@ -918,7 +924,7 @@ function getScriptPath() */ function getRequestUriByServerEnviroment() { - return str_replace('<', '<', $_SERVER['REQUEST_URI']); + return escape($_SERVER['REQUEST_URI']); } /** From ef6f0c839f0b3352943577c8c59b257256cf7d2c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 23:17:37 +0900 Subject: [PATCH 141/318] Absorb core functionality of stripEmbedTagForAdmin() into HTMLFilter class --- common/framework/security/htmlfilter.php | 15 +++++++++++++ common/legacy.php | 28 +++++++++++++----------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index cad870bc5..4cee601b0 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -87,6 +87,21 @@ class HTMLFilter return $output; } + /** + * Remove embedded media from HTML content. + * + * @param string $input + * @param string $replacement + * @return string + */ + public static function removeEmbeddedMedia($input, $replacement = '') + { + $input = preg_replace('!]*>(.*?)?!is', $replacement, $input); + $input = preg_replace('!]*>(.*?)?!is', $replacement, $input); + $input = preg_replace('!]*editor_component="multimedia_link"[^>]*>(.*?)?!is', $replacement, $input); + return $input; + } + /** * Get an instance of HTMLPurifier. * diff --git a/common/legacy.php b/common/legacy.php index 29cbd58e9..729166e14 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -1012,29 +1012,31 @@ function isCrawler($agent = NULL) */ function stripEmbedTagForAdmin(&$content, $writer_member_srl) { - if(!Context::get('is_logged')) + 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 ($logged_info->member_srl == $writer_member_srl) { - if($writer_member_srl) + return; + } + + if ($logged_info->is_admin === 'Y' || getModel('module')->isSiteAdmin($logged_info)) + { + if ($writer_member_srl) { - $oMemberModel = getModel('member'); - $member_info = $oMemberModel->getMemberInfoByMemberSrl($writer_member_srl); - if($member_info->is_admin == "Y") + $member_info = getModel('member')->getMemberInfoByMemberSrl($writer_member_srl); + if ($member_info && $member_info->is_admin === 'Y') { return; } } - $security_msg = "

    " . lang('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); + + $security_msg = '
    ' . + '

    ' . lang('security_warning_embed') . '

    '; + $content = Rhymix\Framework\Security\HTMLFilter::removeEmbeddedMedia($content, $security_msg); } return; From 31080ddc046a33fdd79ecdc4365a5b08a3b35537 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 12 Mar 2016 23:24:00 +0900 Subject: [PATCH 142/318] Add unit tests for removeEmbeddedMedia() --- .../framework/security/HTMLFilterTest.php | 141 ++++++++++-------- 1 file changed, 78 insertions(+), 63 deletions(-) diff --git a/tests/unit/framework/security/HTMLFilterTest.php b/tests/unit/framework/security/HTMLFilterTest.php index e29ae9438..f3ab22629 100644 --- a/tests/unit/framework/security/HTMLFilterTest.php +++ b/tests/unit/framework/security/HTMLFilterTest.php @@ -2,67 +2,82 @@ class HTMLFilterTest extends \Codeception\TestCase\Test { - public function testRemoveHackTag() - { - $tests = array( - // remove iframe - array( - '', - '' - ), - // expression - array( - '
    ', - '
    ' - ), - // no quotes and no semicolon - http://ha.ckers.org/xss.html - array( - '', - '' - ), - // embedded encoded tab to break up XSS - http://ha.ckers.org/xss.html - array( - '', - '' - ), - // issue 178 - array( - '', - '' - ), - // issue 534 - array( - '*/" onerror="console.log(\'Yet another XSS\')">', - '*/" onerror="console.log(\'Yet another XSS\')">' - ), - // issue 602 - array( - 'test', - 'test' - ), - // issue #1813 https://github.com/xpressengine/xe-core/issues/1813 - array( - 'dummy', - 'dummy' - ), - array( - 'dummy', - 'dummy' - ), - array( - "\"dummy\"", - 'dummy' - ), - array( - "\"dummy\"", - 'dummy' - ) - ); - - foreach ($tests as $test) - { - $result = removeHackTag($test[0]); - $this->assertEquals($test[1], $result); - } - } + public function testRemoveHackTag() + { + $tests = array( + // remove iframe + array( + '', + '' + ), + // expression + array( + '
    ', + '
    ' + ), + // no quotes and no semicolon - http://ha.ckers.org/xss.html + array( + '', + '' + ), + // embedded encoded tab to break up XSS - http://ha.ckers.org/xss.html + array( + '', + '' + ), + // issue 178 + array( + '', + '' + ), + // issue 534 + array( + '*/" onerror="console.log(\'Yet another XSS\')">', + '*/" onerror="console.log(\'Yet another XSS\')">' + ), + // issue 602 + array( + 'test', + 'test' + ), + // issue #1813 https://github.com/xpressengine/xe-core/issues/1813 + array( + 'dummy', + 'dummy' + ), + array( + 'dummy', + 'dummy' + ), + array( + "\"dummy\"", + 'dummy' + ), + array( + "\"dummy\"", + 'dummy' + ) + ); + + foreach ($tests as $test) + { + $this->assertEquals($test[1], removeHackTag($test[0])); + } + } + + public function testRemoveEmbeddedMedia() + { + $tests = array( + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + ); + + foreach ($tests as $from => $to) + { + $this->assertEquals($to, Rhymix\Framework\Security\HTMLFilter::removeEmbeddedMedia($from)); + } + } } From 3d3fa6d7d3259db59225349ad6be04fd5b845e28 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 00:11:47 +0900 Subject: [PATCH 143/318] Use HTMLFilter::clean() directly in unit tests --- tests/unit/framework/security/HTMLFilterTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/framework/security/HTMLFilterTest.php b/tests/unit/framework/security/HTMLFilterTest.php index f3ab22629..01162dc9c 100644 --- a/tests/unit/framework/security/HTMLFilterTest.php +++ b/tests/unit/framework/security/HTMLFilterTest.php @@ -2,7 +2,7 @@ class HTMLFilterTest extends \Codeception\TestCase\Test { - public function testRemoveHackTag() + public function testHTMLFilterClean() { $tests = array( // remove iframe @@ -61,7 +61,7 @@ class HTMLFilterTest extends \Codeception\TestCase\Test foreach ($tests as $test) { - $this->assertEquals($test[1], removeHackTag($test[0])); + $this->assertEquals($test[1], Rhymix\Framework\Security\HTMLFilter::clean($test[0])); } } From f41e3f590795058e62b8bdfba3aecfd5fc4ee472 Mon Sep 17 00:00:00 2001 From: MinSoo Kim Date: Sun, 13 Mar 2016 00:37:04 +0900 Subject: [PATCH 144/318] input type=color can not be empty https://www.w3.org/TR/2012/WD-html5-20120329/states-of-the-type-attribute.html#color-state-type-color --- common/js/plugins/spectrum/rx_spectrum.js | 1 + modules/document/tpl/category_list.html | 2 +- .../editor/components/image_gallery/tpl/popup.html | 4 ++-- modules/layout/tpl/faceoff_layout_menu.html | 14 +++++++------- modules/layout/tpl/layout_info_view.html | 2 +- modules/module/tpl/skin_config.html | 2 +- .../widget/tpl/widget_generate_code.include.html | 2 +- modules/widget/tpl/widget_layer.html | 10 +++++----- .../tpl/widget_style_generate_code_in_page.html | 2 +- 9 files changed, 20 insertions(+), 19 deletions(-) diff --git a/common/js/plugins/spectrum/rx_spectrum.js b/common/js/plugins/spectrum/rx_spectrum.js index 39e788732..8aed57387 100644 --- a/common/js/plugins/spectrum/rx_spectrum.js +++ b/common/js/plugins/spectrum/rx_spectrum.js @@ -12,6 +12,7 @@ jQuery(function($){ $.getScript(request_uri + "./common/js/plugins/spectrum/i18n/jquery.spectrum-"+ xe.current_lang.replace("jp", "ja").toLowerCase() +".js", function() { var settings = { showInput: true, + allowEmpty:true, showInitial: true, showPalette: true, showSelectionPalette: true, diff --git a/modules/document/tpl/category_list.html b/modules/document/tpl/category_list.html index e9f03e0ad..f1f998537 100644 --- a/modules/document/tpl/category_list.html +++ b/modules/document/tpl/category_list.html @@ -61,7 +61,7 @@
    - + {$lang->help}
    diff --git a/modules/editor/components/image_gallery/tpl/popup.html b/modules/editor/components/image_gallery/tpl/popup.html index d8cd62292..3e0b93d5a 100644 --- a/modules/editor/components/image_gallery/tpl/popup.html +++ b/modules/editor/components/image_gallery/tpl/popup.html @@ -40,13 +40,13 @@
    - +
    - +
    diff --git a/modules/layout/tpl/faceoff_layout_menu.html b/modules/layout/tpl/faceoff_layout_menu.html index 13bc6d802..a2dc156d9 100644 --- a/modules/layout/tpl/faceoff_layout_menu.html +++ b/modules/layout/tpl/faceoff_layout_menu.html @@ -218,7 +218,7 @@ {$lang->layout_manager[38]} - + - + - + - + - + +
    @@ -335,7 +335,7 @@
    - +
    diff --git a/modules/layout/tpl/layout_info_view.html b/modules/layout/tpl/layout_info_view.html index 780111419..98b48ef9b 100644 --- a/modules/layout/tpl/layout_info_view.html +++ b/modules/layout/tpl/layout_info_view.html @@ -129,7 +129,7 @@ {@ $use_colorpicker = true; } - +

    {$var->description}

    diff --git a/modules/module/tpl/skin_config.html b/modules/module/tpl/skin_config.html index a2de640b0..d92bb669d 100644 --- a/modules/module/tpl/skin_config.html +++ b/modules/module/tpl/skin_config.html @@ -117,7 +117,7 @@
    {@ $use_colorpicker = true; } - +
    {$lang->help} diff --git a/modules/widget/tpl/widget_generate_code.include.html b/modules/widget/tpl/widget_generate_code.include.html index 8d931af62..cf0d13589 100644 --- a/modules/widget/tpl/widget_generate_code.include.html +++ b/modules/widget/tpl/widget_generate_code.include.html @@ -49,7 +49,7 @@ - + diff --git a/modules/widget/tpl/widget_layer.html b/modules/widget/tpl/widget_layer.html index 6f1a2c911..584a0ebf3 100644 --- a/modules/widget/tpl/widget_layer.html +++ b/modules/widget/tpl/widget_layer.html @@ -62,7 +62,7 @@ - + @@ -72,7 +72,7 @@ - + px @@ -80,7 +80,7 @@ - + @@ -90,12 +90,12 @@ - + {$lang->cmd_widget_background_color} - + {$lang->cmd_widget_background_image_url} diff --git a/modules/widget/tpl/widget_style_generate_code_in_page.html b/modules/widget/tpl/widget_style_generate_code_in_page.html index 25c6b0f01..b7127a8e0 100644 --- a/modules/widget/tpl/widget_style_generate_code_in_page.html +++ b/modules/widget/tpl/widget_style_generate_code_in_page.html @@ -70,7 +70,7 @@
    - +
    From 7ecd9230c297877e1fcb28c2f8f6014312856c08 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 09:51:15 +0900 Subject: [PATCH 145/318] Add MediaFilter class to absorb most EmbedFilter functionality --- classes/security/EmbedFilter.class.php | 210 +-- common/defaults/whitelist.php | 1648 ----------------- common/framework/security/htmlfilter.php | 51 +- common/framework/security/mediafilter.php | 180 ++ common/legacy.php | 2 +- .../framework/security/HTMLFilterTest.php | 16 - .../framework/security/MediaFilterTest.php | 47 + 7 files changed, 266 insertions(+), 1888 deletions(-) create mode 100644 common/framework/security/mediafilter.php create mode 100644 tests/unit/framework/security/MediaFilterTest.php diff --git a/classes/security/EmbedFilter.class.php b/classes/security/EmbedFilter.class.php index 382bf0fe0..d6e9e5f01 100644 --- a/classes/security/EmbedFilter.class.php +++ b/classes/security/EmbedFilter.class.php @@ -4,216 +4,78 @@ class EmbedFilter { /** - * allow script access list + * Deprecated properties * @var array */ - var $allowscriptaccessList = array(); - var $whiteUrlList = array(); - var $whiteIframeUrlList = array(); - var $mimeTypeList = array(); - var $extList = array(); - var $parser = NULL; - - /** - * @constructor - * @return void - */ - function __construct() - { - $this->_makeWhiteDomainList(); - } + public $whiteUrlList = array(); + public $whiteIframeUrlList = array(); + public $mimeTypeList = array(); + public $extList = array(); /** * Return EmbedFilter object - * This method for singleton + * * @return EmbedFilter */ function getInstance() { - if(!isset($GLOBALS['__EMBEDFILTER_INSTANCE__'])) - { - $GLOBALS['__EMBEDFILTER_INSTANCE__'] = new EmbedFilter(); - } - return $GLOBALS['__EMBEDFILTER_INSTANCE__']; + return new self(); } - + public function getWhiteUrlList() { - return $this->whiteUrlList; + return Rhymix\Framework\Security\MediaFilter::getObjectWhitelist(); } - + public function getWhiteIframeUrlList() { - return $this->whiteIframeUrlList; + return Rhymix\Framework\Security\MediaFilter::getIframeWhitelist(); } - - /** - * Check the content. - * @return void - */ + + function isWhiteDomain($urlAttribute) + { + return Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist($urlAttribute); + } + + function isWhiteIframeDomain($urlAttribute) + { + return Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist($urlAttribute); + } + + function isWhiteMimetype($mimeType) + { + return true; + } + + function isWhiteExt($ext) + { + return true; + } + function check(&$content) { // This functionality has been moved to the HTMLFilter class. } - - /** - * Check iframe tag in the content. - * @return void - */ + function checkIframeTag(&$content) { // This functionality has been moved to the HTMLFilter class. } - - /** - * Check object tag in the content. - * @return void - */ + function checkObjectTag(&$content) { // This functionality has been moved to the HTMLFilter class. } - - /** - * Check embed tag in the content. - * @return void - */ + function checkEmbedTag(&$content) { // This functionality has been moved to the HTMLFilter class. } - - /** - * Check param tag in the content. - * @return void - */ + function checkParamTag(&$content) { // This functionality has been moved to the HTMLFilter class. } - - /** - * Check white domain in object data attribute or embed src attribute. - * @return string - */ - function isWhiteDomain($urlAttribute) - { - if(is_array($this->whiteUrlList)) - { - foreach($this->whiteUrlList AS $key => $value) - { - if(preg_match('@^https?://' . preg_quote($value, '@') . '@i', $urlAttribute)) - { - return TRUE; - } - } - } - return FALSE; - } - - /** - * Check white domain in iframe src attribute. - * @return string - */ - function isWhiteIframeDomain($urlAttribute) - { - if(is_array($this->whiteIframeUrlList)) - { - foreach($this->whiteIframeUrlList AS $key => $value) - { - if(preg_match('@^https?://' . preg_quote($value, '@') . '@i', $urlAttribute)) - { - return TRUE; - } - } - } - return FALSE; - } - - /** - * Check white mime type in object type attribute or embed type attribute. - * @return string - */ - function isWhiteMimetype($mimeType) - { - if(isset($this->mimeTypeList[$mimeType])) - { - return TRUE; - } - return FALSE; - } - - function isWhiteExt($ext) - { - if(isset($this->extList[$ext])) - { - return TRUE; - } - return FALSE; - } - - /** - * Make white domain list cache file from xml config file. - * @param $whitelist array - * @return void - */ - function _makeWhiteDomainList($whitelist = NULL) - { - $whiteUrlDefaultList = (include RX_BASEDIR . 'common/defaults/whitelist.php'); - $this->extList = $whiteUrlDefaultList['extensions']; - $this->mimeTypeList = $whiteUrlDefaultList['mime']; - $this->whiteUrlList = array(); - $this->whiteIframeUrlList = array(); - - if($whitelist !== NULL) - { - if(!is_array($whitelist) || !isset($whitelist['object']) || !isset($whitelist['iframe'])) - { - $whitelist = array( - 'object' => isset($whitelist->object) ? $whitelist->object : array(), - 'iframe' => isset($whitelist->iframe) ? $whitelist->iframe : array(), - ); - } - foreach ($whitelist['object'] as $prefix) - { - $this->whiteUrlList[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; - } - foreach ($whitelist['iframe'] as $prefix) - { - $this->whiteIframeUrlList[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; - } - } - else - { - foreach ($whiteUrlDefaultList['object'] as $prefix) - { - $this->whiteUrlList[] = $prefix; - } - foreach ($whiteUrlDefaultList['iframe'] as $prefix) - { - $this->whiteIframeUrlList[] = $prefix; - } - if ($embedfilter_object = config('embedfilter.object')) - { - foreach ($embedfilter_object as $prefix) - { - $this->whiteUrlList[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; - } - } - if ($embedfilter_iframe = config('embedfilter.iframe')) - { - foreach ($embedfilter_iframe as $prefix) - { - $this->whiteIframeUrlList[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; - } - } - } - - $this->whiteUrlList = array_unique($this->whiteUrlList); - $this->whiteIframeUrlList = array_unique($this->whiteIframeUrlList); - natcasesort($this->whiteUrlList); - natcasesort($this->whiteIframeUrlList); - } } /* End of file : EmbedFilter.class.php */ /* Location: ./classes/security/EmbedFilter.class.php */ diff --git a/common/defaults/whitelist.php b/common/defaults/whitelist.php index 272da733b..7fb02f008 100644 --- a/common/defaults/whitelist.php +++ b/common/defaults/whitelist.php @@ -77,1652 +77,4 @@ return array( // Afreeca 'afree.ca/', ), - - /** - * Allowed extensions in or tag - */ - 'extensions' => array( - '123' => 1, - '3ds' => 1, - '3g2' => 1, - '3gp' => 1, - '7z' => 1, - 'aab' => 1, - 'aac' => 1, - 'aam' => 1, - 'aas' => 1, - 'abw' => 1, - 'ac' => 1, - 'acc' => 1, - 'ace' => 1, - 'acu' => 1, - 'acutc' => 1, - 'adp' => 1, - 'aep' => 1, - 'afm' => 1, - 'afp' => 1, - 'ahead' => 1, - 'ai' => 1, - 'aif' => 1, - 'aifc' => 1, - 'aiff' => 1, - 'air' => 1, - 'ait' => 1, - 'ami' => 1, - 'apk' => 1, - 'application' => 1, - 'apr' => 1, - 'arc' => 1, - 'asc' => 1, - 'asf' => 1, - 'aso' => 1, - 'asx' => 1, - 'atc' => 1, - 'atom' => 1, - 'atomcat' => 1, - 'atomsvc' => 1, - 'atx' => 1, - 'au' => 1, - 'avi' => 1, - 'aw' => 1, - 'azf' => 1, - 'azs' => 1, - 'azw' => 1, - 'bat' => 1, - 'bcpio' => 1, - 'bdf' => 1, - 'bdm' => 1, - 'bed' => 1, - 'bh2' => 1, - 'bin' => 1, - 'blb' => 1, - 'blorb' => 1, - 'bmi' => 1, - 'bmp' => 1, - 'book' => 1, - 'box' => 1, - 'boz' => 1, - 'bpk' => 1, - 'btif' => 1, - 'bz' => 1, - 'bz2' => 1, - 'c11amc' => 1, - 'c11amz' => 1, - 'c4d' => 1, - 'c4f' => 1, - 'c4g' => 1, - 'c4p' => 1, - 'c4u' => 1, - 'cab' => 1, - 'caf' => 1, - 'cap' => 1, - 'car' => 1, - 'cat' => 1, - 'cb7' => 1, - 'cba' => 1, - 'cbr' => 1, - 'cbt' => 1, - 'cbz' => 1, - 'cct' => 1, - 'ccxml' => 1, - 'cdbcmsg' => 1, - 'cdf' => 1, - 'cdkey' => 1, - 'cdmia' => 1, - 'cdmic' => 1, - 'cdmid' => 1, - 'cdmio' => 1, - 'cdmiq' => 1, - 'cdx' => 1, - 'cdxml' => 1, - 'cdy' => 1, - 'cer' => 1, - 'cfs' => 1, - 'cgm' => 1, - 'chat' => 1, - 'chm' => 1, - 'chrt' => 1, - 'cif' => 1, - 'cii' => 1, - 'cil' => 1, - 'cla' => 1, - 'class' => 1, - 'clkk' => 1, - 'clkp' => 1, - 'clkt' => 1, - 'clkw' => 1, - 'clkx' => 1, - 'clp' => 1, - 'cmc' => 1, - 'cmdf' => 1, - 'cml' => 1, - 'cmp' => 1, - 'cmx' => 1, - 'cod' => 1, - 'com' => 1, - 'cpio' => 1, - 'cpt' => 1, - 'crd' => 1, - 'crl' => 1, - 'crt' => 1, - 'cryptonote' => 1, - 'csh' => 1, - 'csml' => 1, - 'csp' => 1, - 'cst' => 1, - 'cu' => 1, - 'cww' => 1, - 'cxt' => 1, - 'dae' => 1, - 'daf' => 1, - 'dart' => 1, - 'dataless' => 1, - 'davmount' => 1, - 'dbk' => 1, - 'dcr' => 1, - 'dd2' => 1, - 'ddd' => 1, - 'deb' => 1, - 'deploy' => 1, - 'der' => 1, - 'dfac' => 1, - 'dgc' => 1, - 'dir' => 1, - 'dis' => 1, - 'dist' => 1, - 'distz' => 1, - 'djv' => 1, - 'djvu' => 1, - 'dll' => 1, - 'dmg' => 1, - 'dmp' => 1, - 'dms' => 1, - 'dna' => 1, - 'doc dot' => 1, - 'docm' => 1, - 'docx' => 1, - 'dotm' => 1, - 'dotx' => 1, - 'dp' => 1, - 'dpg' => 1, - 'dra' => 1, - 'dssc' => 1, - 'dtb' => 1, - 'dtd' => 1, - 'dts' => 1, - 'dtshd' => 1, - 'dump' => 1, - 'dvb' => 1, - 'dvi' => 1, - 'dwf' => 1, - 'dwg' => 1, - 'dxf' => 1, - 'dxp' => 1, - 'dxr' => 1, - 'ecelp4800' => 1, - 'ecelp7470' => 1, - 'ecelp9600' => 1, - 'ecma' => 1, - 'edm' => 1, - 'edx' => 1, - 'efif' => 1, - 'ei6' => 1, - 'elc' => 1, - 'emf' => 1, - 'eml' => 1, - 'emma' => 1, - 'emz' => 1, - 'eol' => 1, - 'eot' => 1, - 'eps' => 1, - 'epub' => 1, - 'es3' => 1, - 'esa' => 1, - 'esf' => 1, - 'et3' => 1, - 'eva' => 1, - 'evy' => 1, - 'exe' => 1, - 'exi' => 1, - 'ext' => 1, - 'ez' => 1, - 'ez2' => 1, - 'ez3' => 1, - 'f4v' => 1, - 'fbs' => 1, - 'fcdt' => 1, - 'fcs' => 1, - 'fdf' => 1, - 'fe_launch' => 1, - 'fg5' => 1, - 'fgd' => 1, - 'fh' => 1, - 'fh4' => 1, - 'fh5' => 1, - 'fh7' => 1, - 'fhc' => 1, - 'fig' => 1, - 'flac' => 1, - 'fli' => 1, - 'flo' => 1, - 'flv' => 1, - 'flw' => 1, - 'fm' => 1, - 'fnc' => 1, - 'fpx' => 1, - 'frame' => 1, - 'fsc' => 1, - 'fst' => 1, - 'ftc' => 1, - 'fti' => 1, - 'fvt' => 1, - 'fxp' => 1, - 'fxpl' => 1, - 'fzs' => 1, - 'g2w' => 1, - 'g3' => 1, - 'g3w' => 1, - 'gac' => 1, - 'gam' => 1, - 'gbr' => 1, - 'gca' => 1, - 'gdl' => 1, - 'geo' => 1, - 'gex' => 1, - 'ggb' => 1, - 'ggt' => 1, - 'ghf' => 1, - 'gif' => 1, - 'gim' => 1, - 'gml' => 1, - 'gmx' => 1, - 'gnumeric' => 1, - 'gph' => 1, - 'gpx' => 1, - 'gqf' => 1, - 'gqs' => 1, - 'gram' => 1, - 'gramps' => 1, - 'gre' => 1, - 'grv' => 1, - 'grxml' => 1, - 'gsf' => 1, - 'gtar' => 1, - 'gtm' => 1, - 'gtw' => 1, - 'gxf' => 1, - 'gxt' => 1, - 'h261' => 1, - 'h263' => 1, - 'h264' => 1, - 'hal' => 1, - 'hbci' => 1, - 'hdf' => 1, - 'hlp' => 1, - 'hpgl' => 1, - 'hpid' => 1, - 'hps' => 1, - 'hqx' => 1, - 'htke' => 1, - 'hvd' => 1, - 'hvp' => 1, - 'hvs' => 1, - 'i2g' => 1, - 'icc' => 1, - 'ice' => 1, - 'icm' => 1, - 'ico' => 1, - 'ief' => 1, - 'ifm' => 1, - 'iges' => 1, - 'igl' => 1, - 'igm' => 1, - 'igs' => 1, - 'igx' => 1, - 'iif' => 1, - 'imp' => 1, - 'ims' => 1, - 'ink' => 1, - 'inkml' => 1, - 'install' => 1, - 'iota' => 1, - 'ipfix' => 1, - 'ipk' => 1, - 'irm' => 1, - 'irp' => 1, - 'iso' => 1, - 'itp' => 1, - 'ivp' => 1, - 'ivu' => 1, - 'jam' => 1, - 'jar' => 1, - 'jisp' => 1, - 'jlt' => 1, - 'jnlp' => 1, - 'joda' => 1, - 'jpe' => 1, - 'jpeg' => 1, - 'jpg' => 1, - 'jpgm' => 1, - 'jpgv' => 1, - 'jpm' => 1, - 'js' => 1, - 'json' => 1, - 'jsonml' => 1, - 'kar' => 1, - 'karbon' => 1, - 'kfo' => 1, - 'kia' => 1, - 'kml' => 1, - 'kmz' => 1, - 'kne' => 1, - 'knp' => 1, - 'kon' => 1, - 'kpr' => 1, - 'kpt' => 1, - 'kpxx' => 1, - 'ksp' => 1, - 'ktr' => 1, - 'ktx' => 1, - 'ktz' => 1, - 'kwd' => 1, - 'kwt' => 1, - 'lasxml' => 1, - 'latex' => 1, - 'lbd' => 1, - 'lbe' => 1, - 'les' => 1, - 'lha' => 1, - 'link66' => 1, - 'list3820' => 1, - 'listafp' => 1, - 'lnk' => 1, - 'lostxml' => 1, - 'lrf' => 1, - 'lrm' => 1, - 'ltf' => 1, - 'lvp' => 1, - 'lwp' => 1, - 'lzh' => 1, - 'm13' => 1, - 'm14' => 1, - 'm1v' => 1, - 'm21 mp21' => 1, - 'm2a' => 1, - 'm2v' => 1, - 'm3a' => 1, - 'm3u' => 1, - 'm3u8' => 1, - 'm4u' => 1, - 'm4v' => 1, - 'ma' => 1, - 'mads' => 1, - 'mag' => 1, - 'maker' => 1, - 'mar' => 1, - 'mathml' => 1, - 'mb' => 1, - 'mbk' => 1, - 'mbox' => 1, - 'mc1' => 1, - 'mcd' => 1, - 'mdb' => 1, - 'mdi' => 1, - 'mesh' => 1, - 'meta4' => 1, - 'metalink' => 1, - 'mets' => 1, - 'mfm' => 1, - 'mft' => 1, - 'mgp' => 1, - 'mgz' => 1, - 'mid' => 1, - 'midi' => 1, - 'mie' => 1, - 'mif' => 1, - 'mime' => 1, - 'mj2' => 1, - 'mjp2' => 1, - 'mk3d' => 1, - 'mka' => 1, - 'mks' => 1, - 'mkv' => 1, - 'mlp' => 1, - 'mmd' => 1, - 'mmf' => 1, - 'mmr' => 1, - 'mng' => 1, - 'mny' => 1, - 'mobi' => 1, - 'mods' => 1, - 'mov' => 1, - 'movie' => 1, - 'mp2' => 1, - 'mp2a' => 1, - 'mp3' => 1, - 'mp4' => 1, - 'mp4a' => 1, - 'mp4s' => 1, - 'mp4v' => 1, - 'mpc' => 1, - 'mpe' => 1, - 'mpeg' => 1, - 'mpg' => 1, - 'mpg4' => 1, - 'mpga' => 1, - 'mpkg' => 1, - 'mpm' => 1, - 'mpn' => 1, - 'mpp' => 1, - 'mpt' => 1, - 'mpy' => 1, - 'mqy' => 1, - 'mrc' => 1, - 'mrcx' => 1, - 'mscml' => 1, - 'mseed' => 1, - 'mseq' => 1, - 'msf' => 1, - 'msh' => 1, - 'msi' => 1, - 'msl' => 1, - 'msty' => 1, - 'mts' => 1, - 'mus' => 1, - 'musicxml' => 1, - 'mvb' => 1, - 'mwf' => 1, - 'mxf' => 1, - 'mxl' => 1, - 'mxml' => 1, - 'mxs' => 1, - 'mxu' => 1, - 'n-gage' => 1, - 'nb' => 1, - 'nbp' => 1, - 'nc' => 1, - 'ncx' => 1, - 'ngdat' => 1, - 'nitf' => 1, - 'nlu' => 1, - 'nml' => 1, - 'nnd' => 1, - 'nns' => 1, - 'nnw' => 1, - 'npx' => 1, - 'nsc' => 1, - 'nsf' => 1, - 'nzb' => 1, - 'oa2' => 1, - 'oa3' => 1, - 'oas' => 1, - 'obd' => 1, - 'obj' => 1, - 'oda' => 1, - 'odb' => 1, - 'odc' => 1, - 'odf' => 1, - 'odft' => 1, - 'odg' => 1, - 'odi' => 1, - 'odm' => 1, - 'odp' => 1, - 'ods' => 1, - 'odt' => 1, - 'oga' => 1, - 'ogg' => 1, - 'ogv' => 1, - 'ogx' => 1, - 'omdoc' => 1, - 'onepkg' => 1, - 'onetmp' => 1, - 'onetoc' => 1, - 'onetoc2' => 1, - 'opf' => 1, - 'oprc' => 1, - 'org' => 1, - 'osf' => 1, - 'osfpvg' => 1, - 'otc' => 1, - 'otf' => 1, - 'otg' => 1, - 'oth' => 1, - 'oti' => 1, - 'otp' => 1, - 'ots' => 1, - 'ott' => 1, - 'oxps' => 1, - 'oxt' => 1, - 'p10' => 1, - 'p12' => 1, - 'p7b' => 1, - 'p7c' => 1, - 'p7m' => 1, - 'p7r' => 1, - 'p7s' => 1, - 'p8' => 1, - 'paw' => 1, - 'pbd' => 1, - 'pbm' => 1, - 'pcap' => 1, - 'pcf' => 1, - 'pcl' => 1, - 'pclxl' => 1, - 'pct' => 1, - 'pcurl' => 1, - 'pcx' => 1, - 'pdb' => 1, - 'pdf' => 1, - 'pfa' => 1, - 'pfb' => 1, - 'pfm' => 1, - 'pfr' => 1, - 'pfx' => 1, - 'pgm' => 1, - 'pgn' => 1, - 'pgp' => 1, - 'pic' => 1, - 'pkg' => 1, - 'pki' => 1, - 'pkipath' => 1, - 'plb' => 1, - 'plc' => 1, - 'plf' => 1, - 'pls' => 1, - 'pml' => 1, - 'png' => 1, - 'pnm' => 1, - 'portpkg' => 1, - 'pot' => 1, - 'potm' => 1, - 'potx' => 1, - 'ppam' => 1, - 'ppd' => 1, - 'ppm' => 1, - 'pps' => 1, - 'ppsm' => 1, - 'ppsx' => 1, - 'ppt' => 1, - 'pptm' => 1, - 'pptx' => 1, - 'pqa' => 1, - 'prc' => 1, - 'pre' => 1, - 'prf' => 1, - 'ps' => 1, - 'psb' => 1, - 'psd' => 1, - 'psf' => 1, - 'pskcxml' => 1, - 'ptid' => 1, - 'pub' => 1, - 'pvb' => 1, - 'pwn' => 1, - 'pya' => 1, - 'pyv' => 1, - 'qam' => 1, - 'qbo' => 1, - 'qfx' => 1, - 'qps' => 1, - 'qt' => 1, - 'qwd' => 1, - 'qwt' => 1, - 'qxb' => 1, - 'qxd' => 1, - 'qxl' => 1, - 'qxt' => 1, - 'ra' => 1, - 'ram' => 1, - 'rar' => 1, - 'ras' => 1, - 'rcprofile' => 1, - 'rdf' => 1, - 'rdz' => 1, - 'rep' => 1, - 'res' => 1, - 'rgb' => 1, - 'rif' => 1, - 'rip' => 1, - 'ris' => 1, - 'rl' => 1, - 'rlc' => 1, - 'rld' => 1, - 'rm' => 1, - 'rmi' => 1, - 'rmp' => 1, - 'rms' => 1, - 'rmvb' => 1, - 'rnc' => 1, - 'roa' => 1, - 'rp9' => 1, - 'rpss' => 1, - 'rpst' => 1, - 'rq' => 1, - 'rs' => 1, - 'rsd' => 1, - 'rss' => 1, - 'rtf' => 1, - 's3m' => 1, - 'saf' => 1, - 'sbml' => 1, - 'sc' => 1, - 'scd' => 1, - 'scm' => 1, - 'scq' => 1, - 'scs' => 1, - 'sda' => 1, - 'sdc' => 1, - 'sdd' => 1, - 'sdkd' => 1, - 'sdkm' => 1, - 'sdp' => 1, - 'sdw' => 1, - 'see' => 1, - 'seed' => 1, - 'sema' => 1, - 'semd' => 1, - 'semf' => 1, - 'ser' => 1, - 'setpay' => 1, - 'setreg' => 1, - 'sfd-hdstx' => 1, - 'sfs' => 1, - 'sgi' => 1, - 'sgl' => 1, - 'sh' => 1, - 'shar' => 1, - 'shf' => 1, - 'sid' => 1, - 'sig' => 1, - 'sil' => 1, - 'silo' => 1, - 'sis' => 1, - 'sisx' => 1, - 'sit' => 1, - 'sitx' => 1, - 'skd' => 1, - 'skm' => 1, - 'skp' => 1, - 'skt' => 1, - 'sldm' => 1, - 'sldx' => 1, - 'slt' => 1, - 'sm' => 1, - 'smf' => 1, - 'smi' => 1, - 'smil' => 1, - 'smv' => 1, - 'smzip' => 1, - 'snd' => 1, - 'snf' => 1, - 'so' => 1, - 'spc' => 1, - 'spf' => 1, - 'spl' => 1, - 'spp' => 1, - 'spq' => 1, - 'spx' => 1, - 'sql' => 1, - 'src' => 1, - 'srt' => 1, - 'sru' => 1, - 'srx' => 1, - 'ssdl' => 1, - 'sse' => 1, - 'ssf' => 1, - 'ssml' => 1, - 'st' => 1, - 'stc' => 1, - 'std' => 1, - 'stf' => 1, - 'sti' => 1, - 'stk' => 1, - 'stl' => 1, - 'str' => 1, - 'stw' => 1, - 'sub' => 1, - 'sus' => 1, - 'susp' => 1, - 'sv4cpio' => 1, - 'sv4crc' => 1, - 'svc' => 1, - 'svd' => 1, - 'svg' => 1, - 'svgz' => 1, - 'swa' => 1, - 'swf' => 1, - 'swi' => 1, - 'sxc' => 1, - 'sxd' => 1, - 'sxg' => 1, - 'sxi' => 1, - 'sxm' => 1, - 'sxw' => 1, - 't3' => 1, - 'taglet' => 1, - 'tao' => 1, - 'tar' => 1, - 'tcap' => 1, - 'tcl' => 1, - 'teacher' => 1, - 'tei' => 1, - 'teicorpus' => 1, - 'tex' => 1, - 'texi' => 1, - 'texinfo' => 1, - 'tfi' => 1, - 'tfm' => 1, - 'tga' => 1, - 'thmx' => 1, - 'tif' => 1, - 'tiff' => 1, - 'tmo' => 1, - 'torrent' => 1, - 'tpl' => 1, - 'tpt' => 1, - 'tra' => 1, - 'trm' => 1, - 'tsd' => 1, - 'ttc' => 1, - 'ttf' => 1, - 'twd' => 1, - 'twds' => 1, - 'txd' => 1, - 'txf' => 1, - 'u32' => 1, - 'udeb' => 1, - 'ufd' => 1, - 'ufdl' => 1, - 'ulx' => 1, - 'umj' => 1, - 'unityweb' => 1, - 'uoml' => 1, - 'ustar' => 1, - 'utz' => 1, - 'uva' => 1, - 'uvd' => 1, - 'uvf' => 1, - 'uvg' => 1, - 'uvh' => 1, - 'uvi' => 1, - 'uvm' => 1, - 'uvp' => 1, - 'uvs' => 1, - 'uvt' => 1, - 'uvu' => 1, - 'uvv' => 1, - 'uvva' => 1, - 'uvvd' => 1, - 'uvvf' => 1, - 'uvvg' => 1, - 'uvvh' => 1, - 'uvvi' => 1, - 'uvvm' => 1, - 'uvvp' => 1, - 'uvvs' => 1, - 'uvvt' => 1, - 'uvvu' => 1, - 'uvvv' => 1, - 'uvvx' => 1, - 'uvvz' => 1, - 'uvx' => 1, - 'uvz' => 1, - 'vcd' => 1, - 'vcg' => 1, - 'vcx' => 1, - 'vis' => 1, - 'viv' => 1, - 'vob' => 1, - 'vor' => 1, - 'vox' => 1, - 'vrml' => 1, - 'vsd' => 1, - 'vsf' => 1, - 'vss' => 1, - 'vst' => 1, - 'vsw' => 1, - 'vtu' => 1, - 'vxml' => 1, - 'w3d' => 1, - 'wad' => 1, - 'wav' => 1, - 'wax' => 1, - 'wbmp' => 1, - 'wbs' => 1, - 'wbxml' => 1, - 'wcm' => 1, - 'wdb' => 1, - 'wdp' => 1, - 'weba' => 1, - 'webm' => 1, - 'webp' => 1, - 'wg' => 1, - 'wgt' => 1, - 'wks' => 1, - 'wm' => 1, - 'wma' => 1, - 'wmd' => 1, - 'wmf' => 1, - 'wmlc' => 1, - 'wmlsc' => 1, - 'wmv' => 1, - 'wmx' => 1, - 'wmz' => 1, - 'woff' => 1, - 'wpd' => 1, - 'wpl' => 1, - 'wps' => 1, - 'wqd' => 1, - 'wri' => 1, - 'wrl' => 1, - 'wsdl' => 1, - 'wspolicy' => 1, - 'wtb' => 1, - 'wvx' => 1, - 'x32' => 1, - 'x3d' => 1, - 'x3db' => 1, - 'x3dbz' => 1, - 'x3dv' => 1, - 'x3dvz' => 1, - 'x3dz' => 1, - 'xaml' => 1, - 'xap' => 1, - 'xar' => 1, - 'xbap' => 1, - 'xbd' => 1, - 'xbm' => 1, - 'xdf' => 1, - 'xdm' => 1, - 'xdp' => 1, - 'xdssc' => 1, - 'xdw' => 1, - 'xenc' => 1, - 'xer' => 1, - 'xfdf' => 1, - 'xfdl' => 1, - 'xht' => 1, - 'xhtml' => 1, - 'xhvml' => 1, - 'xif' => 1, - 'xla' => 1, - 'xlam' => 1, - 'xlc' => 1, - 'xlf' => 1, - 'xlm' => 1, - 'xls' => 1, - 'xlsb' => 1, - 'xlsm' => 1, - 'xlsx' => 1, - 'xlt' => 1, - 'xltm' => 1, - 'xltx' => 1, - 'xlw' => 1, - 'xm' => 1, - 'xml' => 1, - 'xo' => 1, - 'xop' => 1, - 'xpi' => 1, - 'xpl' => 1, - 'xpm' => 1, - 'xpr' => 1, - 'xps' => 1, - 'xpw' => 1, - 'xpx' => 1, - 'xsl' => 1, - 'xslt' => 1, - 'xsm' => 1, - 'xspf' => 1, - 'xul' => 1, - 'xvm' => 1, - 'xvml' => 1, - 'xwd' => 1, - 'xyz' => 1, - 'xz' => 1, - 'yang' => 1, - 'yin' => 1, - 'z1' => 1, - 'z2' => 1, - 'z3' => 1, - 'z4' => 1, - 'z5' => 1, - 'z6' => 1, - 'z7' => 1, - 'z8' => 1, - 'zaz' => 1, - 'zip' => 1, - 'zir' => 1, - 'zirz' => 1, - 'zmm' => 1, - ), - - // Allowed MIME types - 'mime' => array( - 'application/andrew-inset' => 1, - 'application/applixware' => 1, - 'application/atom+xml' => 1, - 'application/atomcat+xml' => 1, - 'application/atomsvc+xml' => 1, - 'application/ccxml+xml' => 1, - 'application/cdmi-capability' => 1, - 'application/cdmi-container' => 1, - 'application/cdmi-domain' => 1, - 'application/cdmi-object' => 1, - 'application/cdmi-queue' => 1, - 'application/cu-seeme' => 1, - 'application/davmount+xml' => 1, - 'application/docbook+xml' => 1, - 'application/dssc+der' => 1, - 'application/dssc+xml' => 1, - 'application/ecmascript' => 1, - 'application/emma+xml' => 1, - 'application/epub+zip' => 1, - 'application/exi' => 1, - 'application/font-tdpfr' => 1, - 'application/gml+xml' => 1, - 'application/gpx+xml' => 1, - 'application/gxf' => 1, - 'application/hyperstudio' => 1, - 'application/inkml+xml' => 1, - 'application/ipfix' => 1, - 'application/java-archive' => 1, - 'application/java-serialized-object' => 1, - 'application/java-vm' => 1, - 'application/javascript' => 1, - 'application/json' => 1, - 'application/jsonml+json' => 1, - 'application/lost+xml' => 1, - 'application/mac-binhex40' => 1, - 'application/mac-compactpro' => 1, - 'application/mads+xml' => 1, - 'application/marc' => 1, - 'application/marcxml+xml' => 1, - 'application/mathematica' => 1, - 'application/mathml+xml' => 1, - 'application/mbox' => 1, - 'application/mediaservercontrol+xml' => 1, - 'application/metalink+xml' => 1, - 'application/metalink4+xml' => 1, - 'application/mets+xml' => 1, - 'application/mods+xml' => 1, - 'application/mp21' => 1, - 'application/mp4' => 1, - 'application/msword' => 1, - 'application/mxf' => 1, - 'application/octet-stream' => 1, - 'application/oda' => 1, - 'application/oebps-package+xml' => 1, - 'application/ogg' => 1, - 'application/omdoc+xml' => 1, - 'application/onenote' => 1, - 'application/oxps' => 1, - 'application/patch-ops-error+xml' => 1, - 'application/pdf' => 1, - 'application/pgp-encrypted' => 1, - 'application/pgp-signature' => 1, - 'application/pics-rules' => 1, - 'application/pkcs10' => 1, - 'application/pkcs7-mime' => 1, - 'application/pkcs7-signature' => 1, - 'application/pkcs8' => 1, - 'application/pkix-attr-cert' => 1, - 'application/pkix-cert' => 1, - 'application/pkix-crl' => 1, - 'application/pkix-pkipath' => 1, - 'application/pkixcmp' => 1, - 'application/pls+xml' => 1, - 'application/postscript' => 1, - 'application/prs.cww' => 1, - 'application/pskc+xml' => 1, - 'application/rdf+xml' => 1, - 'application/reginfo+xml' => 1, - 'application/relax-ng-compact-syntax' => 1, - 'application/resource-lists+xml' => 1, - 'application/resource-lists-diff+xml' => 1, - 'application/rls-services+xml' => 1, - 'application/rpki-ghostbusters' => 1, - 'application/rpki-manifest' => 1, - 'application/rpki-roa' => 1, - 'application/rsd+xml' => 1, - 'application/rss+xml' => 1, - 'application/rtf' => 1, - 'application/sbml+xml' => 1, - 'application/scvp-cv-request' => 1, - 'application/scvp-cv-response' => 1, - 'application/scvp-vp-request' => 1, - 'application/scvp-vp-response' => 1, - 'application/sdp' => 1, - 'application/set-payment-initiation' => 1, - 'application/set-registration-initiation' => 1, - 'application/shf+xml' => 1, - 'application/smil+xml' => 1, - 'application/sparql-query' => 1, - 'application/sparql-results+xml' => 1, - 'application/srgs' => 1, - 'application/srgs+xml' => 1, - 'application/sru+xml' => 1, - 'application/ssdl+xml' => 1, - 'application/ssml+xml' => 1, - 'application/tei+xml' => 1, - 'application/thraud+xml' => 1, - 'application/timestamped-data' => 1, - 'application/vnd.3gpp.pic-bw-large' => 1, - 'application/vnd.3gpp.pic-bw-small' => 1, - 'application/vnd.3gpp.pic-bw-var' => 1, - 'application/vnd.3gpp2.tcap' => 1, - 'application/vnd.3m.post-it-notes' => 1, - 'application/vnd.accpac.simply.aso' => 1, - 'application/vnd.accpac.simply.imp' => 1, - 'application/vnd.acucobol' => 1, - 'application/vnd.acucorp' => 1, - 'application/vnd.adobe.air-application-installer-package+zip' => 1, - 'application/vnd.adobe.formscentral.fcdt' => 1, - 'application/vnd.adobe.fxp' => 1, - 'application/vnd.adobe.xdp+xml' => 1, - 'application/vnd.adobe.xfdf' => 1, - 'application/vnd.ahead.space' => 1, - 'application/vnd.airzip.filesecure.azf' => 1, - 'application/vnd.airzip.filesecure.azs' => 1, - 'application/vnd.amazon.ebook' => 1, - 'application/vnd.americandynamics.acc' => 1, - 'application/vnd.amiga.ami' => 1, - 'application/vnd.android.package-archive' => 1, - 'application/vnd.anser-web-certificate-issue-initiation' => 1, - 'application/vnd.anser-web-funds-transfer-initiation' => 1, - 'application/vnd.antix.game-component' => 1, - 'application/vnd.apple.installer+xml' => 1, - 'application/vnd.apple.mpegurl' => 1, - 'application/vnd.aristanetworks.swi' => 1, - 'application/vnd.astraea-software.iota' => 1, - 'application/vnd.audiograph' => 1, - 'application/vnd.blueice.multipass' => 1, - 'application/vnd.bmi' => 1, - 'application/vnd.businessobjects' => 1, - 'application/vnd.chemdraw+xml' => 1, - 'application/vnd.chipnuts.karaoke-mmd' => 1, - 'application/vnd.cinderella' => 1, - 'application/vnd.claymore' => 1, - 'application/vnd.cloanto.rp9' => 1, - 'application/vnd.clonk.c4group' => 1, - 'application/vnd.cluetrust.cartomobile-config' => 1, - 'application/vnd.cluetrust.cartomobile-config-pkg' => 1, - 'application/vnd.commonspace' => 1, - 'application/vnd.contact.cmsg' => 1, - 'application/vnd.cosmocaller' => 1, - 'application/vnd.crick.clicker' => 1, - 'application/vnd.crick.clicker.keyboard' => 1, - 'application/vnd.crick.clicker.palette' => 1, - 'application/vnd.crick.clicker.template' => 1, - 'application/vnd.crick.clicker.wordbank' => 1, - 'application/vnd.criticaltools.wbs+xml' => 1, - 'application/vnd.ctc-posml' => 1, - 'application/vnd.cups-ppd' => 1, - 'application/vnd.curl.car' => 1, - 'application/vnd.curl.pcurl' => 1, - 'application/vnd.dart' => 1, - 'application/vnd.data-vision.rdz' => 1, - 'application/vnd.dece.data' => 1, - 'application/vnd.dece.ttml+xml' => 1, - 'application/vnd.dece.unspecified' => 1, - 'application/vnd.dece.zip' => 1, - 'application/vnd.denovo.fcselayout-link' => 1, - 'application/vnd.dna' => 1, - 'application/vnd.dolby.mlp' => 1, - 'application/vnd.dpgraph' => 1, - 'application/vnd.dreamfactory' => 1, - 'application/vnd.ds-keypoint' => 1, - 'application/vnd.dvb.ait' => 1, - 'application/vnd.dvb.service' => 1, - 'application/vnd.dynageo' => 1, - 'application/vnd.ecowin.chart' => 1, - 'application/vnd.enliven' => 1, - 'application/vnd.epson.esf' => 1, - 'application/vnd.epson.msf' => 1, - 'application/vnd.epson.quickanime' => 1, - 'application/vnd.epson.salt' => 1, - 'application/vnd.epson.ssf' => 1, - 'application/vnd.eszigno3+xml' => 1, - 'application/vnd.ezpix-album' => 1, - 'application/vnd.ezpix-package' => 1, - 'application/vnd.fdf' => 1, - 'application/vnd.fdsn.mseed' => 1, - 'application/vnd.fdsn.seed' => 1, - 'application/vnd.flographit' => 1, - 'application/vnd.fluxtime.clip' => 1, - 'application/vnd.framemaker' => 1, - 'application/vnd.frogans.fnc' => 1, - 'application/vnd.frogans.ltf' => 1, - 'application/vnd.fsc.weblaunch' => 1, - 'application/vnd.fujitsu.oasys' => 1, - 'application/vnd.fujitsu.oasys2' => 1, - 'application/vnd.fujitsu.oasys3' => 1, - 'application/vnd.fujitsu.oasysgp' => 1, - 'application/vnd.fujitsu.oasysprs' => 1, - 'application/vnd.fujixerox.ddd' => 1, - 'application/vnd.fujixerox.docuworks' => 1, - 'application/vnd.fujixerox.docuworks.binder' => 1, - 'application/vnd.fuzzysheet' => 1, - 'application/vnd.genomatix.tuxedo' => 1, - 'application/vnd.geogebra.file' => 1, - 'application/vnd.geogebra.tool' => 1, - 'application/vnd.geometry-explorer' => 1, - 'application/vnd.geonext' => 1, - 'application/vnd.geoplan' => 1, - 'application/vnd.geospace' => 1, - 'application/vnd.gmx' => 1, - 'application/vnd.google-earth.kml+xml' => 1, - 'application/vnd.google-earth.kmz' => 1, - 'application/vnd.grafeq' => 1, - 'application/vnd.groove-account' => 1, - 'application/vnd.groove-help' => 1, - 'application/vnd.groove-identity-message' => 1, - 'application/vnd.groove-injector' => 1, - 'application/vnd.groove-tool-message' => 1, - 'application/vnd.groove-tool-template' => 1, - 'application/vnd.groove-vcard' => 1, - 'application/vnd.hal+xml' => 1, - 'application/vnd.handheld-entertainment+xml' => 1, - 'application/vnd.hbci' => 1, - 'application/vnd.hhe.lesson-player' => 1, - 'application/vnd.hp-hpgl' => 1, - 'application/vnd.hp-hpid' => 1, - 'application/vnd.hp-hps' => 1, - 'application/vnd.hp-jlyt' => 1, - 'application/vnd.hp-pcl' => 1, - 'application/vnd.hp-pclxl' => 1, - 'application/vnd.hydrostatix.sof-data' => 1, - 'application/vnd.ibm.minipay' => 1, - 'application/vnd.ibm.modcap' => 1, - 'application/vnd.ibm.rights-management' => 1, - 'application/vnd.ibm.secure-container' => 1, - 'application/vnd.iccprofile' => 1, - 'application/vnd.igloader' => 1, - 'application/vnd.immervision-ivp' => 1, - 'application/vnd.immervision-ivu' => 1, - 'application/vnd.insors.igm' => 1, - 'application/vnd.intercon.formnet' => 1, - 'application/vnd.intergeo' => 1, - 'application/vnd.intu.qbo' => 1, - 'application/vnd.intu.qfx' => 1, - 'application/vnd.ipunplugged.rcprofile' => 1, - 'application/vnd.irepository.package+xml' => 1, - 'application/vnd.is-xpr' => 1, - 'application/vnd.isac.fcs' => 1, - 'application/vnd.jam' => 1, - 'application/vnd.jcp.javame.midlet-rms' => 1, - 'application/vnd.jisp' => 1, - 'application/vnd.joost.joda-archive' => 1, - 'application/vnd.kahootz' => 1, - 'application/vnd.kde.karbon' => 1, - 'application/vnd.kde.kchart' => 1, - 'application/vnd.kde.kformula' => 1, - 'application/vnd.kde.kivio' => 1, - 'application/vnd.kde.kontour' => 1, - 'application/vnd.kde.kpresenter' => 1, - 'application/vnd.kde.kspread' => 1, - 'application/vnd.kde.kword' => 1, - 'application/vnd.kenameaapp' => 1, - 'application/vnd.kidspiration' => 1, - 'application/vnd.kinar' => 1, - 'application/vnd.koan' => 1, - 'application/vnd.kodak-descriptor' => 1, - 'application/vnd.las.las+xml' => 1, - 'application/vnd.llamagraphics.life-balance.desktop' => 1, - 'application/vnd.llamagraphics.life-balance.exchange+xml' => 1, - 'application/vnd.lotus-1-2-3' => 1, - 'application/vnd.lotus-approach' => 1, - 'application/vnd.lotus-freelance' => 1, - 'application/vnd.lotus-notes' => 1, - 'application/vnd.lotus-organizer' => 1, - 'application/vnd.lotus-screencam' => 1, - 'application/vnd.lotus-wordpro' => 1, - 'application/vnd.macports.portpkg' => 1, - 'application/vnd.mcd' => 1, - 'application/vnd.medcalcdata' => 1, - 'application/vnd.mediastation.cdkey' => 1, - 'application/vnd.mfer' => 1, - 'application/vnd.mfmp' => 1, - 'application/vnd.micrografx.flo' => 1, - 'application/vnd.micrografx.igx' => 1, - 'application/vnd.mif' => 1, - 'application/vnd.mobius.daf' => 1, - 'application/vnd.mobius.dis' => 1, - 'application/vnd.mobius.mbk' => 1, - 'application/vnd.mobius.mqy' => 1, - 'application/vnd.mobius.msl' => 1, - 'application/vnd.mobius.plc' => 1, - 'application/vnd.mobius.txf' => 1, - 'application/vnd.mophun.application' => 1, - 'application/vnd.mophun.certificate' => 1, - 'application/vnd.mozilla.xul+xml' => 1, - 'application/vnd.ms-artgalry' => 1, - 'application/vnd.ms-cab-compressed' => 1, - 'application/vnd.ms-excel' => 1, - 'application/vnd.ms-excel.addin.macroenabled.12' => 1, - 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => 1, - 'application/vnd.ms-excel.sheet.macroenabled.12' => 1, - 'application/vnd.ms-excel.template.macroenabled.12' => 1, - 'application/vnd.ms-fontobject' => 1, - 'application/vnd.ms-htmlhelp' => 1, - 'application/vnd.ms-ims' => 1, - 'application/vnd.ms-lrm' => 1, - 'application/vnd.ms-officetheme' => 1, - 'application/vnd.ms-pki.seccat' => 1, - 'application/vnd.ms-pki.stl' => 1, - 'application/vnd.ms-powerpoint' => 1, - 'application/vnd.ms-powerpoint.addin.macroenabled.12' => 1, - 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => 1, - 'application/vnd.ms-powerpoint.slide.macroenabled.12' => 1, - 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => 1, - 'application/vnd.ms-powerpoint.template.macroenabled.12' => 1, - 'application/vnd.ms-project' => 1, - 'application/vnd.ms-word.document.macroenabled.12' => 1, - 'application/vnd.ms-word.template.macroenabled.12' => 1, - 'application/vnd.ms-works' => 1, - 'application/vnd.ms-wpl' => 1, - 'application/vnd.ms-xpsdocument' => 1, - 'application/vnd.mseq' => 1, - 'application/vnd.musician' => 1, - 'application/vnd.muvee.style' => 1, - 'application/vnd.mynfc' => 1, - 'application/vnd.neurolanguage.nlu' => 1, - 'application/vnd.nitf' => 1, - 'application/vnd.noblenet-directory' => 1, - 'application/vnd.noblenet-sealer' => 1, - 'application/vnd.noblenet-web' => 1, - 'application/vnd.nokia.n-gage.data' => 1, - 'application/vnd.nokia.n-gage.symbian.install' => 1, - 'application/vnd.nokia.radio-preset' => 1, - 'application/vnd.nokia.radio-presets' => 1, - 'application/vnd.novadigm.edm' => 1, - 'application/vnd.novadigm.edx' => 1, - 'application/vnd.novadigm.ext' => 1, - 'application/vnd.oasis.opendocument.chart' => 1, - 'application/vnd.oasis.opendocument.chart-template' => 1, - 'application/vnd.oasis.opendocument.database' => 1, - 'application/vnd.oasis.opendocument.formula' => 1, - 'application/vnd.oasis.opendocument.formula-template' => 1, - 'application/vnd.oasis.opendocument.graphics' => 1, - 'application/vnd.oasis.opendocument.graphics-template' => 1, - 'application/vnd.oasis.opendocument.image' => 1, - 'application/vnd.oasis.opendocument.image-template' => 1, - 'application/vnd.oasis.opendocument.presentation' => 1, - 'application/vnd.oasis.opendocument.presentation-template' => 1, - 'application/vnd.oasis.opendocument.spreadsheet' => 1, - 'application/vnd.oasis.opendocument.spreadsheet-template' => 1, - 'application/vnd.oasis.opendocument.text' => 1, - 'application/vnd.oasis.opendocument.text-master' => 1, - 'application/vnd.oasis.opendocument.text-template' => 1, - 'application/vnd.oasis.opendocument.text-web' => 1, - 'application/vnd.olpc-sugar' => 1, - 'application/vnd.oma.dd2+xml' => 1, - 'application/vnd.openofficeorg.extension' => 1, - 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 1, - 'application/vnd.openxmlformats-officedocument.presentationml.slide' => 1, - 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 1, - 'application/vnd.openxmlformats-officedocument.presentationml.template' => 1, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 1, - 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 1, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 1, - 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 1, - 'application/vnd.osgeo.mapguide.package' => 1, - 'application/vnd.osgi.dp' => 1, - 'application/vnd.osgi.subsystem' => 1, - 'application/vnd.palm' => 1, - 'application/vnd.pawaafile' => 1, - 'application/vnd.pg.format' => 1, - 'application/vnd.pg.osasli' => 1, - 'application/vnd.picsel' => 1, - 'application/vnd.pmi.widget' => 1, - 'application/vnd.pocketlearn' => 1, - 'application/vnd.powerbuilder6' => 1, - 'application/vnd.previewsystems.box' => 1, - 'application/vnd.proteus.magazine' => 1, - 'application/vnd.publishare-delta-tree' => 1, - 'application/vnd.pvi.ptid1' => 1, - 'application/vnd.quark.quarkxpress' => 1, - 'application/vnd.realvnc.bed' => 1, - 'application/vnd.recordare.musicxml' => 1, - 'application/vnd.recordare.musicxml+xml' => 1, - 'application/vnd.rig.cryptonote' => 1, - 'application/vnd.rim.cod' => 1, - 'application/vnd.rn-realmedia' => 1, - 'application/vnd.rn-realmedia-vbr' => 1, - 'application/vnd.route66.link66+xml' => 1, - 'application/vnd.sailingtracker.track' => 1, - 'application/vnd.seemail' => 1, - 'application/vnd.sema' => 1, - 'application/vnd.semd' => 1, - 'application/vnd.semf' => 1, - 'application/vnd.shana.informed.formdata' => 1, - 'application/vnd.shana.informed.formtemplate' => 1, - 'application/vnd.shana.informed.interchange' => 1, - 'application/vnd.shana.informed.package' => 1, - 'application/vnd.simtech-mindmapper' => 1, - 'application/vnd.smaf' => 1, - 'application/vnd.smart.teacher' => 1, - 'application/vnd.solent.sdkm+xml' => 1, - 'application/vnd.spotfire.dxp' => 1, - 'application/vnd.spotfire.sfs' => 1, - 'application/vnd.stardivision.calc' => 1, - 'application/vnd.stardivision.draw' => 1, - 'application/vnd.stardivision.impress' => 1, - 'application/vnd.stardivision.math' => 1, - 'application/vnd.stardivision.writer' => 1, - 'application/vnd.stardivision.writer-global' => 1, - 'application/vnd.stepmania.package' => 1, - 'application/vnd.stepmania.stepchart' => 1, - 'application/vnd.sun.xml.calc' => 1, - 'application/vnd.sun.xml.calc.template' => 1, - 'application/vnd.sun.xml.draw' => 1, - 'application/vnd.sun.xml.draw.template' => 1, - 'application/vnd.sun.xml.impress' => 1, - 'application/vnd.sun.xml.impress.template' => 1, - 'application/vnd.sun.xml.math' => 1, - 'application/vnd.sun.xml.writer' => 1, - 'application/vnd.sun.xml.writer.global' => 1, - 'application/vnd.sun.xml.writer.template' => 1, - 'application/vnd.sus-calendar' => 1, - 'application/vnd.svd' => 1, - 'application/vnd.symbian.install' => 1, - 'application/vnd.syncml+xml' => 1, - 'application/vnd.syncml.dm+wbxml' => 1, - 'application/vnd.syncml.dm+xml' => 1, - 'application/vnd.tao.intent-module-archive' => 1, - 'application/vnd.tcpdump.pcap' => 1, - 'application/vnd.tmobile-livetv' => 1, - 'application/vnd.trid.tpt' => 1, - 'application/vnd.triscape.mxs' => 1, - 'application/vnd.trueapp' => 1, - 'application/vnd.ufdl' => 1, - 'application/vnd.uiq.theme' => 1, - 'application/vnd.umajin' => 1, - 'application/vnd.unity' => 1, - 'application/vnd.uoml+xml' => 1, - 'application/vnd.vcx' => 1, - 'application/vnd.visio' => 1, - 'application/vnd.visionary' => 1, - 'application/vnd.vsf' => 1, - 'application/vnd.wap.wbxml' => 1, - 'application/vnd.wap.wmlc' => 1, - 'application/vnd.wap.wmlscriptc' => 1, - 'application/vnd.webturbo' => 1, - 'application/vnd.wolfram.player' => 1, - 'application/vnd.wordperfect' => 1, - 'application/vnd.wqd' => 1, - 'application/vnd.wt.stf' => 1, - 'application/vnd.xara' => 1, - 'application/vnd.xfdl' => 1, - 'application/vnd.yamaha.hv-dic' => 1, - 'application/vnd.yamaha.hv-script' => 1, - 'application/vnd.yamaha.hv-voice' => 1, - 'application/vnd.yamaha.openscoreformat' => 1, - 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => 1, - 'application/vnd.yamaha.smaf-audio' => 1, - 'application/vnd.yamaha.smaf-phrase' => 1, - 'application/vnd.yellowriver-custom-menu' => 1, - 'application/vnd.zul' => 1, - 'application/vnd.zzazz.deck+xml' => 1, - 'application/voicexml+xml' => 1, - 'application/widget' => 1, - 'application/winhlp' => 1, - 'application/wsdl+xml' => 1, - 'application/wspolicy+xml' => 1, - 'application/x-7z-compressed' => 1, - 'application/x-abiword' => 1, - 'application/x-ace-compressed' => 1, - 'application/x-apple-diskimage' => 1, - 'application/x-authorware-bin' => 1, - 'application/x-authorware-map' => 1, - 'application/x-authorware-seg' => 1, - 'application/x-bcpio' => 1, - 'application/x-bittorrent' => 1, - 'application/x-blorb' => 1, - 'application/x-bzip' => 1, - 'application/x-bzip2' => 1, - 'application/x-cbr' => 1, - 'application/x-cdlink' => 1, - 'application/x-cfs-compressed' => 1, - 'application/x-chat' => 1, - 'application/x-chess-pgn' => 1, - 'application/x-conference' => 1, - 'application/x-cpio' => 1, - 'application/x-csh' => 1, - 'application/x-debian-package' => 1, - 'application/x-dgc-compressed' => 1, - 'application/x-director' => 1, - 'application/x-doom' => 1, - 'application/x-dtbncx+xml' => 1, - 'application/x-dtbook+xml' => 1, - 'application/x-dtbresource+xml' => 1, - 'application/x-dvi' => 1, - 'application/x-envoy' => 1, - 'application/x-eva' => 1, - 'application/x-font-bdf' => 1, - 'application/x-font-ghostscript' => 1, - 'application/x-font-linux-psf' => 1, - 'application/x-font-otf' => 1, - 'application/x-font-pcf' => 1, - 'application/x-font-snf' => 1, - 'application/x-font-ttf' => 1, - 'application/x-font-type1' => 1, - 'application/x-font-woff' => 1, - 'application/x-freearc' => 1, - 'application/x-futuresplash' => 1, - 'application/x-gca-compressed' => 1, - 'application/x-glulx' => 1, - 'application/x-gnumeric' => 1, - 'application/x-gramps-xml' => 1, - 'application/x-gtar' => 1, - 'application/x-hdf' => 1, - 'application/x-install-instructions' => 1, - 'application/x-iso9660-image' => 1, - 'application/x-java-jnlp-file' => 1, - 'application/x-latex' => 1, - 'application/x-lzh-compressed' => 1, - 'application/x-mie' => 1, - 'application/x-mobipocket-ebook' => 1, - 'application/x-ms-application' => 1, - 'application/x-ms-shortcut' => 1, - 'application/x-ms-wmd' => 1, - 'application/x-ms-wmz' => 1, - 'application/x-ms-xbap' => 1, - 'application/x-msaccess' => 1, - 'application/x-msbinder' => 1, - 'application/x-mscardfile' => 1, - 'application/x-msclip' => 1, - 'application/x-msdownload' => 1, - 'application/x-msmediaview' => 1, - 'application/x-msmetafile' => 1, - 'application/x-msmoney' => 1, - 'application/x-mspublisher' => 1, - 'application/x-msschedule' => 1, - 'application/x-msterminal' => 1, - 'application/x-mswrite' => 1, - 'application/x-netcdf' => 1, - 'application/x-nzb' => 1, - 'application/x-pkcs12' => 1, - 'application/x-pkcs7-certificates' => 1, - 'application/x-pkcs7-certreqresp' => 1, - 'application/x-rar-compressed' => 1, - 'application/x-research-info-systems' => 1, - 'application/x-sh' => 1, - 'application/x-shar' => 1, - 'application/x-shockwave-flash' => 1, - 'application/x-silverlight-app' => 1, - 'application/x-silverlight-2' => 1, - 'application/x-sql' => 1, - 'application/x-stuffit' => 1, - 'application/x-stuffitx' => 1, - 'application/x-subrip' => 1, - 'application/x-sv4cpio' => 1, - 'application/x-sv4crc' => 1, - 'application/x-t3vm-image' => 1, - 'application/x-tads' => 1, - 'application/x-tar' => 1, - 'application/x-tcl' => 1, - 'application/x-tex' => 1, - 'application/x-tex-tfm' => 1, - 'application/x-texinfo' => 1, - 'application/x-tgif' => 1, - 'application/x-ustar' => 1, - 'application/x-wais-source' => 1, - 'application/x-x509-ca-cert' => 1, - 'application/x-xfig' => 1, - 'application/x-xliff+xml' => 1, - 'application/x-xpinstall' => 1, - 'application/x-xz' => 1, - 'application/x-zmachine' => 1, - 'application/xaml+xml' => 1, - 'application/xcap-diff+xml' => 1, - 'application/xenc+xml' => 1, - 'application/xhtml+xml' => 1, - 'application/xml' => 1, - 'application/xml-dtd' => 1, - 'application/xop+xml' => 1, - 'application/xproc+xml' => 1, - 'application/xslt+xml' => 1, - 'application/xspf+xml' => 1, - 'application/xv+xml' => 1, - 'application/yang' => 1, - 'application/yin+xml' => 1, - 'application/zip' => 1, - 'audio/adpcm' => 1, - 'audio/basic' => 1, - 'audio/midi' => 1, - 'audio/mp4' => 1, - 'audio/mpeg' => 1, - 'audio/ogg' => 1, - 'audio/s3m' => 1, - 'audio/silk' => 1, - 'audio/vnd.dece.audio' => 1, - 'audio/vnd.digital-winds' => 1, - 'audio/vnd.dra' => 1, - 'audio/vnd.dts' => 1, - 'audio/vnd.dts.hd' => 1, - 'audio/vnd.lucent.voice' => 1, - 'audio/vnd.ms-playready.media.pya' => 1, - 'audio/vnd.nuera.ecelp4800' => 1, - 'audio/vnd.nuera.ecelp7470' => 1, - 'audio/vnd.nuera.ecelp9600' => 1, - 'audio/vnd.rip' => 1, - 'audio/webm' => 1, - 'audio/x-aac' => 1, - 'audio/x-aiff' => 1, - 'audio/x-caf' => 1, - 'audio/x-flac' => 1, - 'audio/x-matroska' => 1, - 'audio/x-mpegurl' => 1, - 'audio/x-ms-wax' => 1, - 'audio/x-ms-wma' => 1, - 'audio/x-pn-realaudio' => 1, - 'audio/x-pn-realaudio-plugin' => 1, - 'audio/x-wav' => 1, - 'audio/xm' => 1, - 'chemical/x-cdx' => 1, - 'chemical/x-cif' => 1, - 'chemical/x-cmdf' => 1, - 'chemical/x-cml' => 1, - 'chemical/x-csml' => 1, - 'chemical/x-xyz' => 1, - 'image/bmp' => 1, - 'image/cgm' => 1, - 'image/g3fax' => 1, - 'image/gif' => 1, - 'image/ief' => 1, - 'image/jpeg' => 1, - 'image/ktx' => 1, - 'image/png' => 1, - 'image/prs.btif' => 1, - 'image/sgi' => 1, - 'image/svg+xml' => 1, - 'image/tiff' => 1, - 'image/vnd.adobe.photoshop' => 1, - 'image/vnd.dece.graphic' => 1, - 'image/vnd.dvb.subtitle' => 1, - 'image/vnd.djvu' => 1, - 'image/vnd.dwg' => 1, - 'image/vnd.dxf' => 1, - 'image/vnd.fastbidsheet' => 1, - 'image/vnd.fpx' => 1, - 'image/vnd.fst' => 1, - 'image/vnd.fujixerox.edmics-mmr' => 1, - 'image/vnd.fujixerox.edmics-rlc' => 1, - 'image/vnd.ms-modi' => 1, - 'image/vnd.ms-photo' => 1, - 'image/vnd.net-fpx' => 1, - 'image/vnd.wap.wbmp' => 1, - 'image/vnd.xiff' => 1, - 'image/webp' => 1, - 'image/x-3ds' => 1, - 'image/x-cmu-raster' => 1, - 'image/x-cmx' => 1, - 'image/x-freehand' => 1, - 'image/x-icon' => 1, - 'image/x-mrsid-image' => 1, - 'image/x-pcx' => 1, - 'image/x-pict' => 1, - 'image/x-portable-anymap' => 1, - 'image/x-portable-bitmap' => 1, - 'image/x-portable-graymap' => 1, - 'image/x-portable-pixmap' => 1, - 'image/x-rgb' => 1, - 'image/x-tga' => 1, - 'image/x-xbitmap' => 1, - 'image/x-xpixmap' => 1, - 'image/x-xwindowdump' => 1, - 'message/rfc822' => 1, - 'model/iges' => 1, - 'model/mesh' => 1, - 'model/vnd.collada+xml' => 1, - 'model/vnd.dwf' => 1, - 'model/vnd.gdl' => 1, - 'model/vnd.gtw' => 1, - 'model/vnd.mts' => 1, - 'model/vnd.vtu' => 1, - 'model/vrml' => 1, - 'model/x3d+binary' => 1, - 'model/x3d+vrml' => 1, - 'model/x3d+xml' => 1, - 'video/3gpp' => 1, - 'video/3gpp2' => 1, - 'video/h261' => 1, - 'video/h263' => 1, - 'video/h264' => 1, - 'video/jpeg' => 1, - 'video/jpm' => 1, - 'video/mj2' => 1, - 'video/mp4' => 1, - 'video/mpeg' => 1, - 'video/ogg' => 1, - 'video/quicktime' => 1, - 'video/vnd.dece.hd' => 1, - 'video/vnd.dece.mobile' => 1, - 'video/vnd.dece.pd' => 1, - 'video/vnd.dece.sd' => 1, - 'video/vnd.dece.video' => 1, - 'video/vnd.dvb.file' => 1, - 'video/vnd.fvt' => 1, - 'video/vnd.mpegurl' => 1, - 'video/vnd.ms-playready.media.pyv' => 1, - 'video/vnd.uvvu.mp4' => 1, - 'video/vnd.vivo' => 1, - 'video/webm' => 1, - 'video/x-f4v' => 1, - 'video/x-fli' => 1, - 'video/x-flv' => 1, - 'video/x-m4v' => 1, - 'video/x-matroska' => 1, - 'video/x-mng' => 1, - 'video/x-ms-asf' => 1, - 'video/x-ms-vob' => 1, - 'video/x-ms-wm' => 1, - 'video/x-ms-wmv' => 1, - 'video/x-ms-wmx' => 1, - 'video/x-ms-wvx' => 1, - 'video/x-msvideo' => 1, - 'video/x-sgi-movie' => 1, - 'video/x-smv' => 1, - 'x-conference/x-cooltalk' => 1, - ), ); diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index 4cee601b0..fce40cf71 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -87,21 +87,6 @@ class HTMLFilter return $output; } - /** - * Remove embedded media from HTML content. - * - * @param string $input - * @param string $replacement - * @return string - */ - public static function removeEmbeddedMedia($input, $replacement = '') - { - $input = preg_replace('!]*>(.*?)?!is', $replacement, $input); - $input = preg_replace('!]*>(.*?)?!is', $replacement, $input); - $input = preg_replace('!]*editor_component="multimedia_link"[^>]*>(.*?)?!is', $replacement, $input); - return $input; - } - /** * Get an instance of HTMLPurifier. * @@ -136,7 +121,7 @@ class HTMLFilter $config->set('HTML.SafeEmbed', true); $config->set('HTML.SafeIframe', true); $config->set('HTML.SafeObject', true); - $config->set('URI.SafeIframeRegexp', self::_getIframeWhitelist()); + $config->set('URI.SafeIframeRegexp', MediaFilter::getIframeWhitelistRegex()); // Set the serializer path. $config->set('Cache.SerializerPath', RX_BASEDIR . 'files/cache/htmlpurifier'); @@ -384,38 +369,6 @@ class HTMLFilter } } - /** - * Get the object whitelist as a regular expression. - * - * @return string - */ - protected static function _getObjectWhitelist() - { - $domains = \EmbedFilter::getInstance()->getWhiteUrlList(); - $result = array(); - foreach($domains as $domain) - { - $result[] = preg_quote($domain, '%'); - } - return '%^https?://(' . implode('|', $result) . ')%'; - } - - /** - * Get the iframe whitelist as a regular expression. - * - * @return string - */ - protected static function _getIframeWhitelist() - { - $domains = \EmbedFilter::getInstance()->getWhiteIframeUrlList(); - $result = array(); - foreach($domains as $domain) - { - $result[] = preg_quote($domain, '%'); - } - return '%^https?://(' . implode('|', $result) . ')%'; - } - /** * Rhymix-specific preprocessing method. * @@ -447,7 +400,7 @@ class HTMLFilter }, $content); // Remove object and embed URLs that are not allowed. - $whitelist = self::_getObjectWhitelist(); + $whitelist = MediaFilter::getObjectWhitelistRegex(); $content = preg_replace_callback('!<(object|embed|param)([^>]+)>!i', function($matches) use($whitelist) { return preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use($whitelist) { if (in_array($attr[1], array('data', 'src', 'href', 'url', 'movie', 'source'))) diff --git a/common/framework/security/mediafilter.php b/common/framework/security/mediafilter.php new file mode 100644 index 000000000..4460b0899 --- /dev/null +++ b/common/framework/security/mediafilter.php @@ -0,0 +1,180 @@ +]*>(.*?)?!is', $replacement, $input); + $input = preg_replace('!]*>(.*?)?!is', $replacement, $input); + $input = preg_replace('!]*editor_component="multimedia_link"[^>]*>(.*?)?!is', $replacement, $input); + return $input; + } + + /** + * Load whitelists. + * + * @param array $custom_whitelist + * @return void + */ + protected static function _loadWhitelists($custom_whitelist = array()) + { + $default_whitelist = (include RX_BASEDIR . 'common/defaults/whitelist.php'); + self::$_object_whitelist = array(); + self::$_iframe_whitelist = array(); + + if(count($custom_whitelist)) + { + if(!is_array($custom_whitelist) || !isset($custom_whitelist['iframe']) || !isset($custom_whitelist['object'])) + { + $whitelist = array( + 'iframe' => isset($whitelist->iframe) ? $whitelist->iframe : array(), + 'object' => isset($whitelist->object) ? $whitelist->object : array(), + ); + } + foreach ($custom_whitelist['iframe'] as $prefix) + { + self::$_iframe_whitelist[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; + } + foreach ($custom_whitelist['object'] as $prefix) + { + self::$_object_whitelist[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; + } + } + else + { + foreach ($default_whitelist['iframe'] as $prefix) + { + self::$_iframe_whitelist[] = $prefix; + } + foreach ($default_whitelist['object'] as $prefix) + { + self::$_object_whitelist[] = $prefix; + } + if ($iframe_whitelist = config('mediafilter.iframe') ?: config('embedfilter.iframe')) + { + foreach ($iframe_whitelist as $prefix) + { + self::$_iframe_whitelist[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; + } + } + if ($object_whitelist = config('mediafilter.object') ?: config('embedfilter.object')) + { + foreach ($object_whitelist as $prefix) + { + self::$_object_whitelist[] = preg_match('@^https?://(.*)$@i', $prefix, $matches) ? $matches[1] : $prefix; + } + } + } + + self::$_object_whitelist = array_unique(self::$_object_whitelist); + self::$_iframe_whitelist = array_unique(self::$_iframe_whitelist); + natcasesort(self::$_object_whitelist); + natcasesort(self::$_iframe_whitelist); + } +} diff --git a/common/legacy.php b/common/legacy.php index 729166e14..665d443ff 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -1036,7 +1036,7 @@ function stripEmbedTagForAdmin(&$content, $writer_member_srl) $security_msg = '
    ' . '

    ' . lang('security_warning_embed') . '

    '; - $content = Rhymix\Framework\Security\HTMLFilter::removeEmbeddedMedia($content, $security_msg); + $content = Rhymix\Framework\Security\MediaFilter::removeEmbeddedMedia($content, $security_msg); } return; diff --git a/tests/unit/framework/security/HTMLFilterTest.php b/tests/unit/framework/security/HTMLFilterTest.php index 01162dc9c..169b41c48 100644 --- a/tests/unit/framework/security/HTMLFilterTest.php +++ b/tests/unit/framework/security/HTMLFilterTest.php @@ -64,20 +64,4 @@ class HTMLFilterTest extends \Codeception\TestCase\Test $this->assertEquals($test[1], Rhymix\Framework\Security\HTMLFilter::clean($test[0])); } } - - public function testRemoveEmbeddedMedia() - { - $tests = array( - '
    ' => '
    ', - '
    ' => '
    ', - '
    ' => '
    ', - '
    ' => '
    ', - '
    ' => '
    ', - ); - - foreach ($tests as $from => $to) - { - $this->assertEquals($to, Rhymix\Framework\Security\HTMLFilter::removeEmbeddedMedia($from)); - } - } } diff --git a/tests/unit/framework/security/MediaFilterTest.php b/tests/unit/framework/security/MediaFilterTest.php new file mode 100644 index 000000000..920ad2fd7 --- /dev/null +++ b/tests/unit/framework/security/MediaFilterTest.php @@ -0,0 +1,47 @@ +assertTrue(in_array('www.youtube.com/', Rhymix\Framework\Security\MediaFilter::getIframeWhitelist())); + $this->assertFalse(in_array('random-website.com/', Rhymix\Framework\Security\MediaFilter::getIframeWhitelist())); + + // iframe whitelist as regex. + $this->assertTrue(strpos(Rhymix\Framework\Security\MediaFilter::getIframeWhitelistRegex(), '|www\.youtube\.com/') !== false); + $this->assertFalse(strpos(Rhymix\Framework\Security\MediaFilter::getIframeWhitelistRegex(), 'www.youtube.com/') !== false); + + // Match individual URL against iframe whitelist. + $this->assertTrue(Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist('https://www.youtube.com/v')); + $this->assertFalse(Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist('http://www-youtube.com/v')); + + // object whitelist as array. + $this->assertTrue(in_array('www.youtube.com/', Rhymix\Framework\Security\MediaFilter::getObjectWhitelist())); + $this->assertFalse(in_array('random-website.com/', Rhymix\Framework\Security\MediaFilter::getObjectWhitelist())); + + // object whitelist as regex. + $this->assertTrue(strpos(Rhymix\Framework\Security\MediaFilter::getObjectWhitelistRegex(), '|www\.youtube\.com/') !== false); + $this->assertFalse(strpos(Rhymix\Framework\Security\MediaFilter::getObjectWhitelistRegex(), 'www.youtube.com/') !== false); + + // Match individual URL against object whitelist. + $this->assertTrue(Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist('https://www.youtube.com/v')); + $this->assertFalse(Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist('http://www-youtube.com/v')); + } + + public function testRemoveEmbeddedMedia() + { + $tests = array( + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + ); + + foreach ($tests as $from => $to) + { + $this->assertEquals($to, Rhymix\Framework\Security\MediaFilter::removeEmbeddedMedia($from)); + } + } +} From 2effbea06f04380ff70a8b13f04ab6a53bb9fb5d Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 09:59:26 +0900 Subject: [PATCH 146/318] Update all other places to use new MediaFilter class --- classes/context/Context.class.php | 4 ++-- common/defaults/config.php | 2 +- common/framework/compat/configparser.php | 6 ++--- modules/admin/admin.admin.controller.php | 29 ++++++++++++++---------- modules/admin/admin.admin.view.php | 5 ++-- modules/admin/tpl/config_security.html | 8 +++---- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index c61deeae0..66c11a077 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -574,8 +574,8 @@ class Context $db_info->sitelock_title = $config['lock']['title']; $db_info->sitelock_message = $config['lock']['message']; $db_info->sitelock_whitelist = count($config['lock']['allow']) ? $config['lock']['allow'] : array('127.0.0.1'); - $db_info->embed_white_iframe = $config['embedfilter']['iframe']; - $db_info->embed_white_object = $config['embedfilter']['object']; + $db_info->embed_white_iframe = $config['mediafilter']['iframe'] ?: $config['embedfilter']['iframe']; + $db_info->embed_white_object = $config['mediafilter']['object'] ?: $config['embedfilter']['object']; $db_info->use_mobile_view = $config['use_mobile_view'] ? 'Y' : 'N'; $db_info->use_prepared_statements = $config['use_prepared_statements'] ? 'Y' : 'N'; $db_info->use_rewrite = $config['use_rewrite'] ? 'Y' : 'N'; diff --git a/common/defaults/config.php b/common/defaults/config.php index 0fc4fe801..05c9426dd 100644 --- a/common/defaults/config.php +++ b/common/defaults/config.php @@ -97,7 +97,7 @@ return array( 'display_to' => 'admin', 'allow' => array(), ), - 'embedfilter' => array( + 'mediafilter' => array( 'iframe' => array(), 'object' => array(), ), diff --git a/common/framework/compat/configparser.php b/common/framework/compat/configparser.php index b4d6fa067..c88300dd1 100644 --- a/common/framework/compat/configparser.php +++ b/common/framework/compat/configparser.php @@ -216,14 +216,14 @@ class ConfigParser } $config['lock']['allow'] = array_values($db_info->sitelock_whitelist); - // Convert embed filter configuration. + // Convert media filter configuration. if (is_array($db_info->embed_white_iframe)) { $whitelist = array_unique(array_map(function($item) { return preg_match('@^https?://(.*)$@i', $item, $matches) ? $matches[1] : $item; }, $db_info->embed_white_iframe)); natcasesort($whitelist); - $config['embedfilter']['iframe'] = $whitelist; + $config['mediafilter']['iframe'] = $whitelist; } if (is_array($db_info->embed_white_object)) { @@ -231,7 +231,7 @@ class ConfigParser return preg_match('@^https?://(.*)$@i', $item, $matches) ? $matches[1] : $item; }, $db_info->embed_white_object)); natcasesort($whitelist); - $config['embedfilter']['object'] = $whitelist; + $config['mediafilter']['object'] = $whitelist; } // Convert miscellaneous configuration. diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index 201b13756..023cd7586 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -556,26 +556,31 @@ class adminAdminController extends admin $vars = Context::getRequestVars(); // iframe filter - $embed_iframe = $vars->embedfilter_iframe; - $embed_iframe = array_filter(array_map('trim', preg_split('/[\r\n]/', $embed_iframe)), function($item) { + $iframe_whitelist = $vars->mediafilter_iframe; + $iframe_whitelist = array_filter(array_map('trim', preg_split('/[\r\n]/', $iframe_whitelist)), function($item) { return $item !== ''; }); - $embed_iframe = array_unique(array_map(function($item) { + $iframe_whitelist = array_unique(array_map(function($item) { return preg_match('@^https?://(.*)$@i', $item, $matches) ? $matches[1] : $item; - }, $embed_iframe)); - natcasesort($embed_iframe); - Rhymix\Framework\Config::set('embedfilter.iframe', array_values($embed_iframe)); + }, $iframe_whitelist)); + natcasesort($iframe_whitelist); + Rhymix\Framework\Config::set('mediafilter.iframe', array_values($iframe_whitelist)); // object filter - $embed_object = $vars->embedfilter_object; - $embed_object = array_filter(array_map('trim', preg_split('/[\r\n]/', $embed_object)), function($item) { + $object_whitelist = $vars->mediafilter_object; + $object_whitelist = array_filter(array_map('trim', preg_split('/[\r\n]/', $object_whitelist)), function($item) { return $item !== ''; }); - $embed_object = array_unique(array_map(function($item) { + $object_whitelist = array_unique(array_map(function($item) { return preg_match('@^https?://(.*)$@i', $item, $matches) ? $matches[1] : $item; - }, $embed_object)); - natcasesort($embed_object); - Rhymix\Framework\Config::set('embedfilter.object', array_values($embed_object)); + }, $object_whitelist)); + natcasesort($object_whitelist); + Rhymix\Framework\Config::set('mediafilter.object', array_values($object_whitelist)); + + // Remove old embed filter + $config = Rhymix\Framework\Config::getAll(); + unset($config['embedfilter']); + Rhymix\Framework\Config::setAll($config); // Admin IP access control $allowed_ip = array_map('trim', preg_split('/[\r\n]/', $vars->admin_allowed_ip)); diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index fbe68f961..2ff837e00 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -418,9 +418,8 @@ class adminAdminView extends admin function dispAdminConfigSecurity() { // Load embed filter. - $oEmbedFilter = EmbedFilter::getInstance(); - context::set('embedfilter_iframe', implode(PHP_EOL, $oEmbedFilter->whiteIframeUrlList)); - context::set('embedfilter_object', implode(PHP_EOL, $oEmbedFilter->whiteUrlList)); + context::set('mediafilter_iframe', implode(PHP_EOL, Rhymix\Framework\Security\MediaFilter::getIframeWhitelist())); + context::set('mediafilter_object', implode(PHP_EOL, Rhymix\Framework\Security\MediaFilter::getObjectWhitelist())); // Admin IP access control $allowed_ip = Rhymix\Framework\Config::get('admin.allow'); diff --git a/modules/admin/tpl/config_security.html b/modules/admin/tpl/config_security.html index ff81ba143..a8050b94c 100644 --- a/modules/admin/tpl/config_security.html +++ b/modules/admin/tpl/config_security.html @@ -8,15 +8,15 @@
    - +
    - +
    - +
    - +
    From 0adb13ca30a37e5d358b7ab62eab16fd27b5784d Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 10:18:52 +0900 Subject: [PATCH 147/318] Add inRanges() and validateRanges() methods to IpFilter class --- classes/context/Context.class.php | 8 ++--- classes/security/IpFilter.class.php | 18 ++---------- common/framework/debug.php | 8 ++--- common/framework/ipfilter.php | 37 ++++++++++++++++++++++++ modules/admin/admin.admin.controller.php | 23 ++++----------- modules/admin/admin.admin.view.php | 17 ++--------- modules/member/member.admin.model.php | 18 ++---------- 7 files changed, 52 insertions(+), 77 deletions(-) diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 66c11a077..4a47369e1 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -1478,13 +1478,9 @@ class Context } // Allow if the current user is in the list of allowed IPs. - $allowed_list = config('lock.allow'); - foreach ($allowed_list as $allowed_ip) + if (Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, config('lock.allow'))) { - if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $allowed_ip)) - { - return; - } + return; } // Set headers and constants for backward compatibility. diff --git a/classes/security/IpFilter.class.php b/classes/security/IpFilter.class.php index ea49b8195..455485329 100644 --- a/classes/security/IpFilter.class.php +++ b/classes/security/IpFilter.class.php @@ -6,26 +6,12 @@ class IpFilter public function filter($ip_list, $ip = NULL) { if(!$ip) $ip = $_SERVER['REMOTE_ADDR']; - foreach($ip_list as $filter) - { - if(Rhymix\Framework\IpFilter::inRange($ip, $filter)) - { - return true; - } - } - return false; + return Rhymix\Framework\IpFilter::inRanges($ip, $ip_list); } public function validate($ip_list = array()) { - foreach($ip_list as $filter) - { - if(!Rhymix\Framework\IpFilter::validateRange($filter)) - { - return false; - } - } - return true; + return Rhymix\Framework\IpFilter::validateRanges($ip_list); } } diff --git a/common/framework/debug.php b/common/framework/debug.php index b3653a943..dd2cee5a4 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -445,13 +445,9 @@ class Debug return $cache = true; case 'ip': - $allowed_ip = Config::get('debug.allow'); - foreach ($allowed_ip as $range) + if (IpFilter::inRanges(RX_CLIENT_IP, Config::get('debug.allow'))) { - if (IpFilter::inRange(RX_CLIENT_IP, $range)) - { - return $cache = true; - } + return $cache = true; } return $cache = false; diff --git a/common/framework/ipfilter.php b/common/framework/ipfilter.php index 21a087256..e80170974 100644 --- a/common/framework/ipfilter.php +++ b/common/framework/ipfilter.php @@ -66,6 +66,25 @@ class IpFilter } } + /** + * Check whether the given IP address belongs to a set of ranges. + * + * @param string $ip + * @param array $ranges + * @return bool + */ + public static function inRanges($ip, array $ranges) + { + foreach ($ranges as $range) + { + if (self::inRange($ip, $range)) + { + return true; + } + } + return false; + } + /** * Check whether a range definition is valid. * @@ -91,6 +110,24 @@ class IpFilter return false; } + /** + * Check whether a set of range definitions is valid. + * + * @param array $ranges + * @return bool + */ + public static function validateRanges(array $ranges) + { + foreach ($ranges as $range) + { + if (!self::validateRange($range)) + { + return false; + } + } + return true; + } + /** * Get real IP from CloudFlare headers. * diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index 023cd7586..50c4f431e 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -587,7 +587,7 @@ class adminAdminController extends admin $allowed_ip = array_unique(array_filter($allowed_ip, function($item) { return $item !== ''; })); - if (!IpFilter::validate($whitelist)) { + if (!Rhymix\Framework\IpFilter::validateRanges($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } @@ -595,7 +595,7 @@ class adminAdminController extends admin $denied_ip = array_unique(array_filter($denied_ip, function($item) { return $item !== ''; })); - if (!IpFilter::validate($whitelist)) { + if (!Rhymix\Framework\IpFilter::validateRanges($denied_ip)) { return new Object(-1, 'msg_invalid_ip'); } @@ -771,30 +771,17 @@ class adminAdminController extends admin if ($vars->sitelock_locked === 'Y') { - $allowed_localhost = false; - $allowed_current = false; - foreach ($allowed_ip as $range) - { - if (Rhymix\Framework\IpFilter::inRange('127.0.0.1', $range)) - { - $allowed_localhost = true; - } - if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $range)) - { - $allowed_current = true; - } - } - if (!$allowed_localhost) + if (!Rhymix\Framework\IpFilter::inRanges('127.0.0.1', $allowed_ip)) { array_unshift($allowed_ip, '127.0.0.1'); } - if (!$allowed_current) + if (!Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) { array_unshift($allowed_ip, RX_CLIENT_IP); } } - if (!IpFilter::validate($whitelist)) + if (!Rhymix\Framework\IpFilter::validateRanges($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index 2ff837e00..6cac017c9 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -518,24 +518,11 @@ class adminAdminView extends admin Context::set('sitelock_message', escape(Rhymix\Framework\Config::get('lock.message'))); $allowed_ip = Rhymix\Framework\Config::get('lock.allow') ?: array(); - $allowed_localhost = false; - $allowed_current = false; - foreach ($allowed_ip as $range) - { - if (Rhymix\Framework\IpFilter::inRange('127.0.0.1', $range)) - { - $allowed_localhost = true; - } - if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $range)) - { - $allowed_current = true; - } - } - if (!$allowed_localhost) + if (!Rhymix\Framework\IpFilter::inRanges('127.0.0.1', $allowed_ip)) { array_unshift($allowed_ip, '127.0.0.1'); } - if (!$allowed_current) + if (!Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) { array_unshift($allowed_ip, RX_CLIENT_IP); } diff --git a/modules/member/member.admin.model.php b/modules/member/member.admin.model.php index 9bca07a60..0c0c59887 100644 --- a/modules/member/member.admin.model.php +++ b/modules/member/member.admin.model.php @@ -298,26 +298,12 @@ class memberAdminModel extends member { if ($allow_list = ($allow_list === null) ? config('admin.allow') : $allow_list) { - foreach ($allow_list as $range) - { - if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $range)) - { - return true; - } - } - return false; + return Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $allow_list); } if ($deny_list = ($deny_list === null) ? config('admin.deny') : $deny_list) { - foreach ($deny_list as $range) - { - if (Rhymix\Framework\IpFilter::inRange(RX_CLIENT_IP, $range)) - { - return false; - } - } - return true; + return !Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $deny_list); } return true; From 544170b530c035a08113b6374af00e5d304fbafc Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 10:24:52 +0900 Subject: [PATCH 148/318] Move IpFilter class to Security namespace --- classes/context/Context.class.php | 2 +- classes/security/IpFilter.class.php | 4 +- common/constants.php | 4 +- common/framework/debug.php | 2 +- common/framework/{ => security}/ipfilter.php | 2 +- modules/admin/admin.admin.controller.php | 12 +-- modules/admin/admin.admin.view.php | 4 +- modules/member/member.admin.model.php | 4 +- tests/unit/framework/IpFilterTest.php | 77 ------------------- .../unit/framework/security/IpFilterTest.php | 77 +++++++++++++++++++ 10 files changed, 94 insertions(+), 94 deletions(-) rename common/framework/{ => security}/ipfilter.php (99%) delete mode 100644 tests/unit/framework/IpFilterTest.php create mode 100644 tests/unit/framework/security/IpFilterTest.php diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 4a47369e1..44ec47d6d 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -1478,7 +1478,7 @@ class Context } // Allow if the current user is in the list of allowed IPs. - if (Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, config('lock.allow'))) + if (Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, config('lock.allow'))) { return; } diff --git a/classes/security/IpFilter.class.php b/classes/security/IpFilter.class.php index 455485329..23159dc79 100644 --- a/classes/security/IpFilter.class.php +++ b/classes/security/IpFilter.class.php @@ -6,12 +6,12 @@ class IpFilter public function filter($ip_list, $ip = NULL) { if(!$ip) $ip = $_SERVER['REMOTE_ADDR']; - return Rhymix\Framework\IpFilter::inRanges($ip, $ip_list); + return Rhymix\Framework\Security\IpFilter::inRanges($ip, $ip_list); } public function validate($ip_list = array()) { - return Rhymix\Framework\IpFilter::validateRanges($ip_list); + return Rhymix\Framework\Security\IpFilter::validateRanges($ip_list); } } diff --git a/common/constants.php b/common/constants.php index cab1fd256..d3d992896 100644 --- a/common/constants.php +++ b/common/constants.php @@ -53,8 +53,8 @@ else */ if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])) { - include_once __DIR__ . '/framework/ipfilter.php'; - Rhymix\Framework\IpFilter::getCloudFlareRealIP(); + include_once __DIR__ . '/framework/security/ipfilter.php'; + Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP(); } if (isset($_SERVER['REMOTE_ADDR']) && preg_match('/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/', $_SERVER['REMOTE_ADDR'], $matches)) { diff --git a/common/framework/debug.php b/common/framework/debug.php index dd2cee5a4..4c69a4484 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -445,7 +445,7 @@ class Debug return $cache = true; case 'ip': - if (IpFilter::inRanges(RX_CLIENT_IP, Config::get('debug.allow'))) + if (Security\IpFilter::inRanges(RX_CLIENT_IP, Config::get('debug.allow'))) { return $cache = true; } diff --git a/common/framework/ipfilter.php b/common/framework/security/ipfilter.php similarity index 99% rename from common/framework/ipfilter.php rename to common/framework/security/ipfilter.php index e80170974..b52f13ac1 100644 --- a/common/framework/ipfilter.php +++ b/common/framework/security/ipfilter.php @@ -1,6 +1,6 @@ sitelock_locked === 'Y') { - if (!Rhymix\Framework\IpFilter::inRanges('127.0.0.1', $allowed_ip)) + if (!Rhymix\Framework\Security\IpFilter::inRanges('127.0.0.1', $allowed_ip)) { array_unshift($allowed_ip, '127.0.0.1'); } - if (!Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) + if (!Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) { array_unshift($allowed_ip, RX_CLIENT_IP); } } - if (!Rhymix\Framework\IpFilter::validateRanges($allowed_ip)) + if (!Rhymix\Framework\Security\IpFilter::validateRanges($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index 6cac017c9..a74801f38 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -518,11 +518,11 @@ class adminAdminView extends admin Context::set('sitelock_message', escape(Rhymix\Framework\Config::get('lock.message'))); $allowed_ip = Rhymix\Framework\Config::get('lock.allow') ?: array(); - if (!Rhymix\Framework\IpFilter::inRanges('127.0.0.1', $allowed_ip)) + if (!Rhymix\Framework\Security\IpFilter::inRanges('127.0.0.1', $allowed_ip)) { array_unshift($allowed_ip, '127.0.0.1'); } - if (!Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) + if (!Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) { array_unshift($allowed_ip, RX_CLIENT_IP); } diff --git a/modules/member/member.admin.model.php b/modules/member/member.admin.model.php index 0c0c59887..8e9682bb6 100644 --- a/modules/member/member.admin.model.php +++ b/modules/member/member.admin.model.php @@ -298,12 +298,12 @@ class memberAdminModel extends member { if ($allow_list = ($allow_list === null) ? config('admin.allow') : $allow_list) { - return Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $allow_list); + return Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $allow_list); } if ($deny_list = ($deny_list === null) ? config('admin.deny') : $deny_list) { - return !Rhymix\Framework\IpFilter::inRanges(RX_CLIENT_IP, $deny_list); + return !Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $deny_list); } return true; diff --git a/tests/unit/framework/IpFilterTest.php b/tests/unit/framework/IpFilterTest.php deleted file mode 100644 index 13bb96318..000000000 --- a/tests/unit/framework/IpFilterTest.php +++ /dev/null @@ -1,77 +0,0 @@ -assertTrue(Rhymix\Framework\IpFilter::inRange('10.0.127.191', '10.0.127.191')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('10.1.131.177', '10.1.131.178')); - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('127.0.0.1', '127.0.0.0/8')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('172.34.0.0', '172.16.0.0/12')); - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('192.168.18.214', '192.168.16.0/22')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('192.168.18.214', '192.168.16.0/23')); - } - - public function testIPv6CIDR() - { - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('::1', '::1/128')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('::1', '::2')); - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('2400:cb00::1234', '2400:cb00::/32')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('2405:8100::1234', '2400:cb00::/32')); - } - - public function testIPv4Wildcard() - { - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.134.*')); - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.*.*')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.136.*')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.172.*.*')); - } - - public function testIPv4Hyphen() - { - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.134.0-192.168.134.255')); - $this->assertTrue(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.128.16-192.168.145.0')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.134.242-192.168.244.7')); - $this->assertFalse(Rhymix\Framework\IpFilter::inRange('192.168.134.241', '192.168.100.255-192.168.133.19')); - } - - public function testValidator() - { - $this->assertTrue(Rhymix\Framework\IpFilter::validateRange('192.168.0.1')); - $this->assertTrue(Rhymix\Framework\IpFilter::validateRange('192.168.0.0/16')); - $this->assertTrue(Rhymix\Framework\IpFilter::validateRange('192.168.*.*')); - $this->assertTrue(Rhymix\Framework\IpFilter::validateRange('192.168.*')); - $this->assertTrue(Rhymix\Framework\IpFilter::validateRange('192.168.0.0-192.168.255.255')); - $this->assertTrue(Rhymix\Framework\IpFilter::validateRange('2400:cb00::/32')); - $this->assertFalse(Rhymix\Framework\IpFilter::validateRange('192.168.0.0~192.168.255.255')); - } - - public function testLegacy() - { - $this->assertTrue(\IpFilter::filter(array('192.168.134.241'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('192.168.134.0-192.168.134.255'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('127.0.0.1', '192.168.134.241'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('192.168.134.*'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('192.168.*'), '192.168.134.241')); - $this->assertFalse(\IpFilter::filter(array('127.0.0.1'), '192.168.134.241')); - } - - public function testCloudFlareRealIP() - { - $_SERVER['HTTP_CF_CONNECTING_IP'] = '192.168.134.241'; - - $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; - $this->assertFalse(Rhymix\Framework\IpFilter::getCloudFlareRealIP()); - $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); - - $_SERVER['REMOTE_ADDR'] = '108.162.192.121'; - $this->assertEquals('192.168.134.241', Rhymix\Framework\IpFilter::getCloudFlareRealIP()); - $this->assertEquals('192.168.134.241', $_SERVER['REMOTE_ADDR']); - - unset($_SERVER['HTTP_CF_CONNECTING_IP']); - $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; - $this->assertFalse(Rhymix\Framework\IpFilter::getCloudFlareRealIP()); - $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); - } -} diff --git a/tests/unit/framework/security/IpFilterTest.php b/tests/unit/framework/security/IpFilterTest.php new file mode 100644 index 000000000..235939253 --- /dev/null +++ b/tests/unit/framework/security/IpFilterTest.php @@ -0,0 +1,77 @@ +assertTrue(Rhymix\Framework\Security\IpFilter::inRange('10.0.127.191', '10.0.127.191')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('10.1.131.177', '10.1.131.178')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('127.0.0.1', '127.0.0.0/8')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('172.34.0.0', '172.16.0.0/12')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.18.214', '192.168.16.0/22')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.18.214', '192.168.16.0/23')); + } + + public function testIPv6CIDR() + { + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('::1', '::1/128')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('::1', '::2')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('2400:cb00::1234', '2400:cb00::/32')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('2405:8100::1234', '2400:cb00::/32')); + } + + public function testIPv4Wildcard() + { + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.134.*')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.*.*')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.136.*')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.172.*.*')); + } + + public function testIPv4Hyphen() + { + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.134.0-192.168.134.255')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.128.16-192.168.145.0')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.134.242-192.168.244.7')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.100.255-192.168.133.19')); + } + + public function testValidator() + { + $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.1')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.0/16')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.*.*')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.*')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.0-192.168.255.255')); + $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('2400:cb00::/32')); + $this->assertFalse(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.0~192.168.255.255')); + } + + public function testLegacy() + { + $this->assertTrue(\IpFilter::filter(array('192.168.134.241'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('192.168.134.0-192.168.134.255'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('127.0.0.1', '192.168.134.241'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('192.168.134.*'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('192.168.*'), '192.168.134.241')); + $this->assertFalse(\IpFilter::filter(array('127.0.0.1'), '192.168.134.241')); + } + + public function testCloudFlareRealIP() + { + $_SERVER['HTTP_CF_CONNECTING_IP'] = '192.168.134.241'; + + $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; + $this->assertFalse(Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP()); + $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); + + $_SERVER['REMOTE_ADDR'] = '108.162.192.121'; + $this->assertEquals('192.168.134.241', Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP()); + $this->assertEquals('192.168.134.241', $_SERVER['REMOTE_ADDR']); + + unset($_SERVER['HTTP_CF_CONNECTING_IP']); + $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; + $this->assertFalse(Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP()); + $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); + } +} From 90dcc4a2e849eb84a04cf30f63d33184af7395e4 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 20:40:23 +0900 Subject: [PATCH 149/318] Implement encryption, decryption, and CSPRNG in Security class --- classes/security/Password.class.php | 101 +----------- common/framework/security.php | 219 ++++++++++++++++++++++++++ common/libraries/cryptocompat.php | 4 +- tests/unit/framework/SecurityTest.php | 74 +++++++++ 4 files changed, 301 insertions(+), 97 deletions(-) diff --git a/classes/security/Password.class.php b/classes/security/Password.class.php index 93e87f0e1..fa39fd906 100644 --- a/classes/security/Password.class.php +++ b/classes/security/Password.class.php @@ -173,22 +173,22 @@ class Password $hash = explode(':', $hash); $hash[3] = base64_decode($hash[3]); $hash_to_compare = $this->pbkdf2($password, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3])); - return $this->strcmpConstantTime($hash_to_compare, $hash[3]); + return Rhymix\Framework\Security::compareStrings($hash_to_compare, $hash[3]); case 'bcrypt': $hash_to_compare = $this->bcrypt($password, $hash); - return $this->strcmpConstantTime($hash_to_compare, $hash); + return Rhymix\Framework\Security::compareStrings($hash_to_compare, $hash); default: if($algorithm && isset(self::$_custom[$algorithm])) { $hash_callback = self::$_custom[$algorithm]['callback']; $hash_to_compare = $hash_callback($password, $hash); - return $this->strcmpConstantTime($hash_to_compare, $hash); + return Rhymix\Framework\Security::compareStrings($hash_to_compare, $hash); } if(in_array($algorithm, hash_algos())) { - return $this->strcmpConstantTime(hash($algorithm, $password), $hash); + return Rhymix\Framework\Security::compareStrings(hash($algorithm, $password), $hash); } return false; } @@ -280,90 +280,7 @@ class Password */ public function createSecureSalt($length, $format = 'hex') { - // Find out how many bytes of entropy we really need - switch($format) - { - case 'hex': - $entropy_required_bytes = ceil($length / 2); - break; - case 'alnum': - case 'printable': - $entropy_required_bytes = ceil($length * 3 / 4); - break; - default: - $entropy_required_bytes = $length; - } - - // Cap entropy to 256 bits from any one source, because anything more is meaningless - $entropy_capped_bytes = min(32, $entropy_required_bytes); - - // Find and use the most secure way to generate a random string - $entropy = false; - $is_windows = (defined('PHP_OS') && strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'); - if(function_exists('random_bytes')) // PHP 7 - { - $entropy = random_bytes($entropy_capped_bytes); - } - elseif(function_exists('openssl_random_pseudo_bytes') && (!$is_windows || version_compare(PHP_VERSION, '5.4', '>='))) - { - $entropy = openssl_random_pseudo_bytes($entropy_capped_bytes); - } - elseif(function_exists('mcrypt_create_iv') && (!$is_windows || version_compare(PHP_VERSION, '5.3.7', '>='))) - { - $entropy = mcrypt_create_iv($entropy_capped_bytes, MCRYPT_DEV_URANDOM); - } - elseif(function_exists('mcrypt_create_iv') && $is_windows) - { - $entropy = mcrypt_create_iv($entropy_capped_bytes, MCRYPT_RAND); - } - elseif(!$is_windows && @is_readable('/dev/urandom')) - { - $fp = fopen('/dev/urandom', 'rb'); - if (function_exists('stream_set_read_buffer')) // This function does not exist in HHVM - { - stream_set_read_buffer($fp, 0); // Prevent reading several KB of unnecessary data from urandom - } - $entropy = fread($fp, $entropy_capped_bytes); - fclose($fp); - } - - // Use built-in source of entropy if an error occurs while using other functions - if($entropy === false || strlen($entropy) < $entropy_capped_bytes) - { - $entropy = ''; - for($i = 0; $i < $entropy_capped_bytes; $i += 2) - { - $entropy .= pack('S', rand(0, 65536) ^ mt_rand(0, 65535)); - } - } - - // Mixing (see RFC 4086 section 5) - $output = ''; - for($i = 0; $i < $entropy_required_bytes; $i += 32) - { - $output .= hash('sha256', $entropy . $i . rand(), true); - } - - // Encode and return the random string - switch($format) - { - case 'hex': - return substr(bin2hex($output), 0, $length); - case 'binary': - return substr($output, 0, $length); - case 'printable': - $salt = ''; - for($i = 0; $i < $length; $i++) - { - $salt .= chr(33 + (crc32(sha1($i . $output)) % 94)); - } - return $salt; - case 'alnum': - default: - $salt = substr(base64_encode($output), 0, $length); - $replacements = chr(rand(65, 90)) . chr(rand(97, 122)) . rand(0, 9); - return strtr($salt, '+/=', $replacements); - } + return Rhymix\Framework\Security::getRandom($length, $format); } /** @@ -446,13 +363,7 @@ class Password */ function strcmpConstantTime($a, $b) { - $diff = strlen($a) ^ strlen($b); - $maxlen = min(strlen($a), strlen($b)); - for($i = 0; $i < $maxlen; $i++) - { - $diff |= ord($a[$i]) ^ ord($b[$i]); - } - return $diff === 0; + return Rhymix\Framework\Security::compareStrings($a, $b); } } /* End of file : Password.class.php */ diff --git a/common/framework/security.php b/common/framework/security.php index 5521fca39..4bae27c39 100644 --- a/common/framework/security.php +++ b/common/framework/security.php @@ -43,6 +43,225 @@ class Security } } + /** + * Encrypt a string using AES. + * + * @param string $plaintext + * @param string $key (optional) + * @param bool $force_compat (optional) + * @return string|false + */ + public static function encrypt($plaintext, $key = null, $force_compat = false) + { + // Get the encryption key. + $key = $key ?: config('crypto.encryption_key'); + $key = substr(hash('sha256', $key, true), 0, 16); + + // Use defuse/php-encryption if possible. + if (!$force_compat && version_compare(\PHP_VERSION, '5.4.0', '>=') && function_exists('openssl_encrypt')) + { + try + { + return base64_encode(\Crypto::Encrypt($plaintext, $key)); + } + catch (\Exception $e) + { + return false; + } + } + + // Otherwise, use the CryptoCompat class. + return base64_encode(\CryptoCompat::encrypt($plaintext, $key)); + } + + /** + * Decrypt a string using AES. + * + * @param string $plaintext + * @param string $key (optional) + * @param bool $force_compat (optional) + * @return string|false + */ + public static function decrypt($ciphertext, $key = null, $force_compat = false) + { + // Get the encryption key. + $key = $key ?: config('crypto.encryption_key'); + $key = substr(hash('sha256', $key, true), 0, 16); + + // Check whether the ciphertext is valid. + $ciphertext = @base64_decode($ciphertext); + if (strlen($ciphertext) < 48) + { + return false; + } + + // Use defuse/php-encryption if possible. + if (!$force_compat && version_compare(\PHP_VERSION, '5.4.0', '>=') && function_exists('openssl_decrypt')) + { + try + { + return \Crypto::Decrypt($ciphertext, $key); + } + catch (\Exception $e) + { + return false; + } + } + + // Otherwise, use the CryptoCompat class. + return \CryptoCompat::decrypt($ciphertext, $key); + } + + /** + * Generate a cryptographically secure random string. + * + * @param int $length + * @param string $format + * @return string + */ + public function getRandom($length = 32, $format = 'alnum') + { + // Find out how many bytes of entropy we really need. + switch($format) + { + case 'binary': + $entropy_required_bytes = $length; + break; + case 'hex': + $entropy_required_bytes = ceil($length / 2); + break; + case 'alnum': + case 'printable': + default: + $entropy_required_bytes = ceil($length * 3 / 4); + break; + } + + // Cap entropy to 256 bits from any one source, because anything more is meaningless. + $entropy_capped_bytes = min(32, $entropy_required_bytes); + + // Find and use the most secure way to generate a random string. + $entropy = false; + $is_windows = (defined('\PHP_OS') && strtoupper(substr(\PHP_OS, 0, 3)) === 'WIN'); + if(function_exists('random_bytes')) // PHP 7 + { + $entropy = random_bytes($entropy_capped_bytes); + } + elseif(function_exists('openssl_random_pseudo_bytes') && (!$is_windows || version_compare(\PHP_VERSION, '5.4', '>='))) + { + $entropy = openssl_random_pseudo_bytes($entropy_capped_bytes); + } + elseif(function_exists('mcrypt_create_iv') && (!$is_windows || version_compare(\PHP_VERSION, '5.3.7', '>='))) + { + $entropy = mcrypt_create_iv($entropy_capped_bytes, \MCRYPT_DEV_URANDOM); + } + elseif(function_exists('mcrypt_create_iv') && $is_windows) + { + $entropy = mcrypt_create_iv($entropy_capped_bytes, \MCRYPT_RAND); + } + elseif(!$is_windows && @is_readable('/dev/urandom')) + { + $fp = fopen('/dev/urandom', 'rb'); + if (function_exists('stream_set_read_buffer')) // This function does not exist in HHVM. + { + stream_set_read_buffer($fp, 0); // Prevent reading several KB of unnecessary data from urandom. + } + $entropy = fread($fp, $entropy_capped_bytes); + fclose($fp); + } + + // Use built-in source of entropy if an error occurs while using other functions. + if($entropy === false || strlen($entropy) < $entropy_capped_bytes) + { + $entropy = ''; + for($i = 0; $i < $entropy_capped_bytes; $i += 2) + { + $entropy .= pack('S', rand(0, 65536) ^ mt_rand(0, 65535)); + } + } + + // Mixing (see RFC 4086 section 5) + $output = ''; + for($i = 0; $i < $entropy_required_bytes; $i += 32) + { + $output .= hash('sha256', $entropy . $i . rand(), true); + } + + // Encode and return the random string. + switch($format) + { + case 'binary': + return substr($output, 0, $length); + case 'printable': + $salt = ''; + for($i = 0; $i < $length; $i++) + { + $salt .= chr(33 + (crc32(sha1($i . $output)) % 94)); + } + return $salt; + case 'hex': + return substr(bin2hex($output), 0, $length); + case 'alnum': + default: + $salt = substr(base64_encode($output), 0, $length); + $replacements = chr(rand(65, 90)) . chr(rand(97, 122)) . rand(0, 9); + return strtr($salt, '+/=', $replacements); + } + } + + /** + * Generate a cryptographically secure random number between $min and $max. + * + * @param int $min + * @param int $max + * @return int + */ + public static function getRandomNumber($min = 0, $max = 0x7fffffff) + { + if (function_exists('random_int')) + { + return random_int($min, $max); + } + else + { + $bytes_required = min(4, ceil(log($max - $min, 2) / 8) + 1); + $bytes = self::getRandom($bytes_required, 'binary'); + $offset = abs(hexdec(bin2hex($bytes)) % ($max - $min + 1)); + return intval($min + $offset); + } + } + + /** + * Generate a random UUID. + * + * @return string + */ + public static function getRandomUUID() + { + $randpool = self::getRandom(16, 'binary'); + $randpool[6] = chr(ord($randpool[6]) & 0x0f | 0x40); + $randpool[8] = chr(ord($randpool[8]) & 0x3f | 0x80); + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($randpool), 4)); + } + + /** + * Compare two strings in constant time. + * + * @param string $a + * @param string $b + * @return bool + */ + public static function compareStrings($a, $b) + { + $diff = strlen($a) ^ strlen($b); + $maxlen = min(strlen($a), strlen($b)); + for($i = 0; $i < $maxlen; $i++) + { + $diff |= ord($a[$i]) ^ ord($b[$i]); + } + return $diff === 0; + } + /** * Check if the current request seems to be a CSRF attack. * diff --git a/common/libraries/cryptocompat.php b/common/libraries/cryptocompat.php index 0bebc5f2a..0c2645004 100644 --- a/common/libraries/cryptocompat.php +++ b/common/libraries/cryptocompat.php @@ -49,7 +49,7 @@ class CryptoCompat // Validate MAC $mac_key = self::_defuseCompatibleHKDF($key, self::ENCRYPTION_MAC_INFO); $mac_compare = hash_hmac(self::ENCRYPTION_MAC_ALGO, ($iv . $ciphertext), $mac_key, true); - if (!Password::strcmpConstantTime($mac, $mac_compare)) + if (!Rhymix\Framework\Security::compareStrings($mac, $mac_compare)) { return false; } @@ -80,7 +80,7 @@ class CryptoCompat */ protected static function _createIV() { - return hex2bin(Password::createSecureSalt(self::ENCRYPTION_BLOCK_SIZE * 2, 'hex')); + return Rhymix\Framework\Security::getRandom(self::ENCRYPTION_BLOCK_SIZE, 'binary'); } /** diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index 91e1f3740..23d658a0f 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -17,6 +17,80 @@ class SecurityTest extends \Codeception\TestCase\Test $this->assertEquals('foo(bar).xls', Rhymix\Framework\Security::sanitize('foo.xls', 'filename')); } + public function testEncryption() + { + $plaintext = Rhymix\Framework\Security::getRandom(); + + // Encryption with default key. + $encrypted = Rhymix\Framework\Security::encrypt($plaintext); + $this->assertNotEquals(false, $encrypted); + $decrypted = Rhymix\Framework\Security::decrypt($encrypted); + $this->assertEquals($plaintext, $decrypted); + + // Encryption with custom key. + $key = Rhymix\Framework\Security::getRandom(); + $encrypted = Rhymix\Framework\Security::encrypt($plaintext, $key); + $this->assertNotEquals(false, $encrypted); + $decrypted = Rhymix\Framework\Security::decrypt($encrypted, $key); + $this->assertEquals($plaintext, $decrypted); + + // Encryption with defuse/php-encryption and decryption with CryptoCompat. + $encrypted = Rhymix\Framework\Security::encrypt($plaintext); + $this->assertNotEquals(false, $encrypted); + $decrypted = Rhymix\Framework\Security::decrypt($encrypted, null, true); + $this->assertEquals($plaintext, $decrypted); + + // Encryption with CryptoCompat and decryption with defuse/php-encryption. + $encrypted = Rhymix\Framework\Security::encrypt($plaintext, null, true); + $this->assertNotEquals(false, $encrypted); + $decrypted = Rhymix\Framework\Security::decrypt($encrypted); + $this->assertEquals($plaintext, $decrypted); + + // Test invalid ciphertext. + $decrypted = Rhymix\Framework\Security::decrypt('1234' . substr($encrypted, 4)); + $this->assertEquals(false, $decrypted); + $decrypted = Rhymix\Framework\Security::decrypt(substr($encrypted, strlen($encrypted) - 4) . 'abcd'); + $this->assertEquals(false, $decrypted); + $decrypted = Rhymix\Framework\Security::decrypt($plaintext); + $this->assertEquals(false, $decrypted); + } + + public function testGetRandom() + { + $this->assertEquals(1, preg_match('/^[0-9a-zA-Z]{32}$/', Rhymix\Framework\Security::getRandom())); + $this->assertEquals(1, preg_match('/^[0-9a-zA-Z]{256}$/', Rhymix\Framework\Security::getRandom(256))); + $this->assertEquals(1, preg_match('/^[0-9a-zA-Z]{16}$/', Rhymix\Framework\Security::getRandom(16, 'alnum'))); + $this->assertEquals(1, preg_match('/^[0-9a-f]{16}$/', Rhymix\Framework\Security::getRandom(16, 'hex'))); + $this->assertEquals(1, preg_match('/^[\x21-\x7e]{16}$/', Rhymix\Framework\Security::getRandom(16, 'printable'))); + } + + public function testGetRandomNumber() + { + for ($i = 0; $i < 10; $i++) + { + $min = mt_rand(0, 10000); + $max = $min + mt_rand(0, 10000); + $random = Rhymix\Framework\Security::getRandomNumber($min, $max); + $this->assertTrue($random >= $min && $random < $max); + } + } + + public function testGetRandomUUID() + { + $regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; + for ($i = 0; $i < 10; $i++) + { + $this->assertEquals(1, preg_match($regex, Rhymix\Framework\Security::getRandomUUID())); + } + } + + public function testCompareStrings() + { + $this->assertTrue(Rhymix\Framework\Security::compareStrings('foobar', 'foobar')); + $this->assertFalse(Rhymix\Framework\Security::compareStrings('foobar', 'foobar*')); + $this->assertFalse(Rhymix\Framework\Security::compareStrings('foo', 'bar')); + } + public function testCheckCSRF() { $_SERVER['REQUEST_METHOD'] = 'GET'; From 647bc7c112acadd20ffd82af73da428190e6180e Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 22:08:56 +0900 Subject: [PATCH 150/318] Implement new Password class and related unit tests --- common/framework/password.php | 443 ++++++++++++++++++++++++++ common/libraries/vendorpass.php | 6 +- tests/unit/framework/PasswordTest.php | 127 ++++++++ tests/unit/framework/SecurityTest.php | 12 +- 4 files changed, 579 insertions(+), 9 deletions(-) create mode 100644 common/framework/password.php create mode 100644 tests/unit/framework/PasswordTest.php diff --git a/common/framework/password.php b/common/framework/password.php new file mode 100644 index 000000000..2e4e67017 --- /dev/null +++ b/common/framework/password.php @@ -0,0 +1,443 @@ + '/^\$2[a-z]\$[0-9]{2}\$/', + 'pbkdf2' => '/^[a-z0-9]+:[0-9]+:/', + 'md5' => '/^[0-9a-f]{32}$/', + 'md5,sha1,md5' => '/^[0-9a-f]{32}$/', + 'sha1' => '/^[0-9a-f]{40}$/', + 'sha256' => '/^[0-9a-f]{64}$/', + 'sha384' => '/^[0-9a-f]{96}$/', + 'sha512' => '/^[0-9a-f]{128}$/', + 'ripemd160' => '/^[0-9a-f]{40}$/', + 'whirlpool' => '/^[0-9a-f]{128}$/', + 'mssql_pwdencrypt' => '/^0x0100[0-9A-F]{48}$/', + 'mysql_old_password' => '/^[0-9a-f]{16}$/', + 'mysql_new_password' => '/^\*[0-9A-F]{40}$/', + 'portable' => '/^\$P\$/', + 'drupal' => '/^\$S\$/', + 'joomla' => '/^[0-9a-f]{32}:[0-9a-zA-Z\.\+\/\=]{32}$/', + 'kimsqrb' => '/\$[1-4]\$[0-9]{14}$/', + 'crypt' => '/^([0-9a-zA-Z\.\/]{13}$|_[0-9a-zA-Z\.\/]{19}$|\$[156]\$)/', + ); + + /** + * Add a custom algorithm. + * + * @param string $name + * @param string $signature + * @param callable $callback + * @return void + */ + public static function addAlgorithm($name, $signature, $callback) + { + self::$_algorithm_signatures[$name] = $signature; + self::$_algorithm_callbacks[$name] = $callback; + } + + /** + * Check if the given sequence of algorithms is valid. + * + * @param array|string $algos + * @return bool + */ + public static function isValidAlgorithm($algos) + { + $hash_algos = hash_algos(); + $algos = is_array($algos) ? $algos : explode(',', $algos); + foreach ($algos as $algo) + { + if (array_key_exists($algo, self::$_algorithm_signatures)) + { + continue; + } + if (in_array($algo, $hash_algos)) + { + continue; + } + return false; + } + return true; + } + + /** + * Get the list of hashing algorithms supported by this server. + * + * @return array + */ + public static function getSupportedAlgorithms() + { + $retval = array(); + if (version_compare(PHP_VERSION, '5.3.7', '>=') && defined('\CRYPT_BLOWFISH')) + { + $retval['bcrypt'] = 'bcrypt'; + } + if (function_exists('hash_hmac') && in_array('sha512', hash_algos())) + { + $retval['pbkdf2'] = 'pbkdf2'; + } + $retval['sha512'] = 'sha512'; + $retval['sha256'] = 'sha256'; + $retval['sha1'] = 'sha1'; + $retval['md5'] = 'md5'; + return $retval; + } + + /** + * Get the best hashing algorithm supported by this server. + * + * @return string + */ + public static function getBestSupportedAlgorithm() + { + $algos = self::getSupportedAlgorithms(); + return key($algos); + } + + /** + * Get the currently selected hashing algorithm. + * + * @return string + */ + public static function getSelectedAlgorithm() + { + if (function_exists('getModel')) + { + $config = getModel('member')->getMemberConfig(); + $algorithm = $config->password_hashing_algorithm; + if (strval($algorithm) === '') + { + $algorithm = 'md5'; + } + } + else + { + $algorithm = 'md5'; + } + return $algorithm; + } + + /** + * Get the currently configured work factor for bcrypt and other adjustable algorithms. + * + * @return int + */ + public static function getWorkFactor() + { + if (function_exists('getModel')) + { + $config = getModel('member')->getMemberConfig(); + $work_factor = $config->password_hashing_work_factor; + if (!$work_factor || $work_factor < 4 || $work_factor > 31) + { + $work_factor = 9; + } + } + else + { + $work_factor = 9; + } + + return $work_factor; + } + + /** + * Hash a password. + * + * To use multiple algorithms in series, provide them as an array. + * Salted algorithms such as bcrypt, pbkdf2, or portable must be used last. + * On error, false will be returned. + * + * @param string $password + * @param string|array $algos + * @param string $salt (optional) + * @return string|false + */ + public static function hashPassword($password, $algos, $salt = null) + { + // Initialize the chain of hashes. + $algos = array_map('strtolower', array_map('trim', is_array($algos) ? $algos : explode(',', $algos))); + $hashchain = preg_replace('/\\s+/', ' ', trim($password)); + + // Apply the given algorithms one by one. + foreach ($algos as $algo) + { + switch ($algo) + { + // bcrypt (must be used last) + case 'bcrypt': + $hashchain = self::bcrypt($hashchain, $salt, self::getWorkFactor()); + if ($hashchain[0] === '*') return false; + return $hashchain; + + // PBKDF2 (must be used last) + case 'pbkdf2': + if ($salt === null) + { + $salt = Security::getRandom(12, 'alnum'); + $hash_algorithm = 'sha512'; + $iterations = pow(2, self::getWorkFactor() + 5); + $key_length = 24; + } + else + { + $parts = explode(':', $salt); + $salt = $parts[2]; + $hash_algorithm = $parts[0]; + $iterations = $parts[1]; + $key_length = strlen(base64_decode($parts[3])); + } + return self::pbkdf2($hashchain, $salt, $hash_algorithm, $iterations, $key_length); + + // phpass portable algorithm (must be used last) + case 'portable': + $phpass = new \Hautelook\Phpass\PasswordHash(self::getWorkFactor(), true); + if ($salt === null) + { + $hashchain = $phpass->HashPassword($hashchain); + return $hashchain; + } + else + { + $match = $phpass->CheckPassword($hashchain, $salt); + return $match ? $salt : false; + } + + // Drupal's SHA-512 based algorithm (must be used last) + case 'drupal': + $hashchain = \VendorPass::drupal($password, $salt); + return $hashchain; + + // Joomla's MD5 based algorithm (must be used last) + case 'joomla': + $hashchain = \VendorPass::joomla($password, $salt); + return $hashchain; + + // KimsQ Rb algorithms (must be used last) + case 'kimsqrb': + $hashchain = \VendorPass::kimsqrb($password, $salt); + return $hashchain; + + // crypt() function (must be used last) + case 'crypt': + if ($salt === null) $salt = Security::getRandom(2, 'alnum'); + $hashchain = crypt($hashchain, $salt); + return $hashchain; + + // MS SQL's PWDENCRYPT() function (must be used last) + case 'mssql_pwdencrypt': + $hashchain = \VendorPass::mssql_pwdencrypt($hashchain, $salt); + return $hashchain; + + // MySQL's old PASSWORD() function. + case 'mysql_old_password': + $hashchain = \VendorPass::mysql_old_password($hashchain); + break; + + // MySQL's new PASSWORD() function. + case 'mysql_new_password': + $hashchain = \VendorPass::mysql_new_password($hashchain); + break; + + // A dummy algorithm that does nothing. + case 'null': + break; + + // All other algorithms will be passed to hash() or treated as a function name. + default: + if (isset(self::$_algorithm_callbacks[$algo])) + { + $callback = self::$_algorithm_callbacks[$algo]; + $hashchain = $callback($hashchain, $salt); + } + elseif (in_array($algo, hash_algos())) + { + $hashchain = hash($algo, $hashchain); + } + elseif (function_exists($algo)) + { + $hashchain = $algo($hashchain, $salt); + } + else + { + return false; + } + } + } + + return $hashchain; + } + + /** + * Check a password against a hash. + * + * This method returns true if the password is correct, and false otherwise. + * If the algorithm is not specified, it will be guessed from the format of the hash. + * + * @param string $password + * @param string $hash + * @param array|string $algos + * @return bool + */ + public static function checkPassword($password, $hash, $algos = null) + { + if (!$algos) + { + $algos = self::checkAlgorithm($hash); + } + if (!is_array($algos)) + { + $algos = explode(',', $algos); + } + + return Security::compareStrings($hash, self::hashPassword($password, $algos, $hash)); + } + + /** + * Guess which algorithm(s) were used to generate the given hash. + * + * If there are multiple possibilities, all of them will be returned in an array. + * + * @param string $hash + * @return array + */ + public static function checkAlgorithm($hash) + { + $candidates = array(); + foreach (self::$_algorithm_signatures as $name => $signature) + { + if (preg_match($signature, $hash)) $candidates[] = $name; + } + return $candidates; + } + + /** + * Check the work factor of a hash. + * + * @param string $hash + * @return int + */ + public static function checkWorkFactor($hash) + { + if(preg_match('/^\$2[axy]\$([0-9]{2})\$/', $hash, $matches)) + { + return intval($matches[1], 10); + } + elseif(preg_match('/^sha[0-9]+:([0-9]+):/', $hash, $matches)) + { + return max(0, round(log($matches[1], 2)) - 5); + } + else + { + return 0; + } + } + + /** + * Generate the bcrypt hash of a string. + * + * @param string $password + * @param string $salt (optional) + * @param int $work_factor (optional) + * @return string + */ + public static function bcrypt($password, $salt = null, $work_factor = 10) + { + if ($salt === null) + { + $salt = '$2y$' . sprintf('%02d', $work_factor) . '$' . Security::getRandom(22, 'alnum'); + } + + return crypt($password, $salt); + } + + /** + * Generate the PBKDF2 hash of a string. + * + * @param string $password + * @param string $salt (optional) + * @param string $algorithm (optional) + * @param int $iterations (optional) + * @param int $length (optional) + * @return string + */ + public static function pbkdf2($password, $salt = null, $algorithm = 'sha512', $iterations = 16384, $length = 24) + { + if ($salt === null) + { + $salt = Security::getRandom(12, 'alnum'); + } + + if (function_exists('hash_pbkdf2')) + { + $hash = hash_pbkdf2($algorithm, $password, $salt, $iterations, $length, true); + } + else + { + $output = ''; + $block_count = ceil($length / strlen(hash($algorithm, '', true))); // key length divided by the length of one hash + for ($i = 1; $i <= $block_count; $i++) + { + $last = $salt . pack('N', $i); // $i encoded as 4 bytes, big endian + $last = $xorsum = hash_hmac($algorithm, $last, $password, true); // first iteration + for ($j = 1; $j < $iterations; $j++) // The other $count - 1 iterations + { + $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true)); + } + $output .= $xorsum; + } + $hash = substr($output, 0, $length); + } + + return $algorithm . ':' . sprintf('%07d', $iterations) . ':' . $salt . ':' . base64_encode($hash); + } + + /** + * Count the amount of entropy that a password contains. + * + * @param string $password + * @return int + */ + public static function countEntropyBits($password) + { + // An empty string has no entropy. + + if ($password === '') return 0; + + // Common character sets and the number of possible mutations. + + static $entropy_per_char = array( + '/^[0-9]+$/' => 10, + '/^[a-z]+$/' => 26, + '/^[A-Z]+$/' => 26, + '/^[a-z0-9]+$/' => 36, + '/^[A-Z0-9]+$/' => 36, + '/^[a-zA-Z]+$/' => 52, + '/^[a-zA-Z0-9]+$/' => 62, + '/^[a-zA-Z0-9_-]+$/' => 64, + '/^[\\x20-\\x7e]+$/' => 95, + '/^[\\x00-\\x7f]+$/' => 128, + ); + + foreach ($entropy_per_char as $regex => $entropy) + { + if (preg_match($regex, $password)) + { + return log(pow($entropy, strlen($password)), 2); + } + } + + return strlen($password) * 8; + } +} diff --git a/common/libraries/vendorpass.php b/common/libraries/vendorpass.php index 46e5e73c3..c31bfe30b 100644 --- a/common/libraries/vendorpass.php +++ b/common/libraries/vendorpass.php @@ -61,7 +61,7 @@ class VendorPass else { $iterations = 15; - $salt = Password::createSecureSalt(8, 'hex'); + $salt = Rhymix\Framework\Security::getRandom(8, 'hex'); } $count = 1 << $iterations; $hash = hash('sha512', $salt . $password, true); @@ -104,7 +104,7 @@ class VendorPass } else { - $salt = Password::createSecureSalt(32, 'hex'); + $salt = Rhymix\Framework\Security::getRandom(32, 'hex'); } return md5($password . $salt) . ':' . $salt; } @@ -137,7 +137,7 @@ class VendorPass { if (!isset($options['salt']) || !preg_match('/^[0-9a-zA-Z\.\/]{22,}$/', $options['salt'])) { - $options['salt'] = Password::createSecureSalt(22, 'alnum'); + $options['salt'] = Rhymix\Framework\Security::getRandom(22, 'alnum'); } if (!isset($options['cost']) || $options['cost'] < 4 || $options['cost'] > 31) { diff --git a/tests/unit/framework/PasswordTest.php b/tests/unit/framework/PasswordTest.php new file mode 100644 index 000000000..1bf859bbf --- /dev/null +++ b/tests/unit/framework/PasswordTest.php @@ -0,0 +1,127 @@ +assertTrue(Rhymix\Framework\Password::isValidAlgorithm('bcrypt')); + $this->assertTrue(Rhymix\Framework\Password::isValidAlgorithm('whirlpool,pbkdf2')); + $this->assertTrue(Rhymix\Framework\Password::isValidAlgorithm(array('md5', 'sha1', 'md5'))); + + $this->assertFalse(Rhymix\Framework\Password::isValidAlgorithm('bunga_bunga')); + Rhymix\Framework\Password::addAlgorithm('bunga_bunga', '/bunga_bunga/', function($hash) { return 'bunga_bunga'; }); + $this->assertTrue(Rhymix\Framework\Password::isValidAlgorithm('bunga_bunga')); + } + + public function testGetSupportedAlgorithms() + { + $algos = Rhymix\Framework\Password::getSupportedAlgorithms(); + $this->assertTrue(in_array('bcrypt', $algos)); + $this->assertTrue(in_array('pbkdf2', $algos)); + $this->assertTrue(in_array('md5', $algos)); + } + + public function testGetBestSupportedAlgorithm() + { + $algo = Rhymix\Framework\Password::getBestSupportedAlgorithm(); + $this->assertTrue($algo === 'bcrypt' || $algo === 'pbkdf2'); + } + + public function testGetSelectedAlgorithm() + { + $algo = Rhymix\Framework\Password::getSelectedAlgorithm(); + $this->assertTrue($algo === 'bcrypt' || $algo === 'pbkdf2' || $algo === 'md5'); + } + + public function testGetWorkFactor() + { + $work_factor = $algo = Rhymix\Framework\Password::getWorkFactor(); + $this->assertTrue($work_factor >= 4); + $this->assertTrue($work_factor <= 31); + } + + public function testHashPassword() + { + $password = Rhymix\Framework\Security::getRandom(32); + $this->assertEquals(md5($password), Rhymix\Framework\Password::hashPassword($password, 'md5')); + $this->assertEquals(md5(sha1(md5($password))), Rhymix\Framework\Password::hashPassword($password, 'md5,sha1,md5')); + $this->assertEquals(hash('whirlpool', $password), Rhymix\Framework\Password::hashPassword($password, 'whirlpool')); + $this->assertEquals('5d2e19393cc5ef67', Rhymix\Framework\Password::hashPassword('password', 'mysql_old_password')); + } + + public function testCheckPassword() + { + $password = Rhymix\Framework\Security::getRandom(32); + + $algos = array('whirlpool', 'ripemd160', 'bcrypt'); + $hash = Rhymix\Framework\Password::hashPassword($password, $algos); + $this->assertRegExp('/^\$2y\$/', $hash); + $this->assertEquals(60, strlen($hash)); + $this->assertTrue(Rhymix\Framework\Password::checkPassword($password, $hash, $algos)); + + $algos = array('pbkdf2'); + $hash = Rhymix\Framework\Password::hashPassword($password, $algos); + $this->assertRegExp('/^(sha256|sha512):[0-9]+:/', $hash); + $this->assertEquals(60, strlen($hash)); + $this->assertTrue(Rhymix\Framework\Password::checkPassword($password, $hash, $algos)); + + foreach (array('drupal', 'joomla', 'kimsqrb', 'mysql_old_password', 'mysql_new_password', 'mssql_pwdencrypt') as $algo) + { + $hash = Rhymix\Framework\Password::hashPassword($password, $algo); + $this->assertTrue(Rhymix\Framework\Password::checkPassword($password, $hash, $algo)); + $this->assertFalse(Rhymix\Framework\Password::checkPassword($password, $hash . 'x', $algo)); + } + } + + public function testCheckAlgorithm() + { + $password = Rhymix\Framework\Security::getRandom(32, 'hex'); + + $this->assertEquals(array('md5', 'md5,sha1,md5'), Rhymix\Framework\Password::checkAlgorithm($password)); + $this->assertEquals(array('sha512', 'whirlpool'), Rhymix\Framework\Password::checkAlgorithm(hash('sha512', $password))); + + $hash = '$2y$10$VkxBdEBTZ1HyLluZPjXCjuFffw0a6alZlbb733CF/zA22HDpBNsMm'; + $this->assertEquals(array('bcrypt'), Rhymix\Framework\Password::checkAlgorithm($hash)); + + $hash = 'sha512:0008192:hoXcLXQzIiIJ:ElokybdRf+i512M4/4PIdEiSDgZ8f0uL'; + $this->assertEquals(array('pbkdf2'), Rhymix\Framework\Password::checkAlgorithm($hash)); + } + + public function testCheckWorkFactor() + { + $hash = '$2y$10$VkxBdEBTZ1HyLluZPjXCjuFffw0a6alZlbb733CF/zA22HDpBNsMm'; + $this->assertEquals(10, Rhymix\Framework\Password::checkWorkFactor($hash)); + + $hash = 'sha512:0008192:hoXcLXQzIiIJ:ElokybdRf+i512M4/4PIdEiSDgZ8f0uL'; + $this->assertEquals(8, Rhymix\Framework\Password::checkWorkFactor($hash)); + + $hash = '5f4dcc3b5aa765d61d8327deb882cf99'; + $this->assertEquals(0, Rhymix\Framework\Password::checkWorkFactor($hash)); + } + + public function testBcrypt() + { + $password = 'password'; + $hash = '$2y$10$VkxBdEBTZ1HyLluZPjXCjuFffw0a6alZlbb733CF/zA22HDpBNsMm'; + $this->assertEquals($hash, Rhymix\Framework\Password::bcrypt($password, $hash)); + } + + public function testPBKDF2() + { + $password = 'password'; + $salt = 'rtmIxdEUoWUk'; + $hash = 'sha512:0016384:rtmIxdEUoWUk:1hrwGP3ScWvxslnqNFqyhM6Ddn4iYrwf'; + $this->assertEquals($hash, Rhymix\Framework\Password::pbkdf2($password, $salt, 'sha512', 16384, 24)); + } + + public function testCountEntropyBits() + { + $this->assertEquals(0, Rhymix\Framework\Password::countEntropyBits('')); + $this->assertEquals(13, round(Rhymix\Framework\Password::countEntropyBits('1234'))); + $this->assertEquals(20, round(Rhymix\Framework\Password::countEntropyBits('123456'))); + $this->assertEquals(28, round(Rhymix\Framework\Password::countEntropyBits('rhymix'))); + $this->assertEquals(52, round(Rhymix\Framework\Password::countEntropyBits('rhymix1234'))); + $this->assertEquals(60, round(Rhymix\Framework\Password::countEntropyBits('RhymiX1234'))); + $this->assertEquals(125, round(Rhymix\Framework\Password::countEntropyBits('Rhymix_is*the%Best!'))); + } +} diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index 23d658a0f..8c600e2c6 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -57,11 +57,11 @@ class SecurityTest extends \Codeception\TestCase\Test public function testGetRandom() { - $this->assertEquals(1, preg_match('/^[0-9a-zA-Z]{32}$/', Rhymix\Framework\Security::getRandom())); - $this->assertEquals(1, preg_match('/^[0-9a-zA-Z]{256}$/', Rhymix\Framework\Security::getRandom(256))); - $this->assertEquals(1, preg_match('/^[0-9a-zA-Z]{16}$/', Rhymix\Framework\Security::getRandom(16, 'alnum'))); - $this->assertEquals(1, preg_match('/^[0-9a-f]{16}$/', Rhymix\Framework\Security::getRandom(16, 'hex'))); - $this->assertEquals(1, preg_match('/^[\x21-\x7e]{16}$/', Rhymix\Framework\Security::getRandom(16, 'printable'))); + $this->assertRegExp('/^[0-9a-zA-Z]{32}$/', Rhymix\Framework\Security::getRandom()); + $this->assertRegExp('/^[0-9a-zA-Z]{256}$/', Rhymix\Framework\Security::getRandom(256)); + $this->assertRegExp('/^[0-9a-zA-Z]{16}$/', Rhymix\Framework\Security::getRandom(16, 'alnum')); + $this->assertRegExp('/^[0-9a-f]{16}$/', Rhymix\Framework\Security::getRandom(16, 'hex')); + $this->assertRegExp('/^[\x21-\x7e]{16}$/', Rhymix\Framework\Security::getRandom(16, 'printable')); } public function testGetRandomNumber() @@ -80,7 +80,7 @@ class SecurityTest extends \Codeception\TestCase\Test $regex = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/'; for ($i = 0; $i < 10; $i++) { - $this->assertEquals(1, preg_match($regex, Rhymix\Framework\Security::getRandomUUID())); + $this->assertRegExp($regex, Rhymix\Framework\Security::getRandomUUID()); } } From ddab5ce8d833169d76fd309194372253f2f576ef Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 22:11:30 +0900 Subject: [PATCH 151/318] Fix unit tests for Security::getRandomNumber() --- tests/unit/framework/SecurityTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index 8c600e2c6..b28d99ada 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -71,7 +71,7 @@ class SecurityTest extends \Codeception\TestCase\Test $min = mt_rand(0, 10000); $max = $min + mt_rand(0, 10000); $random = Rhymix\Framework\Security::getRandomNumber($min, $max); - $this->assertTrue($random >= $min && $random < $max); + $this->assertTrue($random >= $min && $random <= $max); } } From 642f048f649b2eb88925930978d4b71bbad26ef8 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 23:01:49 +0900 Subject: [PATCH 152/318] Improve encoding and decoding of widget and editor component attributes --- common/framework/security/htmlfilter.php | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/common/framework/security/htmlfilter.php b/common/framework/security/htmlfilter.php index fce40cf71..9b241dcfe 100644 --- a/common/framework/security/htmlfilter.php +++ b/common/framework/security/htmlfilter.php @@ -442,10 +442,11 @@ class HTMLFilter protected static function _encodeWidgetsAndEditorComponents($content) { return preg_replace_callback('!<(div|img)([^>]*)(editor_component="[^"]+"|class="zbxe_widget_output")([^>]*)>!i', function($match) { + $tag = strtolower($match[1]); $attrs = array(); - $html = preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use(&$attrs) { + $html = preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use($tag, &$attrs) { $attrkey = strtolower($attr[1]); - if (strtolower($match[1]) === 'img' && preg_match('/^(?:width|height|alt)$/', $attrkey)) + if ($tag === 'img' && preg_match('/^(?:width|height|alt)$/', $attrkey)) { return $attr[0]; } @@ -456,11 +457,11 @@ class HTMLFilter $attrs[$attrkey] = htmlspecialchars_decode($attr[2]); return ''; }, $match[0]); - if (strtolower($match[1]) === 'img' && !preg_match('/\ssrc="/', $html)) + if ($tag === 'img' && !preg_match('/\ssrc="/', $html)) { $html = substr($html, 0, 4) . ' src=""' . substr($html, 4); } - $encoded_properties = base64_encode(json_encode($attrs)); + $encoded_properties = \Rhymix\Framework\Security::encrypt(json_encode($attrs)); return substr($html, 0, 4) . ' rx_encoded_properties="' . $encoded_properties . '"' . substr($html, 4); }, $content); } @@ -473,14 +474,23 @@ class HTMLFilter */ protected static function _decodeWidgetsAndEditorComponents($content) { - return preg_replace_callback('!<(div|img)([^>]*)(rx_encoded_properties="([^"]+)")!i', function($match) { + return preg_replace_callback('!<(div|img)([^>]*)(\srx_encoded_properties="([^"]+)")!i', function($match) { $attrs = array(); - $decoded_properties = @json_decode(base64_decode($match[4])) ?: array(); + $decoded_properties = \Rhymix\Framework\Security::decrypt($match[4]); + if (!$decoded_properties) + { + return str_replace($match[3], '', $match[0]); + } + $decoded_properties = json_decode($decoded_properties); + if (!$decoded_properties) + { + return str_replace($match[3], '', $match[0]); + } foreach ($decoded_properties as $key => $val) { $attrs[] = $key . '="' . htmlspecialchars($val) . '"'; } - return str_replace($match[3], implode(' ', $attrs), $match[0]); + return str_replace($match[3], ' ' . implode(' ', $attrs), $match[0]); }, $content); } } From f4dc7e6b214e1fa7a31bb99bbd5b13961acfff38 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 23:23:48 +0900 Subject: [PATCH 153/318] Move all functionality of old Password class to new Password class --- classes/security/Password.class.php | 320 ++------------------------ common/framework/password.php | 55 ++++- tests/unit/framework/PasswordTest.php | 14 +- 3 files changed, 73 insertions(+), 316 deletions(-) diff --git a/classes/security/Password.class.php b/classes/security/Password.class.php index fa39fd906..c0a1da502 100644 --- a/classes/security/Password.class.php +++ b/classes/security/Password.class.php @@ -1,366 +1,76 @@ */ -/** - * This class can be used to hash passwords using various algorithms and check their validity. - * It is fully compatible with previous defaults, while also supporting bcrypt and pbkdf2. - * - * @file Password.class.php - * @author Kijin Sung (kijin@kijinsung.com) - * @package /classes/security - * @version 1.1 - */ class Password { - /** - * @brief Custom algorithms are stored here - * @var array - */ - protected static $_custom = array(); - - /** - * @brief Register a custom algorithm for password checking - * @param string $name The name of the algorithm - * @param string $regexp The regular expression to detect the algorithm - * @param callable $callback The function to call to regenerate the hash - * @return void - */ public static function registerCustomAlgorithm($name, $regexp, $callback) { - self::$_custom[$name] = array('regexp' => $regexp, 'callback' => $callback); + Rhymix\Framework\Password::addAlgorithm($name, $regexp, $callback); } - /** - * @brief Return the list of hashing algorithms supported by this server - * @return array - */ public function getSupportedAlgorithms() { - $retval = array(); - if(function_exists('hash_hmac') && in_array('sha256', hash_algos())) - { - $retval['pbkdf2'] = 'pbkdf2'; - } - if(version_compare(PHP_VERSION, '5.3.7', '>=') && defined('CRYPT_BLOWFISH')) - { - $retval['bcrypt'] = 'bcrypt'; - } - $retval['md5'] = 'md5'; - return $retval; + return Rhymix\Framework\Password::getSupportedAlgorithms(); } - /** - * @brief Return the best hashing algorithm supported by this server - * @return string - */ public function getBestAlgorithm() { - $algos = $this->getSupportedAlgorithms(); - return key($algos); + return Rhymix\Framework\Password::getBestSupportedAlgorithm(); } - /** - * @brief Return the currently selected hashing algorithm - * @return string - */ public function getCurrentlySelectedAlgorithm() { - if(function_exists('getModel')) - { - $config = getModel('member')->getMemberConfig(); - $algorithm = $config->password_hashing_algorithm; - if(strval($algorithm) === '') - { - $algorithm = 'md5'; // Historical default for XE - } - } - else - { - $algorithm = 'md5'; - } - return $algorithm; + return Rhymix\Framework\Password::getDefaultAlgorithm(); } - /** - * @brief Return the currently configured work factor for bcrypt and other adjustable algorithms - * @return int - */ public function getWorkFactor() { - if(function_exists('getModel')) - { - $config = getModel('member')->getMemberConfig(); - $work_factor = $config->password_hashing_work_factor; - if(!$work_factor || $work_factor < 4 || $work_factor > 31) - { - $work_factor = 8; // Reasonable default - } - } - else - { - $work_factor = 8; - } - return $work_factor; + return Rhymix\Framework\Password::getWorkFactor(); } - /** - * @brief Create a hash using the specified algorithm - * @param string $password The password - * @param string $algorithm The algorithm (optional) - * @return string - */ public function createHash($password, $algorithm = null) { - if($algorithm === null) - { - $algorithm = $this->getCurrentlySelectedAlgorithm(); - } - if(!array_key_exists($algorithm, $this->getSupportedAlgorithms())) - { - return false; - } - - $password = trim($password); - - switch($algorithm) - { - case 'md5': - return md5($password); - - case 'pbkdf2': - $iterations = pow(2, $this->getWorkFactor() + 5); - $salt = $this->createSecureSalt(12, 'alnum'); - $hash = base64_encode($this->pbkdf2($password, $salt, 'sha256', $iterations, 24)); - return 'sha256:'.sprintf('%07d', $iterations).':'.$salt.':'.$hash; - - case 'bcrypt': - return $this->bcrypt($password); - - default: - return false; - } + return Rhymix\Framework\Password::hashPassword($password, $algorithm); } - /** - * @brief Check if a password matches a hash - * @param string $password The password - * @param string $hash The hash - * @param string $algorithm The algorithm (optional) - * @return bool - */ public function checkPassword($password, $hash, $algorithm = null) { - if($algorithm === null) - { - $algorithm = $this->checkAlgorithm($hash); - } - - $password = trim($password); - - switch($algorithm) - { - case 'md5': - return md5($password) === $hash || md5(sha1(md5($password))) === $hash; - - case 'mysql_old_password': - return (class_exists('Context') && substr(Context::getDBType(), 0, 5) === 'mysql') ? - DB::getInstance()->isValidOldPassword($password, $hash) : false; - - case 'mysql_password': - return $hash[0] === '*' && substr($hash, 1) === strtoupper(sha1(sha1($password, true))); - - case 'pbkdf2': - $hash = explode(':', $hash); - $hash[3] = base64_decode($hash[3]); - $hash_to_compare = $this->pbkdf2($password, $hash[2], $hash[0], intval($hash[1], 10), strlen($hash[3])); - return Rhymix\Framework\Security::compareStrings($hash_to_compare, $hash[3]); - - case 'bcrypt': - $hash_to_compare = $this->bcrypt($password, $hash); - return Rhymix\Framework\Security::compareStrings($hash_to_compare, $hash); - - default: - if($algorithm && isset(self::$_custom[$algorithm])) - { - $hash_callback = self::$_custom[$algorithm]['callback']; - $hash_to_compare = $hash_callback($password, $hash); - return Rhymix\Framework\Security::compareStrings($hash_to_compare, $hash); - } - if(in_array($algorithm, hash_algos())) - { - return Rhymix\Framework\Security::compareStrings(hash($algorithm, $password), $hash); - } - return false; - } + return Rhymix\Framework\Password::checkPassword($password, $hash, $algorithm); } - /** - * @brief Check the algorithm used to create a hash - * @param string $hash The hash - * @return string - */ function checkAlgorithm($hash) { - foreach(self::$_custom as $name => $definition) - { - if(preg_match($definition['regexp'], $hash)) - { - return $name; - } - } - - if(preg_match('/^\$2[axy]\$([0-9]{2})\$/', $hash, $matches)) - { - return 'bcrypt'; - } - elseif(preg_match('/^sha[0-9]+:([0-9]+):/', $hash, $matches)) - { - return 'pbkdf2'; - } - elseif(strlen($hash) === 32 && ctype_xdigit($hash)) - { - return 'md5'; - } - elseif(strlen($hash) === 40 && ctype_xdigit($hash)) - { - return 'sha1'; - } - elseif(strlen($hash) === 64 && ctype_xdigit($hash)) - { - return 'sha256'; - } - elseif(strlen($hash) === 96 && ctype_xdigit($hash)) - { - return 'sha384'; - } - elseif(strlen($hash) === 128 && ctype_xdigit($hash)) - { - return 'sha512'; - } - elseif(strlen($hash) === 16 && ctype_xdigit($hash)) - { - return 'mysql_old_password'; - } - elseif(strlen($hash) === 41 && $hash[0] === '*') - { - return 'mysql_password'; - } - else - { - return false; - } + $algos = Rhymix\Framework\Password::checkAlgorithm($hash); + return count($algos) ? $algos[0] : false; } - /** - * @brief Check the work factor of a hash - * @param string $hash The hash - * @return int - */ function checkWorkFactor($hash) { - if(preg_match('/^\$2[axy]\$([0-9]{2})\$/', $hash, $matches)) - { - return intval($matches[1], 10); - } - elseif(preg_match('/^sha[0-9]+:([0-9]+):/', $hash, $matches)) - { - return max(0, round(log($matches[1], 2)) - 5); - } - else - { - return false; - } + return Rhymix\Framework\Password::checkWorkFactor($hash); } - /** - * @brief Generate a cryptographically secure random string to use as a salt - * @param int $length The number of bytes to return - * @param string $format hex or alnum - * @return string - */ public function createSecureSalt($length, $format = 'hex') { return Rhymix\Framework\Security::getRandom($length, $format); } - /** - * @brief Generate a temporary password using the secure salt generator - * @param int $length The number of bytes to return - * @return string - */ public function createTemporaryPassword($length = 16) { - while(true) - { - $source = base64_encode($this->createSecureSalt(64, 'binary')); - $source = strtr($source, 'iIoOjl10/', '@#$%&*-!?'); - $source_length = strlen($source); - for($i = 0; $i < $source_length - $length; $i++) - { - $candidate = substr($source, $i, $length); - if(preg_match('/[a-z]/', $candidate) && preg_match('/[A-Z]/', $candidate) && - preg_match('/[0-9]/', $candidate) && preg_match('/[^a-zA-Z0-9]/', $candidate)) - { - return $candidate; - } - } - } + return Rhymix\Framework\Password::getRandomPassword($length); } - /** - * @brief Generate the PBKDF2 hash of a string using a salt - * @param string $password The password - * @param string $salt The salt - * @param string $algorithm The algorithm (optional, default is sha256) - * @param int $iterations Iteration count (optional, default is 8192) - * @param int $length The length of the hash (optional, default is 32) - * @return string - */ public function pbkdf2($password, $salt, $algorithm = 'sha256', $iterations = 8192, $length = 24) { - if(function_exists('hash_pbkdf2')) - { - return hash_pbkdf2($algorithm, $password, $salt, $iterations, $length, true); - } - else - { - $output = ''; - $block_count = ceil($length / strlen(hash($algorithm, '', true))); // key length divided by the length of one hash - for($i = 1; $i <= $block_count; $i++) - { - $last = $salt . pack('N', $i); // $i encoded as 4 bytes, big endian - $last = $xorsum = hash_hmac($algorithm, $last, $password, true); // first iteration - for($j = 1; $j < $iterations; $j++) // The other $count - 1 iterations - { - $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true)); - } - $output .= $xorsum; - } - return substr($output, 0, $length); - } + $hash = Rhymix\Framework\Security::pbkdf2($password, $salt, $algorithm, $iterations, $length); + $hash = explode(':', $hash); + return base64_decode($hash[3]); } - /** - * @brief Generate the bcrypt hash of a string using a salt - * @param string $password The password - * @param string $salt The salt (optional, auto-generated if empty) - * @return string - */ public function bcrypt($password, $salt = null) { - if($salt === null) - { - $salt = '$2y$'.sprintf('%02d', $this->getWorkFactor()).'$'.$this->createSecureSalt(22, 'alnum'); - } - return crypt($password, $salt); + return Rhymix\Framework\Security::bcrypt($password, $salt); } - /** - * @brief Compare two strings in constant time - * @param string $a The first string - * @param string $b The second string - * @return bool - */ function strcmpConstantTime($a, $b) { return Rhymix\Framework\Security::compareStrings($a, $b); diff --git a/common/framework/password.php b/common/framework/password.php index 2e4e67017..bac5e284f 100644 --- a/common/framework/password.php +++ b/common/framework/password.php @@ -106,11 +106,11 @@ class Password } /** - * Get the currently selected hashing algorithm. + * Get the current default hashing algorithm. * * @return string */ - public static function getSelectedAlgorithm() + public static function getDefaultAlgorithm() { if (function_exists('getModel')) { @@ -152,6 +152,31 @@ class Password return $work_factor; } + /** + * Generate a reasonably strong random password. + * + * @param int $length + * @return string + */ + public static function getRandomPassword($length = 16) + { + while(true) + { + $source = base64_encode(Security::getRandom(64, 'binary')); + $source = strtr($source, 'iIoOjl10/', '@#$%&*-!?'); + $source_length = strlen($source); + for($i = 0; $i < $source_length - $length; $i++) + { + $candidate = substr($source, $i, $length); + if(preg_match('/[a-z]/', $candidate) && preg_match('/[A-Z]/', $candidate) && + preg_match('/[0-9]/', $candidate) && preg_match('/[^a-zA-Z0-9]/', $candidate)) + { + return $candidate; + } + } + } + } + /** * Hash a password. * @@ -160,12 +185,18 @@ class Password * On error, false will be returned. * * @param string $password - * @param string|array $algos + * @param string|array $algos (optional) * @param string $salt (optional) * @return string|false */ - public static function hashPassword($password, $algos, $salt = null) + public static function hashPassword($password, $algos = null, $salt = null) { + // If the algorithm is null, use the default algorithm. + if ($algos === null) + { + $algos = self::getDefaultAlgorithm(); + } + // Initialize the chain of hashes. $algos = array_map('strtolower', array_map('trim', is_array($algos) ? $algos : explode(',', $algos))); $hashchain = preg_replace('/\\s+/', ' ', trim($password)); @@ -292,16 +323,22 @@ class Password */ public static function checkPassword($password, $hash, $algos = null) { - if (!$algos) + if ($algos === null) { $algos = self::checkAlgorithm($hash); + foreach ($algos as $algo) + { + if (Security::compareStrings($hash, self::hashPassword($password, $algo, $hash))) + { + return true; + } + } + return false; } - if (!is_array($algos)) + else { - $algos = explode(',', $algos); + return Security::compareStrings($hash, self::hashPassword($password, $algos, $hash)); } - - return Security::compareStrings($hash, self::hashPassword($password, $algos, $hash)); } /** diff --git a/tests/unit/framework/PasswordTest.php b/tests/unit/framework/PasswordTest.php index 1bf859bbf..610092653 100644 --- a/tests/unit/framework/PasswordTest.php +++ b/tests/unit/framework/PasswordTest.php @@ -27,9 +27,9 @@ class PasswordTest extends \Codeception\TestCase\Test $this->assertTrue($algo === 'bcrypt' || $algo === 'pbkdf2'); } - public function testGetSelectedAlgorithm() + public function testGetDefaultAlgorithm() { - $algo = Rhymix\Framework\Password::getSelectedAlgorithm(); + $algo = Rhymix\Framework\Password::getDefaultAlgorithm(); $this->assertTrue($algo === 'bcrypt' || $algo === 'pbkdf2' || $algo === 'md5'); } @@ -40,6 +40,16 @@ class PasswordTest extends \Codeception\TestCase\Test $this->assertTrue($work_factor <= 31); } + public function testGetRandomPassword() + { + $password = Rhymix\Framework\Password::getRandomPassword(16); + $this->assertEquals(16, strlen($password)); + $this->assertRegexp('/[a-z]/', $password); + $this->assertRegexp('/[A-Z]/', $password); + $this->assertRegexp('/[0-9]/', $password); + $this->assertRegexp('/[^a-zA-Z0-9]/', $password); + } + public function testHashPassword() { $password = Rhymix\Framework\Security::getRandom(32); From 9d6284faad40f2b3dcbadeff3d08f68e88864d2f Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 23:39:31 +0900 Subject: [PATCH 154/318] Update all references to old Password class --- common/framework/compat/configparser.php | 6 +-- modules/file/file.controller.php | 24 ++++------- modules/install/install.view.php | 2 +- modules/member/member.admin.controller.php | 3 +- modules/member/member.admin.view.php | 3 +- modules/member/member.class.php | 3 +- modules/member/member.controller.php | 20 +++------ modules/member/member.model.php | 50 ++++++++++++++-------- 8 files changed, 53 insertions(+), 58 deletions(-) diff --git a/common/framework/compat/configparser.php b/common/framework/compat/configparser.php index c88300dd1..44a0a7b59 100644 --- a/common/framework/compat/configparser.php +++ b/common/framework/compat/configparser.php @@ -151,9 +151,9 @@ class ConfigParser } // Create new crypto keys. - $config['crypto']['encryption_key'] = \Password::createSecureSalt(64, 'alnum'); - $config['crypto']['authentication_key'] = \Password::createSecureSalt(64, 'alnum'); - $config['crypto']['session_key'] = \Password::createSecureSalt(64, 'alnum'); + $config['crypto']['encryption_key'] = \Rhymix\Framework\Security::getRandom(64, 'alnum'); + $config['crypto']['authentication_key'] = \Rhymix\Framework\Security::getRandom(64, 'alnum'); + $config['crypto']['session_key'] = \Rhymix\Framework\Security::getRandom(64, 'alnum'); // Convert language configuration. if (isset($db_info->lang_type)) diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 65a4720a1..12d618456 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -285,8 +285,7 @@ class fileController extends file // Redirect to procFileOutput using file key if(!isset($_SESSION['__XE_FILE_KEY__']) || !is_string($_SESSION['__XE_FILE_KEY__']) || strlen($_SESSION['__XE_FILE_KEY__']) != 32) { - $random = new Password(); - $_SESSION['__XE_FILE_KEY__'] = $random->createSecureSalt(32, 'hex'); + $_SESSION['__XE_FILE_KEY__'] = Rhymix\Framework\Security::getRandom(32, 'hex'); } $file_key_data = $file_obj->file_srl . $file_obj->file_size . $file_obj->uploaded_filename . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']; $file_key = substr(hash_hmac('sha256', $file_key_data, $_SESSION['__XE_FILE_KEY__']), 0, 32); @@ -735,9 +734,6 @@ class fileController extends file // Sanitize filename $file_info['name'] = Rhymix\Framework\Security\FilenameFilter::clean($file_info['name']); - // Get random number generator - $random = new Password(); - // Set upload path by checking if the attachement is an image or other kinds of file if(preg_match("/\.(jpe?g|gif|png|wm[va]|mpe?g|avi|swf|flv|mp[1-4]|as[fx]|wav|midi?|moo?v|qt|r[am]{1,2}|m4v)$/i", $file_info['name'])) { @@ -747,7 +743,7 @@ class fileController extends file // change to random file name. because window php bug. window php is not recognize unicode character file name - by cherryfilter $ext = substr(strrchr($file_info['name'],'.'),1); //$_filename = preg_replace('/[#$&*?+%"\']/', '_', $file_info['name']); - $_filename = $random->createSecureSalt(32, 'hex').'.'.$ext; + $_filename = Rhymix\Framework\Security::getRandom(32, 'hex') . '.' . $ext; $filename = $path.$_filename; $idx = 1; while(file_exists($filename)) @@ -760,15 +756,12 @@ class fileController extends file else { $path = sprintf("./files/attach/binaries/%s/%s", $module_srl, getNumberingPath($upload_target_srl,3)); - $filename = $path.$random->createSecureSalt(32, 'hex'); + $filename = $path . Rhymix\Framework\Security::getRandom(32, 'hex'); $direct_download = 'N'; } // Create a directory if(!FileHandler::makeDir($path)) return new Object(-1,'msg_not_permitted_create'); - - // Get random number generator - $random = new Password(); // Move the file if($manual_insert) @@ -776,7 +769,7 @@ class fileController extends file @copy($file_info['tmp_name'], $filename); if(!file_exists($filename)) { - $filename = $path.$random->createSecureSalt(32, 'hex').'.'.$ext; + $filename = $path . Rhymix\Framework\Security::getRandom(32, 'hex') . '.' . $ext; @copy($file_info['tmp_name'], $filename); } } @@ -784,7 +777,7 @@ class fileController extends file { if(!@move_uploaded_file($file_info['tmp_name'], $filename)) { - $filename = $path.$random->createSecureSalt(32, 'hex').'.'.$ext; + $filename = $path . Rhymix\Framework\Security::getRandom(32, 'hex') . '.' . $ext; if(!@move_uploaded_file($file_info['tmp_name'], $filename)) return new Object(-1,'msg_file_upload_error'); } } @@ -803,7 +796,7 @@ class fileController extends file $args->file_size = @filesize($filename); $args->comment = NULL; $args->member_srl = $member_srl; - $args->sid = $random->createSecureSalt(32, 'hex'); + $args->sid = Rhymix\Framework\Security::getRandom(32, 'hex'); $output = executeQuery('file.insertFile', $args); if(!$output->toBool()) return $output; @@ -978,13 +971,12 @@ class fileController extends file 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; + $new_file = $path . $file_info->source_filename; } else { $path = sprintf("./files/attach/binaries/%s/%s/", $target_module_srl, $target_srl); - $random = new Password(); - $new_file = $path.$random->createSecureSalt(32, 'hex'); + $new_file = $path . Rhymix\Framework\Security::getRandom(32, 'hex'); } // Pass if a target document to move is same if($old_file == $new_file) continue; diff --git a/modules/install/install.view.php b/modules/install/install.view.php index 0d8c0498f..27f504ea7 100644 --- a/modules/install/install.view.php +++ b/modules/install/install.view.php @@ -74,7 +74,7 @@ class installView extends install function dispInstallCheckEnv() { // Create a temporary file for mod_rewrite check. - self::$rewriteCheckString = Password::createSecureSalt(32); + self::$rewriteCheckString = Rhymix\Framework\Security::getRandom(32); FileHandler::writeFile(_XE_PATH_ . self::$rewriteCheckFilePath, self::$rewriteCheckString);; // Check if the web server is nginx. diff --git a/modules/member/member.admin.controller.php b/modules/member/member.admin.controller.php index 918838a72..f18ec15c8 100644 --- a/modules/member/member.admin.controller.php +++ b/modules/member/member.admin.controller.php @@ -166,8 +166,7 @@ class memberAdminController extends member 'update_nickname_log' ); - $oPassword = new Password(); - if(!array_key_exists($args->password_hashing_algorithm, $oPassword->getSupportedAlgorithms())) + if(!array_key_exists($args->password_hashing_algorithm, Rhymix\Framework\Password::getSupportedAlgorithms())) { $args->password_hashing_algorithm = 'md5'; } diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index 93619b3c4..a2626716b 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -129,8 +129,7 @@ class memberAdminView extends member */ public function dispMemberAdminConfig() { - $oPassword = new Password(); - Context::set('password_hashing_algos', $oPassword->getSupportedAlgorithms()); + Context::set('password_hashing_algos', Rhymix\Framework\Password::getSupportedAlgorithms()); $this->setTemplateFile('default_config'); } diff --git a/modules/member/member.class.php b/modules/member/member.class.php index b2a63f159..5922c11f7 100644 --- a/modules/member/member.class.php +++ b/modules/member/member.class.php @@ -73,8 +73,7 @@ class member extends ModuleObject { if(!$config->password_hashing_algorithm) { - $oPassword = new Password(); - $config->password_hashing_algorithm = $oPassword->getBestAlgorithm(); + $config->password_hashing_algorithm = Rhymix\Framework\Password::getBestSupportedAlgorithm(); } if(!$config->password_hashing_work_factor) { diff --git a/modules/member/member.controller.php b/modules/member/member.controller.php index a085d1c4e..6f5ea5af0 100644 --- a/modules/member/member.controller.php +++ b/modules/member/member.controller.php @@ -984,12 +984,11 @@ class memberController extends member } // Insert data into the authentication DB - $oPassword = new Password(); $args = new stdClass(); $args->user_id = $member_info->user_id; $args->member_srl = $member_info->member_srl; - $args->new_password = $oPassword->createTemporaryPassword(8); - $args->auth_key = $oPassword->createSecureSalt(40); + $args->new_password = Rhymix\Framework\Password::getRandomPassword(8); + $args->auth_key = Rhymix\Framework\Security::getRandom(40, 'hex'); $args->is_register = 'N'; $output = executeQuery('member.insertAuthMail', $args); @@ -1093,8 +1092,7 @@ class memberController extends member } // Update to a temporary password and set change_password_date to 1 - $oPassword = new Password(); - $temp_password = $oPassword->createTemporaryPassword(8); + $temp_password = Rhymix\Framework\Password::getRandomPassword(8); $args = new stdClass(); $args->member_srl = $member_srl; @@ -1323,12 +1321,11 @@ class memberController extends member $this->_clearMemberCache($args->member_srl); // generate new auth key - $oPassword = new Password(); $auth_args = new stdClass(); $auth_args->user_id = $memberInfo->user_id; $auth_args->member_srl = $memberInfo->member_srl; $auth_args->new_password = $memberInfo->password; - $auth_args->auth_key = $oPassword->createSecureSalt(40); + $auth_args->auth_key = Rhymix\Framework\Security::getRandom(40, 'hex'); $auth_args->is_register = 'Y'; $output = executeQuery('member.insertAuthMail', $auth_args); @@ -1813,8 +1810,7 @@ class memberController extends member if($keep_signed) { // Key generate for auto login - $oPassword = new Password(); - $random_key = $oPassword->createSecureSalt(32, 'hex'); + $random_key = Rhymix\Framework\Security::getRandom(32, 'hex'); $extra_key = strtolower($user_id).$this->memberInfo->password.$_SERVER['HTTP_USER_AGENT']; $extra_key = substr(hash_hmac('sha256', $extra_key, $random_key), 0, 32); $autologin_args = new stdClass; @@ -2091,12 +2087,11 @@ class memberController extends member if($args->denied == 'Y') { // Insert data into the authentication DB - $oPassword = new Password(); $auth_args = new stdClass(); $auth_args->user_id = $args->user_id; $auth_args->member_srl = $args->member_srl; $auth_args->new_password = $args->password; - $auth_args->auth_key = $oPassword->createSecureSalt(40); + $auth_args->auth_key = Rhymix\Framework\Security::getRandom(40, 'hex'); $auth_args->is_register = 'Y'; $output = executeQuery('member.insertAuthMail', $auth_args); @@ -2552,11 +2547,10 @@ class memberController extends member } unset($_SESSION['rechecked_password_step']); - $oPassword = new Password(); $auth_args = new stdClass(); $auth_args->user_id = $newEmail; $auth_args->member_srl = $member_info->member_srl; - $auth_args->auth_key = $oPassword->createSecureSalt(40); + $auth_args->auth_key = Rhymix\Framework\Security::getRandom(40, 'hex'); $auth_args->new_password = 'XE_change_emaill_address'; $oDB = &DB::getInstance(); diff --git a/modules/member/member.model.php b/modules/member/member.model.php index 073b7ab5b..01750966f 100644 --- a/modules/member/member.model.php +++ b/modules/member/member.model.php @@ -1107,10 +1107,19 @@ class memberModel extends member } // Check the password - $oPassword = new Password(); - $current_algorithm = $oPassword->checkAlgorithm($hashed_password); - $match = $oPassword->checkPassword($password_text, $hashed_password, $current_algorithm); - if(!$match) + $password_match = false; + $current_algorithm = false; + $possible_algorithms = Rhymix\Framework\Password::checkAlgorithm($hashed_password); + foreach ($possible_algorithms as $algorithm) + { + if (Rhymix\Framework\Password::checkPassword($password_text, $hashed_password, $algorithm)) + { + $password_match = true; + $current_algorithm = $algorithm; + break; + } + } + if (!$password_match) { return false; } @@ -1119,22 +1128,26 @@ class memberModel extends member $config = $this->getMemberConfig(); if($member_srl > 0 && $config->password_hashing_auto_upgrade != 'N') { - $need_upgrade = false; - - if(!$need_upgrade) + $required_algorithm = Rhymix\Framework\Password::getDefaultAlgorithm(); + if ($required_algorithm !== $current_algorithm) { - $required_algorithm = $oPassword->getCurrentlySelectedAlgorithm(); - if($required_algorithm !== $current_algorithm) $need_upgrade = true; + $need_upgrade = true; + } + else + { + $required_work_factor = Rhymix\Framework\Password::getWorkFactor(); + $current_work_factor = Rhymix\Framework\Password::checkWorkFactor($hashed_password); + if ($current_work_factor !== false && $required_work_factor > $current_work_factor) + { + $need_upgrade = true; + } + else + { + $need_upgrade = false; + } } - if(!$need_upgrade) - { - $required_work_factor = $oPassword->getWorkFactor(); - $current_work_factor = $oPassword->checkWorkFactor($hashed_password); - if($current_work_factor !== false && $required_work_factor > $current_work_factor) $need_upgrade = true; - } - - if($need_upgrade === true) + if ($need_upgrade) { $args = new stdClass(); $args->member_srl = $member_srl; @@ -1155,8 +1168,7 @@ class memberModel extends member */ function hashPassword($password_text, $algorithm = null) { - $oPassword = new Password(); - return $oPassword->createHash($password_text, $algorithm); + return Rhymix\Framework\Password::hashPassword($password_text, $algorithm); } function checkPasswordStrength($password, $strength) From 69c5147888ea82c99eab318f72b13a49bc5ed11c Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 23:52:26 +0900 Subject: [PATCH 155/318] Add phpass and update composer libraries --- composer.json | 3 +- composer.lock | 67 +++- vendor/composer/autoload_classmap.php | 4 + vendor/composer/autoload_namespaces.php | 1 + vendor/composer/installed.json | 163 +++++---- vendor/hautelook/phpass/.gitignore | 2 + vendor/hautelook/phpass/.travis.yml | 13 + vendor/hautelook/phpass/README.md | 46 +++ vendor/hautelook/phpass/Tests/BasicTest.php | 52 +++ vendor/hautelook/phpass/Tests/bootstrap.php | 14 + vendor/hautelook/phpass/Tests/phpunit.xml | 32 ++ vendor/hautelook/phpass/composer.json | 22 ++ vendor/hautelook/phpass/lib/Makefile | 21 ++ vendor/hautelook/phpass/lib/crypt_private.c | 106 ++++++ .../src/Hautelook/Phpass/PasswordHash.php | 314 ++++++++++++++++++ vendor/matthiasmullie/minify/.coveralls.yml | 3 - vendor/matthiasmullie/minify/CONTRIBUTING.md | 59 ++++ vendor/matthiasmullie/minify/composer.json | 3 +- vendor/matthiasmullie/minify/src/CSS.php | 78 +++-- .../matthiasmullie/minify/src/Exception.php | 4 +- .../minify/src/Exceptions/BasicException.php | 12 + .../src/Exceptions/FileImportException.php | 10 + .../minify/src/Exceptions/IOException.php | 10 + vendor/matthiasmullie/minify/src/JS.php | 22 +- vendor/matthiasmullie/minify/src/Minify.php | 139 +++++--- 25 files changed, 1039 insertions(+), 161 deletions(-) create mode 100644 vendor/hautelook/phpass/.gitignore create mode 100644 vendor/hautelook/phpass/.travis.yml create mode 100644 vendor/hautelook/phpass/README.md create mode 100644 vendor/hautelook/phpass/Tests/BasicTest.php create mode 100644 vendor/hautelook/phpass/Tests/bootstrap.php create mode 100644 vendor/hautelook/phpass/Tests/phpunit.xml create mode 100644 vendor/hautelook/phpass/composer.json create mode 100644 vendor/hautelook/phpass/lib/Makefile create mode 100644 vendor/hautelook/phpass/lib/crypt_private.c create mode 100644 vendor/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php delete mode 100644 vendor/matthiasmullie/minify/.coveralls.yml create mode 100644 vendor/matthiasmullie/minify/CONTRIBUTING.md create mode 100644 vendor/matthiasmullie/minify/src/Exceptions/BasicException.php create mode 100644 vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php create mode 100644 vendor/matthiasmullie/minify/src/Exceptions/IOException.php diff --git a/composer.json b/composer.json index be2c76685..5da1f2385 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ { "name": "NAVER", "email": "developers@xpressengine.com" } ], "require": { - "php": ">=5.3.0", + "php": ">=5.3.3", "ext-curl": "*", "ext-gd": "*", "ext-iconv": "*", @@ -22,6 +22,7 @@ "defuse/php-encryption": "1.2.1", "ezyang/htmlpurifier": "4.7.*", "firephp/firephp-core": "0.4.0", + "hautelook/phpass": "0.3.*", "matthiasmullie/minify": "1.3.*", "michelf/php-markdown": "1.5.*", "rmccue/requests": "1.6.*", diff --git a/composer.lock b/composer.lock index 043cbfd87..05bcf4331 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "a35061b94658a2dbdafe943dddcdc898", - "content-hash": "1a71937e1cbc600f8a237c6445d6a69f", + "hash": "9b062f27815a9b2ef1e700b4664ee864", + "content-hash": "69345a9112733f99c09fa298ba72fa22", "packages": [ { "name": "defuse/php-encryption", @@ -133,17 +133,61 @@ "time": "2013-04-23 15:28:20" }, { - "name": "matthiasmullie/minify", - "version": "1.3.32", + "name": "hautelook/phpass", + "version": "0.3.4", "source": { "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "140c714688908afcecde87338c8309233bdc2519" + "url": "https://github.com/hautelook/phpass.git", + "reference": "f0217d804225822f9bdb0d392839029b0fcb0914" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/140c714688908afcecde87338c8309233bdc2519", - "reference": "140c714688908afcecde87338c8309233bdc2519", + "url": "https://api.github.com/repos/hautelook/phpass/zipball/f0217d804225822f9bdb0d392839029b0fcb0914", + "reference": "f0217d804225822f9bdb0d392839029b0fcb0914", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "psr-0": { + "Hautelook": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Public Domain" + ], + "authors": [ + { + "name": "Solar Designer", + "email": "solar@openwall.com", + "homepage": "http://openwall.com/phpass/" + } + ], + "description": "Portable PHP password hashing framework", + "homepage": "http://github.com/hautelook/phpass/", + "keywords": [ + "blowfish", + "crypt", + "password", + "security" + ], + "time": "2012-08-31 00:00:00" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.34", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "272e46113404f66ced256659552a0cc074a7810f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/272e46113404f66ced256659552a0cc074a7810f", + "reference": "272e46113404f66ced256659552a0cc074a7810f", "shasum": "" }, "require": { @@ -153,8 +197,7 @@ }, "require-dev": { "matthiasmullie/scrapbook": "~1.0", - "phpunit/phpunit": "~4.8", - "satooshi/php-coveralls": "~1.0" + "phpunit/phpunit": "~4.8" }, "bin": [ "bin/minifycss", @@ -187,7 +230,7 @@ "minifier", "minify" ], - "time": "2016-01-11 02:10:11" + "time": "2016-03-01 08:00:27" }, { "name": "matthiasmullie/path-converter", @@ -489,7 +532,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.3.0", + "php": ">=5.3.3", "ext-curl": "*", "ext-gd": "*", "ext-iconv": "*", diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 9a99b797a..b85d24e5d 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -237,8 +237,12 @@ return array( 'HTMLPurifier_VarParser_Flexible' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Flexible.php', 'HTMLPurifier_VarParser_Native' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/VarParser/Native.php', 'HTMLPurifier_Zipper' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier/Zipper.php', + 'Hautelook\\Phpass\\PasswordHash' => $vendorDir . '/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php', 'MatthiasMullie\\Minify\\CSS' => $vendorDir . '/matthiasmullie/minify/src/CSS.php', 'MatthiasMullie\\Minify\\Exception' => $vendorDir . '/matthiasmullie/minify/src/Exception.php', + 'MatthiasMullie\\Minify\\Exceptions\\BasicException' => $vendorDir . '/matthiasmullie/minify/src/Exceptions/BasicException.php', + 'MatthiasMullie\\Minify\\Exceptions\\FileImportException' => $vendorDir . '/matthiasmullie/minify/src/Exceptions/FileImportException.php', + 'MatthiasMullie\\Minify\\Exceptions\\IOException' => $vendorDir . '/matthiasmullie/minify/src/Exceptions/IOException.php', 'MatthiasMullie\\Minify\\JS' => $vendorDir . '/matthiasmullie/minify/src/JS.php', 'MatthiasMullie\\Minify\\Minify' => $vendorDir . '/matthiasmullie/minify/src/Minify.php', 'MatthiasMullie\\PathConverter\\Converter' => $vendorDir . '/matthiasmullie/path-converter/src/Converter.php', diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php index 0ba8d72dc..942fa8072 100644 --- a/vendor/composer/autoload_namespaces.php +++ b/vendor/composer/autoload_namespaces.php @@ -9,5 +9,6 @@ return array( 'Sunra\\PhpSimple\\HtmlDomParser' => array($vendorDir . '/sunra/php-simple-html-dom-parser/Src'), 'Requests' => array($vendorDir . '/rmccue/requests/library'), 'Michelf' => array($vendorDir . '/michelf/php-markdown'), + 'Hautelook' => array($vendorDir . '/hautelook/phpass/src'), 'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'), ); diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index f37668d21..18e6cbbfb 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -293,65 +293,6 @@ "relative" ] }, - { - "name": "matthiasmullie/minify", - "version": "1.3.32", - "version_normalized": "1.3.32.0", - "source": { - "type": "git", - "url": "https://github.com/matthiasmullie/minify.git", - "reference": "140c714688908afcecde87338c8309233bdc2519" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/140c714688908afcecde87338c8309233bdc2519", - "reference": "140c714688908afcecde87338c8309233bdc2519", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "matthiasmullie/path-converter": "~1.0", - "php": ">=5.3.0" - }, - "require-dev": { - "matthiasmullie/scrapbook": "~1.0", - "phpunit/phpunit": "~4.8", - "satooshi/php-coveralls": "~1.0" - }, - "time": "2016-01-11 02:10:11", - "bin": [ - "bin/minifycss", - "bin/minifyjs" - ], - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "MatthiasMullie\\Minify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Matthias Mullie", - "email": "minify@mullie.eu", - "homepage": "http://www.mullie.eu", - "role": "Developer" - } - ], - "description": "CSS & JS minifier", - "homepage": "http://www.minifier.org", - "keywords": [ - "JS", - "css", - "javascript", - "minifier", - "minify" - ] - }, { "name": "swiftmailer/swiftmailer", "version": "v5.4.1", @@ -492,5 +433,109 @@ ], "description": "Traditional FirePHPCore library for sending PHP variables to the browser.", "homepage": "https://github.com/firephp/firephp-core" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.34", + "version_normalized": "1.3.34.0", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "272e46113404f66ced256659552a0cc074a7810f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/272e46113404f66ced256659552a0cc074a7810f", + "reference": "272e46113404f66ced256659552a0cc074a7810f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "matthiasmullie/path-converter": "~1.0", + "php": ">=5.3.0" + }, + "require-dev": { + "matthiasmullie/scrapbook": "~1.0", + "phpunit/phpunit": "~4.8" + }, + "time": "2016-03-01 08:00:27", + "bin": [ + "bin/minifycss", + "bin/minifyjs" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "MatthiasMullie\\Minify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "minify@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "CSS & JS minifier", + "homepage": "http://www.minifier.org", + "keywords": [ + "JS", + "css", + "javascript", + "minifier", + "minify" + ] + }, + { + "name": "hautelook/phpass", + "version": "0.3.4", + "version_normalized": "0.3.4.0", + "source": { + "type": "git", + "url": "https://github.com/hautelook/phpass.git", + "reference": "f0217d804225822f9bdb0d392839029b0fcb0914" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hautelook/phpass/zipball/f0217d804225822f9bdb0d392839029b0fcb0914", + "reference": "f0217d804225822f9bdb0d392839029b0fcb0914", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2012-08-31 00:00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Hautelook": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Public Domain" + ], + "authors": [ + { + "name": "Solar Designer", + "email": "solar@openwall.com", + "homepage": "http://openwall.com/phpass/" + } + ], + "description": "Portable PHP password hashing framework", + "homepage": "http://github.com/hautelook/phpass/", + "keywords": [ + "blowfish", + "crypt", + "password", + "security" + ] } ] diff --git a/vendor/hautelook/phpass/.gitignore b/vendor/hautelook/phpass/.gitignore new file mode 100644 index 000000000..987e2a253 --- /dev/null +++ b/vendor/hautelook/phpass/.gitignore @@ -0,0 +1,2 @@ +composer.lock +vendor diff --git a/vendor/hautelook/phpass/.travis.yml b/vendor/hautelook/phpass/.travis.yml new file mode 100644 index 000000000..c8002896d --- /dev/null +++ b/vendor/hautelook/phpass/.travis.yml @@ -0,0 +1,13 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - composer install + +script: cd Tests && phpunit --configuration phpunit.xml --coverage-text diff --git a/vendor/hautelook/phpass/README.md b/vendor/hautelook/phpass/README.md new file mode 100644 index 000000000..5e1310d41 --- /dev/null +++ b/vendor/hautelook/phpass/README.md @@ -0,0 +1,46 @@ +Openwall Phpass, modernized +=========================== + +[![Build Status](https://secure.travis-ci.org/hautelook/phpass.png?branch=master)](http://travis-ci.org/hautelook/phpass) +[![HHVM Status](http://hhvm.h4cc.de/badge/hautelook/phpass.png)](http://hhvm.h4cc.de/package/hautelook/phpass) + +This is Openwall's [Phpass](http://openwall.com/phpass/), based on the 0.3 release, but modernized slightly: + +- Namespaced +- Composer support (Autoloading) +- PHP 5 style +- Unit Tested + +The changes are minimal and only stylistic. The source code is in the public domain. We claim no ownership, but needed it for one of our projects, and wanted to make it available to other people as well. + +## Installation ## + +Add this requirement to your `composer.json` file and run `composer.phar install`: + + { + "require": { + "hautelook/phpass": "dev-master" + } + } + +## Usage ## + +The following example shows how to hash a password (to then store the hash in the database), and how to check whether a provided password is correct (hashes to the same value): + +``` php +HashPassword('secret'); +var_dump($password); + +$passwordMatch = $passwordHasher->CheckPassword('secret', "$2a$08$0RK6Yw6j9kSIXrrEOc3dwuDPQuT78HgR0S3/ghOFDEpOGpOkARoSu"); +var_dump($passwordMatch); + diff --git a/vendor/hautelook/phpass/Tests/BasicTest.php b/vendor/hautelook/phpass/Tests/BasicTest.php new file mode 100644 index 000000000..bc57036b1 --- /dev/null +++ b/vendor/hautelook/phpass/Tests/BasicTest.php @@ -0,0 +1,52 @@ +HashPassword($correct); + + $this->assertTrue($hasher->CheckPassword($correct, $hash)); + } + + public function testIncorrectHash() + { + $hasher = new PasswordHash(8,false); + $correct = 'test12345'; + $hash = $hasher->HashPassword($correct); + $wrong = 'test12346'; + + $this->assertFalse($hasher->CheckPassword($wrong, $hash)); + } + + public function testWeakHashes() + { + $hasher = new PasswordHash(8, true); + $correct = 'test12345'; + $hash = $hasher->HashPassword($correct); + $wrong = 'test12346'; + + $this->assertTrue($hasher->CheckPassword($correct, $hash)); + $this->assertFalse($hasher->CheckPassword($wrong, $hash)); + } + + public function testPortableHashes() + { + $hasher = new PasswordHash(8, true); + $correct = 'test12345'; + $wrong = 'test12346'; + + $this->assertTrue($hasher->CheckPassword($correct, self::PORTABLE_HASH)); + $this->assertFalse($hasher->CheckPassword($wrong, self::PORTABLE_HASH)); + } +} \ No newline at end of file diff --git a/vendor/hautelook/phpass/Tests/bootstrap.php b/vendor/hautelook/phpass/Tests/bootstrap.php new file mode 100644 index 000000000..6bf33ed1a --- /dev/null +++ b/vendor/hautelook/phpass/Tests/bootstrap.php @@ -0,0 +1,14 @@ + + + + + + + + + + + + . + + + + ../ + + + ../src/Hautelook + + ../ + ./bootstrap.php + + + + \ No newline at end of file diff --git a/vendor/hautelook/phpass/composer.json b/vendor/hautelook/phpass/composer.json new file mode 100644 index 000000000..b37cfc9c1 --- /dev/null +++ b/vendor/hautelook/phpass/composer.json @@ -0,0 +1,22 @@ +{ + "name": "hautelook/phpass", + "type": "library", + "time" : "2012-08-31", + "license" : "Public Domain", + "description": "Portable PHP password hashing framework", + "keywords": ["Blowfish", "crypt", "password", "security"], + "homepage": "http://github.com/hautelook/phpass/", + "authors": [ + { + "name" : "Solar Designer", + "email": "solar@openwall.com", + "homepage": "http://openwall.com/phpass/" + } + ], + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "psr-0": {"Hautelook": "src/"} + } +} diff --git a/vendor/hautelook/phpass/lib/Makefile b/vendor/hautelook/phpass/lib/Makefile new file mode 100644 index 000000000..fe48917f7 --- /dev/null +++ b/vendor/hautelook/phpass/lib/Makefile @@ -0,0 +1,21 @@ +# +# Written by Solar Designer and placed in the public domain. +# See crypt_private.c for more information. +# +CC = gcc +LD = $(CC) +RM = rm -f +CFLAGS = -Wall -O2 -fomit-frame-pointer -funroll-loops +LDFLAGS = -s +LIBS = -lcrypto + +all: crypt_private-test + +crypt_private-test: crypt_private-test.o + $(LD) $(LDFLAGS) $(LIBS) crypt_private-test.o -o $@ + +crypt_private-test.o: crypt_private.c + $(CC) -c $(CFLAGS) crypt_private.c -DTEST -o $@ + +clean: + $(RM) crypt_private-test* diff --git a/vendor/hautelook/phpass/lib/crypt_private.c b/vendor/hautelook/phpass/lib/crypt_private.c new file mode 100644 index 000000000..6abc05bc1 --- /dev/null +++ b/vendor/hautelook/phpass/lib/crypt_private.c @@ -0,0 +1,106 @@ +/* + * This code exists for the sole purpose to serve as another implementation + * of the "private" password hashing method implemened in PasswordHash.php + * and thus to confirm that these password hashes are indeed calculated as + * intended. + * + * Other uses of this code are discouraged. There are much better password + * hashing algorithms available to C programmers; one of those is bcrypt: + * + * http://www.openwall.com/crypt/ + * + * Written by Solar Designer in 2005 and placed in + * the public domain. + * + * There's absolutely no warranty. + */ + +#include +#include + +#ifdef TEST +#include +#endif + +static char *itoa64 = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static void encode64(char *dst, char *src, int count) +{ + int i, value; + + i = 0; + do { + value = (unsigned char)src[i++]; + *dst++ = itoa64[value & 0x3f]; + if (i < count) + value |= (unsigned char)src[i] << 8; + *dst++ = itoa64[(value >> 6) & 0x3f]; + if (i++ >= count) + break; + if (i < count) + value |= (unsigned char)src[i] << 16; + *dst++ = itoa64[(value >> 12) & 0x3f]; + if (i++ >= count) + break; + *dst++ = itoa64[(value >> 18) & 0x3f]; + } while (i < count); +} + +char *crypt_private(char *password, char *setting) +{ + static char output[35]; + MD5_CTX ctx; + char hash[MD5_DIGEST_LENGTH]; + char *p, *salt; + int count_log2, length, count; + + strcpy(output, "*0"); + if (!strncmp(setting, output, 2)) + output[1] = '1'; + + if (strncmp(setting, "$P$", 3)) + return output; + + p = strchr(itoa64, setting[3]); + if (!p) + return output; + count_log2 = p - itoa64; + if (count_log2 < 7 || count_log2 > 30) + return output; + + salt = setting + 4; + if (strlen(salt) < 8) + return output; + + length = strlen(password); + + MD5_Init(&ctx); + MD5_Update(&ctx, salt, 8); + MD5_Update(&ctx, password, length); + MD5_Final(hash, &ctx); + + count = 1 << count_log2; + do { + MD5_Init(&ctx); + MD5_Update(&ctx, hash, MD5_DIGEST_LENGTH); + MD5_Update(&ctx, password, length); + MD5_Final(hash, &ctx); + } while (--count); + + memcpy(output, setting, 12); + encode64(&output[12], hash, MD5_DIGEST_LENGTH); + + return output; +} + +#ifdef TEST +int main(int argc, char **argv) +{ + if (argc != 3) return 1; + + puts(crypt_private(argv[1], argv[2])); + + return 0; +} +#endif diff --git a/vendor/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php b/vendor/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php new file mode 100644 index 000000000..eb363268b --- /dev/null +++ b/vendor/hautelook/phpass/src/Hautelook/Phpass/PasswordHash.php @@ -0,0 +1,314 @@ + in 2004-2006 and placed in + * + * There's absolutely no warranty. + * + * The homepage URL for this framework is: + * + * http://www.openwall.com/phpass/ + * + * Please be sure to update the Version line if you edit this file in any way. + * It is suggested that you leave the main version number intact, but indicate + * your project name (after the slash) and add your own revision information. + * + * Please do not change the "private" password hashing method implemented in + * here, thereby making your hashes incompatible. However, if you must, please + * change the hash type identifier (the "$P$") to something different. + * + * Obviously, since this code is in the public domain, the above are not + * requirements (there can be none), but merely suggestions. + * + * @author Solar Designer + */ +class PasswordHash +{ + private $itoa64; + private $iteration_count_log2; + private $portable_hashes; + private $random_state; + + /** + * Constructor + * + * @param int $iteration_count_log2 + * @param boolean $portable_hashes + */ + public function __construct($iteration_count_log2, $portable_hashes) + { + $this->itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + + if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31) { + $iteration_count_log2 = 8; + } + $this->iteration_count_log2 = $iteration_count_log2; + + $this->portable_hashes = $portable_hashes; + + $this->random_state = microtime(); + if (function_exists('getmypid')) { + $this->random_state .= getmypid(); + } + } + + /** + * @param int $count + * @return String + */ + public function get_random_bytes($count) + { + $output = ''; + if (@is_readable('/dev/urandom') && + ($fh = @fopen('/dev/urandom', 'rb'))) { + $output = fread($fh, $count); + fclose($fh); + } + + if (strlen($output) < $count) { + $output = ''; + for ($i = 0; $i < $count; $i += 16) { + $this->random_state = + md5(microtime() . $this->random_state); + $output .= + pack('H*', md5($this->random_state)); + } + $output = substr($output, 0, $count); + } + + return $output; + } + + /** + * @param String $input + * @param int $count + * @return String + */ + public function encode64($input, $count) + { + $output = ''; + $i = 0; + do { + $value = ord($input[$i++]); + $output .= $this->itoa64[$value & 0x3f]; + if ($i < $count) { + $value |= ord($input[$i]) << 8; + } + $output .= $this->itoa64[($value >> 6) & 0x3f]; + if ($i++ >= $count) { + break; + } + if ($i < $count) { + $value |= ord($input[$i]) << 16; + } + $output .= $this->itoa64[($value >> 12) & 0x3f]; + if ($i++ >= $count) { + break; + } + $output .= $this->itoa64[($value >> 18) & 0x3f]; + } while ($i < $count); + + return $output; + } + + /** + * @param String $input + * @return String + */ + public function gensalt_private($input) + { + $output = '$P$'; + $output .= $this->itoa64[min($this->iteration_count_log2 + + ((PHP_VERSION >= '5') ? 5 : 3), 30)]; + $output .= $this->encode64($input, 6); + + return $output; + } + + /** + * @param String $password + * @param String $setting + * @return String + */ + public function crypt_private($password, $setting) + { + $output = '*0'; + if (substr($setting, 0, 2) == $output) { + $output = '*1'; + } + + $id = substr($setting, 0, 3); + # We use "$P$", phpBB3 uses "$H$" for the same thing + if ($id != '$P$' && $id != '$H$') { + return $output; + } + + $count_log2 = strpos($this->itoa64, $setting[3]); + if ($count_log2 < 7 || $count_log2 > 30) { + return $output; + } + + $count = 1 << $count_log2; + + $salt = substr($setting, 4, 8); + if (strlen($salt) != 8) { + return $output; + } + + // We're kind of forced to use MD5 here since it's the only + // cryptographic primitive available in all versions of PHP + // currently in use. To implement our own low-level crypto + // in PHP would result in much worse performance and + // consequently in lower iteration counts and hashes that are + // quicker to crack (by non-PHP code). + if (PHP_VERSION >= '5') { + $hash = md5($salt . $password, TRUE); + do { + $hash = md5($hash . $password, TRUE); + } while (--$count); + } else { + $hash = pack('H*', md5($salt . $password)); + do { + $hash = pack('H*', md5($hash . $password)); + } while (--$count); + } + + $output = substr($setting, 0, 12); + $output .= $this->encode64($hash, 16); + + return $output; + } + + /** + * @param String $input + * @return String + */ + public function gensalt_extended($input) + { + $count_log2 = min($this->iteration_count_log2 + 8, 24); + // This should be odd to not reveal weak DES keys, and the + // maximum valid value is (2**24 - 1) which is odd anyway. + $count = (1 << $count_log2) - 1; + + $output = '_'; + $output .= $this->itoa64[$count & 0x3f]; + $output .= $this->itoa64[($count >> 6) & 0x3f]; + $output .= $this->itoa64[($count >> 12) & 0x3f]; + $output .= $this->itoa64[($count >> 18) & 0x3f]; + + $output .= $this->encode64($input, 3); + + return $output; + } + + /** + * @param String $input + * @return String + */ + public function gensalt_blowfish($input) + { + // This one needs to use a different order of characters and a + // different encoding scheme from the one in encode64() above. + // We care because the last character in our encoded string will + // only represent 2 bits. While two known implementations of + // bcrypt will happily accept and correct a salt string which + // has the 4 unused bits set to non-zero, we do not want to take + // chances and we also do not want to waste an additional byte + // of entropy. + $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + + $output = '$2a$'; + $output .= chr(ord('0') + $this->iteration_count_log2 / 10); + $output .= chr(ord('0') + $this->iteration_count_log2 % 10); + $output .= '$'; + + $i = 0; + do { + $c1 = ord($input[$i++]); + $output .= $itoa64[$c1 >> 2]; + $c1 = ($c1 & 0x03) << 4; + if ($i >= 16) { + $output .= $itoa64[$c1]; + break; + } + + $c2 = ord($input[$i++]); + $c1 |= $c2 >> 4; + $output .= $itoa64[$c1]; + $c1 = ($c2 & 0x0f) << 2; + + $c2 = ord($input[$i++]); + $c1 |= $c2 >> 6; + $output .= $itoa64[$c1]; + $output .= $itoa64[$c2 & 0x3f]; + } while (1); + + return $output; + } + + /** + * @param String $password + */ + public function HashPassword($password) + { + $random = ''; + + if (CRYPT_BLOWFISH == 1 && !$this->portable_hashes) { + $random = $this->get_random_bytes(16); + $hash = + crypt($password, $this->gensalt_blowfish($random)); + if (strlen($hash) == 60) { + return $hash; + } + } + + if (CRYPT_EXT_DES == 1 && !$this->portable_hashes) { + if (strlen($random) < 3) { + $random = $this->get_random_bytes(3); + } + $hash = + crypt($password, $this->gensalt_extended($random)); + if (strlen($hash) == 20) { + return $hash; + } + } + + if (strlen($random) < 6) { + $random = $this->get_random_bytes(6); + } + + $hash = + $this->crypt_private($password, + $this->gensalt_private($random)); + if (strlen($hash) == 34) { + return $hash; + } + + // Returning '*' on error is safe here, but would _not_ be safe + // in a crypt(3)-like function used _both_ for generating new + // hashes and for validating passwords against existing hashes. + return '*'; + } + + /** + * @param String $password + * @param String $stored_hash + * @return boolean + */ + public function CheckPassword($password, $stored_hash) + { + $hash = $this->crypt_private($password, $stored_hash); + if ($hash[0] == '*') { + $hash = crypt($password, $stored_hash); + } + + return $hash === $stored_hash; + } +} diff --git a/vendor/matthiasmullie/minify/.coveralls.yml b/vendor/matthiasmullie/minify/.coveralls.yml deleted file mode 100644 index 09bbb257d..000000000 --- a/vendor/matthiasmullie/minify/.coveralls.yml +++ /dev/null @@ -1,3 +0,0 @@ -src_dir: src -coverage_clover: build/logs/clover.xml -json_path: build/logs/coveralls-upload.json diff --git a/vendor/matthiasmullie/minify/CONTRIBUTING.md b/vendor/matthiasmullie/minify/CONTRIBUTING.md new file mode 100644 index 000000000..226cf976b --- /dev/null +++ b/vendor/matthiasmullie/minify/CONTRIBUTING.md @@ -0,0 +1,59 @@ +# How to contribute + + +## Issues + +When [filing bugs](https://github.com/matthiasmullie/minify/issues/new), +try to be as thorough as possible: +* What version did you use? +* What did you try to do? ***Please post the relevant parts of your code.*** +* What went wrong? ***Please include error messages, if any.*** +* What was the expected result? + + +## Pull requests + +Bug fixes and general improvements to the existing codebase are always welcome. +New features are also welcome, but will be judged on an individual basis. If +you'd rather not risk wasting your time implementing a new feature only to see +it turned down, please start the discussion by +[opening an issue](https://github.com/matthiasmullie/minify/issues/new). + +Don't forget to add your changes to the [changelog](CHANGELOG.md). + + +### Testing + +Please include tests for every change or addition to the code. +To run the complete test suite: + +```sh +vendor/bin/phpunit +``` + +When submitting a new pull request, please make sure that that the test suite +passes (Travis CI will run it & report back on your pull request.) + +To run the tests on Windows, run `tests/convert_symlinks_to_windows_style.sh` +from the command line in order to convert Linux-style test symlinks to +Windows-style. + + +### Coding standards + +All code must follow [PSR-2](http://www.php-fig.org/psr/psr-2/). Just make sure +to run php-cs-fixer before submitting the code, it'll take care of the +formatting for you: + +```sh +vendor/bin/php-cs-fixer fix src +vendor/bin/php-cs-fixer fix tests +``` + +Document the code thoroughly! + + +## License + +Note that minify is MIT-licensed, which basically allows anyone to do +anything they like with it, without restriction. diff --git a/vendor/matthiasmullie/minify/composer.json b/vendor/matthiasmullie/minify/composer.json index 8f81f24a9..ae1bdf0db 100644 --- a/vendor/matthiasmullie/minify/composer.json +++ b/vendor/matthiasmullie/minify/composer.json @@ -20,8 +20,7 @@ }, "require-dev": { "matthiasmullie/scrapbook": "~1.0", - "phpunit/phpunit": "~4.8", - "satooshi/php-coveralls": "~1.0" + "phpunit/phpunit": "~4.8" }, "autoload": { "psr-4": { diff --git a/vendor/matthiasmullie/minify/src/CSS.php b/vendor/matthiasmullie/minify/src/CSS.php index 3d2de11f5..ac9ff1ef2 100644 --- a/vendor/matthiasmullie/minify/src/CSS.php +++ b/vendor/matthiasmullie/minify/src/CSS.php @@ -2,6 +2,7 @@ namespace MatthiasMullie\Minify; +use MatthiasMullie\Minify\Exceptions\FileImportException; use MatthiasMullie\PathConverter\Converter; /** @@ -68,7 +69,7 @@ class CSS extends Minify /** * Move any import statements to the top. * - * @param $content string Nearly finished CSS content + * @param string $content Nearly finished CSS content * * @return string */ @@ -94,12 +95,15 @@ class CSS extends Minify * @import's will be loaded and their content merged into the original file, * to save HTTP requests. * - * @param string $source The file to combine imports for. - * @param string $content The CSS content to combine imports for. + * @param string $source The file to combine imports for. + * @param string $content The CSS content to combine imports for. + * @param string[] $parents Parent paths, for circular reference checks. * * @return string + * + * @throws FileImportException */ - protected function combineImports($source, $content) + protected function combineImports($source, $content, $parents) { $importRegexes = array( // @import url(xxx) @@ -208,14 +212,20 @@ class CSS extends Minify // only replace the import with the content if we can grab the // content of the file - if (strlen($importPath) < PHP_MAXPATHLEN && file_exists($importPath) && is_file($importPath)) { + if ($this->canImportFile($importPath)) { + // check if current file was not imported previously in the same + // import chain. + if (in_array($importPath, $parents)) { + throw new FileImportException('Failed to import file "'.$importPath.'": circular reference detected.'); + } + // grab referenced file & minify it (which may include importing // yet other @import statements recursively) $minifier = new static($importPath); - $importContent = $minifier->execute($source); + $importContent = $minifier->execute($source, $parents); // check if this is only valid for certain media - if ($match['media']) { + if (!empty($match['media'])) { $importContent = '@media '.$match['media'].'{'.$importContent.'}'; } @@ -259,20 +269,15 @@ class CSS extends Minify // only replace the import with the content if we're able to get // the content of the file, and it's relatively small - $import = file_exists($path); - $import = $import && is_file($path); - $import = $import && filesize($path) <= $this->maxImportSize * 1024; - if (!$import) { - continue; + if ($this->canImportFile($path) && $this->canImportBySize($path)) { + // grab content && base64-ize + $importContent = $this->load($path); + $importContent = base64_encode($importContent); + + // build replacement + $search[] = $match[0]; + $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')'; } - - // grab content && base64-ize - $importContent = $this->load($path); - $importContent = base64_encode($importContent); - - // build replacement - $search[] = $match[0]; - $replace[] = 'url('.$this->importExtensions[$extension].';base64,'.$importContent.')'; } // replace the import statements @@ -286,15 +291,16 @@ class CSS extends Minify * Minify the data. * Perform CSS optimizations. * - * @param string[optional] $path Path to write the data to. + * @param string[optional] $path Path to write the data to. + * @param string[] $parents Parent paths, for circular reference checks. * * @return string The minified data. */ - public function execute($path = null) + public function execute($path = null, $parents = array()) { $content = ''; - // loop files + // loop css data (raw data and files) foreach ($this->data as $source => $css) { /* * Let's first take out strings & comments, since we can't just remove @@ -314,8 +320,9 @@ class CSS extends Minify // restore the string we've extracted earlier $css = $this->restoreExtractedData($css); - $source = $source ?: ''; - $css = $this->combineImports($source, $css); + $source = is_int($source) ? '' : $source; + $parents = $source ? array_merge($parents, array($source)) : $parents; + $css = $this->combineImports($source, $css, $parents); $css = $this->importFiles($source, $css); /* @@ -443,8 +450,15 @@ class CSS extends Minify // determine if it's a url() or an @import match $type = (strpos($match[0], '@import') === 0 ? 'import' : 'url'); + // attempting to interpret GET-params makes no sense, so let's discard them for awhile + $params = strrchr($match['path'], '?'); + $url = $params ? substr($match['path'], 0, -strlen($params)) : $match['path']; + // fix relative url - $url = $converter->convert($match['path']); + $url = $converter->convert($url); + + // now that the path has been converted, re-apply GET-params + $url .= $params; // build replacement $search[] = $match[0]; @@ -569,4 +583,16 @@ class CSS extends Minify return trim($content); } + + /** + * Check if file is small enough to be imported. + * + * @param string $path The path to the file. + * + * @return bool + */ + protected function canImportBySize($path) + { + return ($size = @filesize($path)) && $size <= $this->maxImportSize * 1024; + } } diff --git a/vendor/matthiasmullie/minify/src/Exception.php b/vendor/matthiasmullie/minify/src/Exception.php index 5f2af0dea..0cb3fab5e 100644 --- a/vendor/matthiasmullie/minify/src/Exception.php +++ b/vendor/matthiasmullie/minify/src/Exception.php @@ -3,8 +3,10 @@ namespace MatthiasMullie\Minify; /** + * @deprecated Use Exceptions\BasicException instead + * * @author Matthias Mullie */ -class Exception extends \Exception +abstract class Exception extends \Exception { } diff --git a/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php b/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php new file mode 100644 index 000000000..a6328f4e4 --- /dev/null +++ b/vendor/matthiasmullie/minify/src/Exceptions/BasicException.php @@ -0,0 +1,12 @@ + + */ +abstract class BasicException extends Exception +{ +} diff --git a/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php b/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php new file mode 100644 index 000000000..98fc341cc --- /dev/null +++ b/vendor/matthiasmullie/minify/src/Exceptions/FileImportException.php @@ -0,0 +1,10 @@ + + */ +class FileImportException extends BasicException +{ +} diff --git a/vendor/matthiasmullie/minify/src/Exceptions/IOException.php b/vendor/matthiasmullie/minify/src/Exceptions/IOException.php new file mode 100644 index 000000000..9b590742c --- /dev/null +++ b/vendor/matthiasmullie/minify/src/Exceptions/IOException.php @@ -0,0 +1,10 @@ + + */ +class IOException extends BasicException +{ +} diff --git a/vendor/matthiasmullie/minify/src/JS.php b/vendor/matthiasmullie/minify/src/JS.php index f0bd4fbcf..59e0da88a 100644 --- a/vendor/matthiasmullie/minify/src/JS.php +++ b/vendor/matthiasmullie/minify/src/JS.php @@ -263,12 +263,20 @@ class JS extends Minify // strip whitespace that ends in (or next line begin with) an operator // that allows statements to be broken up over multiple lines unset($before['+'], $before['-'], $after['+'], $after['-']); - $content = preg_replace('/('.implode('|', $before).')\s+/', '\\1', $content); - $content = preg_replace('/\s+('.implode('|', $after).')/', '\\1', $content); + $content = preg_replace( + array( + '/('.implode('|', $before).')\s+/', + '/\s+('.implode('|', $after).')/', + ), '\\1', $content + ); // make sure + and - can't be mistaken for, or joined into ++ and -- - $content = preg_replace('/(?getKeywordsForRegex($keywords); $keywords = '(?canImportFile($data)) { + $data = file_get_contents($data); + + // strip BOM, if any + if (substr($data, 0, 3) == "\xef\xbb\xbf") { + $data = substr($data, 3); + } + } + + return $data; + } + + /** + * Save to file. + * + * @param string $content The minified data. + * @param string $path The path to save the minified data to. + * + * @throws IOException + */ + protected function save($content, $path) + { + $handler = $this->openFileForWriting($path); + + $this->writeToFile($handler, $content); + + @fclose($handler); + } + /** * Register a pattern to execute against the source content. * * @param string $pattern PCRE pattern. * @param string|callable $replacement Replacement value for matched pattern. - * - * @throws Exception */ protected function registerPattern($pattern, $replacement = '') { @@ -316,7 +308,7 @@ abstract class Minify * placeholder text, so we've rid all strings from characters that may be * misinterpreted. Original string content will be saved in $this->extracted * and after doing all other minifying, we can restore the original content - * via restoreStrings() + * via restoreStrings(). * * @param string[optional] $chars */ @@ -325,7 +317,8 @@ abstract class Minify // PHP only supports $this inside anonymous functions since 5.4 $minifier = $this; $callback = function ($match) use ($minifier) { - if (!$match[1]) { + // check the second index here, because the first always contains a quote + if ($match[2] === '') { /* * Empty strings need no placeholder; they can't be confused for * anything else anyway. @@ -379,4 +372,50 @@ abstract class Minify return $content; } + + /** + * Check if the path is a regular file and can be read. + * + * @param string $path + * + * @return bool + */ + protected function canImportFile($path) + { + return strlen($path) < PHP_MAXPATHLEN && is_file($path) && is_readable($path); + } + + /** + * Attempts to open file specified by $path for writing. + * + * @param string $path The path to the file. + * + * @return resource Specifier for the target file. + * + * @throws IOException + */ + protected function openFileForWriting($path) + { + if (($handler = @fopen($path, 'w')) === false) { + throw new IOException('The file "'.$path.'" could not be opened for writing. Check if PHP has enough permissions.'); + } + + return $handler; + } + + /** + * Attempts to write $content to the file specified by $handler. $path is used for printing exceptions. + * + * @param resource $handler The resource to write to. + * @param string $content The content to write. + * @param string $path The path to the file (for exception printing only). + * + * @throws IOException + */ + protected function writeToFile($handler, $content, $path = '') + { + if (($result = @fwrite($handler, $content)) === false || ($result < strlen($content))) { + throw new IOException('The file "'.$path.'" could not be written to. Check your disk space and file permissions.'); + } + } } From de0d49b9f3f526ff81344387bbe9a8964510f119 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 13 Mar 2016 23:56:04 +0900 Subject: [PATCH 156/318] Add more algorithms to unit test --- tests/unit/framework/PasswordTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/unit/framework/PasswordTest.php b/tests/unit/framework/PasswordTest.php index 610092653..daa5229ed 100644 --- a/tests/unit/framework/PasswordTest.php +++ b/tests/unit/framework/PasswordTest.php @@ -69,12 +69,18 @@ class PasswordTest extends \Codeception\TestCase\Test $this->assertEquals(60, strlen($hash)); $this->assertTrue(Rhymix\Framework\Password::checkPassword($password, $hash, $algos)); - $algos = array('pbkdf2'); + $algos = array('sha384', 'pbkdf2'); $hash = Rhymix\Framework\Password::hashPassword($password, $algos); $this->assertRegExp('/^(sha256|sha512):[0-9]+:/', $hash); $this->assertEquals(60, strlen($hash)); $this->assertTrue(Rhymix\Framework\Password::checkPassword($password, $hash, $algos)); + $algos = array('sha1', 'portable'); + $hash = Rhymix\Framework\Password::hashPassword($password, $algos); + $this->assertRegExp('/^\$P\$/', $hash); + $this->assertEquals(34, strlen($hash)); + $this->assertTrue(Rhymix\Framework\Password::checkPassword($password, $hash, $algos)); + foreach (array('drupal', 'joomla', 'kimsqrb', 'mysql_old_password', 'mysql_new_password', 'mssql_pwdencrypt') as $algo) { $hash = Rhymix\Framework\Password::hashPassword($password, $algo); From 9c653d210b71669ace013bc5f1861edf79834d63 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Mon, 14 Mar 2016 09:41:34 +0900 Subject: [PATCH 157/318] added a column for administrators. --- modules/board/board.controller.php | 13 ++++++++----- modules/board/lang/ko.php | 1 + modules/board/skins/xedition/board.default.css | 7 +++++++ modules/board/skins/xedition/update_view.html | 4 ++-- modules/document/document.class.php | 9 +++++++++ modules/document/document.controller.php | 6 ++++++ modules/document/document.model.php | 13 +++++++++++++ .../document/queries/getUpdateLogAdminisExists.xml | 11 +++++++++++ .../document/queries/insertDocumentUpdateLog.xml | 1 + modules/document/schemas/document_update_log.xml | 1 + 10 files changed, 59 insertions(+), 7 deletions(-) create mode 100644 modules/document/queries/getUpdateLogAdminisExists.xml diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index e2d38bd98..0b78fdfc6 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -50,6 +50,10 @@ class boardController extends board unset($obj->title_color); unset($obj->title_bold); } + else + { + $obj->is_admin = 'Y'; + } // generate document module model object $oDocumentModel = getModel('document'); @@ -227,12 +231,11 @@ class boardController extends board $isadminDocument = false; if($logged_info->is_admin != 'Y') { - $update_log_list = $oDocumentModel->getDocumentUpdateLog($update_log->document_srl); - foreach($update_log_list->data as $val) + $update_log_list = $oDocumentModel->getUpdateLogAdminisExists($update_log->document_srl); + + foreach($update_log_list as $val) { - $oMemberModel = getModel('member'); - $member_info = $oMemberModel->getMemberInfoByMemberSrl($val->update_member_srl); - if($member_info->is_admin === 'Y') + if($val->is_admin == 'Y') { $isadminDocument = true; break; diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index 0c627e9d1..988bdc19f 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -65,3 +65,4 @@ $lang->msg_no_update_log = '업데이트 로그가 존재하지 않습니다.'; $lang->cmd_modify_by_update_log = '이 로그로 게시물을 수정하기'; $lang->msg_admin_update_log = '관리자가 수정한 적이 있는 게시물입니다. 관리자에게 문의하세요.'; $lang->msg_update_log_revert = '정말로 이 게시물로 되돌리시겠습니까?'; +$lang->write_admin = '관리자작성'; diff --git a/modules/board/skins/xedition/board.default.css b/modules/board/skins/xedition/board.default.css index 30022f34c..92fd8f4c9 100644 --- a/modules/board/skins/xedition/board.default.css +++ b/modules/board/skins/xedition/board.default.css @@ -455,6 +455,13 @@ text-overflow: ellipsis; color: #555; } +.read_header h1 span.is_admin { + font-size: 15px; + font-weight: normal; + line-height:15px; + color:#FF6C00; +} + .read_header h1 a { text-decoration: none; color: #444; diff --git a/modules/board/skins/xedition/update_view.html b/modules/board/skins/xedition/update_view.html index 487b11568..bfbffda3c 100644 --- a/modules/board/skins/xedition/update_view.html +++ b/modules/board/skins/xedition/update_view.html @@ -5,7 +5,7 @@ - + diff --git a/modules/document/document.class.php b/modules/document/document.class.php index 17d9d0530..993adcd25 100644 --- a/modules/document/document.class.php +++ b/modules/document/document.class.php @@ -127,6 +127,9 @@ class document extends ModuleObject // 2016. 1. 27: Add a column(declare_message) for report if(!$oDB->isColumnExists("document_declared_log","declare_message")) return true; + // 2016. 3. 14 Add a column(document_upate_log) for admin + if(!$oDB->isColumnExists('document_update_log', 'is_admin')) return true; + return false; } @@ -328,6 +331,12 @@ class document extends ModuleObject $oDB->addColumn('document_declared_log',"declare_message","text"); } + // 2016. 3. 14 Add a column(document_update_log) for admin + if(!$oDB->isColumnExists('document_update_log', 'is_admin')) + { + $oDB->addColumn('document_update_log', 'is_admin', 'varchar', 1); + } + return new Object(0,'success_updated'); } diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index eb59687f8..593f6ea25 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -476,6 +476,7 @@ class documentController extends document { $obj->extra_vars = serialize($extra_vars); $update_output = $this->insertDocumentUpdateLog($obj); + if(!$update_output->toBool()) { $oDB->rollback(); @@ -749,6 +750,10 @@ class documentController extends document if($obj->update_log_setting === 'Y') { $obj->extra_vars = serialize($extra_vars); + if($this->grant->manager) + { + $obj->is_admin = 'Y'; + } $update_output = $this->insertDocumentUpdateLog($obj, $source_obj); if(!$update_output->toBool()) { @@ -816,6 +821,7 @@ class documentController extends document $update_args->tags = $obj->tags; $update_args->extra_vars = $obj->extra_vars; $update_args->reason_update = $obj->reason_update; + $update_args->is_admin = $obj->is_admin; $update_output = executeQuery('document.insertDocumentUpdateLog', $update_args); return $update_output; diff --git a/modules/document/document.model.php b/modules/document/document.model.php index ac5df7e32..6cbff5dcb 100644 --- a/modules/document/document.model.php +++ b/modules/document/document.model.php @@ -1567,6 +1567,19 @@ class documentModel extends document return $updage_log; } + + function getUpdateLogAdminisExists($document_srl = null) + { + if($document_srl == null) + { + return; + } + $args = new stdClass(); + $args->document_srl = $document_srl; + $output = executeQueryArray('document.getUpdateLogAdminisExists', $args); + + return $output->data; + } } /* End of file document.model.php */ /* Location: ./modules/document/document.model.php */ diff --git a/modules/document/queries/getUpdateLogAdminisExists.xml b/modules/document/queries/getUpdateLogAdminisExists.xml new file mode 100644 index 000000000..18fee9ed8 --- /dev/null +++ b/modules/document/queries/getUpdateLogAdminisExists.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/modules/document/queries/insertDocumentUpdateLog.xml b/modules/document/queries/insertDocumentUpdateLog.xml index 921dd1b51..e92360a85 100644 --- a/modules/document/queries/insertDocumentUpdateLog.xml +++ b/modules/document/queries/insertDocumentUpdateLog.xml @@ -18,5 +18,6 @@ + diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index 85a99283a..05cf6d863 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -15,4 +15,5 @@ +
    From f15a4c88615470aa5f765af28771b4923dc800ec Mon Sep 17 00:00:00 2001 From: BJRambo Date: Mon, 14 Mar 2016 09:44:59 +0900 Subject: [PATCH 158/318] rename method. --- modules/board/board.controller.php | 2 +- modules/board/conf/module.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index 0b78fdfc6..a7fc4e2b3 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -215,7 +215,7 @@ class boardController extends board $this->setMessage($msg_code); } - function procBoardUpdateDocument() + function procBoardRevertDocument() { $update_id = Context::get('update_id'); $logged_info = Context::get('logged_info'); diff --git a/modules/board/conf/module.xml b/modules/board/conf/module.xml index 8551bed96..dfa619e9b 100644 --- a/modules/board/conf/module.xml +++ b/modules/board/conf/module.xml @@ -80,7 +80,7 @@ - + From e37a7adcc7f39911786a14e21978a48633136923 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Mon, 14 Mar 2016 09:51:47 +0900 Subject: [PATCH 159/318] rename update method. --- modules/board/tpl/filter/update.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/board/tpl/filter/update.xml b/modules/board/tpl/filter/update.xml index a4ae8bb65..a55476429 100644 --- a/modules/board/tpl/filter/update.xml +++ b/modules/board/tpl/filter/update.xml @@ -1,4 +1,4 @@ - + From e9acd7fe14283986a08bd5f44d025c20d2d8fc12 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Mon, 14 Mar 2016 10:03:58 +0900 Subject: [PATCH 160/318] Improved problem reverting records didn't write --- modules/board/board.controller.php | 2 ++ modules/board/lang/ko.php | 1 + 2 files changed, 3 insertions(+) diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index a7fc4e2b3..9d7865674 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -259,6 +259,8 @@ class boardController extends board $obj->title_bold = $update_log->title_bold; $obj->title_color = $update_log->title_color; $obj->content = $update_log->content; + $obj->update_log_setting = 'Y'; + $obj->reason_update = lang('board.revert_reason_update'); $output = $oDocumentController->updateDocument($oDocument, $obj); $this->setRedirectUrl(getNotEncodedUrl('', 'mid', Context::get('mid'),'act', '', 'document_srl', $update_log->document_srl)); $this->add('mid', Context::get('mid')); diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index 988bdc19f..215d099e3 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -66,3 +66,4 @@ $lang->cmd_modify_by_update_log = '이 로그로 게시물을 수정하기'; $lang->msg_admin_update_log = '관리자가 수정한 적이 있는 게시물입니다. 관리자에게 문의하세요.'; $lang->msg_update_log_revert = '정말로 이 게시물로 되돌리시겠습니까?'; $lang->write_admin = '관리자작성'; +$lang->revert_reason_update = '작성글을 현재글로 되돌림'; From 39cc333f333752b156806cff2faf88d9f9c55e20 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Mon, 14 Mar 2016 11:10:43 +0900 Subject: [PATCH 161/318] add index is_admin column, and more improving. --- modules/board/board.controller.php | 14 ++------------ modules/document/document.class.php | 1 + modules/document/document.model.php | 10 ++++++++-- .../document/queries/getUpdateLogAdminisExists.xml | 3 ++- modules/document/schemas/document_update_log.xml | 2 +- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/modules/board/board.controller.php b/modules/board/board.controller.php index 9d7865674..4b726a63a 100644 --- a/modules/board/board.controller.php +++ b/modules/board/board.controller.php @@ -228,20 +228,10 @@ class boardController extends board $oDocumentController = getController('document'); $update_log = $oDocumentModel->getUpdateLog($update_id); - $isadminDocument = false; if($logged_info->is_admin != 'Y') { - $update_log_list = $oDocumentModel->getUpdateLogAdminisExists($update_log->document_srl); - - foreach($update_log_list as $val) - { - if($val->is_admin == 'Y') - { - $isadminDocument = true; - break; - } - } - if($isadminDocument === true) + $Exists_log = $oDocumentModel->getUpdateLogAdminisExists($update_log->document_srl); + if($Exists_log === true) { return new Object(-1, 'msg_admin_update_log'); } diff --git a/modules/document/document.class.php b/modules/document/document.class.php index 993adcd25..3eef195d0 100644 --- a/modules/document/document.class.php +++ b/modules/document/document.class.php @@ -335,6 +335,7 @@ class document extends ModuleObject if(!$oDB->isColumnExists('document_update_log', 'is_admin')) { $oDB->addColumn('document_update_log', 'is_admin', 'varchar', 1); + $oDB->addIndex('document_update_log', 'idx_is_admin', array('is_admin')); } return new Object(0,'success_updated'); diff --git a/modules/document/document.model.php b/modules/document/document.model.php index 6cbff5dcb..16e345d59 100644 --- a/modules/document/document.model.php +++ b/modules/document/document.model.php @@ -1576,9 +1576,15 @@ class documentModel extends document } $args = new stdClass(); $args->document_srl = $document_srl; - $output = executeQueryArray('document.getUpdateLogAdminisExists', $args); + $args->is_admin = 'Y'; + $output = executeQuery('document.getUpdateLogAdminisExists', $args); - return $output->data; + if($output->data->count > 0) + { + return true; + } + + return false; } } /* End of file document.model.php */ diff --git a/modules/document/queries/getUpdateLogAdminisExists.xml b/modules/document/queries/getUpdateLogAdminisExists.xml index 18fee9ed8..7074c565c 100644 --- a/modules/document/queries/getUpdateLogAdminisExists.xml +++ b/modules/document/queries/getUpdateLogAdminisExists.xml @@ -3,9 +3,10 @@ - + + diff --git a/modules/document/schemas/document_update_log.xml b/modules/document/schemas/document_update_log.xml index 05cf6d863..fee66b4bd 100644 --- a/modules/document/schemas/document_update_log.xml +++ b/modules/document/schemas/document_update_log.xml @@ -15,5 +15,5 @@ - +
    From aab6b2ad625f04aa8e5c2ab8183fb168b4dcc07f Mon Sep 17 00:00:00 2001 From: BJRambo Date: Mon, 14 Mar 2016 11:12:56 +0900 Subject: [PATCH 162/318] Language improvement --- modules/board/lang/ko.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/board/lang/ko.php b/modules/board/lang/ko.php index 215d099e3..23e90484a 100644 --- a/modules/board/lang/ko.php +++ b/modules/board/lang/ko.php @@ -64,6 +64,6 @@ $lang->msg_no_update_id = '업데이트 고유 번호는 필수입니다.'; $lang->msg_no_update_log = '업데이트 로그가 존재하지 않습니다.'; $lang->cmd_modify_by_update_log = '이 로그로 게시물을 수정하기'; $lang->msg_admin_update_log = '관리자가 수정한 적이 있는 게시물입니다. 관리자에게 문의하세요.'; -$lang->msg_update_log_revert = '정말로 이 게시물로 되돌리시겠습니까?'; +$lang->msg_update_log_revert = '정말로 이 버전으로 되돌리시겠습니까?'; $lang->write_admin = '관리자작성'; -$lang->revert_reason_update = '작성글을 현재글로 되돌림'; +$lang->revert_reason_update = '이 버전으로 되돌림'; From 13a67f3496000964b2031af86f050d4e2927b186 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 14 Mar 2016 11:51:32 +0900 Subject: [PATCH 163/318] Implement URL::modifyURL() --- common/framework/url.php | 43 ++++++++++++++++++++++++-------- tests/unit/framework/URLTest.php | 22 ++++++++++++++++ 2 files changed, 55 insertions(+), 10 deletions(-) diff --git a/common/framework/url.php b/common/framework/url.php index 1829fbe5c..8fc370bdb 100644 --- a/common/framework/url.php +++ b/common/framework/url.php @@ -21,19 +21,15 @@ class URL $proto = \RX_SSL ? 'https://' : 'http://'; $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; $local = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; + $url = $proto . $host . $local; if (count($changes)) { - if (($qpos = strpos($local, '?')) !== false) - { - $querystring = substr($local, $qpos + 1); - $local = substr($local, 0, $qpos); - parse_str($querystring, $args); - $changes = array_merge($args, $changes); - } - $changes = array_filter($changes, function($val) { return $val !== null; }); - $local = $local . '?' . http_build_query($changes); + return self::modifyURL($url, $changes); + } + else + { + return self::getCanonicalURL($url); } - return self::getCanonicalURL($proto . $host) . $local; } /** @@ -102,6 +98,33 @@ class URL return false; } + /** + * Modify a URL. + * + * If $changes are given, they will be appended to the current URL as a query string. + * To delete an existing query string, set its value to null. + * + * @param string $url + * @param array $changes + * @return string + */ + public static function modifyURL($url, array $changes = array()) + { + $url = parse_url(self::getCanonicalURL($url)); + $prefix = sprintf('%s://%s%s%s', $url['scheme'], $url['host'], ($url['port'] ? (':' . $url['port']) : ''), $url['path']); + parse_str($url['query'], $args); + $changes = array_merge($args, $changes); + $changes = array_filter($changes, function($val) { return $val !== null; }); + if (count($changes)) + { + return $prefix . '?' . http_build_query($changes); + } + else + { + return $prefix; + } + } + /** * Encode UTF-8 domain into IDNA (punycode) * diff --git a/tests/unit/framework/URLTest.php b/tests/unit/framework/URLTest.php index 93410ed58..d36dd5fe6 100644 --- a/tests/unit/framework/URLTest.php +++ b/tests/unit/framework/URLTest.php @@ -18,6 +18,9 @@ class URLTest extends \Codeception\TestCase\Test // Removing item from the query string $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks', Rhymix\Framework\URL::getCurrentURL(array('foo' => null))); + // Removing all items from the query string + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php', Rhymix\Framework\URL::getCurrentURL(array('foo' => null, 'xe' => null))); + // Adding and removing parameters at the same time $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks&l=ko', Rhymix\Framework\URL::getCurrentURL(array('l' => 'ko', 'foo' => null))); } @@ -55,6 +58,25 @@ class URLTest extends \Codeception\TestCase\Test } } + public function testModifyURL() + { + $protocol = \RX_SSL ? 'https://' : 'http://'; + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + $url = $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php?foo=bar'; + + // Conversion to absolute + $this->assertEquals($url, Rhymix\Framework\URL::modifyURL('./index.php?foo=bar')); + + // Adding items to the query string + $this->assertEquals($url . '&var=1&arr%5B0%5D=2&arr%5B1%5D=3', Rhymix\Framework\URL::modifyURL($url, array('var' => '1', 'arr' => array(2, 3)))); + + // Removing item from the query string + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php', Rhymix\Framework\URL::modifyURL($url, array('foo' => null))); + + // Adding and removing parameters at the same time + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php?l=ko', Rhymix\Framework\URL::modifyURL($url, array('l' => 'ko', 'foo' => null))); + } + public function testIsInternalURL() { // This function is checked in Security::checkCSRF() From 19ad1d1ac45c83776f22729e646d7fb348cd4b8e Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 14 Mar 2016 13:16:02 +0900 Subject: [PATCH 164/318] Use encryption and URL functions to improve SSO --- classes/context/Context.class.php | 57 +++++++++++++++++-------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 44ec47d6d..94fc3d848 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -712,61 +712,66 @@ class Context $current_site = self::getRequestUri(); // Step 1: if the current site is not the default site, send SSO validation request to the default site - if($default_url !== $current_site && !self::get('SSOID') && $_COOKIE['sso'] !== md5($current_site)) + if($default_url !== $current_site && !self::get('sso_response') && $_COOKIE['sso'] !== md5($current_site)) { // Set sso cookie to prevent multiple simultaneous SSO validation requests setcookie('sso', md5($current_site), 0, '/'); // Redirect to the default site - $redirect_url = sprintf('%s?return_url=%s', $default_url, urlencode(base64_encode($current_site))); + $sso_request = Rhymix\Framework\Security::encrypt(Rhymix\Framework\URL::getCurrentURL()); + $redirect_url = $default_url . '?sso_request=' . urlencode($sso_request); header('Location:' . $redirect_url); - return FALSE; + return false; } // Step 2: receive and process SSO validation request at the default site - if($default_url === $current_site && self::get('return_url')) + if($default_url === $current_site && self::get('sso_request')) { // Get the URL of the origin site - $url = base64_decode(self::get('return_url')); - $url_info = parse_url($url); + $sso_request = Rhymix\Framework\Security::decrypt(self::get('sso_request')); + if (!$sso_request || !preg_match('!^https?://!', $sso_request)) + { + self::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); + return false; + } // Check that the origin site is a valid site in this XE installation (to prevent open redirect vuln) if(!getModel('module')->getSiteInfoByDomain(rtrim($url, '/'))->site_srl) { - htmlHeader(); - echo self::getLang("msg_invalid_request"); - htmlFooter(); - return FALSE; + self::displayErrorPage('SSO Error', 'Invalid SSO Request', 400); + return false; } // Redirect back to the origin site - $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'] ? ('?' . $url_info['query']) : '')); - header('Location:' . $redirect_url); - return FALSE; + $sso_response = Rhymix\Framework\Security::encrypt(session_id()); + header('Location: ' . Rhymix\Framework\URL::modifyURL($sso_request, array('sso_response' => $sso_response))); + return false; } // Step 3: back at the origin site, set session ID to be the same as the default site - if($default_url !== $current_site && self::get('SSOID')) + if($default_url !== $current_site && self::get('sso_response')) { - // Check that the session ID was given by the default site (to prevent session fixation CSRF) + // Check SSO response + $sso_response = Rhymix\Framework\Security::decrypt(self::get('sso_response')); + if ($sso_response === false) + { + self::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); + return false; + } + + // Check that the response was given by the default site (to prevent session fixation CSRF) if(isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $default_url) !== 0) { - htmlHeader(); - echo self::getLang("msg_invalid_request"); - htmlFooter(); - return FALSE; + self::displayErrorPage('SSO Error', 'Invalid SSO Response', 400); + return false; } // Set session ID - setcookie(session_name(), self::get('SSOID')); + setcookie(session_name(), $sso_response); // Finally, redirect to the originally requested URL - $url_info = parse_url(self::getRequestUrl()); - $url_info['query'] = preg_replace('/(^|\b)SSOID=([^&?]+)/', '', $url_info['query']); - $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'] ? ('?' . $url_info['query']) : '')); - header('Location:' . $redirect_url); - return FALSE; + header('Location: ' . Rhymix\Framework\URL::getCurrentURL(array('sso_response' => null))); + return false; } // If none of the conditions above apply, proceed normally From 804fd0515bcb667147753edb17deb4da31b547e0 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 14 Mar 2016 15:32:39 +0900 Subject: [PATCH 165/318] Also apply embed filter to
    '; - $content = Rhymix\Framework\Security\MediaFilter::removeEmbeddedMedia($content, $security_msg); + $content = Rhymix\Framework\Filters\MediaFilter::removeEmbeddedMedia($content, $security_msg); } return; diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index fd8ace3c4..deebc7ed0 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -561,7 +561,7 @@ class adminAdminController extends admin return $item !== ''; }); $iframe_whitelist = array_unique(array_map(function($item) { - return Rhymix\Framework\Security\MediaFilter::formatPrefix($item); + return Rhymix\Framework\Filters\MediaFilter::formatPrefix($item); }, $iframe_whitelist)); natcasesort($iframe_whitelist); Rhymix\Framework\Config::set('mediafilter.iframe', array_values($iframe_whitelist)); @@ -572,7 +572,7 @@ class adminAdminController extends admin return $item !== ''; }); $object_whitelist = array_unique(array_map(function($item) { - return Rhymix\Framework\Security\MediaFilter::formatPrefix($item); + return Rhymix\Framework\Filters\MediaFilter::formatPrefix($item); }, $object_whitelist)); natcasesort($object_whitelist); Rhymix\Framework\Config::set('mediafilter.object', array_values($object_whitelist)); @@ -587,7 +587,7 @@ class adminAdminController extends admin $allowed_ip = array_unique(array_filter($allowed_ip, function($item) { return $item !== ''; })); - if (!Rhymix\Framework\Security\IpFilter::validateRanges($allowed_ip)) { + if (!Rhymix\Framework\Filters\IpFilter::validateRanges($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } @@ -595,7 +595,7 @@ class adminAdminController extends admin $denied_ip = array_unique(array_filter($denied_ip, function($item) { return $item !== ''; })); - if (!Rhymix\Framework\Security\IpFilter::validateRanges($denied_ip)) { + if (!Rhymix\Framework\Filters\IpFilter::validateRanges($denied_ip)) { return new Object(-1, 'msg_invalid_ip'); } @@ -745,7 +745,7 @@ class adminAdminController extends admin $allowed_ip = array_unique(array_filter($allowed_ip, function($item) { return $item !== ''; })); - if (!Rhymix\Framework\Security\IpFilter::validate($allowed_ip)) { + if (!Rhymix\Framework\Filters\IpFilter::validate($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } Rhymix\Framework\Config::set('debug.allow', array_values($allowed_ip)); @@ -771,17 +771,17 @@ class adminAdminController extends admin if ($vars->sitelock_locked === 'Y') { - if (!Rhymix\Framework\Security\IpFilter::inRanges('127.0.0.1', $allowed_ip)) + if (!Rhymix\Framework\Filters\IpFilter::inRanges('127.0.0.1', $allowed_ip)) { array_unshift($allowed_ip, '127.0.0.1'); } - if (!Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) + if (!Rhymix\Framework\Filters\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) { array_unshift($allowed_ip, RX_CLIENT_IP); } } - if (!Rhymix\Framework\Security\IpFilter::validateRanges($allowed_ip)) + if (!Rhymix\Framework\Filters\IpFilter::validateRanges($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index a74801f38..18b23eab1 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -418,8 +418,8 @@ class adminAdminView extends admin function dispAdminConfigSecurity() { // Load embed filter. - context::set('mediafilter_iframe', implode(PHP_EOL, Rhymix\Framework\Security\MediaFilter::getIframeWhitelist())); - context::set('mediafilter_object', implode(PHP_EOL, Rhymix\Framework\Security\MediaFilter::getObjectWhitelist())); + context::set('mediafilter_iframe', implode(PHP_EOL, Rhymix\Framework\Filters\MediaFilter::getIframeWhitelist())); + context::set('mediafilter_object', implode(PHP_EOL, Rhymix\Framework\Filters\MediaFilter::getObjectWhitelist())); // Admin IP access control $allowed_ip = Rhymix\Framework\Config::get('admin.allow'); @@ -518,11 +518,11 @@ class adminAdminView extends admin Context::set('sitelock_message', escape(Rhymix\Framework\Config::get('lock.message'))); $allowed_ip = Rhymix\Framework\Config::get('lock.allow') ?: array(); - if (!Rhymix\Framework\Security\IpFilter::inRanges('127.0.0.1', $allowed_ip)) + if (!Rhymix\Framework\Filters\IpFilter::inRanges('127.0.0.1', $allowed_ip)) { array_unshift($allowed_ip, '127.0.0.1'); } - if (!Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) + if (!Rhymix\Framework\Filters\IpFilter::inRanges(RX_CLIENT_IP, $allowed_ip)) { array_unshift($allowed_ip, RX_CLIENT_IP); } diff --git a/modules/file/file.controller.php b/modules/file/file.controller.php index 12d618456..76cbc63df 100644 --- a/modules/file/file.controller.php +++ b/modules/file/file.controller.php @@ -732,7 +732,7 @@ class fileController extends file } // Sanitize filename - $file_info['name'] = Rhymix\Framework\Security\FilenameFilter::clean($file_info['name']); + $file_info['name'] = Rhymix\Framework\Filters\FilenameFilter::clean($file_info['name']); // Set upload path by checking if the attachement is an image or other kinds of file if(preg_match("/\.(jpe?g|gif|png|wm[va]|mpe?g|avi|swf|flv|mp[1-4]|as[fx]|wav|midi?|moo?v|qt|r[am]{1,2}|m4v)$/i", $file_info['name'])) diff --git a/modules/member/member.admin.model.php b/modules/member/member.admin.model.php index 8e9682bb6..e9930e5db 100644 --- a/modules/member/member.admin.model.php +++ b/modules/member/member.admin.model.php @@ -298,12 +298,12 @@ class memberAdminModel extends member { if ($allow_list = ($allow_list === null) ? config('admin.allow') : $allow_list) { - return Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $allow_list); + return Rhymix\Framework\Filters\IpFilter::inRanges(RX_CLIENT_IP, $allow_list); } if ($deny_list = ($deny_list === null) ? config('admin.deny') : $deny_list) { - return !Rhymix\Framework\Security\IpFilter::inRanges(RX_CLIENT_IP, $deny_list); + return !Rhymix\Framework\Filters\IpFilter::inRanges(RX_CLIENT_IP, $deny_list); } return true; diff --git a/tests/unit/framework/security/FilenameFilterTest.php b/tests/unit/framework/filters/FilenameFilterTest.php similarity index 93% rename from tests/unit/framework/security/FilenameFilterTest.php rename to tests/unit/framework/filters/FilenameFilterTest.php index 935ffd473..7fe095d35 100644 --- a/tests/unit/framework/security/FilenameFilterTest.php +++ b/tests/unit/framework/filters/FilenameFilterTest.php @@ -35,7 +35,7 @@ class FilenameFilterTest extends \Codeception\TestCase\Test foreach ($tests as $from => $to) { - $result = Rhymix\Framework\Security\FilenameFilter::clean($from); + $result = Rhymix\Framework\Filters\FilenameFilter::clean($from); $this->assertEquals($to, $result); } } diff --git a/tests/unit/framework/security/HTMLFilterTest.php b/tests/unit/framework/filters/HTMLFilterTest.php similarity index 84% rename from tests/unit/framework/security/HTMLFilterTest.php rename to tests/unit/framework/filters/HTMLFilterTest.php index 1b32a675c..75aae9cd8 100644 --- a/tests/unit/framework/security/HTMLFilterTest.php +++ b/tests/unit/framework/filters/HTMLFilterTest.php @@ -61,7 +61,7 @@ class HTMLFilterTest extends \Codeception\TestCase\Test foreach ($tests as $test) { - $this->assertEquals($test[1], Rhymix\Framework\Security\HTMLFilter::clean($test[0])); + $this->assertEquals($test[1], Rhymix\Framework\Filters\HTMLFilter::clean($test[0])); } } @@ -69,41 +69,41 @@ class HTMLFilterTest extends \Codeception\TestCase\Test { $source = '
    '; $target = '
    '; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = '
    456
    789
    '; $target = '
    456
    789
    '; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); } public function testHTMLFilterCSS3() { $source = '
    '; $target = '
    '; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = '
    '; $target = '
    '; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = '
    '; $target = '
    '; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); } public function testHTMLFilterEmbeddedMedia() { $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = '' . '' . @@ -123,33 +123,33 @@ class HTMLFilterTest extends \Codeception\TestCase\Test '' . '' . ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); } public function testHTMLFilterEditorComponent() { $source = 'My Picture'; $target = 'My Picture'; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); $source = ''; $target = ''; - $this->assertEquals($target, Rhymix\Framework\Security\HTMLFilter::clean($source)); + $this->assertEquals($target, Rhymix\Framework\Filters\HTMLFilter::clean($source)); } } diff --git a/tests/unit/framework/filters/IpFilterTest.php b/tests/unit/framework/filters/IpFilterTest.php new file mode 100644 index 000000000..5da4b2f97 --- /dev/null +++ b/tests/unit/framework/filters/IpFilterTest.php @@ -0,0 +1,77 @@ +assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('10.0.127.191', '10.0.127.191')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('10.1.131.177', '10.1.131.178')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('127.0.0.1', '127.0.0.0/8')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('172.34.0.0', '172.16.0.0/12')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.16.0/22')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.16.0/23')); + } + + public function testIPv6CIDR() + { + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('::1', '::1/128')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('::1', '::2')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('2400:cb00::1234', '2400:cb00::/32')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('2405:8100::1234', '2400:cb00::/32')); + } + + public function testIPv4Wildcard() + { + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.134.*')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.*.*')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.136.*')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.172.*.*')); + } + + public function testIPv4Hyphen() + { + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.134.0-192.168.134.255')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.128.16-192.168.145.0')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.134.242-192.168.244.7')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.100.255-192.168.133.19')); + } + + public function testValidator() + { + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::validateRange('192.168.0.1')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::validateRange('192.168.0.0/16')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::validateRange('192.168.*.*')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::validateRange('192.168.*')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::validateRange('192.168.0.0-192.168.255.255')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::validateRange('2400:cb00::/32')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::validateRange('192.168.0.0~192.168.255.255')); + } + + public function testLegacy() + { + $this->assertTrue(\IpFilter::filter(array('192.168.134.241'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('192.168.134.0-192.168.134.255'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('127.0.0.1', '192.168.134.241'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('192.168.134.*'), '192.168.134.241')); + $this->assertTrue(\IpFilter::filter(array('192.168.*'), '192.168.134.241')); + $this->assertFalse(\IpFilter::filter(array('127.0.0.1'), '192.168.134.241')); + } + + public function testCloudFlareRealIP() + { + $_SERVER['HTTP_CF_CONNECTING_IP'] = '192.168.134.241'; + + $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::getCloudFlareRealIP()); + $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); + + $_SERVER['REMOTE_ADDR'] = '108.162.192.121'; + $this->assertEquals('192.168.134.241', Rhymix\Framework\Filters\IpFilter::getCloudFlareRealIP()); + $this->assertEquals('192.168.134.241', $_SERVER['REMOTE_ADDR']); + + unset($_SERVER['HTTP_CF_CONNECTING_IP']); + $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::getCloudFlareRealIP()); + $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); + } +} diff --git a/tests/unit/framework/filters/MediaFilterTest.php b/tests/unit/framework/filters/MediaFilterTest.php new file mode 100644 index 000000000..1e865a240 --- /dev/null +++ b/tests/unit/framework/filters/MediaFilterTest.php @@ -0,0 +1,58 @@ +assertTrue(in_array('www.youtube.com/', Rhymix\Framework\Filters\MediaFilter::getIframeWhitelist())); + $this->assertFalse(in_array('random-website.com/', Rhymix\Framework\Filters\MediaFilter::getIframeWhitelist())); + + // iframe whitelist as regex. + $this->assertTrue(strpos(Rhymix\Framework\Filters\MediaFilter::getIframeWhitelistRegex(), '|www\.youtube\.com/') !== false); + $this->assertFalse(strpos(Rhymix\Framework\Filters\MediaFilter::getIframeWhitelistRegex(), 'www.youtube.com/') !== false); + + // Match individual URL against iframe whitelist. + $this->assertTrue(Rhymix\Framework\Filters\MediaFilter::matchIframeWhitelist('https://www.youtube.com/v')); + $this->assertFalse(Rhymix\Framework\Filters\MediaFilter::matchIframeWhitelist('http://www-youtube.com/v')); + + // object whitelist as array. + $this->assertTrue(in_array('www.youtube.com/', Rhymix\Framework\Filters\MediaFilter::getObjectWhitelist())); + $this->assertFalse(in_array('random-website.com/', Rhymix\Framework\Filters\MediaFilter::getObjectWhitelist())); + + // object whitelist as regex. + $this->assertTrue(strpos(Rhymix\Framework\Filters\MediaFilter::getObjectWhitelistRegex(), '|www\.youtube\.com/') !== false); + $this->assertFalse(strpos(Rhymix\Framework\Filters\MediaFilter::getObjectWhitelistRegex(), 'www.youtube.com/') !== false); + + // Match individual URL against object whitelist. + $this->assertTrue(Rhymix\Framework\Filters\MediaFilter::matchObjectWhitelist('https://www.youtube.com/v')); + $this->assertFalse(Rhymix\Framework\Filters\MediaFilter::matchObjectWhitelist('http://www-youtube.com/v')); + } + + public function testAddPrefix() + { + $this->assertFalse(Rhymix\Framework\Filters\MediaFilter::matchIframeWhitelist('http://some.custom.website.com/video.mp4')); + Rhymix\Framework\Filters\MediaFilter::addIframePrefix('*.custom.website.com/'); + $this->assertTrue(Rhymix\Framework\Filters\MediaFilter::matchIframeWhitelist('http://some.custom.website.com/video.mp4')); + + $this->assertFalse(Rhymix\Framework\Filters\MediaFilter::matchObjectWhitelist('http://some.custom.website.com/video.mp4')); + Rhymix\Framework\Filters\MediaFilter::addObjectPrefix('*.custom.website.com/'); + $this->assertTrue(Rhymix\Framework\Filters\MediaFilter::matchObjectWhitelist('http://some.custom.website.com/video.mp4')); + } + + public function testRemoveEmbeddedMedia() + { + $tests = array( + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + '
    ' => '
    ', + ); + + foreach ($tests as $from => $to) + { + $this->assertEquals($to, Rhymix\Framework\Filters\MediaFilter::removeEmbeddedMedia($from)); + } + } +} diff --git a/tests/unit/framework/security/IpFilterTest.php b/tests/unit/framework/security/IpFilterTest.php deleted file mode 100644 index 235939253..000000000 --- a/tests/unit/framework/security/IpFilterTest.php +++ /dev/null @@ -1,77 +0,0 @@ -assertTrue(Rhymix\Framework\Security\IpFilter::inRange('10.0.127.191', '10.0.127.191')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('10.1.131.177', '10.1.131.178')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('127.0.0.1', '127.0.0.0/8')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('172.34.0.0', '172.16.0.0/12')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.18.214', '192.168.16.0/22')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.18.214', '192.168.16.0/23')); - } - - public function testIPv6CIDR() - { - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('::1', '::1/128')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('::1', '::2')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('2400:cb00::1234', '2400:cb00::/32')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('2405:8100::1234', '2400:cb00::/32')); - } - - public function testIPv4Wildcard() - { - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.134.*')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.*.*')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.136.*')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.172.*.*')); - } - - public function testIPv4Hyphen() - { - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.134.0-192.168.134.255')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.128.16-192.168.145.0')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.134.242-192.168.244.7')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::inRange('192.168.134.241', '192.168.100.255-192.168.133.19')); - } - - public function testValidator() - { - $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.1')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.0/16')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.*.*')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.*')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.0-192.168.255.255')); - $this->assertTrue(Rhymix\Framework\Security\IpFilter::validateRange('2400:cb00::/32')); - $this->assertFalse(Rhymix\Framework\Security\IpFilter::validateRange('192.168.0.0~192.168.255.255')); - } - - public function testLegacy() - { - $this->assertTrue(\IpFilter::filter(array('192.168.134.241'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('192.168.134.0-192.168.134.255'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('127.0.0.1', '192.168.134.241'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('192.168.134.*'), '192.168.134.241')); - $this->assertTrue(\IpFilter::filter(array('192.168.*'), '192.168.134.241')); - $this->assertFalse(\IpFilter::filter(array('127.0.0.1'), '192.168.134.241')); - } - - public function testCloudFlareRealIP() - { - $_SERVER['HTTP_CF_CONNECTING_IP'] = '192.168.134.241'; - - $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; - $this->assertFalse(Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP()); - $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); - - $_SERVER['REMOTE_ADDR'] = '108.162.192.121'; - $this->assertEquals('192.168.134.241', Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP()); - $this->assertEquals('192.168.134.241', $_SERVER['REMOTE_ADDR']); - - unset($_SERVER['HTTP_CF_CONNECTING_IP']); - $_SERVER['REMOTE_ADDR'] = '192.168.10.1'; - $this->assertFalse(Rhymix\Framework\Security\IpFilter::getCloudFlareRealIP()); - $this->assertEquals('192.168.10.1', $_SERVER['REMOTE_ADDR']); - } -} diff --git a/tests/unit/framework/security/MediaFilterTest.php b/tests/unit/framework/security/MediaFilterTest.php deleted file mode 100644 index 404bc0a4c..000000000 --- a/tests/unit/framework/security/MediaFilterTest.php +++ /dev/null @@ -1,58 +0,0 @@ -assertTrue(in_array('www.youtube.com/', Rhymix\Framework\Security\MediaFilter::getIframeWhitelist())); - $this->assertFalse(in_array('random-website.com/', Rhymix\Framework\Security\MediaFilter::getIframeWhitelist())); - - // iframe whitelist as regex. - $this->assertTrue(strpos(Rhymix\Framework\Security\MediaFilter::getIframeWhitelistRegex(), '|www\.youtube\.com/') !== false); - $this->assertFalse(strpos(Rhymix\Framework\Security\MediaFilter::getIframeWhitelistRegex(), 'www.youtube.com/') !== false); - - // Match individual URL against iframe whitelist. - $this->assertTrue(Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist('https://www.youtube.com/v')); - $this->assertFalse(Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist('http://www-youtube.com/v')); - - // object whitelist as array. - $this->assertTrue(in_array('www.youtube.com/', Rhymix\Framework\Security\MediaFilter::getObjectWhitelist())); - $this->assertFalse(in_array('random-website.com/', Rhymix\Framework\Security\MediaFilter::getObjectWhitelist())); - - // object whitelist as regex. - $this->assertTrue(strpos(Rhymix\Framework\Security\MediaFilter::getObjectWhitelistRegex(), '|www\.youtube\.com/') !== false); - $this->assertFalse(strpos(Rhymix\Framework\Security\MediaFilter::getObjectWhitelistRegex(), 'www.youtube.com/') !== false); - - // Match individual URL against object whitelist. - $this->assertTrue(Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist('https://www.youtube.com/v')); - $this->assertFalse(Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist('http://www-youtube.com/v')); - } - - public function testAddPrefix() - { - $this->assertFalse(Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist('http://some.custom.website.com/video.mp4')); - Rhymix\Framework\Security\MediaFilter::addIframePrefix('*.custom.website.com/'); - $this->assertTrue(Rhymix\Framework\Security\MediaFilter::matchIframeWhitelist('http://some.custom.website.com/video.mp4')); - - $this->assertFalse(Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist('http://some.custom.website.com/video.mp4')); - Rhymix\Framework\Security\MediaFilter::addObjectPrefix('*.custom.website.com/'); - $this->assertTrue(Rhymix\Framework\Security\MediaFilter::matchObjectWhitelist('http://some.custom.website.com/video.mp4')); - } - - public function testRemoveEmbeddedMedia() - { - $tests = array( - '
    ' => '
    ', - '
    ' => '
    ', - '
    ' => '
    ', - '
    ' => '
    ', - '
    ' => '
    ', - ); - - foreach ($tests as $from => $to) - { - $this->assertEquals($to, Rhymix\Framework\Security\MediaFilter::removeEmbeddedMedia($from)); - } - } -} From 3e728dc6c24e223568c7a42e152270495524014f Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Mon, 14 Mar 2016 22:13:19 +0900 Subject: [PATCH 171/318] Exclude more attributes from widget and editor component detection --- common/framework/filters/htmlfilter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/framework/filters/htmlfilter.php b/common/framework/filters/htmlfilter.php index 64356a8e8..4009d940f 100644 --- a/common/framework/filters/htmlfilter.php +++ b/common/framework/filters/htmlfilter.php @@ -449,11 +449,11 @@ class HTMLFilter $attrs = array(); $html = preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use($tag, &$attrs) { $attrkey = strtolower($attr[1]); - if ($tag === 'img' && preg_match('/^(?:width|height|alt)$/', $attrkey)) + if ($tag === 'img' && preg_match('/^(?:width|height|src|alt|ismap|usemap)$/', $attrkey)) { return $attr[0]; } - if (preg_match('/^(?:on|data-|(?:src|style|class|editor_component)$)/', $attrkey)) + if (preg_match('/^(?:on|data-|(?:accesskey|class|contextmenu|contenteditable|dir|draggable|dropzone|editor_component|hidden|id|lang|name|style|tabindex|title)$)/', $attrkey)) { return $attr[0]; } From 93b045fa17d8496523075c29c2a0e8fc7c938822 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 09:59:38 +0900 Subject: [PATCH 172/318] Fix incorrect use of global constant in Debug class --- common/framework/debug.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/framework/debug.php b/common/framework/debug.php index 0fd10d846..d606f1723 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -445,7 +445,7 @@ class Debug return $cache = true; case 'ip': - if (Filters\IpFilter::inRanges(RX_CLIENT_IP, Config::get('debug.allow'))) + if (Filters\IpFilter::inRanges(\RX_CLIENT_IP, Config::get('debug.allow'))) { return $cache = true; } From f4b35e3717212698150e0d7bc8c9cec3906382db Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 10:06:33 +0900 Subject: [PATCH 173/318] Fix typo --- modules/admin/admin.admin.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index deebc7ed0..20a4bab37 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -745,7 +745,7 @@ class adminAdminController extends admin $allowed_ip = array_unique(array_filter($allowed_ip, function($item) { return $item !== ''; })); - if (!Rhymix\Framework\Filters\IpFilter::validate($allowed_ip)) { + if (!Rhymix\Framework\Filters\IpFilter::validateRanges($allowed_ip)) { return new Object(-1, 'msg_invalid_ip'); } Rhymix\Framework\Config::set('debug.allow', array_values($allowed_ip)); From a6a1b25f2d7c2d6875d285cae88e78b3ec4c8df0 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 10:21:40 +0900 Subject: [PATCH 174/318] Always allow debugging from localhost --- common/framework/debug.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/common/framework/debug.php b/common/framework/debug.php index d606f1723..bf2227904 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -449,6 +449,14 @@ class Debug { return $cache = true; } + if (\RX_CLIENT_IP === '127.0.0.1' || \RX_CLIENT_IP === '::1') + { + return $cache = true; + } + if (\RX_CLIENT_IP === $_SERVER['SERVER_ADDR'] || \RX_CLIENT_IP === $_SERVER['LOCAL_ADDR']) + { + return $cache = true; + } return $cache = false; case 'admin': From 7298adf8555a9256a6cefa3b16cafc1bdb7e0f93 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 10:57:57 +0900 Subject: [PATCH 175/318] Include visitor IP address in debug output --- common/tpl/debug_comment.html | 1 + 1 file changed, 1 insertion(+) diff --git a/common/tpl/debug_comment.html b/common/tpl/debug_comment.html index ca05800df..3e9741aee 100644 --- a/common/tpl/debug_comment.html +++ b/common/tpl/debug_comment.html @@ -6,6 +6,7 @@ Request / Response ================== Request URL: url . "\n"; ?> +Request IP Address: Request Method: request->method . "\n" ?> Request Body Size: request->size . "\n" ?> Response Method: response->method . "\n"; ?> From 468fcc88deeff3782def9dff872b2a511291c35b Mon Sep 17 00:00:00 2001 From: BJRambo Date: Tue, 15 Mar 2016 13:26:09 +0900 Subject: [PATCH 176/318] rename query id --- modules/document/queries/getUpdateLogAdminisExists.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/document/queries/getUpdateLogAdminisExists.xml b/modules/document/queries/getUpdateLogAdminisExists.xml index 7074c565c..5c494fc5d 100644 --- a/modules/document/queries/getUpdateLogAdminisExists.xml +++ b/modules/document/queries/getUpdateLogAdminisExists.xml @@ -1,4 +1,4 @@ - + From 9d2fe0270bc5322441fd75e5ce9249bf8b277dfb Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 13:48:07 +0900 Subject: [PATCH 177/318] Add URL-to-path and clean path conversion --- common/framework/filters/filenamefilter.php | 20 ++++++ common/framework/url.php | 69 +++++++++++++++++-- tests/unit/framework/URLTest.php | 35 ++++++++++ .../framework/filters/FilenameFilterTest.php | 24 ++++++- 4 files changed, 140 insertions(+), 8 deletions(-) diff --git a/common/framework/filters/filenamefilter.php b/common/framework/filters/filenamefilter.php index 42f5a729c..a498f2a98 100644 --- a/common/framework/filters/filenamefilter.php +++ b/common/framework/filters/filenamefilter.php @@ -46,4 +46,24 @@ class FilenameFilter return $filename; } + + /** + * Clean a path to remove ./, ../, trailing slashes, etc. + * + * @param string $path + * @return string + */ + public static function cleanPath($path) + { + $path = str_replace('\\', '/', $path); + $path = preg_replace('@[\?#].+$@', '', $path); + $path = preg_replace('@/{2,}@', '/', $path); + $path = preg_replace('@/\.{3,}/@', '/', $path); + $path = preg_replace('@/(\./)+@', '/', $path); + while (preg_match('@/[^/]+/\.\.(?:/|$)@', $path, $matches)) + { + $path = str_replace($matches[0], '/', $path); + } + return rtrim($path, '/'); + } } diff --git a/common/framework/url.php b/common/framework/url.php index 8fc370bdb..f810c0082 100644 --- a/common/framework/url.php +++ b/common/framework/url.php @@ -18,10 +18,7 @@ class URL */ public static function getCurrentURL(array $changes = array()) { - $proto = \RX_SSL ? 'https://' : 'http://'; - $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; - $local = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; - $url = $proto . $host . $local; + $url = self::getCurrentDomainURL(isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'); if (count($changes)) { return self::modifyURL($url, $changes); @@ -32,6 +29,19 @@ class URL } } + /** + * Get the current domain. + * + * @param string $path + * @return string + */ + public static function getCurrentDomainURL($path = '/') + { + $proto = \RX_SSL ? 'https://' : 'http://'; + $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; + return $proto . $host . '/' . ltrim($path, '/'); + } + /** * Convert a URL to its canonical format. * @@ -42,9 +52,7 @@ class URL { if (preg_match('#^\.?/([^/]|$)#', $url) || !preg_match('#^(https?:|/)#', $url)) { - $proto = \RX_SSL ? 'https://' : 'http://'; - $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; - $url = $proto . $host . \RX_BASEURL . ltrim($url, './'); + $url = self::getCurrentDomainURL(\RX_BASEURL . ltrim($url, './')); } return preg_replace_callback('#^(https?:|)//([^/]+)#i', function($matches) { if ($matches[1] === '') $matches[1] = \RX_SSL ? 'https:' : 'http:'; @@ -125,6 +133,53 @@ class URL } } + /** + * Convert a server-side path to a URL. + * + * This method returns false if the path cannot be converted to a URL, + * e.g. if the path is outside of the document root. + * + * @param string $path + * @return string|false + */ + public static function fromServerPath($path) + { + $cleanpath = Filters\FilenameFilter::cleanPath($path); + if (substr($path, -1) === '/') + { + $cleanpath .= '/'; + } + $root = Filters\FilenameFilter::cleanPath($_SERVER['DOCUMENT_ROOT']); + if ($cleanpath === $root) + { + return self::getCurrentDomainURL('/'); + } + if (starts_with($root . '/', $cleanpath)) + { + return self::getCurrentDomainURL(substr($cleanpath, strlen($root))); + } + return false; + } + + /** + * Convert a URL to a server-side path. + * + * This method returns false if the URL cannot be converted to a server-side path, + * e.g. if the URL belongs to an external domain. + * + * @param string $url + * @return string + */ + public static function toServerPath($url) + { + $url = self::getCanonicalURL($url); + if (!self::isInternalURL($url)) + { + return false; + } + return Filters\FilenameFilter::cleanPath($_SERVER['DOCUMENT_ROOT'] . parse_url($url, \PHP_URL_PATH)); + } + /** * Encode UTF-8 domain into IDNA (punycode) * diff --git a/tests/unit/framework/URLTest.php b/tests/unit/framework/URLTest.php index d36dd5fe6..2faaac28f 100644 --- a/tests/unit/framework/URLTest.php +++ b/tests/unit/framework/URLTest.php @@ -25,6 +25,17 @@ class URLTest extends \Codeception\TestCase\Test $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks&l=ko', Rhymix\Framework\URL::getCurrentURL(array('l' => 'ko', 'foo' => null))); } + public function testGetCurrentDomainURL() + { + $protocol = \RX_SSL ? 'https://' : 'http://'; + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/', Rhymix\Framework\URL::getCurrentDomainURL()); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/', Rhymix\Framework\URL::getCurrentDomainURL('/')); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/foo/bar', Rhymix\Framework\URL::getCurrentDomainURL('/foo/bar')); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?foo=bar', Rhymix\Framework\URL::getCurrentDomainURL('index.php?foo=bar')); + } + public function testGetCanonicalURL() { $protocol = \RX_SSL ? 'https://' : 'http://'; @@ -82,6 +93,30 @@ class URLTest extends \Codeception\TestCase\Test // This function is checked in Security::checkCSRF() } + public function testURLFromServerPath() + { + $protocol = \RX_SSL ? 'https://' : 'http://'; + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL, Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR)); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . 'index.php')); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . '/foo/bar')); + $this->assertEquals(false, Rhymix\Framework\URL::fromServerPath('C:/Windows')); + } + + public function testURLToServerPath() + { + $protocol = \RX_SSL ? 'https://' : 'http://'; + $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; + + $this->assertEquals(\RX_BASEDIR . 'index.php', Rhymix\Framework\URL::toServerPath($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php')); + $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . '/foo/bar?arg=baz')); + $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath('./foo/bar')); + $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath('foo/bar/../bar')); + $this->assertEquals(false, Rhymix\Framework\URL::toServerPath('http://other.domain.com/')); + $this->assertEquals(false, Rhymix\Framework\URL::toServerPath('//other.domain.com/')); + } + public function testEncodeIdna() { $this->assertEquals('xn--9i1bl3b186bf9e.xn--3e0b707e', Rhymix\Framework\URL::encodeIdna('퓨니코드.한국')); diff --git a/tests/unit/framework/filters/FilenameFilterTest.php b/tests/unit/framework/filters/FilenameFilterTest.php index 7fe095d35..7d1bf117a 100644 --- a/tests/unit/framework/filters/FilenameFilterTest.php +++ b/tests/unit/framework/filters/FilenameFilterTest.php @@ -1,5 +1,7 @@ $to) { - $result = Rhymix\Framework\Filters\FilenameFilter::clean($from); + $result = FilenameFilter::clean($from); $this->assertEquals($to, $result); } } + + public function testFilenameFilterCleanPath() + { + // Remove extra dots and slashes. + $this->assertEquals('/usr/share/foo/bar.jpg', FilenameFilter::cleanPath('/usr/share/foo//./baz/../bar.jpg')); + $this->assertEquals('/usr/share/foo/bar.jpg', FilenameFilter::cleanPath('/usr/share/foo/././baz/../../foo/bar.jpg')); + $this->assertEquals('/usr/share', FilenameFilter::cleanPath('/usr/share/foo/..')); + $this->assertEquals('/usr/share', FilenameFilter::cleanPath('/usr/share/foo/bar/../baz/../../')); + + // Test Windows paths. + $this->assertEquals('C:/Windows/Notepad.exe', FilenameFilter::cleanPath('C:\\Windows\\System32\\..\\Notepad.exe')); + + // Do not remove .. if there is no parent directory. + $this->assertEquals('C:/../foobar', FilenameFilter::cleanPath('C:\\..\foobar\\')); + $this->assertEquals('/../foobar', FilenameFilter::cleanPath('/../foobar/')); + + // Remove query strings and URL fragments. + $this->assertEquals('index.php', FilenameFilter::cleanPath('index.php?foo=bar')); + $this->assertEquals('index.php', FilenameFilter::cleanPath('index.php#baz')); + } } From f983335833057b2fcdb4f3593764fd39dd88741a Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 13:54:33 +0900 Subject: [PATCH 178/318] Add function aliases for URL and path conversion --- common/functions.php | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/common/functions.php b/common/functions.php index 154d60455..6840cdcaa 100644 --- a/common/functions.php +++ b/common/functions.php @@ -133,6 +133,19 @@ function class_basename($class) return basename(str_replace('\\', '/', is_object($class) ? get_class($class) : $class)); } +/** + * Clean a path to remove ./, ../, trailing slashes, etc. + * + * This function is an alias to Rhymix\Framework\Filters\FilenameFilter::cleanPath(). + * + * @param string $path + * @return string + */ +function clean_path($path) +{ + return Rhymix\Framework\Filters\FilenameFilter::cleanPath($path); +} + /** * This function is a shortcut to htmlspecialchars(). * @@ -337,6 +350,34 @@ function base64_decode_urlsafe($str) return @base64_decode(str_pad(strtr($str, '-_', '+/'), ceil(strlen($str) / 4) * 4, '=', STR_PAD_RIGHT)); } +/** + * Convert a server-side path to a URL. + * + * This function is an alias to Rhymix\Framework\URL::fromServerPath(). + * It returns false if the path cannot be converted. + * + * @param string $path + * @return string|false + */ +function path2url($path) +{ + return Rhymix\Framework\URL::fromServerPath($path); +} + +/** + * Convert a URL to a server-side path. + * + * This function is an alias to Rhymix\Framework\URL::toServerPath(). + * It returns false if the URL cannot be converted. + * + * @param string $url + * @return string|false + */ +function url2path($url) +{ + return Rhymix\Framework\URL::toServerPath($url); +} + /** * Convert hexadecimal color codes to an array of R, G, B values. * This function can handle both 6-digit and 3-digit notations, optionally prefixed with '#'. From 139e11df13f0beec2d9fd1ba37a7a8822278ca45 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 14:14:50 +0900 Subject: [PATCH 179/318] Also clean relative paths in cleanPath() --- common/framework/filters/filenamefilter.php | 4 ++++ common/framework/storage.php | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 common/framework/storage.php diff --git a/common/framework/filters/filenamefilter.php b/common/framework/filters/filenamefilter.php index a498f2a98..becd5e3f7 100644 --- a/common/framework/filters/filenamefilter.php +++ b/common/framework/filters/filenamefilter.php @@ -55,6 +55,10 @@ class FilenameFilter */ public static function cleanPath($path) { + if (!preg_match('@^(?:[a-z]:[\\\\/]|\\\\|/)@i', $path)) + { + $path = \RX_BASEDIR . $path; + } $path = str_replace('\\', '/', $path); $path = preg_replace('@[\?#].+$@', '', $path); $path = preg_replace('@/{2,}@', '/', $path); diff --git a/common/framework/storage.php b/common/framework/storage.php new file mode 100644 index 000000000..4fee32b08 --- /dev/null +++ b/common/framework/storage.php @@ -0,0 +1,11 @@ + Date: Tue, 15 Mar 2016 14:15:03 +0900 Subject: [PATCH 180/318] Update unit tests --- tests/unit/framework/URLTest.php | 7 ++++--- tests/unit/framework/filters/FilenameFilterTest.php | 8 ++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/unit/framework/URLTest.php b/tests/unit/framework/URLTest.php index 2faaac28f..f3d5befb3 100644 --- a/tests/unit/framework/URLTest.php +++ b/tests/unit/framework/URLTest.php @@ -98,9 +98,10 @@ class URLTest extends \Codeception\TestCase\Test $protocol = \RX_SSL ? 'https://' : 'http://'; $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL, Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR)); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . 'index.php')); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . '/foo/bar')); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR)); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . 'index.php')); + $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/foo/bar', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . '/foo/bar')); + $this->assertEquals(false, Rhymix\Framework\URL::fromServerPath(dirname(dirname(\RX_BASEDIR)))); $this->assertEquals(false, Rhymix\Framework\URL::fromServerPath('C:/Windows')); } diff --git a/tests/unit/framework/filters/FilenameFilterTest.php b/tests/unit/framework/filters/FilenameFilterTest.php index 7d1bf117a..562bac0cc 100644 --- a/tests/unit/framework/filters/FilenameFilterTest.php +++ b/tests/unit/framework/filters/FilenameFilterTest.php @@ -50,6 +50,10 @@ class FilenameFilterTest extends \Codeception\TestCase\Test $this->assertEquals('/usr/share', FilenameFilter::cleanPath('/usr/share/foo/..')); $this->assertEquals('/usr/share', FilenameFilter::cleanPath('/usr/share/foo/bar/../baz/../../')); + // Test internal paths. + $this->assertEquals(\RX_BASEDIR . 'common/js/debug.js', FilenameFilter::cleanPath('common/js/debug.js')); + $this->assertEquals(\RX_BASEDIR . 'common/js/debug.js', FilenameFilter::cleanPath('./common/js/debug.js')); + // Test Windows paths. $this->assertEquals('C:/Windows/Notepad.exe', FilenameFilter::cleanPath('C:\\Windows\\System32\\..\\Notepad.exe')); @@ -58,7 +62,7 @@ class FilenameFilterTest extends \Codeception\TestCase\Test $this->assertEquals('/../foobar', FilenameFilter::cleanPath('/../foobar/')); // Remove query strings and URL fragments. - $this->assertEquals('index.php', FilenameFilter::cleanPath('index.php?foo=bar')); - $this->assertEquals('index.php', FilenameFilter::cleanPath('index.php#baz')); + $this->assertEquals(\RX_BASEDIR . 'index.php', FilenameFilter::cleanPath('index.php?foo=bar')); + $this->assertEquals(\RX_BASEDIR . 'index.php', FilenameFilter::cleanPath('index.php#baz')); } } From ff0df0a14b1346945d89d219a7cbab92ddfc1900 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 14:41:21 +0900 Subject: [PATCH 181/318] Ensure proper handling of network shares and URLs in cleanPath() --- common/framework/filters/filenamefilter.php | 19 +++++++++++++++++-- .../framework/filters/FilenameFilterTest.php | 5 +++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/common/framework/filters/filenamefilter.php b/common/framework/filters/filenamefilter.php index becd5e3f7..dc5fee4eb 100644 --- a/common/framework/filters/filenamefilter.php +++ b/common/framework/filters/filenamefilter.php @@ -55,19 +55,34 @@ class FilenameFilter */ public static function cleanPath($path) { - if (!preg_match('@^(?:[a-z]:[\\\\/]|\\\\|/)@i', $path)) + // Convert relative paths to absolute paths. + if (!preg_match('@^(?:/|[a-z]:[\\\\/]|\\\\|https?:)@i', $path)) { $path = \RX_BASEDIR . $path; } + + // Convert backslashes to forward slashes. $path = str_replace('\\', '/', $path); + + // Remove querystrings and URL fragments. $path = preg_replace('@[\?#].+$@', '', $path); - $path = preg_replace('@/{2,}@', '/', $path); + + // Remove duplicate slashes, except at the beginning of a URL. + $path = preg_replace('@(?assertEquals('C:/Windows/Notepad.exe', FilenameFilter::cleanPath('C:\\Windows\\System32\\..\\Notepad.exe')); + $this->assertEquals('//vboxsrv/hello/world', FilenameFilter::cleanPath('\\\\vboxsrv\\hello\\world')); + + // Test absolute URLs. + $this->assertEquals('https://www.rhymix.org/foo/bar', FilenameFilter::cleanPath('https://www.rhymix.org/foo/.//bar')); + $this->assertEquals('//www.rhymix.org/foo/bar', FilenameFilter::cleanPath('//www.rhymix.org/foo/.//bar')); // Do not remove .. if there is no parent directory. $this->assertEquals('C:/../foobar', FilenameFilter::cleanPath('C:\\..\foobar\\')); From b088348be2c0899d8d463d992e6ffe9c9ed98cc7 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 15 Mar 2016 18:05:48 +0900 Subject: [PATCH 182/318] More explicitly exclude a series of double dots --- common/framework/filters/filenamefilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/framework/filters/filenamefilter.php b/common/framework/filters/filenamefilter.php index dc5fee4eb..a43fb8ba2 100644 --- a/common/framework/filters/filenamefilter.php +++ b/common/framework/filters/filenamefilter.php @@ -77,7 +77,7 @@ class FilenameFilter $path = preg_replace('@/(\./)+@', '/', $path); // Remove double dots and the preceding directory. - while (preg_match('@/[^/]+/\.\.(?:/|$)@', $path, $matches)) + while (preg_match('@/(?!\.\.)[^/]+/\.\.(?:/|$)@', $path, $matches)) { $path = str_replace($matches[0], '/', $path); } From ca7a7b64eaf98a74c12a06990116d220a98567b9 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 09:13:31 +0900 Subject: [PATCH 183/318] Use a more realistic server environment in unit tests --- tests/_bootstrap.php | 15 +++- tests/unit/_bootstrap.php | 1 - tests/unit/classes/ContextTest.php | 3 - tests/unit/classes/FileHandlerTest.php | 1 - .../unit/classes/FrontEndFileHandlerTest.php | 53 +++++++-------- tests/unit/classes/OldSecurityTest.php | 1 - tests/unit/classes/TemplateHandlerTest.php | 35 +++++----- tests/unit/framework/SecurityTest.php | 2 - tests/unit/framework/URLTest.php | 68 +++++++------------ 9 files changed, 81 insertions(+), 98 deletions(-) diff --git a/tests/_bootstrap.php b/tests/_bootstrap.php index 529a86e6c..8017ed216 100644 --- a/tests/_bootstrap.php +++ b/tests/_bootstrap.php @@ -1,6 +1,17 @@ loadFile(array('./common/js/common.js', 'body')); $handler->loadFile(array('./common/js/common.js', 'head')); $handler->loadFile(array('./common/js/xml_js_filter.js', 'body')); - $expected[] = array('file' => '/xe/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); $this->assertEquals($handler->getJsFileList(), $expected); }); @@ -39,8 +38,8 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler = new FrontEndFileHandler(); $handler->loadFile(array('./common/css/xe.css')); $handler->loadFile(array('./common/css/mobile.css')); - $expected[] = array('file' => '/xe/common/css/xe.css' . $this->_filemtime('common/css/xe.css'), 'media' => 'all', 'targetie' => null); - $expected[] = array('file' => '/xe/common/css/mobile.css' . $this->_filemtime('common/css/mobile.css'), 'media' => 'all', 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/css/xe.css' . $this->_filemtime('common/css/xe.css'), 'media' => 'all', 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/css/mobile.css' . $this->_filemtime('common/css/mobile.css'), 'media' => 'all', 'targetie' => null); $this->assertEquals($handler->getCssFileList(), $expected); }); @@ -54,10 +53,10 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler->loadFile(array('./common/js/common.js', 'head', '', -100000)); $handler->loadFile(array('./common/js/xml_handler.js', 'head', '', -100000)); $handler->loadFile(array('./common/js/xml_js_filter.js', 'head', '', -100000)); - $expected[] = array('file' => '/xe/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/xml_handler.js' . $this->_filemtime('common/js/xml_handler.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/xml_js_filter.js' . $this->_filemtime('common/js/xml_js_filter.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/xml_handler.js' . $this->_filemtime('common/js/xml_handler.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/xml_js_filter.js' . $this->_filemtime('common/js/xml_js_filter.js'), 'targetie' => null); $this->assertEquals($handler->getJsFileList(), $expected); }); @@ -67,10 +66,10 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler->loadFile(array('./common/js/js_app.js', 'head', '', -100000)); $handler->loadFile(array('./common/js/common.js', 'head', '', -100000)); $handler->loadFile(array('./common/js/xml_js_filter.js', 'head', '', -100000)); - $expected[] = array('file' => '/xe/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/xml_js_filter.js' . $this->_filemtime('common/js/xml_js_filter.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/xml_handler.js' . $this->_filemtime('common/js/xml_handler.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/xml_js_filter.js' . $this->_filemtime('common/js/xml_js_filter.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/xml_handler.js' . $this->_filemtime('common/js/xml_handler.js'), 'targetie' => null); $this->assertEquals($handler->getJsFileList(), $expected); }); @@ -81,9 +80,9 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler->loadFile(array('./common/js/xml_handler.js', 'head', '', -100000)); $handler->loadFile(array('./common/js/xml_js_filter.js', 'head', '', -100000)); $handler->unloadFile('./common/js/js_app.js', '', 'all'); - $expected[] = array('file' => '/xe/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/xml_handler.js' . $this->_filemtime('common/js/xml_handler.js'), 'targetie' => null); - $expected[] = array('file' => '/xe/common/js/xml_js_filter.js' . $this->_filemtime('common/js/xml_js_filter.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/common.js' . $this->_filemtime('common/js/common.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/xml_handler.js' . $this->_filemtime('common/js/xml_handler.js'), 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/js/xml_js_filter.js' . $this->_filemtime('common/js/xml_js_filter.js'), 'targetie' => null); $this->assertEquals($handler->getJsFileList(), $expected); }); @@ -92,9 +91,9 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler->loadFile(array('./common/js/js_app.js', 'head', 'ie6')); $handler->loadFile(array('./common/js/js_app.js', 'head', 'ie7')); $handler->loadFile(array('./common/js/js_app.js', 'head', 'ie8')); - $expected[] = array('file' => '/xe/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => 'ie6'); - $expected[] = array('file' => '/xe/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => 'ie7'); - $expected[] = array('file' => '/xe/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => 'ie8'); + $expected[] = array('file' => '/rhymix/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => 'ie6'); + $expected[] = array('file' => '/rhymix/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => 'ie7'); + $expected[] = array('file' => '/rhymix/common/js/js_app.js' . $this->_filemtime('common/js/js_app.js'), 'targetie' => 'ie8'); $this->assertEquals($handler->getJsFileList(), $expected); }); @@ -127,9 +126,9 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler->loadFile(array('./common/css/common.css', null, 'ie7')); $handler->loadFile(array('./common/css/common.css', null, 'ie8')); - $expected[] = array('file' => '/xe/common/css/common.css', 'media'=>'all', 'targetie' => 'ie6'); - $expected[] = array('file' => '/xe/common/css/common.css','media'=>'all', 'targetie' => 'ie7'); - $expected[] = array('file' => '/xe/common/css/common.css', 'media'=>'all', 'targetie' => 'ie8'); + $expected[] = array('file' => '/rhymix/common/css/common.css', 'media'=>'all', 'targetie' => 'ie6'); + $expected[] = array('file' => '/rhymix/common/css/common.css','media'=>'all', 'targetie' => 'ie7'); + $expected[] = array('file' => '/rhymix/common/css/common.css', 'media'=>'all', 'targetie' => 'ie8'); $this->assertEquals($handler->getCssFileList(), $expected); }); @@ -139,9 +138,9 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler->loadFile(array('./common/css/common.css', 'screen')); $handler->loadFile(array('./common/css/common.css', 'handled')); - $expected[] = array('file' => '/xe/common/css/common.css', 'media'=>'all', 'targetie' => null); - $expected[] = array('file' => '/xe/common/css/common.css','media'=>'screen', 'targetie' => null); - $expected[] = array('file' => '/xe/common/css/common.css', 'media'=>'handled', 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/css/common.css', 'media'=>'all', 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/css/common.css','media'=>'screen', 'targetie' => null); + $expected[] = array('file' => '/rhymix/common/css/common.css', 'media'=>'handled', 'targetie' => null); $this->assertEquals($handler->getCssFileList(), $expected); }); @@ -151,8 +150,8 @@ class FrontEndFileHandlerTest extends \Codeception\TestCase\Test $handler = new FrontEndFileHandler(); $handler->loadFile(array('./common/css/xe.css')); $handler->loadFile(array('./common/css/mobile.css')); - $expected[] = array('file' => '/xe/files/cache/minify/common.css.xe.min.css', 'media' => 'all', 'targetie' => null); - $expected[] = array('file' => '/xe/files/cache/minify/common.css.mobile.min.css', 'media' => 'all', 'targetie' => null); + $expected[] = array('file' => '/rhymix/files/cache/minify/common.css.xe.min.css', 'media' => 'all', 'targetie' => null); + $expected[] = array('file' => '/rhymix/files/cache/minify/common.css.mobile.min.css', 'media' => 'all', 'targetie' => null); $result = $handler->getCssFileList(); $result[0]['file'] = preg_replace('/\?\d+$/', '', $result[0]['file']); $result[1]['file'] = preg_replace('/\?\d+$/', '', $result[1]['file']); diff --git a/tests/unit/classes/OldSecurityTest.php b/tests/unit/classes/OldSecurityTest.php index f699b8d1b..85ed5e564 100644 --- a/tests/unit/classes/OldSecurityTest.php +++ b/tests/unit/classes/OldSecurityTest.php @@ -1,5 +1,4 @@ ', - '?>' + '?>' ), // relative path2 array( '', - '?>' + '?>' ), // error case array( @@ -213,7 +210,7 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // issue 584 array( 'mobile', - PHP_EOL . 'if($__Context->oBodex->display_extra_images[\'mobile\'] && $__Context->arr_extra && $__Context->arr_extra->bodex->mobile){ ?>mobile' + PHP_EOL . 'if($__Context->oBodex->display_extra_images[\'mobile\'] && $__Context->arr_extra && $__Context->arr_extra->bodex->mobile){ ?>mobile' ), // issue 831 array( @@ -222,8 +219,8 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test ), // issue 746 array( - '', - '?>' + '', + '?>' ), // issue 696 array( @@ -233,47 +230,47 @@ class TemplateHandlerTest extends \Codeception\TestCase\Test // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if($__Context->foo->bar){ ?>' + PHP_EOL . 'if($__Context->foo->bar){ ?>' ), // https://github.com/xpressengine/xe-core/issues/1510 array( 'a!@#$%^&*()_-=[]{}?/', - PHP_EOL . 'if($__Context->foo->bar > 100){ ?>a!@#$%^&*()_-=[]{}?/' + PHP_EOL . 'if($__Context->foo->bar > 100){ ?>a!@#$%^&*()_-=[]{}?/' ), // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if($__Context->foo->bar){ ?>' + PHP_EOL . 'if($__Context->foo->bar){ ?>' ), // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if(!$__Context->module_info->title){ ?>' + PHP_EOL . 'if(!$__Context->module_info->title){ ?>' ), // https://github.com/xpressengine/xe-core/issues/1510 array( '', - PHP_EOL . 'if($__Context->mi->title){ ?>mi->use){ ?> class="tmp_class" src="/xe/tests/unit/classes/img/common/blank.gif" />' + PHP_EOL . 'if($__Context->mi->title){ ?>mi->use){ ?> class="tmp_class" src="/rhymix/tests/unit/classes/img/common/blank.gif" />' ), array( ' alt', - '?> foo->bar){ ?>alt' + '?> foo->bar){ ?>alt' ), array( '' . "\n" . ' alt', - '?>' . PHP_EOL . ' foo->bar){ ?>alt' + '?>' . PHP_EOL . ' foo->bar){ ?>alt' ), array( 'asf ', '?>asf ' ), array( - '', - '?>' + '', + '?>' ), array( - 'asdf src="../img/img.gif" asdf src asdf src="../img/img.gif" asdf', - '?>asdf src="../img/img.gif" asdf src asdf src="../img/img.gif" asdf' + 'asdf src="../img/img.gif" asdf src asdf src="../img/img.gif" asdf', + '?>asdf src="../img/img.gif" asdf src asdf src="../img/img.gif" asdf' ), array( 'asdf src="../img/img.gif" asdf', diff --git a/tests/unit/framework/SecurityTest.php b/tests/unit/framework/SecurityTest.php index b28d99ada..f0db07f0d 100644 --- a/tests/unit/framework/SecurityTest.php +++ b/tests/unit/framework/SecurityTest.php @@ -100,11 +100,9 @@ class SecurityTest extends \Codeception\TestCase\Test $_SERVER['REQUEST_METHOD'] = 'POST'; $this->assertTrue(Rhymix\Framework\Security::checkCSRF()); - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; $_SERVER['HTTP_REFERER'] = 'http://www.foobar.com/'; $this->assertFalse(Rhymix\Framework\Security::checkCSRF()); - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; $this->assertTrue(Rhymix\Framework\Security::checkCSRF('http://www.rhymix.org/')); } diff --git a/tests/unit/framework/URLTest.php b/tests/unit/framework/URLTest.php index f3d5befb3..ed60020ee 100644 --- a/tests/unit/framework/URLTest.php +++ b/tests/unit/framework/URLTest.php @@ -4,48 +4,42 @@ class URLTest extends \Codeception\TestCase\Test { public function testGetCurrentURL() { - $protocol = \RX_SSL ? 'https://' : 'http://'; - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - $_SERVER['REQUEST_URI'] = '/index.php?foo=bar&xe=sucks'; - $full_url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; + $old_request_uri = $_SERVER['REQUEST_URI']; + $_SERVER['REQUEST_URI'] = '/rhymix/index.php?foo=bar&xe=sucks'; // Getting the current URL - $this->assertEquals($full_url, Rhymix\Framework\URL::getCurrentURL()); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?foo=bar&xe=sucks', Rhymix\Framework\URL::getCurrentURL()); // Adding items to the query string - $this->assertEquals($full_url . '&var=1&arr%5B0%5D=2&arr%5B1%5D=3', Rhymix\Framework\URL::getCurrentURL(array('var' => '1', 'arr' => array(2, 3)))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?foo=bar&xe=sucks&var=1&arr%5B0%5D=2&arr%5B1%5D=3', Rhymix\Framework\URL::getCurrentURL(array('var' => '1', 'arr' => array(2, 3)))); // Removing item from the query string - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks', Rhymix\Framework\URL::getCurrentURL(array('foo' => null))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?xe=sucks', Rhymix\Framework\URL::getCurrentURL(array('foo' => null))); // Removing all items from the query string - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php', Rhymix\Framework\URL::getCurrentURL(array('foo' => null, 'xe' => null))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php', Rhymix\Framework\URL::getCurrentURL(array('foo' => null, 'xe' => null))); // Adding and removing parameters at the same time - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?xe=sucks&l=ko', Rhymix\Framework\URL::getCurrentURL(array('l' => 'ko', 'foo' => null))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?xe=sucks&l=ko', Rhymix\Framework\URL::getCurrentURL(array('l' => 'ko', 'foo' => null))); + + $_SERVER['REQUEST_URI'] = $old_request_uri; } public function testGetCurrentDomainURL() { - $protocol = \RX_SSL ? 'https://' : 'http://'; - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/', Rhymix\Framework\URL::getCurrentDomainURL()); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/', Rhymix\Framework\URL::getCurrentDomainURL('/')); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/foo/bar', Rhymix\Framework\URL::getCurrentDomainURL('/foo/bar')); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php?foo=bar', Rhymix\Framework\URL::getCurrentDomainURL('index.php?foo=bar')); + $this->assertEquals('https://www.rhymix.org/', Rhymix\Framework\URL::getCurrentDomainURL()); + $this->assertEquals('https://www.rhymix.org/', Rhymix\Framework\URL::getCurrentDomainURL('/')); + $this->assertEquals('https://www.rhymix.org/foo/bar', Rhymix\Framework\URL::getCurrentDomainURL('/foo/bar')); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?foo=bar', Rhymix\Framework\URL::getCurrentDomainURL('rhymix/index.php?foo=bar')); } public function testGetCanonicalURL() { - $protocol = \RX_SSL ? 'https://' : 'http://'; - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - $tests = array( - 'foo/bar' => $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', - './foo/bar' => $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', - '/foo/bar' => $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'foo/bar', - '//www.example.com/foo' => $protocol . 'www.example.com/foo', + 'foo/bar' => 'https://www.rhymix.org/rhymix/foo/bar', + './foo/bar' => 'https://www.rhymix.org/rhymix/foo/bar', + '/foo/bar' => 'https://www.rhymix.org/rhymix/foo/bar', + '//www.example.com/foo' => 'https://www.example.com/foo', 'http://xn--cg4bkiv2oina.com/' => 'http://삼성전자.com/', ); @@ -71,21 +65,17 @@ class URLTest extends \Codeception\TestCase\Test public function testModifyURL() { - $protocol = \RX_SSL ? 'https://' : 'http://'; - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - $url = $protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php?foo=bar'; - // Conversion to absolute - $this->assertEquals($url, Rhymix\Framework\URL::modifyURL('./index.php?foo=bar')); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?foo=bar', $url = Rhymix\Framework\URL::modifyURL('./index.php?foo=bar')); // Adding items to the query string - $this->assertEquals($url . '&var=1&arr%5B0%5D=2&arr%5B1%5D=3', Rhymix\Framework\URL::modifyURL($url, array('var' => '1', 'arr' => array(2, 3)))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?foo=bar&var=1&arr%5B0%5D=2&arr%5B1%5D=3', Rhymix\Framework\URL::modifyURL($url, array('var' => '1', 'arr' => array(2, 3)))); // Removing item from the query string - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php', Rhymix\Framework\URL::modifyURL($url, array('foo' => null))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php', Rhymix\Framework\URL::modifyURL($url, array('foo' => null))); // Adding and removing parameters at the same time - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php?l=ko', Rhymix\Framework\URL::modifyURL($url, array('l' => 'ko', 'foo' => null))); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php?l=ko', Rhymix\Framework\URL::modifyURL($url, array('l' => 'ko', 'foo' => null))); } public function testIsInternalURL() @@ -95,23 +85,17 @@ class URLTest extends \Codeception\TestCase\Test public function testURLFromServerPath() { - $protocol = \RX_SSL ? 'https://' : 'http://'; - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR)); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/index.php', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . 'index.php')); - $this->assertEquals($protocol . $_SERVER['HTTP_HOST'] . '/foo/bar', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . '/foo/bar')); + $this->assertEquals('https://www.rhymix.org/rhymix/', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR)); + $this->assertEquals('https://www.rhymix.org/rhymix/index.php', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . 'index.php')); + $this->assertEquals('https://www.rhymix.org/rhymix/foo/bar', Rhymix\Framework\URL::fromServerPath(\RX_BASEDIR . '/foo/bar')); $this->assertEquals(false, Rhymix\Framework\URL::fromServerPath(dirname(dirname(\RX_BASEDIR)))); $this->assertEquals(false, Rhymix\Framework\URL::fromServerPath('C:/Windows')); } public function testURLToServerPath() { - $protocol = \RX_SSL ? 'https://' : 'http://'; - $_SERVER['HTTP_HOST'] = 'www.rhymix.org'; - - $this->assertEquals(\RX_BASEDIR . 'index.php', Rhymix\Framework\URL::toServerPath($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . 'index.php')); - $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath($protocol . $_SERVER['HTTP_HOST'] . \RX_BASEURL . '/foo/bar?arg=baz')); + $this->assertEquals(\RX_BASEDIR . 'index.php', Rhymix\Framework\URL::toServerPath('http://www.rhymix.org/rhymix/index.php')); + $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath('http://www.rhymix.org/rhymix/foo/bar?arg=baz')); $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath('./foo/bar')); $this->assertEquals(\RX_BASEDIR . 'foo/bar', Rhymix\Framework\URL::toServerPath('foo/bar/../bar')); $this->assertEquals(false, Rhymix\Framework\URL::toServerPath('http://other.domain.com/')); From f9ea115c19de7d52a7e34ab079a223c979147301 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 10:09:48 +0900 Subject: [PATCH 184/318] Fix some minor bugs in global functions and add unit tests --- common/functions.php | 9 +- tests/unit/functions/FunctionsTest.php | 152 +++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 tests/unit/functions/FunctionsTest.php diff --git a/common/functions.php b/common/functions.php index 154d60455..5f9214123 100644 --- a/common/functions.php +++ b/common/functions.php @@ -238,7 +238,7 @@ function starts_with($needle, $haystack, $case_sensitive = true) } else { - !strncasecmp($needle, $haystack, strlen($needle)); + return !strncasecmp($needle, $haystack, strlen($needle)); } } @@ -452,8 +452,11 @@ if (!function_exists('hex2bin')) */ function tobool($input) { - if (preg_match('/^(1|[ty].*|on|oui|si|vrai|aye)$/i', $input)) return true; - if (preg_match('/^(0|[fn].*|off)$/i', $input)) return false; + if (is_scalar($input)) + { + if (preg_match('/^(1|[ty].*|on|ok.*oui|si|vrai|aye)$/i', $input)) return true; + if (preg_match('/^(0|[fn].*|off)$/i', $input)) return false; + } return (bool)$input; } diff --git a/tests/unit/functions/FunctionsTest.php b/tests/unit/functions/FunctionsTest.php new file mode 100644 index 000000000..e89a73977 --- /dev/null +++ b/tests/unit/functions/FunctionsTest.php @@ -0,0 +1,152 @@ + 'xe', 'bar' => 'rhymix', 'key' => array('value1', 'value2', array('bar' => 'value3')), 'last' => 'bears'); + $flattened1 = array('foo' => 'xe', 'bar' => 'value3', 0 => 'value1', 1 => 'value2', 'last' => 'bears'); + $flattened2 = array(0 => 'xe', 1 => 'rhymix', 2 => 'value1', 3 => 'value2', 4 => 'value3', 5 => 'bears'); + + $this->assertEquals('foo', array_first_key($array)); + $this->assertEquals('xe', array_first($array)); + + $this->assertEquals('last', array_last_key($array)); + $this->assertEquals('bears', array_last($array)); + + $this->assertEquals($flattened1, array_flatten($array)); + $this->assertEquals($flattened2, array_flatten($array, false)); + } + + public function testClassBasename() + { + $this->assertEquals('FunctionsTest', class_basename($this)); + $this->assertEquals('FunctionsTest', class_basename(get_class($this))); + } + + public function testEscapeFunctions() + { + $this->assertEquals('<foo>&amp;</foo>', escape('&')); + $this->assertEquals('<foo>&</foo>', escape('&', false)); + + $this->assertEquals('expressionalertXSS', escape_css('expression:alert("XSS")')); + $this->assertEquals('#123456', escape_css('#123456')); + + $this->assertEquals('hello\\\\world', escape_js('hello\\world')); + $this->assertEquals('\u003Cbr \/\u003E', escape_js('
    ')); + + $this->assertEquals('hello\\\\world', escape_sqstr('hello\\world')); + $this->assertEquals('hello"world\\\'quotes', escape_sqstr('hello"world\'quotes')); + + $this->assertEquals('hello\\\\\\$world in \\"quotes\\"', escape_dqstr('hello\\$world in "quotes"')); + $this->assertEquals('\\${array[\'key\']}', escape_dqstr('${array[\'key\']}')); + } + + public function testExplodeWithEscape() + { + $this->assertEquals(array('foo', 'bar'), explode_with_escape(',', 'foo,bar')); + $this->assertEquals(array('foo', 'bar'), explode_with_escape(',', 'foo , bar')); + $this->assertEquals(array('foo', 'bar', 'baz,rhymix'), explode_with_escape(',', 'foo,bar,baz,rhymix', 3)); + $this->assertEquals(array('foo', 'bar', 'baz , rhymix'), explode_with_escape(',', 'foo,bar,baz , rhymix', 3)); + + $this->assertEquals(array('foo', 'bar,baz'), explode_with_escape(',', 'foo,bar\\,baz')); + $this->assertEquals(array('foo', 'bar\\', 'baz'), explode_with_escape(',', 'foo,bar\\ , baz')); + $this->assertEquals(array('foo', 'bar,baz', 'rhymix'), explode_with_escape(',', 'foo,bar\\,baz,rhymix')); + $this->assertEquals(array('foo', 'bar,baz'), explode_with_escape(',', 'foo,bar!,baz', null, '!')); + } + + public function testStartsEndsContains() + { + $this->assertTrue(starts_with('foo', 'foobar')); + $this->assertFalse(starts_with('FOO', 'foobar')); + $this->assertTrue(starts_with('FOO', 'foobar', false)); + $this->assertFalse(starts_with('bar', 'foobar')); + + $this->assertTrue(ends_with('bar', 'foobar')); + $this->assertFalse(ends_with('BAR', 'foobar')); + $this->assertTrue(ends_with('BAR', 'foobar', false)); + $this->assertFalse(ends_with('foo', 'foobar')); + + $this->assertTrue(contains('foo', 'foo bar baz rhymix rocks')); + $this->assertFalse(contains('barbaz', 'foo bar baz rhymix rocks')); + $this->assertTrue(contains('RHYMIX', 'foo bar baz rhymix rocks', false)); + $this->assertFalse(contains('ROCKS', 'foo bar baz rhymix rocks')); + } + + public function testRangeFunctions() + { + $this->assertTrue(is_between(5, 1, 10)); + $this->assertTrue(is_between(1, 1, 10)); + $this->assertTrue(is_between(10, 1, 10)); + $this->assertTrue(is_between(7, 1, 10, true)); + $this->assertFalse(is_between(1, 1, 10, true)); + $this->assertFalse(is_between(10, 1, 10, true)); + + $this->assertEquals(10, force_range(14, 1, 10)); + $this->assertEquals(3, force_range(3, 1, 10)); + $this->assertEquals(1, force_range(-4, 1, 10)); + } + + public function testUrlSafeBase64() + { + $this->assertEquals('Umh5bWl4IF5-', base64_encode_urlsafe('Rhymix ^~')); + $this->assertEquals('Rhymix ^~', base64_decode_urlsafe('Umh5bWl4IF5-')); + } + + public function testHex2Rgb2Hex() + { + $this->assertEquals(array(128, 128, 128), hex2rgb('808080')); + $this->assertEquals(array(60, 71, 244), hex2rgb('#3c47f4')); + $this->assertEquals(array(119, 119, 119), hex2rgb('#777')); + $this->assertEquals(array(51, 102, 153), hex2rgb('369')); + + $this->assertEquals('#808080', rgb2hex(array(128, 128, 128))); + $this->assertEquals('#3c47f4', rgb2hex(array(60, 71, 244))); + $this->assertEquals('777777', rgb2hex(array(119, 119, 119), false)); + $this->assertEquals('#000000', rgb2hex(array())); + } + + public function testToBool() + { + $this->assertTrue(tobool('Y')); + $this->assertTrue(tobool('yes')); + $this->assertTrue(tobool('on')); + $this->assertTrue(tobool('ok')); + $this->assertTrue(tobool('okay')); + $this->assertTrue(tobool('true')); + $this->assertTrue(tobool(1)); + $this->assertTrue(tobool(-1)); + $this->assertTrue(tobool(true)); + $this->assertTrue(tobool(array(1, 2, 3))); + + $this->assertFalse(tobool('N')); + $this->assertFalse(tobool('no')); + $this->assertFalse(tobool('false')); + $this->assertFalse(tobool('off')); + $this->assertFalse(tobool('Fuck you!')); + $this->assertFalse(tobool(0)); + $this->assertFalse(tobool('')); + $this->assertFalse(tobool(false)); + $this->assertFalse(tobool(null)); + $this->assertFalse(tobool(array())); + } + + public function testUTF8Functions() + { + $this->assertTrue(utf8_check('Hello, world!')); + $this->assertTrue(utf8_check('라이믹스')); + $this->assertTrue(utf8_check('')); + $this->assertTrue(utf8_check(iconv('UTF-8', 'EUC-KR', 'One CMS to rule them all...'))); + $this->assertFalse(utf8_check(iconv('UTF-8', 'EUC-KR', '라이믹스'))); + $this->assertFalse(utf8_check(chr(129) . chr(214) . chr(181) . chr(73) . chr(97))); + + $this->assertEquals('Emoticon: 😁', utf8_mbencode("Emoticon: \xf0\x9f\x98\x81")); + $this->assertEquals('Emoticon: 😜', utf8_mbencode("Emoticon: \xf0\x9f\x98\x9c")); + $this->assertEquals('한글은 인코딩하지 않음', utf8_mbencode('한글은 인코딩하지 않음')); + + $this->assertEquals("Weird spaces are in this string", utf8_normalize_spaces("Weird\x20spaces\xe2\x80\x80are\xe2\x80\x84in\xe2\x80\x86\xe2\x80\x8bthis\x0astring")); + $this->assertEquals("Weird spaces are in this\nstring", utf8_normalize_spaces("Weird\x20spaces\xe2\x80\x80are\xe2\x80\x84in\xe2\x80\x86\xe2\x80\x8bthis\x0astring", true)); + $this->assertEquals("Trimmed", utf8_trim("\x20\xe2\x80\x80Trimmed\xe2\x80\x84\xe2\x80\x86\xe2\x80\x8b")); + $this->assertEquals("Trimmed", utf8_trim("\x20\xe2\x80\x80Trimmed\x0a\x0c\x07\x09")); + } +} From d325ef99bc5494324066e00d81e8412a8b4646a3 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 11:36:36 +0900 Subject: [PATCH 185/318] Add unit tests for some legacy tests, too --- common/legacy.php | 2 +- tests/unit/framework/DateTimeTest.php | 17 +- tests/unit/functions/LegacyTest.php | 220 ++++++++++++++++++++++++++ 3 files changed, 236 insertions(+), 3 deletions(-) diff --git a/common/legacy.php b/common/legacy.php index 3f827fa96..3d4af5102 100644 --- a/common/legacy.php +++ b/common/legacy.php @@ -421,7 +421,7 @@ function getCurrentPageUrl($escape = true) */ function isSiteID($domain) { - return preg_match('/^([a-zA-Z0-9\_]+)$/', $domain); + return (bool)preg_match('/^([a-zA-Z0-9\_]+)$/', $domain); } /** diff --git a/tests/unit/framework/DateTimeTest.php b/tests/unit/framework/DateTimeTest.php index 737147bb3..d5adc1105 100644 --- a/tests/unit/framework/DateTimeTest.php +++ b/tests/unit/framework/DateTimeTest.php @@ -66,15 +66,28 @@ class DateTimeTest extends \Codeception\TestCase\Test { $timestamp = 1454000000; - // Test zdate() when the internal time zone is different from the default time zone. + // Test when the internal time zone is different from the default time zone. Rhymix\Framework\Config::set('locale.internal_timezone', 10800); $this->assertEquals('20160128195320', getInternalDateTime($timestamp)); - // Test zdate() when the internal time zone is the same as the default time zone. + // Test when the internal time zone is the same as the default time zone. Rhymix\Framework\Config::set('locale.internal_timezone', 32400); $this->assertEquals('20160129015320', getInternalDateTime($timestamp)); } + public function testGetDisplayDateTime() + { + $timestamp = 1454000000; + + // Test when the display time zone is different from the internal time zone. + $_SESSION['timezone'] = 'America/Los_Angeles'; + $this->assertEquals('20160128085320', getDisplayDateTime($timestamp)); + + // Test when the display time zone is the same as the internal time zone. + $_SESSION['timezone'] = 'Etc/GMT-3'; + $this->assertEquals('20160128195320', getDisplayDateTime($timestamp)); + } + public function testGetTimeGap() { $GLOBALS['lang'] = Rhymix\Framework\Lang::getInstance('en'); diff --git a/tests/unit/functions/LegacyTest.php b/tests/unit/functions/LegacyTest.php index 413b1f9cd..5bb693d56 100644 --- a/tests/unit/functions/LegacyTest.php +++ b/tests/unit/functions/LegacyTest.php @@ -2,5 +2,225 @@ class LegacyTest extends \Codeception\TestCase\Test { + public function testGetModule() + { + $this->assertTrue(getModule('board', 'controller') instanceof BoardController); + $this->assertTrue(getModule('board', 'model') instanceof BoardModel); + $this->assertTrue(getModule('board', 'view', 'admin') instanceof BoardAdminView); + $this->assertTrue(getModule('board') instanceof BoardView); + $this->assertTrue(getAdminController('board') instanceof BoardAdminController); + $this->assertTrue(getAdminModel('board') instanceof BoardAdminModel); + $this->assertTrue(getAdminView('board') instanceof BoardAdminView); + $this->assertTrue(getController('board') instanceof BoardController); + $this->assertTrue(getModel('board') instanceof BoardModel); + $this->assertTrue(getView('board') instanceof BoardView); + $this->assertTrue(getAPI('board') instanceof BoardApi); + $this->assertTrue(getMobile('board') instanceof BoardMobile); + $this->assertTrue(getWAP('board') instanceof BoardWap); + $this->assertTrue(getClass('board') instanceof Board); + } + public function testGetNextSequence() + { + if (!file_exists(\RX_BASEDIR . 'files/config/config.php')) + { + return; + } + + $this->assertGreaterThan(0, $sequence1 = getNextSequence()); + $this->assertGreaterThan($sequence1, $sequence2 = getNextSequence()); + + $this->assertTrue(checkUserSequence($sequence1)); + $this->assertTrue(checkUserSequence($sequence2)); + + $this->assertFalse(checkUserSequence(-1)); + setUserSequence(-1); + $this->assertTrue(checkUserSequence(-1)); + } + + public function testGetURL() + { + /** + * TODO: + * - getUrl() + * - getNotEncodedUrl() + * - getAutoEncodedUrl() + * - getFullUrl() + * - getNotEncodedFullUrl() + * - getSiteUrl() + * - getNotEncodedSiteUrl() + * - getFullSiteUrl() + * - getCurrentPageUrl() + * - getScriptPath() + * - getRequestUriByServerEnviroment() + */ + } + + public function testIsSiteID() + { + $this->assertTrue(isSiteID('rhymix_RHYMIX_1234')); + $this->assertFalse(isSiteID('www.rhymix.org')); + } + + public function testCutStr() + { + $this->assertEquals('안녕하세요? 라이믹스...', cut_str('안녕하세요? 라이믹스입니다. 제목이 너무 길어서 잘립니다.', 20)); + $this->assertEquals('Hello? This is Rhymix...', cut_str('Hello? This is Rhymix. This title is very long.', 20)); + } + + public function testTimeFunctions() + { + $this->assertEquals(0, get_time_zone_offset('00:00')); + $this->assertEquals(32400, get_time_zone_offset('+09:00')); + $this->assertEquals(32400, get_time_zone_offset('+0900')); + $this->assertEquals(32400, get_time_zone_offset('0900')); + $this->assertEquals(-18000, get_time_zone_offset('-05:00')); + $this->assertEquals(-18000, get_time_zone_offset('-0500')); + + $this->assertEquals('Jan', getMonthName(1)); + $this->assertEquals('Sep', getMonthName(9, true)); + $this->assertEquals('September', getMonthName(9, false)); + + /** + * The following functions are tested in DateTimeTest: + * - zgap() + * - zdate() + * - ztime() + * - getInternalDateTime() + * - getDisplayDateTime() + * - getTimeGap() + */ + } + + public function testGetEncodedEmailAddress() + { + $this->assertNotEquals('devops@rhymix.org', getEncodeEmailAddress('devops@rhymix.org')); + $this->assertContains('&#X', getEncodeEmailAddress('devops@rhymix.org')); + } + + public function testGetMicrotime() + { + $microtime1 = microtime(true); + $microtime2 = getMicroTime(); + $microtime3 = microtime(true); + + $this->assertEquals('double', gettype($microtime2)); + $this->assertGreaterThanOrEqual($microtime1, $microtime2); + $this->assertGreaterThanOrEqual($microtime2, $microtime3); + } + + public function testDelObjectVars() + { + $target = (object)array('foo' => 1, 'bar' => 2, 'baz' => 3, 'rhymix' => 4); + $delete = (object)array('bar' => 5, 'baz' => 6); + $result = delObjectVars($target, $delete); + + // Check if the keys were deleted from the result. + $this->assertTrue(isset($result->foo)); + $this->assertFalse(isset($result->bar)); + $this->assertFalse(isset($result->baz)); + $this->assertTrue(isset($result->rhymix)); + + // Check if the keys are intact in the original target. + $this->assertTrue(isset($target->bar)); + $this->assertTrue(isset($target->baz)); + } + + public function testGetDestroyXeVars() + { + // Test array. (Keys should be intact in the original target.) + $target = array('foo' => 1, 'bar' => 2, 'xe_validator_id' => 3); + $result = getDestroyXeVars($target); + $this->assertFalse(isset($result['xe_validator_id'])); + $this->assertTrue(isset($target['xe_validator_id'])); + + // Test object. (Keys should be deleted from the original target.) + $target = (object)array('foo' => 1, 'bar' => 2, 'xe_validator_id' => 3); + $result = getDestroyXeVars($target); + $this->assertFalse(isset($result->xe_validator_id)); + $this->assertFalse(isset($target->xe_validator_id)); + } + + public function testGetNumberingPath() + { + $this->assertEquals('001/', getNumberingPath(1)); + $this->assertEquals('012/', getNumberingPath(12)); + $this->assertEquals('123/', getNumberingPath(123)); + $this->assertEquals('234/001/', getNumberingPath(1234)); + $this->assertEquals('345/012/', getNumberingPath(12345)); + $this->assertEquals('456/123/', getNumberingPath(123456)); + $this->assertEquals('567/234/001/', getNumberingPath(1234567)); + $this->assertEquals('678/345/012/', getNumberingPath(12345678)); + $this->assertEquals('789/456/123/', getNumberingPath(123456789)); + } + + public function testMysqlPre4HashPassword() + { + $this->assertEquals('5d2e19393cc5ef67', mysql_pre4_hash_password('password')); + $this->assertEquals('25a4fb474e17c19a', mysql_pre4_hash_password('pass\'#word')); + } + + public function testJsonEncode2() + { + $data = array('foo' => 1, 'bar' => 2, 'baz' => 3, 'rhymix' => 4); + $this->assertEquals(json_encode($data), json_encode2($data)); + } + + public function TestIsCrawler() + { + $original_user_agent = $_SERVER['HTTP_USER_AGENT']; + + // Test automatic detection from User-Agent string. + $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 6.1; rv:45.0) Gecko/20100101 Firefox/45.0'; + $this->assertFalse(isCrawler()); + $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'; + $this->assertTrue(isCrawler()); + + // Test manual detection. + $this->assertTrue(isCrawler('Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)')); + $this->assertTrue(isCrawler('Yeti/1.0 (NHN Corp.; http://help.naver.com/robots/)')); + $this->assertFalse(isCrawler('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36')); + $this->assertFalse(isCrawler('Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25')); + + $_SERVER['HTTP_USER_AGENT'] = $original_user_agent; + } + + public function testMiscUTF8Functions() + { + $this->assertEquals('<img>', url_decode('%3Cimg%3E')); + $this->assertEquals('한글 % English', utf8RawUrlDecode('%uD55C%uAE00%20%25%20English')); + $this->assertEquals('뷁', _code2utf(48577)); + + $this->assertTrue(detectUTF8('라이믹스')); + $this->assertTrue(detectUTF8(urlencode('라이믹스'))); + $this->assertTrue(detectUTF8('%87%a9%43%cd%ef', false, false)); + $this->assertFalse(detectUTF8(iconv('UTF-8', 'EUC-KR', '라이믹스'))); + $this->assertFalse(detectUTF8(chr(129) . chr(214) . chr(181) . chr(73) . chr(97))); + $this->assertFalse(detectUTF8('%87%a9%43%cd%ef')); + $this->assertEquals(mb_convert_encoding('라이믹스', 'UTF-8', 'CP949'), detectUTF8('라이믹스', true)); + $this->assertEquals('라이믹스', detectUTF8(iconv('UTF-8', 'EUC-KR', '라이믹스'), true)); + } + + public function testMiscSecurityFunctions() + { + /** + * TODO: + * - stripEmbedTagForAdmin() + * - checkCSRF() + */ + } + + public function testRecurciveExposureCheck() + { + /** + * TODO + */ + } + + public function testChangeValueInUrl() + { + /** + * TODO + */ + } } From b890f9f42e6fc58833b37814d9a353a6c702bd14 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 14:14:41 +0900 Subject: [PATCH 186/318] Consistently update the new message flag file --- .../communication.controller.php | 60 +++++++++---------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 562b14a35..56c161bc4 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -258,13 +258,7 @@ class communicationController extends communication $oDB->commit(); // create a flag that message is sent (in file format) - $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); - - $oCommunicationModel = getModel('communication'); - $new_message_count = $oCommunicationModel->getNewMessageCount($receiver_srl); - FileHandler::writeFile($flag_file, $new_message_count); + $this->updateFlagFile($receiver_srl); return new Object(0, 'success_sended'); } @@ -305,7 +299,7 @@ class communicationController extends communication { return $output; } - + $this->updateFlagFile($logged_info->member_srl); $this->setMessage('success_registed'); } @@ -365,7 +359,7 @@ class communicationController extends communication { return $output; } - + $this->updateFlagFile($member_srl); $this->setMessage('success_deleted'); } @@ -443,7 +437,7 @@ class communicationController extends communication { return $output; } - + $this->updateFlagFile($member_srl); $this->setMessage('success_deleted'); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'mid', Context::get('mid'), 'act', 'dispCommunicationMessages', 'message_type', Context::get('message_type')); @@ -778,26 +772,30 @@ class communicationController extends communication $args->related_srl = $message_srl; $output = executeQuery('communication.setMessageReaded', $args); - // Renew a flag - $logged_info = Context::get('logged_info'); - $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)) - { - $oCommunicationModel = getModel('communication'); - $new_message_count = $oCommunicationModel->getNewMessageCount(); - if($new_message_count > 0) - { - FileHandler::writeFile($flag_file, $new_message_count); - } - else - { - FileHandler::removeFile($flag_file); - } - } - + // Update flag file + $this->updateFlagFile($logged_info->member_srl); return $output; } + + /** + * Update flag file + * @param int $member_srl + * @return void + */ + function updateFlagFile($member_srl) + { + $flag_path = \RX_BASEDIR . 'files/member_extra_info/new_message_flags/' . getNumberingPath($member_srl); + $flag_file = $flag_path . $member_srl; + $new_message_count = getModel('communication')->getNewMessageCount($member_srl); + if($new_message_count > 0) + { + FileHandler::writeFile($flag_file, $new_message_count); + } + else + { + FileHandler::removeFile($flag_file); + } + } function triggerModuleHandlerBefore($obj) { @@ -833,14 +831,14 @@ class communicationController extends communication if($config->enable_message == 'Y' && $obj->act != 'dispCommunicationNewMessage') { $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); + $flag_file = $flag_path . $logged_info->member_srl; if(file_exists($flag_file)) { // Pop-up to display messages if a flag on new message is set - $new_message_count = (int) trim(FileHandler::readFile($flag_file)); + $new_message_count = (int)trim(FileHandler::readFile($flag_file)); if($new_message_count > 0) { - $text = preg_replace('@\r?\n@', '\\n', addslashes(lang('alert_new_message_arrived'))); + $text = escape_js(lang('alert_new_message_arrived')); Context::addHtmlFooter(""); Context::loadFile(array('./modules/communication/tpl/js/member_communication.js'), true); } From 5ead23ae7931455e7e571d5bad3aac9d7eb238a0 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 14:18:37 +0900 Subject: [PATCH 187/318] Update new message flag file when reading message --- modules/communication/communication.view.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/communication/communication.view.php b/modules/communication/communication.view.php index ff3c10dc2..b76264cb6 100644 --- a/modules/communication/communication.view.php +++ b/modules/communication/communication.view.php @@ -116,6 +116,9 @@ class communicationView extends communication $columnList = array('message_srl', 'readed', 'title', 'member.member_srl', 'member.nick_name', 'message.regdate', 'readed_date'); $output = $oCommunicationModel->getMessages($message_type, $columnList); + // Update flag file + getController('communication')->updateFlagFile($logged_info->member_srl); + // set a template file Context::set('total_count', $output->total_count); Context::set('total_page', $output->total_page); From 54795421fe736b0a9885cd8025bd20b447fb2ca0 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 14:20:51 +0900 Subject: [PATCH 188/318] Fix styles of new message notification --- .../tpl/js/member_communication.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/modules/communication/tpl/js/member_communication.js b/modules/communication/tpl/js/member_communication.js index ae6f8c013..a69263a43 100644 --- a/modules/communication/tpl/js/member_communication.js +++ b/modules/communication/tpl/js/member_communication.js @@ -3,17 +3,20 @@ window.xeNotifyMessage = function(text, count){ $bar = $('div.message.info'); if(!$bar.length) { - $bar = $('
    ') - .hide() - .css({ - 'position' : 'absolute', - 'z-index' : '100', - }) - .prependTo(document.body); + $bar = jQuery('
    ').hide().css({ + 'position' : 'absolute', + 'opacity' : 0.7, + 'z-index' : 10000, + }).appendTo(document.body); } text = text.replace('%d', count); - $bar.html('

    '+text+'

    ').height(); + var link = jQuery(''); + link.attr("href", current_url.setQuery('module','').setQuery('act','dispCommunicationNewMessage')); + //link.attr("onclick", "popopen(this.href, 'popup');xeNotifyMessageClose(); return false;"); + link.text(text); + var para = jQuery('

    '); + para.append(link).appendTo($bar); $bar.show().animate({top:0}); }; From 4b2bced0eb3ad48ebd5dfecd005ebad9f1358ea2 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 14:39:53 +0900 Subject: [PATCH 189/318] Fix URL in new message notification --- modules/communication/tpl/js/member_communication.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/communication/tpl/js/member_communication.js b/modules/communication/tpl/js/member_communication.js index a69263a43..661a431ab 100644 --- a/modules/communication/tpl/js/member_communication.js +++ b/modules/communication/tpl/js/member_communication.js @@ -12,7 +12,7 @@ text = text.replace('%d', count); var link = jQuery(''); - link.attr("href", current_url.setQuery('module','').setQuery('act','dispCommunicationNewMessage')); + link.attr("href", current_url.setQuery('module','').setQuery('act','dispCommunicationMessages')); //link.attr("onclick", "popopen(this.href, 'popup');xeNotifyMessageClose(); return false;"); link.text(text); var para = jQuery('

    '); From 488704acf01f1000efef5e2b2dfd76fae1265f2a Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 14:48:54 +0900 Subject: [PATCH 190/318] Move trigger to moduleObject.proc.after for better consistency --- modules/communication/communication.class.php | 19 ++++++++++++++++++- .../communication.controller.php | 5 +++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/communication/communication.class.php b/modules/communication/communication.class.php index a4b2518d3..fd8600e27 100644 --- a/modules/communication/communication.class.php +++ b/modules/communication/communication.class.php @@ -9,9 +9,12 @@ class communication extends ModuleObject { private $triggers = array( - array('moduleHandler.init', 'communication', 'controller', 'triggerModuleHandlerBefore', 'before'), + array('moduleObject.proc', 'communication', 'controller', 'triggerModuleProcAfter', 'after'), array('member.getMemberMenu', 'communication', 'controller', 'triggerMemberMenu', 'before') ); + private $delete_triggers = array( + array('moduleHandler.init', 'communication', 'controller', 'triggerModuleHandlerBefore', 'before'), + ); /** * Implement if additional tasks are necessary when installing @@ -47,6 +50,13 @@ class communication extends ModuleObject return TRUE; } } + foreach($this->delete_triggers as $trigger) + { + if($oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) + { + return TRUE; + } + } if(!is_dir("./files/member_extra_info/new_message_flags")) { @@ -72,6 +82,13 @@ class communication extends ModuleObject $oModuleController->insertTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); } } + foreach($this->delete_triggers as $trigger) + { + if($oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) + { + $oModuleController->deleteTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); + } + } if(!is_dir("./files/member_extra_info/new_message_flags")) { diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 56c161bc4..9b04e270d 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -798,6 +798,11 @@ class communicationController extends communication } function triggerModuleHandlerBefore($obj) + { + return $this->triggerModuleProcAfter($obj); + } + + function triggerModuleProcAfter($obj) { if(!Context::get('is_logged') || $obj->module == 'member') { From 5a3893be5e9894b5bd6914814c30bcfef37bb51b Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 14:51:58 +0900 Subject: [PATCH 191/318] Do not display notification if we are already on the message view --- modules/communication/communication.controller.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 9b04e270d..74392742d 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -808,6 +808,10 @@ class communicationController extends communication { return new Object(); } + if (starts_with('dispCommunication', Context::get('act'))) + { + return new Object(); + } $logged_info = Context::get('logged_info'); $oCommunicationModel = getModel('communication'); From 94859b10460c3ceaca61219e42696dc8b53d0298 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 15:25:32 +0900 Subject: [PATCH 192/318] Improve performance of FilenameFilter::cleanPath() --- common/framework/filters/filenamefilter.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/common/framework/filters/filenamefilter.php b/common/framework/filters/filenamefilter.php index a43fb8ba2..dd99954c9 100644 --- a/common/framework/filters/filenamefilter.php +++ b/common/framework/filters/filenamefilter.php @@ -65,16 +65,16 @@ class FilenameFilter $path = str_replace('\\', '/', $path); // Remove querystrings and URL fragments. - $path = preg_replace('@[\?#].+$@', '', $path); + if (($querystring = strpbrk($path, '?#')) !== false) + { + $path = substr($path, 0, -1 * strlen($querystring)); + } - // Remove duplicate slashes, except at the beginning of a URL. - $path = preg_replace('@(? Date: Wed, 16 Mar 2016 16:31:27 +0900 Subject: [PATCH 193/318] Do not display HTML error page if the current SAPI is CLI --- common/framework/debug.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/framework/debug.php b/common/framework/debug.php index bf2227904..566f0a923 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -397,6 +397,12 @@ class Debug */ public static function displayErrorScreen($message) { + // Do not display error screen in CLI. + if (php_sapi_name() === 'cli') + { + return; + } + // Disable output buffering. while (ob_get_level()) { From e9ca45eac789264c40b7a831ca10c5b182819578 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 19:10:53 +0900 Subject: [PATCH 194/318] Fix disappearing message & friend menu --- modules/communication/communication.controller.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 74392742d..a287e8657 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -808,11 +808,6 @@ class communicationController extends communication { return new Object(); } - if (starts_with('dispCommunication', Context::get('act'))) - { - return new Object(); - } - $logged_info = Context::get('logged_info'); $oCommunicationModel = getModel('communication'); $config = $oCommunicationModel->getConfig(); @@ -837,6 +832,11 @@ class communicationController extends communication $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); } + if (starts_with('dispCommunication', Context::get('act'))) + { + return new Object(); + } + if($config->enable_message == 'Y' && $obj->act != 'dispCommunicationNewMessage') { $flag_path = './files/member_extra_info/new_message_flags/' . getNumberingPath($logged_info->member_srl); From 9fc1926dc361af29c422dcb0be87f93732315f64 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 19:19:53 +0900 Subject: [PATCH 195/318] Fix disappearing message & friend menu in other places, too --- modules/communication/communication.class.php | 18 +-------- .../communication.controller.php | 37 +++++++------------ 2 files changed, 15 insertions(+), 40 deletions(-) diff --git a/modules/communication/communication.class.php b/modules/communication/communication.class.php index fd8600e27..35f51b2a8 100644 --- a/modules/communication/communication.class.php +++ b/modules/communication/communication.class.php @@ -9,12 +9,10 @@ class communication extends ModuleObject { private $triggers = array( + array('moduleHandler.init', 'communication', 'controller', 'triggerModuleHandlerBefore', 'before'), array('moduleObject.proc', 'communication', 'controller', 'triggerModuleProcAfter', 'after'), array('member.getMemberMenu', 'communication', 'controller', 'triggerMemberMenu', 'before') ); - private $delete_triggers = array( - array('moduleHandler.init', 'communication', 'controller', 'triggerModuleHandlerBefore', 'before'), - ); /** * Implement if additional tasks are necessary when installing @@ -50,13 +48,6 @@ class communication extends ModuleObject return TRUE; } } - foreach($this->delete_triggers as $trigger) - { - if($oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) - { - return TRUE; - } - } if(!is_dir("./files/member_extra_info/new_message_flags")) { @@ -82,13 +73,6 @@ class communication extends ModuleObject $oModuleController->insertTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); } } - foreach($this->delete_triggers as $trigger) - { - if($oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) - { - $oModuleController->deleteTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); - } - } if(!is_dir("./files/member_extra_info/new_message_flags")) { diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index a287e8657..3845e8b20 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -799,29 +799,10 @@ class communicationController extends communication function triggerModuleHandlerBefore($obj) { - return $this->triggerModuleProcAfter($obj); - } - - function triggerModuleProcAfter($obj) - { - if(!Context::get('is_logged') || $obj->module == 'member') - { - return new Object(); - } - $logged_info = Context::get('logged_info'); - $oCommunicationModel = getModel('communication'); - $config = $oCommunicationModel->getConfig(); - if($obj->module == 'admin') - { - return new Object(); - } - if($config->enable_message == 'N' && $config->enable_friend == 'N') - { - return new Object(); - } - // Add menus on the member login information + $config = getModel('communication')->getConfig(); $oMemberController = getController('member'); + if($config->enable_message == 'Y') { $oMemberController->addMemberMenu('dispCommunicationMessages', 'cmd_view_message_box'); @@ -831,13 +812,23 @@ class communicationController extends communication { $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); } + } + + function triggerModuleProcAfter($obj) + { + if (!Context::get('is_logged') || $obj->module == 'member' || $obj->module == 'admin') + { + return new Object(); + } - if (starts_with('dispCommunication', Context::get('act'))) + $config = getModel('communication')->getConfig(); + if ($config->enable_message == 'N' || starts_with('dispCommunication', Context::get('act'))) { return new Object(); } - if($config->enable_message == 'Y' && $obj->act != 'dispCommunicationNewMessage') + $logged_info = Context::get('logged_info'); + if ($config->enable_message == 'Y') { $flag_path = './files/member_extra_info/new_message_flags/' . getNumberingPath($logged_info->member_srl); $flag_file = $flag_path . $logged_info->member_srl; From 25cf1856a663141098f4415285c74c6b285c6a84 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Wed, 16 Mar 2016 19:22:53 +0900 Subject: [PATCH 196/318] Remove duplicate checking of new message flag file --- modules/communication/communication.view.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/communication/communication.view.php b/modules/communication/communication.view.php index b76264cb6..28e043767 100644 --- a/modules/communication/communication.view.php +++ b/modules/communication/communication.view.php @@ -115,9 +115,6 @@ class communicationView extends communication // Extract a list $columnList = array('message_srl', 'readed', 'title', 'member.member_srl', 'member.nick_name', 'message.regdate', 'readed_date'); $output = $oCommunicationModel->getMessages($message_type, $columnList); - - // Update flag file - getController('communication')->updateFlagFile($logged_info->member_srl); // set a template file Context::set('total_count', $output->total_count); From 826aa8aa3659f0906c230c1893711b13a3674e3d Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 06:05:05 +0900 Subject: [PATCH 197/318] add ncenterlite module from xe-public. --- modules/ncenterlite/LICENSE | 84 ++ modules/ncenterlite/LICENSE-ko | 97 ++ modules/ncenterlite/conf/info.xml | 14 + modules/ncenterlite/conf/module.xml | 30 + modules/ncenterlite/lang/lang.xml | 458 +++++++ .../m.skins/default/NotifyList.html | 24 + modules/ncenterlite/m.skins/default/img/p.png | Bin 0 -> 7463 bytes .../ncenterlite/m.skins/default/ncenter.html | 124 ++ .../m.skins/default/ncenterlite.black.css | 15 + .../default/ncenterlite.blacknoprofile.css | 17 + .../m.skins/default/ncenterlite.css | 185 +++ .../m.skins/default/ncenterlite.gray.css | 16 + .../default/ncenterlite.graynoprofile.css | 18 + .../m.skins/default/ncenterlite.html | 122 ++ .../m.skins/default/ncenterlite.mobile.css | 12 + .../m.skins/default/ncenterlite.white.css | 16 + .../default/ncenterlite.whitenoprofile.css | 18 + .../ncenterlite/m.skins/default/notify.css | 97 ++ modules/ncenterlite/m.skins/default/skin.xml | 32 + .../m.skins/default/userconfig.html | 66 ++ .../ncenterlite.admin.controller.php | 152 +++ .../ncenterlite/ncenterlite.admin.model.php | 105 ++ .../ncenterlite/ncenterlite.admin.view.php | 90 ++ modules/ncenterlite/ncenterlite.class.php | 213 ++++ .../ncenterlite/ncenterlite.controller.php | 1050 +++++++++++++++++ modules/ncenterlite/ncenterlite.mobile.php | 38 + modules/ncenterlite/ncenterlite.model.php | 376 ++++++ modules/ncenterlite/ncenterlite.view.php | 71 ++ modules/ncenterlite/queries/deleteNotify.xml | 10 + .../ncenterlite/queries/deleteNotifyAll.xml | 8 + .../queries/deleteNotifyByMemberSrl.xml | 10 + .../ncenterlite/queries/deleteNotifyBySrl.xml | 10 + .../queries/deleteNotifyByTargetSrl.xml | 10 + .../queries/getAdminNotifyList.xml | 11 + .../ncenterlite/queries/getAllUserConfig.xml | 11 + .../queries/getCountNewMessage.xml | 13 + .../ncenterlite/queries/getDispNotifyList.xml | 20 + .../ncenterlite/queries/getMemberAdmins.xml | 12 + .../ncenterlite/queries/getMemberSrlById.xml | 13 + .../queries/getMemberSrlByNickName.xml | 13 + .../ncenterlite/queries/getMemberTotals.xml | 12 + modules/ncenterlite/queries/getNotifyList.xml | 21 + .../ncenterlite/queries/getNotifyNewCount.xml | 14 + modules/ncenterlite/queries/getNotifyType.xml | 13 + .../ncenterlite/queries/getNotifyTypeByID.xml | 13 + .../ncenterlite/queries/getSocialxeCount.xml | 13 + modules/ncenterlite/queries/getUserConfig.xml | 13 + modules/ncenterlite/queries/insertNotify.xml | 24 + .../ncenterlite/queries/insertNotifyType.xml | 11 + .../ncenterlite/queries/insertUserConfig.xml | 12 + .../queries/updateNotifyReaded.xml | 12 + .../queries/updateNotifyReadedAll.xml | 11 + .../queries/updateNotifyReadedBySrl.xml | 13 + .../queries/updateNotifyReadedByTargetSrl.xml | 12 + .../queries/updateNotifyReadedByType.xml | 12 + .../ncenterlite/queries/updateUserConfig.xml | 14 + modules/ncenterlite/ruleset/insertConfig.xml | 13 + .../schemas/ncenterlite_notify.xml | 24 + .../schemas/ncenterlite_notify_type.xml | 6 + .../schemas/ncenterlite_user_set.xml | 7 + .../ncenterlite/skins/default/NotifyList.html | 46 + modules/ncenterlite/skins/default/img/p.png | Bin 0 -> 7463 bytes .../skins/default/ncenterlite.black.css | 15 + .../default/ncenterlite.blacknoprofile.css | 17 + .../ncenterlite/skins/default/ncenterlite.css | 185 +++ .../skins/default/ncenterlite.gray.css | 16 + .../default/ncenterlite.graynoprofile.css | 18 + .../skins/default/ncenterlite.html | 125 ++ .../skins/default/ncenterlite.mobile.css | 12 + .../skins/default/ncenterlite.white.css | 16 + .../default/ncenterlite.whitenoprofile.css | 18 + modules/ncenterlite/skins/default/skin.xml | 40 + .../ncenterlite/skins/default/userconfig.html | 68 ++ .../skins/default_bottom/NotifyList.html | 46 + .../skins/default_bottom/img/p.png | Bin 0 -> 7463 bytes .../default_bottom/ncenterlite.black.css | 15 + .../ncenterlite.blacknoprofile.css | 17 + .../skins/default_bottom/ncenterlite.css | 177 +++ .../skins/default_bottom/ncenterlite.gray.css | 16 + .../ncenterlite.graynoprofile.css | 18 + .../skins/default_bottom/ncenterlite.html | 124 ++ .../default_bottom/ncenterlite.mobile.css | 12 + .../default_bottom/ncenterlite.white.css | 16 + .../ncenterlite.whitenoprofile.css | 18 + .../ncenterlite/skins/default_bottom/skin.xml | 40 + .../skins/default_bottom/userconfig.html | 68 ++ modules/ncenterlite/tpl/Config.html | 272 +++++ modules/ncenterlite/tpl/css/ncenter_admin.css | 12 + modules/ncenterlite/tpl/header.html | 14 + modules/ncenterlite/tpl/js/ncenter_admin.js | 106 ++ modules/ncenterlite/tpl/js/ncenterlite.js | 57 + modules/ncenterlite/tpl/ncenter_list.html | 67 ++ 92 files changed, 5622 insertions(+) create mode 100644 modules/ncenterlite/LICENSE create mode 100644 modules/ncenterlite/LICENSE-ko create mode 100644 modules/ncenterlite/conf/info.xml create mode 100644 modules/ncenterlite/conf/module.xml create mode 100644 modules/ncenterlite/lang/lang.xml create mode 100644 modules/ncenterlite/m.skins/default/NotifyList.html create mode 100644 modules/ncenterlite/m.skins/default/img/p.png create mode 100644 modules/ncenterlite/m.skins/default/ncenter.html create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.black.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.blacknoprofile.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.gray.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.graynoprofile.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.html create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.mobile.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.white.css create mode 100644 modules/ncenterlite/m.skins/default/ncenterlite.whitenoprofile.css create mode 100644 modules/ncenterlite/m.skins/default/notify.css create mode 100644 modules/ncenterlite/m.skins/default/skin.xml create mode 100644 modules/ncenterlite/m.skins/default/userconfig.html create mode 100644 modules/ncenterlite/ncenterlite.admin.controller.php create mode 100644 modules/ncenterlite/ncenterlite.admin.model.php create mode 100644 modules/ncenterlite/ncenterlite.admin.view.php create mode 100644 modules/ncenterlite/ncenterlite.class.php create mode 100644 modules/ncenterlite/ncenterlite.controller.php create mode 100644 modules/ncenterlite/ncenterlite.mobile.php create mode 100644 modules/ncenterlite/ncenterlite.model.php create mode 100644 modules/ncenterlite/ncenterlite.view.php create mode 100644 modules/ncenterlite/queries/deleteNotify.xml create mode 100644 modules/ncenterlite/queries/deleteNotifyAll.xml create mode 100644 modules/ncenterlite/queries/deleteNotifyByMemberSrl.xml create mode 100644 modules/ncenterlite/queries/deleteNotifyBySrl.xml create mode 100644 modules/ncenterlite/queries/deleteNotifyByTargetSrl.xml create mode 100644 modules/ncenterlite/queries/getAdminNotifyList.xml create mode 100644 modules/ncenterlite/queries/getAllUserConfig.xml create mode 100644 modules/ncenterlite/queries/getCountNewMessage.xml create mode 100644 modules/ncenterlite/queries/getDispNotifyList.xml create mode 100644 modules/ncenterlite/queries/getMemberAdmins.xml create mode 100644 modules/ncenterlite/queries/getMemberSrlById.xml create mode 100644 modules/ncenterlite/queries/getMemberSrlByNickName.xml create mode 100644 modules/ncenterlite/queries/getMemberTotals.xml create mode 100644 modules/ncenterlite/queries/getNotifyList.xml create mode 100644 modules/ncenterlite/queries/getNotifyNewCount.xml create mode 100644 modules/ncenterlite/queries/getNotifyType.xml create mode 100644 modules/ncenterlite/queries/getNotifyTypeByID.xml create mode 100644 modules/ncenterlite/queries/getSocialxeCount.xml create mode 100644 modules/ncenterlite/queries/getUserConfig.xml create mode 100644 modules/ncenterlite/queries/insertNotify.xml create mode 100644 modules/ncenterlite/queries/insertNotifyType.xml create mode 100644 modules/ncenterlite/queries/insertUserConfig.xml create mode 100644 modules/ncenterlite/queries/updateNotifyReaded.xml create mode 100644 modules/ncenterlite/queries/updateNotifyReadedAll.xml create mode 100644 modules/ncenterlite/queries/updateNotifyReadedBySrl.xml create mode 100644 modules/ncenterlite/queries/updateNotifyReadedByTargetSrl.xml create mode 100644 modules/ncenterlite/queries/updateNotifyReadedByType.xml create mode 100644 modules/ncenterlite/queries/updateUserConfig.xml create mode 100644 modules/ncenterlite/ruleset/insertConfig.xml create mode 100644 modules/ncenterlite/schemas/ncenterlite_notify.xml create mode 100644 modules/ncenterlite/schemas/ncenterlite_notify_type.xml create mode 100644 modules/ncenterlite/schemas/ncenterlite_user_set.xml create mode 100644 modules/ncenterlite/skins/default/NotifyList.html create mode 100644 modules/ncenterlite/skins/default/img/p.png create mode 100644 modules/ncenterlite/skins/default/ncenterlite.black.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.blacknoprofile.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.gray.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.graynoprofile.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.html create mode 100644 modules/ncenterlite/skins/default/ncenterlite.mobile.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.white.css create mode 100644 modules/ncenterlite/skins/default/ncenterlite.whitenoprofile.css create mode 100644 modules/ncenterlite/skins/default/skin.xml create mode 100644 modules/ncenterlite/skins/default/userconfig.html create mode 100644 modules/ncenterlite/skins/default_bottom/NotifyList.html create mode 100644 modules/ncenterlite/skins/default_bottom/img/p.png create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.black.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.blacknoprofile.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.gray.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.graynoprofile.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.html create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.mobile.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.white.css create mode 100644 modules/ncenterlite/skins/default_bottom/ncenterlite.whitenoprofile.css create mode 100644 modules/ncenterlite/skins/default_bottom/skin.xml create mode 100644 modules/ncenterlite/skins/default_bottom/userconfig.html create mode 100644 modules/ncenterlite/tpl/Config.html create mode 100644 modules/ncenterlite/tpl/css/ncenter_admin.css create mode 100644 modules/ncenterlite/tpl/header.html create mode 100644 modules/ncenterlite/tpl/js/ncenter_admin.js create mode 100644 modules/ncenterlite/tpl/js/ncenterlite.js create mode 100644 modules/ncenterlite/tpl/ncenter_list.html diff --git a/modules/ncenterlite/LICENSE b/modules/ncenterlite/LICENSE new file mode 100644 index 000000000..2fb57a6e4 --- /dev/null +++ b/modules/ncenterlite/LICENSE @@ -0,0 +1,84 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not 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 or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program. + +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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. +b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. +c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + +a) 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; or, +b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, +c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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. + +5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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 to this License. + +7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program. + +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. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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. + +9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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 + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. \ No newline at end of file diff --git a/modules/ncenterlite/LICENSE-ko b/modules/ncenterlite/LICENSE-ko new file mode 100644 index 000000000..f51a8569f --- /dev/null +++ b/modules/ncenterlite/LICENSE-ko @@ -0,0 +1,97 @@ +한국어 번역에 대한 안내 + +이 문서는 GNU General Public License를 한국어로 번역된 것이며 해석의 오류 또는 해석이 달라질 수 있으므로 해석에 도움을 받는 것 외 법적 효력이 없으며, 원문의 규정을 따르도록 합니다. +원문은 http://www.gnu.org/licenses/gpl-2.0.html 에서 볼 수 있습니다. + +-------------------------------------------------------------------------------- + +GNU 일반 공중 사용 허가서 + +2판, 1991년 6월 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +누구든지 본 사용 허가서를 있는 그대로 복제하고 배포할 수 +있습니다. 그러나 본문에 대한 수정은 허용되지 않습니다. + +전 문 + +소프트웨어에 적용되는 대부분의 사용 허가서(license)들은 소프트웨어에 대한 수정과 공유의 자유를 제한하려는 것을 그 목적으로 합니다. 그러나 GNU 일반 공중 사용 허가서(이하, ``GPL''이라고 칭합니다.)는 자유 소프트웨어에 대한 수정과 공유의 자유를 모든 사용자들에게 보장하기 위해서 성립된 것입니다. 자유 소프트웨어 재단이 제공하는 대부분의 소프트웨어들은 GPL에 의해서 관리되고 있으며, 몇몇 소프트웨어에는 별도의 사용 허가서인 GNU 라이브러리 일반 공중 사용 허가서(GNU Library General Public License)를 대신 적용하기도 합니다. 자유 소프트웨어란, 이를 사용하려고 하는 모든 사람에 대해서 동일한 자유와 권리가 함께 양도되는 소프트웨어를 말하며 프로그램 저작자의 의지에 따라 어떠한 종류의 프로그램에도 GPL을 적용할 수 있습니다. 따라서 여러분이 만든 프로그램에도 GPL을 적용할 수 있습니다. + +자유 소프트웨어를 언급할 때 사용되는 ``자유''라는 단어는 무료(無料)를 의미하는 금전적인 측면의 자유가 아니라 구속되지 않는다는 관점에서의 자유를 의미하며, GPL은 자유 소프트웨어를 이용한 복제와 개작, 배포와 수익 사업 등의 가능한 모든 형태의 자유를 실질적으로 보장하고 있습니다. 여기에는 원시 코드(source code)의 전부 또는 일부를 원용해서 개선된 프로그램을 만들거나 새로운 프로그램을 창작할 수 있는 자유가 포함되며, 자신에게 양도된 이러한 자유와 권리를 보다 명확하게 인식할 수 있도록 하기 위한 규정도 포함되어 있습니다. + +GPL은 GPL 안에 소프트웨어를 양도받을 사용자의 권리를 제한하는 조항과 단서를 별항으로 추가시키지 못하게 함으로써 사용자들의 자유와 권리를 실제적으로 보장하고 있습니다. 자유 소프트웨어의 개작과 배포에 관계하고 있는 사람들은 이러한 무조건적인 권리 양도 규정을 준수해야만 합니다. + +예를 들어 GPL 프로그램을 배포할 경우에는 프로그램의 유료 판매나 무료 배포에 관계없이 자신이 해당 프로그램에 대해서 가질 수 있었던 모든 권리를, 프로그램을 받게될 사람에게 그대로 양도해 주어야 합니다. 이 경우, 프로그램의 원시 코드를 함께 제공하거나 원시 코드를 구할 수 있는 방법을 확실히 알려주어야 하고 이러한 모든 사항들을 사용자들이 분명히 알 수 있도록 명시해야 합니다. + +자유 소프트웨어 재단은 다음과 같은 두 가지 단계를 통해서 사용자들을 권리를 보호합니다. (1) 소프트웨어에 저작권을 설정합니다. (2) 저작권의 양도에 관한 실정법에 의해서 유효한 법률적 효력을 갖는 GPL을 통해 소프트웨어를 복제하거나 개작 및 배포할 수 있는 권리를 사용자들에게 부여합니다. + +자유 소프트웨어를 사용하는 사람들은 반복적인 재배포 과정을 통해 소프트웨어 자체에 수정과 변형이 일어날 수도 있으며, 이는 최초의 저작자가 만든 소프트웨어가 갖고 있는 문제가 아닐 수 있다는 개연성을 인식하고 있어야 합니다. 우리는 개작과 재배포 과정에서 다른 사람에 의해 발생된 문제로 인해 프로그램 원저작자들의 신망이 훼손되는 것을 원하지 않습니다. GPL에 자유 소프트웨어에 대한 어떠한 형태의 보증도 규정하지 않는 이유는 이러한 점들이 고려되었기 때문이며, 이는 프로그램 원저작자와 자유 소프트웨어 재단의 자유로운 활동을 보장하는 현실적인 수단이기도 합니다. + +특허 제도는 자유 소프트웨어의 발전을 위협하는 요소일 수밖에 없습니다. 자유 프로그램을 재배포하는 사람들이 개별적으로 특허를 취득하게 되면, 결과적으로 그 프로그램이 독점 소프트웨어가 될 가능성이 있습니다. 자유 소프트웨어 재단은 이러한 문제에 대처하기 위해서 어떠한 특허에 대해서도 그 사용 권리를 모든 사람들(이하, ``공중(公衆)''이라고 칭합니다.)에게 자유롭게 허용하는 경우에 한해서만 자유 소프트웨어와 함께 사용할 수 있다는 것을 명확히 밝히고 있습니다. + +복제(copying)와 개작(modification) 및 배포(distribution)에 관련된 구체적인 조건과 규정은 다음과 같습니다. + +복제와 개작 및 배포에 관한 조건과 규정 + +제 0 조. 본 허가서는 GNU 일반 공중 사용 허가서의 규정에 따라 배포될 수 있다는 사항이 저작권자에 의해서 명시된 모든 컴퓨터 프로그램 저작물에 대해서 동일하게 적용됩니다. 컴퓨터 프로그램 저작물(이하, ``프로그램''이라고 칭합니다.)이란 특정한 결과를 얻기 위해서 컴퓨터 등의 정보 처리 능력을 가진 장치(이하, ``컴퓨터''라고 칭합니다.) 내에서 직접 또는 간접으로 사용되는 일련의 지시 및 명령으로 표현된 창작물을 의미하고, ``2차적 프로그램''이란 전술한 프로그램 자신 또는 저작권법의 규정에 따라 프로그램의 전부 또는 상당 부분을 원용하거나 다른 언어로의 번역을 포함할 수 있는 개작 과정을 통해서 창작된 새로운 프로그램과 이와 관련된 저작물을 의미합니다. (이후로 다른 언어로의 번역은 별다른 제한없이 개작의 범위에 포함되는 것으로 간주합니다.) ``피양도자''란 GPL의 규정에 따라 프로그램을 양도받은 사람을 의미하고, ``원(原)프로그램''이란 프로그램을 개작하거나 2차적 프로그램을 만들기 위해서 사용된 최초의 프로그램을 의미합니다. + +본 허가서는 프로그램에 대한 복제와 개작 그리고 배포 행위에 대해서만 적용됩니다. 따라서 프로그램을 실행시키는 행위에 대한 제한은 없습니다. 프로그램의 결과물(output)에는, 그것이 프로그램을 실행시켜서 생성된 것인지 아닌지의 여부에 상관없이 결과물의 내용이 원프로그램으로부터 파생된 2차적 프로그램을 구성했을 때에 한해서 본 허가서의 규정들이 적용됩니다. 2차적 프로그램의 구성 여부는 2차적 프로그램 안에서의 원프로그램의 역할을 토대로 판단합니다. + +제 1 조. 적절한 저작권 표시와 프로그램에 대한 보증이 제공되지 않는다는 사실을 각각의 복제물에 명시하는 한, 피양도자는 프로그램의 원시 코드를 자신이 양도받은 상태 그대로 어떠한 매체를 통해서도 복제하고 배포할 수 있습니다. 복제와 배포가 이루어 질 때는 본 허가서와 프로그램에 대한 보증이 제공되지 않는다는 사실에 대해서 언급되었던 모든 내용을 그대로 유지시켜야 하며, 영문판 GPL을 함께 제공해야 합니다. + +배포자는 복제물을 물리적으로 인도하는데 소요된 비용을 청구할 수 있으며, 선택 사항으로 독자적인 유료 보증을 설정할 수 있습니다. + +제 2 조. 피양도자는 자신이 양도받은 프로그램의 전부나 일부를 개작할 수 있으며, 이를 통해서 2차적 프로그램을 창작할 수 있습니다. 개작된 프로그램이나 창작된 2차적 프로그램은 다음의 사항들을 모두 만족시키는 조건에 한해서, 제1조의 규정에 따라 또다시 복제되고 배포될 수 있습니다. + +제 1 항. 파일을 개작할 때는 파일을 개작한 사실과 그 날짜를 파일 안에 명시해야 합니다. +제 2 항. 배포하거나 공표하려는 저작물의 전부 또는 일부가 양도받은 프로그램으로부터 파생된 것이라면, 저작물 전체에 대한 사용 권리를 본 허가서의 규정에 따라 공중에게 무상으로 허용해야 합니다. + +제 3 항. 개작된 프로그램의 일반적인 실행 형태가 대화형 구조로 명령어를 읽어 들이는 방식을 취하고 있을 경우에는, 적절한 저작권 표시와 프로그램에 대한 보증이 제공되지 않는다는 사실, (별도의 보증을 설정한 경우라면 해당 내용) 그리고 양도받은 프로그램을 본 규정에 따라 재배포할 수 있다는 사실과 GPL 사본을 참고할 수 있는 방법이 함께 포함된 문구가 프로그램이 대화형 구조로 평이하게 실행된 직후에 화면 또는 지면으로 출력되도록 작성되어야 합니다. (예외 규정: 양도받은 프로그램이 대화형 구조를 갖추고 있다 하더라도 통상적인 실행 환경에서 전술한 사항들이 출력되지 않는 형태였을 경우에는 이를 개작한 프로그램 또한 관련 사항들을 출력시키지 않아도 무방합니다.) + +위의 조항들은 개작된 프로그램 전체에 적용됩니다. 만약, 개작된 프로그램에 포함된 특정 부분이 원프로그램으로부터 파생된 것이 아닌 별도의 독립 저작물로 인정될 만한 상당한 이유가 있을 경우에는 해당 저작물의 개별적인 배포에는 본 허가서의 규정들이 적용되지 않습니다. 그러나 이러한 저작물이 2차적 프로그램의 일부로서 함께 배포된다면 개별적인 저작권과 배포 기준에 상관없이 저작물 모두에 본 허가서가 적용되어야 하며, 전체 저작물에 대한 사용 권리는 공중에게 무상으로 양도됩니다. + +이러한 규정은 개별적인 저작물에 대한 저작자의 권리를 침해하거나 인정하지 않으려는 것이 아니라, 원프로그램으로부터 파생된 2차적 프로그램이나 수집 저작물의 배포를 일관적으로 규제할 수 있는 권리를 행사하기 위한 것입니다. + +원프로그램이나 원프로그램으로부터 파생된 2차적 프로그램을 이들로부터 파생되지 않은 다른 저작물과 함께 단순히 저장하거나 배포할 목적으로 동일한 매체에 모아 놓은 집합물의 경우에는, 원프로그램으로부터 파생되지 않은 다른 저작물에는 본 허가서의 규정들이 적용되지 않습니다. + +제 3 조. 피양도자는 다음 중 하나의 항목을 만족시키는 조건에 한해서 제1조와 제2조의 규정에 따라 프로그램(또는 제2조에서 언급된 2차적 프로그램)을 목적 코드(object code)나 실행물(executable form)의 형태로 복제하고 배포할 수 있습니다. + +제 1 항. 목적 코드나 실행물에 상응하는 컴퓨터가 인식할 수 있는 완전한 원시 코드를 함께 제공해야 합니다. 원시 코드는 제1조와 제2조의 규정에 따라 배포될 수 있어야 하며, 소프트웨어의 교환을 위해서 일반적으로 사용되는 매체를 통해 제공되어야 합니다. +제 2 항. 배포에 필요한 최소한의 비용만을 받고 목적 코드나 실행물에 상응하는 완전한 원시 코드를 배포하겠다는, 최소한 3년간 유효한 약정서를 함께 제공해야 합니다. 이 약정서는 약정서를 갖고 있는 어떠한 사람에 대해서도 유효해야 합니다. 원시 코드는 컴퓨터가 인식할 수 있는 형태여야 하고 제1조와 제2조의 규정에 따라 배포될 수 있어야 하며, 소프트웨어의 교환을 위해서 일반적으로 사용되는 매체를 통해 제공되어야 합니다. + +제 3 항. 목적 코드나 실행물에 상응하는 원시 코드를 배포하겠다는 약정에 대해서 자신이 양도받은 정보를 함께 제공해야 합니다. (제3항은 위의 제2항에 따라 원시 코드를 배포하겠다는 약정을 프로그램의 목적 코드나 실행물과 함께 제공 받았고, 동시에 비상업적인 배포를 하고자 할 경우에 한해서만 허용됩니다.) + +저작물에 대한 원시 코드란 해당 저작물을 개작하기에 적절한 형식을 의미합니다. 실행물에 대한 완전한 원시 코드란 실행물에 포함된 모든 모듈들의 원시 코드와 이와 관련된 인터페이스 정의 파일 모두, 그리고 실행물의 컴파일과 설치를 제어하는데 사용된 스크립트 전부를 의미합니다. 그러나 특별한 예외의 하나로서, 실행물이 실행될 운영체제의 주요 부분(컴파일러나 커널 등)과 함께 (원시 코드나 바이너리의 형태로) 일반적으로 배포되는 구성 요소들은 이러한 구성 요소 자체가 실행물에 수반되지 않는 한 원시 코드의 배포 대상에서 제외되어도 무방합니다. + +목적 코드나 실행물을 지정한 장소로부터 복제해 갈 수 있게 하는 방식으로 배포할 경우, 동일한 장소로부터 원시 코드를 복제할 수 있는 동등한 접근 방법을 제공한다면 이는 원시 코드를 목적 코드와 함께 복제되도록 설정하지 않았다고 하더라도 원시 코드를 배포하는 것으로 간주됩니다. + +제 4 조. 본 허가서에 의해 명시적으로 이루어 지지 않는 한 프로그램에 대한 복제와 개작 및 하위 허가권 설정과 배포가 성립될 수 없습니다. 이와 관련된 어떠한 행위도 무효이며 본 허가서가 보장한 권리는 자동으로 소멸됩니다. 그러나 본 허가서의 규정에 따라 프로그램의 복제물이나 권리를 양도받았던 제3자는 본 허가서의 규정들을 준수하는 한, 배포자의 권리 소멸에 관계없이 사용상의 권리를 계속해서 유지할 수 있습니다. + +제 5 조. 본 허가서는 서명이나 날인이 수반되는 형식을 갖고 있지 않기 때문에 피양도자가 본 허가서의 내용을 반드시 받아들여야 할 필요는 없습니다. 그러나 프로그램이나 프로그램에 기반한 2차적 프로그램에 대한 개작 및 배포를 허용하는 것은 본 허가서에 의해서만 가능합니다. 만약 본 허가서에 동의하지 않을 경우에는 이러한 행위들이 법률적으로 금지됩니다. 따라서 프로그램(또는 프로그램에 기반한 2차적 프로그램)을 개작하거나 배포하는 행위는 이에 따른 본 허가서의 내용에 동의한다는 것을 의미하며, 복제와 개작 및 배포에 관한 본 허가서의 조건과 규정들을 모두 받아들이겠다는 의미로 간주됩니다. + +제 6 조. 피양도자에 의해서 프로그램(또는 프로그램에 기반한 2차적 프로그램)이 반복적으로 재배포될 경우, 각 단계에서의 피양도자는 본 허가서의 규정에 따른 프로그램의 복제와 개작 및 배포에 대한 권리를 최초의 양도자로부터 양도받은 것으로 자동적으로 간주됩니다. 프로그램(또는 프로그램에 기반한 2차적 프로그램)을 배포할 때는 피양도자의 권리의 행사를 제한할 수 있는 어떠한 사항도 추가할 수 없습니다. 그러나 피양도자에게, 재배포가 일어날 시점에서의 제3의 피양도자에게 본 허가서를 준수하도록 강제할 책임은 부과되지 않습니다. + +제 7 조. 법원의 판결이나 특허권 침해에 대한 주장 또는 특허 문제에 국한되지 않은 그밖의 이유들로 인해서 본 허가서의 규정에 배치되는 사항이 발생한다 하더라도 그러한 사항이 선행하거나 본 허가서의 조건과 규정들이 면제되는 것은 아닙니다. 따라서 법원의 명령이나 합의 등에 의해서 본 허가서에 위배되는 사항들이 발생한 상황이라도 양측 모두를 만족시킬 수 없다면 프로그램은 배포될 수 없습니다. 예를 들면, 특정한 특허 관련 허가가 프로그램의 복제물을 직접 또는 간접적인 방법으로 양도받은 임의의 제3자에게 해당 프로그램을 무상으로 재배포할 수 있게 허용하지 않는다면, 그러한 허가와 본 사용 허가를 동시에 만족시키면서 프로그램을 배포할 수 있는 방법은 없습니다. + +본 조항은 특정한 상황에서 본 조항의 일부가 유효하지 않거나 적용될 수 없을 경우에도 본 조항의 나머지 부분들을 적용하기 위한 의도로 만들어 졌습니다. 따라서 그 이외의 상황에서는 본 조항을 전체적으로 적용하면 됩니다. + +본 조항의 목적은 특허나 저작권 침해 등의 행위를 조장하거나 해당 권리를 인정하지 않으려는 것이 아니라, GPL을 통해서 구현되어 있는 자유 소프트웨어의 배포 체계를 통합적으로 보호하기 위한 것입니다. 많은 사람들이 배포 체계에 대한 신뢰있는 지원을 계속해 줌으로써 소프트웨어의 다양한 분야에 많은 공헌을 해 주었습니다. 소프트웨어를 어떠한 배포 체계로 배포할 것인가를 결정하는 것은 전적으로 저작자와 기증자들의 의지에 달려있는 것이지, 일반 사용자들이 강요할 수 있는 문제는 아닙니다. + +본 조항은 본 허가서의 다른 조항들에서 무엇이 중요하게 고려되어야 하는 지를 명확하게 설명하기 위한 목적으로 만들어진 것입니다. + +제 8 조. 특허나 저작권이 설정된 인터페이스로 인해서 특정 국가에서 프로그램의 배포와 사용이 함께 또는 개별적으로 제한되어 있는 경우, 본 사용 허가서를 프로그램에 적용한 최초의 저작권자는 문제가 발생하지 않는 국가에 한해서 프로그램을 배포한다는 배포상의 지역적 제한 조건을 명시적으로 설정할 수 있으며, 이러한 사항은 본 허가서의 일부로 간주됩니다. + +제 9 조. 자유 소프트웨어 재단은 때때로 본 사용 허가서의 개정판이나 신판을 공표할 수 있습니다. 새롭게 공표될 판은 당면한 문제나 현안을 처리하기 위해서 세부적인 내용에 차이가 발생할 수 있지만, 그 근본 정신에는 변함이 없을 것입니다. + +각각의 판들은 판번호를 사용해서 구별됩니다. 특정한 판번호와 그 이후 판을 따른다는 사항이 명시된 프로그램에는 해당 판이나 그 이후에 발행된 어떠한 판을 선택해서 적용해도 무방하고, 판번호를 명시하고 있지 않은 경우에는 자유 소프트웨어 재단이 공표한 어떠한 판번호의 판을 적용해도 무방합니다. + +제 10 조. 프로그램의 일부를 본 허가서와 배포 기준이 다른 자유 프로그램과 함께 결합하고자 할 경우에는 해당 프로그램의 저작자로부터 서면 승인을 받아야 합니다. 자유 소프트웨어 재단이 저작권을 갖고 있는 소프트웨어의 경우에는 자유 소프트웨어 재단의 승인을 얻어야 합니다. 우리는 이러한 요청을 수락하기 위해서 때때로 예외 기준을 만들기도 합니다. 자유 소프트웨어 재단은 일반적으로 자유 소프트웨어의 2차적 저작물들을 모두 자유로운 상태로 유지시키려는 목적과 소프트웨어의 공유와 재활용을 증진시키려는 두가지 목적을 기준으로 승인 여부를 결정할 것입니다. + + +보증의 결여 (제11조, 제12조) + +제 11 조. 본 허가서를 따르는 프로그램은 무상으로 양도되기 때문에 관련 법률이 허용하는 한도 내에서 어떠한 형태의 보증도 제공되지 않습니다. 프로그램의 저작권자와 배포자가 공동 또는 개별적으로 별도의 보증을 서면으로 제공할 때를 제외하면, 특정한 목적에 대한 프로그램의 적합성이나 상업성 여부에 대한 보증을 포함한 어떠한 형태의 보증도 명시적이나 묵시적으로 설정되지 않은 ``있는 그대로의'' 상태로 이 프로그램을 배포합니다. 프로그램과 프로그램의 실행에 따라 발생할 수 있는 모든 위험은 피양도자에게 인수되며 이에 따른 보수 및 복구를 위한 제반 경비 또한 피양도자가 모두 부담해야 합니다. + +제 12 조. 저작권자나 배포자가 프로그램의 손상 가능성을 사전에 알고 있었다 하더라도 발생된 손실이 관련 법규에 의해 보호되고 있거나 이에 대한 별도의 서면 보증이 설정된 경우가 아니라면, 저작권자나 프로그램을 원래의 상태 또는 개작한 상태로 제공한 배포자는 프로그램의 사용이나 비작동으로 인해 발생된 손실이나 프로그램 자체의 손실에 대해 책임지지 않습니다. 이러한 면책 조건은 사용자나 제3자가 프로그램을 조작함으로써 발생된 손실이나 다른 소프트웨어와 프로그램을 함께 동작시키는 것으로 인해서 발생된 데이터의 상실 및 부정확한 산출 결과에만 국한되는 것이 아닙니다. 발생된 손실의 일반성이나 특수성 뿐 아니라 원인의 우발성 및 필연성도 전혀 고려되지 않습니다. diff --git a/modules/ncenterlite/conf/info.xml b/modules/ncenterlite/conf/info.xml new file mode 100644 index 000000000..6d943f59c --- /dev/null +++ b/modules/ncenterlite/conf/info.xml @@ -0,0 +1,14 @@ + + + XE 알림센터 Lite + XE Notification Center Lite + 사이트 사용자간의 커뮤니케이션에 대한 정보를 알려주는 모듈입니다. + This module notify users of information about new documents, comments and/or messages that call them. This module will enhance communication beween site users. + 2.1.5 + 2014-12-09 + content + + XE Public + XE Public + + diff --git a/modules/ncenterlite/conf/module.xml b/modules/ncenterlite/conf/module.xml new file mode 100644 index 000000000..489517102 --- /dev/null +++ b/modules/ncenterlite/conf/module.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + XE 알림센터 Lite + XE Notification Center Lite + XE 通知センター Lite + + + diff --git a/modules/ncenterlite/lang/lang.xml b/modules/ncenterlite/lang/lang.xml new file mode 100644 index 000000000..d6a8762c3 --- /dev/null +++ b/modules/ncenterlite/lang/lang.xml @@ -0,0 +1,458 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %1$s님이 "%2$s"라고 글을 남겼습니다.]]> + %1$s wrote an article as "%2$s".]]> + %1$s wrote an article as "%2$s".]]> + + + %1$s님이 게시판 "%2$s""%3$s"라고 글을 남겼습니다.]]> + %1$s wrote an article as "%3$s" on the board %2$s.]]> + %1$s wrote an article as "%3$s" on the board %2$s.]]> + + + %1$s님이 회원님의 %2$s에 "%3$s"라고 댓글을 남겼습니다.]]> + %1$s commented as "%3$s" on your %2$s.]]> + %sさんがあなたの%sに「%s」とコメントしました。]]> + + + %1$s님이 게시판 "%2$s""%3$s"라고 댓글을 남겼습니다.]]> + %1$s commented as "%3$s" on the board %2$s.]]> + %1$s commented as "%3$s" on the board %2$s.]]> + + + %s님이 "%s" %s에서 회원님을 언급하였습니다.]]> + %s mentioned you on "%s" %s.]]> + %sさんが「%s」%sにあなたをタグ付けしました。]]> + + + %d개의 읽지 않은 메시지가 있습니다.]]> + %d new message(s).]]> + %d件の読んでないメッセージがあります。]]> + + + %s님께서 "%s"라고 메세지를 보내셨습니다.]]> + %1$s sent a message as "%2$s".]]> + %1$s sent a message as "%2$s".]]> + + + %s님! 스킨 테스트 알림을 완료했습니다.]]> + %s! Skin test notification has been done.]]> + %s! Skin test notification has been done.]]> + + + %s님이 "%s" 글을 추천하였습니다.]]> + %1$s marked the article "%2$s" with a recommendation.]]> + %1$s marked the article "%2$s" with a recommendation.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %s개의 알림이 있습니다.]]> + %s notification.]]> + %s件のお知らせがあります。]]> + + + %s개의 알림이 있습니다.]]> + %s notifications.]]> + %s件のお知らせがあります。]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 도와주세요! 사용 환경 정보 제공 동의]]> + HELP! Agreement on gathering server environment information]]> + HELP! Agreement on gathering server environment information]]> + + + '알림센터 Lite'를 자유소프트웨어로 제공하고 있습니다.

    +

    '알림센터 Lite'는 사용자의 버그 보고, 의견 제출을 통해 공동의 힘으로 발전하고 있습니다.
    '제공 동의'를 선택하면 아래와 같은 항목이 전송되며, 알림센터 Lite의 기능을 개선하는데 참고하겠습니다. 감사합니다.

    +
      +
    • 이 사이트의 도메인
    • +
    • 알림센터 Lite의 버전
    • +
    • XE 버전
    • +
    • PHP 버전
    • +
    + ]]>
    + 'Notification Center Lite' is distributed as an free software.

    +

    'Notification Center Lite' is developing with collective intelligence, such as users' bug reports, suggestions and/or contributions.
    If you select to 'Agree on gathering', the items below will be gathered by developers of this program, and the information will be referenced to enhance functions of this program. Thank you.

    +
      +
    • Domain name of this website
    • +
    • Version value of Notification Center Lite
    • +
    • XE Core version value
    • +
    • PHP version value
    • +
    + ]]>
    + 'Notification Center Lite' is distributed as an free software.

    +

    'Notification Center Lite' is developing with collective intelligence, such as users' bug reports, suggestions and/or contributions.
    If you select to 'Agree on gathering', the items below will be gathered by developers of this program, and the information will be referenced to enhance functions of this program. Thank you.

    +
      +
    • Domain name of this website
    • +
    • Version value of Notification Center Lite
    • +
    • XE Core version value
    • +
    • PHP version value
    • +
    + ]]>
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 주의! 알림센터를 레이아웃이나 위젯으로 표현할 수 있을 때에만 동작안함 선택하세요.]]> + Watch out! 알림센터를 레이아웃이나 위젯으로 표현할 수 있을 때에만 동작안함 선택하세요.]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    \ No newline at end of file diff --git a/modules/ncenterlite/m.skins/default/NotifyList.html b/modules/ncenterlite/m.skins/default/NotifyList.html new file mode 100644 index 000000000..6c111c5a6 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/NotifyList.html @@ -0,0 +1,24 @@ + +
    +

    {$lang->ncenterlite_my_list}

    +
      +
    • + {@ + $oMemberModel = getModel('member'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($val->member_srl); + } +
      + + {$val->target_nick_name} -> + {$member_info->nick_name} + +
      + {$val->text} + ({zdate($val->regdate,"Y-m-d H:i:s")}) + ({$lang->ncenterlite_read_y}) + ({$lang->ncenterlite_read_n}) +
      +
      +
    • +
    +
    \ No newline at end of file diff --git a/modules/ncenterlite/m.skins/default/img/p.png b/modules/ncenterlite/m.skins/default/img/p.png new file mode 100644 index 0000000000000000000000000000000000000000..44e3d8d1203e991132d400e26b13aa3e469862d9 GIT binary patch literal 7463 zcmV+?9oXWDP)5000;CX+uL$Nkc;* zP;zf(X>4Tx09b{USqC_l(c3@I^SsM=?Y(91y_3E79;v+crq@;^B&(2-LJEl#O;kc8 zC0U75q!3D_fvkKFjsO4qkL$a>b6w{=zxRIbbD#U%_kG6wyZ~_AAcchm!E^uwheVKV zjdb~(U0nI_uK*0_0VCi5j3m$SFdb`abMRlw(lCIwo=>H=Wc_!(|5)g~yu&>KfUHsM z;T7%~jN%&rAWfcOBf_?D4vLw`sDdc2+`_)UaMKp{_=S76dF*ZVP&@$u zfto}j`vO3mN9lY~p1!CY8fpM=3?W|rAt);!ig$VXk-Pxla7TG0gM&l2a2AS1J^o3K z@BfnN@mD5^bLzv)$B5xTa&>COHTCiYu4Lh+Daq_M+qJR2G4po3yA6t4${nr-o;c7oYL zJS?qH%z$D+&u~50Uov6kI6r%*-#q4C-ueb8MxzLJCWqSo;r9!Vvin1ii}Ta7{KFqW zGTrhw4T>{J1HVK}K8S?m+RSun24W-(&TL1X=!`3q0jRHnjbXSG~ix=es>t zgrB|fFZl>v1R4OpWFlNX{)Q&MbU`?8%X~TXqmcv5$9%!*7{L zh8IcS?3YcD5?}~OfDF8W2M7ThfDf1hJ)r-)J_{FBK4(#PX(kAK(65KL`L{mmg;D?2B<{-^&xW{fky z>En!XhBz@K4Y`hVA@`6+NHfw1_>fkl3F$%ZZsC6!h4kAhO$n9St|52mJ zzZ}1*G~zT$z;>HI5Pj$WcLc|6t^NN^N+eo6P)PykJF~xY{9|ch)VfL-U5qAbXVk_R z77PcF!YHB^*THC^K2SobdjHz%cPj;awrv@;J(oc64#mL{-Z2qdfvy)C7EAW`^^4%s zL3c}UNj{ShPiaX$d09Dmu(kL8TH4=ixA#M0MDfdf5G$;cVpc-5T*FYm^2KT@N@EG)iXW%860MpB=n*sk zy@1|8bI@046-Hocmx+%XreX`RRoI)@PINs_ zW0!C^91Bhar-DYi3oZb60GEX;#nt25a09qW+#(*2XU9w6HStz>5H;7SM~BoPV;7YQwdLBb4Sje?Fsh(evhio%N`mLi*?lHxW+AH_7q z8YMlY2&E>aJ!JspVag)PI?7JUSCrqVsHk>OsZrTb`BNoQ6;WNGdPwz#YK5ACTAW&s z+KoDr`Z)Ck>Ne^Z)Zd6iqA*dL=t_(r9w*iiJBZ`NA2f_K(ljPCUNnbjifI~X25COg zQqT&~>d@|`jiW83y-wRlJ5NVJCrqbDN1{uhE2g_eH$t~a&qyyvZ$%$WpGAL>{t^8w z1D-*c!GOVwA%&rWp@U(P5n&Wy)MNByOlGWP>|~r~!ZC?3nJ@(~Winl6>SbDBW?)ui zc4UrWE@r;VJi&sn2(y^51hHhZTw@t#S!LyB)nWB!O=qoR9b{c*<7Crj^JdFnt7m)0 zw#v@OZonSMp3C0IKE{FJ5a+Prh~_xM(aAB-$;7F_>B*VFd5v?F3+58%vgJC!Rl(K6 zwaCrGZNweMeTut-d!C1dN1G>rC!eQ~PqTw4;8M}-@OXGPdVOhn>DYDHd&5=FH{_luT`4vFE!RK)_tO2zucVR0pKKk;Jm zJ_%StS;AkURAN99E2$X2McQ0CNxD(`lZ>E@t4yv;m&{LD zCD|a^O4*lk405J&NpiR4zRHWsd&(Ef4=E583>6M3G%0*hlu-0mJfrwriBZWy>8Mh> z(uT5%GFiD!c}_)8#a*RDWki)p)mk-6^`RP8O;_!ZTC>`Uy0UtN`Ze{>8d4g88W%NY zcZ%%v-dVYGQgeqUN%NfM#4f&F?z_(Jn$Y6cB59Rtz10@b_R_A>p3xE03DCKu^GR1$ zm#lkJcUezeFJ7-rAJI3`&(QBRU@&knIBhU)xWmxbu-0(FNXh7cQJXQ=*vvTBc*KO; z#M7k4WWiL$G~V>S8MT?6*=e)4=HljL^V=4%g{eiJ#Vbo8%Mi;(D_~_}m1i|(En>aj z`i>3G#@eRX=AEsa?LpfvJ4U;Gb{FlI>~-z4?O!^GIz&3OJJLG3Io3EXJLx-}aGG$I zagKL>?84#V@6zOocXf2Fa$VeQu)ARQw40J!s@w1$kv%bc9_{7W8?^WCKH7bxeb?Qw z?oRF(-PcK0q;k@thlxjt$AYJx=Sj~GUfN#yUUS}>-Y2|gd^CMd_{{oh`sVr0`DytT z`px_6`JeXx5?~xq7O)&>6?h?VGsr2ZK9~^f9(*f=AtW&5ekf09Oz1$EL|AIr#D4Yt z1^XAsX5^}HD11+NQv?%w$?b_0jXV9I3$hH>W) zU=Da5Xg|n*@bJMm@jCJ65}*W+g!V%Mhf)qrCmJPIAErDUc=$<@Y|@FO@5xTdw^O)N z5>qCR7#*oirAZ~HjvUoET9$@M^H1wdS4cmV{xicXqdQYJvoLc#%QLI{nB1|VW1Gi) zj`wCOXP?Qz<%Hx6=W69vpP)YxcVaTnBCjEzFFzyyd%?bfM}>-oWhW_5MxLA~GB0X6 zC3q_5)cR?^)6a@^i|b3cO43V~OT9`5&uE{iE8{N9EL%P6fA;w~qjL@A!sUe(xQeKX zca@HnUFTKL*Hm#-Wmaum2)Qs(ZCic6My00aBG<+2TDUf{cJ7kfrT)wMmz(OO>dw`( z)Ms7+S0b;xzv_N<_?p?Z_Uo$G>uw0$D7ndaGot}&h;3MC^lO}Ga%md4WqPaqw#Mz7 zcckxJXy$J&zRP?!yM?kPrDd}Q?P;e60Mqp+~9b<`bnSH+z+P8~RlGn)=oHZx8GoXc^QRy!TZ9 z>4PDYp~ufGpA8H<3_l-n8<}|S^?de4(2FmlQKM@w6JKFpWsK2{6^?U_m%kQ!T|c2b zarce>o1V9JZ(mM&PJWmQpIVL&bXYJ2D3(gDEU&voJzh-@7|90WK;`jDN>&5Y<;H9lW5XV#+E z@#{q!VjH)An*DsW8N9g}Mk158uL1~KVILm=zFt7{78d{*`_VfE&9B_(cR|q02aG-) zA!+CXd>={1*kQGCB6to08wD?=CY2?1ATfvL7VSK}6oWTo1=A#pIBP6hD+ev76IUho zH{P9mDf~|a=ml+sjtM^&1!4-~J`yJ-yQP+8L}hK{66I?Zo+-h~aw>aNGt?T?-|Qr6 zs_t^vO4q)s^Gc7PuWaCHm}AsrJZ=h^37Q*O1XyNU-LQUc^TUqCUctf2G1%#tbDhg$ z*EhQt+?MyO?E~(VBz6xePaQ8??|nYrz9c_8|D6GRfl%N?P;2nnkmOLmFzfxQWWI1h z_~(e>$d;(;=)9PO*q}I<111MG<5d!r52+>U95zdGO7>2PIC3O4|7c~}_4Kxkp3LE_ z*T-g#f6V@xvzWVdVli(qf3*;ElDSCol+kI=;zK1xrFCao%O0N{IyYKAQ88Efy$ZR& zTrFOsd(o{n`cnSoYjp$lU#`+$Q@Cz-Bm8DgLrvrDrhB(KZnxdJ(|q%8eM?PiMO*2; zg7%D#gZBeE?H(w1v30FHoOsmN{orv&&%Gzjz4d)X{ow<8gT%q7Pm70qo+%Auhet-L zpGUpW9>tAzq4A~kYGy2VTw{Fl^|1+!i4Ske-r7zgll4;$Q!CT??Q4=wD@mPsG$*WR5(zCJ{Iez(_3a*L~N}0-)Dz{Xh zsJ&JHz7wa(xl2yVLOVz&Tlb1yzy3!pBh5t~%oG`kG@ zEQbuo6sK5cKNovf{oPt_hI?H1M(-e?Fi;@ODs5 zaB)a>Xi^w?zZ+RQoHu+e;#uV7sMKhW7=u{ZIKczl2ifD96X*`%4lO0VJ=~piHMt-q z`pBMC)1&%n=INx2!2t5kUsMcKK0M!2)qJ75`r}3Z+C7&_F2AT}x?*`X4c)y~Zb~#*MAXf`_9Zv;sF<&8n{*G*cRKX}AlCXgYpU4l<9_ckrId3JvG8V*ExE!KIzx|y>4g2*UrTmD&+M8AtBCKBMNvDW#-kHsxMS|dy2r7^jUK2ym>ln%Aeyjr zs3S4&uy2xnvUm#H5vo*>`u*r++LQG9jI2yjmf|t|vC-pKvNLi5bB#_goOqD8J8wQe zu0W?y_hi~B!s(3SsZ#bc@?~mg)y^rE%T$O~@}Fm~qQ5{{O;JOOMv~?w_sd7?F4sT3 zvVKkUy6cS-HwPM-np|#`+#YGh-W6*xYV~M4bni@iOULW`n-BQA^d9;?%Id!Qc(`Yy zSFCS$|H*;zr}9I`o_!jzdwy$_|7F3L%xjuA(NmeTu^%nJF0I&X`Ty59vaNzs1|Sd3 zGaZkibq;{sMl{d70{|-}0MVbpQ%H^7s6J(8QB~=A0~m7l;8xG}AN( zu4uj;1Jcoq@)BqPgJ^cV4lzJtkT#khhC|2De6SOmgdvz8)`h*`qiB{l2(Kanhy@ad zR3jr80!AGZjH$r9z%pRX(2T4D2jR4FiMVz=7H^8r!9OSP6M_i0DDV_c6x9@~lopid zD3_@$sj8_l)E?9wL?L22@e_?bO*5M51rXP3)HJvm9xha-5S~W!xS-5m=srguI2LkIU8lA9wGBkQB3Vy?#RJkTE>dWb7= zI4M8H{K(SL{B+5T&Mfca%-OGVpX7}dY!>mIRx2?-v+rzd`Ps_R3sN;_FUi(TTs?PV zZzI*My5>Et679U5h7ZeosQW|*mWFaiL|+WNI`jJE+rfA4b1NSiK41C@zRNDDEpM)5 ztTwF;t>4+G_!+jTvb}#m+us}*04ERz@<0n%05=c}5$U~Dm&m`*H&)x;ja-odWpv~bC|M|e8C z3;sO*D?x{lM|ek}L6Ju>Pictye4Waf>IRw#lc|S@YQ(cNR5UR(Gqf(Wy>y0jZS=e7 zTN(5ix*6>l$I#4ll{uS5oaHg=el`}i26h|vcO0>tM9xYsZLTTqTpm+i8s0I!>-@)e z_zUO?vI%|=x+|O`;v=dnCM3=vL6F2s5u|Bk7-Z??2y!d(vkD`M-AebA@2PaFzEu0F zL9p=8O%eOmeU*M4M zc-E=a`HQR4?nJjIdwKRnxc7Moc=~u1c;EEt^_}ut3t$OU2(k~33OOCx7WSUZ8g3X7 z6?q|QG=?tLA};&D^LXKe_(PM2eUs@@x>F<4aOp=gF{UxsI%Pma#M`u-YvLpjMbEjVL5S2(ZoIpbT^a?nceTFQFI#`m8q+x~~q)lUz2 zfE3sTY=94l2Zi7Y=mGB`3P=L7fXGl0)CRqWSzvuQ04U7gR4s#o` zj@7|tU`KFbxWl+H{4RVsfj|f)3{j|2lv2W!0hG_E^r`Mpt5M%0S`**VB+>HIw$ZuK zEz##NNHIKN3}GTNRWs`{zha4H4q8s8g5`vQ2Qtr};GNrOja!=*IDRL;8C?~0Os8OrCXF{(UGxU2Rxc%r`(OaoqC9a08 z4z4M!6|H?)H(4)VU)!+Xxcn3O>HPE3Cba3Wd2!4C;XVrT+s6k)tqTBld~@@gFaY=y z0Bq!LZmyMYZf;bd$;K-H+Jb)l@3MW?&;d~LdJ8=)sfqd5|3Cf*hMK?V*1e)V00009 za7bBm000XU000XU0RWnu7ytkS*-1n}R9J<*nA?uyHVlS8%Ca3h$C;h&c7gW&-=(*G zgrYzTbhneu(7cw4eOTl}@i%5kcf~QbbVI%Ry!QUBD3b^u0$_DU4881$9+mjBq&i^v+{s zYpOZ&=eDL>9T;c>vm(Wzkl&vyx_3Qk9l3j|aZ(&KM(Mf9}jgcvFM{ z8-tJz0XitjmM}tyhEtl_@^II(TGY&{5@RlwsdlN%_8Hn?q z`&Gl|A6B%pa_s2f)!n+m82J6q9j9}TEd;#|ORhX~+@?tCc)#SI3eGDJn>jyyT48N5 z0+91gfV)+TEed}7W6R;x1weYO^wyrq!D{{_`|G`D(Nui?xWw85RYg@9lm8MSRb@G^ z`SD?iF(%x!35O@adGdK*C3M8Y<=F8G_}QfkK{BUa3p3VX2- zi3nwpg7_kkYblISSu^?U>ed5bQsiC;p(+>=j4|o|w`Jf@O5;Sa$v&gXlqSv2$W?97 zDTaTiL<+p7>QW(wYJRhEs9auO=gO4i>JmRD>RJSAudjUkaxtkm^l~GmA+Dsox7k z21V!2;eAH@7wD7HM79vYrQ0n+@090r|86kROy7G>=WdK3kGu>eWe}5cIE7e4dekdl zw@13pjfbx{WPd!f+n+JUjLQGG5t8ovC^8ZUo*2>0i{q)|)V&>@FusN^y+3qxolnIq z^}eZIAVbkhoH3(kL`MoEbiLm zx$|^5vp<|EOg6&aVjjtKOU(dBpNc}*?Vs80pI_V_XB_X9zrUU6dPia8^5!v>o{K5W zRQJpeU3z9%@b4gRK71t#yy9pSJDPXpW`8Prkt4-0O1#!EMFcZMXynl~=qsC}c94um z-efgLRcY#ySrumZX#$7qV2m(tOG;~QBRNrWMqu(yF}D&M+Q4oF?$-@%Tk?{`_c4IY zvSHp;aG9s%pH`89$3INV$hY^^!B{IBCzCPC|r7f7xN;>E1U6_I6-^kX0 zOv&e&j8H0psLpu=Vcu4J+_bc_>J37ca l%5XU^6|Cd|?`v-#SNw`M^J`4Z=002ovPDHLkV1i5TjzRzc literal 0 HcmV?d00001 diff --git a/modules/ncenterlite/m.skins/default/ncenter.html b/modules/ncenterlite/m.skins/default/ncenter.html new file mode 100644 index 000000000..f43222c58 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenter.html @@ -0,0 +1,124 @@ + + + +
    + + diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.black.css b/modules/ncenterlite/m.skins/default/ncenterlite.black.css new file mode 100644 index 000000000..6f2596f91 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.black.css @@ -0,0 +1,15 @@ +#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95; } +#nc_container a { color:#B0B0B0; } +#nc_container a:hover { color:#B0B0B0; } +#nc_container strong { color:#F3F3F3; } + +#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#555; } +#nc_container .list li a:hover { background-color:#555; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list .more { background: #555; } +#nc_container a.readall { display:none; color:#555; color:#D83722;} + +#nc_container a.notify { color:white; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.blacknoprofile.css b/modules/ncenterlite/m.skins/default/ncenterlite.blacknoprofile.css new file mode 100644 index 000000000..88c94a4a4 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.blacknoprofile.css @@ -0,0 +1,17 @@ +#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95; } +#nc_container a { color:#B0B0B0; } +#nc_container a:hover { color:#B0B0B0; } +#nc_container strong { color:#F3F3F3; } + +#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#555; } +#nc_container .list li a:hover { background-color:#555; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list .more { background: #555; } +#nc_container a.readall { display:none; color:#555; color:#D83722;} + +#nc_container a.notify { color:white; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.css b/modules/ncenterlite/m.skins/default/ncenterlite.css new file mode 100644 index 000000000..60df8e548 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.css @@ -0,0 +1,185 @@ +#nc_container { + z-index:99; + position:fixed; + top:0; + left:0; + margin:0; + padding:0; + width:100%; + height:30px; + border-bottom:1px solid; + font-size:12px; + line-height:15px; +} + +.ncenterlite_block { + height:28px; +} + +#nc_container a { + padding:0; + font-size:12px; + text-decoration:none; +} + +#nc_container ul.nc_memu { + display:block; + margin:0; + padding:4px; + list-style:none; + line-height:20px; +} + +#nc_container ul:after { + content:""; + display:block; + clear:both; +} + +#nc_container ul.nc_memu li { + display:inline-block; + padding:0 5px; + height:20px; + width:auto; + background:transparent!important; +} + +#nc_container ul.nc_memu li.fLeft { + float:left; +} + +#nc_container ul.nc_memu li.fRight { + float:right; +} + +#nc_container ul.nc_memu li a.notify { + display:block; + float:left; +} + +#nc_container a.close { + display:block; +} + +#nc_container .nc_profile img { + width:20px; + height:20px; + vertical-align:top; +} + +#nc_container a.notify .num { + padding:1px 2px; + border:0; + border-radius:3px; + -webkit-border-radius:3px; + -moz-border-radius:3px; + font-size:12px; + font-weight:700; + font-family:Gulim,"lucida grande",tahoma,verdana,arial,sans-serif; +} + +#nc_container .list { + display:none; + position:absolute; + top:30px; + left:0; + max-width:330px; + width:330px; + box-sizing:border-box; + -moz-box-sizing:border-box; + -webkit-box-sizing:border-box; + -o-box-sizing:border-box; +} + +#nc_container a.readall { + display:none; + float:left; + margin:0 4px; + font-size:11px; + font-weight:700; +} + +#nc_container .listscroll { + overflow-y:auto; + overflow-x:hidden; +} + +#nc_container .list ul { + overflow:hidden; + margin:-1px 0; + padding:0; + list-style:none; +} + +#nc_container .list li { + margin:-1px 0; + border:1px solid #555; + border-width:1px 0; +} + +#nc_container .list li img { + float:left; + margin-right:5px; + width:45px; + height:45px; + border:0; +} + +#nc_container .list li a { + display:block; + overflow:hidden; + padding:10px; + font-size:12px; +} + +#nc_container .list span.ago { + display:block; + font-size:10px; +} + +#nc_container .list .more { + display:block; + padding:10px; + text-align:center; +} + +#nc_container ~ .navbar.navbar-fixed-top { + top:28px; +} + +#nc_container a:hover,#nc_container .list li a:hover,#nc_container .list .more:hover { + text-decoration:none; +} + +@media only screen and max-device-width 480px { + #nc_container { + position:relative; + height:auto; + } + + #nc_container .list { + top:2px; + position:relative; + } + + #nc_container .list ul { + display:block; + position:relative; + } + + #nc_container ul.nc_memu:after { + content:""; + display:block; + visibility:hidden; + height:0; + clear:both; + } + + #nc_container .listscroll { + overflow:visible; + } + + .ncenterlite_block { + display:none; + } +} diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.gray.css b/modules/ncenterlite/m.skins/default/ncenterlite.gray.css new file mode 100644 index 000000000..4d167ea21 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.gray.css @@ -0,0 +1,16 @@ +#nc_container { border-bottom-color:#C0C0C0; background-color:#efefef; color:#666; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#666; } +#nc_container a.notify strong { color:#FC2772; } +#nc_container .list { background-color:#efefef; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#ddd; } +#nc_container .list li a:hover { background-color: #ddd; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify sup.num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #ddd; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.graynoprofile.css b/modules/ncenterlite/m.skins/default/ncenterlite.graynoprofile.css new file mode 100644 index 000000000..d8704070b --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.graynoprofile.css @@ -0,0 +1,18 @@ +#nc_container { border-bottom-color:#C0C0C0; background-color:#efefef; color:#666; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#666; } +#nc_container a.notify strong { color:#FC2772; } +#nc_container .list { background-color:#efefef; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#ddd; } +#nc_container .list li a:hover { background-color: #ddd; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify sup.num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #ddd; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.html b/modules/ncenterlite/m.skins/default/ncenterlite.html new file mode 100644 index 000000000..07c776b5d --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.html @@ -0,0 +1,122 @@ + +
    + + diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.mobile.css b/modules/ncenterlite/m.skins/default/ncenterlite.mobile.css new file mode 100644 index 000000000..ef3125177 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.mobile.css @@ -0,0 +1,12 @@ +#nc_container { height:auto; position:relative; } +#nc_container .list { top:2px; position:relative; } +#nc_container .list ul { display:block; position:relative; } +#nc_container ul.nc_memu:after { + content: ""; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +#nc_container .listscroll { overflow: visible; } +.ncenterlite_block { display:none; } diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.white.css b/modules/ncenterlite/m.skins/default/ncenterlite.white.css new file mode 100644 index 000000000..c3fd4444a --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.white.css @@ -0,0 +1,16 @@ +#nc_container { border:1px solid #efefef; background-color:#fff; color:#000; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#000; } +#nc_container a.notify strong { color:#F60; } +#nc_container .list { border:1px solid #efefef; background-color:#fff; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#eee; } +#nc_container .list li a:hover { background-color: #eee; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify .num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #eee; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/m.skins/default/ncenterlite.whitenoprofile.css b/modules/ncenterlite/m.skins/default/ncenterlite.whitenoprofile.css new file mode 100644 index 000000000..69342bd1d --- /dev/null +++ b/modules/ncenterlite/m.skins/default/ncenterlite.whitenoprofile.css @@ -0,0 +1,18 @@ +#nc_container { border:1px solid #efefef; background-color:#fff; color:#000; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#000; } +#nc_container a.notify strong { color:#F60; } +#nc_container .list { border:1px solid #efefef; background-color:#fff; filter:alpha(opacity=97); opacity:0.97; -moz-opacity:0.97; } +#nc_container .list li { border-color:#eee; } +#nc_container .list li a:hover { background-color: #eee; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify .num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #eee; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/m.skins/default/notify.css b/modules/ncenterlite/m.skins/default/notify.css new file mode 100644 index 000000000..0c6e55f3d --- /dev/null +++ b/modules/ncenterlite/m.skins/default/notify.css @@ -0,0 +1,97 @@ +@charset "utf-8"; + +.sosi-title { + position: relative; + font-size: 16px; + font-style: bold; + display: block; + margin: 14px 0 14px 14px; + width: auto; +} + + +.history-list { + margin: 0 0 22px 0px; +} + +.history-list .history-item { + position: relative; + padding: 4px 0 4px 14px; + border-top: 1px solid #ececec; + overflow: hidden; + +} + +.history-list .history-info { +padding: 0 11px 9px 0; +} + +.history-list .history-info .history-gird{ + color: #252525; + font-size: 14px; + line-height: 16px; + font-weight: bold; + margin-top: 9px; + display:block; +} + +.text-ellipsis { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.history-list .history-info .history-gird .history-succeed{ + color:#3c763d +} +.history-list .history-info .history-gird .history-failed{ + color:#a94442 +} +.history-list .history-text{ + color: #252525; + font-size: 11px; + line-height: 16px; +} +.history-list .history-text .history-ip{ + color: #8A8D99; + font-size: 12px; +} + +.history-list .history-text .history-auth{ + color: #8A8D99; + margin-left:3px; +} + + +html{color:#000;background:#fff;} +legend{color:#000;} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,ul,li,ol,dl,dt,dd,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;} +abbr,acronym,address,caption,cite,code,dfn,em,strong,th,var,h1,h2,h3,h4,h5,h6{font-style:normal;font-weight:normal;font-variant:normal;} + + + +body{line-height:1; color: #333; font: normal normal normal 13px/1.5 'Helvetica Neue', Helvetica, Arial, sans-serif;} +ol,ul,li{list-style:none;} + + + + + +html {margin: 0; padding: 0; border: 0; overflow: auto; background-color: #f4f4f4;} +body, .default-font {font: normal normal normal 12px/16px 'Helvetica Neue', Helvetica, Arial, sans-serif;} +body, .default-color {color: #3b3b3b;} +body, .default-background-color {background-color: #fff;} +table {font-size: inherit; font: 100%;} + +h1, h2, h3, h4, h5, h6 {margin: 0; font-weight: bold;} +h1 {font-size: 36px; line-height: 45px;} +h2 {font-size: 24px; line-height: 30px;} +h3 {font-size: 18px; line-height: 22px;} +h4 {font-size: 16px; line-height: 20px;} +h5 {font-size: 14px; line-height: 18px;} +h6 {font-size: 12px; line-height: 16px;} + +.cfix { zoom:1 } +.cfix:after { content: '.'; display:block; clear:both; visibility:hidden; line-height:0; height:0; overflow: hidden; } +strong, .bold {font-weight: bold;} +a { text-decoration:none; color:#1769FF;} diff --git a/modules/ncenterlite/m.skins/default/skin.xml b/modules/ncenterlite/m.skins/default/skin.xml new file mode 100644 index 000000000..bc4725b2d --- /dev/null +++ b/modules/ncenterlite/m.skins/default/skin.xml @@ -0,0 +1,32 @@ + + + XE 알림센터 Lite 기본스킨 + 1.1.1 + 2013-03-21 + + + XE Magazine + + + + + 검은색 + + + 회색 + + + 흰색 + + + + 검은색(no profile) + + + 회색(no profile) + + + 흰색(no profile) + + + diff --git a/modules/ncenterlite/m.skins/default/userconfig.html b/modules/ncenterlite/m.skins/default/userconfig.html new file mode 100644 index 000000000..fae62dae5 --- /dev/null +++ b/modules/ncenterlite/m.skins/default/userconfig.html @@ -0,0 +1,66 @@ + +
    + +
    +

    {$XE_VALIDATOR_MESSAGE}

    +
    + + + + + + + +
    +

    {@$user_str = $member_info->nick_name} + {@$user_str = $logged_info->nick_name} + {@$title_str = Context::getLang('ncenterlite_userconfig_title')} + {sprintf($title_str, $user_str)} +

    + +

    {$lang->ncenterlite_userconfig_about} ({$lang->ncenterlite_userconfig_about_warning})

    +
    + +
    + + +

    {$lang->ncenterlite_comment_noti_about}

    +
    +
    +
    + +
    + + +

    {$lang->ncenterlite_mention_noti_about}

    +
    +
    +
    + +
    + + +

    {$lang->ncenterlite_message_noti_about}

    +
    +
    + +
    +
    +
    + +
    +
    + +
    \ No newline at end of file diff --git a/modules/ncenterlite/ncenterlite.admin.controller.php b/modules/ncenterlite/ncenterlite.admin.controller.php new file mode 100644 index 000000000..91b15fa10 --- /dev/null +++ b/modules/ncenterlite/ncenterlite.admin.controller.php @@ -0,0 +1,152 @@ +use = $obj->use; + $config->display_use = $obj->display_use; + + $config->user_config_list = $obj->user_config_list; + $config->mention_format = $obj->mention_format; + $config->mention_names = $obj->mention_names; + $config->document_notify = $obj->document_notify; + $config->message_notify = $obj->message_notify; + $config->hide_module_srls = $obj->hide_module_srls; + $config->android_format = $obj->android_format; + if(!$config->mention_format && !is_array($config->mention_format)) + { + $config->mention_format = array(); + } + $config->admin_comment_module_srls = $obj->admin_comment_module_srls; + + $config->skin = $obj->skin; + $config->mskin = $obj->mskin; + $config->mcolorset = $obj->mcolorset; + $config->colorset = $obj->colorset; + $config->zindex = $obj->zindex; + $config->anonymous_name = $obj->anonymous_name; + $config->document_read = $obj->document_read; + $config->layout_srl = $obj->layout_srl; + $config->mlayout_srl = $obj->mlayout_srl; + $config->voted_format = $obj->voted_format; + + if(!$config->document_notify) + { + $config->document_notify = 'direct-comment'; + } + + $this->setMessage('success_updated'); + + $oModuleController->updateModuleConfig('ncenterlite', $config); + + if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) + { + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispNcenterliteAdminConfig'); + header('location: ' . $returnUrl); + return; + } + } + + /** + * @brief 스킨 테스트를 위한 더미 데이터 생성 5개 생성 + **/ + function procNcenterliteAdminInsertDummyData() + { + $oNcenterliteController = getController('ncenterlite'); + $logged_info = Context::get('logged_info'); + + for($i = 1; $i <= 5; $i++) + { + $args = new stdClass(); + $args->member_srl = $logged_info->member_srl; + $args->srl = 1; + $args->target_srl = 1; + $args->type = $this->_TYPE_TEST; + $args->target_type = $this->_TYPE_TEST; + $args->target_url = getUrl(''); + $args->target_summary = Context::getLang('ncenterlite_thisistest') . rand(); + $args->target_nick_name = $logged_info->nick_name; + $args->regdate = date('YmdHis'); + $args->notify = $oNcenterliteController->_getNotifyId($args); + $output = $oNcenterliteController->_insertNotify($args); + } + } + + /** + * @brief 모듈 푸시 테스트를 위한 더미 데이터 생성 1개 생성 + **/ + function procNcenterliteAdminInsertPushData() + { + $oNcenterliteController = getController('ncenterlite'); + $logged_info = Context::get('logged_info'); + + $args = new stdClass(); + $args->member_srl = $logged_info->member_srl; + $args->srl = 1; + $args->target_srl = 1; + $args->type = $this->_TYPE_DOCUMENT; + $args->target_type = $this->_TYPE_COMMENT; + $args->target_url = getUrl(''); + $args->target_summary = Context::getLang('ncenterlite_thisistest') . rand(); + $args->target_nick_name = $logged_info->nick_name; + $args->regdate = date('YmdHis'); + $args->notify = $oNcenterliteController->_getNotifyId($args); + $output = $oNcenterliteController->_insertNotify($args); + } + + function procNcenterliteAdminDeleteNofity() + { + $old_date = Context::get('old_date'); + $args = new stdClass; + if($old_date) + { + $args->old_date = $old_date; + } + $output = executeQuery('ncenterlite.deleteNotifyAll', $args); + if(!$output->toBool()) + { + $oDB->rollback(); + return $output; + } + + if($old_date) + { + $oNcenterliteModel = getModel('ncenterlite'); + $message = Context::getLang('ncenterlite_message_delete_notification_before'); + $message = sprintf($message, $oNcenterliteModel->getAgo($old_date) ); + $this->setMessage($message); + } + else + { + $this->setMessage('ncenterlite_message_delete_notification_all'); + } + + if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) + { + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispNcenterliteAdminList'); + header('location: ' .$returnUrl); + return; + } + } + + function procNcenterliteAdminEnviromentGatheringAgreement() + { + $vars = Context::getRequestVars(); + $oModuleModel = getModel('module'); + $ncenterlite_module_info = $oModuleModel->getModuleInfoXml('ncenterlite'); + $agreement_file = FileHandler::getRealPath(sprintf('%s%s.txt', './files/ncenterlite/ncenterlite-', $ncenterlite_module_info->version)); + + FileHandler::writeFile($agreement_file, $vars->is_agree); + + if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) + { + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispNcenterliteAdminConfig'); + header('location: ' . $returnUrl); + return; + } + } +} diff --git a/modules/ncenterlite/ncenterlite.admin.model.php b/modules/ncenterlite/ncenterlite.admin.model.php new file mode 100644 index 000000000..4e5a9ecb9 --- /dev/null +++ b/modules/ncenterlite/ncenterlite.admin.model.php @@ -0,0 +1,105 @@ +getConfig(); + + global $lang; + + $act = Context::get('act'); + $output = $oNcenterliteModel->getNcenterliteAdminList(); + + $oMemberModel = getModel('member'); + $list = $output->data; + + foreach($list as $k => $v) + { + $target_member = $v->target_nick_name; + + switch($v->type) + { + case 'D': + $type = $lang->ncenterlite_document; //$type = '글'; + break; + case 'C': + $type = $lang->ncenterlite_comment; //$type = '댓글'; + break; + // 메시지. 쪽지 + case 'E': + $type = $lang->ncenterlite_type_message; //$type = '쪽지'; + break; + } + + switch($v->target_type) + { + case 'C': + $str = sprintf($lang->ncenterlite_commented, $target_member, $type, $v->target_summary); + //$str = sprintf('%s님이 회원님의 %s에 "%s" 댓글을 남겼습니다.', $target_member, $type, $v->target_summary); + break; + case 'A': + $str = sprintf($lang->ncenterlite_commented_board, $target_member, $v->target_browser, $v->target_summary); + //$str = sprintf('%1$s님이 게시판 "%2$s""%3$s"라고 댓글을 남겼습니다.', $target_member, $type, $v->target_summary); + break; + case 'M': + $str = sprintf($lang->ncenterlite_mentioned, $target_member, $v->target_summary, $type); + //$str = sprintf('%s님이 "%s" %s에서 회원님을 언급하였습니다.', $target_member, $v->target_summary, $type); + break; + // 메시지. 쪽지 + case 'E': + if(version_compare(__XE_VERSION__, '1.7.4', '>=')) + { + $str = sprintf($lang->ncenterlite_message_mention, $target_member, $v->target_summary); + //%s님께서 "%s"라고 메세지를 보내셨습니다. + } + else + { + $str = sprintf($lang->ncenterlite_message_string, $v->target_summary); + } + break; + case 'T': + $str = sprintf($lang->ncenterlite_test_noti, $target_member); + break; + case 'P': + $str = sprintf($lang->ncenterlite_board, $target_member, $v->target_browser, $v->target_summary); + //%1$s님이 게시판 "%2$s""%3$s"라고 글을 남겼습니다. + break; + case 'S': + if($v->target_browser) + { + $str = sprintf($lang->ncenterlite_board, $target_member, $v->target_browser, $v->target_summary); + } + else + { + $str = sprintf($lang->ncenterlite_article, $target_member, $v->target_summary); + } + break; + case 'V': + $str = sprintf($lang->ncenterlite_vote, $target_member, $v->target_summary); + break; + } + + if($v->type=='U') + { + $str = $oNcenterliteModel->getNotifyTypeString($v->notify_type,unserialize($v->target_body)); + } + $v->text = $str; + $v->ago = $oNcenterliteModel->getAgo($v->regdate); + $v->url = getUrl('','act','procNcenterliteRedirect', 'notify', $v->notify, 'url', $v->target_url); + if($v->target_member_srl) + { + $profileImage = $oMemberModel->getProfileImage($v->target_member_srl); + $v->profileImage = $profileImage->src; + } + + $list[$k] = $v; + } + + $output->data = $list; + return $output; + } + +} \ No newline at end of file diff --git a/modules/ncenterlite/ncenterlite.admin.view.php b/modules/ncenterlite/ncenterlite.admin.view.php new file mode 100644 index 000000000..4c745ed0b --- /dev/null +++ b/modules/ncenterlite/ncenterlite.admin.view.php @@ -0,0 +1,90 @@ +setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile(str_replace('dispNcenterliteAdmin', '', $this->act)); + } + + function dispNcenterliteAdminConfig() + { + $oModuleModel = getModel('module'); + $oNcenterliteModel = getModel('ncenterlite'); + $oLayoutModel = getModel('layout'); + + $config = $oNcenterliteModel->getConfig(); + Context::set('config', $config); + + $layout_list = $oLayoutModel->getLayoutList(); + Context::set('layout_list', $layout_list); + + $mobile_layout_list = $oLayoutModel->getLayoutList(0, 'M'); + Context::set('mlayout_list', $mobile_layout_list); + + $skin_list = $oModuleModel->getSkins($this->module_path); + Context::set('skin_list', $skin_list); + + $mskin_list = $oModuleModel->getSkins($this->module_path, "m.skins"); + Context::set('mskin_list', $mskin_list); + + if(!$skin_list[$config->skin]) $config->skin = 'default'; + Context::set('colorset_list', $skin_list[$config->skin]->colorset); + + if(!$mskin_list[$config->mskin]) $config->mskin = 'default'; + Context::set('mcolorset_list', $mskin_list[$config->mskin]->colorset); + + $security = new Security(); + $security->encodeHTML('config..'); + $security->encodeHTML('skin_list..title'); + $security->encodeHTML('colorset_list..name','colorset_list..title'); + + $mid_list = $oModuleModel->getMidList(null, array('module_srl', 'mid', 'browser_title', 'module')); + + Context::set('mid_list', $mid_list); + + // 사용환경정보 전송 확인 + $ncenterlite_module_info = $oModuleModel->getModuleInfoXml('ncenterlite'); + $agreement_file = FileHandler::getRealPath(sprintf('%s%s.txt', './files/ncenterlite/ncenterlite-', $ncenterlite_module_info->version)); + + $agreement_ver_file = FileHandler::getRealPath(sprintf('%s%s.txt', './files/ncenterlite/ncenterlite_ver-', $ncenterlite_module_info->version)); + + if(file_exists($agreement_file)) + { + $agreement = FileHandler::readFile($agreement_file); + Context::set('_ncenterlite_env_agreement', $agreement); + $agreement_ver = FileHandler::readFile($agreement_ver_file); + if($agreement == 'Y') + { + $_ncenterlite_iframe_url = 'http://sosifam.com/index.php?mid=ncenterlite_iframe'; + if(!$agreement_ver) + { + $_host_info = urlencode($_SERVER['HTTP_HOST']) . '-NC' . $ncenterlite_module_info->version . '-PHP' . phpversion() . '-XE' . __XE_VERSION__; + } + Context::set('_ncenterlite_iframe_url', $_ncenterlite_iframe_url . '&_host='. $_host_info); + Context::set('ncenterlite_module_info', $ncenterlite_module_info); + } + FileHandler::writeFile($agreement_ver_file, 'Y'); + } + else + { + Context::set('_ncenterlite_env_agreement', 'NULL'); + } + } + + function dispNcenterliteAdminList() + { + $oNcenterliteAdminModel = getAdminModel('ncenterlite'); + + $output = $oNcenterliteAdminModel->getAdminNotifyList(); + + Context::set('total_count', $output->page_navigation->total_count); + Context::set('total_page', $output->page_navigation->total_page); + Context::set('page', $output->page); + Context::set('ncenterlite_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('ncenter_list'); + } + +} diff --git a/modules/ncenterlite/ncenterlite.class.php b/modules/ncenterlite/ncenterlite.class.php new file mode 100644 index 000000000..edcc7777f --- /dev/null +++ b/modules/ncenterlite/ncenterlite.class.php @@ -0,0 +1,213 @@ +disable_notify)) + { + $module_info = Context::get('module_info'); + if(in_array($module_info->mid, $this->disable_notify)) $result = TRUE; + } + + return $result; + } + + function moduleInstall() + { + return new Object(); + } + + function checkUpdate() + { + $oModuleModel = getModel('module'); + $oDB = &DB::getInstance(); + + foreach($this->triggers as $trigger) + { + if(!$oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) return true; + } + + if(!$oDB->isColumnExists('ncenterlite_notify', 'readed')) + { + return true; + } + + if(!$oDB->isColumnExists('ncenterlite_notify', 'target_body')) + { + return true; + } + + if(!$oDB->isColumnExists('ncenterlite_notify', 'notify_type')) + { + return true; + } + + if(!$oDB->isColumnExists('ncenterlite_notify', 'target_browser')) + { + return true; + } + + if(!$oDB->isColumnExists('ncenterlite_notify', 'target_p_srl')) + { + return true; + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_srl')) + { + return true; + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_target_srl')) + { + return true; + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_target_p_srl')) + { + return true; + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_notify')) + { + return true; + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_target_member_srl')) + { + return true; + } + + return false; + } + + function moduleUpdate() + { + $oModuleModel = getModel('module'); + $oModuleController = getController('module'); + $oDB = &DB::getInstance(); + + foreach($this->triggers as $trigger) + { + if(!$oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) + { + $oModuleController->insertTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); + } + } + + if(!$oDB->isColumnExists('ncenterlite_notify','readed')) + { + $oDB->addColumn('ncenterlite_notify', 'readed', 'char', 1, 'N', true); + $oDB->addIndex('ncenterlite_notify', 'idx_readed', array('readed')); + $oDB->addIndex('ncenterlite_notify', 'idx_member_srl', array('member_srl')); + $oDB->addIndex('ncenterlite_notify', 'idx_regdate', array('regdate')); + } + + if(!$oDB->isColumnExists('ncenterlite_notify','target_browser')) + { + $oDB->addColumn('ncenterlite_notify', 'target_browser', 'varchar', 50, true); + } + + if(!$oDB->isColumnExists('ncenterlite_notify','target_body')) + { + $oDB->addColumn('ncenterlite_notify', 'target_body', 'varchar', 255, true); + } + + if(!$oDB->isColumnExists('ncenterlite_notify','notify_type')) + { + $oDB->addColumn('ncenterlite_notify', 'notify_type', 'number', 11, 0); + } + + if(!$oDB->isColumnExists('ncenterlite_notify','target_p_srl')) + { + $oDB->addColumn('ncenterlite_notify', 'target_p_srl', 'number', 10, true); + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_srl')) + { + $oDB->addIndex('ncenterlite_notify', 'idx_srl', array('srl')); + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_target_srl')) + { + $oDB->addIndex('ncenterlite_notify', 'idx_target_srl', array('target_srl')); + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_target_p_srl')) + { + $oDB->addIndex('ncenterlite_notify', 'idx_target_p_srl', array('target_p_srl')); + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_notify')) + { + $oDB->addIndex('ncenterlite_notify', 'idx_notify', array('notify')); + } + + if(!$oDB->isIndexExists('ncenterlite_notify', 'idx_target_member_srl')) + { + $oDB->addIndex('ncenterlite_notify', 'idx_target_member_srl', array('target_member_srl')); + } + + return new Object(0, 'success_updated'); + } + + function recompileCache() + { + return new Object(); + } + + function moduleUninstall() + { + $oModuleController = getController('module'); + + foreach($this->triggers as $trigger) + { + $oModuleController->deleteTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); + } + return new Object(); + } +} diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php new file mode 100644 index 000000000..99538bb5b --- /dev/null +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -0,0 +1,1050 @@ +member_srl; + } + + if($logged_info->member_srl != $member_srl && $logged_info->is_admin != 'Y') return new Object(-1, 'ncenterlite_stop_no_permission_other_user_settings'); + + $output = $oNcenterliteModel->getMemberConfig($member_srl); + + $obj = Context::getRequestVars(); + + $args = new stdClass(); + $args->member_srl = $member_srl; + $args->comment_notify = $obj->comment_notify; + $args->mention_notify = $obj->mention_notify; + $args->message_notify = $obj->message_notify; + + if(!$output) + { + $outputs = executeQuery('ncenterlite.insertUserConfig', $args); + } + else + { + $outputs = executeQuery('ncenterlite.updateUserConfig', $args); + } + + $this->setMessage('success_updated'); + + if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) + { + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'act', 'dispNcenterliteUserConfig','member_srl',$member_srl); + header('location: ' . $returnUrl); + return; + } + } + + function triggerAfterDeleteMember($obj) + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + + $member_srl = $obj->member_srl; + if(!$member_srl) return new Object(); + + $args = new stdClass(); + $args->member_srl = $member_srl; + $output = executeQuery('ncenterlite.deleteNotifyByMemberSrl', $args); + if(!$output->toBool()) + { + return $output; + } + return new Object(); + } + + function triggerAfterInsertDocument(&$obj) + { + $oModuleModel = getModel('module'); + + if($this->_isDisable()) return; + + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + + $content = strip_tags($obj->title . ' ' . $obj->content); + + $mention_targets = $this->_getMentionTarget($content); + if(!$mention_targets || !count($mention_targets)) return new Object(); + + $oDocumentModel = getModel('document'); + $document_srl = $obj->document_srl; + $oDocument = $oDocumentModel->getDocument($document_srl); + $module_info = $oModuleModel->getModuleInfoByDocumentSrl($document_srl); + + $is_anonymous = $this->_isAnonymous($this->_TYPE_DOCUMENT, $obj); + // 맨션 알림일경우 맨션알림 시작. + if($mention_targets) + { + // !TODO 공용 메소드로 분리 + foreach($mention_targets as $mention_member_srl) + { + $target_member_config = $oNcenterliteModel->getMemberConfig($mention_member_srl); + $notify_member_config = $target_member_config->data; + + if($notify_member_config->mention_notify == 'N') + { + continue; + } + + $args = new stdClass(); + $args->member_srl = $mention_member_srl; + $args->srl = $obj->document_srl; + $args->target_p_srl = $obj->document_srl; + $args->target_srl = $obj->document_srl; + $args->type = $this->_TYPE_DOCUMENT; + $args->target_type = $this->_TYPE_MENTION; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $obj->document_srl); + $args->target_summary = cut_str(strip_tags($obj->title), 50); + $args->target_nick_name = $obj->nick_name; + $args->target_email_address = $obj->email_address; + $args->regdate = date('YmdHis'); + $args->target_browser = $module_info->browser_title; + $args->notify = $this->_getNotifyId($args); + $output = $this->_insertNotify($args, $is_anonymous); + } + } + + return new Object(); + } + + function triggerAfterInsertComment(&$obj) + { + if($this->_isDisable()) return; + + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + + $logged_info = Context::get('logged_info'); + $notify_member_srl = array(); + + $document_srl = $obj->document_srl; + $oModuleModel = getModel('module'); + $module_info = $oModuleModel->getModuleInfoByDocumentSrl($document_srl); + $comment_srl = $obj->comment_srl; + $parent_srl = $obj->parent_srl; + $content = $obj->content; + $regdate = $obj->regdate; + + // 익명 노티 체크 + $is_anonymous = $this->_isAnonymous($this->_TYPE_COMMENT, $obj); + + // 멘션 + $mention_targets = $this->_getMentionTarget(strip_tags($obj->content)); + // !TODO 공용 메소드로 분리 + foreach($mention_targets as $mention_member_srl) + { + $target_member_config = $oNcenterliteModel->getMemberConfig($mention_member_srl); + $notify_member_config = $target_member_config->data; + if($notify_member_config->mention_notify == 'N') + { + continue; + } + + $args = new stdClass(); + $args->member_srl = $mention_member_srl; + $args->target_p_srl = $obj->comment_srl; + $args->srl = $obj->document_srl; + $args->target_srl = $obj->comment_srl; + $args->type = $this->_TYPE_COMMENT; + $args->target_type = $this->_TYPE_MENTION; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_summary = cut_str(strip_tags($content), 50); + $args->target_nick_name = $obj->nick_name; + $args->target_email_address = $obj->email_address; + $args->regdate = date('YmdHis'); + $args->target_browser = $module_info->browser_title; + $args->notify = $this->_getNotifyId($args); + $output = $this->_insertNotify($args, $is_anonymous); + $notify_member_srl[] = $mention_member_srl; + } + + $admin_list = $oNcenterliteModel->getMemberAdmins(); + $admins_list = $admin_list->data; + + foreach($admins_list as $admins) + { + if(is_array($config->admin_comment_module_srls) && in_array($module_info->module_srl, $config->admin_comment_module_srls)) + { + $args = new stdClass(); + $args->member_srl = $admins->member_srl; + $args->target_p_srl = $obj->comment_srl; + $args->srl = $obj->document_srl; + $args->target_srl = $obj->comment_srl; + $args->type = $this->_TYPE_COMMENT; + $args->target_type = $this->_TYPE_ADMIN_COMMENT; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_summary = cut_str(strip_tags($content), 50); + $args->target_nick_name = $obj->nick_name; + $args->target_email_address = $obj->email_address; + $args->regdate = date('YmdHis'); + $args->target_browser = $module_info->browser_title; + $args->notify = $this->_getNotifyId($args); + $output = $this->_insertNotify($args, $is_anonymous); + } + } + // 대댓글 + if($parent_srl) + { + $oCommentModel = getModel('comment'); + $oComment = $oCommentModel->getComment($parent_srl); + $member_srl = $oComment->member_srl; + $comment_member_config = $oNcenterliteModel->getMemberConfig($member_srl); + $parent_member_config = $comment_member_config->data; + + // !TODO 공용 메소드로 분리 + if(!in_array(abs($member_srl), $notify_member_srl) && (!$logged_info || ($member_srl != 0 && abs($member_srl) != $logged_info->member_srl)) && $parent_member_config->comment_notify != 'N') + { + $args = new stdClass(); + $args->member_srl = abs($member_srl); + $args->srl = $obj->document_srl; + $args->target_p_srl = $parent_srl; + $args->target_srl = $obj->comment_srl; + $args->type = $this->_TYPE_COMMENT; + $args->target_type = $this->_TYPE_COMMENT; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_summary = cut_str(strip_tags($content), 50); + $args->target_nick_name = $obj->nick_name; + $args->target_email_address = $obj->email_address; + $args->regdate = $regdate; + $args->target_browser = $module_info->browser_title; + $args->notify = $this->_getNotifyId($args); + $output = $this->_insertNotify($args, $is_anonymous); + $notify_member_srl[] = abs($member_srl); + } + } + // 대댓글이 아니고, 게시글의 댓글을 남길 경우 + if(!$parent_srl || ($parent_srl && $config->document_notify == 'all-comment')) + { + $oDocumentModel = getModel('document'); + $oDocument = $oDocumentModel->getDocument($document_srl); + + $member_srl = $oDocument->get('member_srl'); + $comment_member_config = $oNcenterliteModel->getMemberConfig($member_srl); + $document_comment_member_config = $comment_member_config->data; + + // !TODO 공용 메소드로 분리 + if(!in_array(abs($member_srl), $notify_member_srl) && (!$logged_info || ($member_srl != 0 && abs($member_srl) != $logged_info->member_srl)) && $document_comment_member_config->comment_notify != 'N') + { + $args = new stdClass(); + $args->member_srl = abs($member_srl); + $args->srl = $document_srl; + $args->target_p_srl = $comment_srl; + $args->target_srl = $comment_srl; + $args->type = $this->_TYPE_DOCUMENT; + $args->target_type = $this->_TYPE_COMMENT; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_summary = cut_str(strip_tags($content), 50); + $args->target_nick_name = $obj->nick_name; + $args->target_email_address = $obj->email_address; + $args->regdate = $regdate; + $args->target_browser = $module_info->browser_title; + $args->notify = $this->_getNotifyId($args); + $output = $this->_insertNotify($args, $is_anonymous); + } + } + + return new Object(); + } + + function triggerBeforeModuleObjectProc(&$oModule) + { + if(version_compare(__XE_VERSION__, '1.7.4', '>=')) + { + return new Object(); + } + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + + $vars = Context::getRequestVars(); + $logged_info = Context::get('logged_info'); + + $messages_member_config = $oNcenterliteModel->getMemberConfig($logged_info->member_srl); + $message_member_config = $messages_member_config->data; + + // 쪽지 체크 및 유저 쪽지 알림 채크 + if($config->message_notify == 'Y' && $message_member_config->message_notify != 'N') + { + $flag_path = './files/ncenterlite/new_message_flags/'; + + $need_update = false; + // 쪽지 알림 메시지 체크 + if(strpos(Context::getHtmlFooter(), 'xeNotifyMessage') !== FALSE) + { + $need_update = true; + } + // 메시지 플래그 파일 체크 + else if(file_exists($flag_path . $logged_info->member_srl)) + { + $need_update = true; + } + + if($oModule->act == 'procCommunicationSendMessage') + { + FileHandler::makeDir($flag_path); + $flag_file = sprintf('%s%s', $flag_path, $vars->receiver_srl); + FileHandler::writeFile($flag_file, $vars->receiver_srl); + } + else if($need_update) + { + $oMemberModel = getModel('member'); + $_sender_member_srl = trim(FileHandler::readFile($flag_path . $logged_info->member_srl)); + $sender_member_info = $oMemberModel->getMemberInfoByMemberSrl($_sender_member_srl); + FileHandler::removeFile($flag_path . $logged_info->member_srl); + + // 새 쪽지 수 + $args = new stdClass(); + $args->receiver_srl = $logged_info->member_srl; + $output = executeQuery('ncenterlite.getCountNewMessage', $args); + $message_count = $output->data->count; + + // 기존 쪽지 알림을 읽은 것으로 변경 + $cond = new stdClass(); + $cond->type = $this->_TYPE_MESSAGE; + $cond->member_srl = $logged_info->member_srl; + $output = executeQuery('ncenterlite.updateNotifyReadedByType', $cond); + + if(!$message_count) return; + + // 알림 추가 + $args = new stdClass(); + $args->member_srl = $logged_info->member_srl; + $args->srl = $sender_member_info->member_srl; + if(!$args->srl) $args->srl = 0; + $args->target_p_srl = 1; + $args->target_srl = $sender_member_info->member_srl; + if(!$args->srl) $args->target_srl = 0; + $args->type = $this->_TYPE_MESSAGE; + $args->target_type = $this->_TYPE_MESSAGE; + $args->target_url_params = $target_url_params; + $args->target_summary = $message_count; + $args->target_nick_name = $sender_member_info->nick_name; + $args->target_member_srl = $sender_member_info->member_srl; + $args->regdate = date('YmdHis'); + $args->notify = $this->_getNotifyId($args); + $args->target_url = getNotEncodedFullUrl('', 'act', 'dispCommunicationMessages'); + + $output = $this->_insertNotify($args); + } + } + } + + function triggerAfterSendMessage(&$trigger_obj) + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + if($config->message_notify == 'N') + { + return new Object(); + } + $messages_member_config = $oNcenterliteModel->getMemberConfig($trigger_obj->receiver_srl); + $message_member_config = $messages_member_config->data; + + if(version_compare(__XE_VERSION__, '1.8', '>=') && $message_member_config->message_notify != 'N') + { + $args = new stdClass(); + $args->member_srl = $trigger_obj->receiver_srl; + $args->srl = $trigger_obj->related_srl; + $args->target_p_srl = '1'; + $args->target_srl = $trigger_obj->message_srl; + $args->type = $this->_TYPE_MESSAGE; + $args->target_type = $this->_TYPE_MESSAGE; + $args->target_summary = $trigger_obj->title; + $args->regdate = date('YmdHis'); + $args->notify = $this->_getNotifyId($args); + $args->target_url = getNotEncodedFullUrl('', 'act', 'dispCommunicationMessages', 'message_srl', $trigger_obj->related_srl); + $output = $this->_insertNotify($args); + } + elseif($message_member_config->message_notify != 'N') + { + $args = new stdClass(); + $args->member_srl = $trigger_obj->receiver_srl; + $args->srl = $trigger_obj->receiver_srl; + $args->target_p_srl = '1'; + $args->target_srl = $trigger_obj->sender_srl; + $args->type = $this->_TYPE_MESSAGE; + $args->target_type = $this->_TYPE_MESSAGE; + $args->target_summary = $trigger_obj->title; + $args->regdate = date('YmdHis'); + $args->notify = $this->_getNotifyId($args); + $args->target_url = getNotEncodedFullUrl('', 'act', 'dispCommunicationMessages'); + $output = $this->_insertNotify($args); + } + + } + + function triggerAfterVotedupdate(&$obj) + { + $oDocumentModel = getModel('document'); + $oDocument = $oDocumentModel->getDocument($obj->document_srl, false, false); + + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + if($config->voted_format != 'Y') return new Object(); + if($obj->point < 0) return new Object(); + + $args = new stdClass(); + $args->member_srl = $obj->member_srl; + $args->srl = $obj->document_srl; + $args->target_p_srl = '1'; + $args->target_srl = $obj->document_srl; + $args->type = $this->_TYPE_DOCUMENT; + $args->target_type = $this->_TYPE_VOTED; + $args->target_summary = $oDocument->get('title'); + $args->regdate = date('YmdHis'); + $args->notify = $this->_getNotifyId($args); + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $obj->document_srl); + $output = $this->_insertNotify($args, $is_anonymous); + } + + function triggerAfterDeleteComment(&$obj) + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + + $args = new stdClass(); + $args->srl = $obj->comment_srl; + $output = executeQuery('ncenterlite.deleteNotifyBySrl', $args); + return new Object(); + } + + function triggerAfterDeleteDocument(&$obj) + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + + $args = new stdClass(); + $args->srl = $obj->document_srl; + $output = executeQuery('ncenterlite.deleteNotifyBySrl', $args); + return new Object(); + } + + function triggerAfterModuleHandlerProc(&$oModule) + { + $vars = Context::getRequestVars(); + $logged_info = Context::get('logged_info'); + $args = new stdClass(); + + if($oModule->getLayoutFile() == 'popup_layout.html') Context::set('ncenterlite_is_popup', TRUE); + + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if($config->use != 'Y') return new Object(); + + $this->_hide_ncenterlite = false; + if($oModule->module == 'beluxe' && Context::get('is_modal')) + { + $this->_hide_ncenterlite = true; + } + if($oModule->module == 'bodex' && Context::get('is_iframe')) + { + $this->_hide_ncenterlite = true; + } + if($oModule->getLayoutFile() == 'popup_layout.html') + { + $this->_hide_ncenterlite = true; + } + + if($oModule->act == 'dispBoardReplyComment') + { + $comment_srl = Context::get('comment_srl'); + $logged_info = Context::get('logged_info'); + if($comment_srl && $logged_info) + { + $args->target_srl = $comment_srl; + $args->member_srl = $logged_info->member_srl; + $output_update = executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args); + } + } + else if($oModule->act == 'dispBoardContent') + { + $comment_srl = Context::get('_comment_srl'); + $document_srl = Context::get('document_srl'); + $oDocument = Context::get('oDocument'); + $logged_info = Context::get('logged_info'); + + if($document_srl && $logged_info && $config->document_read=='Y') + { + $args->srl = $document_srl; + $args->member_srl = $logged_info->member_srl; + $outputs = executeQuery('ncenterlite.updateNotifyReadedBySrl', $args); + } + + if($comment_srl && $document_srl && $oDocument) + { + $_comment_list = $oDocument->getComments(); + if($_comment_list) + { + if(array_key_exists($comment_srl, $_comment_list)) + { + $url = getNotEncodedUrl('_comment_srl','') . '#comment_' . $comment_srl; + $need_check_socialxe = true; + } + else + { + $cpage = $oDocument->comment_page_navigation->cur_page; + if($cpage > 1) + { + $url = getNotEncodedUrl('cpage', $cpage-1) . '#comment_' . $comment_srl; + $need_check_socialxe = true; + } + else + { + $url = getNotEncodedUrl('_comment_srl', '', 'cpage', '') . '#comment_' . $comment_srl; + } + } + + if($need_check_socialxe) + { + $oDB = &DB::getInstance(); + if($oDB->isTableExists('socialxe')) + { + $args = new stdClass(); + $oModuleModel = getModel('module'); + $module_info = $oModuleModel->getModuleInfoByDocumentSrl($document_srl); + $args->module_srl = $module_info->module_srl; + $output = executeQuery('ncenterlite.getSocialxeCount', $args); + if($output->data->cnt) + { + $socialxe_comment_srl = $comment_srl; + + $args = new stdClass(); + $args->comment_srl = $comment_srl; + $oCommentModel = getModel('comment'); + $oComment = $oCommentModel->getComment($comment_srl); + $parent_srl = $oComment->get('parent_srl'); + if($parent_srl) + { + $socialxe_comment_srl = $parent_srl; + } + + $url = getNotEncodedUrl('_comment_srl', '', 'cpage', '', 'comment_srl', $socialxe_comment_srl) . '#comment_' . $comment_srl; + } + } + } + + $url = str_replace('&','&',$url); + header('location: ' . $url); + Context::close(); + exit; + } + } + } + elseif($oModule->act == 'dispCommunicationMessages') + { + $message_srl = Context::get('message_srl'); + $logged_info = Context::get('logged_info'); + if($message_srl) + { + $args = new stdClass(); + $args->target_srl = $message_srl; + $args->member_srl = $logged_info->member_srl; + executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args); + } + } + + // 지식인 모듈의 의견 + // TODO: 코드 분리 + if($oModule->act == 'procKinInsertComment') + { + // 글, 댓글 구분 + $parent_type = ($vars->document_srl == $vars->parent_srl) ? 'DOCUMENT' : 'COMMENT'; + if($parent_type == 'DOCUMENT') + { + $oDocumentModel = getModel('document'); + $oDocument = $oDocumentModel->getDocument($vars->document_srl); + $member_srl = $oDocument->get('member_srl'); + $type = $this->_TYPE_DOCUMENT; + } + else + { + $oCommentModel = getModel('comment'); + $oComment = $oCommentModel->getComment($vars->parent_srl); + $member_srl = $oComment->get('member_srl'); + $type = $this->_TYPE_COMMENT; + } + + if($logged_info->member_srl != $member_srl) + { + $args = new stdClass(); + $args->member_srl = abs($member_srl); + $args->srl = ($parent_type == 'DOCUMENT') ? $vars->document_srl : $vars->parent_srl; + $args->type = $type; + $args->target_type = $this->_TYPE_COMMENT; + $args->target_srl = $vars->parent_srl; + $args->target_p_srl = '1'; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $vars->document_srl, '_comment_srl', $vars->parent_srl) . '#comment_'. $vars->parent_srl; + $args->target_summary = cut_str(strip_tags($vars->content), 50); + $args->target_nick_name = $logged_info->nick_name; + $args->target_email_address = $logged_info->email_address; + $args->regdate = date('YmdHis'); + $args->notify = $this->_getNotifyId($args); + $output = $this->_insertNotify($args); + } + } + else if($oModule->act == 'dispKinView' || $oModule->act == 'dispKinIndex') + { + // 글을 볼 때 알림 제거 + $oDocumentModel = getModel('document'); + $oDocument = $oDocumentModel->getDocument($vars->document_srl); + $member_srl = $oDocument->get('member_srl'); + + if($logged_info->member_srl == $member_srl) + { + $args = new stdClass; + $args->member_srl = $logged_info->member_srl; + $args->srl = $vars->document_srl; + $args->type = $this->_TYPE_DOCUMENT; + $output = executeQuery('ncenterlite.updateNotifyReadedBySrl', $args); + } + } + else if($oModule->act == 'getKinComments') + { + // 의견을 펼칠 때 알림 제거 + $args = new stdClass; + $args->member_srl = $logged_info->member_srl; + $args->target_srl = $vars->parent_srl; + $output = executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args); + } + + return new Object(); + } + + function triggerBeforeDisplay(&$output_display) + { + $act = Context::get('act'); + // 팝업창이면 중지 + if(Context::get('ncenterlite_is_popup')) return; + + // 자신의 알림목록을 보고 있을 경우엔 알림센터창을 띄우지 않는다. + if($act == 'dispNcenterliteNotifyList') return; + + if(count($this->disable_notify_bar_act)) + { + if(in_array(Context::get('act'), $this->disable_notify_bar_act)) return; + } + + // HTML 모드가 아니면 중지 + act에 admin이 포함되어 있으면 중지 + if(Context::getResponseMethod() != 'HTML' || strpos(strtolower(Context::get('act')), 'admin') !== false) return; + + $logged_info = Context::get('logged_info'); + + // 로그인 상태가 아니면 중지 + if(!$logged_info) return; + + $module_info = Context::get('module_info'); + + if(count($this->disable_notify_bar_mid)) + { + if(in_array($module_info->mid, $this->disable_notify_bar_mid)) return; + } + + // admin 모듈이면 중지 + if($module_info->module == 'admin' ) return; + + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + + // 알림센터가 비활성화 되어 있으면 중지 + if($config->use != 'Y') return new Object(); + if($config->display_use == 'N') return new Object(); + + // 노티바 제외 페이지이면 중지 + if(in_array($module_info->module_srl, $config->hide_module_srls)) return new Object(); + + Context::set('ncenterlite_config', $config); + + $oModuleModel = getModel('module'); + $ncenterlite_module_info = $oModuleModel->getModuleInfoXml('ncenterlite'); + $jsCacheRefresh = '?'.$ncenterlite_module_info->version.'.'.$ncenterlite_module_info->date.'.js'; + Context::addJsFile('./modules/ncenterlite/tpl/js/ncenterlite.js'.$jsCacheRefresh, true, '', 100000); + + + $oNcenterliteModel = getModel('ncenterlite'); + + // 알림 목록 가져오기 + $_output = $oNcenterliteModel->getMyNotifyList(); + if(!$_output->data) return; // 알림 메시지가 없어도 항상 표시하게 하려면 이 줄을 제거 또는 주석 처리하세요. + + $_latest_notify_id = array_slice($_output->data, 0, 1); + $_latest_notify_id = $_latest_notify_id[0]->notify; + Context::set('ncenterlite_latest_notify_id', $_latest_notify_id); + + if($_COOKIE['_ncenterlite_hide_id'] && $_COOKIE['_ncenterlite_hide_id'] == $_latest_notify_id) return; + setcookie('_ncenterlite_hide_id', '', 0, '/'); + + $oMemberModel = getModel('member'); + $memberConfig = $oMemberModel->getMemberConfig(); + if($memberConfig->profile_image == 'Y') + { + $profileImage = $oMemberModel->getProfileImage($logged_info->member_srl); + Context::set('profileImage', $profileImage); + } + Context::set('useProfileImage', ($memberConfig->profile_image == 'Y') ? true : false); + + Context::set('ncenterlite_list', $_output->data); + Context::set('ncenterlite_page_navigation', $_output->page_navigation); + + if(Mobile::isFromMobilePhone()) + { + $this->template_path = sprintf('%sm.skins/%s/', $this->module_path, $config->mskin); + if(!is_dir($this->template_path)||!$config->mskin) + { + $config->mskin = 'default'; + $this->template_path = sprintf('%sm.skins/%s/',$this->module_path, $config->mskin); + } + } + else + { + $this->template_path = sprintf('%sskins/%s/', $this->module_path, $config->skin); + if(!is_dir($this->template_path)||!$config->skin) + { + $config->skin = 'default'; + $this->template_path = sprintf('%sskins/%s/',$this->module_path, $config->skin); + } + } + + Context::addHtmlFooter(''); + + $this->_addFile(); + $html = $this->_getTemplate(); + $output_display = $html . $output_display; + } + + function triggerAddMemberMenu() + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + + if($config->user_config_list == 'Y') + { + $logged_info = Context::get('logged_info'); + if(!Context::get('is_logged')) return new Object(); + $target_srl = Context::get('target_srl'); + + $oMemberController = getController('member'); + $oMemberController->addMemberMenu('dispNcenterliteNotifyList', 'ncenterlite_my_list'); + $oMemberController->addMemberMenu('dispNcenterliteUserConfig', 'ncenterlite_my_settings'); + + if($logged_info->is_admin== 'Y') + { + $url = getUrl('','act','dispNcenterliteUserConfig','member_srl',$target_srl); + $str = Context::getLang('ncenterlite_user_settings'); + $oMemberController->addMemberPopupMenu($url, $str, ''); + } + } + + return new Object(); + } + + function _addFile() + { + $oModuleModel = getModel('module'); + $module_info = $oModuleModel->getModuleInfoXml('ncenterlite'); + if(file_exists(FileHandler::getRealPath($this->template_path . 'ncenterlite.css'))) + { + Context::addCssFile($this->template_path . 'ncenterlite.css', true, 'all', '', 100); + } + + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + if(!Mobile::isFromMobilePhone()) + { + if($config->colorset && file_exists(FileHandler::getRealPath($this->template_path . 'ncenterlite.' . $config->colorset . '.css'))) + { + Context::addCssFile($this->template_path . 'ncenterlite.'.$config->colorset.'.css', true, 'all', '', 100); + } + } + elseif(Mobile::isFromMobilePhone()) + { + if($config->mcolorset && file_exists(FileHandler::getRealPath($this->template_path . 'ncenterlite.' . $config->mcolorset . '.css'))) + { + Context::addCssFile($this->template_path . 'ncenterlite.'.$config->mcolorset.'.css', true, 'all', '', 100); + } + + Context::loadFile(array('./common/js/jquery.min.js', 'head', '', -100000), true); + Context::loadFile(array('./common/js/xe.min.js', 'head', '', -100000), true); + Context::addCssFile($this->template_path . 'ncenterlite.mobile.css', true, 'all', '', 100); + } + if($config->zindex) + { + Context::set('ncenterlite_zindex', ' style="z-index:' . $config->zindex . ';" '); + } + } + + function _getTemplate() + { + $oNcenterModel = getModel('ncenterlite'); + $config = $oNcenterModel->getConfig(); + + $oTemplateHandler = TemplateHandler::getInstance(); + $result = ''; + + if(Mobile::isFromMobilePhone()) + { + $path = sprintf('%sm.skins/%s/', $this->module_path, $config->mskin); + } + else + { + $path = sprintf('%sskins/%s/', $this->module_path, $config->skin); + } + $result = $oTemplateHandler->compile($path, 'ncenterlite.html'); + + return $result; + } + + function updateNotifyRead($notify, $member_srl) + { + $args = new stdClass(); + $args->member_srl = $member_srl; + $args->notify = $notify; + $output = executeQuery('ncenterlite.updateNotifyReaded', $args); + //$output = executeQuery('ncenterlite.deleteNotify', $args); + + return $output; + } + + function updateNotifyReadiByTargetSrl($target_srl, $member_srl) + { + $args = new stdClass(); + $args->member_srl = $member_srl; + $args->target_srl = $target_srl; + $output = executeQuery('ncenterlite.updateNotifyReadedByTargetSrl', $args); + //$output = executeQuery('ncenterlite.deleteNotifyByTargetSrl', $args); + + return $output; + } + + function updateNotifyReadAll($member_srl) + { + $args = new stdClass(); + $args->member_srl = $member_srl; + $output = executeQuery('ncenterlite.updateNotifyReadedAll', $args); + //$output = executeQuery('ncenterlite.deleteNotifyByMemberSrl', $args); + + return $ouptut; + } + + function procNcenterliteNotifyRead() + { + $logged_info = Context::get('logged_info'); + $target_srl = Context::get('target_srl'); + if(!$logged_info || !$target_srl) return new Object(-1, 'msg_invalid_request'); + + $output = $this->updateNotifyRead($notify, $logged_info->member_srl); + return $output; + } + + function procNcenterliteNotifyReadAll() + { + $logged_info = Context::get('logged_info'); + if(!$logged_info) return new Object(-1, 'msg_invalid_request'); + + $output = $this->updateNotifyReadAll($logged_info->member_srl); + return $output; + } + + function procNcenterliteRedirect() + { + $logged_info = Context::get('logged_info'); + $url = Context::get('url'); + $notify = Context::get('notify'); + if(!$logged_info || !$url || !$notify) return new Object(-1, 'msg_invalid_request'); + + $output = $this->updateNotifyRead($notify, $logged_info->member_srl); + if(!$output->toBool()) return $output; + + $url = str_replace('&', '&', $url); + header('Location: ' . $url, TRUE, 302); + Context::close(); + exit; + } + + /** + * @brief 익명으로 노티해야 할지 체크하여 반환 + * @return boolean + **/ + function _isAnonymous($source_type, $triggerObj) + { + // 회원번호가 음수 + if($triggerObj->member_srl < 0) return TRUE; + + $module_info = Context::get('module_info'); + + // DX 익명 체크박스 + if($module_info->module == 'beluxe' && $triggerObj->anonymous == 'Y') return TRUE; + + if($source_type == $this->_TYPE_COMMENT) + { + // DX 익명 강제 + if($module_info->module == 'beluxe' && $module_info->use_anonymous == 'Y') return TRUE; + } + + if($source_type == $this->_TYPE_DOCUMENT) + { + // DX 익명 강제 + if($module_info->module == 'beluxe' && $module_info->use_anonymous == 'Y') return TRUE; + } + + return FALSE; + } + + function _insertNotify($args, $anonymous = FALSE) + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + // 비회원 노티 제거 + if($args->member_srl <= 0) return new Object(); + + $logged_info = Context::get('logged_info'); + + if($anonymous == TRUE) + { + // 설정에서 익명 이름이 설정되어 있으면 익명 이름을 설정함. 없을 경우 Anonymous 를 사용한다. + if(!$config->anonymous_name) + { + $anonymous_name = 'Anonymous'; + } + else + { + $anonymous_name = $config->anonymous_name; + } + // 익명 노티 시 회원정보 제거 + $args->target_member_srl = 0; + $args->target_nick_name = $anonymous_name; + $args->target_user_id = $anonymous_name; + $args->target_email_address = $anonymous_name; + } + else if($logged_info) + { + // 익명 노티가 아닐 때 로그인 세션의 회원정보 넣기 + $args->target_member_srl = $logged_info->member_srl; + $args->target_nick_name = $logged_info->nick_name; + $args->target_user_id = $logged_info->user_id; + $args->target_email_address = $logged_info->email_address; + } + else if($args->target_member_srl) + { + $oMemberModel = getModel('member'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($args->target_member_srl); + $args->target_member_srl = $member_info->member_srl; + $args->target_nick_name = $member_info->nick_name; + $args->target_user_id = $member_info->user_id; + $args->target_email_address = $member_info->email_address; + } + else + { + // 비회원 + $args->target_member_srl = 0; + $args->target_user_id = ''; + } + + $output = executeQuery('ncenterlite.insertNotify', $args); + if(!$output->toBool()) + { + return $output; + } + + if($output->toBool()) + { + $trigger_notify = ModuleHandler::triggerCall('ncenterlite._insertNotify', 'after', $args); + if(!$trigger_notify->toBool()) + { + return $trigger_notify; + } + } + + return $output; + } + + /** + * @brief 노티 ID 반환 + **/ + function _getNotifyId($args) + { + return md5(uniqid('') . $args->member_srl . $args->srl . $args->target_srl . $args->type . $args->target_type); + } + + /** + * @brief 멘션 대상 member_srl 목록 반환 + * @return array + **/ + function _getMentionTarget($content) + { + $oNcenterliteModel = getModel('ncenterlite'); + $config = $oNcenterliteModel->getConfig(); + $logged_info = Context::get('logged_info'); + + $list = array(); + + $content = strip_tags($content); + $content = str_replace(' ', ' ', $content); + + // 정규표현식 정리 + $split = array(); + if(in_array('comma', $config->mention_format)) $split[] = ','; + $regx = join('', array('/(^|\s)@([^@\s', join('', $split), ']+)/i')); + + preg_match_all($regx, $content, $matches); + + // '님'문자 이후 제거 + if(in_array('respect', $config->mention_format)) + { + foreach($matches[2] as $idx => $item) + { + $pos = strpos($item, '님'); + if($pos !== false && $pos > 0) + { + $matches[2][$idx] = trim(substr($item, 0, $pos)); + if($logged_info && $logged_info->nick_name == $matches[2][$idx]) unset($matches[2][$idx]); + } + } + } + + $nicks = array_unique($matches[2]); + + $oMemberModel = getModel('member'); + $member_config = $oMemberModel->getMemberConfig(); + + if($config->mention_names == 'id' && $member_config->identifier != 'email_address') + { + foreach($nicks as $user_id) + { + $vars = new stdClass(); + $vars->user_id = $user_id; + $output = executeQuery('ncenterlite.getMemberSrlById', $vars); + if($output->data && $output->data->member_srl) $list[] = $output->data->member_srl; + } + } + else + { + foreach($nicks as $nick_name) + { + $vars = new stdClass(); + $vars->nick_name = $nick_name; + $output = executeQuery('ncenterlite.getMemberSrlByNickName', $vars); + if($output->data && $output->data->member_srl) $list[] = $output->data->member_srl; + } + } + + return $list; + } +} diff --git a/modules/ncenterlite/ncenterlite.mobile.php b/modules/ncenterlite/ncenterlite.mobile.php new file mode 100644 index 000000000..8d8a5a7c0 --- /dev/null +++ b/modules/ncenterlite/ncenterlite.mobile.php @@ -0,0 +1,38 @@ +getConfig(); + $template_path = sprintf("%sm.skins/%s/",$this->module_path, $config->mskin); + if(!is_dir($template_path)||!$config->mskin) + { + $config->skin = 'default'; + $template_path = sprintf("%sm.skins/%s/",$this->module_path, $config->mskin); + } + $this->setTemplatePath($template_path); + + $oLayoutModel = getModel('layout'); + $layout_info = $oLayoutModel->getLayout($config->mlayout_srl); + + if($layout_info) + { + $this->module_info->mlayout_srl = $config->mlayout_srl; + $this->setLayoutPath($layout_info->path); + } + + } + + function dispNcenterliteNotifyList() + { + parent::dispNcenterliteNotifyList(); + } + + function dispNcenterliteUserConfig() + { + parent::dispNcenterliteUserConfig(); + } + +} diff --git a/modules/ncenterlite/ncenterlite.model.php b/modules/ncenterlite/ncenterlite.model.php new file mode 100644 index 000000000..bb4c48c18 --- /dev/null +++ b/modules/ncenterlite/ncenterlite.model.php @@ -0,0 +1,376 @@ +getModuleConfig('ncenterlite'); + if(!$config->use) $config->use = 'Y'; + if(!$config->display_use) $config->display_use = 'Y'; + + if(!$config->mention_names) $config->mention_names = 'nick_name'; + if(!$config->message_notify) $config->message_notify = 'Y'; + if(!$config->mention_format && !is_array($config->mention_format)) $config->mention_format = array('respect'); + if(!is_array($config->mention_format)) $config->mention_format = explode('|@|', $config->mention_format); + if(!$config->document_notify) $config->document_notify = 'direct-comment'; + if(!$config->hide_module_srls) $config->hide_module_srls = array(); + if(!is_array($config->hide_module_srls)) $config->hide_module_srls = explode('|@|', $config->hide_module_srls); + if(!$config->document_read) $config->document_read = 'N'; + if(!$config->voted_format) $config->voted_format = 'N'; + if(!$config->skin) $config->skin = 'default'; + if(!$config->colorset) $config->colorset = 'black'; + + self::$config = $config; + } + + return self::$config; + } + + function getNotifyTypebySrl($notify_srl='') + { + $args = new stdClass(); + $args->notify_type_srl = $notify_srl; + + $output = executeQuery('ncenterlite.getNotifyType',$args); + + return $output; + } + + function getNotifyTypeString($notify_srl='',$notify_args) + { + $this->notify_args = $notify_args; + + $output = $this->getNotifyTypebySrl($notify_srl); + + $this->notify_arguments = explode("|",$output->data->notify_type_args); + $string = preg_replace_callback("/%([^%]*)%/",array($this, 'replaceNotifyType'),$output->data->notify_string); + + return $string; + } + + function replaceNotifyType($match) + { + //if replace string is not at arguments, return + if(!in_array($match[1],$this->notify_arguments)) + { + return $match[0]; + } + + //if replace string is not set, return + if(!isset($this->notify_args->{$match[1]})) + { + return $match[0]; + } + + return $this->notify_args->{$match[1]}; + } + + function isNotifyTypeExistsbySrl($notify_srl='') + { + $args = new stdClass(); + $args->notify_type_srl = $notify_srl; + + $output = executeQuery('ncenterlite.getNotifyType',$args); + + return isset($output->data->notify_type_id); + } + + function insertNotifyType($args) + { + return executeQuery('ncenterlite.insertNotifyType',$args); + } + + function getMemberConfig($member_srl=null) + { + if(!$member_srl) + { + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl; + } + + $args = new stdClass(); + $args->member_srl = $member_srl; + $output = executeQuery('ncenterlite.getUserConfig', $args); + if(!$output->data) return $output->data; + + return $output; + } + + function getAllMemberConfig() + { + $output = executeQueryArray('ncenterlite.getAllUserConfig'); + + return $output; + } + + function getMyNotifyList($member_srl=null, $page=1, $readed='N') + { + global $lang; + + $act = Context::get('act'); + if($act=='dispNcenterliteNotifyList') + { + $output = $this->getMyDispNotifyList($member_srl); + } + else + { + $output = $this->_getMyNotifyList($member_srl, $page, $readed); + } + + $oMemberModel = getModel('member'); + $list = $output->data; + + foreach($list as $k => $v) + { + + $target_member = $v->target_nick_name; + + switch($v->type) + { + case 'D': + $type = $lang->ncenterlite_document; //$type = '글'; + break; + case 'C': + $type = $lang->ncenterlite_comment; //$type = '댓글'; + break; + // 메시지. 쪽지 + case 'E': + $type = $lang->ncenterlite_type_message; //$type = '쪽지'; + break; + } + + switch($v->target_type) + { + case 'C': + $str = sprintf($lang->ncenterlite_commented, $target_member, $type, $v->target_summary); + //$str = sprintf('%s님이 회원님의 %s에 "%s" 댓글을 남겼습니다.', $target_member, $type, $v->target_summary); + break; + case 'A': + $str = sprintf($lang->ncenterlite_commented_board, $target_member, $v->target_browser, $v->target_summary); + //$str = sprintf('%1$s님이 게시판 "%2$s""%3$s"라고 댓글을 남겼습니다.', $target_member, $type, $v->target_summary); + break; + case 'M': + $str = sprintf($lang->ncenterlite_mentioned, $target_member, $v->target_summary, $type); + //$str = sprintf('%s님이 "%s" %s에서 회원님을 언급하였습니다.', $target_member, $v->target_summary, $type); + break; + // 메시지. 쪽지 + case 'E': + if(version_compare(__XE_VERSION__, '1.7.4', '>=')) + { + $str = sprintf($lang->ncenterlite_message_mention,$target_member, $v->target_summary); + } + else + { + $str = sprintf($lang->ncenterlite_message_string, $v->target_summary); + } + break; + case 'T': + $str = sprintf($lang->ncenterlite_test_noti, $target_member); + break; + case 'P': + $str = sprintf($lang->ncenterlite_board, $target_member, $v->target_browser, $v->target_summary); + break; + case 'S': + if($v->target_browser) + { + $str = sprintf($lang->ncenterlite_board, $target_member, $v->target_browser, $v->target_summary); + } + else + { + $str = sprintf($lang->ncenterlite_article, $target_member, $v->target_summary); + } + break; + case 'V': + $str = sprintf($lang->ncenterlite_vote, $target_member, $v->target_summary); + break; + } + + if($v->type=='U') + { + $str = $this->getNotifyTypeString($v->notify_type,unserialize($v->target_body)); + } + + $v->text = $str; + $v->ago = $this->getAgo($v->regdate); + $v->url = getUrl('','act','procNcenterliteRedirect', 'notify', $v->notify, 'url', $v->target_url); + if($v->target_member_srl) + { + $profileImage = $oMemberModel->getProfileImage($v->target_member_srl); + $v->profileImage = $profileImage->src; + } + + $list[$k] = $v; + } + + $output->data = $list; + return $output; + } + + function getMyNotifyListTpl() + { + $logged_info = Context::get('logged_info'); + if(!$logged_info) return new Object(-1, 'msg_not_permitted'); + + $oMemberModel = getModel('member'); + $memberConfig = $oMemberModel->getMemberConfig(); + $page = Context::get('page'); + + $member_srl = $logged_info->member_srl; + $tmp = $this->getMyNotifyList($member_srl, $page); + foreach($tmp->data as $key => $obj) + { + $tmp->data[$key]->url = str_replace('&', '&', $obj->url); + } + + $list->data = $tmp->data; + $list->page = $tmp->page_navigation; + $this->add('list', $list); + $this->add('useProfileImage', $memberConfig->profile_image); + } + + function _getMyNotifyList($member_srl=null, $page=1, $readed='N') + { + if(!$member_srl) + { + $logged_info = Context::get('logged_info'); + if(!$logged_info) return array(); + + $member_srl = $logged_info->member_srl; + } + + $args = new stdClass(); + $args->member_srl = $member_srl; + $args->page = $page ? $page : 1; + if($readed) $args->readed = $readed; + $output = executeQueryArray('ncenterlite.getNotifyList', $args); + if(!$output->data) $output->data = array(); + + return $output; + } + + function getMyDispNotifyList($member_srl) + { + + $logged_info = Context::get('logged_info'); + + $member_srl = $logged_info->member_srl; + + $args = new stdClass(); + $args->page = Context::get('page'); + $args->list_count = '20'; + $args->page_count = '10'; + $args->member_srl = $member_srl; + $output = executeQueryArray('ncenterlite.getDispNotifyList', $args); + if(!$output->data) $output->data = array(); + + return $output; + } + + function getNcenterliteAdminList($member_srl) + { + $logged_info = Context::get('logged_info'); + + $member_srl = $logged_info->member_srl; + + $args = new stdClass(); + $args->page = Context::get('page'); + $args->list_count = '20'; + $args->page_count = '10'; + $output = executeQueryArray('ncenterlite.getAdminNotifyList', $args); + if(!$output->data) $output->data = array(); + + return $output; + } + + function getMemberAdmins() + { + $args = new stdClass(); + $args->is_admin = 'Y'; + $output = executeQueryArray('ncenterlite.getMemberAdmins', $args); + if(!$output->data) $output->data = array(); + + return $output; + } + + function _getNewCount($member_srl=null) + { + if(!$member_srl) + { + $logged_info = Context::get('logged_info'); + if(!$logged_info) return 0; + + $member_srl = $logged_info->member_srl; + } + + $args->member_srl = $member_srl; + $output = executeQuery('ncenterlite.getNotifyNewCount', $args); + if(!$output->data) return 0; + return $output->data->cnt; + } + + + function getColorsetList() + { + $oModuleModel = getModel('module'); + $skin = Context::get('skin'); + + $skin_info = $oModuleModel->loadSkinInfo($this->module_path, $skin); + + for($i=0, $c=count($skin_info->colorset); $i<$c; $i++) + { + $colorset = sprintf('%s|@|%s', $skin_info->colorset[$i]->name, $skin_info->colorset[$i]->title); + $colorset_list[] = $colorset; + } + + if(count($colorset_list)) $colorsets = implode("\n", $colorset_list); + $this->add('colorset_list', $colorsets); + } + + /** + * @brief 주어진 시간이 얼마 전 인지 반환 + * @param string YmdHis + * @return string + **/ + function getAgo($datetime) + { + global $lang; + $lang_type = Context::getLangType(); + + $display = $lang->ncenterlite_date; // array('Year', 'Month', 'Day', 'Hour', 'Minute', 'Second') + + $ago = $lang->ncenterlite_ago; // 'Ago' + + $date = getdate(strtotime(zdate($datetime, 'Y-m-d H:i:s'))); + + $current = getdate(); + $p = array('year', 'mon', 'mday', 'hours', 'minutes', 'seconds'); + $factor = array(0, 12, 30, 24, 60, 60); + + for($i = 0; $i < 6; $i++) + { + if($i > 0) + { + $current[$p[$i]] += $current[$p[$i - 1]] * $factor[$i]; + $date[$p[$i]] += $date[$p[$i - 1]] * $factor[$i]; + } + + if($current[$p[$i]] - $date[$p[$i]] > 1) + { + $value = $current[$p[$i]] - $date[$p[$i]]; + if($lang_type == 'en') + { + return $value . ' ' . $display[$i] . (($value != 1) ? 's' : '') . ' ' . $ago; + } + return $value . $display[$i] . ' ' . $ago; + } + } + + return zdate($datetime, 'Y-m-d'); + } +} diff --git a/modules/ncenterlite/ncenterlite.view.php b/modules/ncenterlite/ncenterlite.view.php new file mode 100644 index 000000000..13c9b4823 --- /dev/null +++ b/modules/ncenterlite/ncenterlite.view.php @@ -0,0 +1,71 @@ +getConfig(); + $template_path = sprintf("%sskins/%s/",$this->module_path, $config->skin); + if(!is_dir($template_path)||!$config->skin) + { + $config->skin = 'default'; + $template_path = sprintf("%sskins/%s/",$this->module_path, $config->skin); + } + $this->setTemplatePath($template_path); + + $oLayoutModel = getModel('layout'); + $layout_info = $oLayoutModel->getLayout($config->layout_srl); + + if($layout_info) + { + $this->module_info->layout_srl = $config->layout_srl; + $this->setLayoutPath($layout_info->path); + } + } + + function dispNcenterliteNotifyList() + { + $oNcenterliteModel = getModel('ncenterlite'); + + $output = $oNcenterliteModel->getMyNotifyList(); + + Context::set('total_count', $output->page_navigation->total_count); + Context::set('total_page', $output->page_navigation->total_page); + Context::set('page', $output->page); + Context::set('ncenterlite_list', $output->data); + Context::set('page_navigation', $output->page_navigation); + + $this->setTemplateFile('NotifyList'); + } + + function dispNcenterliteUserConfig() + { + $oMemberModel = getModel('member'); + $member_srl = Context::get('member_srl'); + $logged_info = Context::get('logged_info'); + if(!$logged_info) return new Object(-1, 'ncenterlite_stop_login_required'); + + if($logged_info->is_admin == 'Y') + { + $member_info = $oMemberModel->getMemberInfoByMemberSrl($member_srl); + } + if($logged_info->is_admin != 'Y' && $member_srl) + { + if($member_srl != $logged_info->member_srl) + { + return new Object(-1, 'ncenterlite_stop_no_permission_other_user'); + } + } + $oNcenterliteModel = getModel('ncenterlite'); + if(!$member_srl) + { + $member_srl = $logged_info->member_srl; + } + $output = $oNcenterliteModel->getMemberConfig($member_srl); + + Context::set('member_info', $member_info); + Context::set('user_config', $output->data); + $this->setTemplateFile('userconfig'); + } +} diff --git a/modules/ncenterlite/queries/deleteNotify.xml b/modules/ncenterlite/queries/deleteNotify.xml new file mode 100644 index 000000000..53f3b42a6 --- /dev/null +++ b/modules/ncenterlite/queries/deleteNotify.xml @@ -0,0 +1,10 @@ + + +
    + + + + + + + diff --git a/modules/ncenterlite/queries/deleteNotifyAll.xml b/modules/ncenterlite/queries/deleteNotifyAll.xml new file mode 100644 index 000000000..f6886172b --- /dev/null +++ b/modules/ncenterlite/queries/deleteNotifyAll.xml @@ -0,0 +1,8 @@ + + +
    + + + + + diff --git a/modules/ncenterlite/queries/deleteNotifyByMemberSrl.xml b/modules/ncenterlite/queries/deleteNotifyByMemberSrl.xml new file mode 100644 index 000000000..35492b021 --- /dev/null +++ b/modules/ncenterlite/queries/deleteNotifyByMemberSrl.xml @@ -0,0 +1,10 @@ + + +
    + + + + + + + diff --git a/modules/ncenterlite/queries/deleteNotifyBySrl.xml b/modules/ncenterlite/queries/deleteNotifyBySrl.xml new file mode 100644 index 000000000..384f992c0 --- /dev/null +++ b/modules/ncenterlite/queries/deleteNotifyBySrl.xml @@ -0,0 +1,10 @@ + + +
    + + + + + + + diff --git a/modules/ncenterlite/queries/deleteNotifyByTargetSrl.xml b/modules/ncenterlite/queries/deleteNotifyByTargetSrl.xml new file mode 100644 index 000000000..202147b77 --- /dev/null +++ b/modules/ncenterlite/queries/deleteNotifyByTargetSrl.xml @@ -0,0 +1,10 @@ + + +
    + + + + + + + diff --git a/modules/ncenterlite/queries/getAdminNotifyList.xml b/modules/ncenterlite/queries/getAdminNotifyList.xml new file mode 100644 index 000000000..d1a12d794 --- /dev/null +++ b/modules/ncenterlite/queries/getAdminNotifyList.xml @@ -0,0 +1,11 @@ + + +
    + + + + + + + + diff --git a/modules/ncenterlite/queries/getAllUserConfig.xml b/modules/ncenterlite/queries/getAllUserConfig.xml new file mode 100644 index 000000000..61bb35180 --- /dev/null +++ b/modules/ncenterlite/queries/getAllUserConfig.xml @@ -0,0 +1,11 @@ + + +
    + + + + + + + + diff --git a/modules/ncenterlite/queries/getCountNewMessage.xml b/modules/ncenterlite/queries/getCountNewMessage.xml new file mode 100644 index 000000000..ba1aa4a84 --- /dev/null +++ b/modules/ncenterlite/queries/getCountNewMessage.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getDispNotifyList.xml b/modules/ncenterlite/queries/getDispNotifyList.xml new file mode 100644 index 000000000..e39b573b2 --- /dev/null +++ b/modules/ncenterlite/queries/getDispNotifyList.xml @@ -0,0 +1,20 @@ + + +
    + + + + + + + + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getMemberAdmins.xml b/modules/ncenterlite/queries/getMemberAdmins.xml new file mode 100644 index 000000000..46a776b5c --- /dev/null +++ b/modules/ncenterlite/queries/getMemberAdmins.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + diff --git a/modules/ncenterlite/queries/getMemberSrlById.xml b/modules/ncenterlite/queries/getMemberSrlById.xml new file mode 100644 index 000000000..2fcec16c1 --- /dev/null +++ b/modules/ncenterlite/queries/getMemberSrlById.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getMemberSrlByNickName.xml b/modules/ncenterlite/queries/getMemberSrlByNickName.xml new file mode 100644 index 000000000..3bb63a178 --- /dev/null +++ b/modules/ncenterlite/queries/getMemberSrlByNickName.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getMemberTotals.xml b/modules/ncenterlite/queries/getMemberTotals.xml new file mode 100644 index 000000000..9036bc858 --- /dev/null +++ b/modules/ncenterlite/queries/getMemberTotals.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + diff --git a/modules/ncenterlite/queries/getNotifyList.xml b/modules/ncenterlite/queries/getNotifyList.xml new file mode 100644 index 000000000..fc8901dde --- /dev/null +++ b/modules/ncenterlite/queries/getNotifyList.xml @@ -0,0 +1,21 @@ + + +
    + + + + + + + + + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getNotifyNewCount.xml b/modules/ncenterlite/queries/getNotifyNewCount.xml new file mode 100644 index 000000000..dd6b55f1f --- /dev/null +++ b/modules/ncenterlite/queries/getNotifyNewCount.xml @@ -0,0 +1,14 @@ + + +
    + + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getNotifyType.xml b/modules/ncenterlite/queries/getNotifyType.xml new file mode 100644 index 000000000..803ce2aba --- /dev/null +++ b/modules/ncenterlite/queries/getNotifyType.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getNotifyTypeByID.xml b/modules/ncenterlite/queries/getNotifyTypeByID.xml new file mode 100644 index 000000000..c2977adfe --- /dev/null +++ b/modules/ncenterlite/queries/getNotifyTypeByID.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getSocialxeCount.xml b/modules/ncenterlite/queries/getSocialxeCount.xml new file mode 100644 index 000000000..33b2c96ae --- /dev/null +++ b/modules/ncenterlite/queries/getSocialxeCount.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/getUserConfig.xml b/modules/ncenterlite/queries/getUserConfig.xml new file mode 100644 index 000000000..2a0ce0f41 --- /dev/null +++ b/modules/ncenterlite/queries/getUserConfig.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/insertNotify.xml b/modules/ncenterlite/queries/insertNotify.xml new file mode 100644 index 000000000..24e96cdd4 --- /dev/null +++ b/modules/ncenterlite/queries/insertNotify.xml @@ -0,0 +1,24 @@ + + +
    + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/ncenterlite/queries/insertNotifyType.xml b/modules/ncenterlite/queries/insertNotifyType.xml new file mode 100644 index 000000000..5f1e1f27e --- /dev/null +++ b/modules/ncenterlite/queries/insertNotifyType.xml @@ -0,0 +1,11 @@ + + +
    + + + + + + + + diff --git a/modules/ncenterlite/queries/insertUserConfig.xml b/modules/ncenterlite/queries/insertUserConfig.xml new file mode 100644 index 000000000..c2bc581e3 --- /dev/null +++ b/modules/ncenterlite/queries/insertUserConfig.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + diff --git a/modules/ncenterlite/queries/updateNotifyReaded.xml b/modules/ncenterlite/queries/updateNotifyReaded.xml new file mode 100644 index 000000000..23f9f24bc --- /dev/null +++ b/modules/ncenterlite/queries/updateNotifyReaded.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + diff --git a/modules/ncenterlite/queries/updateNotifyReadedAll.xml b/modules/ncenterlite/queries/updateNotifyReadedAll.xml new file mode 100644 index 000000000..935cea3bf --- /dev/null +++ b/modules/ncenterlite/queries/updateNotifyReadedAll.xml @@ -0,0 +1,11 @@ + + +
    + + + + + + + + diff --git a/modules/ncenterlite/queries/updateNotifyReadedBySrl.xml b/modules/ncenterlite/queries/updateNotifyReadedBySrl.xml new file mode 100644 index 000000000..2ecae2689 --- /dev/null +++ b/modules/ncenterlite/queries/updateNotifyReadedBySrl.xml @@ -0,0 +1,13 @@ + + +
    + + + + + + + + + + diff --git a/modules/ncenterlite/queries/updateNotifyReadedByTargetSrl.xml b/modules/ncenterlite/queries/updateNotifyReadedByTargetSrl.xml new file mode 100644 index 000000000..842363152 --- /dev/null +++ b/modules/ncenterlite/queries/updateNotifyReadedByTargetSrl.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + diff --git a/modules/ncenterlite/queries/updateNotifyReadedByType.xml b/modules/ncenterlite/queries/updateNotifyReadedByType.xml new file mode 100644 index 000000000..6f6328df3 --- /dev/null +++ b/modules/ncenterlite/queries/updateNotifyReadedByType.xml @@ -0,0 +1,12 @@ + + +
    + + + + + + + + + diff --git a/modules/ncenterlite/queries/updateUserConfig.xml b/modules/ncenterlite/queries/updateUserConfig.xml new file mode 100644 index 000000000..7bfcb07d6 --- /dev/null +++ b/modules/ncenterlite/queries/updateUserConfig.xml @@ -0,0 +1,14 @@ + + +
    + + + + + + + + + + + diff --git a/modules/ncenterlite/ruleset/insertConfig.xml b/modules/ncenterlite/ruleset/insertConfig.xml new file mode 100644 index 000000000..1015ba521 --- /dev/null +++ b/modules/ncenterlite/ruleset/insertConfig.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/modules/ncenterlite/schemas/ncenterlite_notify.xml b/modules/ncenterlite/schemas/ncenterlite_notify.xml new file mode 100644 index 000000000..083da9708 --- /dev/null +++ b/modules/ncenterlite/schemas/ncenterlite_notify.xml @@ -0,0 +1,24 @@ +
    + + + + + + + + + + + + + + + + + + + + + + +
    diff --git a/modules/ncenterlite/schemas/ncenterlite_notify_type.xml b/modules/ncenterlite/schemas/ncenterlite_notify_type.xml new file mode 100644 index 000000000..5beb4bf6e --- /dev/null +++ b/modules/ncenterlite/schemas/ncenterlite_notify_type.xml @@ -0,0 +1,6 @@ + + + + + +
    diff --git a/modules/ncenterlite/schemas/ncenterlite_user_set.xml b/modules/ncenterlite/schemas/ncenterlite_user_set.xml new file mode 100644 index 000000000..0562ed1e4 --- /dev/null +++ b/modules/ncenterlite/schemas/ncenterlite_user_set.xml @@ -0,0 +1,7 @@ + + + + + + +
    diff --git a/modules/ncenterlite/skins/default/NotifyList.html b/modules/ncenterlite/skins/default/NotifyList.html new file mode 100644 index 000000000..dae56b337 --- /dev/null +++ b/modules/ncenterlite/skins/default/NotifyList.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + {@ + $oMemberModel = getModel('member'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($val->member_srl); + } + + + + + + + + + +
    {$lang->ncenterlite_sender}{$lang->ncenterlite_addressee}{$lang->ncenterlite_noti_contents}{$lang->ncenterlite_read}{$lang->date}
    {$val->target_nick_name}{$member_info->nick_name} {$lang->ncenterlite_no_target}{$val->text} + {$lang->ncenterlite_read_y} + {$lang->ncenterlite_read_n} + + {zdate($val->regdate,"Y-m-d")} +
    + {zdate($val->regdate,"H:i:s")} +
    + + + + \ No newline at end of file diff --git a/modules/ncenterlite/skins/default/img/p.png b/modules/ncenterlite/skins/default/img/p.png new file mode 100644 index 0000000000000000000000000000000000000000..44e3d8d1203e991132d400e26b13aa3e469862d9 GIT binary patch literal 7463 zcmV+?9oXWDP)5000;CX+uL$Nkc;* zP;zf(X>4Tx09b{USqC_l(c3@I^SsM=?Y(91y_3E79;v+crq@;^B&(2-LJEl#O;kc8 zC0U75q!3D_fvkKFjsO4qkL$a>b6w{=zxRIbbD#U%_kG6wyZ~_AAcchm!E^uwheVKV zjdb~(U0nI_uK*0_0VCi5j3m$SFdb`abMRlw(lCIwo=>H=Wc_!(|5)g~yu&>KfUHsM z;T7%~jN%&rAWfcOBf_?D4vLw`sDdc2+`_)UaMKp{_=S76dF*ZVP&@$u zfto}j`vO3mN9lY~p1!CY8fpM=3?W|rAt);!ig$VXk-Pxla7TG0gM&l2a2AS1J^o3K z@BfnN@mD5^bLzv)$B5xTa&>COHTCiYu4Lh+Daq_M+qJR2G4po3yA6t4${nr-o;c7oYL zJS?qH%z$D+&u~50Uov6kI6r%*-#q4C-ueb8MxzLJCWqSo;r9!Vvin1ii}Ta7{KFqW zGTrhw4T>{J1HVK}K8S?m+RSun24W-(&TL1X=!`3q0jRHnjbXSG~ix=es>t zgrB|fFZl>v1R4OpWFlNX{)Q&MbU`?8%X~TXqmcv5$9%!*7{L zh8IcS?3YcD5?}~OfDF8W2M7ThfDf1hJ)r-)J_{FBK4(#PX(kAK(65KL`L{mmg;D?2B<{-^&xW{fky z>En!XhBz@K4Y`hVA@`6+NHfw1_>fkl3F$%ZZsC6!h4kAhO$n9St|52mJ zzZ}1*G~zT$z;>HI5Pj$WcLc|6t^NN^N+eo6P)PykJF~xY{9|ch)VfL-U5qAbXVk_R z77PcF!YHB^*THC^K2SobdjHz%cPj;awrv@;J(oc64#mL{-Z2qdfvy)C7EAW`^^4%s zL3c}UNj{ShPiaX$d09Dmu(kL8TH4=ixA#M0MDfdf5G$;cVpc-5T*FYm^2KT@N@EG)iXW%860MpB=n*sk zy@1|8bI@046-Hocmx+%XreX`RRoI)@PINs_ zW0!C^91Bhar-DYi3oZb60GEX;#nt25a09qW+#(*2XU9w6HStz>5H;7SM~BoPV;7YQwdLBb4Sje?Fsh(evhio%N`mLi*?lHxW+AH_7q z8YMlY2&E>aJ!JspVag)PI?7JUSCrqVsHk>OsZrTb`BNoQ6;WNGdPwz#YK5ACTAW&s z+KoDr`Z)Ck>Ne^Z)Zd6iqA*dL=t_(r9w*iiJBZ`NA2f_K(ljPCUNnbjifI~X25COg zQqT&~>d@|`jiW83y-wRlJ5NVJCrqbDN1{uhE2g_eH$t~a&qyyvZ$%$WpGAL>{t^8w z1D-*c!GOVwA%&rWp@U(P5n&Wy)MNByOlGWP>|~r~!ZC?3nJ@(~Winl6>SbDBW?)ui zc4UrWE@r;VJi&sn2(y^51hHhZTw@t#S!LyB)nWB!O=qoR9b{c*<7Crj^JdFnt7m)0 zw#v@OZonSMp3C0IKE{FJ5a+Prh~_xM(aAB-$;7F_>B*VFd5v?F3+58%vgJC!Rl(K6 zwaCrGZNweMeTut-d!C1dN1G>rC!eQ~PqTw4;8M}-@OXGPdVOhn>DYDHd&5=FH{_luT`4vFE!RK)_tO2zucVR0pKKk;Jm zJ_%StS;AkURAN99E2$X2McQ0CNxD(`lZ>E@t4yv;m&{LD zCD|a^O4*lk405J&NpiR4zRHWsd&(Ef4=E583>6M3G%0*hlu-0mJfrwriBZWy>8Mh> z(uT5%GFiD!c}_)8#a*RDWki)p)mk-6^`RP8O;_!ZTC>`Uy0UtN`Ze{>8d4g88W%NY zcZ%%v-dVYGQgeqUN%NfM#4f&F?z_(Jn$Y6cB59Rtz10@b_R_A>p3xE03DCKu^GR1$ zm#lkJcUezeFJ7-rAJI3`&(QBRU@&knIBhU)xWmxbu-0(FNXh7cQJXQ=*vvTBc*KO; z#M7k4WWiL$G~V>S8MT?6*=e)4=HljL^V=4%g{eiJ#Vbo8%Mi;(D_~_}m1i|(En>aj z`i>3G#@eRX=AEsa?LpfvJ4U;Gb{FlI>~-z4?O!^GIz&3OJJLG3Io3EXJLx-}aGG$I zagKL>?84#V@6zOocXf2Fa$VeQu)ARQw40J!s@w1$kv%bc9_{7W8?^WCKH7bxeb?Qw z?oRF(-PcK0q;k@thlxjt$AYJx=Sj~GUfN#yUUS}>-Y2|gd^CMd_{{oh`sVr0`DytT z`px_6`JeXx5?~xq7O)&>6?h?VGsr2ZK9~^f9(*f=AtW&5ekf09Oz1$EL|AIr#D4Yt z1^XAsX5^}HD11+NQv?%w$?b_0jXV9I3$hH>W) zU=Da5Xg|n*@bJMm@jCJ65}*W+g!V%Mhf)qrCmJPIAErDUc=$<@Y|@FO@5xTdw^O)N z5>qCR7#*oirAZ~HjvUoET9$@M^H1wdS4cmV{xicXqdQYJvoLc#%QLI{nB1|VW1Gi) zj`wCOXP?Qz<%Hx6=W69vpP)YxcVaTnBCjEzFFzyyd%?bfM}>-oWhW_5MxLA~GB0X6 zC3q_5)cR?^)6a@^i|b3cO43V~OT9`5&uE{iE8{N9EL%P6fA;w~qjL@A!sUe(xQeKX zca@HnUFTKL*Hm#-Wmaum2)Qs(ZCic6My00aBG<+2TDUf{cJ7kfrT)wMmz(OO>dw`( z)Ms7+S0b;xzv_N<_?p?Z_Uo$G>uw0$D7ndaGot}&h;3MC^lO}Ga%md4WqPaqw#Mz7 zcckxJXy$J&zRP?!yM?kPrDd}Q?P;e60Mqp+~9b<`bnSH+z+P8~RlGn)=oHZx8GoXc^QRy!TZ9 z>4PDYp~ufGpA8H<3_l-n8<}|S^?de4(2FmlQKM@w6JKFpWsK2{6^?U_m%kQ!T|c2b zarce>o1V9JZ(mM&PJWmQpIVL&bXYJ2D3(gDEU&voJzh-@7|90WK;`jDN>&5Y<;H9lW5XV#+E z@#{q!VjH)An*DsW8N9g}Mk158uL1~KVILm=zFt7{78d{*`_VfE&9B_(cR|q02aG-) zA!+CXd>={1*kQGCB6to08wD?=CY2?1ATfvL7VSK}6oWTo1=A#pIBP6hD+ev76IUho zH{P9mDf~|a=ml+sjtM^&1!4-~J`yJ-yQP+8L}hK{66I?Zo+-h~aw>aNGt?T?-|Qr6 zs_t^vO4q)s^Gc7PuWaCHm}AsrJZ=h^37Q*O1XyNU-LQUc^TUqCUctf2G1%#tbDhg$ z*EhQt+?MyO?E~(VBz6xePaQ8??|nYrz9c_8|D6GRfl%N?P;2nnkmOLmFzfxQWWI1h z_~(e>$d;(;=)9PO*q}I<111MG<5d!r52+>U95zdGO7>2PIC3O4|7c~}_4Kxkp3LE_ z*T-g#f6V@xvzWVdVli(qf3*;ElDSCol+kI=;zK1xrFCao%O0N{IyYKAQ88Efy$ZR& zTrFOsd(o{n`cnSoYjp$lU#`+$Q@Cz-Bm8DgLrvrDrhB(KZnxdJ(|q%8eM?PiMO*2; zg7%D#gZBeE?H(w1v30FHoOsmN{orv&&%Gzjz4d)X{ow<8gT%q7Pm70qo+%Auhet-L zpGUpW9>tAzq4A~kYGy2VTw{Fl^|1+!i4Ske-r7zgll4;$Q!CT??Q4=wD@mPsG$*WR5(zCJ{Iez(_3a*L~N}0-)Dz{Xh zsJ&JHz7wa(xl2yVLOVz&Tlb1yzy3!pBh5t~%oG`kG@ zEQbuo6sK5cKNovf{oPt_hI?H1M(-e?Fi;@ODs5 zaB)a>Xi^w?zZ+RQoHu+e;#uV7sMKhW7=u{ZIKczl2ifD96X*`%4lO0VJ=~piHMt-q z`pBMC)1&%n=INx2!2t5kUsMcKK0M!2)qJ75`r}3Z+C7&_F2AT}x?*`X4c)y~Zb~#*MAXf`_9Zv;sF<&8n{*G*cRKX}AlCXgYpU4l<9_ckrId3JvG8V*ExE!KIzx|y>4g2*UrTmD&+M8AtBCKBMNvDW#-kHsxMS|dy2r7^jUK2ym>ln%Aeyjr zs3S4&uy2xnvUm#H5vo*>`u*r++LQG9jI2yjmf|t|vC-pKvNLi5bB#_goOqD8J8wQe zu0W?y_hi~B!s(3SsZ#bc@?~mg)y^rE%T$O~@}Fm~qQ5{{O;JOOMv~?w_sd7?F4sT3 zvVKkUy6cS-HwPM-np|#`+#YGh-W6*xYV~M4bni@iOULW`n-BQA^d9;?%Id!Qc(`Yy zSFCS$|H*;zr}9I`o_!jzdwy$_|7F3L%xjuA(NmeTu^%nJF0I&X`Ty59vaNzs1|Sd3 zGaZkibq;{sMl{d70{|-}0MVbpQ%H^7s6J(8QB~=A0~m7l;8xG}AN( zu4uj;1Jcoq@)BqPgJ^cV4lzJtkT#khhC|2De6SOmgdvz8)`h*`qiB{l2(Kanhy@ad zR3jr80!AGZjH$r9z%pRX(2T4D2jR4FiMVz=7H^8r!9OSP6M_i0DDV_c6x9@~lopid zD3_@$sj8_l)E?9wL?L22@e_?bO*5M51rXP3)HJvm9xha-5S~W!xS-5m=srguI2LkIU8lA9wGBkQB3Vy?#RJkTE>dWb7= zI4M8H{K(SL{B+5T&Mfca%-OGVpX7}dY!>mIRx2?-v+rzd`Ps_R3sN;_FUi(TTs?PV zZzI*My5>Et679U5h7ZeosQW|*mWFaiL|+WNI`jJE+rfA4b1NSiK41C@zRNDDEpM)5 ztTwF;t>4+G_!+jTvb}#m+us}*04ERz@<0n%05=c}5$U~Dm&m`*H&)x;ja-odWpv~bC|M|e8C z3;sO*D?x{lM|ek}L6Ju>Pictye4Waf>IRw#lc|S@YQ(cNR5UR(Gqf(Wy>y0jZS=e7 zTN(5ix*6>l$I#4ll{uS5oaHg=el`}i26h|vcO0>tM9xYsZLTTqTpm+i8s0I!>-@)e z_zUO?vI%|=x+|O`;v=dnCM3=vL6F2s5u|Bk7-Z??2y!d(vkD`M-AebA@2PaFzEu0F zL9p=8O%eOmeU*M4M zc-E=a`HQR4?nJjIdwKRnxc7Moc=~u1c;EEt^_}ut3t$OU2(k~33OOCx7WSUZ8g3X7 z6?q|QG=?tLA};&D^LXKe_(PM2eUs@@x>F<4aOp=gF{UxsI%Pma#M`u-YvLpjMbEjVL5S2(ZoIpbT^a?nceTFQFI#`m8q+x~~q)lUz2 zfE3sTY=94l2Zi7Y=mGB`3P=L7fXGl0)CRqWSzvuQ04U7gR4s#o` zj@7|tU`KFbxWl+H{4RVsfj|f)3{j|2lv2W!0hG_E^r`Mpt5M%0S`**VB+>HIw$ZuK zEz##NNHIKN3}GTNRWs`{zha4H4q8s8g5`vQ2Qtr};GNrOja!=*IDRL;8C?~0Os8OrCXF{(UGxU2Rxc%r`(OaoqC9a08 z4z4M!6|H?)H(4)VU)!+Xxcn3O>HPE3Cba3Wd2!4C;XVrT+s6k)tqTBld~@@gFaY=y z0Bq!LZmyMYZf;bd$;K-H+Jb)l@3MW?&;d~LdJ8=)sfqd5|3Cf*hMK?V*1e)V00009 za7bBm000XU000XU0RWnu7ytkS*-1n}R9J<*nA?uyHVlS8%Ca3h$C;h&c7gW&-=(*G zgrYzTbhneu(7cw4eOTl}@i%5kcf~QbbVI%Ry!QUBD3b^u0$_DU4881$9+mjBq&i^v+{s zYpOZ&=eDL>9T;c>vm(Wzkl&vyx_3Qk9l3j|aZ(&KM(Mf9}jgcvFM{ z8-tJz0XitjmM}tyhEtl_@^II(TGY&{5@RlwsdlN%_8Hn?q z`&Gl|A6B%pa_s2f)!n+m82J6q9j9}TEd;#|ORhX~+@?tCc)#SI3eGDJn>jyyT48N5 z0+91gfV)+TEed}7W6R;x1weYO^wyrq!D{{_`|G`D(Nui?xWw85RYg@9lm8MSRb@G^ z`SD?iF(%x!35O@adGdK*C3M8Y<=F8G_}QfkK{BUa3p3VX2- zi3nwpg7_kkYblISSu^?U>ed5bQsiC;p(+>=j4|o|w`Jf@O5;Sa$v&gXlqSv2$W?97 zDTaTiL<+p7>QW(wYJRhEs9auO=gO4i>JmRD>RJSAudjUkaxtkm^l~GmA+Dsox7k z21V!2;eAH@7wD7HM79vYrQ0n+@090r|86kROy7G>=WdK3kGu>eWe}5cIE7e4dekdl zw@13pjfbx{WPd!f+n+JUjLQGG5t8ovC^8ZUo*2>0i{q)|)V&>@FusN^y+3qxolnIq z^}eZIAVbkhoH3(kL`MoEbiLm zx$|^5vp<|EOg6&aVjjtKOU(dBpNc}*?Vs80pI_V_XB_X9zrUU6dPia8^5!v>o{K5W zRQJpeU3z9%@b4gRK71t#yy9pSJDPXpW`8Prkt4-0O1#!EMFcZMXynl~=qsC}c94um z-efgLRcY#ySrumZX#$7qV2m(tOG;~QBRNrWMqu(yF}D&M+Q4oF?$-@%Tk?{`_c4IY zvSHp;aG9s%pH`89$3INV$hY^^!B{IBCzCPC|r7f7xN;>E1U6_I6-^kX0 zOv&e&j8H0psLpu=Vcu4J+_bc_>J37ca l%5XU^6|Cd|?`v-#SNw`M^J`4Z=002ovPDHLkV1i5TjzRzc literal 0 HcmV?d00001 diff --git a/modules/ncenterlite/skins/default/ncenterlite.black.css b/modules/ncenterlite/skins/default/ncenterlite.black.css new file mode 100644 index 000000000..6f2596f91 --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.black.css @@ -0,0 +1,15 @@ +#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95; } +#nc_container a { color:#B0B0B0; } +#nc_container a:hover { color:#B0B0B0; } +#nc_container strong { color:#F3F3F3; } + +#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#555; } +#nc_container .list li a:hover { background-color:#555; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list .more { background: #555; } +#nc_container a.readall { display:none; color:#555; color:#D83722;} + +#nc_container a.notify { color:white; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/skins/default/ncenterlite.blacknoprofile.css b/modules/ncenterlite/skins/default/ncenterlite.blacknoprofile.css new file mode 100644 index 000000000..88c94a4a4 --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.blacknoprofile.css @@ -0,0 +1,17 @@ +#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95; } +#nc_container a { color:#B0B0B0; } +#nc_container a:hover { color:#B0B0B0; } +#nc_container strong { color:#F3F3F3; } + +#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#555; } +#nc_container .list li a:hover { background-color:#555; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list .more { background: #555; } +#nc_container a.readall { display:none; color:#555; color:#D83722;} + +#nc_container a.notify { color:white; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/skins/default/ncenterlite.css b/modules/ncenterlite/skins/default/ncenterlite.css new file mode 100644 index 000000000..60df8e548 --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.css @@ -0,0 +1,185 @@ +#nc_container { + z-index:99; + position:fixed; + top:0; + left:0; + margin:0; + padding:0; + width:100%; + height:30px; + border-bottom:1px solid; + font-size:12px; + line-height:15px; +} + +.ncenterlite_block { + height:28px; +} + +#nc_container a { + padding:0; + font-size:12px; + text-decoration:none; +} + +#nc_container ul.nc_memu { + display:block; + margin:0; + padding:4px; + list-style:none; + line-height:20px; +} + +#nc_container ul:after { + content:""; + display:block; + clear:both; +} + +#nc_container ul.nc_memu li { + display:inline-block; + padding:0 5px; + height:20px; + width:auto; + background:transparent!important; +} + +#nc_container ul.nc_memu li.fLeft { + float:left; +} + +#nc_container ul.nc_memu li.fRight { + float:right; +} + +#nc_container ul.nc_memu li a.notify { + display:block; + float:left; +} + +#nc_container a.close { + display:block; +} + +#nc_container .nc_profile img { + width:20px; + height:20px; + vertical-align:top; +} + +#nc_container a.notify .num { + padding:1px 2px; + border:0; + border-radius:3px; + -webkit-border-radius:3px; + -moz-border-radius:3px; + font-size:12px; + font-weight:700; + font-family:Gulim,"lucida grande",tahoma,verdana,arial,sans-serif; +} + +#nc_container .list { + display:none; + position:absolute; + top:30px; + left:0; + max-width:330px; + width:330px; + box-sizing:border-box; + -moz-box-sizing:border-box; + -webkit-box-sizing:border-box; + -o-box-sizing:border-box; +} + +#nc_container a.readall { + display:none; + float:left; + margin:0 4px; + font-size:11px; + font-weight:700; +} + +#nc_container .listscroll { + overflow-y:auto; + overflow-x:hidden; +} + +#nc_container .list ul { + overflow:hidden; + margin:-1px 0; + padding:0; + list-style:none; +} + +#nc_container .list li { + margin:-1px 0; + border:1px solid #555; + border-width:1px 0; +} + +#nc_container .list li img { + float:left; + margin-right:5px; + width:45px; + height:45px; + border:0; +} + +#nc_container .list li a { + display:block; + overflow:hidden; + padding:10px; + font-size:12px; +} + +#nc_container .list span.ago { + display:block; + font-size:10px; +} + +#nc_container .list .more { + display:block; + padding:10px; + text-align:center; +} + +#nc_container ~ .navbar.navbar-fixed-top { + top:28px; +} + +#nc_container a:hover,#nc_container .list li a:hover,#nc_container .list .more:hover { + text-decoration:none; +} + +@media only screen and max-device-width 480px { + #nc_container { + position:relative; + height:auto; + } + + #nc_container .list { + top:2px; + position:relative; + } + + #nc_container .list ul { + display:block; + position:relative; + } + + #nc_container ul.nc_memu:after { + content:""; + display:block; + visibility:hidden; + height:0; + clear:both; + } + + #nc_container .listscroll { + overflow:visible; + } + + .ncenterlite_block { + display:none; + } +} diff --git a/modules/ncenterlite/skins/default/ncenterlite.gray.css b/modules/ncenterlite/skins/default/ncenterlite.gray.css new file mode 100644 index 000000000..4d167ea21 --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.gray.css @@ -0,0 +1,16 @@ +#nc_container { border-bottom-color:#C0C0C0; background-color:#efefef; color:#666; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#666; } +#nc_container a.notify strong { color:#FC2772; } +#nc_container .list { background-color:#efefef; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#ddd; } +#nc_container .list li a:hover { background-color: #ddd; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify sup.num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #ddd; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/skins/default/ncenterlite.graynoprofile.css b/modules/ncenterlite/skins/default/ncenterlite.graynoprofile.css new file mode 100644 index 000000000..d8704070b --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.graynoprofile.css @@ -0,0 +1,18 @@ +#nc_container { border-bottom-color:#C0C0C0; background-color:#efefef; color:#666; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#666; } +#nc_container a.notify strong { color:#FC2772; } +#nc_container .list { background-color:#efefef; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#ddd; } +#nc_container .list li a:hover { background-color: #ddd; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify sup.num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #ddd; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/skins/default/ncenterlite.html b/modules/ncenterlite/skins/default/ncenterlite.html new file mode 100644 index 000000000..39d6ebe10 --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.html @@ -0,0 +1,125 @@ + +
    + + diff --git a/modules/ncenterlite/skins/default/ncenterlite.mobile.css b/modules/ncenterlite/skins/default/ncenterlite.mobile.css new file mode 100644 index 000000000..ef3125177 --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.mobile.css @@ -0,0 +1,12 @@ +#nc_container { height:auto; position:relative; } +#nc_container .list { top:2px; position:relative; } +#nc_container .list ul { display:block; position:relative; } +#nc_container ul.nc_memu:after { + content: ""; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +#nc_container .listscroll { overflow: visible; } +.ncenterlite_block { display:none; } diff --git a/modules/ncenterlite/skins/default/ncenterlite.white.css b/modules/ncenterlite/skins/default/ncenterlite.white.css new file mode 100644 index 000000000..c3fd4444a --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.white.css @@ -0,0 +1,16 @@ +#nc_container { border:1px solid #efefef; background-color:#fff; color:#000; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#000; } +#nc_container a.notify strong { color:#F60; } +#nc_container .list { border:1px solid #efefef; background-color:#fff; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#eee; } +#nc_container .list li a:hover { background-color: #eee; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify .num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #eee; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/skins/default/ncenterlite.whitenoprofile.css b/modules/ncenterlite/skins/default/ncenterlite.whitenoprofile.css new file mode 100644 index 000000000..69342bd1d --- /dev/null +++ b/modules/ncenterlite/skins/default/ncenterlite.whitenoprofile.css @@ -0,0 +1,18 @@ +#nc_container { border:1px solid #efefef; background-color:#fff; color:#000; opacity:0.95; } +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#000; } +#nc_container a.notify strong { color:#F60; } +#nc_container .list { border:1px solid #efefef; background-color:#fff; filter:alpha(opacity=97); opacity:0.97; -moz-opacity:0.97; } +#nc_container .list li { border-color:#eee; } +#nc_container .list li a:hover { background-color: #eee; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify .num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #eee; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/skins/default/skin.xml b/modules/ncenterlite/skins/default/skin.xml new file mode 100644 index 000000000..78ac42418 --- /dev/null +++ b/modules/ncenterlite/skins/default/skin.xml @@ -0,0 +1,40 @@ + + + XE 알림센터 Lite 기본스킨 + XE Notification Center Lite Default Skin + 1.1.1 + 2013-03-21 + + + XE Public + XE Public + + + + + 검은색 + Black + + + 회색 + Gray + + + 흰색 + White + + + + 검은색(no profile) + Black (no profile) + + + 회색(no profile) + Gray (no profile) + + + 흰색(no profile) + White (no profile) + + + diff --git a/modules/ncenterlite/skins/default/userconfig.html b/modules/ncenterlite/skins/default/userconfig.html new file mode 100644 index 000000000..fffbfeaeb --- /dev/null +++ b/modules/ncenterlite/skins/default/userconfig.html @@ -0,0 +1,68 @@ + + +
    + +
    +

    {$XE_VALIDATOR_MESSAGE}

    +
    + + +
    + + + + +
    +

    {@$user_str = $member_info->nick_name} + {@$user_str = $logged_info->nick_name} + {@$title_str = Context::getLang('ncenterlite_userconfig_title')} + {sprintf($title_str, $user_str)} +

    + +

    {$lang->ncenterlite_userconfig_about} ({$lang->ncenterlite_userconfig_about_warning})

    +
    + +
    + + +

    {$lang->ncenterlite_comment_noti_about}

    +
    +
    +
    + +
    + + +

    {$lang->ncenterlite_mention_noti_about}

    +
    +
    +
    + +
    + + +

    {$lang->ncenterlite_message_noti_about}

    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/modules/ncenterlite/skins/default_bottom/NotifyList.html b/modules/ncenterlite/skins/default_bottom/NotifyList.html new file mode 100644 index 000000000..dae56b337 --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/NotifyList.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + {@ + $oMemberModel = getModel('member'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($val->member_srl); + } + + + + + + + + + +
    {$lang->ncenterlite_sender}{$lang->ncenterlite_addressee}{$lang->ncenterlite_noti_contents}{$lang->ncenterlite_read}{$lang->date}
    {$val->target_nick_name}{$member_info->nick_name} {$lang->ncenterlite_no_target}{$val->text} + {$lang->ncenterlite_read_y} + {$lang->ncenterlite_read_n} + + {zdate($val->regdate,"Y-m-d")} +
    + {zdate($val->regdate,"H:i:s")} +
    + + + + \ No newline at end of file diff --git a/modules/ncenterlite/skins/default_bottom/img/p.png b/modules/ncenterlite/skins/default_bottom/img/p.png new file mode 100644 index 0000000000000000000000000000000000000000..44e3d8d1203e991132d400e26b13aa3e469862d9 GIT binary patch literal 7463 zcmV+?9oXWDP)5000;CX+uL$Nkc;* zP;zf(X>4Tx09b{USqC_l(c3@I^SsM=?Y(91y_3E79;v+crq@;^B&(2-LJEl#O;kc8 zC0U75q!3D_fvkKFjsO4qkL$a>b6w{=zxRIbbD#U%_kG6wyZ~_AAcchm!E^uwheVKV zjdb~(U0nI_uK*0_0VCi5j3m$SFdb`abMRlw(lCIwo=>H=Wc_!(|5)g~yu&>KfUHsM z;T7%~jN%&rAWfcOBf_?D4vLw`sDdc2+`_)UaMKp{_=S76dF*ZVP&@$u zfto}j`vO3mN9lY~p1!CY8fpM=3?W|rAt);!ig$VXk-Pxla7TG0gM&l2a2AS1J^o3K z@BfnN@mD5^bLzv)$B5xTa&>COHTCiYu4Lh+Daq_M+qJR2G4po3yA6t4${nr-o;c7oYL zJS?qH%z$D+&u~50Uov6kI6r%*-#q4C-ueb8MxzLJCWqSo;r9!Vvin1ii}Ta7{KFqW zGTrhw4T>{J1HVK}K8S?m+RSun24W-(&TL1X=!`3q0jRHnjbXSG~ix=es>t zgrB|fFZl>v1R4OpWFlNX{)Q&MbU`?8%X~TXqmcv5$9%!*7{L zh8IcS?3YcD5?}~OfDF8W2M7ThfDf1hJ)r-)J_{FBK4(#PX(kAK(65KL`L{mmg;D?2B<{-^&xW{fky z>En!XhBz@K4Y`hVA@`6+NHfw1_>fkl3F$%ZZsC6!h4kAhO$n9St|52mJ zzZ}1*G~zT$z;>HI5Pj$WcLc|6t^NN^N+eo6P)PykJF~xY{9|ch)VfL-U5qAbXVk_R z77PcF!YHB^*THC^K2SobdjHz%cPj;awrv@;J(oc64#mL{-Z2qdfvy)C7EAW`^^4%s zL3c}UNj{ShPiaX$d09Dmu(kL8TH4=ixA#M0MDfdf5G$;cVpc-5T*FYm^2KT@N@EG)iXW%860MpB=n*sk zy@1|8bI@046-Hocmx+%XreX`RRoI)@PINs_ zW0!C^91Bhar-DYi3oZb60GEX;#nt25a09qW+#(*2XU9w6HStz>5H;7SM~BoPV;7YQwdLBb4Sje?Fsh(evhio%N`mLi*?lHxW+AH_7q z8YMlY2&E>aJ!JspVag)PI?7JUSCrqVsHk>OsZrTb`BNoQ6;WNGdPwz#YK5ACTAW&s z+KoDr`Z)Ck>Ne^Z)Zd6iqA*dL=t_(r9w*iiJBZ`NA2f_K(ljPCUNnbjifI~X25COg zQqT&~>d@|`jiW83y-wRlJ5NVJCrqbDN1{uhE2g_eH$t~a&qyyvZ$%$WpGAL>{t^8w z1D-*c!GOVwA%&rWp@U(P5n&Wy)MNByOlGWP>|~r~!ZC?3nJ@(~Winl6>SbDBW?)ui zc4UrWE@r;VJi&sn2(y^51hHhZTw@t#S!LyB)nWB!O=qoR9b{c*<7Crj^JdFnt7m)0 zw#v@OZonSMp3C0IKE{FJ5a+Prh~_xM(aAB-$;7F_>B*VFd5v?F3+58%vgJC!Rl(K6 zwaCrGZNweMeTut-d!C1dN1G>rC!eQ~PqTw4;8M}-@OXGPdVOhn>DYDHd&5=FH{_luT`4vFE!RK)_tO2zucVR0pKKk;Jm zJ_%StS;AkURAN99E2$X2McQ0CNxD(`lZ>E@t4yv;m&{LD zCD|a^O4*lk405J&NpiR4zRHWsd&(Ef4=E583>6M3G%0*hlu-0mJfrwriBZWy>8Mh> z(uT5%GFiD!c}_)8#a*RDWki)p)mk-6^`RP8O;_!ZTC>`Uy0UtN`Ze{>8d4g88W%NY zcZ%%v-dVYGQgeqUN%NfM#4f&F?z_(Jn$Y6cB59Rtz10@b_R_A>p3xE03DCKu^GR1$ zm#lkJcUezeFJ7-rAJI3`&(QBRU@&knIBhU)xWmxbu-0(FNXh7cQJXQ=*vvTBc*KO; z#M7k4WWiL$G~V>S8MT?6*=e)4=HljL^V=4%g{eiJ#Vbo8%Mi;(D_~_}m1i|(En>aj z`i>3G#@eRX=AEsa?LpfvJ4U;Gb{FlI>~-z4?O!^GIz&3OJJLG3Io3EXJLx-}aGG$I zagKL>?84#V@6zOocXf2Fa$VeQu)ARQw40J!s@w1$kv%bc9_{7W8?^WCKH7bxeb?Qw z?oRF(-PcK0q;k@thlxjt$AYJx=Sj~GUfN#yUUS}>-Y2|gd^CMd_{{oh`sVr0`DytT z`px_6`JeXx5?~xq7O)&>6?h?VGsr2ZK9~^f9(*f=AtW&5ekf09Oz1$EL|AIr#D4Yt z1^XAsX5^}HD11+NQv?%w$?b_0jXV9I3$hH>W) zU=Da5Xg|n*@bJMm@jCJ65}*W+g!V%Mhf)qrCmJPIAErDUc=$<@Y|@FO@5xTdw^O)N z5>qCR7#*oirAZ~HjvUoET9$@M^H1wdS4cmV{xicXqdQYJvoLc#%QLI{nB1|VW1Gi) zj`wCOXP?Qz<%Hx6=W69vpP)YxcVaTnBCjEzFFzyyd%?bfM}>-oWhW_5MxLA~GB0X6 zC3q_5)cR?^)6a@^i|b3cO43V~OT9`5&uE{iE8{N9EL%P6fA;w~qjL@A!sUe(xQeKX zca@HnUFTKL*Hm#-Wmaum2)Qs(ZCic6My00aBG<+2TDUf{cJ7kfrT)wMmz(OO>dw`( z)Ms7+S0b;xzv_N<_?p?Z_Uo$G>uw0$D7ndaGot}&h;3MC^lO}Ga%md4WqPaqw#Mz7 zcckxJXy$J&zRP?!yM?kPrDd}Q?P;e60Mqp+~9b<`bnSH+z+P8~RlGn)=oHZx8GoXc^QRy!TZ9 z>4PDYp~ufGpA8H<3_l-n8<}|S^?de4(2FmlQKM@w6JKFpWsK2{6^?U_m%kQ!T|c2b zarce>o1V9JZ(mM&PJWmQpIVL&bXYJ2D3(gDEU&voJzh-@7|90WK;`jDN>&5Y<;H9lW5XV#+E z@#{q!VjH)An*DsW8N9g}Mk158uL1~KVILm=zFt7{78d{*`_VfE&9B_(cR|q02aG-) zA!+CXd>={1*kQGCB6to08wD?=CY2?1ATfvL7VSK}6oWTo1=A#pIBP6hD+ev76IUho zH{P9mDf~|a=ml+sjtM^&1!4-~J`yJ-yQP+8L}hK{66I?Zo+-h~aw>aNGt?T?-|Qr6 zs_t^vO4q)s^Gc7PuWaCHm}AsrJZ=h^37Q*O1XyNU-LQUc^TUqCUctf2G1%#tbDhg$ z*EhQt+?MyO?E~(VBz6xePaQ8??|nYrz9c_8|D6GRfl%N?P;2nnkmOLmFzfxQWWI1h z_~(e>$d;(;=)9PO*q}I<111MG<5d!r52+>U95zdGO7>2PIC3O4|7c~}_4Kxkp3LE_ z*T-g#f6V@xvzWVdVli(qf3*;ElDSCol+kI=;zK1xrFCao%O0N{IyYKAQ88Efy$ZR& zTrFOsd(o{n`cnSoYjp$lU#`+$Q@Cz-Bm8DgLrvrDrhB(KZnxdJ(|q%8eM?PiMO*2; zg7%D#gZBeE?H(w1v30FHoOsmN{orv&&%Gzjz4d)X{ow<8gT%q7Pm70qo+%Auhet-L zpGUpW9>tAzq4A~kYGy2VTw{Fl^|1+!i4Ske-r7zgll4;$Q!CT??Q4=wD@mPsG$*WR5(zCJ{Iez(_3a*L~N}0-)Dz{Xh zsJ&JHz7wa(xl2yVLOVz&Tlb1yzy3!pBh5t~%oG`kG@ zEQbuo6sK5cKNovf{oPt_hI?H1M(-e?Fi;@ODs5 zaB)a>Xi^w?zZ+RQoHu+e;#uV7sMKhW7=u{ZIKczl2ifD96X*`%4lO0VJ=~piHMt-q z`pBMC)1&%n=INx2!2t5kUsMcKK0M!2)qJ75`r}3Z+C7&_F2AT}x?*`X4c)y~Zb~#*MAXf`_9Zv;sF<&8n{*G*cRKX}AlCXgYpU4l<9_ckrId3JvG8V*ExE!KIzx|y>4g2*UrTmD&+M8AtBCKBMNvDW#-kHsxMS|dy2r7^jUK2ym>ln%Aeyjr zs3S4&uy2xnvUm#H5vo*>`u*r++LQG9jI2yjmf|t|vC-pKvNLi5bB#_goOqD8J8wQe zu0W?y_hi~B!s(3SsZ#bc@?~mg)y^rE%T$O~@}Fm~qQ5{{O;JOOMv~?w_sd7?F4sT3 zvVKkUy6cS-HwPM-np|#`+#YGh-W6*xYV~M4bni@iOULW`n-BQA^d9;?%Id!Qc(`Yy zSFCS$|H*;zr}9I`o_!jzdwy$_|7F3L%xjuA(NmeTu^%nJF0I&X`Ty59vaNzs1|Sd3 zGaZkibq;{sMl{d70{|-}0MVbpQ%H^7s6J(8QB~=A0~m7l;8xG}AN( zu4uj;1Jcoq@)BqPgJ^cV4lzJtkT#khhC|2De6SOmgdvz8)`h*`qiB{l2(Kanhy@ad zR3jr80!AGZjH$r9z%pRX(2T4D2jR4FiMVz=7H^8r!9OSP6M_i0DDV_c6x9@~lopid zD3_@$sj8_l)E?9wL?L22@e_?bO*5M51rXP3)HJvm9xha-5S~W!xS-5m=srguI2LkIU8lA9wGBkQB3Vy?#RJkTE>dWb7= zI4M8H{K(SL{B+5T&Mfca%-OGVpX7}dY!>mIRx2?-v+rzd`Ps_R3sN;_FUi(TTs?PV zZzI*My5>Et679U5h7ZeosQW|*mWFaiL|+WNI`jJE+rfA4b1NSiK41C@zRNDDEpM)5 ztTwF;t>4+G_!+jTvb}#m+us}*04ERz@<0n%05=c}5$U~Dm&m`*H&)x;ja-odWpv~bC|M|e8C z3;sO*D?x{lM|ek}L6Ju>Pictye4Waf>IRw#lc|S@YQ(cNR5UR(Gqf(Wy>y0jZS=e7 zTN(5ix*6>l$I#4ll{uS5oaHg=el`}i26h|vcO0>tM9xYsZLTTqTpm+i8s0I!>-@)e z_zUO?vI%|=x+|O`;v=dnCM3=vL6F2s5u|Bk7-Z??2y!d(vkD`M-AebA@2PaFzEu0F zL9p=8O%eOmeU*M4M zc-E=a`HQR4?nJjIdwKRnxc7Moc=~u1c;EEt^_}ut3t$OU2(k~33OOCx7WSUZ8g3X7 z6?q|QG=?tLA};&D^LXKe_(PM2eUs@@x>F<4aOp=gF{UxsI%Pma#M`u-YvLpjMbEjVL5S2(ZoIpbT^a?nceTFQFI#`m8q+x~~q)lUz2 zfE3sTY=94l2Zi7Y=mGB`3P=L7fXGl0)CRqWSzvuQ04U7gR4s#o` zj@7|tU`KFbxWl+H{4RVsfj|f)3{j|2lv2W!0hG_E^r`Mpt5M%0S`**VB+>HIw$ZuK zEz##NNHIKN3}GTNRWs`{zha4H4q8s8g5`vQ2Qtr};GNrOja!=*IDRL;8C?~0Os8OrCXF{(UGxU2Rxc%r`(OaoqC9a08 z4z4M!6|H?)H(4)VU)!+Xxcn3O>HPE3Cba3Wd2!4C;XVrT+s6k)tqTBld~@@gFaY=y z0Bq!LZmyMYZf;bd$;K-H+Jb)l@3MW?&;d~LdJ8=)sfqd5|3Cf*hMK?V*1e)V00009 za7bBm000XU000XU0RWnu7ytkS*-1n}R9J<*nA?uyHVlS8%Ca3h$C;h&c7gW&-=(*G zgrYzTbhneu(7cw4eOTl}@i%5kcf~QbbVI%Ry!QUBD3b^u0$_DU4881$9+mjBq&i^v+{s zYpOZ&=eDL>9T;c>vm(Wzkl&vyx_3Qk9l3j|aZ(&KM(Mf9}jgcvFM{ z8-tJz0XitjmM}tyhEtl_@^II(TGY&{5@RlwsdlN%_8Hn?q z`&Gl|A6B%pa_s2f)!n+m82J6q9j9}TEd;#|ORhX~+@?tCc)#SI3eGDJn>jyyT48N5 z0+91gfV)+TEed}7W6R;x1weYO^wyrq!D{{_`|G`D(Nui?xWw85RYg@9lm8MSRb@G^ z`SD?iF(%x!35O@adGdK*C3M8Y<=F8G_}QfkK{BUa3p3VX2- zi3nwpg7_kkYblISSu^?U>ed5bQsiC;p(+>=j4|o|w`Jf@O5;Sa$v&gXlqSv2$W?97 zDTaTiL<+p7>QW(wYJRhEs9auO=gO4i>JmRD>RJSAudjUkaxtkm^l~GmA+Dsox7k z21V!2;eAH@7wD7HM79vYrQ0n+@090r|86kROy7G>=WdK3kGu>eWe}5cIE7e4dekdl zw@13pjfbx{WPd!f+n+JUjLQGG5t8ovC^8ZUo*2>0i{q)|)V&>@FusN^y+3qxolnIq z^}eZIAVbkhoH3(kL`MoEbiLm zx$|^5vp<|EOg6&aVjjtKOU(dBpNc}*?Vs80pI_V_XB_X9zrUU6dPia8^5!v>o{K5W zRQJpeU3z9%@b4gRK71t#yy9pSJDPXpW`8Prkt4-0O1#!EMFcZMXynl~=qsC}c94um z-efgLRcY#ySrumZX#$7qV2m(tOG;~QBRNrWMqu(yF}D&M+Q4oF?$-@%Tk?{`_c4IY zvSHp;aG9s%pH`89$3INV$hY^^!B{IBCzCPC|r7f7xN;>E1U6_I6-^kX0 zOv&e&j8H0psLpu=Vcu4J+_bc_>J37ca l%5XU^6|Cd|?`v-#SNw`M^J`4Z=002ovPDHLkV1i5TjzRzc literal 0 HcmV?d00001 diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.black.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.black.css new file mode 100644 index 000000000..e0eb7f2ac --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.black.css @@ -0,0 +1,15 @@ +#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95;} +#nc_container a { color:#B0B0B0; } +#nc_container a:hover { color:#B0B0B0; } +#nc_container strong { color:#F3F3F3; } + +#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#555; } +#nc_container .list li a:hover { background-color:#555; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list .more { background: #555; } +#nc_container a.readall { display:none; color:#555; color:#D83722;} + +#nc_container a.notify { color:white; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.blacknoprofile.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.blacknoprofile.css new file mode 100644 index 000000000..3db203843 --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.blacknoprofile.css @@ -0,0 +1,17 @@ +#nc_container { border-bottom-color:#555; background-color:#333; color:#B0B0B0; opacity:0.95;} +#nc_container a { color:#B0B0B0; } +#nc_container a:hover { color:#B0B0B0; } +#nc_container strong { color:#F3F3F3; } + +#nc_container .list { background-color:#333; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#555; } +#nc_container .list li a:hover { background-color:#555; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list .more { background: #555; } +#nc_container a.readall { display:none; color:#555; color:#D83722;} + +#nc_container a.notify { color:white; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.css new file mode 100644 index 000000000..d22532260 --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.css @@ -0,0 +1,177 @@ +#nc_container { + z-index:99; + position:fixed; + bottom:0; + right:0; + margin:0; + padding:0; + width:330px; + height:50px; + border-bottom:1px solid; + font-size:12px; + line-height:15px; +} + +#nc_container a { + padding:0; + font-size:12px; + text-decoration:none; +} + +#nc_container ul.nc_memu { + display:block; + margin:0; + padding:4px; + list-style:none; + line-height:20px; +} + +#nc_container ul:after { + content:""; + display:block; + clear:both; +} + +#nc_container ul.nc_memu li { + display:inline-block; + padding:0 5px; + height:20px; + width:auto; + background:transparent!important; +} + +#nc_container ul.nc_memu li.fLeft { + float:left; +} + +#nc_container ul.nc_memu li.fRight { + float:right; +} + +#nc_container ul.nc_memu li a.notify { + display:block; + float:left; +} + +#nc_container a.close { + display:block; +} + +#nc_container .nc_profile img { + width:20px; + height:20px; + vertical-align:top; +} + +#nc_container a.notify .num { + padding:1px 2px; + border:0; + border-radius:3px; + -webkit-border-radius:3px; + -moz-border-radius:3px; + font-size:12px; + font-weight:700; + font-family:Gulim,"lucida grande",tahoma,verdana,arial,sans-serif; +} + +#nc_container .list { + display:none; + position:absolute; + left:0; + bottom:50px; + max-width:330px; + width:330px; + box-sizing:border-box; + -moz-box-sizing:border-box; + -webkit-box-sizing:border-box; + -o-box-sizing:border-box; +} + +#nc_container a.readall { + display:none; + float:left; + margin:0 4px; + font-size:11px; + font-weight:700; +} + +#nc_container .listscroll { + overflow-y:auto; + overflow-x:hidden; +} + +#nc_container .list ul { + overflow:hidden; + margin:-1px 0; + padding:0; + list-style:none; +} + +#nc_container .list li { + margin:-1px 0; + border:1px solid #555; + border-width:1px 0; +} + +#nc_container .list li img { + float:left; + margin-right:5px; + width:45px; + height:45px; + border:0; +} + +#nc_container .list li a { + display:block; + overflow:hidden; + padding:10px; + font-size:12px; +} + +#nc_container .list span.ago { + display:block; + font-size:10px; +} + +#nc_container .list .more { + display:block; + padding:10px; + text-align:center; +} + +#nc_container a:hover,#nc_container .list li a:hover,#nc_container .list .more:hover { + text-decoration:none; +} + +@media only screen and max-device-width 480px { + #nc_container { + position:relative; + height:auto; + } + + #nc_container .list { + top:2px; + position:relative; + } + + #nc_container .list ul { + display:block; + position:relative; + } + + #nc_container ul.nc_memu:after { + content:""; + display:block; + visibility:hidden; + height:0; + clear:both; + } + + #nc_container .listscroll { + overflow:visible; + } + + .ncenterlite_block { + display:none; + } +} diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.gray.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.gray.css new file mode 100644 index 000000000..91f3e6898 --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.gray.css @@ -0,0 +1,16 @@ +#nc_container { border-bottom-color:#C0C0C0; background-color:#efefef; color:#666; opacity:0.95;} +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#666; } +#nc_container a.notify strong { color:#FC2772; } +#nc_container .list { background-color:#efefef; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#ddd; } +#nc_container .list li a:hover { background-color: #ddd; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify sup.num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #ddd; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.graynoprofile.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.graynoprofile.css new file mode 100644 index 000000000..b7a8c5d5a --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.graynoprofile.css @@ -0,0 +1,18 @@ +#nc_container { border-bottom-color:#C0C0C0; background-color:#efefef; color:#666; opacity:0.95;} +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#666; } +#nc_container a.notify strong { color:#FC2772; } +#nc_container .list { background-color:#efefef; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#ddd; } +#nc_container .list li a:hover { background-color: #ddd; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify sup.num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #ddd; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.html b/modules/ncenterlite/skins/default_bottom/ncenterlite.html new file mode 100644 index 000000000..b4a5b5703 --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.html @@ -0,0 +1,124 @@ + + + diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.mobile.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.mobile.css new file mode 100644 index 000000000..c221ae4da --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.mobile.css @@ -0,0 +1,12 @@ +#nc_container { width:100%; height:auto; position:relative; } +#nc_container .list { top:2px; position:relative; } +#nc_container .list ul { display:block; position:relative; } +#nc_container ul.nc_memu:after { + content: ""; + display: block; + height: 0; + clear: both; + visibility: hidden; +} +#nc_container .listscroll { overflow: visible; } +.ncenterlite_block { display:none; } diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.white.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.white.css new file mode 100644 index 000000000..5cd778257 --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.white.css @@ -0,0 +1,16 @@ +#nc_container { border:1px solid #EFEFEF; background-color:#fff; color:#000; opacity:0.95;} +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#000; } +#nc_container a.notify strong { color:#F60; } +#nc_container .list { border:1px solid #EFEFEF; background-color:#fff; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#eee; } +#nc_container .list li a:hover { background-color: #eee; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify .num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #eee; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } diff --git a/modules/ncenterlite/skins/default_bottom/ncenterlite.whitenoprofile.css b/modules/ncenterlite/skins/default_bottom/ncenterlite.whitenoprofile.css new file mode 100644 index 000000000..175a58afe --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/ncenterlite.whitenoprofile.css @@ -0,0 +1,18 @@ +#nc_container { border:1px solid #EFEFEF; background-color:#fff; color:#000; opacity:0.95;} +#nc_container a { color:#666; } +#nc_container a:hover { color:#666; } +#nc_container strong { color:#000; } +#nc_container a.notify strong { color:#F60; } +#nc_container .list { border:1px solid #EFEFEF; background-color:#fff; filter:alpha(opacity=95); opacity:0.95; -moz-opacity:0.95; } +#nc_container .list li { border-color:#eee; } +#nc_container .list li a:hover { background-color: #eee; } +#nc_container .list span.ago { color:#D4AF37; } +#nc_container .list a.notify .num { background-color:#D83722; color:white; } +#nc_container .list .more { background: #eee; } +#nc_container a.readall { display:none; color:#555; font-size:10px; color:#D83722;} + +#nc_container a.notify { color:#666; } +#nc_container a.notify .num { background-color:#D83722; color:white; } +#nc_container ul.nc_memu li { padding-right:5px; } + +#nc_container img.nc_profile_img { display:none;} diff --git a/modules/ncenterlite/skins/default_bottom/skin.xml b/modules/ncenterlite/skins/default_bottom/skin.xml new file mode 100644 index 000000000..aeecfd5cf --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/skin.xml @@ -0,0 +1,40 @@ + + + XE 알림센터 Lite 기본스킨 - 우측 하단 + XE Notification Center Lite Default Skin - Right bottom + 1.2.0 + 2013-05-10 + + + XE Public + XE Public + + + + + 검은색 + Black + + + 회색 + Gray + + + 흰색 + White + + + + 검은색(no profile) + Black (no profile) + + + 회색(no profile) + Gray (no profile) + + + 흰색(no profile) + White (no profile) + + + diff --git a/modules/ncenterlite/skins/default_bottom/userconfig.html b/modules/ncenterlite/skins/default_bottom/userconfig.html new file mode 100644 index 000000000..52e2e2f0b --- /dev/null +++ b/modules/ncenterlite/skins/default_bottom/userconfig.html @@ -0,0 +1,68 @@ + + +
    + +
    +

    {$XE_VALIDATOR_MESSAGE}

    +
    + + +
    + + + + +
    +

    {@$user_str = $member_info->nick_name} + {@$user_str = $logged_info->nick_name} + {@$title_str = Context::getLang('ncenterlite_userconfig_title')} + {sprintf($title_str, $user_str)} +

    + +

    {$lang->ncenterlite_userconfig_about} ({$lang->ncenterlite_userconfig_about_warning})

    +
    + +
    + + +

    {$lang->ncenterlite_comment_noti_about}

    +
    +
    +
    + +
    + + +

    {$lang->ncenterlite_mention_noti_about}

    +
    +
    +
    + +
    + + +

    {$lang->ncenterlite_message_noti_about}

    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + \ No newline at end of file diff --git a/modules/ncenterlite/tpl/Config.html b/modules/ncenterlite/tpl/Config.html new file mode 100644 index 000000000..0067f5496 --- /dev/null +++ b/modules/ncenterlite/tpl/Config.html @@ -0,0 +1,272 @@ + + + + +
    +
    + + +

    {$lang->ncenterlite_config_environment}

    + {$lang->ncenterlite_config_environment_about} +
    + + +
    +
    +
    + + +
    + + + + + + + + + + + + + +
    +
    + +
    +
    + +
    +

    {$lang->etc}

    +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    +
    +
    +

    {$lang->ncenterlite_install_version} : Lite v{$ncenterlite_module_info->version}

    + +
    \ No newline at end of file diff --git a/modules/ncenterlite/tpl/css/ncenter_admin.css b/modules/ncenterlite/tpl/css/ncenter_admin.css new file mode 100644 index 000000000..b01d9527b --- /dev/null +++ b/modules/ncenterlite/tpl/css/ncenter_admin.css @@ -0,0 +1,12 @@ +.mention_option ul.preview, +.mention_option ul.preview li { margin:0; padding:0; list-style:none; } + +.mention_option ul.preview li { display:inline-block; margin:5px; padding:3px 7px; border-radius:50px; color:red; font-size:1.2em; background:#EEE; } +.mention_option ul.preview li strong { color:black; } + +.mention_option ul.preview li.enable, +.mention_option ul.preview li.disable { color:black; } +.mention_option ul.preview li.enable strong, +.mention_option ul.preview li.disable strong { color:#FFF; } +.mention_option ul.preview li.enable { background:green; } +.mention_option ul.preview li.disable { background:red; } diff --git a/modules/ncenterlite/tpl/header.html b/modules/ncenterlite/tpl/header.html new file mode 100644 index 000000000..be44bc02d --- /dev/null +++ b/modules/ncenterlite/tpl/header.html @@ -0,0 +1,14 @@ +
    +

    {$lang->ncenterlite}

    +
    + + + +
    +

    {$XE_VALIDATOR_MESSAGE}

    +
    \ No newline at end of file diff --git a/modules/ncenterlite/tpl/js/ncenter_admin.js b/modules/ncenterlite/tpl/js/ncenter_admin.js new file mode 100644 index 000000000..5fa289894 --- /dev/null +++ b/modules/ncenterlite/tpl/js/ncenter_admin.js @@ -0,0 +1,106 @@ +function doDisplaySkinColorset(sel, colorset) +{ + var skin = sel.options[sel.selectedIndex].value; + + var params = new Array(); + params["skin"] = skin; + params["colorset"] = colorset; + + var response_tags = ['error', 'message', 'colorset_list']; + + exec_xml('ncenterlite', 'getColorsetList', params, completeGetSkinColorset, response_tags, params); +} + +function completeGetSkinColorset(ret_obj, response_tags, params, fo_obj) +{ + var sel = get_by_id('fo_ncenterlite').colorset; + var length = sel.options.length; + var selected_colorset = params['colorset']; + for(var i=0;i= steps) { + //element.style.backgroundColor = 'rgb(' + endcolour.toString() + ')'; + element.style.backgroundColor = c; //'rgb(' + endcolour.toString() + ')'; + clearInterval(timer); + } + }, interval); + } + + var s = decodeURIComponent(location.href).replace(/.*#comment_/,''); + if(!s || s === decodeURIComponent(location.href)) return; + s = 'comment_' + s; + jQuery('.xe_content').each(function(){ + var t = jQuery(this); + if(t.hasClass(s) || (new RegExp(s + '_')).test(t.attr('class'))){ + var c = t.css('display','block').css('background-color'); + y(this, [255,255,60], [255,255,255], 750, c); + ncenterlite_need_highlight = false; + } + }); +} + +if(typeof _viewSubComment == 'function') { + old__viewSubComment = _viewSubComment; + _viewSubComment = function(ret_obj) { + old__viewSubComment(ret_obj); + if(ncenterlite_need_highlight) { + setTimeout(function(){ + var s = decodeURIComponent(location.href).match(/#.*comment_([0-9]+)/); + if(s) { + ncenterlite_highlight(); + location.href = '#social_comment_' + s[1]; + } + }, 500); + } + }; +} + +jQuery(function(){ + ncenterlite_highlight(); +}); diff --git a/modules/ncenterlite/tpl/ncenter_list.html b/modules/ncenterlite/tpl/ncenter_list.html new file mode 100644 index 000000000..2bf1b1fad --- /dev/null +++ b/modules/ncenterlite/tpl/ncenter_list.html @@ -0,0 +1,67 @@ + + + +
    +

    알림 목록

    + +

    알림이 없습니다.

    + + +
    +
    +
    + + + + +

    주의! 회원이 확인하지 않은 알림도 삭제됩니다.

    +
    +
    +
    + + + + + + + + + + + + + + {@ + $oMemberModel = getModel('member'); + $member_info = $oMemberModel->getMemberInfoByMemberSrl($val->member_srl); + } + + + + + + + + + +
    보낸사람받은사람내용읽음여부{$lang->date}
    {$val->target_nick_name}{$member_info->nick_name} 타겟없음{$val->text}{$val->readed} + {zdate($val->regdate,"Y-m-d")} +
    + {zdate($val->regdate,"H:i:s")} +
    + + +
    +
    \ No newline at end of file From 7ed2d132d90673eecf864cd1d2918e2a797db383 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 06:06:30 +0900 Subject: [PATCH 198/318] delete moduleObject trigger. --- modules/ncenterlite/ncenterlite.class.php | 1 - .../ncenterlite/ncenterlite.controller.php | 83 ------------------- 2 files changed, 84 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.class.php b/modules/ncenterlite/ncenterlite.class.php index edcc7777f..a622e9384 100644 --- a/modules/ncenterlite/ncenterlite.class.php +++ b/modules/ncenterlite/ncenterlite.class.php @@ -38,7 +38,6 @@ class ncenterlite extends ModuleObject array('document.deleteDocument', 'ncenterlite', 'controller', 'triggerAfterDeleteDocument', 'after'), array('display', 'ncenterlite', 'controller', 'triggerBeforeDisplay', 'before'), array('moduleHandler.proc', 'ncenterlite', 'controller', 'triggerAfterModuleHandlerProc', 'after'), - array('moduleObject.proc', 'ncenterlite', 'controller', 'triggerBeforeModuleObjectProc', 'before'), array('member.deleteMember', 'ncenterlite', 'controller', 'triggerAfterDeleteMember', 'after'), array('communication.sendMessage', 'ncenterlite', 'controller', 'triggerAfterSendMessage', 'after'), array('document.updateVotedCount', 'ncenterlite', 'controller', 'triggerAfterVotedupdate', 'after'), diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index 99538bb5b..c54f1bac1 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -258,89 +258,6 @@ class ncenterliteController extends ncenterlite return new Object(); } - function triggerBeforeModuleObjectProc(&$oModule) - { - if(version_compare(__XE_VERSION__, '1.7.4', '>=')) - { - return new Object(); - } - $oNcenterliteModel = getModel('ncenterlite'); - $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); - - $vars = Context::getRequestVars(); - $logged_info = Context::get('logged_info'); - - $messages_member_config = $oNcenterliteModel->getMemberConfig($logged_info->member_srl); - $message_member_config = $messages_member_config->data; - - // 쪽지 체크 및 유저 쪽지 알림 채크 - if($config->message_notify == 'Y' && $message_member_config->message_notify != 'N') - { - $flag_path = './files/ncenterlite/new_message_flags/'; - - $need_update = false; - // 쪽지 알림 메시지 체크 - if(strpos(Context::getHtmlFooter(), 'xeNotifyMessage') !== FALSE) - { - $need_update = true; - } - // 메시지 플래그 파일 체크 - else if(file_exists($flag_path . $logged_info->member_srl)) - { - $need_update = true; - } - - if($oModule->act == 'procCommunicationSendMessage') - { - FileHandler::makeDir($flag_path); - $flag_file = sprintf('%s%s', $flag_path, $vars->receiver_srl); - FileHandler::writeFile($flag_file, $vars->receiver_srl); - } - else if($need_update) - { - $oMemberModel = getModel('member'); - $_sender_member_srl = trim(FileHandler::readFile($flag_path . $logged_info->member_srl)); - $sender_member_info = $oMemberModel->getMemberInfoByMemberSrl($_sender_member_srl); - FileHandler::removeFile($flag_path . $logged_info->member_srl); - - // 새 쪽지 수 - $args = new stdClass(); - $args->receiver_srl = $logged_info->member_srl; - $output = executeQuery('ncenterlite.getCountNewMessage', $args); - $message_count = $output->data->count; - - // 기존 쪽지 알림을 읽은 것으로 변경 - $cond = new stdClass(); - $cond->type = $this->_TYPE_MESSAGE; - $cond->member_srl = $logged_info->member_srl; - $output = executeQuery('ncenterlite.updateNotifyReadedByType', $cond); - - if(!$message_count) return; - - // 알림 추가 - $args = new stdClass(); - $args->member_srl = $logged_info->member_srl; - $args->srl = $sender_member_info->member_srl; - if(!$args->srl) $args->srl = 0; - $args->target_p_srl = 1; - $args->target_srl = $sender_member_info->member_srl; - if(!$args->srl) $args->target_srl = 0; - $args->type = $this->_TYPE_MESSAGE; - $args->target_type = $this->_TYPE_MESSAGE; - $args->target_url_params = $target_url_params; - $args->target_summary = $message_count; - $args->target_nick_name = $sender_member_info->nick_name; - $args->target_member_srl = $sender_member_info->member_srl; - $args->regdate = date('YmdHis'); - $args->notify = $this->_getNotifyId($args); - $args->target_url = getNotEncodedFullUrl('', 'act', 'dispCommunicationMessages'); - - $output = $this->_insertNotify($args); - } - } - } - function triggerAfterSendMessage(&$trigger_obj) { $oNcenterliteModel = getModel('ncenterlite'); From d8ef4bfb37ba057d53b79cb3c6f0176fdc0326fd Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 06:13:24 +0900 Subject: [PATCH 199/318] if use massage notify, communication notify do not use. --- modules/communication/communication.controller.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index 3845e8b20..6af77537f 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -820,7 +820,13 @@ class communicationController extends communication { return new Object(); } - + + $ncenterlite_config = getModel('ncenterlite')->getConfig(); + if($ncenterlite_config->message_notify == 'Y' && $ncenterlite_config->use == 'Y') + { + return new Object(); + } + $config = getModel('communication')->getConfig(); if ($config->enable_message == 'N' || starts_with('dispCommunication', Context::get('act'))) { From 2bf39091c5f8c005717b8f6a14f49a4e29362a24 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 06:15:57 +0900 Subject: [PATCH 200/318] erase code intended to disable a message. --- modules/ncenterlite/ncenterlite.controller.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index c54f1bac1..faefc6c51 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -637,10 +637,6 @@ class ncenterliteController extends ncenterlite } } - Context::addHtmlFooter(''); - $this->_addFile(); $html = $this->_getTemplate(); $output_display = $html . $output_display; From 07f2656424fd325e4cac93cafa0ad1f22f32ffe8 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 06:50:31 +0900 Subject: [PATCH 201/318] Revised methods of improting files. --- modules/ncenterlite/ncenterlite.controller.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index faefc6c51..13602a8e3 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -587,11 +587,13 @@ class ncenterliteController extends ncenterlite Context::set('ncenterlite_config', $config); - $oModuleModel = getModel('module'); - $ncenterlite_module_info = $oModuleModel->getModuleInfoXml('ncenterlite'); - $jsCacheRefresh = '?'.$ncenterlite_module_info->version.'.'.$ncenterlite_module_info->date.'.js'; - Context::addJsFile('./modules/ncenterlite/tpl/js/ncenterlite.js'.$jsCacheRefresh, true, '', 100000); - + $js_args = array( + './modules/ncenterlite/tpl/js/ncenterlite.js', + 'body', + '', + 100000 + ); + Context::loadFile($js_args); $oNcenterliteModel = getModel('ncenterlite'); From 7bcc9658d6c2e6fdc161a6c0ed62babd68a54b93 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 06:58:38 +0900 Subject: [PATCH 202/318] modity XE to Rhymix --- modules/ncenterlite/conf/info.xml | 4 ++-- modules/ncenterlite/conf/module.xml | 6 +++--- modules/ncenterlite/lang/lang.xml | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/ncenterlite/conf/info.xml b/modules/ncenterlite/conf/info.xml index 6d943f59c..5aab600eb 100644 --- a/modules/ncenterlite/conf/info.xml +++ b/modules/ncenterlite/conf/info.xml @@ -1,7 +1,7 @@ - XE 알림센터 Lite - XE Notification Center Lite + Rhymix 알림센터 Lite + Rhymix Notification Center Lite 사이트 사용자간의 커뮤니케이션에 대한 정보를 알려주는 모듈입니다. This module notify users of information about new documents, comments and/or messages that call them. This module will enhance communication beween site users. 2.1.5 diff --git a/modules/ncenterlite/conf/module.xml b/modules/ncenterlite/conf/module.xml index 489517102..0559d6e93 100644 --- a/modules/ncenterlite/conf/module.xml +++ b/modules/ncenterlite/conf/module.xml @@ -22,9 +22,9 @@ - XE 알림센터 Lite - XE Notification Center Lite - XE 通知センター Lite + Rhymix 알림센터 Lite + Rhymix Notification Center Lite + Rhymix 通知センター Lite diff --git a/modules/ncenterlite/lang/lang.xml b/modules/ncenterlite/lang/lang.xml index d6a8762c3..4e2e080f0 100644 --- a/modules/ncenterlite/lang/lang.xml +++ b/modules/ncenterlite/lang/lang.xml @@ -1,14 +1,14 @@ - - - + + + - + From 50581484e49528361e5ab3af4b082c635a314821 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:07:39 +0900 Subject: [PATCH 203/318] modify __XE_VERSION__ to RX_VERSION --- modules/ncenterlite/ncenterlite.admin.view.php | 2 +- modules/ncenterlite/ncenterlite.controller.php | 2 +- modules/ncenterlite/ncenterlite.model.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.admin.view.php b/modules/ncenterlite/ncenterlite.admin.view.php index 4c745ed0b..81c1ac34a 100644 --- a/modules/ncenterlite/ncenterlite.admin.view.php +++ b/modules/ncenterlite/ncenterlite.admin.view.php @@ -59,7 +59,7 @@ class ncenterliteAdminView extends ncenterlite $_ncenterlite_iframe_url = 'http://sosifam.com/index.php?mid=ncenterlite_iframe'; if(!$agreement_ver) { - $_host_info = urlencode($_SERVER['HTTP_HOST']) . '-NC' . $ncenterlite_module_info->version . '-PHP' . phpversion() . '-XE' . __XE_VERSION__; + $_host_info = urlencode($_SERVER['HTTP_HOST']) . '-NC' . $ncenterlite_module_info->version . '-PHP' . phpversion() . '-XE' . RX_VERSION; } Context::set('_ncenterlite_iframe_url', $_ncenterlite_iframe_url . '&_host='. $_host_info); Context::set('ncenterlite_module_info', $ncenterlite_module_info); diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index 13602a8e3..516d705ba 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -270,7 +270,7 @@ class ncenterliteController extends ncenterlite $messages_member_config = $oNcenterliteModel->getMemberConfig($trigger_obj->receiver_srl); $message_member_config = $messages_member_config->data; - if(version_compare(__XE_VERSION__, '1.8', '>=') && $message_member_config->message_notify != 'N') + if(version_compare(RX_VERSION, '1.8', '>=') && $message_member_config->message_notify != 'N') { $args = new stdClass(); $args->member_srl = $trigger_obj->receiver_srl; diff --git a/modules/ncenterlite/ncenterlite.model.php b/modules/ncenterlite/ncenterlite.model.php index bb4c48c18..23a6d749c 100644 --- a/modules/ncenterlite/ncenterlite.model.php +++ b/modules/ncenterlite/ncenterlite.model.php @@ -161,7 +161,7 @@ class ncenterliteModel extends ncenterlite break; // 메시지. 쪽지 case 'E': - if(version_compare(__XE_VERSION__, '1.7.4', '>=')) + if(version_compare(RX_VERSION, '1.7.4', '>=')) { $str = sprintf($lang->ncenterlite_message_mention,$target_member, $v->target_summary); } From 36d7b83e4352b813068286b59007625e6d338865 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:09:48 +0900 Subject: [PATCH 204/318] do not check XE Version. --- modules/ncenterlite/ncenterlite.controller.php | 18 +----------------- modules/ncenterlite/ncenterlite.model.php | 9 +-------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index 516d705ba..821c9e8a4 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -270,7 +270,7 @@ class ncenterliteController extends ncenterlite $messages_member_config = $oNcenterliteModel->getMemberConfig($trigger_obj->receiver_srl); $message_member_config = $messages_member_config->data; - if(version_compare(RX_VERSION, '1.8', '>=') && $message_member_config->message_notify != 'N') + if($message_member_config->message_notify != 'N') { $args = new stdClass(); $args->member_srl = $trigger_obj->receiver_srl; @@ -285,22 +285,6 @@ class ncenterliteController extends ncenterlite $args->target_url = getNotEncodedFullUrl('', 'act', 'dispCommunicationMessages', 'message_srl', $trigger_obj->related_srl); $output = $this->_insertNotify($args); } - elseif($message_member_config->message_notify != 'N') - { - $args = new stdClass(); - $args->member_srl = $trigger_obj->receiver_srl; - $args->srl = $trigger_obj->receiver_srl; - $args->target_p_srl = '1'; - $args->target_srl = $trigger_obj->sender_srl; - $args->type = $this->_TYPE_MESSAGE; - $args->target_type = $this->_TYPE_MESSAGE; - $args->target_summary = $trigger_obj->title; - $args->regdate = date('YmdHis'); - $args->notify = $this->_getNotifyId($args); - $args->target_url = getNotEncodedFullUrl('', 'act', 'dispCommunicationMessages'); - $output = $this->_insertNotify($args); - } - } function triggerAfterVotedupdate(&$obj) diff --git a/modules/ncenterlite/ncenterlite.model.php b/modules/ncenterlite/ncenterlite.model.php index 23a6d749c..77c261582 100644 --- a/modules/ncenterlite/ncenterlite.model.php +++ b/modules/ncenterlite/ncenterlite.model.php @@ -161,14 +161,7 @@ class ncenterliteModel extends ncenterlite break; // 메시지. 쪽지 case 'E': - if(version_compare(RX_VERSION, '1.7.4', '>=')) - { - $str = sprintf($lang->ncenterlite_message_mention,$target_member, $v->target_summary); - } - else - { - $str = sprintf($lang->ncenterlite_message_string, $v->target_summary); - } + $str = sprintf($lang->ncenterlite_message_mention,$target_member, $v->target_summary); break; case 'T': $str = sprintf($lang->ncenterlite_test_noti, $target_member); From 47da220e439a29668788a1a65915572ccb068625 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:14:19 +0900 Subject: [PATCH 205/318] modify check RX Version. --- modules/ncenterlite/ncenterlite.admin.view.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ncenterlite/ncenterlite.admin.view.php b/modules/ncenterlite/ncenterlite.admin.view.php index 81c1ac34a..cd28e11f9 100644 --- a/modules/ncenterlite/ncenterlite.admin.view.php +++ b/modules/ncenterlite/ncenterlite.admin.view.php @@ -59,7 +59,7 @@ class ncenterliteAdminView extends ncenterlite $_ncenterlite_iframe_url = 'http://sosifam.com/index.php?mid=ncenterlite_iframe'; if(!$agreement_ver) { - $_host_info = urlencode($_SERVER['HTTP_HOST']) . '-NC' . $ncenterlite_module_info->version . '-PHP' . phpversion() . '-XE' . RX_VERSION; + $_host_info = urlencode($_SERVER['HTTP_HOST']) . '-NC' . $ncenterlite_module_info->version . '-PHP' . phpversion() . '-RX' . RX_VERSION; } Context::set('_ncenterlite_iframe_url', $_ncenterlite_iframe_url . '&_host='. $_host_info); Context::set('ncenterlite_module_info', $ncenterlite_module_info); From 76a62b0edad5a772ed722f2421a6f0bec602a139 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:21:32 +0900 Subject: [PATCH 206/318] delete unused methods. --- modules/ncenterlite/conf/module.xml | 1 - modules/ncenterlite/ncenterlite.controller.php | 15 +++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/modules/ncenterlite/conf/module.xml b/modules/ncenterlite/conf/module.xml index 0559d6e93..f2a415997 100644 --- a/modules/ncenterlite/conf/module.xml +++ b/modules/ncenterlite/conf/module.xml @@ -13,7 +13,6 @@ - diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index 821c9e8a4..e455a39d8 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -262,6 +262,11 @@ class ncenterliteController extends ncenterlite { $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); + $communication_config = getModel('communication')->getConfig(); + if($communication_config->enable_message != 'Y') + { + return new Object(); + } if($config->use != 'Y') return new Object(); if($config->message_notify == 'N') { @@ -742,16 +747,6 @@ class ncenterliteController extends ncenterlite return $ouptut; } - function procNcenterliteNotifyRead() - { - $logged_info = Context::get('logged_info'); - $target_srl = Context::get('target_srl'); - if(!$logged_info || !$target_srl) return new Object(-1, 'msg_invalid_request'); - - $output = $this->updateNotifyRead($notify, $logged_info->member_srl); - return $output; - } - function procNcenterliteNotifyReadAll() { $logged_info = Context::get('logged_info'); From 25e491e2fc6915c89d63ddc60bf80f09aeb35290 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:38:11 +0900 Subject: [PATCH 207/318] delete does not use functions. --- modules/ncenterlite/ncenterlite.controller.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index e455a39d8..7adaa5dff 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -46,9 +46,6 @@ class ncenterliteController extends ncenterlite function triggerAfterDeleteMember($obj) { - $oNcenterliteModel = getModel('ncenterlite'); - $config = $oNcenterliteModel->getConfig(); - $member_srl = $obj->member_srl; if(!$member_srl) return new Object(); @@ -77,9 +74,7 @@ class ncenterliteController extends ncenterlite $mention_targets = $this->_getMentionTarget($content); if(!$mention_targets || !count($mention_targets)) return new Object(); - $oDocumentModel = getModel('document'); $document_srl = $obj->document_srl; - $oDocument = $oDocumentModel->getDocument($document_srl); $module_info = $oModuleModel->getModuleInfoByDocumentSrl($document_srl); $is_anonymous = $this->_isAnonymous($this->_TYPE_DOCUMENT, $obj); From e7b21ea2ee941749a46dea17046fde0b5e423126 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:48:18 +0900 Subject: [PATCH 208/318] =?UTF-8?q?=EC=BD=94=EB=93=9C=EB=A5=BC=20=EA=B9=94?= =?UTF-8?q?=EA=B8=88=ED=95=98=EA=B2=8C=20=EC=A0=95=EB=A6=AC=ED=95=A8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ncenterlite/ncenterlite.controller.php | 252 +++++++++++++----- 1 file changed, 184 insertions(+), 68 deletions(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index 7adaa5dff..f8368eb9f 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -1,4 +1,5 @@ member_srl; } - if($logged_info->member_srl != $member_srl && $logged_info->is_admin != 'Y') return new Object(-1, 'ncenterlite_stop_no_permission_other_user_settings'); + if($logged_info->member_srl != $member_srl && $logged_info->is_admin != 'Y') + { + return new Object(-1, 'ncenterlite_stop_no_permission_other_user_settings'); + } $output = $oNcenterliteModel->getMemberConfig($member_srl); @@ -36,9 +40,9 @@ class ncenterliteController extends ncenterlite $this->setMessage('success_updated'); - if(!in_array(Context::getRequestMethod(),array('XMLRPC','JSON'))) + if(!in_array(Context::getRequestMethod(), array('XMLRPC', 'JSON'))) { - $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'act', 'dispNcenterliteUserConfig','member_srl',$member_srl); + $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'act', 'dispNcenterliteUserConfig', 'member_srl', $member_srl); header('location: ' . $returnUrl); return; } @@ -47,7 +51,10 @@ class ncenterliteController extends ncenterlite function triggerAfterDeleteMember($obj) { $member_srl = $obj->member_srl; - if(!$member_srl) return new Object(); + if(!$member_srl) + { + return new Object(); + } $args = new stdClass(); $args->member_srl = $member_srl; @@ -63,16 +70,25 @@ class ncenterliteController extends ncenterlite { $oModuleModel = getModel('module'); - if($this->_isDisable()) return; + if($this->_isDisable()) + { + return; + } $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } $content = strip_tags($obj->title . ' ' . $obj->content); $mention_targets = $this->_getMentionTarget($content); - if(!$mention_targets || !count($mention_targets)) return new Object(); + if(!$mention_targets || !count($mention_targets)) + { + return new Object(); + } $document_srl = $obj->document_srl; $module_info = $oModuleModel->getModuleInfoByDocumentSrl($document_srl); @@ -115,11 +131,17 @@ class ncenterliteController extends ncenterlite function triggerAfterInsertComment(&$obj) { - if($this->_isDisable()) return; + if($this->_isDisable()) + { + return; + } $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } $logged_info = Context::get('logged_info'); $notify_member_srl = array(); @@ -154,7 +176,7 @@ class ncenterliteController extends ncenterlite $args->target_srl = $obj->comment_srl; $args->type = $this->_TYPE_COMMENT; $args->target_type = $this->_TYPE_MENTION; - $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_' . $comment_srl; $args->target_summary = cut_str(strip_tags($content), 50); $args->target_nick_name = $obj->nick_name; $args->target_email_address = $obj->email_address; @@ -167,7 +189,7 @@ class ncenterliteController extends ncenterlite $admin_list = $oNcenterliteModel->getMemberAdmins(); $admins_list = $admin_list->data; - + foreach($admins_list as $admins) { if(is_array($config->admin_comment_module_srls) && in_array($module_info->module_srl, $config->admin_comment_module_srls)) @@ -179,7 +201,7 @@ class ncenterliteController extends ncenterlite $args->target_srl = $obj->comment_srl; $args->type = $this->_TYPE_COMMENT; $args->target_type = $this->_TYPE_ADMIN_COMMENT; - $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_' . $comment_srl; $args->target_summary = cut_str(strip_tags($content), 50); $args->target_nick_name = $obj->nick_name; $args->target_email_address = $obj->email_address; @@ -208,7 +230,7 @@ class ncenterliteController extends ncenterlite $args->target_srl = $obj->comment_srl; $args->type = $this->_TYPE_COMMENT; $args->target_type = $this->_TYPE_COMMENT; - $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_' . $comment_srl; $args->target_summary = cut_str(strip_tags($content), 50); $args->target_nick_name = $obj->nick_name; $args->target_email_address = $obj->email_address; @@ -239,7 +261,7 @@ class ncenterliteController extends ncenterlite $args->target_srl = $comment_srl; $args->type = $this->_TYPE_DOCUMENT; $args->target_type = $this->_TYPE_COMMENT; - $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_'. $comment_srl; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $document_srl, '_comment_srl', $comment_srl) . '#comment_' . $comment_srl; $args->target_summary = cut_str(strip_tags($content), 50); $args->target_nick_name = $obj->nick_name; $args->target_email_address = $obj->email_address; @@ -262,7 +284,10 @@ class ncenterliteController extends ncenterlite { return new Object(); } - if($config->use != 'Y') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } if($config->message_notify == 'N') { return new Object(); @@ -294,9 +319,18 @@ class ncenterliteController extends ncenterlite $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); - if($config->voted_format != 'Y') return new Object(); - if($obj->point < 0) return new Object(); + if($config->use != 'Y') + { + return new Object(); + } + if($config->voted_format != 'Y') + { + return new Object(); + } + if($obj->point < 0) + { + return new Object(); + } $args = new stdClass(); $args->member_srl = $obj->member_srl; @@ -309,14 +343,17 @@ class ncenterliteController extends ncenterlite $args->regdate = date('YmdHis'); $args->notify = $this->_getNotifyId($args); $args->target_url = getNotEncodedFullUrl('', 'document_srl', $obj->document_srl); - $output = $this->_insertNotify($args, $is_anonymous); + $output = $this->_insertNotify($args); } function triggerAfterDeleteComment(&$obj) { $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } $args = new stdClass(); $args->srl = $obj->comment_srl; @@ -328,7 +365,10 @@ class ncenterliteController extends ncenterlite { $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } $args = new stdClass(); $args->srl = $obj->document_srl; @@ -342,11 +382,17 @@ class ncenterliteController extends ncenterlite $logged_info = Context::get('logged_info'); $args = new stdClass(); - if($oModule->getLayoutFile() == 'popup_layout.html') Context::set('ncenterlite_is_popup', TRUE); + if($oModule->getLayoutFile() == 'popup_layout.html') + { + Context::set('ncenterlite_is_popup', TRUE); + } $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); - if($config->use != 'Y') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } $this->_hide_ncenterlite = false; if($oModule->module == 'beluxe' && Context::get('is_modal')) @@ -380,7 +426,7 @@ class ncenterliteController extends ncenterlite $oDocument = Context::get('oDocument'); $logged_info = Context::get('logged_info'); - if($document_srl && $logged_info && $config->document_read=='Y') + if($document_srl && $logged_info && $config->document_read == 'Y') { $args->srl = $document_srl; $args->member_srl = $logged_info->member_srl; @@ -394,7 +440,7 @@ class ncenterliteController extends ncenterlite { if(array_key_exists($comment_srl, $_comment_list)) { - $url = getNotEncodedUrl('_comment_srl','') . '#comment_' . $comment_srl; + $url = getNotEncodedUrl('_comment_srl', '') . '#comment_' . $comment_srl; $need_check_socialxe = true; } else @@ -402,7 +448,7 @@ class ncenterliteController extends ncenterlite $cpage = $oDocument->comment_page_navigation->cur_page; if($cpage > 1) { - $url = getNotEncodedUrl('cpage', $cpage-1) . '#comment_' . $comment_srl; + $url = getNotEncodedUrl('cpage', $cpage - 1) . '#comment_' . $comment_srl; $need_check_socialxe = true; } else @@ -440,7 +486,7 @@ class ncenterliteController extends ncenterlite } } - $url = str_replace('&','&',$url); + $url = str_replace('&', '&', $url); header('location: ' . $url); Context::close(); exit; @@ -490,7 +536,7 @@ class ncenterliteController extends ncenterlite $args->target_type = $this->_TYPE_COMMENT; $args->target_srl = $vars->parent_srl; $args->target_p_srl = '1'; - $args->target_url = getNotEncodedFullUrl('', 'document_srl', $vars->document_srl, '_comment_srl', $vars->parent_srl) . '#comment_'. $vars->parent_srl; + $args->target_url = getNotEncodedFullUrl('', 'document_srl', $vars->document_srl, '_comment_srl', $vars->parent_srl) . '#comment_' . $vars->parent_srl; $args->target_summary = cut_str(strip_tags($vars->content), 50); $args->target_nick_name = $logged_info->nick_name; $args->target_email_address = $logged_info->email_address; @@ -531,65 +577,96 @@ class ncenterliteController extends ncenterlite { $act = Context::get('act'); // 팝업창이면 중지 - if(Context::get('ncenterlite_is_popup')) return; + if(Context::get('ncenterlite_is_popup')) + { + return; + } // 자신의 알림목록을 보고 있을 경우엔 알림센터창을 띄우지 않는다. - if($act == 'dispNcenterliteNotifyList') return; + if($act == 'dispNcenterliteNotifyList') + { + return; + } if(count($this->disable_notify_bar_act)) { - if(in_array(Context::get('act'), $this->disable_notify_bar_act)) return; + if(in_array(Context::get('act'), $this->disable_notify_bar_act)) + { + return; + } } // HTML 모드가 아니면 중지 + act에 admin이 포함되어 있으면 중지 - if(Context::getResponseMethod() != 'HTML' || strpos(strtolower(Context::get('act')), 'admin') !== false) return; + if(Context::getResponseMethod() != 'HTML' || strpos(strtolower(Context::get('act')), 'admin') !== false) + { + return; + } $logged_info = Context::get('logged_info'); // 로그인 상태가 아니면 중지 - if(!$logged_info) return; + if(!$logged_info) + { + return; + } $module_info = Context::get('module_info'); if(count($this->disable_notify_bar_mid)) { - if(in_array($module_info->mid, $this->disable_notify_bar_mid)) return; + if(in_array($module_info->mid, $this->disable_notify_bar_mid)) + { + return; + } } // admin 모듈이면 중지 - if($module_info->module == 'admin' ) return; + if($module_info->module == 'admin') + { + return; + } $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); // 알림센터가 비활성화 되어 있으면 중지 - if($config->use != 'Y') return new Object(); - if($config->display_use == 'N') return new Object(); + if($config->use != 'Y') + { + return new Object(); + } + if($config->display_use == 'N') + { + return new Object(); + } // 노티바 제외 페이지이면 중지 - if(in_array($module_info->module_srl, $config->hide_module_srls)) return new Object(); + if(in_array($module_info->module_srl, $config->hide_module_srls)) + { + return new Object(); + } Context::set('ncenterlite_config', $config); - $js_args = array( - './modules/ncenterlite/tpl/js/ncenterlite.js', - 'body', - '', - 100000 - ); + $js_args = array('./modules/ncenterlite/tpl/js/ncenterlite.js', 'body', '', 100000); Context::loadFile($js_args); $oNcenterliteModel = getModel('ncenterlite'); // 알림 목록 가져오기 $_output = $oNcenterliteModel->getMyNotifyList(); - if(!$_output->data) return; // 알림 메시지가 없어도 항상 표시하게 하려면 이 줄을 제거 또는 주석 처리하세요. + if(!$_output->data) + { + return; + } // 알림 메시지가 없어도 항상 표시하게 하려면 이 줄을 제거 또는 주석 처리하세요. $_latest_notify_id = array_slice($_output->data, 0, 1); $_latest_notify_id = $_latest_notify_id[0]->notify; Context::set('ncenterlite_latest_notify_id', $_latest_notify_id); - if($_COOKIE['_ncenterlite_hide_id'] && $_COOKIE['_ncenterlite_hide_id'] == $_latest_notify_id) return; + if($_COOKIE['_ncenterlite_hide_id'] && $_COOKIE['_ncenterlite_hide_id'] == $_latest_notify_id) + { + return; + } setcookie('_ncenterlite_hide_id', '', 0, '/'); $oMemberModel = getModel('member'); @@ -607,19 +684,19 @@ class ncenterliteController extends ncenterlite if(Mobile::isFromMobilePhone()) { $this->template_path = sprintf('%sm.skins/%s/', $this->module_path, $config->mskin); - if(!is_dir($this->template_path)||!$config->mskin) + if(!is_dir($this->template_path) || !$config->mskin) { $config->mskin = 'default'; - $this->template_path = sprintf('%sm.skins/%s/',$this->module_path, $config->mskin); + $this->template_path = sprintf('%sm.skins/%s/', $this->module_path, $config->mskin); } } else { $this->template_path = sprintf('%sskins/%s/', $this->module_path, $config->skin); - if(!is_dir($this->template_path)||!$config->skin) + if(!is_dir($this->template_path) || !$config->skin) { $config->skin = 'default'; - $this->template_path = sprintf('%sskins/%s/',$this->module_path, $config->skin); + $this->template_path = sprintf('%sskins/%s/', $this->module_path, $config->skin); } } @@ -636,16 +713,19 @@ class ncenterliteController extends ncenterlite if($config->user_config_list == 'Y') { $logged_info = Context::get('logged_info'); - if(!Context::get('is_logged')) return new Object(); + if(!Context::get('is_logged')) + { + return new Object(); + } $target_srl = Context::get('target_srl'); $oMemberController = getController('member'); $oMemberController->addMemberMenu('dispNcenterliteNotifyList', 'ncenterlite_my_list'); $oMemberController->addMemberMenu('dispNcenterliteUserConfig', 'ncenterlite_my_settings'); - if($logged_info->is_admin== 'Y') + if($logged_info->is_admin == 'Y') { - $url = getUrl('','act','dispNcenterliteUserConfig','member_srl',$target_srl); + $url = getUrl('', 'act', 'dispNcenterliteUserConfig', 'member_srl', $target_srl); $str = Context::getLang('ncenterlite_user_settings'); $oMemberController->addMemberPopupMenu($url, $str, ''); } @@ -669,14 +749,14 @@ class ncenterliteController extends ncenterlite { if($config->colorset && file_exists(FileHandler::getRealPath($this->template_path . 'ncenterlite.' . $config->colorset . '.css'))) { - Context::addCssFile($this->template_path . 'ncenterlite.'.$config->colorset.'.css', true, 'all', '', 100); + Context::addCssFile($this->template_path . 'ncenterlite.' . $config->colorset . '.css', true, 'all', '', 100); } } elseif(Mobile::isFromMobilePhone()) { if($config->mcolorset && file_exists(FileHandler::getRealPath($this->template_path . 'ncenterlite.' . $config->mcolorset . '.css'))) { - Context::addCssFile($this->template_path . 'ncenterlite.'.$config->mcolorset.'.css', true, 'all', '', 100); + Context::addCssFile($this->template_path . 'ncenterlite.' . $config->mcolorset . '.css', true, 'all', '', 100); } Context::loadFile(array('./common/js/jquery.min.js', 'head', '', -100000), true); @@ -745,7 +825,10 @@ class ncenterliteController extends ncenterlite function procNcenterliteNotifyReadAll() { $logged_info = Context::get('logged_info'); - if(!$logged_info) return new Object(-1, 'msg_invalid_request'); + if(!$logged_info) + { + return new Object(-1, 'msg_invalid_request'); + } $output = $this->updateNotifyReadAll($logged_info->member_srl); return $output; @@ -756,10 +839,16 @@ class ncenterliteController extends ncenterlite $logged_info = Context::get('logged_info'); $url = Context::get('url'); $notify = Context::get('notify'); - if(!$logged_info || !$url || !$notify) return new Object(-1, 'msg_invalid_request'); + if(!$logged_info || !$url || !$notify) + { + return new Object(-1, 'msg_invalid_request'); + } $output = $this->updateNotifyRead($notify, $logged_info->member_srl); - if(!$output->toBool()) return $output; + if(!$output->toBool()) + { + return $output; + } $url = str_replace('&', '&', $url); header('Location: ' . $url, TRUE, 302); @@ -774,23 +863,35 @@ class ncenterliteController extends ncenterlite function _isAnonymous($source_type, $triggerObj) { // 회원번호가 음수 - if($triggerObj->member_srl < 0) return TRUE; + if($triggerObj->member_srl < 0) + { + return TRUE; + } $module_info = Context::get('module_info'); // DX 익명 체크박스 - if($module_info->module == 'beluxe' && $triggerObj->anonymous == 'Y') return TRUE; + if($module_info->module == 'beluxe' && $triggerObj->anonymous == 'Y') + { + return TRUE; + } if($source_type == $this->_TYPE_COMMENT) { // DX 익명 강제 - if($module_info->module == 'beluxe' && $module_info->use_anonymous == 'Y') return TRUE; + if($module_info->module == 'beluxe' && $module_info->use_anonymous == 'Y') + { + return TRUE; + } } if($source_type == $this->_TYPE_DOCUMENT) { // DX 익명 강제 - if($module_info->module == 'beluxe' && $module_info->use_anonymous == 'Y') return TRUE; + if($module_info->module == 'beluxe' && $module_info->use_anonymous == 'Y') + { + return TRUE; + } } return FALSE; @@ -801,7 +902,10 @@ class ncenterliteController extends ncenterlite $oNcenterliteModel = getModel('ncenterlite'); $config = $oNcenterliteModel->getConfig(); // 비회원 노티 제거 - if($args->member_srl <= 0) return new Object(); + if($args->member_srl <= 0) + { + return new Object(); + } $logged_info = Context::get('logged_info'); @@ -858,7 +962,7 @@ class ncenterliteController extends ncenterlite if(!$trigger_notify->toBool()) { return $trigger_notify; - } + } } return $output; @@ -889,7 +993,10 @@ class ncenterliteController extends ncenterlite // 정규표현식 정리 $split = array(); - if(in_array('comma', $config->mention_format)) $split[] = ','; + if(in_array('comma', $config->mention_format)) + { + $split[] = ','; + } $regx = join('', array('/(^|\s)@([^@\s', join('', $split), ']+)/i')); preg_match_all($regx, $content, $matches); @@ -903,7 +1010,10 @@ class ncenterliteController extends ncenterlite if($pos !== false && $pos > 0) { $matches[2][$idx] = trim(substr($item, 0, $pos)); - if($logged_info && $logged_info->nick_name == $matches[2][$idx]) unset($matches[2][$idx]); + if($logged_info && $logged_info->nick_name == $matches[2][$idx]) + { + unset($matches[2][$idx]); + } } } } @@ -920,7 +1030,10 @@ class ncenterliteController extends ncenterlite $vars = new stdClass(); $vars->user_id = $user_id; $output = executeQuery('ncenterlite.getMemberSrlById', $vars); - if($output->data && $output->data->member_srl) $list[] = $output->data->member_srl; + if($output->data && $output->data->member_srl) + { + $list[] = $output->data->member_srl; + } } } else @@ -930,7 +1043,10 @@ class ncenterliteController extends ncenterlite $vars = new stdClass(); $vars->nick_name = $nick_name; $output = executeQuery('ncenterlite.getMemberSrlByNickName', $vars); - if($output->data && $output->data->member_srl) $list[] = $output->data->member_srl; + if($output->data && $output->data->member_srl) + { + $list[] = $output->data->member_srl; + } } } From 8e39e77db75e489a45f35d05121969bc7fd6a7f5 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 07:55:08 +0900 Subject: [PATCH 209/318] Fixed the position of the comment --- modules/ncenterlite/ncenterlite.controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index f8368eb9f..ae9928f8e 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -654,10 +654,11 @@ class ncenterliteController extends ncenterlite // 알림 목록 가져오기 $_output = $oNcenterliteModel->getMyNotifyList(); + // 알림 메시지가 없어도 항상 표시하게 하려면 이 줄을 제거 또는 주석 처리하세요. if(!$_output->data) { return; - } // 알림 메시지가 없어도 항상 표시하게 하려면 이 줄을 제거 또는 주석 처리하세요. + } $_latest_notify_id = array_slice($_output->data, 0, 1); $_latest_notify_id = $_latest_notify_id[0]->notify; From e3e6a3d8f4907658003011052905ec790892a8f5 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 08:02:44 +0900 Subject: [PATCH 210/318] fix typo --- modules/ncenterlite/ncenterlite.controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ncenterlite/ncenterlite.controller.php b/modules/ncenterlite/ncenterlite.controller.php index ae9928f8e..c7bc678ab 100644 --- a/modules/ncenterlite/ncenterlite.controller.php +++ b/modules/ncenterlite/ncenterlite.controller.php @@ -820,7 +820,7 @@ class ncenterliteController extends ncenterlite $output = executeQuery('ncenterlite.updateNotifyReadedAll', $args); //$output = executeQuery('ncenterlite.deleteNotifyByMemberSrl', $args); - return $ouptut; + return $output; } function procNcenterliteNotifyReadAll() From d2960ddb9f52335e427223ae632cad703b7b2926 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 08:10:07 +0900 Subject: [PATCH 211/318] trigger ModuleObject deleted. --- modules/ncenterlite/ncenterlite.class.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/ncenterlite/ncenterlite.class.php b/modules/ncenterlite/ncenterlite.class.php index a622e9384..ccf8564a4 100644 --- a/modules/ncenterlite/ncenterlite.class.php +++ b/modules/ncenterlite/ncenterlite.class.php @@ -43,6 +43,9 @@ class ncenterlite extends ModuleObject array('document.updateVotedCount', 'ncenterlite', 'controller', 'triggerAfterVotedupdate', 'after'), array('moduleHandler.init', 'ncenterlite', 'controller', 'triggerAddMemberMenu', 'after'), ); + private $delete_triggers = array( + array('moduleObject.proc', 'ncenterlite', 'controller', 'triggerBeforeModuleObjectProc', 'before') + ); function _isDisable() { @@ -71,6 +74,14 @@ class ncenterlite extends ModuleObject if(!$oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) return true; } + foreach($this->delete_triggers as $trigger) + { + if($oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) + { + return true; + } + } + if(!$oDB->isColumnExists('ncenterlite_notify', 'readed')) { return true; @@ -138,6 +149,14 @@ class ncenterlite extends ModuleObject } } + foreach($this->delete_triggers as $trigger) + { + if($oModuleModel->getTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4])) + { + $oModuleController->deleteTrigger($trigger[0], $trigger[1], $trigger[2], $trigger[3], $trigger[4]); + } + } + if(!$oDB->isColumnExists('ncenterlite_notify','readed')) { $oDB->addColumn('ncenterlite_notify', 'readed', 'char', 1, 'N', true); From 5d13c67caec0269db916a68f3bb0384c3c24b72a Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 13:29:35 +0900 Subject: [PATCH 212/318] Merge Lang::getPluginLang() back into Lang::loadDirectory() --- common/framework/lang.php | 98 ++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 58 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index e2cfb49be..a08e0ce09 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -108,70 +108,52 @@ class Lang return true; } - // Load the language file. - $lang = $this->getPluginLang($dir); + // Initialize variables. + $filename = null; + $lang = new \stdClass; + $result = true; - // Load the default language file. + // Find a suitable language file in the given directory. + if (file_exists($dir . '/' . $this->_language . '.php')) + { + $filename = $dir . '/' . $this->_language . '.php'; + } + elseif (($hyphen = strpos($this->_language, '-')) !== false && file_exists($dir . '/' . substr($this->_language, 0, $hyphen) . '.php')) + { + $filename = $dir . '/' . substr($this->_language, 0, $hyphen) . '.php'; + } + elseif (file_exists("$dir/lang.xml")) + { + $filename = Parsers\LangParser::compileXMLtoPHP("$dir/lang.xml", $this->_language === 'ja' ? 'jp' : $this->_language); + } + elseif (file_exists($dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php')) + { + $filename = $dir . '/' . ($this->_language === 'ja' ? 'jp' : $this->_language) . '.lang.php'; + } + + // Load the language file. + if ($filename) + { + include $filename; + array_unshift($this->_search_priority, $plugin_name); + $result = true; + } + else + { + $result = false; + } + + // Mark this directory and plugin as loaded. + $this->_loaded_directories[$dir] = true; + $this->_loaded_plugins[$plugin_name] = $lang; + + // Load the same directory in the default language, too. if ($this->_language !== 'en') { self::getInstance('en')->loadDirectory($dir, $plugin_name); } - if (!empty($lang)) - { - $this->_loaded_directories[$dir] = true; - $this->_loaded_plugins[$plugin_name] = $lang; - array_unshift($this->_search_priority, $plugin_name); - return true; - } - else - { - $this->_loaded_directories[$dir] = true; - $this->_loaded_plugins[$plugin_name] = new \stdClass; - return false; - } - } - - /** - * Get the language file from plugin. - * - * @param string $dir - * @param string $language - * @return object - */ - public function getPluginLang($dir, $language = null) - { - if (!$language) - { - $language = $this->_language; - } - - if (file_exists($dir . '/' . $language . '.php')) - { - $filename = $dir . '/' . $language . '.php'; - } - elseif (($hyphen = strpos($language, '-')) !== false && file_exists($dir . '/' . substr($language, 0, $hyphen) . '.php')) - { - $filename = $dir . '/' . substr($language, 0, $hyphen) . '.php'; - } - elseif (file_exists("$dir/lang.xml")) - { - $filename = Parsers\LangParser::compileXMLtoPHP("$dir/lang.xml", $language === 'ja' ? 'jp' : $language); - } - elseif (file_exists($dir . '/' . ($language === 'ja' ? 'jp' : $language) . '.lang.php')) - { - $filename = $dir . '/' . ($language === 'ja' ? 'jp' : $language) . '.lang.php'; - } - - if (!$filename) - { - return new \stdClass; - } - - $lang = new \stdClass; - include $filename; - - return $lang; + return $result; } /** From ece681bda6fbf78cd4a613ffea4345c47b7191e1 Mon Sep 17 00:00:00 2001 From: BJRambo Date: Thu, 17 Mar 2016 13:47:28 +0900 Subject: [PATCH 213/318] revised language file info Rhymix form. --- modules/ncenterlite/lang/de.php | 1 + modules/ncenterlite/lang/en.php | 102 +++++++ modules/ncenterlite/lang/es.php | 1 + modules/ncenterlite/lang/fr.php | 1 + modules/ncenterlite/lang/ja.php | 70 +++++ modules/ncenterlite/lang/ko.php | 102 +++++++ modules/ncenterlite/lang/lang.xml | 458 ----------------------------- modules/ncenterlite/lang/mn.php | 1 + modules/ncenterlite/lang/ru.php | 1 + modules/ncenterlite/lang/tr.php | 1 + modules/ncenterlite/lang/vi.php | 1 + modules/ncenterlite/lang/zh-CN.php | 1 + modules/ncenterlite/lang/zh-TW.php | 1 + 13 files changed, 283 insertions(+), 458 deletions(-) create mode 100644 modules/ncenterlite/lang/de.php create mode 100644 modules/ncenterlite/lang/en.php create mode 100644 modules/ncenterlite/lang/es.php create mode 100644 modules/ncenterlite/lang/fr.php create mode 100644 modules/ncenterlite/lang/ja.php create mode 100644 modules/ncenterlite/lang/ko.php delete mode 100644 modules/ncenterlite/lang/lang.xml create mode 100644 modules/ncenterlite/lang/mn.php create mode 100644 modules/ncenterlite/lang/ru.php create mode 100644 modules/ncenterlite/lang/tr.php create mode 100644 modules/ncenterlite/lang/vi.php create mode 100644 modules/ncenterlite/lang/zh-CN.php create mode 100644 modules/ncenterlite/lang/zh-TW.php diff --git a/modules/ncenterlite/lang/de.php b/modules/ncenterlite/lang/de.php new file mode 100644 index 000000000..b3d9bbc7f --- /dev/null +++ b/modules/ncenterlite/lang/de.php @@ -0,0 +1 @@ +ncenterlite = 'Rhymix Notification Center Lite'; +$lang->ncenterlite_install_version = 'Installed Notification Center Lite version'; +$lang->ncenterlite_document = 'document'; +$lang->ncenterlite_comment = 'comment'; +$lang->ncenterlite_type_message = 'message'; +$lang->ncenterlite_sender = 'Sender'; +$lang->ncenterlite_addressee = 'Addressee'; +$lang->ncenterlite_noti_contents = 'Contents'; +$lang->ncenterlite_read = 'Have read'; +$lang->ncenterlite_read_y = 'Have read'; +$lang->ncenterlite_read_n = 'Not read'; +$lang->ncenterlite_no_target = 'no target'; +$lang->ncenterlite_my_list = 'My notification list'; +$lang->ncenterlite_my_settings = 'My notification settings'; +$lang->ncenterlite_user_settings = 'User notification settings'; +$lang->ncenterlite_userconfig_title = 'Notification Center Settings of %s'; +$lang->ncenterlite_userconfig_about = 'Personalized settings of notification center can be controlled by you.'; +$lang->ncenterlite_comment_noti = 'Comment notice'; +$lang->ncenterlite_comment_noti_about = 'Get notice of a comment after someone replies to my documents or comments.'; +$lang->ncenterlite_mention_noti = 'Mention notice'; +$lang->ncenterlite_mention_noti_about = 'Get notice of a mention after someone mention me on documents and/or comments. ( @Nickname to mention )'; +$lang->ncenterlite_message_noti = 'Message notice'; +$lang->ncenterlite_message_noti_about = 'Get notice of a message after someone send the message to me.'; +$lang->ncenterlite_activate = 'Activate'; +$lang->ncenterlite_inactivate = 'Inactivate'; +$lang->ncenterlite_userconfig_about_warning = 'Watch out! You are controlling other user\'s settings via this page.'; +$lang->ncenterlite_article = '%1$s wrote an article as "%2$s".'; +$lang->ncenterlite_board = '%1$s wrote an article as "%3$s" on the board %2$s.'; +$lang->ncenterlite_commented = '%1$s commented as "%3$s" on your %2$s.'; +$lang->ncenterlite_commented_board = '%1$s commented as "%3$s" on the board %2$s.'; +$lang->ncenterlite_mentioned = '%s mentioned you on "%s" %s.'; +$lang->ncenterlite_message_string = 'You have %d new message(s).'; +$lang->ncenterlite_message_mention = '%1$s sent a message as "%2$s".'; +$lang->ncenterlite_test_noti = '%s! Skin test notification has been done.'; +$lang->ncenterlite_vote = '%1$s marked the article "%2$s" with a recommendation.'; +$lang->ncenterlite_ago = 'ago'; +$lang->ncenterlite_date['0'] = 'Year'; +$lang->ncenterlite_date['1'] = 'Month'; +$lang->ncenterlite_date['2'] = 'Day'; +$lang->ncenterlite_date['3'] = 'Hour'; +$lang->ncenterlite_date['4'] = 'Minute'; +$lang->ncenterlite_date['5'] = 'Second'; +$lang->ncenterlite_sir = ' '; +$lang->ncenterlite_message = 'You have %s notification.'; +$lang->ncenterlite_messages = 'you have %s notifications.'; +$lang->ncenterlite_thisistest = '[*] This is a test notice.'; +$lang->ncenterlite_delete_all = 'delete all'; +$lang->ncenterlite_more = 'More'; +$lang->ncenterlite_stop_login_required = 'Sign in to control your own notification settings.'; +$lang->ncenterlite_stop_no_permission_other_user = 'You don\'t have the authority to read settings of other members.'; +$lang->ncenterlite_stop_no_permission_other_user_settings = 'You don\'t have the authority to control settings of other members.'; +$lang->ncenterlite_message_delete_notification_before = 'Notifications before %s are deleted.'; +$lang->ncenterlite_message_delete_notification_all = 'Every notification is deleted.'; +$lang->ncenterlite_config_environment = 'HELP! Agreement on gathering server environment information'; +$lang->ncenterlite_config_environment_about = ' +

    \'Notification Center Lite\' is distributed as an free software.

    +

    \'Notification Center Lite\' is developing with collective intelligence, such as users\' bug reports, suggestions and/or contributions.
    If you select to \'Agree on gathering\', the items below will be gathered by developers of this program, and the information will be referenced to enhance functions of this program. Thank you.

    +
      +
    • Domain name of this website
    • +
    • Version value of Notification Center Lite
    • +
    • XE Core version value
    • +
    • PHP version value
    • +
    + '; +$lang->ncenterlite_config_environment_agree = 'Agree on gathering'; +$lang->ncenterlite_config_environment_disagree = 'Disagree on gathering'; +$lang->ncenterlite_click_to_open = 'Click here to open'; +$lang->ncenterlite_notice_list = 'Notification list'; +$lang->ncenterlite_basic_settings = 'Basic function settings'; +$lang->ncenterlite_warning = 'Watch out!'; +$lang->ncenterlite_io = 'Activate Notification Center'; +$lang->ncenterlite_io_about = 'You can activate or inactivate every function of Notification Center Lite module.'; +$lang->ncenterlite_on = 'Active'; +$lang->ncenterlite_off = 'Inactive'; +$lang->ncenterlite_display = 'Display Notification Center'; +$lang->ncenterlite_display_y = 'Display'; +$lang->ncenterlite_display_n = 'Hide'; +$lang->ncenterlite_display_about = '알림센터의 스킨을 사용할 것인지 혹은 위젯 레이아웃에서 제작되어 들어간 스킨을 사용할지 선택합니다. 기본은 알림센터모듈의 기본스킨을 사용하도록 합니다. + Watch out! 알림센터를 레이아웃이나 위젯으로 표현할 수 있을 때에만 동작안함 선택하세요.'; +$lang->ncenterlite_mention_target = 'Mention target'; +$lang->ncenterlite_mention_target_about = 'Mention target can be nicknames or IDs (@Nickname or @ID).'; +$lang->ncenterlite_skin_settings = 'Skin settings'; +$lang->ncenterlite_zindex = 'Z-index of notification'; +$lang->ncenterlite_zindex_about = 'Some elements that have high z-index can hide notification layer. If so, set z-index of notification layer as 100, 200, and so on to show it.'; +$lang->ncenterlite_test_make_dummy = 'Make dummy data'; +$lang->ncenterlite_test_mention = 'Web page notification test'; +$lang->ncenterlite_test_mention_about = 'Create dummy data for module and/or skin test.'; +$lang->ncenterlite_test_push = 'Push notification test'; +$lang->ncenterlite_test_push_about = 'Create dummy data for mobile push notification test.'; +$lang->ncenterlite_document_event_settings = 'Document event notification'; +$lang->ncenterlite_document_event_vote = 'Recommendation'; +$lang->ncenterlite_document_event_vote_about = 'When someone recommend document, the author of it can get notifying.'; +$lang->ncenterlite_document_event_read = 'Delete notifying after read the article'; +$lang->ncenterlite_document_event_read_preserve = 'Preserve notification'; +$lang->ncenterlite_document_event_read_delete = 'Delete notification'; +$lang->ncenterlite_document_event_read_about = 'Delete every notification after read the article. Default is do not delete (preserve).'; +$lang->ncenterlite_commnet_event = 'Comments'; +$lang->ncenterlite_commnet_event_noti_all = 'Notice every comments to the author'; +$lang->ncenterlite_commnet_event_noti_some = 'Notice only direct replies to the author'; +$lang->ncenterlite_message_event = 'Notify message'; +$lang->ncenterlite_message_event_about = 'Do not notify message (Use XE Core message notification system).'; diff --git a/modules/ncenterlite/lang/es.php b/modules/ncenterlite/lang/es.php new file mode 100644 index 000000000..b3d9bbc7f --- /dev/null +++ b/modules/ncenterlite/lang/es.php @@ -0,0 +1 @@ +ncenterlite = 'Rhymix 通知センター Lite'; +$lang->ncenterlite_install_version = 'Installed Rhymix 通知センター Lite version'; +$lang->ncenterlite_document = '書き込み'; +$lang->ncenterlite_comment = 'コメント'; +$lang->ncenterlite_type_message = 'メッセージ'; +$lang->ncenterlite_sender = 'Sender'; +$lang->ncenterlite_addressee = 'Addressee'; +$lang->ncenterlite_noti_contents = 'Contents'; +$lang->ncenterlite_read = 'Have read'; +$lang->ncenterlite_read_y = 'Have read'; +$lang->ncenterlite_read_n = 'Not read'; +$lang->ncenterlite_no_target = 'no target'; +$lang->ncenterlite_my_list = 'My notification list'; +$lang->ncenterlite_my_settings = 'My notification settings'; +$lang->ncenterlite_user_settings = 'User notification settings'; +$lang->ncenterlite_userconfig_title = 'Notification Center Settings of %s'; +$lang->ncenterlite_userconfig_about = 'Personalized settings of notification center can be controlled by you.'; +$lang->ncenterlite_comment_noti = 'Comment notice'; +$lang->ncenterlite_comment_noti_about = 'Get notice of a comment after someone replies to my documents or comments.'; +$lang->ncenterlite_mention_noti = 'Mention notice'; +$lang->ncenterlite_mention_noti_about = 'Get notice of a mention after someone mention me on documents and/or comments. ( @Nickname to mention )'; +$lang->ncenterlite_message_noti = 'Message notice'; +$lang->ncenterlite_message_noti_about = 'Get notice of a message after someone send the message to me.'; +$lang->ncenterlite_activate = 'Activate'; +$lang->ncenterlite_inactivate = 'Inactivate'; +$lang->ncenterlite_userconfig_about_warning = 'Watch out! You are controlling other user\'s settings via this page.'; +$lang->ncenterlite_article = '%1$s wrote an article as "%2$s".'; +$lang->ncenterlite_board = '%1$s wrote an article as "%3$s" on the board %2$s.'; +$lang->ncenterlite_commented = '%sさんがあなたの%sに「%s」とコメントしました。'; +$lang->ncenterlite_commented_board = '%1$s commented as "%3$s" on the board %2$s.'; +$lang->ncenterlite_mentioned = '%sさんが「%s」%sにあなたをタグ付けしました。'; +$lang->ncenterlite_message_string = '%d件の読んでないメッセージがあります。'; +$lang->ncenterlite_message_mention = '%1$s sent a message as "%2$s".'; +$lang->ncenterlite_test_noti = '%s! Skin test notification has been done.'; +$lang->ncenterlite_vote = '%1$s marked the article "%2$s" with a recommendation.'; +$lang->ncenterlite_ago = '前'; +$lang->ncenterlite_date['0'] = '年'; +$lang->ncenterlite_date['1'] = 'ヶ月'; +$lang->ncenterlite_date['2'] = '日'; +$lang->ncenterlite_date['3'] = '時間'; +$lang->ncenterlite_date['4'] = '分'; +$lang->ncenterlite_date['5'] = '秒'; +$lang->ncenterlite_sir = 'さん'; +$lang->ncenterlite_message = '%s件のお知らせがあります。'; +$lang->ncenterlite_messages = '%s件のお知らせがあります。'; +$lang->ncenterlite_thisistest = '[*] This is a test notice.'; +$lang->ncenterlite_delete_all = 'すべて削除'; +$lang->ncenterlite_more = 'もっと見る'; +$lang->ncenterlite_stop_login_required = 'Sign in to control your own notification settings.'; +$lang->ncenterlite_stop_no_permission_other_user = 'You don\'t have the authority to read settings of other members.'; +$lang->ncenterlite_stop_no_permission_other_user_settings = 'You don\'t have the authority to control settings of other members.'; +$lang->ncenterlite_message_delete_notification_before = 'Notifications before %s are deleted.'; +$lang->ncenterlite_message_delete_notification_all = 'Every notification is deleted.'; +$lang->ncenterlite_config_environment = 'HELP! Agreement on gathering server environment information'; +$lang->ncenterlite_config_environment_about = ' +

    \'Notification Center Lite\' is distributed as an free software.

    +

    \'Notification Center Lite\' is developing with collective intelligence, such as users\' bug reports, suggestions and/or contributions.
    If you select to \'Agree on gathering\', the items below will be gathered by developers of this program, and the information will be referenced to enhance functions of this program. Thank you.

    +
      +
    • Domain name of this website
    • +
    • Version value of Notification Center Lite
    • +
    • XE Core version value
    • +
    • PHP version value
    • +
    + '; +$lang->ncenterlite_config_environment_agree = 'Agree on gathering'; +$lang->ncenterlite_config_environment_disagree = 'Disagree on gathering'; +$lang->ncenterlite_click_to_open = 'Click here to open'; +$lang->ncenterlite_notice_list = 'Notification list'; +$lang->ncenterlite_basic_settings = 'Basic function settings'; diff --git a/modules/ncenterlite/lang/ko.php b/modules/ncenterlite/lang/ko.php new file mode 100644 index 000000000..0af3cc4bf --- /dev/null +++ b/modules/ncenterlite/lang/ko.php @@ -0,0 +1,102 @@ +ncenterlite = 'Rhymix 알림센터 Lite'; +$lang->ncenterlite_install_version = '설치된 알림센터 Lite 버전'; +$lang->ncenterlite_document = '글'; +$lang->ncenterlite_comment = '댓글'; +$lang->ncenterlite_type_message = '쪽지'; +$lang->ncenterlite_sender = '보낸 사람'; +$lang->ncenterlite_addressee = '받는 사람'; +$lang->ncenterlite_noti_contents = '내용'; +$lang->ncenterlite_read = '읽음 확인'; +$lang->ncenterlite_read_y = '읽음'; +$lang->ncenterlite_read_n = '읽지 않음'; +$lang->ncenterlite_no_target = '대상 없음'; +$lang->ncenterlite_my_list = '내 알림 목록'; +$lang->ncenterlite_my_settings = '내 알림 설정'; +$lang->ncenterlite_user_settings = '사용자 알림 설정'; +$lang->ncenterlite_userconfig_title = '%s님의 알림센터 설정'; +$lang->ncenterlite_userconfig_about = '알림센터의 개인의 설정을 저장하도록 합니다.'; +$lang->ncenterlite_comment_noti = '댓글 알림'; +$lang->ncenterlite_comment_noti_about = '내 게시물의 혹은 내 댓글에 댓글이 달릴경우 알림을 받습니다.'; +$lang->ncenterlite_mention_noti = '멘션 알림'; +$lang->ncenterlite_mention_noti_about = '누군가 글, 혹은 댓글을 통해서 나를 맨션 했을 경우 알려줍니다. (맨션 방법 @닉네임 )'; +$lang->ncenterlite_message_noti = '쪽지 알림'; +$lang->ncenterlite_message_noti_about = '누군가에게 받은 쪽지를 알림을 받습니다.'; +$lang->ncenterlite_activate = '사용'; +$lang->ncenterlite_inactivate = '사용 안함'; +$lang->ncenterlite_userconfig_about_warning = '주의! 당신은 관리자 권한으로 다른 사용자의 설정창을 접속하였습니다.'; +$lang->ncenterlite_article = '%1$s님이 "%2$s"라고 글을 남겼습니다.'; +$lang->ncenterlite_board = '%1$s님이 게시판 "%2$s""%3$s"라고 글을 남겼습니다.'; +$lang->ncenterlite_commented = '%1$s님이 회원님의 %2$s에 "%3$s"라고 댓글을 남겼습니다.'; +$lang->ncenterlite_commented_board = '%1$s님이 게시판 "%2$s""%3$s"라고 댓글을 남겼습니다.'; +$lang->ncenterlite_mentioned = '%s님이 "%s" %s에서 회원님을 언급하였습니다.'; +$lang->ncenterlite_message_string = '%d개의 읽지 않은 메시지가 있습니다.'; +$lang->ncenterlite_message_mention = '%s님께서 "%s"라고 메세지를 보내셨습니다.'; +$lang->ncenterlite_test_noti = '%s님! 스킨 테스트 알림을 완료했습니다.'; +$lang->ncenterlite_vote = '%s님이 "%s" 글을 추천하였습니다.'; +$lang->ncenterlite_ago = '전'; +$lang->ncenterlite_date['0'] = '년'; +$lang->ncenterlite_date['1'] = '개월'; +$lang->ncenterlite_date['2'] = '일'; +$lang->ncenterlite_date['3'] = '시간'; +$lang->ncenterlite_date['4'] = '분'; +$lang->ncenterlite_date['5'] = '초'; +$lang->ncenterlite_sir = '님'; +$lang->ncenterlite_message = '%s개의 알림이 있습니다.'; +$lang->ncenterlite_messages = '%s개의 알림이 있습니다.'; +$lang->ncenterlite_thisistest = '[*] 시험용 알림입니다'; +$lang->ncenterlite_delete_all = '모두 삭제'; +$lang->ncenterlite_more = '더보기'; +$lang->ncenterlite_stop_login_required = '알림센터 설정을 하시려면 로그인 해주세요.'; +$lang->ncenterlite_stop_no_permission_other_user = '다른 회원의 설정을 볼 권한이 없습니다.'; +$lang->ncenterlite_stop_no_permission_other_user_settings = '다른 회원의 설정을 변경할 권한이 없습니다.'; +$lang->ncenterlite_message_delete_notification_before = '%s까지 알림 정보를 삭제했습니다.'; +$lang->ncenterlite_message_delete_notification_all = '모든 알림을 삭제했습니다.'; +$lang->ncenterlite_config_environment = '도와주세요! 사용 환경 정보 제공 동의'; +$lang->ncenterlite_config_environment_about = ' +

    \'알림센터 Lite\'를 자유소프트웨어로 제공하고 있습니다.

    +

    \'알림센터 Lite\'는 사용자의 버그 보고, 의견 제출을 통해 공동의 힘으로 발전하고 있습니다.
    \'제공 동의\'를 선택하면 아래와 같은 항목이 전송되며, 알림센터 Lite의 기능을 개선하는데 참고하겠습니다. 감사합니다.

    +
      +
    • 이 사이트의 도메인
    • +
    • 알림센터 Lite의 버전
    • +
    • XE 버전
    • +
    • PHP 버전
    • +
    + '; +$lang->ncenterlite_config_environment_agree = '제공 동의'; +$lang->ncenterlite_config_environment_disagree = '제공 안 함'; +$lang->ncenterlite_click_to_open = '클릭하시면 기능설정을 할 수 있습니다.'; +$lang->ncenterlite_notice_list = '알림 목록'; +$lang->ncenterlite_basic_settings = '기본 기능 설정'; +$lang->ncenterlite_warning = '주의!'; +$lang->ncenterlite_io = '알림센터 동작여부'; +$lang->ncenterlite_io_about = '알림센터의 모든 기능을 중지 시킬 수 있습니다.'; +$lang->ncenterlite_on = '동작'; +$lang->ncenterlite_off = '동작 안 함'; +$lang->ncenterlite_display = '알림센터 노출여부'; +$lang->ncenterlite_display_y = '노출'; +$lang->ncenterlite_display_n = '숨김'; +$lang->ncenterlite_display_about = '알림센터의 스킨을 사용할 것인지 혹은 위젯 레이아웃에서 제작되어 들어간 스킨을 사용할지 선택합니다. 기본은 알림센터모듈의 기본스킨을 사용하도록 합니다. + 주의! 알림센터를 레이아웃이나 위젯으로 표현할 수 있을 때에만 동작안함 선택하세요.'; +$lang->ncenterlite_mention_target = '멘션 타겟 설정'; +$lang->ncenterlite_mention_target_about = '알림센터에서 닉네임 혹은 아이디 선택하여 맨션설정을 할 수 있습니다.'; +$lang->ncenterlite_skin_settings = '스킨 설정'; +$lang->ncenterlite_zindex = '알림센터의 z-index'; +$lang->ncenterlite_zindex_about = '알림센터가 다른 요소에 가려지는 경우에 100, 200, ... 이상으로 높여 보세요.'; +$lang->ncenterlite_test_make_dummy = '더미 데이터 생성'; +$lang->ncenterlite_test_mention = '시험용 스킨 알림 생성'; +$lang->ncenterlite_test_mention_about = '스킨 및 모듈 테스트를 위한 시험용 알림 생성.'; +$lang->ncenterlite_test_push = '시험용 푸시 알림 생성'; +$lang->ncenterlite_test_push_about = '모듈 및 모바일 테스트를 위한 시험용 알림 생성'; +$lang->ncenterlite_document_event_settings = '새 글 알림 및 문서알림'; +$lang->ncenterlite_document_event_vote = '글 추천 알림'; +$lang->ncenterlite_document_event_vote_about = '글이 추천받았을때 추천알림을 받을 수 있습니다.'; +$lang->ncenterlite_document_event_read = '게시판 읽을경우 관련알림 삭제'; +$lang->ncenterlite_document_event_read_preserve = '알림을 지우지 않음'; +$lang->ncenterlite_document_event_read_delete = '알림을 지움'; +$lang->ncenterlite_document_event_read_about = '게시판을 읽을경우 해당 글의 포함된 모든 알림내역을 알림내역에서 삭제 합니다. 기본값은 알림을 보존합니다.'; +$lang->ncenterlite_commnet_event = '댓글 알림 설정'; +$lang->ncenterlite_commnet_event_noti_all = '글쓴이에게 모든 댓글 알림'; +$lang->ncenterlite_commnet_event_noti_some = '대댓글은 알리지 않음'; +$lang->ncenterlite_message_event = '쪽지 알림 설정'; +$lang->ncenterlite_message_event_about = '쪽지 알림을 사용하지 않음(XE의 기본 쪽지 알림을 사용)'; diff --git a/modules/ncenterlite/lang/lang.xml b/modules/ncenterlite/lang/lang.xml deleted file mode 100644 index 4e2e080f0..000000000 --- a/modules/ncenterlite/lang/lang.xml +++ /dev/null @@ -1,458 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %1$s님이 "%2$s"라고 글을 남겼습니다.]]> - %1$s wrote an article as "%2$s".]]> - %1$s wrote an article as "%2$s".]]> - - - %1$s님이 게시판 "%2$s""%3$s"라고 글을 남겼습니다.]]> - %1$s wrote an article as "%3$s" on the board %2$s.]]> - %1$s wrote an article as "%3$s" on the board %2$s.]]> - - - %1$s님이 회원님의 %2$s에 "%3$s"라고 댓글을 남겼습니다.]]> - %1$s commented as "%3$s" on your %2$s.]]> - %sさんがあなたの%sに「%s」とコメントしました。]]> - - - %1$s님이 게시판 "%2$s""%3$s"라고 댓글을 남겼습니다.]]> - %1$s commented as "%3$s" on the board %2$s.]]> - %1$s commented as "%3$s" on the board %2$s.]]> - - - %s님이 "%s" %s에서 회원님을 언급하였습니다.]]> - %s mentioned you on "%s" %s.]]> - %sさんが「%s」%sにあなたをタグ付けしました。]]> - - - %d개의 읽지 않은 메시지가 있습니다.]]> - %d new message(s).]]> - %d件の読んでないメッセージがあります。]]> - - - %s님께서 "%s"라고 메세지를 보내셨습니다.]]> - %1$s sent a message as "%2$s".]]> - %1$s sent a message as "%2$s".]]> - - - %s님! 스킨 테스트 알림을 완료했습니다.]]> - %s! Skin test notification has been done.]]> - %s! Skin test notification has been done.]]> - - - %s님이 "%s" 글을 추천하였습니다.]]> - %1$s marked the article "%2$s" with a recommendation.]]> - %1$s marked the article "%2$s" with a recommendation.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - %s개의 알림이 있습니다.]]> - %s notification.]]> - %s件のお知らせがあります。]]> - - - %s개의 알림이 있습니다.]]> - %s notifications.]]> - %s件のお知らせがあります。]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 도와주세요! 사용 환경 정보 제공 동의]]> - HELP! Agreement on gathering server environment information]]> - HELP! Agreement on gathering server environment information]]> - - - '알림센터 Lite'를 자유소프트웨어로 제공하고 있습니다.

    -

    '알림센터 Lite'는 사용자의 버그 보고, 의견 제출을 통해 공동의 힘으로 발전하고 있습니다.
    '제공 동의'를 선택하면 아래와 같은 항목이 전송되며, 알림센터 Lite의 기능을 개선하는데 참고하겠습니다. 감사합니다.

    -
      -
    • 이 사이트의 도메인
    • -
    • 알림센터 Lite의 버전
    • -
    • XE 버전
    • -
    • PHP 버전
    • -
    - ]]>
    - 'Notification Center Lite' is distributed as an free software.

    -

    'Notification Center Lite' is developing with collective intelligence, such as users' bug reports, suggestions and/or contributions.
    If you select to 'Agree on gathering', the items below will be gathered by developers of this program, and the information will be referenced to enhance functions of this program. Thank you.

    -
      -
    • Domain name of this website
    • -
    • Version value of Notification Center Lite
    • -
    • XE Core version value
    • -
    • PHP version value
    • -
    - ]]>
    - 'Notification Center Lite' is distributed as an free software.

    -

    'Notification Center Lite' is developing with collective intelligence, such as users' bug reports, suggestions and/or contributions.
    If you select to 'Agree on gathering', the items below will be gathered by developers of this program, and the information will be referenced to enhance functions of this program. Thank you.

    -
      -
    • Domain name of this website
    • -
    • Version value of Notification Center Lite
    • -
    • XE Core version value
    • -
    • PHP version value
    • -
    - ]]>
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 주의! 알림센터를 레이아웃이나 위젯으로 표현할 수 있을 때에만 동작안함 선택하세요.]]> - Watch out! 알림센터를 레이아웃이나 위젯으로 표현할 수 있을 때에만 동작안함 선택하세요.]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    \ No newline at end of file diff --git a/modules/ncenterlite/lang/mn.php b/modules/ncenterlite/lang/mn.php new file mode 100644 index 000000000..b3d9bbc7f --- /dev/null +++ b/modules/ncenterlite/lang/mn.php @@ -0,0 +1 @@ + Date: Thu, 17 Mar 2016 13:58:57 +0900 Subject: [PATCH 214/318] Refactor default language search routine for better performance --- common/framework/lang.php | 111 +++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 54 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index a08e0ce09..ec47de9ad 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -191,6 +191,24 @@ class Lang $this->__set($key, $value); } + /** + * Fallback method for getting the default translation. + * + * @param string $key + * @return string + */ + public function getFromDefaultLang($key) + { + if ($this->_language === 'en') + { + return $key; + } + else + { + return self::getInstance('en')->__get($key); + } + } + /** * Magic method for translations without arguments. * @@ -199,45 +217,58 @@ class Lang */ public function __get($key) { - // Get default language - if ($this->_language !== 'en') + // Load a dot-separated key (prefixed by plugin name). + if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key)) && count($keys) >= 2) { - $lang_en = self::getInstance('en')->{$key}; - } - - // Separate the plugin name from the key. - if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key, 2)) && count($keys) === 2) - { - list($plugin_name, $lang_key) = $keys; + // Attempt to load the plugin. + $plugin_name = array_shift($keys); if (!isset($this->_loaded_plugins[$plugin_name])) { $this->loadPlugin($plugin_name); } - - if (isset($this->_loaded_plugins[$plugin_name]->{$lang_key})) + if (!isset($this->_loaded_plugins[$plugin_name])) { - $lang = $this->_loaded_plugins[$plugin_name]->{$lang_key}; - if (is_array($lang) && is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) + return $this->getFromDefaultLang($key); + } + + // Find the given key. + $lang = $this->_loaded_plugins[$plugin_name]; + foreach ($keys as $subkey) + { + if (isset($lang->{$subkey})) { - return $lang_en; + $lang = is_scalar($lang->{$subkey}) ? $lang->{$subkey} : new \ArrayObject($lang->{$subkey}, 3); } - + else + { + return $this->getFromDefaultLang($key); + } + } + return $lang; + } + + // Search custom translations first. + if (isset($this->_loaded_plugins['_custom_']->{$key})) + { + $lang = $this->_loaded_plugins['_custom_']->{$key}; + if (is_array($lang)) + { + return new \ArrayObject($lang, 3); + } + else + { return $lang; } } - else + + // Search other plugins. + foreach ($this->_search_priority as $plugin_name) { - // Search custom translations first. - if (isset($this->_loaded_plugins['_custom_']->{$key})) + if (isset($this->_loaded_plugins[$plugin_name]->{$key})) { - $lang = $this->_loaded_plugins['_custom_']->{$key}; + $lang = $this->_loaded_plugins[$plugin_name]->{$key}; if (is_array($lang)) { - if (is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) - { - return new \ArrayObject($lang_en, 3); - } - return new \ArrayObject($lang, 3); } else @@ -245,38 +276,10 @@ class Lang return $lang; } } - - // Search other plugins. - foreach ($this->_search_priority as $plugin_name) - { - if (isset($this->_loaded_plugins[$plugin_name]->{$key})) - { - $lang = $this->_loaded_plugins[$plugin_name]->{$key}; - if (is_array($lang)) - { - if (is_array($lang_en) && count($lang_en, COUNT_RECURSIVE) > count($lang, COUNT_RECURSIVE)) - { - return new \ArrayObject($lang_en, 3); - } - - return new \ArrayObject($lang, 3); - } - else - { - return $lang; - } - } - } } - // Search other language. - if (isset($lang_en)) - { - return $lang_en; - } - - // If no translation is found, return the key. - return $key; + // If no translation is found, return the default language. + return $this->getFromDefaultLang($key); } /** From 014e7f13a495f54fa0505dd68315d5c044b5ae0f Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 14:11:33 +0900 Subject: [PATCH 215/318] Move string interpolation from __call() to get() --- common/framework/lang.php | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index ec47de9ad..8366e715f 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -176,7 +176,19 @@ class Lang { $args = func_get_args(); array_shift($args); - return $this->__call($key, $args); + if (count($args) === 1 && is_array($args[0])) + { + $args = $args[0]; + } + + // Get the translation. + $translation = $this->__get($key); + + // If there are no arguments, return the translation. + if (!count($args)) return $translation; + + // If there are arguments, interpolate them into the translation and return the result. + return vsprintf($translation, $args); } /** @@ -338,16 +350,6 @@ class Lang */ public function __call($key, $args = array()) { - // Remove a colon from the beginning of the string. - if ($key !== '' && $key[0] === ':') $key = substr($key, 1); - - // Find the translation. - $translation = $this->__get($key); - - // If there are no arguments, return the translation. - if (!count($args)) return $translation; - - // If there are arguments, interpolate them into the translation and return the result. - return vsprintf($translation, $args); + return $this->get($key, $args); } } From ef30f0fa408dcb12e0a4dbd774a756f3753505fc Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 14:19:35 +0900 Subject: [PATCH 216/318] Update and expand unit tests for Lang class --- tests/unit/framework/LangTest.php | 42 +++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/tests/unit/framework/LangTest.php b/tests/unit/framework/LangTest.php index 2ca57cb61..094cb9843 100644 --- a/tests/unit/framework/LangTest.php +++ b/tests/unit/framework/LangTest.php @@ -4,30 +4,50 @@ class LangTest extends \Codeception\TestCase\Test { public function testLang() { + // Test separation of languages. $ko = Rhymix\Framework\Lang::getInstance('ko'); $en = Rhymix\Framework\Lang::getInstance('en'); $this->assertTrue($ko instanceof Rhymix\Framework\Lang); $this->assertTrue($en instanceof Rhymix\Framework\Lang); $this->assertFalse($ko === $en); + // Test backward compatible language code for Japanese. $ja = Rhymix\Framework\Lang::getInstance('ja'); $jp = Rhymix\Framework\Lang::getInstance('jp'); $this->assertTrue($ja === $jp); - $this->assertEquals('도움말', $ko->get('common.help')); - $this->assertEquals('Help', $en->get('common.help')); - $this->assertEquals('도움말', $ko->help); - $this->assertEquals('Help', $en->help); - - $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent')); - $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent', 'foo', 'bar')); - - $this->assertEquals('admin.help', $ko->get('admin.help')); - $this->assertEquals('admin.help', $en->get('admin.help')); - + // Test loading new plugins. + $this->assertNotEquals('ヘルプ', $ja->help); $ja->loadPlugin('common'); $this->assertEquals('ヘルプ', $ja->help); + // Test simple translations with namespacing. + $this->assertEquals('도움말', $ko->get('common.help')); + $this->assertEquals('Help', $en->get('common.help')); + + // Test simple translations without namespacing. + $this->assertEquals('도움말', $ko->help); + $this->assertEquals('Help', $en->help); + + // Test complex translations with multidimensional arrays. + $this->assertEquals('%d분 전', $ko->get('common.time_gap.min')); + $this->assertEquals('10분 전', $ko->get('common.time_gap.min', 10)); + $this->assertTrue($ko->get('common.time_gap') instanceof \ArrayObject); + $this->assertEquals('%d분 전', $ko->get('common.time_gap')->min); + + // Test nonexistent keys. + $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent')); + $this->assertEquals('common.nonexistent', $ko->get('common.nonexistent', 'foo', 'bar')); + $this->assertEquals('admin.help', $ko->get('admin.help')); + $this->assertEquals('admin.help', $en->get('admin.help')); + + // Test fallback to English. + $en->only_in_english = 'Hello world'; + $this->assertEquals('Hello world', $ko->only_in_english); + $this->assertEquals('Hello world', $en->only_in_english); + $this->assertEquals('Hello world', $ja->only_in_english); + + // Test string interpolation. $ko->foobartestlang = '%s님 안녕하세요?'; $this->assertEquals('Travis님 안녕하세요?', $ko->foobartestlang('Travis')); $en->foobartestlang = 'Hello, %s!'; From 15e33606098e619fadd7e79007816b786c43e421 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 14:52:05 +0900 Subject: [PATCH 217/318] Also support dot notation when setting new language keys --- common/framework/lang.php | 103 ++++++++++++++++++++++-------- tests/unit/framework/LangTest.php | 13 ++++ 2 files changed, 90 insertions(+), 26 deletions(-) diff --git a/common/framework/lang.php b/common/framework/lang.php index 8366e715f..023ece8d7 100644 --- a/common/framework/lang.php +++ b/common/framework/lang.php @@ -247,30 +247,27 @@ class Lang $lang = $this->_loaded_plugins[$plugin_name]; foreach ($keys as $subkey) { - if (isset($lang->{$subkey})) + if (is_object($lang) && isset($lang->{$subkey})) { - $lang = is_scalar($lang->{$subkey}) ? $lang->{$subkey} : new \ArrayObject($lang->{$subkey}, 3); + $lang = $lang->{$subkey}; + } + elseif (is_array($lang) && isset($lang[$subkey])) + { + $lang = $lang[$subkey]; } else { return $this->getFromDefaultLang($key); } } - return $lang; + return is_array($lang) ? new \ArrayObject($lang, 3) : $lang; } // Search custom translations first. if (isset($this->_loaded_plugins['_custom_']->{$key})) { $lang = $this->_loaded_plugins['_custom_']->{$key}; - if (is_array($lang)) - { - return new \ArrayObject($lang, 3); - } - else - { - return $lang; - } + return is_array($lang) ? new \ArrayObject($lang, 3) : $lang; } // Search other plugins. @@ -279,14 +276,7 @@ class Lang if (isset($this->_loaded_plugins[$plugin_name]->{$key})) { $lang = $this->_loaded_plugins[$plugin_name]->{$key}; - if (is_array($lang)) - { - return new \ArrayObject($lang, 3); - } - else - { - return $lang; - } + return is_array($lang) ? new \ArrayObject($lang, 3) : $lang; } } @@ -303,6 +293,73 @@ class Lang */ public function __set($key, $value) { + // Set a dot-separated key (prefixed by plugin name). + if (preg_match('/^[a-z0-9_.-]+$/i', $key) && ($keys = explode('.', $key)) && count($keys) >= 2) + { + // Attempt to load the plugin. + $plugin_name = array_shift($keys); + if (!isset($this->_loaded_plugins[$plugin_name])) + { + $this->loadPlugin($plugin_name); + } + if (!isset($this->_loaded_plugins[$plugin_name])) + { + return false; + } + + // Set the given key. + $count = count($keys); + $lang = $this->_loaded_plugins[$plugin_name]; + foreach ($keys as $i => $subkey) + { + if (is_object($lang) && isset($lang->{$subkey})) + { + if ($i === $count - 1) + { + $lang->{$subkey} = $value; + break; + } + elseif (is_array($lang->{$subkey})) + { + $lang = &$lang->{$subkey}; + } + else + { + return false; + } + } + elseif (is_array($lang) && isset($lang[$subkey])) + { + if ($i === $count - 1) + { + $lang[$subkey] = $value; + break; + } + elseif (is_array($lang[$subkey])) + { + $lang = &$lang[$subkey]; + } + else + { + return false; + } + } + else + { + if (is_object($lang)) + { + $lang->{$subkey} = $value; + } + else + { + $lang[$subkey] = $value; + } + break; + } + } + } + + // Set a regular key. $this->_loaded_plugins['_custom_']->{$key} = $value; } @@ -332,13 +389,7 @@ class Lang */ public function __unset($key) { - foreach ($this->_loaded_plugins as $plugin_name => $translations) - { - if (isset($translations->{$key})) - { - unset($translations->{$key}); - } - } + $this->set($key, null); } /** diff --git a/tests/unit/framework/LangTest.php b/tests/unit/framework/LangTest.php index 094cb9843..4533b063c 100644 --- a/tests/unit/framework/LangTest.php +++ b/tests/unit/framework/LangTest.php @@ -41,6 +41,19 @@ class LangTest extends \Codeception\TestCase\Test $this->assertEquals('admin.help', $ko->get('admin.help')); $this->assertEquals('admin.help', $en->get('admin.help')); + // Test setting new keys with and without namespacing. + $ko->set('foo', 'FOO!'); + $this->assertEquals('FOO!', $ko->get('foo')); + $ko->set('common.foobar', 'FOOBAR!'); + $this->assertEquals('FOOBAR!', $ko->get('common.foobar')); + $this->assertEquals('FOOBAR!', $ko->get('foobar')); + + // Test setting new keys with multidimensional arrays. + $ko->set('common.time_gap.foobar', 'FOOBAR!'); + $this->assertEquals('FOOBAR!', $ko->get('common.time_gap.foobar')); + $ko->set('common.foobar.baz', 'BAZ!'); + $this->assertNotEquals('BAZ!', $ko->get('common.foobar.baz')); + // Test fallback to English. $en->only_in_english = 'Hello world'; $this->assertEquals('Hello world', $ko->only_in_english); From a9d6cf598d30a73f959277fdc616e178b51a95e1 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 15:45:31 +0900 Subject: [PATCH 218/318] Add MIME class --- classes/mail/Mail.class.php | 76 +-------------- common/framework/mime.php | 152 ++++++++++++++++++++++++++++++ tests/unit/framework/MIMETest.php | 22 +++++ 3 files changed, 175 insertions(+), 75 deletions(-) create mode 100644 common/framework/mime.php create mode 100644 tests/unit/framework/MIMETest.php diff --git a/classes/mail/Mail.class.php b/classes/mail/Mail.class.php index c2d9725db..465e623be 100644 --- a/classes/mail/Mail.class.php +++ b/classes/mail/Mail.class.php @@ -460,81 +460,7 @@ class Mail */ 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], "."); - } + return Rhymix\Framework\MIME::getTypeByFilename($filename); } } diff --git a/common/framework/mime.php b/common/framework/mime.php new file mode 100644 index 000000000..00488659a --- /dev/null +++ b/common/framework/mime.php @@ -0,0 +1,152 @@ + $mime) + { + if (!strncasecmp($type, $mime, strlen($type))) return $extension; + } + return false; + } + + /** + * The default MIME type for unknown extensions. + */ + protected static $_default = 'application/octet-stream'; + + /** + * The list of known MIME types. + */ + protected static $_types = array( + + // Text-based document formats. + 'html' => 'text/html', + 'htm' => 'text/html', + 'shtml' => 'text/html', + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => 'text/plain', + 'rtf' => 'text/rtf', + 'xml' => 'text/xml', + 'xsl' => 'text/xml', + 'css' => 'text/css', + 'csv' => 'text/csv', + + // Binary document formats. + 'doc' => 'application/msword', + 'dot' => 'application/msword', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + 'odp' => 'application/vnd.oasis.opendocument.presentation', + 'odg' => 'application/vnd.oasis.opendocument.graphics', + 'odb' => 'application/vnd.oasis.opendocument.database', + 'pdf' => 'application/pdf', + + // Images. + 'bmp' => 'image/bmp', + 'gif' => 'image/gif', + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpe' => 'image/jpeg', + 'png' => 'image/png', + 'svg' => 'image/svg+xml', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'ico' => 'image/vnd.microsoft.icon', + + // Audio. + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => 'audio/mpeg', + 'aif' => 'audio/x-aiff', + 'aiff' => 'audio/x-aiff', + 'ra' => 'audio/x-realaudio', + 'wav' => 'audio/x-wav', + 'ogg' => 'audio/ogg', + + // Video. + 'avi' => 'video/x-msvideo', + 'flv' => 'video/x-flv', + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'mp4' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'movie' => 'video/x-sgi-movie', + 'rv' => 'video/vnd.rn-realvideo', + 'dvi' => 'application/x-dvi', + + // Other multimedia file formats. + 'psd' => 'application/x-photoshop', + 'swf' => 'application/x-shockwave-flash', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'mif' => 'application/vnd.mif', + 'xul' => 'application/vnd.mozilla.xul+xml', + + // Source code formats. + 'phps' => 'application/x-httpd-php-source', + 'js' => 'application/x-javascript', + + // Archives. + 'bz2' => 'application/x-bzip', + 'gz' => 'application/x-gzip', + 'tar' => 'application/x-tar', + 'tgz' => 'application/x-tar', + 'gtar' => 'application/x-gtar', + 'rar' => 'application/x-rar-compressed', + 'zip' => 'application/x-zip', + + // RFC822 email message. + 'eml' => 'message/rfc822', + ); +} diff --git a/tests/unit/framework/MIMETest.php b/tests/unit/framework/MIMETest.php new file mode 100644 index 000000000..f62324ce7 --- /dev/null +++ b/tests/unit/framework/MIMETest.php @@ -0,0 +1,22 @@ +assertEquals('audio/ogg', Rhymix\Framework\MIME::getTypeByExtension('ogg')); + $this->assertEquals('image/gif', Rhymix\Framework\MIME::getTypeByExtension('gif')); + $this->assertEquals('text/html', Rhymix\Framework\MIME::getTypeByExtension('htm')); + + $this->assertEquals('application/msword', Rhymix\Framework\MIME::getTypeByFilename('attachment.doc')); + $this->assertEquals('application/pdf', Rhymix\Framework\MIME::getTypeByFilename('라이믹스.pdf')); + $this->assertEquals('application/postscript', Rhymix\Framework\MIME::getTypeByFilename('MyGraphics.v2.eps')); + $this->assertEquals('application/vnd.ms-excel', Mail::returnMIMEType('MySpreadsheet.xls')); + $this->assertEquals('application/octet-stream', Mail::returnMIMEType('Untitled File')); + + $this->assertEquals('odt', Rhymix\Framework\MIME::getExtensionByType('application/vnd.oasis.opendocument.text')); + $this->assertEquals('jpg', Rhymix\Framework\MIME::getExtensionByType('image/jpeg')); + $this->assertEquals('mpeg', Rhymix\Framework\MIME::getExtensionByType('video/mpeg')); + $this->assertFalse(Rhymix\Framework\MIME::getExtensionByType('application/octet-stream')); + } +} From 63006e025a0ba871a29c77e120b4e69ae17fc36f Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 16:04:36 +0900 Subject: [PATCH 219/318] Add Timer class --- common/framework/timer.php | 109 +++++++++++++++++++++++++++++ tests/unit/framework/TimerTest.php | 63 +++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 common/framework/timer.php create mode 100644 tests/unit/framework/TimerTest.php diff --git a/common/framework/timer.php b/common/framework/timer.php new file mode 100644 index 000000000..b4650b663 --- /dev/null +++ b/common/framework/timer.php @@ -0,0 +1,109 @@ +assertGreaterThanOrEqual($t1, $started); + $this->assertLessThanOrEqual($t2, $started); + $this->assertGreaterThanOrEqual($t2 - $started, $elapsed); + $this->assertLessThanOrEqual($t3 - $t1, $elapsed); + $this->assertGreaterThan(0, $elapsed); + } + + function testNestedTimers() + { + $t1 = Rhymix\Framework\Timer::start(); + $t2 = Rhymix\Framework\Timer::start(); + $t3 = Rhymix\Framework\Timer::stop(); + $t4 = Rhymix\Framework\Timer::stop(); + + $this->assertGreaterThanOrEqual($t1, $t2); + $this->assertGreaterThan($t4, $t3); + } + + function testMultipleTimers() + { + $t1 = Rhymix\Framework\Timer::start('timer1'); + usleep(5000); + $t2 = Rhymix\Framework\Timer::start('timer2'); + + $t3 = Rhymix\Framework\Timer::stop('timer1'); + usleep(2000); + $t4 = Rhymix\Framework\Timer::stop('timer2'); + + $this->assertGreaterThanOrEqual($t1, $t2); + $this->assertGreaterThanOrEqual($t4, $t3); + } + + function testTimerFormat() + { + $t1 = Rhymix\Framework\Timer::start(); + $t2 = Rhymix\Framework\Timer::stopFormat(); + + $this->assertRegexp('/^[0-9\.]+ms$/', $t2); + } + + function testTimerSinceStartup() + { + $t1 = Rhymix\Framework\Timer::sinceStartup(); + $t2 = Rhymix\Framework\Timer::sinceStartup(); + + $this->assertGreaterThanOrEqual($t1, $t2); + + $t3 = Rhymix\Framework\Timer::sinceStartupFormat(); + $this->assertRegexp('/^[0-9\.]+ms$/', $t3); + } +} From 15a0c591dc0bbfb0dcf0d77b97f91b03d215186b Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 16:22:18 +0900 Subject: [PATCH 220/318] Add Calendar class --- common/framework/calendar.php | 132 ++++++++++++++++++++++++++ tests/unit/framework/CalendarTest.php | 52 ++++++++++ 2 files changed, 184 insertions(+) create mode 100644 common/framework/calendar.php create mode 100644 tests/unit/framework/CalendarTest.php diff --git a/common/framework/calendar.php b/common/framework/calendar.php new file mode 100644 index 000000000..43f49a030 --- /dev/null +++ b/common/framework/calendar.php @@ -0,0 +1,132 @@ +assertEquals('January', Rhymix\Framework\Calendar::getMonthName('01')); + $this->assertEquals('October', Rhymix\Framework\Calendar::getMonthName('10')); + $this->assertEquals('Nov', Rhymix\Framework\Calendar::getMonthName(11, false)); + $this->assertEquals('Dec', Rhymix\Framework\Calendar::getMonthName(12, false)); + } + + public function testGetMonthStartDayOfWeek() + { + $this->assertEquals(5, Rhymix\Framework\Calendar::getMonthStartDayOfWeek(1, 2016)); + $this->assertEquals(1, Rhymix\Framework\Calendar::getMonthStartDayOfWeek(2, 2016)); + $this->assertEquals(2, Rhymix\Framework\Calendar::getMonthStartDayOfWeek(3, 2016)); + $this->assertEquals(5, Rhymix\Framework\Calendar::getMonthStartDayOfWeek(4, 2016)); + } + + public function testGetMonthDays() + { + $this->assertEquals(30, Rhymix\Framework\Calendar::getMonthDays(11, 2015)); + $this->assertEquals(31, Rhymix\Framework\Calendar::getMonthDays(12, 2015)); + $this->assertEquals(31, Rhymix\Framework\Calendar::getMonthDays(1, 2016)); + $this->assertEquals(29, Rhymix\Framework\Calendar::getMonthDays(2, 2016)); + } + + public function testGetMonthCalendar() + { + $target_201508 = array( + array(null, null, null, null, null, null, 1), + array(2, 3, 4, 5, 6, 7, 8), + array(9, 10, 11, 12, 13, 14, 15), + array(16, 17, 18, 19, 20, 21, 22), + array(23, 24, 25, 26, 27, 28, 29), + array(30, 31, null, null, null, null, null), + ); + + $target_201603 = array( + array(null, null, 1, 2, 3, 4, 5), + array(6, 7, 8, 9, 10, 11, 12), + array(13, 14, 15, 16, 17, 18, 19), + array(20, 21, 22, 23, 24, 25, 26), + array(27, 28, 29, 30, 31, null, null), + array(null, null, null, null, null, null, null), + ); + + $this->assertEquals($target_201508, Rhymix\Framework\Calendar::getMonthCalendar(8, 2015)); + $this->assertEquals($target_201603, Rhymix\Framework\Calendar::getMonthCalendar(3, 2016)); + } +} From 8b559598803fee0ca8d896819a86fca4995df752 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 16:24:27 +0900 Subject: [PATCH 221/318] Fix unit tests to accommodate exceptionally long-running tests --- tests/unit/framework/TimerTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/framework/TimerTest.php b/tests/unit/framework/TimerTest.php index d69623563..87dd9bc6d 100644 --- a/tests/unit/framework/TimerTest.php +++ b/tests/unit/framework/TimerTest.php @@ -47,7 +47,7 @@ class TimerTest extends \Codeception\TestCase\Test $t1 = Rhymix\Framework\Timer::start(); $t2 = Rhymix\Framework\Timer::stopFormat(); - $this->assertRegexp('/^[0-9\.]+ms$/', $t2); + $this->assertRegexp('/^[0-9\.,]+ms$/', $t2); } function testTimerSinceStartup() @@ -58,6 +58,6 @@ class TimerTest extends \Codeception\TestCase\Test $this->assertGreaterThanOrEqual($t1, $t2); $t3 = Rhymix\Framework\Timer::sinceStartupFormat(); - $this->assertRegexp('/^[0-9\.]+ms$/', $t3); + $this->assertRegexp('/^[0-9\.,]+ms$/', $t3); } } From 475c8d49a9264c8163420a8c8f4a1b685f9fa844 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 17:33:58 +0900 Subject: [PATCH 222/318] Fix short array syntax --- common/framework/calendar.php | 4 ++-- common/framework/timer.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/common/framework/calendar.php b/common/framework/calendar.php index 43f49a030..b24e7b379 100644 --- a/common/framework/calendar.php +++ b/common/framework/calendar.php @@ -101,7 +101,7 @@ class Calendar $count = self::getMonthDays($month_number, $year); $initial_blank_cells = (7 + $start - $start_dow) % 7; $final_blank_cells = 42 - $count - $initial_blank_cells; - $temp = []; + $temp = array(); for ($i = 0; $i < $initial_blank_cells; $i++) { @@ -116,7 +116,7 @@ class Calendar $temp[] = null; } - $return = []; + $return = array(); for ($i = 0; $i < 6; $i++) { $week = []; diff --git a/common/framework/timer.php b/common/framework/timer.php index b4650b663..86842158a 100644 --- a/common/framework/timer.php +++ b/common/framework/timer.php @@ -10,7 +10,7 @@ class Timer /** * Timestamps are stored here. */ - protected static $_timestamps = []; + protected static $_timestamps = array(); /** * Start a timer. From 509893e791cf2e7372caed674aa25fae507d7263 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 17:41:03 +0900 Subject: [PATCH 223/318] Fix short array syntax and backwards test --- common/framework/calendar.php | 2 +- tests/unit/framework/TimerTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common/framework/calendar.php b/common/framework/calendar.php index b24e7b379..67aaafbe4 100644 --- a/common/framework/calendar.php +++ b/common/framework/calendar.php @@ -119,7 +119,7 @@ class Calendar $return = array(); for ($i = 0; $i < 6; $i++) { - $week = []; + $week = array(); for ($j = 0; $j < 7; $j++) { $week[] = array_shift($temp); diff --git a/tests/unit/framework/TimerTest.php b/tests/unit/framework/TimerTest.php index 87dd9bc6d..b0427d688 100644 --- a/tests/unit/framework/TimerTest.php +++ b/tests/unit/framework/TimerTest.php @@ -25,7 +25,7 @@ class TimerTest extends \Codeception\TestCase\Test $t4 = Rhymix\Framework\Timer::stop(); $this->assertGreaterThanOrEqual($t1, $t2); - $this->assertGreaterThan($t4, $t3); + $this->assertGreaterThan($t3, $t4); } function testMultipleTimers() From 97c10ab2cf4e8a141e95fb47ba7bd6c503ec7df0 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 17:45:15 +0900 Subject: [PATCH 224/318] Add some delays to timer test --- tests/unit/framework/TimerTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/unit/framework/TimerTest.php b/tests/unit/framework/TimerTest.php index b0427d688..1c9783c0d 100644 --- a/tests/unit/framework/TimerTest.php +++ b/tests/unit/framework/TimerTest.php @@ -5,9 +5,13 @@ class TimerTest extends \Codeception\TestCase\Test function testStartStop() { $t1 = microtime(true); + usleep(1000); $started = Rhymix\Framework\Timer::start(); + usleep(1000); $t2 = microtime(true); + usleep(1000); $elapsed = Rhymix\Framework\Timer::stop(); + usleep(1000); $t3 = microtime(true); $this->assertGreaterThanOrEqual($t1, $started); @@ -20,8 +24,11 @@ class TimerTest extends \Codeception\TestCase\Test function testNestedTimers() { $t1 = Rhymix\Framework\Timer::start(); + usleep(1000); $t2 = Rhymix\Framework\Timer::start(); + usleep(1000); $t3 = Rhymix\Framework\Timer::stop(); + usleep(1000); $t4 = Rhymix\Framework\Timer::stop(); $this->assertGreaterThanOrEqual($t1, $t2); @@ -33,7 +40,7 @@ class TimerTest extends \Codeception\TestCase\Test $t1 = Rhymix\Framework\Timer::start('timer1'); usleep(5000); $t2 = Rhymix\Framework\Timer::start('timer2'); - + usleep(1000); $t3 = Rhymix\Framework\Timer::stop('timer1'); usleep(2000); $t4 = Rhymix\Framework\Timer::stop('timer2'); @@ -45,6 +52,7 @@ class TimerTest extends \Codeception\TestCase\Test function testTimerFormat() { $t1 = Rhymix\Framework\Timer::start(); + usleep(1000); $t2 = Rhymix\Framework\Timer::stopFormat(); $this->assertRegexp('/^[0-9\.,]+ms$/', $t2); From 59ee4a7387831e127f245d545eff7aebeb975008 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Thu, 17 Mar 2016 19:46:32 +0900 Subject: [PATCH 225/318] Add pagination class --- common/framework/pagination.php | 153 ++++++++++++++++++++++++ tests/unit/framework/PaginationTest.php | 48 ++++++++ 2 files changed, 201 insertions(+) create mode 100644 common/framework/pagination.php create mode 100644 tests/unit/framework/PaginationTest.php diff --git a/common/framework/pagination.php b/common/framework/pagination.php new file mode 100644 index 000000000..cc26906e4 --- /dev/null +++ b/common/framework/pagination.php @@ -0,0 +1,153 @@ + $total_pages) + { + $last_shown = $total_pages; + } + } + else + { + $first_shown = $current_page - floor(($count - 1) / 2); + if ($first_shown < 1) + { + $first_shown = 1; + } + $last_shown = $first_shown + $count - 1; + if ($last_shown > $total_pages) + { + $last_shown = $total_pages; + $first_shown = max(1, $last_shown - $count + 1); + } + } + + // Open the
    tag. + $return = array('
    - +
    - + + + + - From 5a935779cc461d84796a114580afa8f8f68d4ee9 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sat, 5 Mar 2016 14:50:33 +0900 Subject: [PATCH 076/318] Add more incompatible addons and modules to blacklist --- common/defaults/blacklist.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/defaults/blacklist.php b/common/defaults/blacklist.php index bcbe7904f..fed12c706 100644 --- a/common/defaults/blacklist.php +++ b/common/defaults/blacklist.php @@ -6,6 +6,9 @@ * Copyright (c) Rhymix Developers and Contributors */ return array( + 'autolang' => true, + 'errorlogger' => true, + 'fix_mysql_utf8' => true, 'member_communication' => true, 'smartphone' => true, 'zipperupper' => true, From cb206acfc0438f8a4a983e315269a5289849f2a0 Mon Sep 17 00:00:00 2001 From: conory Date: Sat, 5 Mar 2016 17:45:51 +0900 Subject: [PATCH 077/318] =?UTF-8?q?=EC=83=88=20=EC=AA=BD=EC=A7=80=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=AC=B8=EC=A0=9C=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../communication.controller.php | 56 ++++++++++++---- modules/communication/communication.view.php | 66 ++++++++++++------- .../tpl/js/member_communication.js | 11 +--- 3 files changed, 87 insertions(+), 46 deletions(-) diff --git a/modules/communication/communication.controller.php b/modules/communication/communication.controller.php index b45dd42e6..289096a3b 100644 --- a/modules/communication/communication.controller.php +++ b/modules/communication/communication.controller.php @@ -254,15 +254,17 @@ class communicationController extends communication $oDB->rollback(); return $trigger_output; } - + + $oDB->commit(); + // create a flag that message is sent (in file format) $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(); + + $oCommunicationModel = getModel('communication'); + $new_message_count = $oCommunicationModel->getNewMessageCount($receiver_srl); + FileHandler::writeFile($flag_file, $new_message_count); return new Object(0, 'success_sended'); } @@ -771,10 +773,30 @@ class communicationController extends communication */ function setMessageReaded($message_srl) { - $args = new stdClass(); + $args = new stdClass; $args->message_srl = $message_srl; $args->related_srl = $message_srl; - return executeQuery('communication.setMessageReaded', $args); + $output = executeQuery('communication.setMessageReaded', $args); + + // Renew a flag + $logged_info = Context::get('logged_info'); + $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)) + { + $oCommunicationModel = getModel('communication'); + $new_message_count = $oCommunicationModel->getNewMessageCount(); + if($new_message_count > 0) + { + FileHandler::writeFile($flag_file, $new_message_count); + } + else + { + FileHandler::removeFile($flag_file); + } + } + + return $output; } function triggerModuleHandlerBefore($obj) @@ -805,18 +827,24 @@ class communicationController extends communication $oMemberController->addMemberMenu('dispCommunicationFriend', 'cmd_view_friend'); } - if($config->enable_message == 'Y') + if($config->enable_message == 'Y' && $obj->act != 'dispCommunicationNewMessage') { - $flag_file = './files/member_extra_info/new_message_flags/' . getNumberingPath($logged_info->member_srl) . $logged_info->member_srl; + $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)) { // Pop-up to display messages if a flag on new message is set $new_message_count = (int) trim(FileHandler::readFile($flag_file)); - $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); - Context::addHtmlFooter(""); - Context::loadFile(array('./modules/communication/tpl/js/member_communication.js'), true); - - FileHandler::removeFile($flag_file); + if($new_message_count > 0) + { + $text = preg_replace('@\r?\n@', '\\n', addslashes(Context::getLang('alert_new_message_arrived'))); + Context::addHtmlFooter(""); + Context::loadFile(array('./modules/communication/tpl/js/member_communication.js'), true); + } + else + { + FileHandler::removeFile($flag_file); + } } } } diff --git a/modules/communication/communication.view.php b/modules/communication/communication.view.php index 23c008524..ff3c10dc2 100644 --- a/modules/communication/communication.view.php +++ b/modules/communication/communication.view.php @@ -17,10 +17,10 @@ class communicationView extends communication { $oCommunicationModel = getModel('communication'); - $this->communication_config = $oCommunicationModel->getConfig(); - $skin = $this->communication_config->skin; + $this->config = $oCommunicationModel->getConfig(); + $skin = $this->config->skin; - Context::set('communication_config', $this->communication_config); + Context::set('communication_config', $this->config); $config_parse = explode('|@|', $skin); @@ -36,10 +36,10 @@ class communicationView extends communication $this->setTemplatePath($tpl_path); $oLayoutModel = getModel('layout'); - $layout_info = $oLayoutModel->getLayout($this->communication_config->layout_srl); + $layout_info = $oLayoutModel->getLayout($this->config->layout_srl); if($layout_info) { - $this->module_info->layout_srl = $this->communication_config->layout_srl; + $this->module_info->layout_srl = $this->config->layout_srl; $this->setLayoutPath($layout_info->path); } } @@ -50,6 +50,11 @@ class communicationView extends communication */ function dispCommunicationMessages() { + if($this->config->enable_message == 'N') + { + return $this->stop('msg_invalid_request'); + } + // Error appears if not logged-in if(!Context::get('is_logged')) { @@ -58,11 +63,6 @@ class communicationView extends communication $logged_info = Context::get('logged_info'); - if(!array_key_exists('dispCommunicationMessages', $logged_info->menu_list)) - { - return $this->stop('msg_invalid_request'); - } - // Set the variables $message_srl = Context::get('message_srl'); $message_type = Context::get('message_type'); @@ -138,6 +138,11 @@ class communicationView extends communication $this->setLayoutPath('./common/tpl/'); $this->setLayoutFile('popup_layout'); + if($this->config->enable_message == 'N') + { + return $this->stop('msg_invalid_request'); + } + // Error appears if not logged-in if(!Context::get('is_logged')) { @@ -157,11 +162,6 @@ class communicationView extends communication Context::set('message', $message); } - // Delete a flag - $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'); } @@ -174,9 +174,11 @@ class communicationView extends communication $this->setLayoutPath('./common/tpl/'); $this->setLayoutFile("popup_layout"); - $oCommunicationModel = getModel('communication'); - $oMemberModel = getModel('member'); - + if($this->config->enable_message == 'N') + { + return $this->stop('msg_invalid_request'); + } + // Error appears if not logged-in if(!Context::get('is_logged')) { @@ -199,6 +201,9 @@ class communicationView extends communication return $this->stop('msg_cannot_send_to_yourself'); } + $oCommunicationModel = getModel('communication'); + $oMemberModel = getModel('member'); + // get message_srl of the original message if it is a reply $message_srl = Context::get('message_srl'); if($message_srl) @@ -235,8 +240,8 @@ class communicationView extends communication $option->resizable = FALSE; $option->disable_html = TRUE; $option->height = 300; - $option->skin = $this->communication_config->editor_skin; - $option->colorset = $this->communication_config->editor_colorset; + $option->skin = $this->config->editor_skin; + $option->colorset = $this->config->editor_colorset; $editor = $oEditorModel->getEditor($logged_info->member_srl, $option); Context::set('editor', $editor); @@ -249,12 +254,17 @@ class communicationView extends communication */ function dispCommunicationFriend() { + if($this->config->enable_friend == 'N') + { + return $this->stop('msg_invalid_request'); + } + // Error appears if not logged-in if(!Context::get('is_logged')) { return $this->stop('msg_not_logged'); } - + $oCommunicationModel = getModel('communication'); // get a group list @@ -307,7 +317,12 @@ class communicationView extends communication { $this->setLayoutPath('./common/tpl/'); $this->setLayoutFile("popup_layout"); - + + if($this->config->enable_friend == 'N') + { + return $this->stop('msg_invalid_request'); + } + // error appears if not logged-in if(!Context::get('is_logged')) { @@ -349,7 +364,12 @@ class communicationView extends communication { $this->setLayoutPath('./common/tpl/'); $this->setLayoutFile("popup_layout"); - + + if($this->config->enable_friend == 'N') + { + return $this->stop('msg_invalid_request'); + } + // error apprears if not logged-in if(!Context::get('is_logged')) { diff --git a/modules/communication/tpl/js/member_communication.js b/modules/communication/tpl/js/member_communication.js index 78f6501e2..e0e71d1a3 100644 --- a/modules/communication/tpl/js/member_communication.js +++ b/modules/communication/tpl/js/member_communication.js @@ -11,16 +11,9 @@ }) .prependTo(document.body); } + text = text.replace('%d', count); - var cur_module = current_url.getQuery('module'); - if( cur_module == "admin" ) - h = $bar.html('

    '+text+'

    ').height(); - else - h = $bar.html('

    '+text+'

    ').height(); + $bar.html('

    '+text+'

    ').height(); $bar.show().animate({top:0}); - // hide after 10 seconds - setTimeout(function(){ - $bar.slideUp(); - }, 5000); }; })(jQuery); From 622a6d932496d6ef3110c6002fe0bacfb68e1ce5 Mon Sep 17 00:00:00 2001 From: conory Date: Sat, 5 Mar 2016 18:03:28 +0900 Subject: [PATCH 078/318] =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=EB=A9=94=EC=8B=9C?= =?UTF-8?q?=EC=A7=80=20=ED=81=B4=EB=A6=AD=EC=8B=9C=202=EC=B4=88=20?= =?UTF-8?q?=ED=9B=84=EC=97=90=20=EB=A9=94=EC=84=B8=EC=A7=80=20=EB=8B=AB?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/communication/tpl/js/member_communication.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/communication/tpl/js/member_communication.js b/modules/communication/tpl/js/member_communication.js index e0e71d1a3..ae6f8c013 100644 --- a/modules/communication/tpl/js/member_communication.js +++ b/modules/communication/tpl/js/member_communication.js @@ -1,6 +1,6 @@ (function($){ + var $bar; window.xeNotifyMessage = function(text, count){ - var $bar; $bar = $('div.message.info'); if(!$bar.length) { $bar = $('
    ') @@ -13,7 +13,13 @@ } text = text.replace('%d', count); - $bar.html('

    '+text+'

    ').height(); + $bar.html('

    '+text+'

    ').height(); $bar.show().animate({top:0}); }; + + window.xeNotifyMessageClose = function(){ + setTimeout(function(){ + $bar.slideUp(); + }, 2000); + }; })(jQuery); From bd6f7d6542579e5347f28ca0e22ae465b6f6ff0a Mon Sep 17 00:00:00 2001 From: conory Date: Sat, 5 Mar 2016 23:05:41 +0900 Subject: [PATCH 079/318] =?UTF-8?q?lang()=20=ED=95=A8=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/functions.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/common/functions.php b/common/functions.php index a1bd7234a..154d60455 100644 --- a/common/functions.php +++ b/common/functions.php @@ -25,6 +25,31 @@ function config($key, $value = null) } } +/** + * Get or set lang variable. + * + * @param string $code Lang variable name + * @param string $value `$code`s value + * @return mixed + */ +function lang($code, $value = null) +{ + if (!$GLOBALS['lang'] instanceof Rhymix\Framework\Lang) + { + $GLOBALS['lang'] = Rhymix\Framework\Lang::getInstance(Context::getLangType() ?: config('locale.default_lang') ?: 'ko'); + $GLOBALS['lang']->loadDirectory(RX_BASEDIR . 'common/lang', 'common'); + } + + if ($value === null) + { + return $GLOBALS['lang']->get($code); + } + else + { + $GLOBALS['lang']->set($code, $value); + } +} + /** * Get the first value of an array. * From 7b0c24e67cf360a833bb47c1ab4b43ed54a237c2 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Sun, 6 Mar 2016 14:13:34 +0900 Subject: [PATCH 080/318] Improve debug settings --- classes/display/DisplayHandler.class.php | 26 ++++++++++++++++-- common/defaults/config.php | 3 +-- common/framework/debug.php | 4 +-- common/tpl/debug_comment.html | 18 ++++++++----- modules/admin/admin.admin.controller.php | 6 +++-- modules/admin/admin.admin.view.php | 3 +-- modules/admin/lang/ko.php | 10 +++++-- modules/admin/tpl/config_debug.html | 34 +++++++++++------------- 8 files changed, 68 insertions(+), 36 deletions(-) diff --git a/classes/display/DisplayHandler.class.php b/classes/display/DisplayHandler.class.php index f48da0460..8ed67bf13 100644 --- a/classes/display/DisplayHandler.class.php +++ b/classes/display/DisplayHandler.class.php @@ -149,6 +149,27 @@ class DisplayHandler extends Handler { case 'panel': $data = Rhymix\Framework\Debug::getDebugData(); + $display_content = array_fill_keys(config('debug.display_content'), true); + if (count($display_content) && !isset($display_content['entries'])) + { + $data->entries = null; + } + if (count($display_content) && !isset($display_content['queries'])) + { + unset($data->queries); + } + if (count($display_content) && !isset($display_content['slow_queries'])) + { + unset($data->slow_queries); + } + if (count($display_content) && !isset($display_content['slow_triggers'])) + { + unset($data->slow_triggers); + } + if (count($display_content) && !isset($display_content['slow_widgets'])) + { + unset($data->slow_widgets); + } if ($data->entries) { foreach ($data->entries as &$entry) @@ -206,8 +227,9 @@ class DisplayHandler extends Handler } ob_start(); $data = Rhymix\Framework\Debug::getDebugData(); + $display_content = array_fill_keys(config('debug.display_content'), true); include RX_BASEDIR . 'common/tpl/debug_comment.html'; - $content = ob_get_clean(); + $content = preg_replace('/\n{2,}/', "\n\n", trim(ob_get_clean())) . PHP_EOL; if ($display_type === 'file') { $log_filename = config('debug.log_filename') ?: 'files/debug/YYYYMMDD.php'; @@ -226,7 +248,7 @@ class DisplayHandler extends Handler { $phpheader = ''; } - FileHandler::writeFile($log_filename, $phpheader . $content, 'a'); + FileHandler::writeFile($log_filename, $phpheader . $content . PHP_EOL, 'a'); return ''; } else diff --git a/common/defaults/config.php b/common/defaults/config.php index 71ee5ff4f..2262d7be6 100644 --- a/common/defaults/config.php +++ b/common/defaults/config.php @@ -87,13 +87,12 @@ return array( ), 'debug' => array( 'enabled' => true, - 'log_errors' => true, - 'log_queries' => false, 'log_slow_queries' => 0, 'log_slow_triggers' => 0, 'log_slow_widgets' => 0, 'log_filename' => null, 'display_type' => 'comment', + 'display_content' => array(), 'display_to' => 'admin', 'allow' => array(), ), diff --git a/common/framework/debug.php b/common/framework/debug.php index ea1dec766..87877ba14 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -496,8 +496,8 @@ class Debug 'trans' => sprintf('%0.4f sec', $GLOBALS['__trans_content_elapsed__']), ), 'entries' => self::$_entries, - 'errors' => config('debug.log_errors') ? self::$_errors : null, - 'queries' => config('debug.log_queries') ? self::$_queries : null, + 'errors' => self::$_errors, + 'queries' => self::$_queries, 'slow_queries' => self::$_slow_queries, 'slow_triggers' => self::$_slow_triggers, 'slow_widgets' => self::$_slow_widgets, diff --git a/common/tpl/debug_comment.html b/common/tpl/debug_comment.html index db0b873b0..ca05800df 100644 --- a/common/tpl/debug_comment.html +++ b/common/tpl/debug_comment.html @@ -2,6 +2,7 @@ timestamp . ']' . "\n"; ?> + Request / Response ================== Request URL: url . "\n"; ?> @@ -25,7 +26,9 @@ Resource Usage ============== Peak Memory Usage: Included Files: + + Debug Entries ============= + + PHP Errors and Warnings ======================= -errors === null): ?> -Error logging is disabled. - errors)) @@ -74,11 +76,9 @@ Error logging is disabled. ?> + Database Queries ================ -queries === null): ?> -Query logging is disabled. - queries)) @@ -99,6 +99,7 @@ Query logging is disabled. ?> + Slow Queries ============ + + Slow Triggers ============= trigger_time) . "\n"; } ?> + + Slow Widgets ============ widget_time) . "\n"; } ?> + diff --git a/modules/admin/admin.admin.controller.php b/modules/admin/admin.admin.controller.php index a4873f482..ac1a17e96 100644 --- a/modules/admin/admin.admin.controller.php +++ b/modules/admin/admin.admin.controller.php @@ -702,14 +702,16 @@ class adminAdminController extends admin // Debug settings Rhymix\Framework\Config::set('debug.enabled', $vars->debug_enabled === 'Y'); - Rhymix\Framework\Config::set('debug.log_errors', $vars->debug_log_errors === 'Y'); - Rhymix\Framework\Config::set('debug.log_queries', $vars->debug_log_queries === 'Y'); Rhymix\Framework\Config::set('debug.log_slow_queries', max(0, floatval($vars->debug_log_slow_queries))); Rhymix\Framework\Config::set('debug.log_slow_triggers', max(0, floatval($vars->debug_log_slow_triggers))); Rhymix\Framework\Config::set('debug.log_slow_widgets', max(0, floatval($vars->debug_log_slow_widgets))); Rhymix\Framework\Config::set('debug.display_type', strval($vars->debug_display_type) ?: 'comment'); Rhymix\Framework\Config::set('debug.display_to', strval($vars->debug_display_to) ?: 'admin'); + // Debug content + $debug_content = array_values($vars->debug_display_content); + Rhymix\Framework\Config::set('debug.display_content', $debug_content); + // Log filename $log_filename = strval($vars->debug_log_filename); $log_filename_today = str_replace(array('YYYY', 'YY', 'MM', 'DD'), array( diff --git a/modules/admin/admin.admin.view.php b/modules/admin/admin.admin.view.php index c31f8dd0c..8823175fd 100644 --- a/modules/admin/admin.admin.view.php +++ b/modules/admin/admin.admin.view.php @@ -491,13 +491,12 @@ class adminAdminView extends admin { // Load debug settings. Context::set('debug_enabled', Rhymix\Framework\Config::get('debug.enabled')); - Context::set('debug_log_errors', Rhymix\Framework\Config::get('debug.log_errors')); - Context::set('debug_log_queries', Rhymix\Framework\Config::get('debug.log_queries')); Context::set('debug_log_slow_queries', Rhymix\Framework\Config::get('debug.log_slow_queries')); Context::set('debug_log_slow_triggers', Rhymix\Framework\Config::get('debug.log_slow_triggers')); Context::set('debug_log_slow_widgets', Rhymix\Framework\Config::get('debug.log_slow_widgets')); Context::set('debug_log_filename', Rhymix\Framework\Config::get('debug.log_filename') ?: 'files/debug/YYYYMMDD.php'); Context::set('debug_display_type', Rhymix\Framework\Config::get('debug.display_type')); + Context::set('debug_display_content', Rhymix\Framework\Config::get('debug.display_content')); Context::set('debug_display_to', Rhymix\Framework\Config::get('debug.display_to')); // IP access control diff --git a/modules/admin/lang/ko.php b/modules/admin/lang/ko.php index 3e959816e..0c3f720cb 100644 --- a/modules/admin/lang/ko.php +++ b/modules/admin/lang/ko.php @@ -107,8 +107,6 @@ $lang->use_sftp_support = 'SFTP 사용'; $lang->disable_sftp_support = 'SFTP를 사용하려면 PHP에 ssh2 모듈이 설치되어 있어야 합니다.'; $lang->msg_self_restart_cache_engine = 'Memcached 또는 캐시 서비스를 재시작해 주세요.'; $lang->debug_enabled = '디버그 기능 사용'; -$lang->debug_log_errors = '에러 기록'; -$lang->debug_log_queries = '쿼리 기록'; $lang->debug_log_slow_queries = '느린 쿼리 기록'; $lang->debug_log_slow_triggers = '느린 트리거 기록'; $lang->debug_log_slow_widgets = '느린 위젯 기록'; @@ -117,6 +115,14 @@ $lang->debug_display_type = '디버그 정보 표시 방법'; $lang->debug_display_type_comment = 'HTML 소스에 표시 (주석)'; $lang->debug_display_type_panel = '화면에 표시 (패널)'; $lang->debug_display_type_file = '파일에 기록'; +$lang->debug_display_content = '디버그 정보 표시 내용'; +$lang->debug_display_content_request_info = '요청/응답 정보'; +$lang->debug_display_content_entries = '디버그 메시지'; +$lang->debug_display_content_errors = '에러'; +$lang->debug_display_content_queries = '쿼리'; +$lang->debug_display_content_slow_queries = '느린 쿼리'; +$lang->debug_display_content_slow_triggers = '느린 트리거'; +$lang->debug_display_content_slow_widgets = '느린 위젯'; $lang->debug_display_to = '디버그 정보 표시 대상'; $lang->debug_display_to_admin = '관리자에게만 표시'; $lang->debug_display_to_ip = '아래 IP의 방문자에게만 표시'; diff --git a/modules/admin/tpl/config_debug.html b/modules/admin/tpl/config_debug.html index d9efecc66..7a9e68969 100644 --- a/modules/admin/tpl/config_debug.html +++ b/modules/admin/tpl/config_debug.html @@ -14,38 +14,24 @@
    -
    - -
    - - -
    -
    -
    - -
    - - -
    -
    - +  {$lang->debug_seconds}
    - +  {$lang->debug_seconds}
    - +  {$lang->debug_seconds}
    @@ -57,10 +43,22 @@