diff --git a/.gitignore b/.gitignore index 83b06d623d..ea34c6950e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ config.user.inc.php /files/ /build/ /node_modules/ -.DS_Srore +.DS_Store Thumbs.db diff --git a/.htaccess b/.htaccess index 89ecf951f9..43536f5e95 100644 --- a/.htaccess +++ b/.htaccess @@ -15,37 +15,7 @@ RewriteRule ^(.+)/files/(member_extra_info|attach|cache|faceOff)/(.*) ./files/$2 RewriteCond %{SCRIPT_FILENAME} !-f RewriteRule ^(.+)/(files|modules|widgets|widgetstyles|layouts|m.layouts|addons)/(.*) ./$2/$3 [L] -# rss , blogAPI -RewriteRule ^(rss|atom)$ ./index.php?module=rss&act=$1 [L] -RewriteRule ^([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?mid=$1&act=$2 [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?vid=$1&mid=$2&act=$3 [L] - -# trackback -RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?mid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&mid=$2&document_srl=$3&key=$4&act=trackback [L] - -# document permanent link -RewriteRule ^([0-9]+)$ ./index.php?document_srl=$1 [L,QSA] - -# mid link -RewriteCond %{SCRIPT_FILENAME} !-d -RewriteRule ^([a-zA-Z0-9_]+)/?$ ./index.php?mid=$1 [L,QSA] -# mid + document link -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L,QSA] - -# vid + mid link -RewriteCond %{SCRIPT_FILENAME} !-d -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ ./index.php?vid=$1&mid=$2 [L,QSA] -# vid + mid + document link -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L,QSA] - -# mid + entry title -RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L,QSA] -# vid + mid + entry title -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?vid=$1&mid=$2&entry=$3 [L,QSA] - -#shop / vid / [category|product] / identifier +# router RewriteCond %{SCRIPT_FILENAME} !-f -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\.-]+)$ ./index.php?act=route&vid=$1&type=$2&identifier=$3 [L,QSA] +RewriteCond %{SCRIPT_FILENAME} !-d +RewriteRule ^(.*)$ ./index.php [L] diff --git a/.travis.yml b/.travis.yml index d518a61dec..cb2c700cf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ php: - 5.3 - 5.4 - 5.5 + - 5.6 + - hhvm before_script: - npm install -g grunt-cli - npm install diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..ae1039e7b4 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contribution Guide + +## Issue 작성 +Issue 작성 시 참고해주세요. + +* 작성하려는 이슈가 이미 있는지 검색 후 등록해주세요. 비슷한 이슈가 있다면 댓글로 추가 내용을 덧붙일 수 있습니다. +* 이슈에는 하나의 문제 또는 제안을 작성해주세요. 절대 하나의 이슈에 2개 이상의 내용을 적지마세요. +* 이슈는 가능한 상세하고 간결하게 작성해주세요 + * 필요하다면 화면을 캡쳐하여 이미지를 업로드할 수 있습니다 + +## Pull request(PR) +* `master` 브랜치의 코드는 수정하지마세요 +* PR은 `develop` 브랜치만 허용합니다. +* `develop` 브랜치를 부모로한 토픽 브랜치를 활용하면 편리합니다. + + +## Coding Guidelines +코드를 기여할 때 Coding conventions을 따라야합니다. + +* 모든 text 파일의 charset은 BOM이 없는 UTF-8입니다 +* newline은 UNIX type을 사용합니다. 일부 파일이 다른 type을 사용하더라도 절대 고치지 마세요! +* 들여쓰기는 1개의 탭으로 합니다 +* class 선언과 function, if, foreach, for, while 등 중괄호의 `{}`는 다음 줄에 있어야 합니다 + * 마찬가지로 선언 다음에는 공백을 두지 않습니다. ex) CORRECT `if(...)`, INCORRECT `if (...)` +* **Coding convention에 맞지 않는 코드를 발견 하더라도 목적과 관계 없는 코드는 절대 고치지 마세요** diff --git a/Gruntfile.js b/Gruntfile.js index eada99fb96..d78bbea203 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -52,6 +52,7 @@ module.exports = function(grunt) { }, 'modules': { files: { + 'common/js/x.min.js' : ['common/js/x.js'], // addon 'addons/captcha/captcha.min.js' : ['addons/captcha/captcha.js'], 'addons/captcha_member/captcha.min.js' : ['addons/captcha_member/captcha.js'], @@ -60,14 +61,20 @@ module.exports = function(grunt) { 'modules/editor/skins/xpresseditor/js/xpresseditor.min.js': ['modules/editor/skins/xpresseditor/js/xpresseditor.js'], 'modules/editor/skins/xpresseditor/js/xe_textarea.min.js': ['modules/editor/skins/xpresseditor/js/xe_textarea.js'], 'modules/editor/tpl/js/editor_common.min.js': ['modules/editor/tpl/js/editor_common.js'], + 'modules/editor/tpl/js/swfupload.min.js': ['modules/editor/tpl/js/swfupload.js'], + 'modules/editor/tpl/js/uploader.min.js': ['modules/editor/tpl/js/uploader.js'], + 'modules/editor/tpl/js/editor.min.js': ['modules/editor/tpl/js/editor.js'], + 'modules/editor/tpl/js/editor_module_config.min.js': ['modules/editor/tpl/js/editor_module_config.js'], // module/admin 'modules/admin/tpl/js/admin.min.js': ['modules/admin/tpl/js/admin.js'], 'modules/admin/tpl/js/config.min.js': ['modules/admin/tpl/js/config.js'], 'modules/admin/tpl/js/menu_setup.min.js': ['modules/admin/tpl/js/menu_setup.js'], - 'modules/admin/tpl/js/sitemap.min.js': ['modules/admin/tpl/js/sitemap.js'], - 'modules/admin/tpl/js/theme.min.js': ['modules/admin/tpl/js/theme.js'], - // editor-component-multimedia-link - 'modules/editor/components/multimedia_link/tpl/popup.min.js': ['modules/editor/components/multimedia_link/tpl/popup.js'], + //module/board + 'modules/board/tpl/js/board.min.js': ['modules/board/tpl/js/board.js'], + 'modules/board/tpl/js/board_admin.min.js': ['modules/board/tpl/js/board_admin.js'], + 'modules/board/skins/default/board.default.min.js': ['modules/board/skins/default/board.default.js'], + 'modules/board/m.skins/default/js/mboard.min.js': ['modules/board/m.skins/default/js/mboard.js'], + 'modules/board/m.skins/simpleGray/js/mboard.min.js': ['modules/board/m.skins/simpleGray/js/mboard.js'], // editor-component-image-gallery 'modules/editor/components/image_gallery/tpl/gallery.min.js' : ['modules/editor/components/image_gallery/tpl/gallery.js'], 'modules/editor/components/image_gallery/tpl/list_gallery.min.js' : ['modules/editor/components/image_gallery/tpl/list_gallery.js'], @@ -85,7 +92,7 @@ module.exports = function(grunt) { 'addons/oembed/jquery.oembed.min.js': ['addons/oembed/jquery.oembed.js'], 'addons/oembed/oembed.min.js': ['addons/oembed/oembed.js'], } - } + }, }, cssmin: { 'common-css': { @@ -105,11 +112,6 @@ module.exports = function(grunt) { 'modules/editor/components/image_gallery/tpl/slide_gallery.min.css': ['modules/editor/components/image_gallery/tpl/slide_gallery.css'], } }, - 'editor-component-multimedia-link': { - files: { - 'modules/editor/components/multimedia_link/tpl/popup.min.css': ['modules/editor/components/multimedia_link/tpl/popup.css'], - } - }, 'moudle-widget-tpl': { files: { 'modules/widget/tpl/css/widget.min.css': ['modules/widget/tpl/css/widget.css'], @@ -131,18 +133,24 @@ module.exports = function(grunt) { files: { 'addons/oembed/jquery.oembed.min.css': ['addons/oembed/jquery.oembed.css'], } + }, + 'module-board': { + files: { + 'modules/board/skins/default/board.default.min.css': ['modules/board/skins/default/board.default.css'], + 'modules/board/m.skins/default/css/mboard.min.css': ['modules/board/m.skins/default/css/mboard.css'], + 'modules/board/m.skins/simpleGray/css/mboard.min.css': ['modules/board/m.skins/simpleGray/css/mboard.css'] + } } }, jshint: { files: [ 'Gruntfile.js', 'common/js/*.js', '!common/js/html5.js', '!common/js/jquery.js', '!common/js/x.js', '!common/js/xe.js', - 'modules/widget/tpl/js/generate_code.js', - 'modules/widget/tpl/js/widget.js', - 'modules/widget/tpl/js/widget_admin.js', - '!**/jquery*.js', - '!**/*.min.js', - '!**/*-packed.js' + 'modules/admin/tpl/js/*.js', + 'modules/board/tpl/js/*.js', + 'modules/editor/tpl/js/*.js', + 'modules/menu/tpl/js/*.js', + 'modules/widget/tpl/js/*.js', ], options : { globalstrict: false, @@ -155,9 +163,10 @@ module.exports = function(grunt) { "window" : true }, ignores : [ - 'skins/xe_2010_gallery/js/jquery.easing.1.3.js', - 'skins/xe_2010_gallery/js/json2007.js', + '**/jquery*.js', + '**/swfupload.js', '**/*.min.js', + '**/*-packed.js', '**/*.compressed.js' ] } @@ -212,7 +221,7 @@ module.exports = function(grunt) { md5.update(buffer); var md5Hash = md5.digest('hex'); grunt.verbose.writeln('file md5: ' + md5Hash); - + var md5FileName = file + '.md5'; grunt.file.write(md5FileName, md5Hash); grunt.verbose.writeln('File "' + md5FileName + '" created.').writeln('...'); @@ -220,7 +229,7 @@ module.exports = function(grunt) { grunt.registerTask('build', '', function(A, B) { var _only_export = false; - var tasks = ['board', 'krzip', 'syndication']; + var tasks = ['krzip', 'syndication']; if(!A) { grunt.fail.warn('Undefined build target.'); @@ -250,9 +259,10 @@ module.exports = function(grunt) { if(tasks.length === 0) { grunt.util.spawn({ cmd: "tar", - args: ['cfz', 'xe.'+version+'.tar.gz', 'xe/'], + args: ['cfz', '../xe.'+version+'.tar.gz', './'], opts: { - cwd: 'build' + cwd: 'build/xe', + cache: false } }, function (error, result, code) { grunt.log.ok('Archived(full) : ' + build_dir + '/xe.'+version+'.tar.gz'); @@ -260,9 +270,10 @@ module.exports = function(grunt) { grunt.util.spawn({ cmd: "zip", - args: ['-r', 'xe.'+version+'.zip', 'xe/'], + args: ['-r', '../xe.'+version+'.zip', './'], opts: { - cwd: 'build' + cwd: 'build/xe', + cache: false } }, function (error, result, code) { grunt.log.ok('Archived(full) : ' + build_dir + '/xe.'+version+'.zip'); @@ -304,8 +315,8 @@ module.exports = function(grunt) { // changed if(diff.length) { - var args_tar = ['archive', '--prefix=xe/', '-o', 'build/xe.'+version+'.changed.tar.gz', version]; - var args_zip = ['archive', '--prefix=xe/', '-o', 'build/xe.'+version+'.changed.zip', version]; + var args_tar = ['archive', '-o', 'build/xe.'+version+'.changed.tar.gz', version]; + var args_zip = ['archive', '-o', 'build/xe.'+version+'.changed.zip', version]; args_tar = args_tar.concat(diff); args_zip = args_zip.concat(diff); @@ -337,15 +348,6 @@ module.exports = function(grunt) { cmd: "tar", args: ['xf', 'build/temp.full.tar', '-C', 'build/xe'] }, function (error, result, code) { - // board - grunt.util.spawn({ - cmd: "git", - args: ['clone', '-b', 'master', 'git@github.com:xpressengine/xe-module-board.git', 'build/xe/modules/board'] - }, function (error, result, code) { - grunt.file.delete('build/xe/modules/board/.git'); - taskDone(); - }); - // krzip grunt.util.spawn({ cmd: "git", diff --git a/README.md b/README.md index bf0d9ed52c..977e48730a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,29 @@ -# XpressEngine +XpressEngine +============ + +[![Build Status](https://travis-ci.org/xpressengine/xe-core.svg?branch=master)](https://travis-ci.org/xpressengine/xe-core) +[![License](http://img.shields.io/badge/license-GNU%20LGPL-brightgreen.svg)](http://www.gnu.org/licenses/gpl.html) +[![Latest release](http://img.shields.io/github/release/xpressengine/xe-core.svg)](https://github.com/xpressengine/xe-core/releases) + +XpressEngine(XE)은 PHP로 작성한 설치형 CMS(Content Management System)입니다. +오픈소스 라이선스로 누구나 사용 또는 개작할 수 있으며, 개방형 프로젝트로서 누구나 개발에 참여할 수 있습니다. + +## Support +* Official sitie (Korean) : http://www.xpressengine.com/ + +## Maintainers +@akasima @bnu @jhyeon1010 @khongchi @ngleader ## Authors -adrian.vasile.constantin, aerofleet, @akasima, @andreimarin, araste, @bnu, bradly1, buffkj, c2joy, @canto, cbrghost, @ccata17, @ChanMyeong, chinaskyking, chschy, clench, @devjin, @dionirom, @dorami, @dragan-dan, ducduydaovn, duvent, @Eundong, @florinutz, @flourscent, @flyskyko, @ForPeople, FruitsHake, guny, @haneul, hankm2004, haojilin, heemin, ikko, johnsonshu, juanlee0, k10206, kagami, @khongchi, @largeden, liahona, lickawtl, mayoojin, mglclub, @misol, mmx900, mooo, mosmartin, @nagoon97, @ngleader, nicetwo, ovclas, @qw5414, @Rayyin, risapapa, rokmcssu, royallin, rubyeye, ryin005, sanghunjun, @sejin7940, @SMaker, @solidh, sspa3141, supershop, @taggon, @ucorina, unryong, venister, wdlee91, welcomeju, @YJSoft, ysnglee2000, zero + + +## Contribution Guide +`CONTRIBUTING.md`파일을 참고하세요. ## License -Copyright (C) NAVER +Copyright 2014 NAVER Corp. -This library is free software; you can redistribute it and/or +This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. diff --git a/addons/blogapi/blogapi.addon.php b/addons/blogapi/blogapi.addon.php index 2fe2de2906..d78bf0eb70 100644 --- a/addons/blogapi/blogapi.addon.php +++ b/addons/blogapi/blogapi.addon.php @@ -30,6 +30,13 @@ // Read func file require_once(_XE_PATH_ . 'addons/blogapi/blogapi.func.php'); +// If HTTP_RAW_POST_DATA is NULL, Print error message +if(!$GLOBALS['HTTP_RAW_POST_DATA']) +{ + $content = getXmlRpcFailure(1, 'Invalid Method Call'); + printContent($content); +} + // xmlprc parsing // Parse the requested xmlrpc $xml = new SimpleXMLElement($GLOBALS['HTTP_RAW_POST_DATA']); @@ -487,7 +494,7 @@ $post = new stdClass(); $post->categories = array(); $post->dateCreated = date("Ymd", $oDocument->getRegdateTime()) . 'T' . date("H:i:s", $oDocument->getRegdateTime()); - $post->description = htmlspecialchars($oEditorController->transComponent($oDocument->getContent(false, false, true, false)), ENT_COMPAT | ENT_HTML401, 'UTF-8', false); + $post->description = sprintf('',$oEditorController->transComponent($oDocument->getContent(false, false, true, false))); $post->link = $post->permaLink = getFullUrl('', 'document_srl', $oDocument->document_srl); $post->postid = $oDocument->document_srl; $post->title = htmlspecialchars($oDocument->get('title'), ENT_COMPAT | ENT_HTML401, 'UTF-8', false); diff --git a/addons/blogapi/blogapi.func.php b/addons/blogapi/blogapi.func.php index adc3c66f64..06cc06c849 100644 --- a/addons/blogapi/blogapi.func.php +++ b/addons/blogapi/blogapi.func.php @@ -31,7 +31,11 @@ function getXmlRpcResponse($params) // Encoding function _getEncodedVal($val, $is_sub_set = false) { - if(is_int($val)) + if(preg_match('/^\<\!\[CDATA\[/',$val)) + { + $buff = sprintf("%s", $val); + } + elseif(is_int($val)) { $buff = sprintf("%d", $val); } diff --git a/addons/captcha/captcha.addon.php b/addons/captcha/captcha.addon.php index 433adf5274..f570247041 100644 --- a/addons/captcha/captcha.addon.php +++ b/addons/captcha/captcha.addon.php @@ -9,11 +9,14 @@ * @brief Captcha for a particular action * English alphabets and voice verification added * */ -if(!class_exists('AddonCaptcha')) +if(!class_exists('AddonCaptcha', false)) { // On the mobile mode, XE Core does not load jquery and xe.js as normal. - Context::loadFile(array('./common/js/jquery.min.js', 'head', NULL, -100000), true); - Context::loadFile(array('./common/js/xe.min.js', 'head', NULL, -100000), true); + if(Mobile::isFromMobilePhone()) + { + Context::loadFile(array('./common/js/jquery.min.js', 'head', NULL, -100000), true); + Context::loadFile(array('./common/js/xe.min.js', 'head', NULL, -100000), true); + } class AddonCaptcha { diff --git a/addons/captcha/captcha.min.js b/addons/captcha/captcha.min.js index 85c4fed9d3..b22dc0a66a 100644 --- a/addons/captcha/captcha.min.js +++ b/addons/captcha/captcha.min.js @@ -1 +1 @@ -var calledArgs=null;!function(a){a(function(){function b(){a("form").each(function(b){var d=!1;if(!a(this).attr("onsubmit")||a(this).attr("onsubmit").indexOf("procFilter")<0)for(var e=a(this).find("input[name=act]").val(),b=0;b'),a(this).find("input[name=error_return_url]")||a(this).append(''),a(this).submit(function(b){if(a(this).find("input[name=secret_text]").val())return!0;b.preventDefault();var d=this;a("#captcha_layer form").submit(function(b){return b.preventDefault(),a("#secret_text").val()?(a(d).append(''),a(d).submit(),void 0):(a(this).find("input[type=text]").val("").focus(),!1)});var e=new Array;e.captcha_action="setCaptchaSession",e.mid=current_mid,window.oldExecXml("","",e,c.show,new Array("error","message","about_captcha","captcha_reload","captcha_play","cmd_input","cmd_cancel"))}))});a(document.body);if(!c){var b=-1!=navigator.appVersion.indexOf("MSIE")?!0:!1,d=-1!=navigator.appVersion.toLowerCase().indexOf("win")?!0:!1,e=-1!=navigator.userAgent.indexOf("Opera")?!0:!1,f=request_uri+"addons/captcha/swf/play.swf";b&&d&&!e?(_object_='',_object_+='',_object_+='',_object_+='',_object_+='',_object_+='',_object_+='',_object_+=""):_object_='',c=a(' + + +
+

embed Filter {$lang->subtitle_embed_whitelist} {$lang->help}

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