mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-07 10:41:40 +09:00
Merge branch 'develop' into pr/session-class
This commit is contained in:
commit
483ac84796
454 changed files with 10659 additions and 30145 deletions
14
.travis.yml
14
.travis.yml
|
|
@ -1,23 +1,21 @@
|
||||||
language: php
|
language: php
|
||||||
php:
|
php:
|
||||||
- 5.4
|
|
||||||
- 5.5
|
- 5.5
|
||||||
- 5.6
|
- 5.6
|
||||||
- 7.0
|
- 7.0
|
||||||
|
- 7.1
|
||||||
- hhvm
|
- hhvm
|
||||||
sudo: false
|
sudo: false
|
||||||
before_script:
|
before_script:
|
||||||
- npm install grunt grunt-cli grunt-contrib-jshint grunt-contrib-csslint grunt-phplint --save-dev
|
- npm install grunt grunt-cli grunt-contrib-jshint grunt-contrib-csslint grunt-phplint --save-dev
|
||||||
- mysql -u root -e "CREATE DATABASE rhymix"
|
- mysql -u root -e "CREATE DATABASE rhymix"
|
||||||
- mysql -u root -e "SET PASSWORD FOR 'travis'@'localhost' = PASSWORD('travis')"
|
- mysql -u root -e "SET PASSWORD FOR 'travis'@'localhost' = PASSWORD('travis')"
|
||||||
- if [[ $TRAVIS_PHP_VERSION != "5.4" && $TRAVIS_PHP_VERSION != "hhvm" ]]; then php -S localhost:8000 & fi
|
- if [[ $TRAVIS_PHP_VERSION != "hhvm" ]]; then php -S localhost:8000 & fi
|
||||||
- if [[ $TRAVIS_PHP_VERSION == "5.4" ]]; then wget http://codeception.com/releases/2.0.16/codecept.phar; fi
|
- wget http://codeception.com/releases/2.1.11/codecept.phar
|
||||||
- if [[ ! -f codecept.phar ]]; then wget http://codeception.com/releases/2.1.6/codecept.phar; fi
|
|
||||||
script:
|
script:
|
||||||
- if [[ -s codecept.phar ]]; then php codecept.phar build; fi
|
- php codecept.phar build
|
||||||
- if [[ -s codecept.phar && $TRAVIS_PHP_VERSION == "hhvm" ]]; then php codecept.phar run -d --fail-fast --env travis --skip install; fi
|
- if [[ $TRAVIS_PHP_VERSION == "hhvm" ]]; then php codecept.phar run -d --fail-fast --env travis --skip install; fi
|
||||||
- if [[ -s codecept.phar && $TRAVIS_PHP_VERSION == "5.4" ]]; then php codecept.phar run -d --fail-fast --env travis --skip install; fi
|
- if [[ $TRAVIS_PHP_VERSION != "hhvm" ]]; then php codecept.phar run -d --fail-fast --env travis; fi
|
||||||
- if [[ -s codecept.phar && $TRAVIS_PHP_VERSION != "5.4" && $TRAVIS_PHP_VERSION != "hhvm" ]]; then php codecept.phar run -d --fail-fast --env travis; fi
|
|
||||||
- grunt lint
|
- grunt lint
|
||||||
notifications:
|
notifications:
|
||||||
email: false
|
email: false
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ module.exports = function(grunt) {
|
||||||
'box-sizing' : false,
|
'box-sizing' : false,
|
||||||
'font-sizes' : false,
|
'font-sizes' : false,
|
||||||
'duplicate-background-images' : false,
|
'duplicate-background-images' : false,
|
||||||
|
'order-alphabetical' : false,
|
||||||
'ids' : false,
|
'ids' : false,
|
||||||
'important' : false,
|
'important' : false,
|
||||||
'overqualified-elements' : false,
|
'overqualified-elements' : false,
|
||||||
|
|
|
||||||
12
README.md
12
README.md
|
|
@ -3,7 +3,7 @@
|
||||||
Rhymix(라이믹스)는 누구든지 쉽고 자유롭게 독립적인 홈페이지를 만들어
|
Rhymix(라이믹스)는 누구든지 쉽고 자유롭게 독립적인 홈페이지를 만들어
|
||||||
자신을 표현하고 커뮤니티를 키워나갈 수 있도록 돕기 위한 CMS(content management system)입니다.
|
자신을 표현하고 커뮤니티를 키워나갈 수 있도록 돕기 위한 CMS(content management system)입니다.
|
||||||
|
|
||||||
XETOWN 커뮤니티에서 [XE](https://www.xpressengine.com)를 fork(가지치기)하여 진행하는 프로젝트로,
|
[XpressEngine](https://www.xpressengine.com) 1.8 버전을 fork(가지치기)하여 진행하는 프로젝트로,
|
||||||
누구나 무료로 사용할 수 있고 개발에 참여할 수도 있는 자유 소프트웨어(free software)입니다.
|
누구나 무료로 사용할 수 있고 개발에 참여할 수도 있는 자유 소프트웨어(free software)입니다.
|
||||||
|
|
||||||
Rhymix는 "시를 짓다, 운을 맞추다"라는 의미의 "rhyme"과
|
Rhymix는 "시를 짓다, 운을 맞추다"라는 의미의 "rhyme"과
|
||||||
|
|
@ -28,7 +28,7 @@ Rhymix는 개발자와 사용자가 서로의 권리와 책임을 존중하는
|
||||||
- 초보자도 쉽게 클릭 몇 번으로 웹사이트를 완성할 수 있을 만큼 편리한 CMS
|
- 초보자도 쉽게 클릭 몇 번으로 웹사이트를 완성할 수 있을 만큼 편리한 CMS
|
||||||
- 최신 기술을 적극적으로 사용하고 속도가 빠르며 보안이 우수한 CMS
|
- 최신 기술을 적극적으로 사용하고 속도가 빠르며 보안이 우수한 CMS
|
||||||
- 커뮤니티를 통해 사용자와 개발자의 건전한 의사소통을 돕는 CMS
|
- 커뮤니티를 통해 사용자와 개발자의 건전한 의사소통을 돕는 CMS
|
||||||
- **애드온, 모듈, 위젯 등 기존 XE 서드파티 자료와의 호환성 100% 목표!**
|
- 애드온, 모듈, 위젯 등 기존 XE 서드파티 자료들과의 호환성을 최대한 보장하려고 노력합니다.
|
||||||
|
|
||||||
### 설치 환경
|
### 설치 환경
|
||||||
|
|
||||||
|
|
@ -46,9 +46,6 @@ Rhymix를 사용하려면 아래의 조건을 충족하는 웹호스팅이나
|
||||||
- simplexml
|
- simplexml
|
||||||
- php.ini에서 session.auto_start = Off로 설정되어 있어야 합니다.
|
- php.ini에서 session.auto_start = Off로 설정되어 있어야 합니다.
|
||||||
- 설치 폴더 또는 files 폴더에 쓰기 권한이 주어져야 합니다.
|
- 설치 폴더 또는 files 폴더에 쓰기 권한이 주어져야 합니다.
|
||||||
- MySQL/MariaDB 외에도 아래의 DB를 사용할 수 있습니다.
|
|
||||||
- CUBRID 9.0 이상
|
|
||||||
- Microsoft SQL Server 2008 이상
|
|
||||||
|
|
||||||
### 개발 참여
|
### 개발 참여
|
||||||
|
|
||||||
|
|
@ -61,9 +58,12 @@ devops@rhymix.org로 알려 주시면 감사하겠습니다.
|
||||||
|
|
||||||
### 공식 홈페이지
|
### 공식 홈페이지
|
||||||
|
|
||||||
- XETOWN : https://www.xetown.com
|
|
||||||
- Rhymix : https://www.rhymix.org
|
- Rhymix : https://www.rhymix.org
|
||||||
|
|
||||||
|
### 커뮤니티
|
||||||
|
|
||||||
|
- XETOWN : https://www.xetown.com
|
||||||
|
|
||||||
### 저작권 및 라이선스
|
### 저작권 및 라이선스
|
||||||
|
|
||||||
Rhymix는 [GNU GPL v2](http://korea.gnu.org/documents/copyleft/gpl.ko.html)
|
Rhymix는 [GNU GPL v2](http://korea.gnu.org/documents/copyleft/gpl.ko.html)
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
* @author NAVER (developers@xpressengine.com)
|
* @author NAVER (developers@xpressengine.com)
|
||||||
*/
|
*/
|
||||||
(function($){
|
(function($){
|
||||||
var protocol_re = '(https?|ftp|news|telnet|irc|mms)://';
|
var protocol_re = '(?:(?:https?|ftp|news|telnet|irc|mms)://)';
|
||||||
var domain_re = '(?:[^\\s./]+\\.)+[^\\s./]+';
|
var domain_re = '(?:[^\\s./)>]+\\.)+[^\\s./)>]+';
|
||||||
var max_255_re = '(?:1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9]?[0-9])';
|
var max_255_re = '(?:1[0-9]{2}|2[0-4][0-9]|25[0-5]|[1-9]?[0-9])';
|
||||||
var ip_re = '(?:'+max_255_re+'\\.){3}'+max_255_re;
|
var ip_re = '(?:'+max_255_re+'\\.){3}'+max_255_re;
|
||||||
var port_re = '(?::([0-9]+))?';
|
var port_re = '(?::([0-9]+))?';
|
||||||
var user_re = '(?:/~\\w+)?';
|
var user_re = '(?:/~\\w+)?';
|
||||||
var path_re = '(?:/[\\w!@$%&!?+=_~"/.,:;-]*)?';
|
var path_re = '(?:/[^\\s]*)?';
|
||||||
var hash_re = '(?:#[\\w!@$%&!?+=_~"/.,:;-]*)?';
|
var hash_re = '(?:#[^\\s]*)?';
|
||||||
|
|
||||||
var url_regex = new RegExp('('+protocol_re+'('+domain_re+'|'+ip_re+'|localhost'+')'+port_re+user_re+path_re+hash_re+')', 'ig');
|
var url_regex = new RegExp('('+protocol_re+'('+domain_re+'|'+ip_re+'|localhost'+')'+port_re+user_re+path_re+hash_re+')', 'ig');
|
||||||
|
|
||||||
|
|
@ -36,8 +36,25 @@
|
||||||
var content = textNode.nodeValue;
|
var content = textNode.nodeValue;
|
||||||
var dummy = $('<span>');
|
var dummy = $('<span>');
|
||||||
|
|
||||||
//content = content.replace(/</g, '<').replace(/>/g, '>');
|
content = content.replace(/</g, '<').replace(/>/g, '>');
|
||||||
content = content.replace(url_regex, '<a href="$1" target="_blank">$1</a>');
|
content = content.replace(url_regex, function(match, p1, offset, string) {
|
||||||
|
var match;
|
||||||
|
var suffix = '';
|
||||||
|
if (p1.indexOf('(') < 0 && p1.match(/\)$/)) {
|
||||||
|
p1 = p1.replace(/\)$/, '');
|
||||||
|
suffix = ')';
|
||||||
|
} else if (p1.indexOf('[') < 0 && p1.match(/\]$/)) {
|
||||||
|
p1 = p1.replace(/\]$/, '');
|
||||||
|
suffix = ']';
|
||||||
|
} else if (p1.indexOf('<') < 0 && p1.match(/>$/)) {
|
||||||
|
p1 = p1.replace(/>$/, '');
|
||||||
|
suffix = '>';
|
||||||
|
} else if (match = /^([\x21-\x7E]+\.[a-z]+)([가-힣]{1,3})$/.exec(p1)) {
|
||||||
|
p1 = match[1];
|
||||||
|
suffix = match[2];
|
||||||
|
}
|
||||||
|
return '<a href="' + p1 + '" target="_blank">' + p1 + '</a>' + suffix;
|
||||||
|
});
|
||||||
|
|
||||||
$(textNode).before(dummy);
|
$(textNode).before(dummy);
|
||||||
$(textNode).replaceWith(content);
|
$(textNode).replaceWith(content);
|
||||||
|
|
@ -75,4 +92,11 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
xe.registerPlugin(new AutoLink());
|
xe.registerPlugin(new AutoLink());
|
||||||
|
|
||||||
|
$(document).on('click', '.xe_content a', function() {
|
||||||
|
if (!$(this).attr("target")) {
|
||||||
|
$(this).attr("target", "_blank");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,10 @@ if($called_position == 'before_module_proc')
|
||||||
$category_list = $oDocumentModel->getCategoryList($this->module_srl);
|
$category_list = $oDocumentModel->getCategoryList($this->module_srl);
|
||||||
|
|
||||||
// Specifies a temporary file storage
|
// Specifies a temporary file storage
|
||||||
$tmp_uploaded_path = sprintf(_XE_PATH_ . 'files/cache/blogapi/%s/%s/', $this->mid, $user_id);
|
$logged_info = Context::get('logged_info');
|
||||||
$uploaded_target_path = sprintf(_XE_PATH_ . 'files/cache/blogapi/%s/%s/', $this->mid, $user_id);
|
$mediaPath = sprintf('files/cache/blogapi/%s/%s/', $this->mid, $logged_info->member_srl);
|
||||||
|
$mediaAbsPath = _XE_PATH_ . $mediaPath;
|
||||||
|
$mediaUrlPath = Context::getRequestUri() . $mediaPath;
|
||||||
|
|
||||||
switch($method_name)
|
switch($method_name)
|
||||||
{
|
{
|
||||||
|
|
@ -167,22 +169,56 @@ if($called_position == 'before_module_proc')
|
||||||
foreach($fileinfo as $key => $val)
|
foreach($fileinfo as $key => $val)
|
||||||
{
|
{
|
||||||
$nodename = (string)$val->name;
|
$nodename = (string)$val->name;
|
||||||
if($nodename == 'bits')
|
if($nodename === 'bits')
|
||||||
|
{
|
||||||
$filedata = base64_decode((string)$val->value->base64);
|
$filedata = base64_decode((string)$val->value->base64);
|
||||||
elseif($nodename == 'name')
|
}
|
||||||
$filename = (string)$val->value->string;
|
else if($nodename === 'name')
|
||||||
|
{
|
||||||
|
$filename = pathinfo((string)$val->value->string, PATHINFO_BASENAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmp_arr = explode('/', $filename);
|
if($logged_info->is_admin != 'Y')
|
||||||
$filename = array_pop($tmp_arr);
|
{
|
||||||
|
// check file type
|
||||||
|
if(isset($file_module_config->allowed_filetypes) && $file_module_config->allowed_filetypes !== '*.*')
|
||||||
|
{
|
||||||
|
$filetypes = explode(';', $file_module_config->allowed_filetypes);
|
||||||
|
$ext = array();
|
||||||
|
|
||||||
FileHandler::makeDir($tmp_uploaded_path);
|
foreach($filetypes as $item)
|
||||||
|
{
|
||||||
|
$item = explode('.', $item);
|
||||||
|
$ext[] = strtolower(array_pop($item));
|
||||||
|
}
|
||||||
|
|
||||||
$target_filename = sprintf('%s%s', $tmp_uploaded_path, $filename);
|
$uploaded_ext = explode('.', $filename);
|
||||||
|
$uploaded_ext = strtolower(array_pop($uploaded_ext));
|
||||||
|
|
||||||
|
if(!in_array($uploaded_ext, $ext))
|
||||||
|
{
|
||||||
|
printContent(getXmlRpcFailure(1, 'Not allowed file type'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowed_filesize = $file_module_config->allowed_filesize * 1024 * 1024;
|
||||||
|
if($allowed_filesize < strlen($filedata))
|
||||||
|
{
|
||||||
|
printContent(getXmlRpcFailure(1, 'This file exceeds the attachment limit'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$temp_filename = Password::createSecureSalt(12, 'alnum');
|
||||||
|
$target_filename = sprintf('%s%s', $mediaAbsPath, $temp_filename);
|
||||||
|
FileHandler::makeDir($mediaAbsPath);
|
||||||
FileHandler::writeFile($target_filename, $filedata);
|
FileHandler::writeFile($target_filename, $filedata);
|
||||||
$obj = new stdClass();
|
FileHandler::writeFile($target_filename . '_source_filename', $filename);
|
||||||
$obj->url = Context::getRequestUri() . $target_filename;
|
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->url = Context::getRequestUri() . $mediaPath . $temp_filename;
|
||||||
$content = getXmlRpcResponse($obj);
|
$content = getXmlRpcResponse($obj);
|
||||||
printContent($content);
|
printContent($content);
|
||||||
break;
|
break;
|
||||||
|
|
@ -291,21 +327,34 @@ if($called_position == 'before_module_proc')
|
||||||
$obj->module_srl = $this->module_srl;
|
$obj->module_srl = $this->module_srl;
|
||||||
|
|
||||||
// Attachment
|
// Attachment
|
||||||
if(is_dir($tmp_uploaded_path))
|
if(is_dir($mediaAbsPath))
|
||||||
{
|
{
|
||||||
$file_list = FileHandler::readDir($tmp_uploaded_path);
|
$file_list = FileHandler::readDir($mediaAbsPath, '/(_source_filename)$/is');
|
||||||
$file_count = count($file_list);
|
$file_count = count($file_list);
|
||||||
if($file_count)
|
if($file_count)
|
||||||
{
|
{
|
||||||
$oFileController = getController('file');
|
$oFileController = getController('file');
|
||||||
for($i = 0; $i < $file_count; $i++)
|
$oFileModel = getModel('file');
|
||||||
|
foreach($file_list as $file)
|
||||||
{
|
{
|
||||||
$file_info['tmp_name'] = sprintf('%s%s', $tmp_uploaded_path, $file_list[$i]);
|
$filename = FileHandler::readFile($mediaAbsPath . $file);
|
||||||
$file_info['name'] = $file_list[$i];
|
$temp_filename = str_replace('_source_filename', '', $file);
|
||||||
|
|
||||||
|
$file_info = array();
|
||||||
|
$file_info['tmp_name'] = sprintf('%s%s', $mediaAbsPath, $temp_filename);
|
||||||
|
$file_info['name'] = $filename;
|
||||||
$fileOutput = $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true);
|
$fileOutput = $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true);
|
||||||
$uploaded_filename = $fileOutput->get('uploaded_filename');
|
|
||||||
$source_filename = $fileOutput->get('source_filename');
|
if($fileOutput->get('direct_download') === 'N')
|
||||||
$obj->content = str_replace($uploaded_target_path . $source_filename, sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl, 3), $uploaded_filename), $obj->content);
|
{
|
||||||
|
$replace_url = Context::getRequestUri() . $oFileModel->getDownloadUrl($fileOutput->file_srl, $fileOutput->sid, $this->module_srl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$replace_url = Context::getRequestUri() . $fileOutput->get('uploaded_filename');
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj->content = str_replace($mediaUrlPath . $temp_filename, $replace_url, $obj->content);
|
||||||
}
|
}
|
||||||
$obj->uploaded_count = $file_count;
|
$obj->uploaded_count = $file_count;
|
||||||
}
|
}
|
||||||
|
|
@ -332,7 +381,7 @@ if($called_position == 'before_module_proc')
|
||||||
{
|
{
|
||||||
$content = getXmlRpcResponse(strval($document_srl));
|
$content = getXmlRpcResponse(strval($document_srl));
|
||||||
}
|
}
|
||||||
FileHandler::removeDir($tmp_uploaded_path);
|
FileHandler::removeDir($mediaAbsPath);
|
||||||
|
|
||||||
printContent($content);
|
printContent($content);
|
||||||
break;
|
break;
|
||||||
|
|
@ -404,27 +453,36 @@ if($called_position == 'before_module_proc')
|
||||||
// Document srl
|
// Document srl
|
||||||
$obj->document_srl = $document_srl;
|
$obj->document_srl = $document_srl;
|
||||||
$obj->module_srl = $this->module_srl;
|
$obj->module_srl = $this->module_srl;
|
||||||
|
|
||||||
// Attachment
|
// Attachment
|
||||||
if(is_dir($tmp_uploaded_path))
|
if(is_dir($mediaAbsPath))
|
||||||
{
|
{
|
||||||
$file_list = FileHandler::readDir($tmp_uploaded_path);
|
$file_list = FileHandler::readDir($mediaAbsPath, '/(_source_filename)$/is');
|
||||||
$file_count = count($file_list);
|
$file_count = count($file_list);
|
||||||
if($file_count)
|
if($file_count)
|
||||||
{
|
{
|
||||||
$oFileController = getController('file');
|
$oFileController = getController('file');
|
||||||
for($i = 0; $i < $file_count; $i++)
|
$oFileModel = getModel('file');
|
||||||
|
foreach($file_list as $file)
|
||||||
{
|
{
|
||||||
$file_info['tmp_name'] = sprintf('%s%s', $tmp_uploaded_path, $file_list[$i]);
|
$filename = FileHandler::readFile($mediaAbsPath . $file);
|
||||||
$file_info['name'] = $file_list[$i];
|
$temp_filename = str_replace('_source_filename', '', $file);
|
||||||
|
|
||||||
$moved_filename = sprintf('./files/attach/images/%s/%s/%s', $this->module_srl, $document_srl, $file_info['name']);
|
|
||||||
if(file_exists($moved_filename))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
|
$file_info = array();
|
||||||
|
$file_info['tmp_name'] = sprintf('%s%s', $mediaAbsPath, $temp_filename);
|
||||||
|
$file_info['name'] = $filename;
|
||||||
$fileOutput = $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true);
|
$fileOutput = $oFileController->insertFile($file_info, $this->module_srl, $document_srl, 0, true);
|
||||||
$uploaded_filename = $fileOutput->get('uploaded_filename');
|
|
||||||
$source_filename = $fileOutput->get('source_filename');
|
if($fileOutput->get('direct_download') === 'N')
|
||||||
$obj->content = str_replace($uploaded_target_path . $source_filename, sprintf('/files/attach/images/%s/%s%s', $this->module_srl, getNumberingPath($document_srl, 3), $uploaded_filename), $obj->content);
|
{
|
||||||
|
$replace_url = Context::getRequestUri() . $oFileModel->getDownloadUrl($fileOutput->file_srl, $fileOutput->sid, $this->module_srl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$replace_url = Context::getRequestUri() . $fileOutput->get('uploaded_filename');
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj->content = str_replace($mediaUrlPath . $temp_filename, $replace_url, $obj->content);
|
||||||
}
|
}
|
||||||
$obj->uploaded_count += $file_count;
|
$obj->uploaded_count += $file_count;
|
||||||
}
|
}
|
||||||
|
|
@ -440,7 +498,7 @@ if($called_position == 'before_module_proc')
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$content = getXmlRpcResponse(true);
|
$content = getXmlRpcResponse(true);
|
||||||
FileHandler::removeDir($tmp_uploaded_path);
|
FileHandler::removeDir($mediaAbsPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
printContent($content);
|
printContent($content);
|
||||||
|
|
|
||||||
|
|
@ -1425,6 +1425,14 @@ class Context
|
||||||
{
|
{
|
||||||
$result[$k] = urlencode($v);
|
$result[$k] = urlencode($v);
|
||||||
}
|
}
|
||||||
|
elseif($key === 'xe_validator_id')
|
||||||
|
{
|
||||||
|
$result[$k] = htmlspecialchars($v, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
|
||||||
|
}
|
||||||
|
elseif(starts_with('XE_VALIDATOR_', $key, false))
|
||||||
|
{
|
||||||
|
unset($result[$k]);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$result[$k] = $v;
|
$result[$k] = $v;
|
||||||
|
|
@ -1513,6 +1521,10 @@ class Context
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow if the current user is in the list of allowed IPs.
|
// Allow if the current user is in the list of allowed IPs.
|
||||||
|
if (PHP_SAPI === 'cli')
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (Rhymix\Framework\Filters\IpFilter::inRanges(RX_CLIENT_IP, config('lock.allow')))
|
if (Rhymix\Framework\Filters\IpFilter::inRanges(RX_CLIENT_IP, config('lock.allow')))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -369,7 +369,7 @@ class DB
|
||||||
$log['time'] = date('Y-m-d H:i:s');
|
$log['time'] = date('Y-m-d H:i:s');
|
||||||
$log['backtrace'] = array();
|
$log['backtrace'] = array();
|
||||||
|
|
||||||
if (config('debug.enabled') && in_array('queries', config('debug.display_content')))
|
if (config('debug.enabled') && ($this->isError() || in_array('queries', config('debug.display_content'))))
|
||||||
{
|
{
|
||||||
$bt = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
|
$bt = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
foreach($bt as $no => $call)
|
foreach($bt as $no => $call)
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ class HTMLDisplayHandler
|
||||||
if(is_array(Context::get('INPUT_ERROR')))
|
if(is_array(Context::get('INPUT_ERROR')))
|
||||||
{
|
{
|
||||||
$INPUT_ERROR = Context::get('INPUT_ERROR');
|
$INPUT_ERROR = Context::get('INPUT_ERROR');
|
||||||
$keys = array_keys($INPUT_ERROR);
|
$keys = array_map(function($str) { return preg_quote($str, '@'); }, array_keys($INPUT_ERROR));
|
||||||
$keys = '(' . implode('|', $keys) . ')';
|
$keys = '(' . implode('|', $keys) . ')';
|
||||||
|
|
||||||
$output = preg_replace_callback('@(<input)([^>]*?)\sname="' . $keys . '"([^>]*?)/?>@is', array(&$this, '_preserveValue'), $output);
|
$output = preg_replace_callback('@(<input)([^>]*?)\sname="' . $keys . '"([^>]*?)/?>@is', array(&$this, '_preserveValue'), $output);
|
||||||
|
|
@ -259,42 +259,28 @@ class HTMLDisplayHandler
|
||||||
|
|
||||||
// get type
|
// get type
|
||||||
$type = 'text';
|
$type = 'text';
|
||||||
if(preg_match('/\stype="([a-z]+)"/i', $str, $m))
|
if(preg_match('/\stype="([^"]+)"/i', $str, $m))
|
||||||
{
|
{
|
||||||
$type = strtolower($m[1]);
|
$type = strtolower($m[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch($type)
|
switch($type)
|
||||||
{
|
{
|
||||||
case 'text':
|
|
||||||
case 'hidden':
|
|
||||||
case 'email':
|
|
||||||
case 'search':
|
|
||||||
case 'tel':
|
|
||||||
case 'url':
|
|
||||||
case 'email':
|
|
||||||
case 'datetime':
|
|
||||||
case 'date':
|
|
||||||
case 'month':
|
|
||||||
case 'week':
|
|
||||||
case 'time':
|
|
||||||
case 'datetime-local':
|
|
||||||
case 'number':
|
|
||||||
case 'range':
|
|
||||||
case 'color':
|
|
||||||
$str = preg_replace('@\svalue="[^"]*?"@', ' ', $str) . ' value="' . htmlspecialchars($INPUT_ERROR[$match[3]], ENT_COMPAT | ENT_HTML401, 'UTF-8', false) . '"';
|
|
||||||
break;
|
|
||||||
case 'password':
|
|
||||||
$str = preg_replace('@\svalue="[^"]*?"@', ' ', $str);
|
|
||||||
break;
|
|
||||||
case 'radio':
|
case 'radio':
|
||||||
case 'checkbox':
|
case 'checkbox':
|
||||||
$str = preg_replace('@\schecked(="[^"]*?")?@', ' ', $str);
|
if(preg_match('@\s(?i:value)="' . preg_quote($INPUT_ERROR[$match[3]], '@') . '"@', $str))
|
||||||
if(@preg_match('@\s(?i:value)="' . $INPUT_ERROR[$match[3]] . '"@', $str))
|
|
||||||
{
|
{
|
||||||
$str .= ' checked="checked"';
|
$str = preg_replace('@\schecked(="[^"]*?")?@', ' checked="checked"', $str);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
if (!preg_match('@\svalue="([^"]*?)"@', $str))
|
||||||
|
{
|
||||||
|
$str = $str . ' value=""';
|
||||||
|
}
|
||||||
|
$str = preg_replace_callback('@\svalue="([^"]*?)"@', function() use($INPUT_ERROR, $match) {
|
||||||
|
return ' value="' . escape($INPUT_ERROR[$match[3]], true) . '"';
|
||||||
|
}, $str);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $str . ' />';
|
return $str . ' />';
|
||||||
|
|
@ -333,7 +319,7 @@ class HTMLDisplayHandler
|
||||||
{
|
{
|
||||||
$INPUT_ERROR = Context::get('INPUT_ERROR');
|
$INPUT_ERROR = Context::get('INPUT_ERROR');
|
||||||
preg_match('@<textarea.*?>@is', $matches[0], $mm);
|
preg_match('@<textarea.*?>@is', $matches[0], $mm);
|
||||||
return $mm[0] . $INPUT_ERROR[$matches[1]] . '</textarea>';
|
return $mm[0] . escape($INPUT_ERROR[$matches[1]], true) . '</textarea>';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -403,7 +389,7 @@ class HTMLDisplayHandler
|
||||||
if ($document_srl)
|
if ($document_srl)
|
||||||
{
|
{
|
||||||
$oDocument = Context::get('oDocument') ?: getModel('document')->getDocument($document_srl, false, false);
|
$oDocument = Context::get('oDocument') ?: getModel('document')->getDocument($document_srl, false, false);
|
||||||
if ($oDocument instanceof documentItem && $oDocument->document_srl == $document_srl && !$oDocument->isSecret())
|
if (is_object($oDocument) && $oDocument->document_srl == $document_srl && (!method_exists($oDocument, 'isSecret') || !$oDocument->isSecret()))
|
||||||
{
|
{
|
||||||
$page_type = 'article';
|
$page_type = 'article';
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -208,15 +208,7 @@ class FileHandler
|
||||||
*/
|
*/
|
||||||
public static function removeBlankDir($path)
|
public static function removeBlankDir($path)
|
||||||
{
|
{
|
||||||
$path = self::getRealPath($path);
|
return Rhymix\Framework\Storage::deleteEmptyDirectory(self::getRealPath($path), false);
|
||||||
if (Rhymix\Framework\Storage::isEmptyDirectory($path))
|
|
||||||
{
|
|
||||||
return Rhymix\Framework\Storage::deleteDirectory($path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -256,12 +248,22 @@ class FileHandler
|
||||||
return $size . 'Bytes';
|
return $size . 'Bytes';
|
||||||
}
|
}
|
||||||
|
|
||||||
if($size >= 1024 && $size < 1024 * 1024)
|
if($size >= 1024 && $size < (1024 * 1024))
|
||||||
{
|
{
|
||||||
return sprintf("%0.1fKB", $size / 1024);
|
return sprintf("%0.1fKB", $size / 1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sprintf("%0.2fMB", $size / (1024 * 1024));
|
if($size >= (1024 * 1024) && $size < (1024 * 1024 * 1024))
|
||||||
|
{
|
||||||
|
return sprintf("%0.2fMB", $size / (1024 * 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
if($size >= (1024 * 1024 * 1024) && $size < (1024 * 1024 * 1024 * 1024))
|
||||||
|
{
|
||||||
|
return sprintf("%0.2fGB", $size / (1024 * 1024 * 1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf("%0.2fTB", $size / (1024 * 1024 * 1024 * 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -426,11 +428,14 @@ class FileHandler
|
||||||
*/
|
*/
|
||||||
public static function returnBytes($val)
|
public static function returnBytes($val)
|
||||||
{
|
{
|
||||||
|
$val = preg_replace('/[^0-9\.PTGMK]/', '', $val);
|
||||||
$unit = strtoupper(substr($val, -1));
|
$unit = strtoupper(substr($val, -1));
|
||||||
$val = (float)$val;
|
$val = (float)$val;
|
||||||
|
|
||||||
switch ($unit)
|
switch ($unit)
|
||||||
{
|
{
|
||||||
|
case 'P': $val *= 1024;
|
||||||
|
case 'T': $val *= 1024;
|
||||||
case 'G': $val *= 1024;
|
case 'G': $val *= 1024;
|
||||||
case 'M': $val *= 1024;
|
case 'M': $val *= 1024;
|
||||||
case 'K': $val *= 1024;
|
case 'K': $val *= 1024;
|
||||||
|
|
|
||||||
|
|
@ -909,7 +909,7 @@ class ModuleHandler extends Handler
|
||||||
public static function _setInputValueToSession()
|
public static function _setInputValueToSession()
|
||||||
{
|
{
|
||||||
$requestVars = Context::getRequestVars();
|
$requestVars = Context::getRequestVars();
|
||||||
unset($requestVars->act, $requestVars->mid, $requestVars->vid, $requestVars->success_return_url, $requestVars->error_return_url);
|
unset($requestVars->act, $requestVars->mid, $requestVars->vid, $requestVars->success_return_url, $requestVars->error_return_url, $requestVars->xe_validator_id);
|
||||||
foreach($requestVars AS $key => $value)
|
foreach($requestVars AS $key => $value)
|
||||||
{
|
{
|
||||||
$_SESSION['INPUT_ERROR'][$key] = $value;
|
$_SESSION['INPUT_ERROR'][$key] = $value;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
/**
|
/**
|
||||||
* RX_VERSION is the version number of the Rhymix CMS.
|
* RX_VERSION is the version number of the Rhymix CMS.
|
||||||
*/
|
*/
|
||||||
define('RX_VERSION', '1.8.25');
|
define('RX_VERSION', '1.8.29');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
|
* RX_MICROTIME is the startup time of the current script, in microseconds since the Unix epoch.
|
||||||
|
|
@ -27,9 +27,9 @@ if (isset($_SERVER['DOCUMENT_ROOT']) && !strncmp(RX_BASEDIR, str_replace('\\',
|
||||||
{
|
{
|
||||||
define('RX_BASEURL', str_replace('//', '/', '/' . trim(substr(RX_BASEDIR, strlen($_SERVER['DOCUMENT_ROOT'])), '/') . '/'));
|
define('RX_BASEURL', str_replace('//', '/', '/' . trim(substr(RX_BASEDIR, strlen($_SERVER['DOCUMENT_ROOT'])), '/') . '/'));
|
||||||
}
|
}
|
||||||
elseif (isset($_SERVER['PHP_SELF']) && ($len = strlen($_SERVER['PHP_SELF'])) && $len >= 10 && substr($_SERVER['PHP_SELF'], $len - 10) === '/index.php')
|
elseif (isset($_SERVER['PHP_SELF']) && ($pos = strpos($_SERVER['PHP_SELF'], '/index.php')) !== false)
|
||||||
{
|
{
|
||||||
define('RX_BASEURL', str_replace('//', '/', '/' . trim(str_replace('\\', '/', substr($_SERVER['PHP_SELF'], 0, $len - 10)), '/') . '/'));
|
define('RX_BASEURL', str_replace('//', '/', '/' . trim(str_replace('\\', '/', substr($_SERVER['PHP_SELF'], 0, $pos)), '/') . '/'));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -66,6 +66,11 @@ elseif (isset($_SERVER['REMOTE_ADDR']) && @inet_pton($_SERVER['REMOTE_ADDR']) !=
|
||||||
define('RX_CLIENT_IP_VERSION', 6);
|
define('RX_CLIENT_IP_VERSION', 6);
|
||||||
define('RX_CLIENT_IP', $_SERVER['REMOTE_ADDR']);
|
define('RX_CLIENT_IP', $_SERVER['REMOTE_ADDR']);
|
||||||
}
|
}
|
||||||
|
elseif (PHP_SAPI === 'cli')
|
||||||
|
{
|
||||||
|
define('RX_CLIENT_IP_VERSION', 4);
|
||||||
|
define('RX_CLIENT_IP', '127.0.0.1');
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
define('RX_CLIENT_IP_VERSION', 4);
|
define('RX_CLIENT_IP_VERSION', 4);
|
||||||
|
|
@ -135,6 +140,20 @@ define('_XE_LOCATION_SITE_', 'https://www.xpressengine.com/');
|
||||||
define('_XE_DOWNLOAD_SERVER_', 'https://download.xpressengine.com/');
|
define('_XE_DOWNLOAD_SERVER_', 'https://download.xpressengine.com/');
|
||||||
define('__DEBUG__', 0);
|
define('__DEBUG__', 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Status constants for various content types.
|
||||||
|
*/
|
||||||
|
define('RX_STATUS_TEMP', 0);
|
||||||
|
define('RX_STATUS_PUBLIC', 1);
|
||||||
|
define('RX_STATUS_SECRET', 2);
|
||||||
|
define('RX_STATUS_EMBARGO', 3);
|
||||||
|
define('RX_STATUS_TRASH', 4);
|
||||||
|
define('RX_STATUS_CENSORED', 5);
|
||||||
|
define('RX_STATUS_CENSORED_BY_ADMIN', 6);
|
||||||
|
define('RX_STATUS_DELETED', 7);
|
||||||
|
define('RX_STATUS_DELETED_BY_ADMIN', 8);
|
||||||
|
define('RX_STATUS_OTHER', 9);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Other useful constants.
|
* Other useful constants.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ return array(
|
||||||
'mediafilter' => array(
|
'mediafilter' => array(
|
||||||
'iframe' => array(),
|
'iframe' => array(),
|
||||||
'object' => array(),
|
'object' => array(),
|
||||||
|
'classes' => array(),
|
||||||
),
|
),
|
||||||
'mobile' => array(
|
'mobile' => array(
|
||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,6 @@ class Config
|
||||||
// Save the main config file.
|
// Save the main config file.
|
||||||
$buff = '<?php' . "\n" . '// Rhymix System Configuration' . "\n" . 'return ' . self::serialize(self::$_config) . ';' . "\n";
|
$buff = '<?php' . "\n" . '// Rhymix System Configuration' . "\n" . 'return ' . self::serialize(self::$_config) . ';' . "\n";
|
||||||
$result = Storage::write(\RX_BASEDIR . self::$config_filename, $buff) ? true : false;
|
$result = Storage::write(\RX_BASEDIR . self::$config_filename, $buff) ? true : false;
|
||||||
//if (!$result) return false;
|
|
||||||
|
|
||||||
// Save XE-compatible config files.
|
// Save XE-compatible config files.
|
||||||
$db_info = \Context::convertDBInfo(self::$_config);
|
$db_info = \Context::convertDBInfo(self::$_config);
|
||||||
|
|
@ -148,7 +147,7 @@ class Config
|
||||||
Storage::write(\RX_BASEDIR . self::$old_db_config_filename, $buff);
|
Storage::write(\RX_BASEDIR . self::$old_db_config_filename, $buff);
|
||||||
$buff = '<?php' . "\n\n" . $warning . "\n\n" . '$ftp_info = ' . self::serialize($ftp_info) . ';' . "\n";
|
$buff = '<?php' . "\n\n" . $warning . "\n\n" . '$ftp_info = ' . self::serialize($ftp_info) . ';' . "\n";
|
||||||
Storage::write(\RX_BASEDIR . self::$old_ftp_config_filename, $buff);
|
Storage::write(\RX_BASEDIR . self::$old_ftp_config_filename, $buff);
|
||||||
return true;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -236,10 +236,33 @@ class Debug
|
||||||
'file' => $query['called_file'],
|
'file' => $query['called_file'],
|
||||||
'line' => $query['called_line'],
|
'line' => $query['called_line'],
|
||||||
'method' => $query['called_method'],
|
'method' => $query['called_method'],
|
||||||
'backtrace' => $query['backtrace'],
|
'backtrace' => $query['backtrace'] ?: array(),
|
||||||
);
|
);
|
||||||
|
|
||||||
self::$_queries[] = $query_object;
|
self::$_queries[] = $query_object;
|
||||||
|
|
||||||
|
// Add the entry to the error log if the result wasn't successful.
|
||||||
|
if ($query['result'] === 'error')
|
||||||
|
{
|
||||||
|
$error_object = (object)array(
|
||||||
|
'type' => 'Query Error',
|
||||||
|
'time' => $query_object->time,
|
||||||
|
'message' => $query['errstr'] . ' (code ' . intval($query['errno']) . ')',
|
||||||
|
'file' => $query_object->file,
|
||||||
|
'line' => $query_object->line,
|
||||||
|
'backtrace' => $query_object->backtrace ?: array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
self::$_errors[] = $error_object;
|
||||||
|
|
||||||
|
if (config('debug.write_error_log') === 'all')
|
||||||
|
{
|
||||||
|
$log_entry = strtr(sprintf('Query Error: %s in %s on line %d', $error_object->message, $error_object->file, intval($error_object->line)), "\0\r\n\t\v\e\f", ' ');
|
||||||
|
error_log($log_entry . \PHP_EOL . self::formatBacktrace($error_object->backtrace));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the entry to the slow query log.
|
||||||
if ($query_object->query_time && $query_object->query_time >= config('debug.log_slow_queries'))
|
if ($query_object->query_time && $query_object->query_time >= config('debug.log_slow_queries'))
|
||||||
{
|
{
|
||||||
self::$_slow_queries[] = $query_object;
|
self::$_slow_queries[] = $query_object;
|
||||||
|
|
|
||||||
7
common/framework/drivers/cache/redis.php
vendored
7
common/framework/drivers/cache/redis.php
vendored
|
|
@ -143,6 +143,10 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (ctype_digit($value))
|
||||||
|
{
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
$value = unserialize($value);
|
$value = unserialize($value);
|
||||||
if ($value === false)
|
if ($value === false)
|
||||||
|
|
@ -168,7 +172,8 @@ class Redis implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return $this->_conn->setex($key, $ttl, serialize($value)) ? true : false;
|
$value = (is_scalar($value) && ctype_digit($value)) ? $value : serialize($value);
|
||||||
|
return $this->_conn->setex($key, $ttl, $value) ? true : false;
|
||||||
}
|
}
|
||||||
catch (\RedisException $e)
|
catch (\RedisException $e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
36
common/framework/drivers/cache/sqlite.php
vendored
36
common/framework/drivers/cache/sqlite.php
vendored
|
|
@ -61,6 +61,7 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
protected function _connect($filename)
|
protected function _connect($filename)
|
||||||
{
|
{
|
||||||
$this->_dbh = new \SQLite3($filename);
|
$this->_dbh = new \SQLite3($filename);
|
||||||
|
$this->_dbh->busyTimeout(250);
|
||||||
$this->_dbh->exec('PRAGMA journal_mode = MEMORY');
|
$this->_dbh->exec('PRAGMA journal_mode = MEMORY');
|
||||||
$this->_dbh->exec('PRAGMA synchronous = OFF');
|
$this->_dbh->exec('PRAGMA synchronous = OFF');
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +90,7 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
*/
|
*/
|
||||||
public static function isSupported()
|
public static function isSupported()
|
||||||
{
|
{
|
||||||
return class_exists('\\SQLite3', false) && config('crypto.authentication_key') !== null;
|
return class_exists('\\SQLite3', false) && config('crypto.authentication_key') !== null && stripos(\PHP_SAPI, 'win') === false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -117,8 +118,18 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
{
|
{
|
||||||
$table = 'cache_' . (crc32($key) % 32);
|
$table = 'cache_' . (crc32($key) % 32);
|
||||||
$stmt = $this->_dbh->prepare('SELECT v, exp FROM ' . $table . ' WHERE k = :key');
|
$stmt = $this->_dbh->prepare('SELECT v, exp FROM ' . $table . ' WHERE k = :key');
|
||||||
|
if (!$stmt)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
||||||
$result = $stmt->execute();
|
$result = $stmt->execute();
|
||||||
|
if (!$result)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$row = $result->fetchArray(\SQLITE3_NUM);
|
$row = $result->fetchArray(\SQLITE3_NUM);
|
||||||
if ($row)
|
if ($row)
|
||||||
{
|
{
|
||||||
|
|
@ -154,6 +165,11 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
{
|
{
|
||||||
$table = 'cache_' . (crc32($key) % 32);
|
$table = 'cache_' . (crc32($key) % 32);
|
||||||
$stmt = $this->_dbh->prepare('INSERT OR REPLACE INTO ' . $table . ' (k, v, exp) VALUES (:key, :val, :exp)');
|
$stmt = $this->_dbh->prepare('INSERT OR REPLACE INTO ' . $table . ' (k, v, exp) VALUES (:key, :val, :exp)');
|
||||||
|
if (!$stmt)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
||||||
$stmt->bindValue(':val', serialize($value), \SQLITE3_TEXT);
|
$stmt->bindValue(':val', serialize($value), \SQLITE3_TEXT);
|
||||||
$stmt->bindValue(':exp', $ttl ? (time() + $ttl) : 0, \SQLITE3_INTEGER);
|
$stmt->bindValue(':exp', $ttl ? (time() + $ttl) : 0, \SQLITE3_INTEGER);
|
||||||
|
|
@ -173,6 +189,11 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
{
|
{
|
||||||
$table = 'cache_' . (crc32($key) % 32);
|
$table = 'cache_' . (crc32($key) % 32);
|
||||||
$stmt = $this->_dbh->prepare('DELETE FROM ' . $table . ' WHERE k = :key');
|
$stmt = $this->_dbh->prepare('DELETE FROM ' . $table . ' WHERE k = :key');
|
||||||
|
if (!$stmt)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
||||||
return $stmt->execute() ? true : false;
|
return $stmt->execute() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
@ -189,9 +210,19 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
{
|
{
|
||||||
$table = 'cache_' . (crc32($key) % 32);
|
$table = 'cache_' . (crc32($key) % 32);
|
||||||
$stmt = $this->_dbh->prepare('SELECT 1 FROM ' . $table . ' WHERE k = :key AND (exp = 0 OR exp >= :exp)');
|
$stmt = $this->_dbh->prepare('SELECT 1 FROM ' . $table . ' WHERE k = :key AND (exp = 0 OR exp >= :exp)');
|
||||||
|
if (!$stmt)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
$stmt->bindValue(':key', $key, \SQLITE3_TEXT);
|
||||||
$stmt->bindValue(':exp', time(), \SQLITE3_INTEGER);
|
$stmt->bindValue(':exp', time(), \SQLITE3_INTEGER);
|
||||||
$result = $stmt->execute();
|
$result = $stmt->execute();
|
||||||
|
if (!$result)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$row = $result->fetchArray(\SQLITE3_NUM);
|
$row = $result->fetchArray(\SQLITE3_NUM);
|
||||||
if ($row)
|
if ($row)
|
||||||
{
|
{
|
||||||
|
|
@ -215,14 +246,17 @@ class SQLite implements \Rhymix\Framework\Drivers\CacheInterface
|
||||||
*/
|
*/
|
||||||
public function incr($key, $amount)
|
public function incr($key, $amount)
|
||||||
{
|
{
|
||||||
|
$this->_dbh->exec('BEGIN');
|
||||||
$current_value = $this->get($key);
|
$current_value = $this->get($key);
|
||||||
$new_value = intval($current_value) + $amount;
|
$new_value = intval($current_value) + $amount;
|
||||||
if ($this->set($key, $new_value))
|
if ($this->set($key, $new_value))
|
||||||
{
|
{
|
||||||
|
$this->_dbh->exec('COMMIT');
|
||||||
return $new_value;
|
return $new_value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
$this->_dbh->exec('ROLLBACK');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ abstract class Base implements \Rhymix\Framework\Drivers\MailInterface
|
||||||
* Create a new instance of the current mail driver, using the given settings.
|
* Create a new instance of the current mail driver, using the given settings.
|
||||||
*
|
*
|
||||||
* @param array $config
|
* @param array $config
|
||||||
* @return void
|
* @return object
|
||||||
*/
|
*/
|
||||||
public static function getInstance(array $config)
|
public static function getInstance(array $config)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -160,13 +160,16 @@ class Woorimail extends Base implements \Rhymix\Framework\Drivers\MailInterface
|
||||||
$data['receiver_nickname'] = implode(',', $data['receiver_nickname']);
|
$data['receiver_nickname'] = implode(',', $data['receiver_nickname']);
|
||||||
|
|
||||||
// Define connection options.
|
// Define connection options.
|
||||||
|
$headers = array(
|
||||||
|
'Accept' => 'application/json, text/javascript, */*; q=0.1',
|
||||||
|
);
|
||||||
$options = array(
|
$options = array(
|
||||||
'timeout' => 5,
|
'timeout' => 5,
|
||||||
'useragent' => 'PHP',
|
'useragent' => 'PHP',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Send the API request.
|
// Send the API request.
|
||||||
$request = \Requests::post(self::$_url, array(), $data, $options);
|
$request = \Requests::post(self::$_url, $headers, $data, $options);
|
||||||
$result = @json_decode($request->body);
|
$result = @json_decode($request->body);
|
||||||
|
|
||||||
// Parse the result.
|
// Parse the result.
|
||||||
|
|
|
||||||
120
common/framework/drivers/sms/base.php
Normal file
120
common/framework/drivers/sms/base.php
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rhymix\Framework\Drivers\SMS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base class for other SMS drivers.
|
||||||
|
*/
|
||||||
|
abstract class Base implements \Rhymix\Framework\Drivers\SMSInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The configuration is stored here.
|
||||||
|
*/
|
||||||
|
protected $_config = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The driver specification is stored here.
|
||||||
|
*/
|
||||||
|
protected static $_spec = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config keys used by this driver are stored here.
|
||||||
|
*/
|
||||||
|
protected static $_required_config = array();
|
||||||
|
protected static $_optional_config = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Direct invocation of the constructor is not permitted.
|
||||||
|
*/
|
||||||
|
protected function __construct(array $config)
|
||||||
|
{
|
||||||
|
$this->_config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance of the current SMS driver, using the given settings.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public static function getInstance(array $config)
|
||||||
|
{
|
||||||
|
return new static($config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the human-readable name of this SMS driver.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getName()
|
||||||
|
{
|
||||||
|
return class_basename(get_called_class());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of configuration fields required by this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getRequiredConfig()
|
||||||
|
{
|
||||||
|
return static::$_required_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of configuration fields optionally used by this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getOptionalConfig()
|
||||||
|
{
|
||||||
|
return static::$_optional_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of API types supported by this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAPITypes()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the spec for this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAPISpec()
|
||||||
|
{
|
||||||
|
return static::$_spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current SMS driver is supported on this server.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isSupported()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @param array $messages
|
||||||
|
* @param object $original
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function send(array $messages, \Rhymix\Framework\SMS $original)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
123
common/framework/drivers/sms/coolsms.php
Normal file
123
common/framework/drivers/sms/coolsms.php
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rhymix\Framework\Drivers\SMS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The CoolSMS SMS driver.
|
||||||
|
*/
|
||||||
|
class CoolSMS extends Base implements \Rhymix\Framework\Drivers\SMSInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* API specifications.
|
||||||
|
*/
|
||||||
|
protected static $_spec = array(
|
||||||
|
'max_recipients' => 1000,
|
||||||
|
'sms_max_length' => 90,
|
||||||
|
'sms_max_length_in_charset' => 'CP949',
|
||||||
|
'lms_supported' => true,
|
||||||
|
'lms_supported_country_codes' => array(82),
|
||||||
|
'lms_max_length' => 2000,
|
||||||
|
'lms_max_length_in_charset' => 'CP949',
|
||||||
|
'lms_subject_supported' => true,
|
||||||
|
'lms_subject_max_length' => 40,
|
||||||
|
'mms_supported' => true,
|
||||||
|
'mms_supported_country_codes' => array(82),
|
||||||
|
'mms_max_length' => 2000,
|
||||||
|
'mms_max_length_in_charset' => 'CP949',
|
||||||
|
'mms_subject_supported' => true,
|
||||||
|
'mms_subject_max_length' => 40,
|
||||||
|
'image_allowed_types' => array('jpg', 'gif', 'png'),
|
||||||
|
'image_max_dimensions' => array(2048, 2048),
|
||||||
|
'image_max_filesize' => 300000,
|
||||||
|
'delay_supported' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config keys used by this driver are stored here.
|
||||||
|
*/
|
||||||
|
protected static $_required_config = array('api_key', 'api_secret');
|
||||||
|
protected static $_optional_config = array('sender_key');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current SMS driver is supported on this server.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isSupported()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @param array $messages
|
||||||
|
* @param object $original
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function send(array $messages, \Rhymix\Framework\SMS $original)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$sender = new \Nurigo\Api\Message($this->_config['api_key'], $this->_config['api_secret']);
|
||||||
|
$status = true;
|
||||||
|
|
||||||
|
foreach ($messages as $i => $message)
|
||||||
|
{
|
||||||
|
$options = new \stdClass;
|
||||||
|
if ($this->_config['sender_key'])
|
||||||
|
{
|
||||||
|
$options->sender_key = $this->_config['sender_key'];
|
||||||
|
$options->type = 'CTA';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$options->type = $message->type;
|
||||||
|
}
|
||||||
|
$options->from = $message->from;
|
||||||
|
$options->to = implode(',', $message->to);
|
||||||
|
$options->text = $message->content ?: $message->type;
|
||||||
|
$options->charset = 'utf8';
|
||||||
|
$options->srk = 'K0009334574';
|
||||||
|
if ($message->delay && $message->delay > time())
|
||||||
|
{
|
||||||
|
$options->datetime = gmdate('YmdHis', $message->delay + (3600 * 9));
|
||||||
|
}
|
||||||
|
if ($message->country && $message->country != 82)
|
||||||
|
{
|
||||||
|
$options->country = $message->country;
|
||||||
|
}
|
||||||
|
if ($message->subject)
|
||||||
|
{
|
||||||
|
$options->subject = $message->subject;
|
||||||
|
}
|
||||||
|
if ($message->image)
|
||||||
|
{
|
||||||
|
$options->image = $message->image;
|
||||||
|
}
|
||||||
|
foreach ($original->getExtraVars() as $key => $value)
|
||||||
|
{
|
||||||
|
$options->$key = $value;
|
||||||
|
}
|
||||||
|
$result = $sender->send($options);
|
||||||
|
if (!$result->success_count)
|
||||||
|
{
|
||||||
|
$error_codes = implode(', ', $result->error_list ?: array('Unknown'));
|
||||||
|
$original->addError('Error (' . $error_codes . ') while sending message ' . ($i + 1) . ' of ' . count($messages) . ' to ' . $options->to);
|
||||||
|
$status = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $status;
|
||||||
|
}
|
||||||
|
catch (\Nurigo\Exceptions\CoolsmsException $e)
|
||||||
|
{
|
||||||
|
$message->errors[] = class_basename($e) . ': ' . $e->getMessage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
common/framework/drivers/sms/dummy.php
Normal file
89
common/framework/drivers/sms/dummy.php
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rhymix\Framework\Drivers\SMS;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The dummy SMS driver.
|
||||||
|
*/
|
||||||
|
class Dummy extends Base implements \Rhymix\Framework\Drivers\SMSInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* API specifications.
|
||||||
|
*/
|
||||||
|
protected static $_spec = array(
|
||||||
|
'max_recipients' => 100,
|
||||||
|
'sms_max_length' => 90,
|
||||||
|
'sms_max_length_in_charset' => 'CP949',
|
||||||
|
'lms_supported' => true,
|
||||||
|
'lms_supported_country_codes' => array(82),
|
||||||
|
'lms_max_length' => 2000,
|
||||||
|
'lms_max_length_in_charset' => 'CP949',
|
||||||
|
'lms_subject_supported' => true,
|
||||||
|
'lms_subject_max_length' => 40,
|
||||||
|
'mms_supported' => true,
|
||||||
|
'mms_supported_country_codes' => array(82),
|
||||||
|
'mms_max_length' => 2000,
|
||||||
|
'mms_max_length_in_charset' => 'CP949',
|
||||||
|
'mms_subject_supported' => false,
|
||||||
|
'mms_subject_max_length' => 40,
|
||||||
|
'image_allowed_types' => array(),
|
||||||
|
'image_max_dimensions' => array(1024, 1024),
|
||||||
|
'image_max_filesize' => 300000,
|
||||||
|
'delay_supported' => true,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sent messages are stored here for debugging and testing.
|
||||||
|
*/
|
||||||
|
protected $_sent_messages = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current SMS driver is supported on this server.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isSupported()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @param array $messages
|
||||||
|
* @param object $original
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function send(array $messages, \Rhymix\Framework\SMS $original)
|
||||||
|
{
|
||||||
|
foreach ($messages as $message)
|
||||||
|
{
|
||||||
|
$this->_sent_messages[] = $message;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get sent messages.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSentMessages()
|
||||||
|
{
|
||||||
|
return $this->_sent_messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset sent messages.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function resetSentMessages()
|
||||||
|
{
|
||||||
|
$this->_sent_messages = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
72
common/framework/drivers/smsinterface.php
Normal file
72
common/framework/drivers/smsinterface.php
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rhymix\Framework\Drivers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SMS driver interface.
|
||||||
|
*/
|
||||||
|
interface SMSInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new instance of the current SMS driver, using the given settings.
|
||||||
|
*
|
||||||
|
* @param array $config
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function getInstance(array $config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the human-readable name of this SMS driver.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of configuration fields required by this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getRequiredConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of configuration fields optionally used by this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getOptionalConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of API types supported by this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAPITypes();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the spec for this SMS driver.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getAPISpec();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the current SMS driver is supported on this server.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isSupported();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message.
|
||||||
|
*
|
||||||
|
* This method returns true on success and false on failure.
|
||||||
|
*
|
||||||
|
* @param array $messages
|
||||||
|
* @param object $original
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function send(array $messages, \Rhymix\Framework\SMS $original);
|
||||||
|
}
|
||||||
|
|
@ -16,8 +16,8 @@ class FilenameFilter
|
||||||
public static function clean($filename)
|
public static function clean($filename)
|
||||||
{
|
{
|
||||||
// Replace dangerous characters with safe alternatives, maintaining meaning as much as possible.
|
// Replace dangerous characters with safe alternatives, maintaining meaning as much as possible.
|
||||||
$illegal = array('\\', '/', '<', '>', '{', '}', ':', ';', '|', '"', '~', '`', '@', '#', '$', '%', '^', '&', '*', '?');
|
$illegal = array('\\', '/', '<', '>', '{', '}', ':', ';', '|', '"', '~', '`', '$', '%', '^', '*', '?');
|
||||||
$replace = array('', '', '(', ')', '(', ')', '_', ',', '_', '', '_', '\'', '_', '_', '_', '_', '_', '_', '', '');
|
$replace = array('', '', '(', ')', '(', ')', '_', ',', '_', '', '_', '\'', '_', '_', '_', '', '');
|
||||||
$filename = str_replace($illegal, $replace, $filename);
|
$filename = str_replace($illegal, $replace, $filename);
|
||||||
|
|
||||||
// Remove control characters.
|
// Remove control characters.
|
||||||
|
|
@ -85,4 +85,22 @@ class FilenameFilter
|
||||||
// Trim trailing slashes.
|
// Trim trailing slashes.
|
||||||
return rtrim($path, '/');
|
return rtrim($path, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a file has an extension that would allow direct download.
|
||||||
|
*
|
||||||
|
* @param string $filename
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isDirectDownload($filename)
|
||||||
|
{
|
||||||
|
if (preg_match('/\.(as[fx]|avi|flac|flv|gif|jpe?g|m4[av]|midi?|mkv|moov|mov|mp[1234]|mpe?g|ogg|png|qt|ram?|rmm?|swf|wav|web[mp]|wm[av])$/i', $filename))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Rhymix\Framework\Filters;
|
namespace Rhymix\Framework\Filters;
|
||||||
|
|
||||||
|
use Rhymix\Framework\Config;
|
||||||
use Rhymix\Framework\Security;
|
use Rhymix\Framework\Security;
|
||||||
use Rhymix\Framework\Storage;
|
use Rhymix\Framework\Storage;
|
||||||
|
|
||||||
|
|
@ -11,9 +12,9 @@ use Rhymix\Framework\Storage;
|
||||||
class HTMLFilter
|
class HTMLFilter
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* HTMLPurifier instance is cached here.
|
* HTMLPurifier instances are cached here.
|
||||||
*/
|
*/
|
||||||
protected static $_htmlpurifier;
|
protected static $_instances = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pre-processing and post-processing filters are stored here.
|
* Pre-processing and post-processing filters are stored here.
|
||||||
|
|
@ -69,18 +70,42 @@ class HTMLFilter
|
||||||
* Filter HTML content to block XSS attacks.
|
* Filter HTML content to block XSS attacks.
|
||||||
*
|
*
|
||||||
* @param string $input
|
* @param string $input
|
||||||
|
* @param array|bool $allow_classes (optional)
|
||||||
|
* @param bool $allow_editor_components (optional)
|
||||||
|
* @param bool $allow_widgets (optional)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function clean($input)
|
public static function clean($input, $allow_classes = false, $allow_editor_components = true, $allow_widgets = false)
|
||||||
{
|
{
|
||||||
foreach (self::$_preproc as $callback)
|
foreach (self::$_preproc as $callback)
|
||||||
{
|
{
|
||||||
$input = $callback($input);
|
$input = $callback($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
$input = self::_preprocess($input);
|
if ($allow_classes === true)
|
||||||
$output = self::getHTMLPurifier()->purify($input);
|
{
|
||||||
$output = self::_postprocess($output);
|
$allowed_classes = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (is_array($allow_classes))
|
||||||
|
{
|
||||||
|
$allowed_classes = array_values($allow_classes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$allowed_classes = Config::get('mediafilter.classes') ?: array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($allow_widgets)
|
||||||
|
{
|
||||||
|
$allowed_classes[] = 'zbxe_widget_output';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = self::_preprocess($input, $allow_editor_components, $allow_widgets);
|
||||||
|
$output = self::getHTMLPurifier($allowed_classes)->purify($input);
|
||||||
|
$output = self::_postprocess($output, $allow_editor_components, $allow_widgets);
|
||||||
|
|
||||||
foreach (self::$_postproc as $callback)
|
foreach (self::$_postproc as $callback)
|
||||||
{
|
{
|
||||||
|
|
@ -93,17 +118,27 @@ class HTMLFilter
|
||||||
/**
|
/**
|
||||||
* Get an instance of HTMLPurifier.
|
* Get an instance of HTMLPurifier.
|
||||||
*
|
*
|
||||||
|
* @param array|null $allowed_classes (optional)
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public static function getHTMLPurifier()
|
public static function getHTMLPurifier($allowed_classes = null)
|
||||||
{
|
{
|
||||||
|
// Keep separate instances for different sets of allowed classes.
|
||||||
|
if ($allowed_classes !== null)
|
||||||
|
{
|
||||||
|
$allowed_classes = array_unique($allowed_classes);
|
||||||
|
sort($allowed_classes);
|
||||||
|
}
|
||||||
|
$key = sha1(serialize($allowed_classes));
|
||||||
|
|
||||||
// Create an instance with reasonable defaults.
|
// Create an instance with reasonable defaults.
|
||||||
if (self::$_htmlpurifier === null)
|
if (!isset(self::$_instances[$key]))
|
||||||
{
|
{
|
||||||
// Get the default configuration.
|
// Get the default configuration.
|
||||||
$config = \HTMLPurifier_Config::createDefault();
|
$config = \HTMLPurifier_Config::createDefault();
|
||||||
|
|
||||||
// Customize the default configuration.
|
// Customize the default configuration.
|
||||||
|
$config->set('Attr.AllowedClasses', $allowed_classes);
|
||||||
$config->set('Attr.AllowedFrameTargets', array('_blank'));
|
$config->set('Attr.AllowedFrameTargets', array('_blank'));
|
||||||
$config->set('Attr.DefaultImageAlt', '');
|
$config->set('Attr.DefaultImageAlt', '');
|
||||||
$config->set('Attr.EnableID', true);
|
$config->set('Attr.EnableID', true);
|
||||||
|
|
@ -143,11 +178,11 @@ class HTMLFilter
|
||||||
self::_supportCSS3($config);
|
self::_supportCSS3($config);
|
||||||
|
|
||||||
// Cache our instance of HTMLPurifier.
|
// Cache our instance of HTMLPurifier.
|
||||||
self::$_htmlpurifier = new \HTMLPurifier($config);
|
self::$_instances[$key] = new \HTMLPurifier($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the cached instance.
|
// Return the cached instance.
|
||||||
return self::$_htmlpurifier;
|
return self::$_instances[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -226,6 +261,7 @@ class HTMLFilter
|
||||||
));
|
));
|
||||||
|
|
||||||
// Support additional properties.
|
// Support additional properties.
|
||||||
|
$def->addAttribute('i', 'aria-hidden', 'Text');
|
||||||
$def->addAttribute('img', 'srcset', 'Text');
|
$def->addAttribute('img', 'srcset', 'Text');
|
||||||
$def->addAttribute('iframe', 'allowfullscreen', 'Bool');
|
$def->addAttribute('iframe', 'allowfullscreen', 'Bool');
|
||||||
}
|
}
|
||||||
|
|
@ -378,12 +414,17 @@ class HTMLFilter
|
||||||
* Rhymix-specific preprocessing method.
|
* Rhymix-specific preprocessing method.
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
|
* @param bool $allow_editor_components (optional)
|
||||||
|
* @param bool $allow_widgets (optional)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected static function _preprocess($content)
|
protected static function _preprocess($content, $allow_editor_components = true, $allow_widgets = false)
|
||||||
{
|
{
|
||||||
// Encode widget and editor component properties so that they are not removed by HTMLPurifier.
|
// Encode widget and editor component properties so that they are not removed by HTMLPurifier.
|
||||||
$content = self::_encodeWidgetsAndEditorComponents($content);
|
if ($allow_editor_components || $allow_widgets)
|
||||||
|
{
|
||||||
|
$content = self::_encodeWidgetsAndEditorComponents($content, $allow_editor_components, $allow_widgets);
|
||||||
|
}
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,9 +432,11 @@ class HTMLFilter
|
||||||
* Rhymix-specific postprocessing method.
|
* Rhymix-specific postprocessing method.
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
|
* @param bool $allow_editor_components (optional)
|
||||||
|
* @param bool $allow_widgets (optional)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected static function _postprocess($content)
|
protected static function _postprocess($content, $allow_editor_components = true, $allow_widgets = false)
|
||||||
{
|
{
|
||||||
// Define acts to allow and deny.
|
// Define acts to allow and deny.
|
||||||
$allow_acts = array('procFileDownload');
|
$allow_acts = array('procFileDownload');
|
||||||
|
|
@ -435,7 +478,7 @@ class HTMLFilter
|
||||||
}, $content);
|
}, $content);
|
||||||
|
|
||||||
// Restore widget and editor component properties.
|
// Restore widget and editor component properties.
|
||||||
$content = self::_decodeWidgetsAndEditorComponents($content);
|
$content = self::_decodeWidgetsAndEditorComponents($content, $allow_editor_components, $allow_widgets);
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -443,11 +486,27 @@ class HTMLFilter
|
||||||
* Encode widgets and editor components before processing.
|
* Encode widgets and editor components before processing.
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
|
* @param bool $allow_editor_components (optional)
|
||||||
|
* @param bool $allow_widgets (optional)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected static function _encodeWidgetsAndEditorComponents($content)
|
protected static function _encodeWidgetsAndEditorComponents($content, $allow_editor_components = true, $allow_widgets = false)
|
||||||
{
|
{
|
||||||
return preg_replace_callback('!<(div|img)([^>]*)(editor_component="[^"]+"|class="zbxe_widget_output")([^>]*)>!i', function($match) {
|
$regexp = array();
|
||||||
|
if ($allow_editor_components)
|
||||||
|
{
|
||||||
|
$regexp[] = 'editor_component="[^"]+"';
|
||||||
|
}
|
||||||
|
if ($allow_widgets)
|
||||||
|
{
|
||||||
|
$regexp[] = 'class="zbxe_widget_output"';
|
||||||
|
}
|
||||||
|
if (!count($regexp))
|
||||||
|
{
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_replace_callback('!<(div|img)([^>]*)(' . implode('|', $regexp) . ')([^>]*)>!i', function($match) {
|
||||||
$tag = strtolower($match[1]);
|
$tag = strtolower($match[1]);
|
||||||
$attrs = array();
|
$attrs = array();
|
||||||
$html = preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use($tag, &$attrs) {
|
$html = preg_replace_callback('!([a-zA-Z0-9_-]+)="([^"]+)"!', function($attr) use($tag, &$attrs) {
|
||||||
|
|
@ -476,10 +535,25 @@ class HTMLFilter
|
||||||
* Decode widgets and editor components after processing.
|
* Decode widgets and editor components after processing.
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
|
* @param bool $allow_editor_components (optional)
|
||||||
|
* @param bool $allow_widgets (optional)
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected static function _decodeWidgetsAndEditorComponents($content)
|
protected static function _decodeWidgetsAndEditorComponents($content, $allow_editor_components = true, $allow_widgets = false)
|
||||||
{
|
{
|
||||||
|
if (!$allow_editor_components)
|
||||||
|
{
|
||||||
|
$content = preg_replace('!(<(?:div|img)[^>]*)\s(editor_component="(?:[^"]+)")!i', '$1', $content);
|
||||||
|
}
|
||||||
|
if (!$allow_widgets)
|
||||||
|
{
|
||||||
|
$content = preg_replace('!(<(?:div|img)[^>]*)\s(widget="(?:[^"]+)")!i', '$1blocked-$2', $content);
|
||||||
|
}
|
||||||
|
if (!$allow_editor_components && !$allow_widgets)
|
||||||
|
{
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
return preg_replace_callback('!<(div|img)([^>]*)(\srx_encoded_properties="([^"]+)")!i', function($match) {
|
return preg_replace_callback('!<(div|img)([^>]*)(\srx_encoded_properties="([^"]+)")!i', function($match) {
|
||||||
$attrs = array();
|
$attrs = array();
|
||||||
$decoded_properties = Security::decrypt($match[4]);
|
$decoded_properties = Security::decrypt($match[4]);
|
||||||
|
|
|
||||||
820
common/framework/sms.php
Normal file
820
common/framework/sms.php
Normal file
|
|
@ -0,0 +1,820 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rhymix\Framework;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SMS class.
|
||||||
|
*/
|
||||||
|
class SMS
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Instance properties.
|
||||||
|
*/
|
||||||
|
public $driver = null;
|
||||||
|
protected $caller = '';
|
||||||
|
protected $from = null;
|
||||||
|
protected $to = array();
|
||||||
|
protected $subject = '';
|
||||||
|
protected $content = '';
|
||||||
|
protected $attachments = array();
|
||||||
|
protected $extra_vars = array();
|
||||||
|
protected $delay_timestamp = 0;
|
||||||
|
protected $force_sms = false;
|
||||||
|
protected $allow_split_sms = true;
|
||||||
|
protected $allow_split_lms = true;
|
||||||
|
protected $errors = array();
|
||||||
|
protected $sent = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static properties.
|
||||||
|
*/
|
||||||
|
public static $default_driver = null;
|
||||||
|
public static $custom_drivers = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the default driver.
|
||||||
|
*
|
||||||
|
* @param object $driver
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function setDefaultDriver(Drivers\SMSInterface $driver)
|
||||||
|
{
|
||||||
|
self::$default_driver = $driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the default driver.
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public static function getDefaultDriver()
|
||||||
|
{
|
||||||
|
if (!self::$default_driver)
|
||||||
|
{
|
||||||
|
$default_driver = config('sms.type');
|
||||||
|
$default_driver_class = '\Rhymix\Framework\Drivers\SMS\\' . $default_driver;
|
||||||
|
if (class_exists($default_driver_class))
|
||||||
|
{
|
||||||
|
$default_driver_config = config('sms.' . $default_driver) ?: array();
|
||||||
|
self::$default_driver = $default_driver_class::getInstance($default_driver_config);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self::$default_driver = Drivers\SMS\Dummy::getInstance(array());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return self::$default_driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a custom mail driver.
|
||||||
|
*/
|
||||||
|
public static function addDriver(Drivers\SMSInterface $driver)
|
||||||
|
{
|
||||||
|
self::$custom_drivers[] = $driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of supported mail drivers.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getSupportedDrivers()
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
foreach (Storage::readDirectory(__DIR__ . '/drivers/sms', false) as $filename)
|
||||||
|
{
|
||||||
|
$driver_name = substr($filename, 0, -4);
|
||||||
|
$class_name = '\Rhymix\Framework\Drivers\SMS\\' . $driver_name;
|
||||||
|
if ($class_name::isSupported())
|
||||||
|
{
|
||||||
|
$result[$driver_name] = array(
|
||||||
|
'name' => $class_name::getName(),
|
||||||
|
'required' => $class_name::getRequiredConfig(),
|
||||||
|
'optional' => $class_name::getOptionalConfig(),
|
||||||
|
'api_types' => $class_name::getAPITypes(),
|
||||||
|
'api_spec' => $class_name::getAPISpec(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (self::$custom_drivers as $driver)
|
||||||
|
{
|
||||||
|
if ($driver->isSupported())
|
||||||
|
{
|
||||||
|
$result[strtolower(class_basename($driver))] = array(
|
||||||
|
'name' => $driver->getName(),
|
||||||
|
'required' => $driver->getRequiredConfig(),
|
||||||
|
'optional' => $driver->getOptionalConfig(),
|
||||||
|
'api_types' => $driver->getAPITypes(),
|
||||||
|
'api_spec' => $class_name::getAPISpec(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ksort($result);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->driver = self::getDefaultDriver();
|
||||||
|
$this->from = trim(preg_replace('/[^0-9]/', '', config('sms.default_from'))) ?: null;
|
||||||
|
$this->allow_split_sms = (config('sms.allow_split.sms') !== false);
|
||||||
|
$this->allow_split_lms = (config('sms.allow_split.lms') !== false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the sender's phone number.
|
||||||
|
*
|
||||||
|
* @param string $number Phone number
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setFrom($number)
|
||||||
|
{
|
||||||
|
$this->from = preg_replace('/[^0-9]/', '', $number);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sender's phone number.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getFrom()
|
||||||
|
{
|
||||||
|
return $this->from;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a recipient.
|
||||||
|
*
|
||||||
|
* @param string $number Phone number
|
||||||
|
* @param string $country Country code (optional)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function addTo($number, $country = 0)
|
||||||
|
{
|
||||||
|
$this->to[] = (object)array(
|
||||||
|
'number' => preg_replace('/[^0-9]/', '', $number),
|
||||||
|
'country' => intval(preg_replace('/[^0-9]/', '', $country)),
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of recipients without country codes.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRecipients()
|
||||||
|
{
|
||||||
|
return array_map(function($recipient) {
|
||||||
|
return $recipient->number;
|
||||||
|
}, $this->to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of recipients with country codes.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRecipientsWithCountry()
|
||||||
|
{
|
||||||
|
return $this->to;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of recipients grouped by country code.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getRecipientsGroupedByCountry()
|
||||||
|
{
|
||||||
|
$result = array();
|
||||||
|
foreach ($this->to as $recipient)
|
||||||
|
{
|
||||||
|
$result[$recipient->country][] = $recipient->number;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the subject.
|
||||||
|
*
|
||||||
|
* @param string $subject
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setSubject($subject)
|
||||||
|
{
|
||||||
|
$this->subject = utf8_trim(utf8_clean($subject));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the subject.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getSubject()
|
||||||
|
{
|
||||||
|
return $this->subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the subject (alias to setSubject).
|
||||||
|
*
|
||||||
|
* @param string $subject
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setTitle($subject)
|
||||||
|
{
|
||||||
|
return $this->setSubject($subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the subject (alias to getSubject).
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getTitle()
|
||||||
|
{
|
||||||
|
return $this->getSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the content.
|
||||||
|
*
|
||||||
|
* @param string $content
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setBody($content)
|
||||||
|
{
|
||||||
|
$this->content = utf8_trim(utf8_clean($content));
|
||||||
|
$this->content = strtr($this->content, array("\r\n" => "\n"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getBody()
|
||||||
|
{
|
||||||
|
return $this->content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the content (alias to setBody).
|
||||||
|
*
|
||||||
|
* @param string $content
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setContent($content)
|
||||||
|
{
|
||||||
|
return $this->setBody($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the content (alias to getBody).
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getContent()
|
||||||
|
{
|
||||||
|
return $this->getBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach a file.
|
||||||
|
*
|
||||||
|
* @param string $local_filename
|
||||||
|
* @param string $display_filename (optional)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function attach($local_filename, $display_filename = null)
|
||||||
|
{
|
||||||
|
if ($display_filename === null)
|
||||||
|
{
|
||||||
|
$display_filename = basename($local_filename);
|
||||||
|
}
|
||||||
|
if (!Storage::exists($local_filename))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->attachments[] = (object)array(
|
||||||
|
'type' => 'mms',
|
||||||
|
'local_filename' => $local_filename,
|
||||||
|
'display_filename' => $display_filename,
|
||||||
|
'cid' => null,
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of attachments to this message.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getAttachments()
|
||||||
|
{
|
||||||
|
return $this->attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an extra variable.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $value
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setExtraVar($key, $value)
|
||||||
|
{
|
||||||
|
$this->extra_vars[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an extra variable.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getExtraVar($key)
|
||||||
|
{
|
||||||
|
return isset($this->extra_vars[$key]) ? $this->extra_vars[$key] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all extra variables.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function getExtraVars()
|
||||||
|
{
|
||||||
|
return $this->extra_vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set all extra variables.
|
||||||
|
*
|
||||||
|
* @param array $vars
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setExtraVars(array $vars)
|
||||||
|
{
|
||||||
|
$this->extra_vars = $vars;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delay sending the message.
|
||||||
|
*
|
||||||
|
* Delays (in seconds) less than 1 year will be treated as relative to the
|
||||||
|
* current time. Greater values will be interpreted as a Unix timestamp.
|
||||||
|
*
|
||||||
|
* This feature may not be implemented by all drivers.
|
||||||
|
*
|
||||||
|
* @param int $when Unix timestamp
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function setDelay($when)
|
||||||
|
{
|
||||||
|
if ($when <= (86400 * 365))
|
||||||
|
{
|
||||||
|
$when = time() + $when;
|
||||||
|
}
|
||||||
|
if ($when <= time())
|
||||||
|
{
|
||||||
|
$when = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->delay_timestamp = intval($when);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Unix timestamp of when to send the message.
|
||||||
|
*
|
||||||
|
* This method always returns a Unix timestamp, even if the original value
|
||||||
|
* was given as a relative delay.
|
||||||
|
*
|
||||||
|
* This feature may not be implemented by all drivers.
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getDelay()
|
||||||
|
{
|
||||||
|
return $this->delay_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force this message to use SMS (not LMS or MMS).
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function forceSMS()
|
||||||
|
{
|
||||||
|
$this->force_sms = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unforce this message to use SMS (not LMS or MMS).
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unforceSMS()
|
||||||
|
{
|
||||||
|
$this->force_sms = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this message is forced to use SMS.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isForceSMS()
|
||||||
|
{
|
||||||
|
return $this->force_sms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow this message to be split into multiple SMS.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function allowSplitSMS()
|
||||||
|
{
|
||||||
|
$this->allow_split_sms = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow this message to be split into multiple LMS.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function allowSplitLMS()
|
||||||
|
{
|
||||||
|
$this->allow_split_lms = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disallow this message to be split into multiple SMS.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function disallowSplitSMS()
|
||||||
|
{
|
||||||
|
$this->allow_split_sms = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disallow this message to be split into multiple LMS.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function disallowSplitLMS()
|
||||||
|
{
|
||||||
|
$this->allow_split_lms = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if splitting this message into multiple SMS is allowed.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isSplitSMSAllowed()
|
||||||
|
{
|
||||||
|
return $this->allow_split_sms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if splitting this message into multiple LMS is allowed.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isSplitLMSAllowed()
|
||||||
|
{
|
||||||
|
return $this->allow_split_lms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the message.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function send()
|
||||||
|
{
|
||||||
|
// Get caller information.
|
||||||
|
$backtrace = debug_backtrace(0);
|
||||||
|
if(count($backtrace) && isset($backtrace[0]['file']))
|
||||||
|
{
|
||||||
|
$this->caller = $backtrace[0]['file'] . ($backtrace[0]['line'] ? (' line ' . $backtrace[0]['line']) : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = \ModuleHandler::triggerCall('sms.send', 'before', $this);
|
||||||
|
if(!$output->toBool())
|
||||||
|
{
|
||||||
|
$this->errors[] = $output->getMessage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config('sms.default_force') && config('sms.default_from'))
|
||||||
|
{
|
||||||
|
$this->setFrom(config('sms.default_from'));
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ($this->driver)
|
||||||
|
{
|
||||||
|
$messages = $this->_formatSpec($this->driver->getAPISpec());
|
||||||
|
if (count($messages))
|
||||||
|
{
|
||||||
|
$this->sent = $this->driver->send($messages, $this) ? true : false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->errors[] = 'No recipients selected';
|
||||||
|
$this->sent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->errors[] = 'No SMS driver selected';
|
||||||
|
$this->sent = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(\Exception $e)
|
||||||
|
{
|
||||||
|
$this->errors[] = class_basename($e) . ': ' . $e->getMessage();
|
||||||
|
$this->sent = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = \ModuleHandler::triggerCall('sms.send', 'after', $this);
|
||||||
|
if(!$output->toBool())
|
||||||
|
{
|
||||||
|
$this->errors[] = $output->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the message was sent.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isSent()
|
||||||
|
{
|
||||||
|
return $this->sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get caller information.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCaller()
|
||||||
|
{
|
||||||
|
return $this->caller;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get errors.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return $this->errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an error message.
|
||||||
|
*
|
||||||
|
* @param string $message
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addError($message)
|
||||||
|
{
|
||||||
|
$this->errors[] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the current message according to an API spec.
|
||||||
|
*
|
||||||
|
* @param array $spec API specifications
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function _formatSpec(array $spec)
|
||||||
|
{
|
||||||
|
// Initialize the return array.
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
// Get the list of recipients.
|
||||||
|
$recipients = $this->getRecipientsGroupedByCountry();
|
||||||
|
|
||||||
|
// Group the recipients by country code.
|
||||||
|
foreach ($recipients as $country_code => $country_recipients)
|
||||||
|
{
|
||||||
|
// Merge recipients into groups.
|
||||||
|
if ($spec['max_recipients'] > 1)
|
||||||
|
{
|
||||||
|
$country_recipients = array_chunk($country_recipients, $spec['max_recipients']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send to each set of merged recipients.
|
||||||
|
foreach ($country_recipients as $recipient_numbers)
|
||||||
|
{
|
||||||
|
// Populate the item.
|
||||||
|
$item = new \stdClass;
|
||||||
|
$item->type = 'SMS';
|
||||||
|
$item->from = $this->getFrom();
|
||||||
|
$item->to = $recipient_numbers;
|
||||||
|
$item->country = $country_code;
|
||||||
|
if ($spec['delay_supported'])
|
||||||
|
{
|
||||||
|
$item->delay = $this->getDelay() ?: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get message content.
|
||||||
|
$subject = $this->getSubject();
|
||||||
|
$content = $this->getContent();
|
||||||
|
$attachments = $attachments = $this->getAttachments();
|
||||||
|
|
||||||
|
// Determine the message type.
|
||||||
|
if (!$this->isForceSMS() && ($spec['lms_supported'] || $spec['mms_supported']))
|
||||||
|
{
|
||||||
|
// Check attachments, subject, and message length.
|
||||||
|
if ($spec['mms_supported'] && count($attachments))
|
||||||
|
{
|
||||||
|
$item->type = 'MMS';
|
||||||
|
}
|
||||||
|
elseif ($spec['lms_supported'] && $subject)
|
||||||
|
{
|
||||||
|
$item->subject = $subject;
|
||||||
|
$item->type = 'LMS';
|
||||||
|
}
|
||||||
|
elseif ($spec['lms_supported'] && $this->_getLengthInCharset($content, $spec['sms_max_length_in_charset']) > $spec['sms_max_length'])
|
||||||
|
{
|
||||||
|
$item->type = 'LMS';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$item->type = 'SMS';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the country code.
|
||||||
|
if ($item->type === 'MMS' && $country_code && is_array($spec['mms_supported_country_codes']) && !in_array($country_code, $spec['mms_supported_country_codes']))
|
||||||
|
{
|
||||||
|
$item->type = 'LMS';
|
||||||
|
}
|
||||||
|
if ($item->type === 'LMS' && $country_code && is_array($spec['lms_supported_country_codes']) && !in_array($country_code, $spec['lms_supported_country_codes']))
|
||||||
|
{
|
||||||
|
$item->type = 'SMS';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove subject and attachments if the message type is SMS.
|
||||||
|
if ($item->type === 'SMS')
|
||||||
|
{
|
||||||
|
if ($subject)
|
||||||
|
{
|
||||||
|
$content = $subject . "\n" . $content;
|
||||||
|
unset($item->subject);
|
||||||
|
}
|
||||||
|
$attachments = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If message subject is not supported, prepend it to the content instead.
|
||||||
|
if ($item->subject && !$spec[strtolower($item->type) . '_subject_supported'])
|
||||||
|
{
|
||||||
|
$content = $item->subject . "\n" . $content;
|
||||||
|
unset($item->subject);
|
||||||
|
}
|
||||||
|
elseif ($item->subject && $this->_getLengthInCharset($item->subject, $spec[strtolower($item->type) . '_max_length_in_charset']) > $spec[strtolower($item->type) . '_subject_max_length'])
|
||||||
|
{
|
||||||
|
$subject_parts = $this->_splitString($item->subject, $spec[strtolower($item->type) . '_subject_max_length'], $spec[strtolower($item->type) . '_max_length_in_charset']);
|
||||||
|
$subject_short = array_shift($subject_parts);
|
||||||
|
$subject_remainder = utf8_trim(substr($item->subject, strlen($subject_short)));
|
||||||
|
$item->subject = $subject_short;
|
||||||
|
$content = $subject_remainder . "\n" . $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split the content if necessary.
|
||||||
|
if (($item->type === 'SMS' && $this->allow_split_sms) || ($item->type !== 'SMS' && $this->allow_split_lms))
|
||||||
|
{
|
||||||
|
if ($this->_getLengthInCharset($content, $spec[strtolower($item->type) . '_max_length_in_charset']) > $spec[strtolower($item->type) . '_max_length'])
|
||||||
|
{
|
||||||
|
$content_parts = $this->_splitString($content, $spec[strtolower($item->type) . '_max_length'], $spec[strtolower($item->type) . '_max_length_in_charset']);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$content_parts = array($content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$content_parts = array($content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a message for each part of the content and attachments.
|
||||||
|
$message_count = max(count($content_parts), count($attachments));
|
||||||
|
$last_content = $item->type;
|
||||||
|
for ($i = 1; $i <= $message_count; $i++)
|
||||||
|
{
|
||||||
|
// Get the message content.
|
||||||
|
if ($content_part = array_shift($content_parts))
|
||||||
|
{
|
||||||
|
$item->content = $last_content = $content_part;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$item->content = $last_content ?: $item->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the attachment.
|
||||||
|
if ($attachment = array_shift($attachments))
|
||||||
|
{
|
||||||
|
$item->image = $attachment->local_filename;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unset($item->image);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone the item to make a part.
|
||||||
|
$cloneitem = clone $item;
|
||||||
|
|
||||||
|
// Determine the best message type for this part.
|
||||||
|
if ($cloneitem->type !== 'SMS' && !$cloneitem->subject)
|
||||||
|
{
|
||||||
|
$cloneitem->type = $attachment ? 'MMS' : ($this->_getLengthInCharset($content_part, $spec['sms_max_length_in_charset']) > $spec['sms_max_length'] ? 'LMS' : 'SMS');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the cloned part to the result array.
|
||||||
|
$result[] = $cloneitem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the message parts.
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length of a string in another character set.
|
||||||
|
*
|
||||||
|
* @param string $str String to measure
|
||||||
|
* @param string $charset Character set to measure length
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected function _getLengthInCharset($str, $charset)
|
||||||
|
{
|
||||||
|
$str = @iconv('UTF-8', $charset . '//IGNORE', $str);
|
||||||
|
return strlen($str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split a string into several short chunks.
|
||||||
|
*
|
||||||
|
* @param string $str String to split
|
||||||
|
* @param int $max_length Maximum length of a chunk
|
||||||
|
* @param string $charset Character set to measure length
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function _splitString($str, $max_length, $charset)
|
||||||
|
{
|
||||||
|
$str = utf8_trim(utf8_normalize_spaces($str, true));
|
||||||
|
$chars = preg_split('//u', $str, -1, \PREG_SPLIT_NO_EMPTY);
|
||||||
|
$result = array();
|
||||||
|
$current_entry = '';
|
||||||
|
$current_length = 0;
|
||||||
|
|
||||||
|
foreach ($chars as $char)
|
||||||
|
{
|
||||||
|
$char_length = strlen(@iconv('UTF-8', $charset . '//IGNORE', $char));
|
||||||
|
if (($current_length + $char_length > $max_length) || ($current_length + $char_length > $max_length - 7 && ctype_space($char)))
|
||||||
|
{
|
||||||
|
$result[] = trim($current_entry);
|
||||||
|
$current_entry = $char;
|
||||||
|
$current_length = $char_length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$current_entry .= $char;
|
||||||
|
$current_length += $char_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($current_entry !== '')
|
||||||
|
{
|
||||||
|
$result[] = trim($current_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -714,6 +714,36 @@ class Storage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a directory only if it is empty.
|
||||||
|
*
|
||||||
|
* @param string $dirname
|
||||||
|
* @param bool $delete_empty_parents (optional)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function deleteEmptyDirectory($dirname, $delete_empty_parents = false)
|
||||||
|
{
|
||||||
|
$dirname = rtrim($dirname, '/\\');
|
||||||
|
if (!self::isDirectory($dirname) || !self::isEmptyDirectory($dirname))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = @rmdir($dirname);
|
||||||
|
if (!$result)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ($delete_empty_parents)
|
||||||
|
{
|
||||||
|
self::deleteEmptyDirectory(dirname($dirname), true);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current umask.
|
* Get the current umask.
|
||||||
*
|
*
|
||||||
|
|
@ -742,7 +772,7 @@ class Storage
|
||||||
/**
|
/**
|
||||||
* Determine the best umask for this installation of Rhymix.
|
* Determine the best umask for this installation of Rhymix.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function recommendUmask()
|
public static function recommendUmask()
|
||||||
{
|
{
|
||||||
|
|
@ -756,27 +786,7 @@ class Storage
|
||||||
$file_uid = fileowner(__FILE__);
|
$file_uid = fileowner(__FILE__);
|
||||||
|
|
||||||
// Get the UID of the current PHP process.
|
// Get the UID of the current PHP process.
|
||||||
if (function_exists('posix_geteuid'))
|
$php_uid = self::getServerUID();
|
||||||
{
|
|
||||||
$php_uid = posix_geteuid();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$testfile = \RX_BASEDIR . 'files/cache/uidcheck';
|
|
||||||
if (self::exists($testfile))
|
|
||||||
{
|
|
||||||
self::delete($testfile);
|
|
||||||
}
|
|
||||||
if (self::write($testfile, 'TEST'))
|
|
||||||
{
|
|
||||||
$php_uid = fileowner($testfile);
|
|
||||||
self::delete($testfile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$php_uid = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If both UIDs are the same, set the umask to 0022.
|
// If both UIDs are the same, set the umask to 0022.
|
||||||
if ($file_uid == $php_uid)
|
if ($file_uid == $php_uid)
|
||||||
|
|
@ -790,4 +800,36 @@ class Storage
|
||||||
return '0000';
|
return '0000';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the UID of the server process.
|
||||||
|
*
|
||||||
|
* @return int|false
|
||||||
|
*/
|
||||||
|
public static function getServerUID()
|
||||||
|
{
|
||||||
|
if (function_exists('posix_geteuid'))
|
||||||
|
{
|
||||||
|
return posix_geteuid();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$testfile = \RX_BASEDIR . 'files/cache/uidcheck_' . time();
|
||||||
|
if (self::exists($testfile))
|
||||||
|
{
|
||||||
|
self::delete($testfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::write($testfile, 'TEST'))
|
||||||
|
{
|
||||||
|
$uid = fileowner($testfile);
|
||||||
|
self::delete($testfile);
|
||||||
|
return $uid;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,35 @@ function array_last_key(array $array)
|
||||||
return key($array);
|
return key($array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape all keys and values in a multi-dimensional array.
|
||||||
|
*
|
||||||
|
* @param array $array The array to escape
|
||||||
|
* @param bool $double_escape Set this to false to skip symbols that are already escaped (default: true)
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function array_escape(array $array, $double_escape = true)
|
||||||
|
{
|
||||||
|
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
|
||||||
|
$result = array();
|
||||||
|
foreach ($array as $key => $value)
|
||||||
|
{
|
||||||
|
if (is_array($value))
|
||||||
|
{
|
||||||
|
$result[htmlspecialchars($key, $flags, 'UTF-8', $double_escape)] = array_escape($value, $double_escape, $flags);
|
||||||
|
}
|
||||||
|
elseif (is_object($value))
|
||||||
|
{
|
||||||
|
$result[htmlspecialchars($key, $flags, 'UTF-8', $double_escape)] = (object)array_escape(get_object_vars($value), $double_escape, $flags);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$result[htmlspecialchars($key, $flags, 'UTF-8', $double_escape)] = htmlspecialchars($value, $flags, 'UTF-8', $double_escape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flatten a multi-dimensional array into a one-dimensional array.
|
* Flatten a multi-dimensional array into a one-dimensional array.
|
||||||
* Based on util.php <https://github.com/brandonwamboldt/utilphp>
|
* Based on util.php <https://github.com/brandonwamboldt/utilphp>
|
||||||
|
|
@ -155,7 +184,7 @@ function clean_path($path)
|
||||||
*/
|
*/
|
||||||
function escape($str, $double_escape = true)
|
function escape($str, $double_escape = true)
|
||||||
{
|
{
|
||||||
$flags = defined('ENT_SUBSTITUTE') ? (ENT_QUOTES | ENT_SUBSTITUTE) : (ENT_QUOTES | ENT_IGNORE);
|
$flags = ENT_QUOTES | ENT_SUBSTITUTE;
|
||||||
return htmlspecialchars($str, $flags, 'UTF-8', $double_escape);
|
return htmlspecialchars($str, $flags, 'UTF-8', $double_escape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,8 +207,7 @@ function escape_css($str)
|
||||||
*/
|
*/
|
||||||
function escape_js($str)
|
function escape_js($str)
|
||||||
{
|
{
|
||||||
$flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT;
|
$flags = JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_UNESCAPED_UNICODE;
|
||||||
if (defined('JSON_UNESCAPED_UNICODE')) $flags = $flags | JSON_UNESCAPED_UNICODE;
|
|
||||||
$str = json_encode((string)$str, $flags);
|
$str = json_encode((string)$str, $flags);
|
||||||
return substr($str, 1, strlen($str) - 2);
|
return substr($str, 1, strlen($str) - 2);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -313,12 +313,27 @@ jQuery(function($) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief string prototype으로 trim 함수 추가
|
* @brief string prototype으로 escape 함수 추가
|
||||||
**/
|
**/
|
||||||
String.prototype.trim = function() {
|
String.prototype.escape = function(double_escape) {
|
||||||
return this.replace(/(^\s*)|(\s*$)/g, "");
|
var map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' };
|
||||||
|
var revmap = { '&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '"', "&#039;": ''' };
|
||||||
|
var result = String(this).replace(/[&<>"']/g, function(m) { return map[m]; });
|
||||||
|
if (double_escape === false) {
|
||||||
|
return result.replace(/&(amp|lt|gt|quot|#039);/g, function(m) { return revmap[m]; });
|
||||||
|
} else {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief string prototype으로 trim 함수 추가
|
||||||
|
**/
|
||||||
|
if (!String.prototype.trim) {
|
||||||
|
String.prototype.trim = function() {
|
||||||
|
return String(this).replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
|
||||||
|
};
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -511,17 +526,17 @@ function setFixedPopupSize() {
|
||||||
|
|
||||||
if(w < 800) w = 800 + offset.left*2;
|
if(w < 800) w = 800 + offset.left*2;
|
||||||
|
|
||||||
|
|
||||||
dw = $win.width();
|
dw = $win.width();
|
||||||
dh = $win.height();
|
dh = $win.height();
|
||||||
|
|
||||||
// Window 의 너비나 높이는 스크린의 너비나 높이보다 클 수 없다. 스크린의 너비나 높이와 내용의 너비나 높이를 비교해서 최소값을 이용한다.
|
// Window 의 너비나 높이는 스크린의 너비나 높이보다 클 수 없다. 스크린의 너비나 높이와 내용의 너비나 높이를 비교해서 최소값을 이용한다.
|
||||||
if(Math.min(w, window.screen.availWidth) != dw) window.resizeBy(Math.min(w, window.screen.availWidth) - dw, 0);
|
w = Math.min(w, window.screen.availWidth);
|
||||||
if(Math.min(h, window.screen.availHeight-100) != dh) window.resizeBy(0, Math.min(h, window.screen.availHeight-100) - dh);
|
h = Math.min(h, window.screen.availHeight - 100);
|
||||||
|
window.resizeBy(w - dw, h - dh);
|
||||||
|
|
||||||
$pc.width(Math.min(w, window.screen.availWidth)-offset.left*2).css({overflow:'',height:''});
|
$pc.width(w - offset.left*2).css({overflow:'',height:''});
|
||||||
if(Math.min(h, window.screen.availHeight-100) === window.screen.availHeight-100) {
|
if(h === window.screen.availHeight - 100) {
|
||||||
$pc.width(Math.min(w, window.screen.availWidth)-offset.left*2-scbw).css({overflow:'',height:''});
|
$pc.width(w - offset.left*2-scbw).css({overflow:'',height:''});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,24 +62,24 @@
|
||||||
|
|
||||||
var currentEnforce_ssl = window.enforce_ssl;
|
var currentEnforce_ssl = window.enforce_ssl;
|
||||||
if(location.protocol == 'https:') { window.enforce_ssl = true; }
|
if(location.protocol == 'https:') { window.enforce_ssl = true; }
|
||||||
|
|
||||||
|
var chunkStatus = true;
|
||||||
|
var defaultFormData = {
|
||||||
|
"editor_sequence": data.editorSequence,
|
||||||
|
"upload_target_srl" : data.uploadTargetSrl,
|
||||||
|
"mid" : window.current_mid,
|
||||||
|
"act": 'procFileUpload'
|
||||||
|
};
|
||||||
|
|
||||||
var settings = {
|
var settings = {
|
||||||
url: request_uri
|
url: request_uri,
|
||||||
.setQuery('module', 'file')
|
formData: defaultFormData,
|
||||||
.setQuery('act', 'procFileUpload')
|
|
||||||
.setQuery('mid', window.current_mid),
|
|
||||||
formData: {
|
|
||||||
"editor_sequence": data.editorSequence,
|
|
||||||
"upload_target_srl" : data.uploadTargetSrl,
|
|
||||||
"mid" : window.current_mid,
|
|
||||||
"act": 'procFileUpload'
|
|
||||||
},
|
|
||||||
dropZone: $container,
|
dropZone: $container,
|
||||||
add: function(e, d) {
|
add: function(e, d) {
|
||||||
var dfd = jQuery.Deferred();
|
var dfd = jQuery.Deferred();
|
||||||
|
|
||||||
$.each(d.files, function(index, file) {
|
$.each(d.files, function(index, file) {
|
||||||
if(data.settings.maxFileSize <= file.size) {
|
if(data.settings.maxFileSize > 0 && data.settings.maxFileSize < file.size) {
|
||||||
dfd.reject();
|
dfd.reject();
|
||||||
alert(window.xe.msg_exceeds_limit_size);
|
alert(window.xe.msg_exceeds_limit_size);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -91,25 +91,79 @@
|
||||||
d.submit();
|
d.submit();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
submit: function(e, data) {
|
||||||
|
data.formData = defaultFormData;
|
||||||
|
data.formData.nonce = "T" + new Date().getTime() + "." + Math.random();
|
||||||
|
chunkStatus = true;
|
||||||
|
},
|
||||||
|
chunksend: function(e, data) {
|
||||||
|
if (!chunkStatus) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chunkdone: function(e, res) {
|
||||||
|
if (res.result) {
|
||||||
|
if (res.result.error != 0) {
|
||||||
|
if (res.result.message) {
|
||||||
|
alert(res.result.message);
|
||||||
|
} else {
|
||||||
|
alert(window.xe.msg_file_upload_error + " (Type 1)");
|
||||||
|
}
|
||||||
|
return chunkStatus = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alert(window.xe.msg_file_upload_error + " (Type 2)");
|
||||||
|
return chunkStatus = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chunkfail: function(e, data) {
|
||||||
|
if (chunkStatus) {
|
||||||
|
alert(window.xe.msg_file_upload_error + " (Type 3)" + "<br>\n" + data.errorThrown + "<br>\n" + data.textStatus);
|
||||||
|
return chunkStatus = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
done: function(e, res) {
|
done: function(e, res) {
|
||||||
|
data.settings.progressbarGraph.width('100%');
|
||||||
|
data.settings.progressPercent.text('100%');
|
||||||
|
data.settings.progressbar.delay(1000).slideUp();
|
||||||
|
data.settings.progressStatus.delay(1000).slideUp();
|
||||||
var result = res.response().result;
|
var result = res.response().result;
|
||||||
var temp_code = '';
|
var temp_code = '';
|
||||||
|
if (!result) {
|
||||||
if(!result) return;
|
alert(window.xe.msg_file_upload_error + " (Type 4)");
|
||||||
|
return false;
|
||||||
if(!jQuery.isPlainObject(result)) result = jQuery.parseJSON(result);
|
}
|
||||||
|
if (!jQuery.isPlainObject(result)) {
|
||||||
if(!result) return;
|
result = jQuery.parseJSON(result);
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
alert(window.xe.msg_file_upload_error + " (Type 5)" + "<br>\n" + res.response().result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(result.error == 0) {
|
if(result.error == 0) {
|
||||||
if(/\.(jpe?g|png|gif)$/i.test(result.source_filename)) {
|
if(/\.(jpe?g|png|gif)$/i.test(result.source_filename)) {
|
||||||
temp_code += '<img src="' + result.download_url + '" alt="' + result.source_filename + '" editor_component="image_link" data-file-srl="' + result.file_srl + '" />';
|
temp_code += '<img src="' + result.download_url + '" alt="' + result.source_filename + '" editor_component="image_link" data-file-srl="' + result.file_srl + '" />';
|
||||||
temp_code += "\r\n<p><br></p>\r\n";
|
if (opt.autoinsertImage === 'paragraph') {
|
||||||
|
_getCkeInstance(settings.formData.editor_sequence).insertHtml("<p>" + temp_code + "</p>\n", "unfiltered_html");
|
||||||
|
} else if (opt.autoinsertImage === 'inline') {
|
||||||
|
_getCkeInstance(settings.formData.editor_sequence).insertHtml(temp_code, "unfiltered_html");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else if (result.message) {
|
||||||
_getCkeInstance(settings.formData.editor_sequence).insertHtml(temp_code, "unfiltered_html");
|
|
||||||
} else {
|
|
||||||
alert(result.message);
|
alert(result.message);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
alert(window.xe.msg_file_upload_error + " (Type 6)" + "<br>\n" + res.response().result);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: function(e, data) {
|
||||||
|
data.settings.progressbar.delay(1000).slideUp();
|
||||||
|
data.settings.progressStatus.delay(1000).slideUp();
|
||||||
|
if (chunkStatus) {
|
||||||
|
alert(window.xe.msg_file_upload_error + " (Type 7)" + "<br>\n" + data.errorThrown + "<br>\n" + data.textStatus);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
stop: function() {
|
stop: function() {
|
||||||
|
|
@ -121,14 +175,9 @@
|
||||||
data.settings.progressbar.show();
|
data.settings.progressbar.show();
|
||||||
},
|
},
|
||||||
progressall: function (e, d) {
|
progressall: function (e, d) {
|
||||||
var progress = parseInt(d.loaded / d.total * 100, 10);
|
var progress = Math.round(d.loaded / d.total * 999) / 10;
|
||||||
data.settings.progressbarGraph.width(progress+'%');
|
data.settings.progressbarGraph.width(progress+'%');
|
||||||
data.settings.progressPercent.text(progress+'%');
|
data.settings.progressPercent.text(progress+'%');
|
||||||
|
|
||||||
if(progress >= 100) {
|
|
||||||
data.settings.progressbar.delay(3000).slideUp();
|
|
||||||
data.settings.progressStatus.delay(3000).slideUp();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.enforce_ssl = currentEnforce_ssl;
|
window.enforce_ssl = currentEnforce_ssl;
|
||||||
|
|
@ -277,13 +326,13 @@
|
||||||
file_srls.push(file_srl);
|
file_srls.push(file_srl);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_srls = file_srls.join(',');
|
exec_json('file.procFileDelete', {'file_srls': file_srls.join(','), 'editor_sequence': data.editorSequence}, function() {
|
||||||
|
|
||||||
exec_json('file.procFileDelete', {'file_srls': file_srls, 'editor_sequence': data.editorSequence}, function() {
|
|
||||||
file_srls = file_srls.split(',');
|
|
||||||
$.each(file_srls, function(idx, srl){
|
$.each(file_srls, function(idx, srl){
|
||||||
data.settings.fileList.find('ul').find('li[data-file-srl=' + srl + ']').remove();
|
data.settings.fileList.find('ul').find('li[data-file-srl=' + srl + ']').remove();
|
||||||
});
|
});
|
||||||
|
var ckeditor = _getCkeInstance(data.editorSequence);
|
||||||
|
var regexp = new RegExp('<(img) [^>]*data-file-srl="(' + file_srls.join('|') + ')"[^>]*>', 'g');
|
||||||
|
ckeditor.setData(ckeditor.getData().replace(regexp, ''));
|
||||||
self.loadFilelist($container);
|
self.loadFilelist($container);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -296,6 +345,7 @@
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.mid = window.current_mid;
|
obj.mid = window.current_mid;
|
||||||
obj.editor_sequence = data.editorSequence;
|
obj.editor_sequence = data.editorSequence;
|
||||||
|
obj.allow_chunks = 'Y';
|
||||||
|
|
||||||
$.exec_json('file.getFileList', obj, function(res){
|
$.exec_json('file.getFileList', obj, function(res){
|
||||||
data.uploadTargetSrl = res.upload_target_srl;
|
data.uploadTargetSrl = res.upload_target_srl;
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
main.js
|
|
||||||
1
common/js/plugins/jquery.fileupload/js/main.min.js
vendored
Normal file
1
common/js/plugins/jquery.fileupload/js/main.min.js
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
This file is not used in Rhymix.
|
||||||
|
|
@ -168,7 +168,7 @@
|
||||||
// Convert params to object and fill in the module and act.
|
// Convert params to object and fill in the module and act.
|
||||||
params = params ? ($.isArray(params) ? arr2obj(params) : params) : {};
|
params = params ? ($.isArray(params) ? arr2obj(params) : params) : {};
|
||||||
action = action.split(".");
|
action = action.split(".");
|
||||||
if (action.length != 2) return;
|
//if (action.length != 2) return;
|
||||||
params.module = action[0];
|
params.module = action[0];
|
||||||
params.act = action[1];
|
params.act = action[1];
|
||||||
params._rx_ajax_compat = 'JSON';
|
params._rx_ajax_compat = 'JSON';
|
||||||
|
|
@ -275,7 +275,7 @@
|
||||||
// Convert params to object and fill in the module and act.
|
// Convert params to object and fill in the module and act.
|
||||||
params = params ? ($.isArray(params) ? arr2obj(params) : params) : {};
|
params = params ? ($.isArray(params) ? arr2obj(params) : params) : {};
|
||||||
action = action.split(".");
|
action = action.split(".");
|
||||||
if (action.length != 2) return;
|
//if (action.length != 2) return;
|
||||||
params.module = action[0];
|
params.module = action[0];
|
||||||
params.act = action[1];
|
params.act = action[1];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ $lang->comment = 'Comment';
|
||||||
$lang->description = 'Description';
|
$lang->description = 'Description';
|
||||||
$lang->trackback = 'Trackback';
|
$lang->trackback = 'Trackback';
|
||||||
$lang->tag = 'Tag';
|
$lang->tag = 'Tag';
|
||||||
|
$lang->mail = 'Mail';
|
||||||
|
$lang->email = 'E-mail';
|
||||||
|
$lang->sms = 'SMS';
|
||||||
$lang->allow_comment = 'Allow Comments';
|
$lang->allow_comment = 'Allow Comments';
|
||||||
$lang->lock_comment = 'Block Comments';
|
$lang->lock_comment = 'Block Comments';
|
||||||
$lang->allow_trackback = 'Allow Trackbacks';
|
$lang->allow_trackback = 'Allow Trackbacks';
|
||||||
|
|
|
||||||
|
|
@ -110,6 +110,9 @@ $lang->comment = '댓글';
|
||||||
$lang->description = '설명';
|
$lang->description = '설명';
|
||||||
$lang->trackback = '엮인글';
|
$lang->trackback = '엮인글';
|
||||||
$lang->tag = '태그';
|
$lang->tag = '태그';
|
||||||
|
$lang->mail = '메일';
|
||||||
|
$lang->email = '이메일';
|
||||||
|
$lang->sms = 'SMS';
|
||||||
$lang->allow_comment = '댓글 허용';
|
$lang->allow_comment = '댓글 허용';
|
||||||
$lang->lock_comment = '댓글 잠금';
|
$lang->lock_comment = '댓글 잠금';
|
||||||
$lang->allow_trackback = '엮인글 허용';
|
$lang->allow_trackback = '엮인글 허용';
|
||||||
|
|
|
||||||
58
common/scripts/clean_empty_dirs.php
Normal file
58
common/scripts/clean_empty_dirs.php
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script deletes empty directories under the 'files' directory.
|
||||||
|
*
|
||||||
|
* It may be useful when your web host imposes a hard limit on the number of
|
||||||
|
* inodes, or when your backups take too long due to the large number of
|
||||||
|
* unused directories.
|
||||||
|
*
|
||||||
|
* This script only works on Unix-like operating systems where the 'find'
|
||||||
|
* command is available.
|
||||||
|
*/
|
||||||
|
require_once __DIR__ . '/common.php';
|
||||||
|
|
||||||
|
// Initialize the exit status.
|
||||||
|
$exit_status = 0;
|
||||||
|
|
||||||
|
// Delete empty directories in the attachment directory.
|
||||||
|
passthru(sprintf('find %s -type d -empty -delete', escapeshellarg(RX_BASEDIR . 'files/attach')), $result);
|
||||||
|
if ($result == 0)
|
||||||
|
{
|
||||||
|
echo "Successfully deleted all empty directories under files/attach.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting empty directories under files/attach.\n";
|
||||||
|
$exit_status = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete empty directories in the member extra info directory.
|
||||||
|
passthru(sprintf('find %s -type d -empty -delete', escapeshellarg(RX_BASEDIR . 'files/member_extra_info')), $result);
|
||||||
|
if ($result == 0)
|
||||||
|
{
|
||||||
|
echo "Successfully deleted all empty directories under files/member_extra_info.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting empty directories under files/member_extra_info.\n";
|
||||||
|
$exit_status = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete empty directories in the thumbnails directory.
|
||||||
|
passthru(sprintf('find %s -type d -empty -delete', escapeshellarg(RX_BASEDIR . 'files/thumbnails')), $result);
|
||||||
|
if ($result == 0)
|
||||||
|
{
|
||||||
|
echo "Successfully deleted all empty directories under files/thumbnails.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting empty directories under files/thumbnails.\n";
|
||||||
|
$exit_status = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the exit status if there were any errors.
|
||||||
|
if ($exit_status != 0)
|
||||||
|
{
|
||||||
|
exit($exit_status);
|
||||||
|
}
|
||||||
98
common/scripts/clean_garbage_files.php
Normal file
98
common/scripts/clean_garbage_files.php
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script deletes files that were not properly uploaded.
|
||||||
|
*
|
||||||
|
* Files can remain in an invalid status for two reasons: 1) a user abandons
|
||||||
|
* a document or comment after uploading files; or 2) a chunked upload is
|
||||||
|
* aborted without the server having any opportunity to clean it up.
|
||||||
|
* These files can obviously take up a lot of disk space. In order to prevent
|
||||||
|
* them from accumulating too much, you should run this script at least once
|
||||||
|
* every few days.
|
||||||
|
*/
|
||||||
|
require_once __DIR__ . '/common.php';
|
||||||
|
|
||||||
|
// Delete garbage files older than this number of days.
|
||||||
|
$days = 10;
|
||||||
|
|
||||||
|
// Initialize the exit status.
|
||||||
|
$exit_status = 0;
|
||||||
|
|
||||||
|
// Initialize objects.
|
||||||
|
$oDB = DB::getInstance();
|
||||||
|
$oFileController = getController('file');
|
||||||
|
|
||||||
|
// Find and delete files where isvalid = N.
|
||||||
|
$args = new stdClass;
|
||||||
|
$args->isvalid = 'N';
|
||||||
|
$args->list_count = 50;
|
||||||
|
$args->regdate_before = date('YmdHis', time() - ($days * 86400));
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
$output = executeQueryArray('file.getFileList', $args);
|
||||||
|
if ($output->toBool())
|
||||||
|
{
|
||||||
|
if ($output->data)
|
||||||
|
{
|
||||||
|
$oDB->begin();
|
||||||
|
foreach ($output->data as $file_info)
|
||||||
|
{
|
||||||
|
$oFileController->deleteFile($file_info->file_srl);
|
||||||
|
}
|
||||||
|
$oDB->commit();
|
||||||
|
|
||||||
|
if ($output->page_navigation && $output->page_navigation->total_count == count($output->data))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting garbage files older than $days days.\n";
|
||||||
|
echo $output->getMessage() . "\n";
|
||||||
|
$exit_status = 11;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($exit_status == 0)
|
||||||
|
{
|
||||||
|
echo "Successfully deleted all garbage files older than $days days.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and delete temporary chunks.
|
||||||
|
$dirname = RX_BASEDIR . 'files/attach/chunks';
|
||||||
|
$threshold = time() - ($days * 86400);
|
||||||
|
$chunks = Rhymix\Framework\Storage::readDirectory($dirname);
|
||||||
|
if ($chunks)
|
||||||
|
{
|
||||||
|
foreach ($chunks as $chunk)
|
||||||
|
{
|
||||||
|
if (@filemtime($chunk) < $threshold)
|
||||||
|
{
|
||||||
|
$result = Rhymix\Framework\Storage::delete($chunk);
|
||||||
|
if (!$result)
|
||||||
|
{
|
||||||
|
$exit_status = 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($exit_status == 0)
|
||||||
|
{
|
||||||
|
echo "Successfully deleted aborted file chunks older than $days days.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting aborted file chunks older than $days days.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the exit status if there were any errors.
|
||||||
|
if ($exit_status != 0)
|
||||||
|
{
|
||||||
|
exit($exit_status);
|
||||||
|
}
|
||||||
37
common/scripts/clean_old_notifications.php
Normal file
37
common/scripts/clean_old_notifications.php
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script deletes old notifications.
|
||||||
|
*
|
||||||
|
* Notifications must be dismissed as quickly as possible in order to prevent
|
||||||
|
* the ncenterlite_notify table from becoming too large. For best performance,
|
||||||
|
* you should run this script at least once every few days.
|
||||||
|
*/
|
||||||
|
require_once __DIR__ . '/common.php';
|
||||||
|
|
||||||
|
// Delete notifications older than this number of days.
|
||||||
|
$days = 30;
|
||||||
|
|
||||||
|
// Initialize the exit status.
|
||||||
|
$exit_status = 0;
|
||||||
|
|
||||||
|
// Execute the query.
|
||||||
|
$args = new stdClass;
|
||||||
|
$args->old_date = date('YmdHis', time() - ($days * 86400));
|
||||||
|
$output = executeQuery('ncenterlite.deleteNotifyAll', $args);
|
||||||
|
if ($output->toBool())
|
||||||
|
{
|
||||||
|
echo "Successfully deleted all notifications older than $days days.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting notifications older than $days days.\n";
|
||||||
|
echo $output->getMessage() . "\n";
|
||||||
|
$exit_status = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the exit status if there were any errors.
|
||||||
|
if ($exit_status != 0)
|
||||||
|
{
|
||||||
|
exit($exit_status);
|
||||||
|
}
|
||||||
41
common/scripts/clean_old_thumbnails.php
Normal file
41
common/scripts/clean_old_thumbnails.php
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This script deletes old thumbnails.
|
||||||
|
*
|
||||||
|
* Thumbnails can take up a large amount of disk space and inodes if they are
|
||||||
|
* allowed to accumulate. Since most websites only need thumbnails for recent
|
||||||
|
* posts, it is okay to delete old thumbnails.
|
||||||
|
*
|
||||||
|
* Do not run this script if you have a gallery-style module where visitors
|
||||||
|
* regularly view old posts. This will force thumbnails to be regenerated,
|
||||||
|
* increasing the server load and making your pages load slower.
|
||||||
|
*
|
||||||
|
* This script only works on Unix-like operating systems where the 'find'
|
||||||
|
* command is available.
|
||||||
|
*/
|
||||||
|
require_once __DIR__ . '/common.php';
|
||||||
|
|
||||||
|
// Delete thumbnails older than this number of days.
|
||||||
|
$days = 90;
|
||||||
|
|
||||||
|
// Initialize the exit status.
|
||||||
|
$exit_status = 0;
|
||||||
|
|
||||||
|
// Delete old thumbnails.
|
||||||
|
passthru(sprintf('find %s -type f -mtime +%d -delete', escapeshellarg(RX_BASEDIR . 'files/thumbnails'), abs($days)), $result);
|
||||||
|
if ($result == 0)
|
||||||
|
{
|
||||||
|
echo "Successfully deleted all thumbnails older than $days days.\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo "Error while deleting thumbnails older than $days days.\n";
|
||||||
|
$exit_status = $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the exit status if there were any errors.
|
||||||
|
if ($exit_status != 0)
|
||||||
|
{
|
||||||
|
exit($exit_status);
|
||||||
|
}
|
||||||
42
common/scripts/common.php
Normal file
42
common/scripts/common.php
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file must be included at the top of all shell scripts (cron jobs).
|
||||||
|
*
|
||||||
|
* HERE BE DRAGONS.
|
||||||
|
*
|
||||||
|
* Failure to perform the checks listed in this file at the top of a cron job,
|
||||||
|
* or any attempt to work around the limitations deliberately placed in this
|
||||||
|
* file, may result in errors or degradation of service.
|
||||||
|
*
|
||||||
|
* Please be warned that errors may not show up immediately, especially if you
|
||||||
|
* screw up the permissions inside deeply nested directory trees. You may find
|
||||||
|
* it difficult and/or costly to undo the damages when errors begin to show up
|
||||||
|
* several months later.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Abort if not CLI.
|
||||||
|
if (PHP_SAPI !== 'cli')
|
||||||
|
{
|
||||||
|
echo "This script must be executed on the command line interface.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Rhymix.
|
||||||
|
chdir(dirname(dirname(__DIR__)));
|
||||||
|
require_once dirname(__DIR__) . '/autoload.php';
|
||||||
|
|
||||||
|
// Abort if the UID does not match.
|
||||||
|
$uid = Rhymix\Framework\Storage::getServerUID();
|
||||||
|
if ($uid === 0)
|
||||||
|
{
|
||||||
|
echo "This script must not be executed by the root user.\n";
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
$web_server_uid = fileowner(RX_BASEDIR . 'files/config/config.php');
|
||||||
|
if ($uid !== $web_server_uid)
|
||||||
|
{
|
||||||
|
$web_server_uid = posix_getpwuid($web_server_uid);
|
||||||
|
echo "This script must be executed by the same user as the usual web server process ({$web_server_uid['name']}).\n";
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
{$content}
|
{$content}
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
jQuery(window).load(setFixedPopupSize);
|
jQuery(function() {
|
||||||
|
setTimeout(setFixedPopupSize, 500);
|
||||||
|
});
|
||||||
var _isPoped = true;
|
var _isPoped = true;
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
"ext-openssl": "*",
|
"ext-openssl": "*",
|
||||||
"ext-pcre": "*",
|
"ext-pcre": "*",
|
||||||
"ext-xml": "*",
|
"ext-xml": "*",
|
||||||
|
"coolsms/php-sdk": "2.0.*",
|
||||||
"defuse/php-encryption": "1.2.1",
|
"defuse/php-encryption": "1.2.1",
|
||||||
"ezyang/htmlpurifier": "4.7.*",
|
"ezyang/htmlpurifier": "4.7.*",
|
||||||
"hautelook/phpass": "0.3.*",
|
"hautelook/phpass": "0.3.*",
|
||||||
|
|
|
||||||
126
composer.lock
generated
126
composer.lock
generated
|
|
@ -4,9 +4,63 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"hash": "64d8278cd705dec01a94208e378716f8",
|
"hash": "66af49066c9b92d6708080f3d32860f4",
|
||||||
"content-hash": "fa544ace96d8d80c11db9dafb2c49753",
|
"content-hash": "51acda30c4d45b4c956743d4bd1ac16e",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "coolsms/php-sdk",
|
||||||
|
"version": "v2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/coolsms/php-sdk.git",
|
||||||
|
"reference": "ce00fea155169dcf2a3759abd41ad20ff80ca0b1"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/coolsms/php-sdk/zipball/ce00fea155169dcf2a3759abd41ad20ff80ca0b1",
|
||||||
|
"reference": "ce00fea155169dcf2a3759abd41ad20ff80ca0b1",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.5.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Nurigo\\": "app/Nurigo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "nurigo",
|
||||||
|
"email": "contact@nurigo.net",
|
||||||
|
"homepage": "http://coolsms.co.kr",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Send message using PHP and RestAPI[TEST]",
|
||||||
|
"homepage": "http://coolsms.co.kr",
|
||||||
|
"keywords": [
|
||||||
|
"TextMessage",
|
||||||
|
"cellphone",
|
||||||
|
"cool",
|
||||||
|
"coolsms",
|
||||||
|
"global",
|
||||||
|
"lms",
|
||||||
|
"message",
|
||||||
|
"messages",
|
||||||
|
"mms",
|
||||||
|
"mobile",
|
||||||
|
"nurigo",
|
||||||
|
"phone",
|
||||||
|
"sms"
|
||||||
|
],
|
||||||
|
"time": "2016-09-02 03:28:39"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "defuse/php-encryption",
|
"name": "defuse/php-encryption",
|
||||||
"version": "v1.2.1",
|
"version": "v1.2.1",
|
||||||
|
|
@ -272,16 +326,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "leafo/scssphp",
|
"name": "leafo/scssphp",
|
||||||
"version": "v0.6.3",
|
"version": "v0.6.6",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/leafo/scssphp.git",
|
"url": "https://github.com/leafo/scssphp.git",
|
||||||
"reference": "a27edad3d16635a222d7204706572e24c338aa17"
|
"reference": "6fdfe19d2b13a3f12ba0792227f0718809ce4e4d"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/leafo/scssphp/zipball/a27edad3d16635a222d7204706572e24c338aa17",
|
"url": "https://api.github.com/repos/leafo/scssphp/zipball/6fdfe19d2b13a3f12ba0792227f0718809ce4e4d",
|
||||||
"reference": "a27edad3d16635a222d7204706572e24c338aa17",
|
"reference": "6fdfe19d2b13a3f12ba0792227f0718809ce4e4d",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -321,20 +375,20 @@
|
||||||
"scss",
|
"scss",
|
||||||
"stylesheet"
|
"stylesheet"
|
||||||
],
|
],
|
||||||
"time": "2016-01-15 02:50:06"
|
"time": "2016-09-11 01:34:11"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "league/html-to-markdown",
|
"name": "league/html-to-markdown",
|
||||||
"version": "4.2.0",
|
"version": "4.2.2",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/thephpleague/html-to-markdown.git",
|
"url": "https://github.com/thephpleague/html-to-markdown.git",
|
||||||
"reference": "9a5becc8c6b520920fb846afefcfd7faf4c31712"
|
"reference": "8dfe3b1e6d459b320bec1a4b5499cd9d62796ac0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/9a5becc8c6b520920fb846afefcfd7faf4c31712",
|
"url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/8dfe3b1e6d459b320bec1a4b5499cd9d62796ac0",
|
||||||
"reference": "9a5becc8c6b520920fb846afefcfd7faf4c31712",
|
"reference": "8dfe3b1e6d459b320bec1a4b5499cd9d62796ac0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -385,20 +439,20 @@
|
||||||
"html",
|
"html",
|
||||||
"markdown"
|
"markdown"
|
||||||
],
|
],
|
||||||
"time": "2016-02-01 16:49:02"
|
"time": "2016-09-27 12:38:24"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "matthiasmullie/minify",
|
"name": "matthiasmullie/minify",
|
||||||
"version": "1.3.34",
|
"version": "1.3.39",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/matthiasmullie/minify.git",
|
"url": "https://github.com/matthiasmullie/minify.git",
|
||||||
"reference": "272e46113404f66ced256659552a0cc074a7810f"
|
"reference": "1a6cb6b457690034bde461593edb510949bdd6e7"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/272e46113404f66ced256659552a0cc074a7810f",
|
"url": "https://api.github.com/repos/matthiasmullie/minify/zipball/1a6cb6b457690034bde461593edb510949bdd6e7",
|
||||||
"reference": "272e46113404f66ced256659552a0cc074a7810f",
|
"reference": "1a6cb6b457690034bde461593edb510949bdd6e7",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -441,7 +495,7 @@
|
||||||
"minifier",
|
"minifier",
|
||||||
"minify"
|
"minify"
|
||||||
],
|
],
|
||||||
"time": "2016-03-01 08:00:27"
|
"time": "2016-10-27 22:32:49"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "matthiasmullie/path-converter",
|
"name": "matthiasmullie/path-converter",
|
||||||
|
|
@ -553,7 +607,7 @@
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/michelf/php-smartypants/zipball/c0465c6d4c5ab853c2fa45df6c10bce7e35cc137",
|
"url": "https://api.github.com/repos/michelf/php-smartypants/zipball/171a3a2552f33340bf3636bdb4b05eb4e406fbda",
|
||||||
"reference": "c0465c6d4c5ab853c2fa45df6c10bce7e35cc137",
|
"reference": "c0465c6d4c5ab853c2fa45df6c10bce7e35cc137",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
|
|
@ -649,16 +703,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "sunra/php-simple-html-dom-parser",
|
"name": "sunra/php-simple-html-dom-parser",
|
||||||
"version": "v1.5.0",
|
"version": "v1.5.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/sunra/php-simple-html-dom-parser.git",
|
"url": "https://github.com/sunra/php-simple-html-dom-parser.git",
|
||||||
"reference": "a0b80ace086c7e09085669205e1b3c2c9c7a453c"
|
"reference": "f910346ce47513a49ed5b8de197cde26c3f0b193"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/sunra/php-simple-html-dom-parser/zipball/a0b80ace086c7e09085669205e1b3c2c9c7a453c",
|
"url": "https://api.github.com/repos/sunra/php-simple-html-dom-parser/zipball/f910346ce47513a49ed5b8de197cde26c3f0b193",
|
||||||
"reference": "a0b80ace086c7e09085669205e1b3c2c9c7a453c",
|
"reference": "f910346ce47513a49ed5b8de197cde26c3f0b193",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -676,9 +730,9 @@
|
||||||
],
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "sunra",
|
"name": "Sunra",
|
||||||
"email": "sunra@yandex.ru",
|
"email": "sunra@yandex.ru",
|
||||||
"homepage": "http://github.com/sunra"
|
"homepage": "https://github.com/sunra"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Composer adaptation of: A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way! Require PHP 5+. Supports invalid HTML. Find tags on an HTML page with selectors just like jQuery. Extract contents from HTML in a single line.",
|
"description": "Composer adaptation of: A HTML DOM parser written in PHP5+ let you manipulate HTML in a very easy way! Require PHP 5+. Supports invalid HTML. Find tags on an HTML page with selectors just like jQuery. Extract contents from HTML in a single line.",
|
||||||
|
|
@ -688,27 +742,27 @@
|
||||||
"html",
|
"html",
|
||||||
"parser"
|
"parser"
|
||||||
],
|
],
|
||||||
"time": "2013-05-04 14:32:03"
|
"time": "2016-05-20 11:21:15"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "swiftmailer/swiftmailer",
|
"name": "swiftmailer/swiftmailer",
|
||||||
"version": "v5.4.2",
|
"version": "v5.4.3",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||||
"reference": "d8db871a54619458a805229a057ea2af33c753e8"
|
"reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/d8db871a54619458a805229a057ea2af33c753e8",
|
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
|
||||||
"reference": "d8db871a54619458a805229a057ea2af33c753e8",
|
"reference": "4cc92842069c2bbc1f28daaaf1d2576ec4dfe153",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.3.3"
|
"php": ">=5.3.3"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"mockery/mockery": "~0.9.1,<0.9.4"
|
"mockery/mockery": "~0.9.1"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
|
|
@ -741,20 +795,20 @@
|
||||||
"mail",
|
"mail",
|
||||||
"mailer"
|
"mailer"
|
||||||
],
|
],
|
||||||
"time": "2016-05-01 08:45:47"
|
"time": "2016-07-08 11:51:25"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "true/punycode",
|
"name": "true/punycode",
|
||||||
"version": "v2.0.2",
|
"version": "v2.1.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/true/php-punycode.git",
|
"url": "https://github.com/true/php-punycode.git",
|
||||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c"
|
"reference": "74033cbe9fdd3eba597f8af501947a125b3b8087"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/true/php-punycode/zipball/74fa01d4de396c40e239794123b3874cb594a30c",
|
"url": "https://api.github.com/repos/true/php-punycode/zipball/74033cbe9fdd3eba597f8af501947a125b3b8087",
|
||||||
"reference": "74fa01d4de396c40e239794123b3874cb594a30c",
|
"reference": "74033cbe9fdd3eba597f8af501947a125b3b8087",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
|
@ -787,7 +841,7 @@
|
||||||
"idna",
|
"idna",
|
||||||
"punycode"
|
"punycode"
|
||||||
],
|
],
|
||||||
"time": "2016-01-07 17:12:58"
|
"time": "2016-08-09 14:50:44"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": null,
|
"packages-dev": null,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
$material_colors = array(
|
$material_colors = array(
|
||||||
'red' => '#f44336',
|
'red' => '#f44336',
|
||||||
'crimson' => '#66001f',
|
'crimson' => '#aa0000',
|
||||||
'pink' => '#e91e63',
|
'pink' => '#e91e63',
|
||||||
'purple' => '#9c27b0',
|
'purple' => '#9c27b0',
|
||||||
'deep-purple' => '#673ab7',
|
'deep-purple' => '#673ab7',
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
<load target="layout.scss" vars="$layout_scss_value" />
|
<load target="layout.scss" vars="$layout_scss_value" />
|
||||||
<load target="layout.js" />
|
<load target="layout.js" />
|
||||||
|
|
||||||
<div class="skip"><a href="#content">{$lang->skip_to_content}</a></div>
|
<div class="skip"><a href="#content">{lang('skip_to_content')}</a></div>
|
||||||
<header class="layout_frame">
|
<header class="layout_frame">
|
||||||
<div class="layout_header layout_canvas">
|
<div class="layout_header layout_canvas">
|
||||||
<h1>
|
<h1>
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
</h1>
|
</h1>
|
||||||
<div id="layout_menu_toggle">
|
<div id="layout_menu_toggle">
|
||||||
<button class="layout_mobile_menu layout_mobile_menu--htx" data-target="layout_gnb">
|
<button class="layout_mobile_menu layout_mobile_menu--htx" data-target="layout_gnb">
|
||||||
<span>{$lang->menu}</span>
|
<span>{lang('common.menu')}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="hside layout_pc">
|
<div class="hside layout_pc">
|
||||||
|
|
@ -75,8 +75,8 @@
|
||||||
<input type="hidden" name="vid" value="{$vid}" />
|
<input type="hidden" name="vid" value="{$vid}" />
|
||||||
<input type="hidden" name="mid" value="{$mid}" />
|
<input type="hidden" name="mid" value="{$mid}" />
|
||||||
<input type="hidden" name="act" value="IS" />
|
<input type="hidden" name="act" value="IS" />
|
||||||
<input type="text" name="is_keyword" value="{$is_keyword}" required placeholder="{$lang->cmd_search}" title="{$lang->cmd_search}" />
|
<input type="text" name="is_keyword" value="{$is_keyword}" required placeholder="{lang('common.cmd_search')}" title="{lang('common.cmd_search')}" />
|
||||||
<input type="submit" value="{$lang->cmd_search}" />
|
<input type="submit" value="{lang('common.cmd_search')}" />
|
||||||
</form>
|
</form>
|
||||||
<!--// Search -->
|
<!--// Search -->
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -86,18 +86,18 @@
|
||||||
<nav class="layout_frame layout_menu" id="layout_gnb">
|
<nav class="layout_frame layout_menu" id="layout_gnb">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="layout_dropdown">
|
<li class="layout_dropdown">
|
||||||
<a href="{getUrl('act', 'dispMemberLoginForm')}" cond="!$is_logged">{sprintf($lang->simple_hello, $lang->simple_guest)}</a>
|
<a href="{getUrl('act', 'dispMemberLoginForm')}" cond="!$is_logged">{sprintf(lang('simple_hello'), lang('simple_guest'))}</a>
|
||||||
<ul class="layout_dropdown-content" cond="!$is_logged">
|
<ul class="layout_dropdown-content" cond="!$is_logged">
|
||||||
<li><a href="{getUrl('act', 'dispMemberLoginForm')}">{$lang->cmd_login}...</a></li>
|
<li><a href="{getUrl('act', 'dispMemberLoginForm')}">{lang('member.cmd_login')}...</a></li>
|
||||||
<li><a href="{getUrl('act', 'dispMemberSignUpForm')}" cond="$member_config->enable_join === 'Y'">{$lang->cmd_signup}...</a></li>
|
<li><a href="{getUrl('act', 'dispMemberSignUpForm')}" cond="$member_config->enable_join === 'Y'">{lang('member.cmd_signup')}...</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<a href="{getUrl('act', 'dispMemberInfo')}" cond="$is_logged">{sprintf($lang->simple_hello, $logged_info->nick_name)}</a>
|
<a href="{getUrl('act', 'dispMemberInfo')}" cond="$is_logged">{sprintf(lang('simple_hello'), $logged_info->nick_name)}</a>
|
||||||
<ul class="layout_dropdown-content" cond="$is_logged">
|
<ul class="layout_dropdown-content" cond="$is_logged">
|
||||||
<li><a href="{getUrl('act', 'dispMemberInfo')}">{$lang->cmd_view_member_info}</a></li>
|
<li><a href="{getUrl('act', 'dispMemberInfo')}">{lang('member.cmd_view_member_info')}</a></li>
|
||||||
<li cond="$logged_info->is_admin == 'Y'">
|
<li cond="$logged_info->is_admin == 'Y'">
|
||||||
<a href="{getUrl('', 'module','admin')}">{$lang->cmd_management}</a>
|
<a href="{getUrl('', 'module','admin')}">{lang('common.cmd_management')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a href="{getUrl('act', 'dispMemberLogout')}">{$lang->cmd_logout}</a></li>
|
<li><a href="{getUrl('act', 'dispMemberLogout')}">{lang('member.cmd_logout')}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li loop="$GNB->list=>$key1,$val1" class="<!--@if($val1['selected'])-->active <!--@endif--><!--@if($val1['list'])-->layout_dropdown<!--@endif-->">
|
<li loop="$GNB->list=>$key1,$val1" class="<!--@if($val1['selected'])-->active <!--@endif--><!--@if($val1['list'])-->layout_dropdown<!--@endif-->">
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li id="layout_search_link">
|
<li id="layout_search_link">
|
||||||
<a href="{getUrl('vid', $vid, 'mid', $mid, 'act', 'IS')}"><span>{$lang->cmd_search}</span></a>
|
<a href="{getUrl('vid', $vid, 'mid', $mid, 'act', 'IS')}"><span>{lang('common.cmd_search')}</span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,20 @@
|
||||||
$(function() {
|
$(function()
|
||||||
|
{
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
/* adjust the width of the right member menu */
|
/* adjust the width of the right member menu */
|
||||||
var menu_width = function() {
|
var menu_width = function()
|
||||||
if($('#layout_gnb>ul>li:first-child').width() > 50) {
|
{
|
||||||
|
if($('#layout_gnb>ul>li:first-child').width() > 50)
|
||||||
|
{
|
||||||
$('#layout_gnb>ul>li:first-child .layout_dropdown-content, #layout_gnb>ul>li:first-child .layout_dropdown-content a').css('width', $('#layout_gnb>ul>li:first-child').width()).css('min-width', $('#layout_gnb>ul>li:first-child').width());
|
$('#layout_gnb>ul>li:first-child .layout_dropdown-content, #layout_gnb>ul>li:first-child .layout_dropdown-content a').css('width', $('#layout_gnb>ul>li:first-child').width()).css('min-width', $('#layout_gnb>ul>li:first-child').width());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$( window ).resize(function() {
|
$( window ).resize(function()
|
||||||
if($('#layout_gnb>ul>li:first-child').width() > 50) {
|
{
|
||||||
|
if($('#layout_gnb>ul>li:first-child').width() > 50)
|
||||||
|
{
|
||||||
menu_width();
|
menu_width();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -17,32 +22,65 @@ $(function() {
|
||||||
menu_width();
|
menu_width();
|
||||||
|
|
||||||
/* mobile hamburger menu toggle */
|
/* mobile hamburger menu toggle */
|
||||||
$(".layout_mobile_menu").each(function() {
|
$(".layout_mobile_menu").each(function()
|
||||||
$( this ).click(function( event ) {
|
{
|
||||||
|
$( this ).click(function( event )
|
||||||
|
{
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
layout_toggleMenuOpener( $( this ).get(0) );
|
layout_toggleMenuOpener( $( this ).get(0) );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* detect scrolling up or down to hide or show hamburger menu */
|
||||||
|
var previousScroll = 0;
|
||||||
|
$( window ).scroll(function()
|
||||||
|
{
|
||||||
|
var currentScroll = $(this).scrollTop();
|
||||||
|
if (currentScroll > previousScroll)
|
||||||
|
{
|
||||||
|
if($("#layout_menu_toggle").css( 'position' ) === 'fixed' && $("#layout_menu_toggle").attr('data-scroll-down') !== 'true')
|
||||||
|
{
|
||||||
|
$("#layout_menu_toggle").attr('data-scroll-down', 'true');
|
||||||
|
$("#layout_menu_toggle").fadeOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if($("#layout_menu_toggle").css( 'position' ) === 'fixed' && $("#layout_menu_toggle").attr('data-scroll-down') === 'true')
|
||||||
|
{
|
||||||
|
$("#layout_menu_toggle").attr('data-scroll-down', '');
|
||||||
|
$("#layout_menu_toggle").fadeIn();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previousScroll = currentScroll;
|
||||||
|
});
|
||||||
|
|
||||||
/* keyboard accessibility for dropdown menu */
|
/* keyboard accessibility for dropdown menu */
|
||||||
$(".layout_dropdown").each(function() {
|
$(".layout_dropdown").each(function()
|
||||||
$( this ).focusin( function( event ) {
|
{
|
||||||
|
$( this ).focusin( function( event )
|
||||||
|
{
|
||||||
$( this ).addClass('layout_focus');
|
$( this ).addClass('layout_focus');
|
||||||
$( this ).find("ul.layout_dropdown-content").css('display', 'block').attr('data-dropdown', 'active');
|
$( this ).find("ul.layout_dropdown-content").css('display', 'block').attr('data-dropdown', 'active');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('body').focusin(function( event ) {
|
$('body').focusin(function( event )
|
||||||
if (!$(event.target).parents('.layout_dropdown').is('.layout_dropdown')) {
|
{
|
||||||
|
if (!$(event.target).parents('.layout_dropdown').is('.layout_dropdown'))
|
||||||
|
{
|
||||||
$('*[data-dropdown="active"]').css('display', '').attr('data-dropdown', '').parents('li.layout_dropdown').removeClass('layout_focus');
|
$('*[data-dropdown="active"]').css('display', '').attr('data-dropdown', '').parents('li.layout_dropdown').removeClass('layout_focus');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/* keyboard accessibility for dropdown menu END */
|
/* keyboard accessibility for dropdown menu END */
|
||||||
|
|
||||||
function layout_toggleMenuOpener(obj) {
|
function layout_toggleMenuOpener(obj)
|
||||||
if(obj.classList.contains("is-active") === true){
|
{
|
||||||
|
if(obj.classList.contains("is-active") === true)
|
||||||
|
{
|
||||||
var targetMenu = $(obj).attr('data-target');
|
var targetMenu = $(obj).attr('data-target');
|
||||||
$('#' + targetMenu).slideUp('300', function() {
|
$('#' + targetMenu).slideUp('300', function()
|
||||||
|
{
|
||||||
$(this).css('display', '');
|
$(this).css('display', '');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -62,7 +100,8 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Language Select
|
// Language Select
|
||||||
$('.layout_language>.toggle').click(function(){
|
$('.layout_language>.toggle').click(function()
|
||||||
|
{
|
||||||
$('.selectLang').toggle();
|
$('.selectLang').toggle();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
<block cond="count($addon_info->extra_vars)">
|
<block cond="count($addon_info->extra_vars)">
|
||||||
<block loop="$addon_info->extra_vars => $id, $var">
|
<block loop="$addon_info->extra_vars => $id, $var">
|
||||||
<block cond="$group != $var->group">
|
<block cond="$group != $var->group">
|
||||||
<h2>{$var->group}</h2>
|
<h2 style="margin-top:50px;">{$var->group}</h2>
|
||||||
{@$group = $var->group}
|
{@$group = $var->group}
|
||||||
</block>
|
</block>
|
||||||
{@$not_first = true}
|
{@$not_first = true}
|
||||||
|
|
|
||||||
|
|
@ -549,12 +549,124 @@ class adminAdminController extends admin
|
||||||
$this->_saveDefaultImage($vars->is_delete_default_image);
|
$this->_saveDefaultImage($vars->is_delete_default_image);
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update notification configuration.
|
||||||
|
*/
|
||||||
|
function procAdminUpdateNotification()
|
||||||
|
{
|
||||||
|
$vars = Context::getRequestVars();
|
||||||
|
|
||||||
|
// Load advanced mailer module (for lang).
|
||||||
|
$oAdvancedMailerAdminView = getAdminView('advanced_mailer');
|
||||||
|
|
||||||
|
// Validate the mail sender's information.
|
||||||
|
if (!$vars->mail_default_name)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_sender_name_is_empty');
|
||||||
|
}
|
||||||
|
if (!$vars->mail_default_from)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_sender_email_is_empty');
|
||||||
|
}
|
||||||
|
if (!Mail::isVaildMailAddress($vars->mail_default_from))
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_sender_email_is_invalid');
|
||||||
|
}
|
||||||
|
if ($vars->mail_default_reply_to && !Mail::isVaildMailAddress($vars->mail_default_reply_to))
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_reply_to_is_invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the mail driver.
|
||||||
|
$mail_drivers = Rhymix\Framework\Mail::getSupportedDrivers();
|
||||||
|
$mail_driver = $vars->mail_driver;
|
||||||
|
if (!array_key_exists($mail_driver, $mail_drivers))
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_sending_method_is_invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the mail driver settings.
|
||||||
|
$mail_driver_config = array();
|
||||||
|
foreach ($mail_drivers[$mail_driver]['required'] as $conf_name)
|
||||||
|
{
|
||||||
|
$conf_value = $vars->{'mail_' . $mail_driver . '_' . $conf_name} ?: null;
|
||||||
|
if (!$conf_value)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_smtp_host_is_invalid');
|
||||||
|
}
|
||||||
|
$mail_driver_config[$conf_name] = $conf_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the SMS driver.
|
||||||
|
$sms_drivers = Rhymix\Framework\SMS::getSupportedDrivers();
|
||||||
|
$sms_driver = $vars->sms_driver;
|
||||||
|
if (!array_key_exists($sms_driver, $sms_drivers))
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_sending_method_is_invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the SMS driver settings.
|
||||||
|
$sms_driver_config = array();
|
||||||
|
foreach ($sms_drivers[$sms_driver]['required'] as $conf_name)
|
||||||
|
{
|
||||||
|
$conf_value = $vars->{'sms_' . $sms_driver . '_' . $conf_name} ?: null;
|
||||||
|
if (!$conf_value)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_advanced_mailer_smtp_host_is_invalid');
|
||||||
|
}
|
||||||
|
$sms_driver_config[$conf_name] = $conf_value;
|
||||||
|
}
|
||||||
|
foreach ($sms_drivers[$sms_driver]['optional'] as $conf_name)
|
||||||
|
{
|
||||||
|
$conf_value = $vars->{'sms_' . $sms_driver . '_' . $conf_name} ?: null;
|
||||||
|
$sms_driver_config[$conf_name] = $conf_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save advanced mailer config.
|
||||||
|
getController('module')->updateModuleConfig('advanced_mailer', (object)array(
|
||||||
|
'sender_name' => trim($vars->mail_default_name),
|
||||||
|
'sender_email' => trim($vars->mail_default_from),
|
||||||
|
'force_sender' => toBool($vars->mail_force_default_sender),
|
||||||
|
'reply_to' => trim($vars->mail_default_reply_to),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Save member config.
|
||||||
|
getController('module')->updateModuleConfig('member', (object)array(
|
||||||
|
'webmaster_name' => trim($vars->mail_default_name),
|
||||||
|
'webmaster_email' => trim($vars->mail_default_from),
|
||||||
|
));
|
||||||
|
|
||||||
|
// Save system config.
|
||||||
|
Rhymix\Framework\Config::set("mail.default_name", trim($vars->mail_default_name));
|
||||||
|
Rhymix\Framework\Config::set("mail.default_from", trim($vars->mail_default_from));
|
||||||
|
Rhymix\Framework\Config::set("mail.default_force", toBool($vars->mail_force_default_sender));
|
||||||
|
Rhymix\Framework\Config::set("mail.default_reply_to", trim($vars->mail_default_reply_to));
|
||||||
|
Rhymix\Framework\Config::set("mail.type", $mail_driver);
|
||||||
|
Rhymix\Framework\Config::set("mail.$mail_driver", $mail_driver_config);
|
||||||
|
Rhymix\Framework\Config::set("sms.default_from", trim($vars->sms_default_from));
|
||||||
|
Rhymix\Framework\Config::set("sms.default_force", toBool($vars->sms_force_default_sender));
|
||||||
|
Rhymix\Framework\Config::set("sms.type", $sms_driver);
|
||||||
|
Rhymix\Framework\Config::set("sms.$sms_driver", $sms_driver_config);
|
||||||
|
Rhymix\Framework\Config::set("sms.allow_split.sms", toBool($vars->allow_split_sms));
|
||||||
|
Rhymix\Framework\Config::set("sms.allow_split.lms", toBool($vars->allow_split_lms));
|
||||||
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->setMessage('success_updated');
|
||||||
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigNotification'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update security configuration.
|
* Update security configuration.
|
||||||
*/
|
*/
|
||||||
|
|
@ -584,6 +696,14 @@ class adminAdminController extends admin
|
||||||
natcasesort($object_whitelist);
|
natcasesort($object_whitelist);
|
||||||
Rhymix\Framework\Config::set('mediafilter.object', array_values($object_whitelist));
|
Rhymix\Framework\Config::set('mediafilter.object', array_values($object_whitelist));
|
||||||
|
|
||||||
|
// HTML classes
|
||||||
|
$classes = $vars->mediafilter_classes;
|
||||||
|
$classes = array_filter(array_map('trim', preg_split('/[\r\n]/', $classes)), function($item) {
|
||||||
|
return preg_match('/^[a-zA-Z0-9_-]+$/u', $item);
|
||||||
|
});
|
||||||
|
natcasesort($classes);
|
||||||
|
Rhymix\Framework\Config::set('mediafilter.classes', array_values($classes));
|
||||||
|
|
||||||
// Remove old embed filter
|
// Remove old embed filter
|
||||||
$config = Rhymix\Framework\Config::getAll();
|
$config = Rhymix\Framework\Config::getAll();
|
||||||
unset($config['embedfilter']);
|
unset($config['embedfilter']);
|
||||||
|
|
@ -616,7 +736,10 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('admin.deny', array_values($denied_ip));
|
Rhymix\Framework\Config::set('admin.deny', array_values($denied_ip));
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSecurity'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSecurity'));
|
||||||
|
|
@ -631,7 +754,7 @@ class adminAdminController extends admin
|
||||||
|
|
||||||
// Default URL
|
// Default URL
|
||||||
$default_url = rtrim(trim($vars->default_url), '/\\') . '/';
|
$default_url = rtrim(trim($vars->default_url), '/\\') . '/';
|
||||||
if (!filter_var($default_url, FILTER_VALIDATE_URL) || !preg_match('@^https?://@', $default_url))
|
if (!filter_var(Rhymix\Framework\URL::encodeIdna($default_url), FILTER_VALIDATE_URL) || !preg_match('@^https?://@', $default_url))
|
||||||
{
|
{
|
||||||
return new Object(-1, 'msg_invalid_default_url');
|
return new Object(-1, 'msg_invalid_default_url');
|
||||||
}
|
}
|
||||||
|
|
@ -700,10 +823,11 @@ class adminAdminController extends admin
|
||||||
}
|
}
|
||||||
|
|
||||||
// Thumbnail settings
|
// Thumbnail settings
|
||||||
$args = new stdClass;
|
$oDocumentModel = getModel('document');
|
||||||
$args->thumbnail_type = $vars->thumbnail_type === 'ratio' ? 'ratio' : 'crop';
|
$document_config = $oDocumentModel->getDocumentConfig();
|
||||||
|
$document_config->thumbnail_type = $vars->thumbnail_type ?: 'crop';
|
||||||
$oModuleController = getController('module');
|
$oModuleController = getController('module');
|
||||||
$oModuleController->insertModuleConfig('document', $args);
|
$oModuleController->insertModuleConfig('document', $document_config);
|
||||||
|
|
||||||
// Other settings
|
// Other settings
|
||||||
Rhymix\Framework\Config::set('use_rewrite', $vars->use_rewrite === 'Y');
|
Rhymix\Framework\Config::set('use_rewrite', $vars->use_rewrite === 'Y');
|
||||||
|
|
@ -716,7 +840,10 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('view.use_gzip', $vars->use_gzip === 'Y');
|
Rhymix\Framework\Config::set('view.use_gzip', $vars->use_gzip === 'Y');
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigAdvanced'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigAdvanced'));
|
||||||
|
|
@ -776,7 +903,10 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('debug.allow', array_values($allowed_ip));
|
Rhymix\Framework\Config::set('debug.allow', array_values($allowed_ip));
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigDebug'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigDebug'));
|
||||||
|
|
@ -805,7 +935,10 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('seo.og_use_timestamps', $vars->og_use_timestamps === 'Y');
|
Rhymix\Framework\Config::set('seo.og_use_timestamps', $vars->og_use_timestamps === 'Y');
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSEO'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSEO'));
|
||||||
|
|
@ -844,7 +977,10 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('lock.title', trim($vars->sitelock_title));
|
Rhymix\Framework\Config::set('lock.title', trim($vars->sitelock_title));
|
||||||
Rhymix\Framework\Config::set('lock.message', trim($vars->sitelock_message));
|
Rhymix\Framework\Config::set('lock.message', trim($vars->sitelock_message));
|
||||||
Rhymix\Framework\Config::set('lock.allow', array_values($allowed_ip));
|
Rhymix\Framework\Config::set('lock.allow', array_values($allowed_ip));
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSitelock'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSitelock'));
|
||||||
|
|
@ -916,7 +1052,10 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('ftp.path', $vars->ftp_path);
|
Rhymix\Framework\Config::set('ftp.path', $vars->ftp_path);
|
||||||
Rhymix\Framework\Config::set('ftp.pasv', $vars->ftp_pasv === 'Y');
|
Rhymix\Framework\Config::set('ftp.pasv', $vars->ftp_pasv === 'Y');
|
||||||
Rhymix\Framework\Config::set('ftp.sftp', $vars->ftp_sftp === 'Y');
|
Rhymix\Framework\Config::set('ftp.sftp', $vars->ftp_sftp === 'Y');
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_updated');
|
$this->setMessage('success_updated');
|
||||||
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigFtp'));
|
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigFtp'));
|
||||||
|
|
@ -934,7 +1073,11 @@ class adminAdminController extends admin
|
||||||
Rhymix\Framework\Config::set('ftp.path', null);
|
Rhymix\Framework\Config::set('ftp.path', null);
|
||||||
Rhymix\Framework\Config::set('ftp.pasv', true);
|
Rhymix\Framework\Config::set('ftp.pasv', true);
|
||||||
Rhymix\Framework\Config::set('ftp.sftp', false);
|
Rhymix\Framework\Config::set('ftp.sftp', false);
|
||||||
Rhymix\Framework\Config::save();
|
if (!Rhymix\Framework\Config::save())
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_failed_to_save_config');
|
||||||
|
}
|
||||||
|
|
||||||
$this->setMessage('success_deleted');
|
$this->setMessage('success_deleted');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -445,6 +445,42 @@ class adminAdminView extends admin
|
||||||
$this->setTemplateFile('config_general');
|
$this->setTemplateFile('config_general');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display Notification Settings page
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
function dispAdminConfigNotification()
|
||||||
|
{
|
||||||
|
// Load advanced mailer module (for lang).
|
||||||
|
$oAdvancedMailerAdminView = getAdminView('advanced_mailer');
|
||||||
|
|
||||||
|
// Load advanced mailer config.
|
||||||
|
$advanced_mailer_config = $oAdvancedMailerAdminView->getConfig();
|
||||||
|
Context::set('advanced_mailer_config', $advanced_mailer_config);
|
||||||
|
|
||||||
|
// Load member config.
|
||||||
|
$member_config = getModel('module')->getModuleConfig('member');
|
||||||
|
Context::set('member_config', $member_config);
|
||||||
|
Context::set('webmaster_name', $member_config->webmaster_name ? $member_config->webmaster_name : 'webmaster');
|
||||||
|
Context::set('webmaster_email', $member_config->webmaster_email);
|
||||||
|
|
||||||
|
// Load module config.
|
||||||
|
$module_config = getModel('module')->getModuleConfig('module');
|
||||||
|
Context::set('module_config', $module_config);
|
||||||
|
|
||||||
|
// Load mail drivers.
|
||||||
|
$mail_drivers = Rhymix\Framework\Mail::getSupportedDrivers();
|
||||||
|
Context::set('mail_drivers', $mail_drivers);
|
||||||
|
Context::set('mail_driver', config('mail.type') ?: 'mailfunction');
|
||||||
|
|
||||||
|
// Load SMS drivers.
|
||||||
|
$sms_drivers = Rhymix\Framework\SMS::getSupportedDrivers();
|
||||||
|
Context::set('sms_drivers', $sms_drivers);
|
||||||
|
Context::set('sms_driver', config('sms.type') ?: 'dummy');
|
||||||
|
|
||||||
|
$this->setTemplateFile('config_notification');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display Security Settings page
|
* Display Security Settings page
|
||||||
* @return void
|
* @return void
|
||||||
|
|
@ -454,6 +490,7 @@ class adminAdminView extends admin
|
||||||
// Load embed filter.
|
// Load embed filter.
|
||||||
context::set('mediafilter_iframe', implode(PHP_EOL, Rhymix\Framework\Filters\MediaFilter::getIframeWhitelist()));
|
context::set('mediafilter_iframe', implode(PHP_EOL, Rhymix\Framework\Filters\MediaFilter::getIframeWhitelist()));
|
||||||
context::set('mediafilter_object', implode(PHP_EOL, Rhymix\Framework\Filters\MediaFilter::getObjectWhitelist()));
|
context::set('mediafilter_object', implode(PHP_EOL, Rhymix\Framework\Filters\MediaFilter::getObjectWhitelist()));
|
||||||
|
context::set('mediafilter_classes', implode(PHP_EOL, Rhymix\Framework\Config::get('mediafilter.classes') ?: array()));
|
||||||
|
|
||||||
// Admin IP access control
|
// Admin IP access control
|
||||||
$allowed_ip = Rhymix\Framework\Config::get('admin.allow');
|
$allowed_ip = Rhymix\Framework\Config::get('admin.allow');
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<actions>
|
<actions>
|
||||||
<action name="dispAdminIndex" type="view" index="true" />
|
<action name="dispAdminIndex" type="view" index="true" />
|
||||||
<action name="dispAdminConfigGeneral" type="view" menu_name="adminConfigurationGeneral" menu_index="true" />
|
<action name="dispAdminConfigGeneral" type="view" menu_name="adminConfigurationGeneral" menu_index="true" />
|
||||||
|
<action name="dispAdminConfigNotification" type="view" menu_name="adminConfigurationGeneral" />
|
||||||
<action name="dispAdminConfigSecurity" type="view" menu_name="adminConfigurationGeneral" />
|
<action name="dispAdminConfigSecurity" type="view" menu_name="adminConfigurationGeneral" />
|
||||||
<action name="dispAdminConfigAdvanced" type="view" menu_name="adminConfigurationGeneral" />
|
<action name="dispAdminConfigAdvanced" type="view" menu_name="adminConfigurationGeneral" />
|
||||||
<action name="dispAdminConfigDebug" type="view" menu_name="adminConfigurationGeneral" />
|
<action name="dispAdminConfigDebug" type="view" menu_name="adminConfigurationGeneral" />
|
||||||
|
|
@ -24,6 +25,7 @@
|
||||||
<action name="procAdminDeleteLogo" type="controller" />
|
<action name="procAdminDeleteLogo" type="controller" />
|
||||||
<action name="procAdminMenuReset" type="controller" />
|
<action name="procAdminMenuReset" type="controller" />
|
||||||
<action name="procAdminUpdateConfigGeneral" type="controller" />
|
<action name="procAdminUpdateConfigGeneral" type="controller" />
|
||||||
|
<action name="procAdminUpdateNotification" type="controller" />
|
||||||
<action name="procAdminUpdateSecurity" type="controller" />
|
<action name="procAdminUpdateSecurity" type="controller" />
|
||||||
<action name="procAdminUpdateAdvanced" type="controller" />
|
<action name="procAdminUpdateAdvanced" type="controller" />
|
||||||
<action name="procAdminUpdateDebug" type="controller" />
|
<action name="procAdminUpdateDebug" type="controller" />
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
$lang->admin = 'Admin';
|
$lang->admin = 'Admin';
|
||||||
$lang->cmd_configure = 'Configure';
|
$lang->cmd_configure = 'Configure';
|
||||||
$lang->subtitle_primary = 'General Settings';
|
$lang->subtitle_primary = 'General Settings';
|
||||||
|
$lang->subtitle_notification = 'Notification Settings';
|
||||||
$lang->subtitle_security = 'Security Settings';
|
$lang->subtitle_security = 'Security Settings';
|
||||||
$lang->subtitle_advanced = 'Advanced Settings';
|
$lang->subtitle_advanced = 'Advanced Settings';
|
||||||
$lang->subtitle_debug = 'Debug Settings';
|
$lang->subtitle_debug = 'Debug Settings';
|
||||||
|
|
@ -74,11 +75,28 @@ $lang->msg_blacklisted_reason['session_shield'] = 'The functionality that this a
|
||||||
$lang->msg_blacklisted_reason['smartphone'] = 'This module was disabled in XE long before Rhymix even existed.';
|
$lang->msg_blacklisted_reason['smartphone'] = 'This module was disabled in XE long before Rhymix even existed.';
|
||||||
$lang->msg_blacklisted_reason['zipperupper'] = 'Similar functionality can be configured in the <a href="./index.php?module=admin&act=dispAdminConfigAdvanced">Advanced Settings</a> page.';
|
$lang->msg_blacklisted_reason['zipperupper'] = 'Similar functionality can be configured in the <a href="./index.php?module=admin&act=dispAdminConfigAdvanced">Advanced Settings</a> page.';
|
||||||
$lang->msg_warning = 'Warning';
|
$lang->msg_warning = 'Warning';
|
||||||
|
$lang->msg_failed_to_save_config = 'Failed to save configuration. Please check permissions on files/config.';
|
||||||
$lang->welcome_to_xe = 'Welcome to the Rhymix admin page.';
|
$lang->welcome_to_xe = 'Welcome to the Rhymix admin page.';
|
||||||
$lang->about_lang_env = 'If you want to make the language setting same for first-time visitors, change the language setting to what you want and click [Save] button below.';
|
$lang->about_lang_env = 'If you want to make the language setting same for first-time visitors, change the language setting to what you want and click [Save] button below.';
|
||||||
$lang->xe_license = 'Rhymix complies with the GPL.';
|
$lang->xe_license = 'Rhymix complies with the GPL.';
|
||||||
$lang->yesterday = 'Yesterday';
|
$lang->yesterday = 'Yesterday';
|
||||||
$lang->today = 'Today';
|
$lang->today = 'Today';
|
||||||
|
$lang->cmd_admin_default_from_name = 'Default Sender Name';
|
||||||
|
$lang->cmd_admin_default_from_email = 'Default Sender E-mail';
|
||||||
|
$lang->cmd_admin_default_from_phone = 'Default Sender Number';
|
||||||
|
$lang->cmd_admin_default_reply_to = 'Reply-To';
|
||||||
|
$lang->cmd_admin_force_default_sender = 'Apply to All';
|
||||||
|
$lang->cmd_admin_sending_method = 'Sending Method';
|
||||||
|
$lang->cmd_admin_allow_split_sms = 'Split long SMS';
|
||||||
|
$lang->cmd_admin_allow_split_lms = 'Split long LMS/MMS';
|
||||||
|
$lang->cmd_admin_default_from_name_help = 'This name will be used in all outgoing emails, such as welcome e-mails, authentication e-mails, and other e-mail notifications.';
|
||||||
|
$lang->cmd_admin_default_from_email_help = 'This e-mail address will be used in all outgoing e-mails.<br>If you are using SMTP or an external API, please check "Apply to All" to avoid having your e-mails treated as spam.';
|
||||||
|
$lang->cmd_admin_default_reply_to_help = 'This e-mail will receive replies. Please leave it empty if it is the same as the address above.<br>Some sending methods may not support a separate Reply-To address.';
|
||||||
|
$lang->cmd_admin_default_from_phone_help = 'This number will be used in all outgoing SMS notifications.<br>Some SMS gateways may require that you pre-register your phone number. In that case, you should also check "Apply to All".';
|
||||||
|
$lang->cmd_admin_sms_dummy_driver_help = 'Select "Dummy" if you are not going to send any SMS.';
|
||||||
|
$lang->cmd_admin_sms_sender_key_help = 'The sender key is used for Alimtalk. Please leave it empty if you do not use Alimtalk.';
|
||||||
|
$lang->cmd_admin_allow_split_sms_help = 'Split long texts into multiple SMS in order to prevent clipping.<br>This only applies to gateways that cannot send LMS/MMS. Otherwise, long texts will be automatically converted to LMS/MMS.';
|
||||||
|
$lang->cmd_admin_allow_split_lms_help = 'Split very long texts into multiple LMS/MMS in order to prevent clipping.<br>This may increase your LMS/MMS cost significantly.';
|
||||||
$lang->default_lang = 'Default Language';
|
$lang->default_lang = 'Default Language';
|
||||||
$lang->lang_select = 'Supported Languages';
|
$lang->lang_select = 'Supported Languages';
|
||||||
$lang->auto_select_lang = 'Auto-select Language';
|
$lang->auto_select_lang = 'Auto-select Language';
|
||||||
|
|
@ -198,8 +216,9 @@ $lang->tablets_as_mobile = 'Treat Tablets as Mobile';
|
||||||
$lang->thumbnail_type = 'Select thumbnail type.';
|
$lang->thumbnail_type = 'Select thumbnail type.';
|
||||||
$lang->input_footer_script = 'Footer script';
|
$lang->input_footer_script = 'Footer script';
|
||||||
$lang->detail_input_footer_script = 'The script is inserted into the bottom of body. It does not work at admin page.';
|
$lang->detail_input_footer_script = 'The script is inserted into the bottom of body. It does not work at admin page.';
|
||||||
$lang->corp = 'Crop (Cut)';
|
$lang->thumbnail_crop = 'Crop';
|
||||||
$lang->ratio = 'Ratio (Keep Aspect Ratio)';
|
$lang->thumbnail_ratio = 'Keep aspect ratio (may result in spaces)';
|
||||||
|
$lang->thumbnail_none = 'Do not create thumbnails';
|
||||||
$lang->admin_ip_allow = 'IP addresses allowed to log in as administrator';
|
$lang->admin_ip_allow = 'IP addresses allowed to log in as administrator';
|
||||||
$lang->admin_ip_deny = 'IP addresses forbidden to log in as administrator';
|
$lang->admin_ip_deny = 'IP addresses forbidden to log in as administrator';
|
||||||
$lang->local_ip_address = 'Local IP address';
|
$lang->local_ip_address = 'Local IP address';
|
||||||
|
|
|
||||||
|
|
@ -125,8 +125,9 @@ $lang->about_use_mobile_view = 'モバイル機器で接続した際にモバイ
|
||||||
$lang->thumbnail_type = 'サムネイルの作成方式を選択してください。';
|
$lang->thumbnail_type = 'サムネイルの作成方式を選択してください。';
|
||||||
$lang->input_footer_script = '下段(footer)スクリプト';
|
$lang->input_footer_script = '下段(footer)スクリプト';
|
||||||
$lang->detail_input_footer_script = '最下段にコードを追加します。管理者ページでは遂行できません。';
|
$lang->detail_input_footer_script = '最下段にコードを追加します。管理者ページでは遂行できません。';
|
||||||
$lang->corp = '切り取り';
|
$lang->thumbnail_crop = 'トリミングする';
|
||||||
$lang->ratio = 'Ratio(縦横の比率をキープ)';
|
$lang->thumbnail_ratio = '比率に合わせる';
|
||||||
|
$lang->thumbnail_none = 'サムネイルを作成しない';
|
||||||
$lang->admin_ip_allow = '管理者ログイン許容IP';
|
$lang->admin_ip_allow = '管理者ログイン許容IP';
|
||||||
$lang->admin_ip_deny = '管理者ログイン禁止IP';
|
$lang->admin_ip_deny = '管理者ログイン禁止IP';
|
||||||
$lang->local_ip_address = 'ローカルIPアドレス';
|
$lang->local_ip_address = 'ローカルIPアドレス';
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
$lang->admin = '관리자';
|
$lang->admin = '관리자';
|
||||||
$lang->cmd_configure = '설정하기';
|
$lang->cmd_configure = '설정하기';
|
||||||
$lang->subtitle_primary = '기본 설정';
|
$lang->subtitle_primary = '기본 설정';
|
||||||
|
$lang->subtitle_notification = '알림 설정';
|
||||||
$lang->subtitle_security = '보안 설정';
|
$lang->subtitle_security = '보안 설정';
|
||||||
$lang->subtitle_advanced = '고급 설정';
|
$lang->subtitle_advanced = '고급 설정';
|
||||||
$lang->subtitle_debug = '디버그 설정';
|
$lang->subtitle_debug = '디버그 설정';
|
||||||
|
|
@ -74,11 +75,28 @@ $lang->msg_blacklisted_reason['session_shield'] = '이 애드온에서 제공하
|
||||||
$lang->msg_blacklisted_reason['smartphone'] = '이 모듈은 XE에서도 사용되지 않고 있었습니다.';
|
$lang->msg_blacklisted_reason['smartphone'] = '이 모듈은 XE에서도 사용되지 않고 있었습니다.';
|
||||||
$lang->msg_blacklisted_reason['zipperupper'] = '이 애드온에서 제공하던 기능은 <a href="./index.php?module=admin&act=dispAdminConfigAdvanced">고급 설정</a> 페이지에서 관리할 수 있습니다.';
|
$lang->msg_blacklisted_reason['zipperupper'] = '이 애드온에서 제공하던 기능은 <a href="./index.php?module=admin&act=dispAdminConfigAdvanced">고급 설정</a> 페이지에서 관리할 수 있습니다.';
|
||||||
$lang->msg_warning = '경고';
|
$lang->msg_warning = '경고';
|
||||||
|
$lang->msg_failed_to_save_config = '설정을 저장할 수 없습니다. files/config 폴더 및 설정파일들의 퍼미션을 확인해 주시기 바랍니다.';
|
||||||
$lang->welcome_to_xe = 'Rhymix 관리자';
|
$lang->welcome_to_xe = 'Rhymix 관리자';
|
||||||
$lang->about_lang_env = '처음 방문하는 사용자들의 언어 설정을 동일하게 하려면, 원하는 언어로 변경 후 아래 [저장] 버튼을 클릭하면 됩니다.';
|
$lang->about_lang_env = '처음 방문하는 사용자들의 언어 설정을 동일하게 하려면, 원하는 언어로 변경 후 아래 [저장] 버튼을 클릭하면 됩니다.';
|
||||||
$lang->xe_license = 'Rhymix는 GPL을 따릅니다.';
|
$lang->xe_license = 'Rhymix는 GPL을 따릅니다.';
|
||||||
$lang->yesterday = '어제';
|
$lang->yesterday = '어제';
|
||||||
$lang->today = '오늘';
|
$lang->today = '오늘';
|
||||||
|
$lang->cmd_admin_default_from_name = '기본 발신자 이름';
|
||||||
|
$lang->cmd_admin_default_from_email = '기본 발신자 주소';
|
||||||
|
$lang->cmd_admin_default_from_phone = '기본 발신자 번호';
|
||||||
|
$lang->cmd_admin_default_reply_to = 'Reply-To 주소';
|
||||||
|
$lang->cmd_admin_force_default_sender = '일괄 적용';
|
||||||
|
$lang->cmd_admin_sending_method = '발송 방법';
|
||||||
|
$lang->cmd_admin_allow_split_sms = 'SMS 분할 발송';
|
||||||
|
$lang->cmd_admin_allow_split_lms = 'LMS/MMS 분할 발송';
|
||||||
|
$lang->cmd_admin_default_from_name_help = '가입환영 메일, 인증메일, 알림 등을 발송할 때 사용할 이름입니다. 사이트 이름 사용을 권장합니다.';
|
||||||
|
$lang->cmd_admin_default_from_email_help = '가입환영 메일, 인증메일, 알림 등을 발송할 때 사용할 메일 주소입니다.<br>SMTP 또는 외부 API 사용시 일괄 적용 옵션을 선택하지 않으면 스팸으로 취급될 가능성이 높아지니 주의하십시오.';
|
||||||
|
$lang->cmd_admin_default_reply_to_help = '받는이가 "답장"을 클릭했을 때 발신자 주소가 아닌 다른 주소로 답장을 받을 수 있습니다.<br>발송 방법에 따라 이 기능을 지원하지 않을 수도 있습니다.';
|
||||||
|
$lang->cmd_admin_default_from_phone_help = 'SMS 알림을 발송할 때 사용할 번호입니다.<br>국내 서비스 사용시 API 제공 업체에 발신자 번호를 미리 등록하고, 일괄 적용 옵션을 사용하시기 바랍니다.';
|
||||||
|
$lang->cmd_admin_sms_dummy_driver_help = 'SMS를 사용하지 않는 경우 Dummy를 선택하십시오.';
|
||||||
|
$lang->cmd_admin_sms_sender_key_help = '알림톡 발송에 필요한 Sender Key입니다. 알림톡을 사용하지 않는 경우 비워 두시기 바랍니다.';
|
||||||
|
$lang->cmd_admin_allow_split_sms_help = '긴 내용을 SMS로 발송할 때 잘리지 않도록 2개 이상의 SMS로 분할 발송합니다.<br>LMS/MMS를 사용할 수 있는 경우 자동 변경되므로, LMS/MMS 사용이 불가능한 서비스에만 해당됩니다.';
|
||||||
|
$lang->cmd_admin_allow_split_lms_help = '매우 긴 내용을 LMS 또는 MMS로 발송할 때 잘리지 않도록 2개 이상의 LMS 또는 MMS로 분할 발송합니다.<br>내용이 지나치게 긴 경우 비용이 많이 발생할 수 있으니 주의하십시오.';
|
||||||
$lang->default_lang = '기본 언어 선택';
|
$lang->default_lang = '기본 언어 선택';
|
||||||
$lang->lang_select = '지원 언어 선택';
|
$lang->lang_select = '지원 언어 선택';
|
||||||
$lang->auto_select_lang = '언어 자동 선택';
|
$lang->auto_select_lang = '언어 자동 선택';
|
||||||
|
|
@ -193,8 +211,9 @@ $lang->tablets_as_mobile = '태블릿도 모바일 취급';
|
||||||
$lang->thumbnail_type = '썸네일 생성 방식';
|
$lang->thumbnail_type = '썸네일 생성 방식';
|
||||||
$lang->input_footer_script = '하단(footer) 스크립트';
|
$lang->input_footer_script = '하단(footer) 스크립트';
|
||||||
$lang->detail_input_footer_script = '최하단에 코드를 삽입합니다. 관리자 페이지에서는 수행되지 않습니다.';
|
$lang->detail_input_footer_script = '최하단에 코드를 삽입합니다. 관리자 페이지에서는 수행되지 않습니다.';
|
||||||
$lang->corp = 'Crop (잘라내기)';
|
$lang->thumbnail_crop = '크기에 맞추어 잘라내기';
|
||||||
$lang->ratio = 'Ratio (비율 맞추기)';
|
$lang->thumbnail_ratio = '비율 유지 (여백이 생길 수 있음)';
|
||||||
|
$lang->thumbnail_none = '썸네일 생성하지 않음';
|
||||||
$lang->admin_ip_allow = '관리자 로그인 허용 IP';
|
$lang->admin_ip_allow = '관리자 로그인 허용 IP';
|
||||||
$lang->admin_ip_deny = '관리자 로그인 금지 IP';
|
$lang->admin_ip_deny = '관리자 로그인 금지 IP';
|
||||||
$lang->local_ip_address = '로컬 IP 주소';
|
$lang->local_ip_address = '로컬 IP 주소';
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<button type="button" class="x_btn-link" onclick="doResetAdminMenu();">{$lang->cmd_admin_menu_reset}</button> <span class="vr">|</span>
|
<button type="button" class="x_btn-link" onclick="doResetAdminMenu();">{$lang->cmd_admin_menu_reset}</button> <span class="vr">|</span>
|
||||||
<button type="button" class="x_btn-link" onclick="doRecompileCacheFile();">{$lang->cmd_remake_cache}</button> <span class="vr">|</span>
|
<button type="button" class="x_btn-link" onclick="doRecompileCacheFile();">{$lang->cmd_remake_cache}</button> <span class="vr">|</span>
|
||||||
<button type="button" class="x_btn-link" onclick="doClearSession();">{$lang->cmd_clear_session}</button> <span class="vr">|</span>
|
<button type="button" class="x_btn-link" onclick="doClearSession();">{$lang->cmd_clear_session}</button> <span class="vr">|</span>
|
||||||
<a href="./index.php?module=admin&act=dispAdminViewServerEnv">{$lang->cmd_view_server_env}</a> <span class="vr">|</span>
|
<a href="./index.php?module=admin&act=dispAdminViewServerEnv" style="vertical-align:middle">{$lang->cmd_view_server_env}</a> <span class="vr">|</span>
|
||||||
<a href="https://github.com/rhymix/rhymix/issues" target="_blank" style="vertical-align:middle">{$lang->bug_report}</a>
|
<a href="https://github.com/rhymix/rhymix/issues" target="_blank" style="vertical-align:middle">{$lang->bug_report}</a>
|
||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
||||||
|
|
@ -62,12 +62,16 @@
|
||||||
<label class="x_control-label">{$lang->thumbnail_type}</label>
|
<label class="x_control-label">{$lang->thumbnail_type}</label>
|
||||||
<div class="x_controls">
|
<div class="x_controls">
|
||||||
<label for="thumbnail_type_crop" class="x_inline">
|
<label for="thumbnail_type_crop" class="x_inline">
|
||||||
<input type="radio" name="thumbnail_type" id="thumbnail_type_crop" value="crop" checked="checked"|cond="$thumbnail_type != 'ratio'" />
|
<input type="radio" name="thumbnail_type" id="thumbnail_type_crop" value="crop" checked="checked"|cond="$thumbnail_type == 'crop' || !$thumbnail_type" />
|
||||||
{$lang->corp}
|
{$lang->thumbnail_crop}
|
||||||
</label>
|
</label>
|
||||||
<label for="thumbnail_type_ratio" class="x_inline">
|
<label for="thumbnail_type_ratio" class="x_inline">
|
||||||
<input type="radio" name="thumbnail_type" id="thumbnail_type_ratio" value="ratio" checked="checked"|cond="$thumbnail_type == 'ratio'" />
|
<input type="radio" name="thumbnail_type" id="thumbnail_type_ratio" value="ratio" checked="checked"|cond="$thumbnail_type == 'ratio'" />
|
||||||
{$lang->ratio}
|
{$lang->thumbnail_ratio}
|
||||||
|
</label>
|
||||||
|
<label for="thumbnail_type_none" class="x_inline">
|
||||||
|
<input type="radio" name="thumbnail_type" id="thumbnail_type_none" value="none" checked="checked"|cond="$thumbnail_type == 'none'" />
|
||||||
|
{$lang->thumbnail_none}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
<ul class="x_nav x_nav-tabs">
|
<ul class="x_nav x_nav-tabs">
|
||||||
<li class="x_active"|cond="$act == 'dispAdminConfigGeneral'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')}">{$lang->subtitle_primary}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdminConfigGeneral'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigGeneral')}">{$lang->subtitle_primary}</a></li>
|
||||||
|
<li class="x_active"|cond="$act == 'dispAdminConfigNotification'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigNotification')}">{$lang->subtitle_notification}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdminConfigSecurity'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigSecurity')}">{$lang->subtitle_security}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdminConfigSecurity'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigSecurity')}">{$lang->subtitle_security}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdminConfigAdvanced'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigAdvanced')}">{$lang->subtitle_advanced}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdminConfigAdvanced'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigAdvanced')}">{$lang->subtitle_advanced}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdminConfigDebug'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigDebug')}">{$lang->subtitle_debug}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdminConfigDebug'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigDebug')}">{$lang->subtitle_debug}</a></li>
|
||||||
|
|
|
||||||
296
modules/admin/tpl/config_notification.html
Normal file
296
modules/admin/tpl/config_notification.html
Normal file
|
|
@ -0,0 +1,296 @@
|
||||||
|
<include target="config_header.html" />
|
||||||
|
<load target="js/notification_config.js" />
|
||||||
|
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/admin/tpl/config_notification/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
|
||||||
|
<p>{$XE_VALIDATOR_MESSAGE}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var mail_drivers = {json_encode($mail_drivers)};
|
||||||
|
var sms_drivers = {json_encode($sms_drivers)};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form action="./" method="post" class="x_form-horizontal">
|
||||||
|
<input type="hidden" name="module" value="admin" />
|
||||||
|
<input type="hidden" name="act" value="procAdminUpdateNotification" />
|
||||||
|
<input type="hidden" name="xe_validator_id" value="modules/admin/tpl/config_notification/1" />
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
|
||||||
|
<h2>{$lang->email}</h2>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="mail_default_name">{$lang->cmd_admin_default_from_name}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_default_name" id="mail_default_name" value="{escape($member_config->webmaster_name) ?: $module_config->siteTitle}" />
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_default_from_name_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="mail_default_from">{$lang->cmd_admin_default_from_email}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_default_from" id="mail_default_from" value="{escape($member_config->webmaster_email)}" />
|
||||||
|
|
||||||
|
<label for="mail_force_default_sender" class="x_inline">
|
||||||
|
<input type="checkbox" name="mail_force_default_sender" id="mail_force_default_sender" value="Y" checked="checked"|cond="toBool($advanced_mailer_config->force_sender)" />
|
||||||
|
{$lang->cmd_admin_force_default_sender}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_default_from_email_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="mail_default_reply_to">{$lang->cmd_admin_default_reply_to}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_default_reply_to" id="mail_default_reply_to" value="{escape($advanced_mailer_config->reply_to ?: config('mail.default_reply_to'))}" />
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_default_reply_to_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="mail_driver">{$lang->cmd_admin_sending_method}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<select name="mail_driver" id="mail_driver">
|
||||||
|
<!--@foreach($mail_drivers as $driver_name => $driver_definition)-->
|
||||||
|
<option value="{$driver_name}" selected="selected"|cond="$mail_driver === $driver_name">{$driver_definition['name']}</option>
|
||||||
|
<!--@end-->
|
||||||
|
</select>
|
||||||
|
<p class="x_help-block hidden-by-default show-for-dummy">
|
||||||
|
{$lang->msg_advanced_mailer_about_dummy}<br />{$lang->msg_advanced_mailer_about_dummy_exceptions}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--@foreach($mail_drivers as $driver_name => $driver_definition)-->
|
||||||
|
|
||||||
|
<!--@foreach($driver_definition['required'] as $conf_name)-->
|
||||||
|
|
||||||
|
{@ $conf_value = escape(config("mail.$driver_name.$conf_name"))}
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'smtp_host')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_smtp_host">{$lang->cmd_advanced_mailer_smtp_host}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_{$driver_name}_smtp_host" id="mail_{$driver_name}_smtp_host" value="{$conf_value}" />
|
||||||
|
<select id="mail_{$driver_name}_manual_entry">
|
||||||
|
<option value="">{$lang->cmd_advanced_mailer_smtp_manual_entry}</option>
|
||||||
|
<option value="gmail">Gmail</option>
|
||||||
|
<option value="hanmail">Hanmail</option>
|
||||||
|
<option value="naver">Naver</option>
|
||||||
|
<option value="worksmobile">Works Mobile</option>
|
||||||
|
<option value="outlook">Outlook.com</option>
|
||||||
|
<option value="yahoo">Yahoo</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'smtp_port')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_smtp_port">{$lang->cmd_advanced_mailer_smtp_port}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_{$driver_name}_smtp_port" id="mail_{$driver_name}_smtp_port" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'smtp_security')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label">{$lang->cmd_advanced_mailer_smtp_security}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<label class="x_inline" for="mail_{$driver_name}_security_none"><input type="radio" name="mail_{$driver_name}_smtp_security" id="mail_{$driver_name}_security_none" value="none" checked="checked"|cond="!in_array($conf_value, array('ssl', 'tls'))" /> {$lang->cmd_advanced_mailer_smtp_security_none}</label>
|
||||||
|
<label class="x_inline" for="mail_{$driver_name}_security_ssl"><input type="radio" name="mail_{$driver_name}_smtp_security" id="mail_{$driver_name}_security_ssl" value="ssl" checked="checked"|cond="$conf_value === 'ssl'" /> {$lang->cmd_advanced_mailer_smtp_security_ssl}</label>
|
||||||
|
<label class="x_inline" for="mail_{$driver_name}_security_tls"><input type="radio" name="mail_{$driver_name}_smtp_security" id="mail_{$driver_name}_security_tls" value="tls" checked="checked"|cond="$conf_value === 'tls'" /> {$lang->cmd_advanced_mailer_smtp_security_tls}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'smtp_user')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_smtp_user">{$lang->cmd_advanced_mailer_smtp_user}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_{$driver_name}_smtp_user" id="mail_{$driver_name}_smtp_user" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'smtp_pass')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_smtp_pass">{$lang->cmd_advanced_mailer_smtp_pass}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="password" name="mail_{$driver_name}_smtp_pass" id="mail_{$driver_name}_smtp_pass" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_type')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_api_type">{$lang->cmd_advanced_mailer_api_type}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<select id="mail_{$driver_name}_api_type" name="mail_{$driver_name}_api_type">
|
||||||
|
<!--@foreach($driver_definition['api_types'] as $api_type)-->
|
||||||
|
<option value="{$api_type}" selected="selected"|cond="$api_type === $conf_value">{$api_type}</option>
|
||||||
|
<!--@end-->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_domain')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_api_domain">{$lang->cmd_advanced_mailer_api_domain}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_{$driver_name}_api_domain" id="mail_{$driver_name}_api_domain" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_token')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_api_token">{$lang->cmd_advanced_mailer_api_token}</label>
|
||||||
|
<div class="x_controls full-width">
|
||||||
|
<input type="text" name="mail_{$driver_name}_api_token" id="mail_{$driver_name}_api_token" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_user')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_api_user">{$lang->cmd_advanced_mailer_api_user}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="mail_{$driver_name}_api_user" id="mail_{$driver_name}_api_user" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_pass')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="mail_{$driver_name}_api_pass">{$lang->cmd_advanced_mailer_api_pass}</label>
|
||||||
|
<div class="x_controls full-width">
|
||||||
|
<input type="password" name="mail_{$driver_name}_api_pass" id="mail_{$driver_name}_api_pass" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
|
||||||
|
<h2>{$lang->sms}</h2>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="sms_default_from">{$lang->cmd_admin_default_from_phone}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="sms_default_from" id="sms_default_from" value="{escape(config('sms.default_from'))}" />
|
||||||
|
|
||||||
|
<label for="sms_force_default_sender" class="x_inline">
|
||||||
|
<input type="checkbox" name="sms_force_default_sender" id="sms_force_default_sender" value="Y" checked="checked"|cond="config('sms.default_force') !== false" />
|
||||||
|
{$lang->cmd_admin_force_default_sender}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_default_from_phone_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="sms_driver">{$lang->cmd_admin_sending_method}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<select name="sms_driver" id="sms_driver">
|
||||||
|
<!--@foreach($sms_drivers as $driver_name => $driver_definition)-->
|
||||||
|
<option value="{$driver_name}" selected="selected"|cond="$sms_driver === $driver_name">{$driver_definition['name']}</option>
|
||||||
|
<!--@end-->
|
||||||
|
</select>
|
||||||
|
<p class="x_help-block hidden-by-default show-for-dummy">
|
||||||
|
{$lang->cmd_admin_sms_dummy_driver_help}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--@foreach($sms_drivers as $driver_name => $driver_definition)-->
|
||||||
|
|
||||||
|
{@ $conf_names = array_merge($driver_definition['required'], $driver_definition['optional'])}
|
||||||
|
|
||||||
|
<!--@foreach($conf_names as $conf_name)-->
|
||||||
|
|
||||||
|
{@ $conf_value = escape(config("sms.$driver_name.$conf_name"))}
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_key')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="sms_{$driver_name}_api_key">{$lang->cmd_advanced_mailer_api_key}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="sms_{$driver_name}_api_key" id="sms_{$driver_name}_api_key" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'api_secret')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="sms_{$driver_name}_api_secret">{$lang->cmd_advanced_mailer_api_secret}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="password" name="sms_{$driver_name}_api_secret" id="sms_{$driver_name}_api_secret" value="{$conf_value}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@if($conf_name === 'sender_key')-->
|
||||||
|
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
||||||
|
<label class="x_control-label" for="sms_{$driver_name}_sender_key">{$lang->cmd_advanced_mailer_sender_key}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" name="sms_{$driver_name}_sender_key" id="sms_{$driver_name}_sender_key" value="{$conf_value}" />
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_sms_sender_key_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<!--@end-->
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label">{$lang->cmd_admin_allow_split_sms}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<label for="allow_split_sms_y" class="x_inline">
|
||||||
|
<input type="radio" name="allow_split_sms" id="allow_split_sms_y" value="Y" checked="checked"|cond="config('sms.allow_split.sms') !== false" />
|
||||||
|
{$lang->cmd_yes}
|
||||||
|
</label>
|
||||||
|
<label for="allow_split_sms_n" class="x_inline">
|
||||||
|
<input type="radio" name="allow_split_sms" id="allow_split_sms_n" value="N" checked="checked"|cond="config('sms.allow_split.sms') === false" />
|
||||||
|
{$lang->cmd_no}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_allow_split_sms_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label">{$lang->cmd_admin_allow_split_lms}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<label for="allow_split_lms_y" class="x_inline">
|
||||||
|
<input type="radio" name="allow_split_lms" id="allow_split_lms_y" value="Y" checked="checked"|cond="config('sms.allow_split.lms') !== false" />
|
||||||
|
{$lang->cmd_yes}
|
||||||
|
</label>
|
||||||
|
<label for="allow_split_lms_n" class="x_inline">
|
||||||
|
<input type="radio" name="allow_split_lms" id="allow_split_lms_n" value="N" checked="checked"|cond="config('sms.allow_split.lms') === false" />
|
||||||
|
{$lang->cmd_no}
|
||||||
|
</label>
|
||||||
|
<br />
|
||||||
|
<p class="x_help-block">{$lang->cmd_admin_allow_split_lms_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="x_clearfix btnArea">
|
||||||
|
<div class="x_pull-right">
|
||||||
|
<button type="submit" class="x_btn x_btn-primary">{$lang->cmd_save}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
@ -19,6 +19,12 @@
|
||||||
<textarea name="mediafilter_object" id="mediafilter_object" rows="8" style="width:100%;">{$mediafilter_object}</textarea>
|
<textarea name="mediafilter_object" id="mediafilter_object" rows="8" style="width:100%;">{$mediafilter_object}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="mediafilter_classes">HTML class</label>
|
||||||
|
<div class="x_controls" style="margin-right:14px">
|
||||||
|
<textarea name="mediafilter_classes" id="mediafilter_classes" rows="4" style="width:100%;">{$mediafilter_classes}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="x_control-group">
|
<div class="x_control-group">
|
||||||
<label class="x_control-label" for="admin_allowed_ip">{$lang->admin_ip_allow}</label>
|
<label class="x_control-label" for="admin_allowed_ip">{$lang->admin_ip_allow}</label>
|
||||||
<div class="x_controls">
|
<div class="x_controls">
|
||||||
|
|
|
||||||
82
modules/admin/tpl/js/notification_config.js
Normal file
82
modules/admin/tpl/js/notification_config.js
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
$("#mail_driver").on("change", function() {
|
||||||
|
var selected_driver = $(this).val();
|
||||||
|
$(this).parents("section").find("div.x_control-group.hidden-by-default, p.x_help-block.hidden-by-default").each(function() {
|
||||||
|
if ($(this).hasClass("show-for-" + selected_driver)) {
|
||||||
|
$(this).show();
|
||||||
|
} else {
|
||||||
|
$(this).hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).triggerHandler("change");
|
||||||
|
|
||||||
|
$("#sms_driver").on("change", function() {
|
||||||
|
var selected_driver = $(this).val();
|
||||||
|
$(this).parents("section").find("div.x_control-group.hidden-by-default, p.x_help-block.hidden-by-default").each(function() {
|
||||||
|
if ($(this).hasClass("show-for-" + selected_driver)) {
|
||||||
|
$(this).show();
|
||||||
|
} else {
|
||||||
|
$(this).hide();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).triggerHandler("change");
|
||||||
|
|
||||||
|
$("#mail_smtp_manual_entry").on("change", function() {
|
||||||
|
var auto_fill = $(this).val();
|
||||||
|
if (auto_fill === 'gmail') {
|
||||||
|
$("#mail_smtp_smtp_host").val('smtp.gmail.com');
|
||||||
|
$("#mail_smtp_smtp_port").val('465');
|
||||||
|
$("#mail_smtp_security_ssl").prop("checked", true).parent().addClass("checked");
|
||||||
|
$("#mail_smtp_security_tls").parent().removeClass("checked");
|
||||||
|
$("#mail_smtp_security_none").parent().removeClass("checked");
|
||||||
|
$("#mail_force_default_sender").prop("checked", true).parent().addClass("checked");
|
||||||
|
}
|
||||||
|
if (auto_fill === 'hanmail') {
|
||||||
|
$("#mail_smtp_smtp_host").val('smtp.daum.net');
|
||||||
|
$("#mail_smtp_smtp_port").val('465');
|
||||||
|
$("#mail_smtp_security_ssl").prop("checked", true).parent().addClass("checked");
|
||||||
|
$("#mail_smtp_security_tls").parent().removeClass("checked");
|
||||||
|
$("#mail_smtp_security_none").parent().removeClass("checked");
|
||||||
|
$("#mail_force_default_sender").prop("checked", true).parent().addClass("checked");
|
||||||
|
}
|
||||||
|
if (auto_fill === 'naver') {
|
||||||
|
$("#mail_smtp_smtp_host").val('smtp.naver.com');
|
||||||
|
$("#mail_smtp_smtp_port").val('587');
|
||||||
|
$("#mail_smtp_security_tls").prop("checked", true).parent().addClass("checked");
|
||||||
|
$("#mail_smtp_security_ssl").parent().removeClass("checked");
|
||||||
|
$("#mail_smtp_security_none").parent().removeClass("checked");
|
||||||
|
$("#mail_force_default_sender").prop("checked", true).parent().addClass("checked");
|
||||||
|
}
|
||||||
|
if (auto_fill === 'worksmobile') {
|
||||||
|
$("#mail_smtp_smtp_host").val('smtp.worksmobile.com');
|
||||||
|
$("#mail_smtp_smtp_port").val('587');
|
||||||
|
$("#mail_smtp_security_tls").prop("checked", true).parent().addClass("checked");
|
||||||
|
$("#mail_smtp_security_ssl").parent().removeClass("checked");
|
||||||
|
$("#mail_smtp_security_none").parent().removeClass("checked");
|
||||||
|
$("#mail_force_default_sender").prop("checked", true).parent().addClass("checked");
|
||||||
|
}
|
||||||
|
if (auto_fill === 'outlook') {
|
||||||
|
$("#mail_smtp_smtp_host").val('smtp-mail.outlook.com');
|
||||||
|
$("#mail_smtp_smtp_port").val('587');
|
||||||
|
$("#mail_smtp_security_tls").prop("checked", true).parent().addClass("checked");
|
||||||
|
$("#mail_smtp_security_ssl").parent().removeClass("checked");
|
||||||
|
$("#mail_smtp_security_none").parent().removeClass("checked");
|
||||||
|
$("#mail_force_default_sender").prop("checked", true).parent().addClass("checked");
|
||||||
|
}
|
||||||
|
if (auto_fill === 'yahoo') {
|
||||||
|
$("#mail_smtp_smtp_host").val('smtp.mail.yahoo.com');
|
||||||
|
$("#mail_smtp_smtp_port").val('465');
|
||||||
|
$("#mail_smtp_security_ssl").prop("checked", true).parent().addClass("checked");
|
||||||
|
$("#mail_smtp_security_tls").parent().removeClass("checked");
|
||||||
|
$("#mail_smtp_security_none").parent().removeClass("checked");
|
||||||
|
$("#mail_force_default_sender").prop("checked", true).parent().addClass("checked");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
} (jQuery));
|
||||||
|
|
@ -15,51 +15,13 @@ class Advanced_MailerAdminController extends Advanced_Mailer
|
||||||
{
|
{
|
||||||
// Get and validate the new configuration.
|
// Get and validate the new configuration.
|
||||||
$vars = Context::getRequestVars();
|
$vars = Context::getRequestVars();
|
||||||
if (!$vars->sender_name)
|
|
||||||
{
|
|
||||||
return new Object(-1, 'msg_advanced_mailer_sender_name_is_empty');
|
|
||||||
}
|
|
||||||
if (!$vars->sender_email)
|
|
||||||
{
|
|
||||||
return new Object(-1, 'msg_advanced_mailer_sender_email_is_empty');
|
|
||||||
}
|
|
||||||
if (!Mail::isVaildMailAddress($vars->sender_email))
|
|
||||||
{
|
|
||||||
return new Object(-1, 'msg_advanced_mailer_sender_email_is_invalid');
|
|
||||||
}
|
|
||||||
if ($vars->reply_to && !Mail::isVaildMailAddress($vars->reply_to))
|
|
||||||
{
|
|
||||||
return new Object(-1, 'msg_advanced_mailer_reply_to_is_invalid');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the sending method.
|
|
||||||
$sending_methods = Rhymix\Framework\Mail::getSupportedDrivers();
|
|
||||||
$sending_method = $vars->sending_method;
|
|
||||||
if (!array_key_exists($sending_method, $sending_methods))
|
|
||||||
{
|
|
||||||
return new Object(-1, 'msg_advanced_mailer_sending_method_is_invalid');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the configuration for the selected sending method.
|
|
||||||
$sending_method_config = array();
|
|
||||||
foreach ($sending_methods[$sending_method]['required'] as $conf_name)
|
|
||||||
{
|
|
||||||
$conf_value = $vars->{$sending_method . '_' . $conf_name} ?: null;
|
|
||||||
if (!$conf_value)
|
|
||||||
{
|
|
||||||
return new Object(-1, 'msg_advanced_mailer_smtp_host_is_invalid');
|
|
||||||
}
|
|
||||||
$sending_method_config[$conf_name] = $conf_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the current module's configuration.
|
// Update the current module's configuration.
|
||||||
$config = $this->getConfig();
|
$config = $this->getConfig();
|
||||||
$config->sender_name = $vars->sender_name;
|
|
||||||
$config->sender_email = $vars->sender_email;
|
|
||||||
$config->reply_to = $vars->reply_to;
|
|
||||||
$config->force_sender = toBool($vars->force_sender);
|
|
||||||
$config->log_sent_mail = toBool($vars->log_sent_mail);
|
$config->log_sent_mail = toBool($vars->log_sent_mail);
|
||||||
$config->log_errors = toBool($vars->log_errors);
|
$config->log_errors = toBool($vars->log_errors);
|
||||||
|
$config->log_sent_sms = toBool($vars->log_sent_sms);
|
||||||
|
$config->log_sms_errors = toBool($vars->log_sms_errors);
|
||||||
$output = getController('module')->insertModuleConfig('advanced_mailer', $config);
|
$output = getController('module')->insertModuleConfig('advanced_mailer', $config);
|
||||||
if ($output->toBool())
|
if ($output->toBool())
|
||||||
{
|
{
|
||||||
|
|
@ -70,17 +32,6 @@ class Advanced_MailerAdminController extends Advanced_Mailer
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the webmaster's name and email in the member module.
|
|
||||||
getController('module')->updateModuleConfig('member', (object)array(
|
|
||||||
'webmaster_name' => $config->sender_name,
|
|
||||||
'webmaster_email' => $config->sender_email,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Update system configuration.
|
|
||||||
Rhymix\Framework\Config::set("mail.type", $sending_method);
|
|
||||||
Rhymix\Framework\Config::set("mail.$sending_method", $sending_method_config);
|
|
||||||
Rhymix\Framework\Config::save();
|
|
||||||
|
|
||||||
if (Context::get('success_return_url'))
|
if (Context::get('success_return_url'))
|
||||||
{
|
{
|
||||||
$this->setRedirectUrl(Context::get('success_return_url'));
|
$this->setRedirectUrl(Context::get('success_return_url'));
|
||||||
|
|
@ -198,7 +149,7 @@ class Advanced_MailerAdminController extends Advanced_Mailer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear old sending log.
|
* Clear old mail sending log.
|
||||||
*/
|
*/
|
||||||
public function procAdvanced_mailerAdminClearSentMail()
|
public function procAdvanced_mailerAdminClearSentMail()
|
||||||
{
|
{
|
||||||
|
|
@ -216,22 +167,53 @@ class Advanced_MailerAdminController extends Advanced_Mailer
|
||||||
$obj = new stdClass();
|
$obj = new stdClass();
|
||||||
$obj->status = $status;
|
$obj->status = $status;
|
||||||
$obj->regdate = date('YmdHis', time() - ($clear_before_days * 86400) + zgap());
|
$obj->regdate = date('YmdHis', time() - ($clear_before_days * 86400) + zgap());
|
||||||
$output = executeQuery('advanced_mailer.deleteLogs', $obj);
|
$output = executeQuery('advanced_mailer.deleteMailLogs', $obj);
|
||||||
|
|
||||||
if ($status === 'success')
|
if ($status === 'success')
|
||||||
{
|
{
|
||||||
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSentMail'));
|
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminMailLog'));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminErrors'));
|
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminMailErrors'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a test email using a temporary configuration.
|
* Clear old SMS sending log.
|
||||||
*/
|
*/
|
||||||
public function procAdvanced_MailerAdminTestSend()
|
public function procAdvanced_mailerAdminClearSentSMS()
|
||||||
|
{
|
||||||
|
$status = Context::get('status');
|
||||||
|
$clear_before_days = intval(Context::get('clear_before_days'));
|
||||||
|
if (!in_array($status, array('success', 'error')))
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_invalid_request');
|
||||||
|
}
|
||||||
|
if ($clear_before_days < 0)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_invalid_request');
|
||||||
|
}
|
||||||
|
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->status = $status;
|
||||||
|
$obj->regdate = date('YmdHis', time() - ($clear_before_days * 86400) + zgap());
|
||||||
|
$output = executeQuery('advanced_mailer.deleteSMSLogs', $obj);
|
||||||
|
|
||||||
|
if ($status === 'success')
|
||||||
|
{
|
||||||
|
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSMSLog'));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->setRedirectUrl(getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSMSErrors'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a test mail.
|
||||||
|
*/
|
||||||
|
public function procAdvanced_MailerAdminTestSendMail()
|
||||||
{
|
{
|
||||||
$advanced_mailer_config = $this->getConfig();
|
$advanced_mailer_config = $this->getConfig();
|
||||||
$recipient_config = Context::gets('recipient_name', 'recipient_email');
|
$recipient_config = Context::gets('recipient_name', 'recipient_email');
|
||||||
|
|
@ -268,23 +250,23 @@ class Advanced_MailerAdminController extends Advanced_Mailer
|
||||||
|
|
||||||
if (!$result)
|
if (!$result)
|
||||||
{
|
{
|
||||||
if (count($oMail->errors))
|
if (count($oMail->getErrors()))
|
||||||
{
|
{
|
||||||
if (config('mail.type') === 'smtp')
|
if (config('mail.type') === 'smtp')
|
||||||
{
|
{
|
||||||
if (strpos(config('mail.smtp.smtp_host'), 'gmail.com') !== false && strpos(implode("\n", $oMail->errors), 'code "535"') !== false)
|
if (strpos(config('mail.smtp.smtp_host'), 'gmail.com') !== false && strpos(implode("\n", $oMail->getErrors()), 'code "535"') !== false)
|
||||||
{
|
{
|
||||||
$this->add('test_result', Context::getLang('msg_advanced_mailer_google_account_security'));
|
$this->add('test_result', Context::getLang('msg_advanced_mailer_google_account_security'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (strpos(config('mail.smtp.smtp_host'), 'naver.com') !== false && strpos(implode("\n", $oMail->errors), 'Failed to authenticate') !== false)
|
if (strpos(config('mail.smtp.smtp_host'), 'naver.com') !== false && strpos(implode("\n", $oMail->getErrors()), 'Failed to authenticate') !== false)
|
||||||
{
|
{
|
||||||
$this->add('test_result', Context::getLang('msg_advanced_mailer_naver_smtp_disabled'));
|
$this->add('test_result', Context::getLang('msg_advanced_mailer_naver_smtp_disabled'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->add('test_result', nl2br(htmlspecialchars(implode("\n", $oMail->errors))));
|
$this->add('test_result', nl2br(htmlspecialchars(implode("\n", $oMail->getErrors()))));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -303,4 +285,56 @@ class Advanced_MailerAdminController extends Advanced_Mailer
|
||||||
$this->add('test_result', Context::getLang('msg_advanced_mailer_test_success'));
|
$this->add('test_result', Context::getLang('msg_advanced_mailer_test_success'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a test SMS.
|
||||||
|
*/
|
||||||
|
public function procAdvanced_MailerAdminTestSendSMS()
|
||||||
|
{
|
||||||
|
$advanced_mailer_config = $this->getConfig();
|
||||||
|
$recipient_number = Context::get('recipient_number');
|
||||||
|
$country_code = intval(Context::get('country_code'));
|
||||||
|
$content = trim(Context::get('content'));
|
||||||
|
|
||||||
|
if (!$recipient_number)
|
||||||
|
{
|
||||||
|
$this->add('test_result', 'Error: ' . Context::getLang('msg_advanced_mailer_recipient_number_is_empty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!$content)
|
||||||
|
{
|
||||||
|
$this->add('test_result', 'Error: ' . Context::getLang('msg_advanced_mailer_content_is_empty'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$oSMS = new Rhymix\Framework\SMS();
|
||||||
|
$oSMS->addTo($recipient_number, $country_code);
|
||||||
|
$oSMS->setBody($content);
|
||||||
|
$result = $oSMS->send();
|
||||||
|
|
||||||
|
if (!$result)
|
||||||
|
{
|
||||||
|
if (count($oSMS->getErrors()))
|
||||||
|
{
|
||||||
|
$this->add('test_result', nl2br(htmlspecialchars(implode("\n", $oSMS->getErrors()))));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->add('test_result', Context::getLang('msg_advanced_mailer_unknown_error'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception $e)
|
||||||
|
{
|
||||||
|
$this->add('test_result', nl2br(htmlspecialchars($e->getMessage())));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->add('test_result', Context::getLang('msg_advanced_mailer_test_success_sms'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,7 @@ class Advanced_MailerAdminView extends Advanced_Mailer
|
||||||
public function dispAdvanced_MailerAdminConfig()
|
public function dispAdvanced_MailerAdminConfig()
|
||||||
{
|
{
|
||||||
$advanced_mailer_config = $this->getConfig();
|
$advanced_mailer_config = $this->getConfig();
|
||||||
$member_config = getModel('module')->getModuleConfig('member');
|
|
||||||
$sending_methods = Rhymix\Framework\Mail::getSupportedDrivers();
|
|
||||||
|
|
||||||
Context::set('advanced_mailer_config', $advanced_mailer_config);
|
Context::set('advanced_mailer_config', $advanced_mailer_config);
|
||||||
Context::set('sending_methods', $sending_methods);
|
|
||||||
Context::set('sending_method', config('mail.type'));
|
|
||||||
Context::set('webmaster_name', $member_config->webmaster_name ? $member_config->webmaster_name : 'webmaster');
|
|
||||||
Context::set('webmaster_email', $member_config->webmaster_email);
|
|
||||||
|
|
||||||
$this->setTemplatePath($this->module_path.'tpl');
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
$this->setTemplateFile('config');
|
$this->setTemplateFile('config');
|
||||||
|
|
@ -117,9 +110,9 @@ class Advanced_MailerAdminView extends Advanced_Mailer
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the test send form.
|
* Display the mail test form.
|
||||||
*/
|
*/
|
||||||
public function dispAdvanced_MailerAdminTestConfig()
|
public function dispAdvanced_MailerAdminMailTest()
|
||||||
{
|
{
|
||||||
$advanced_mailer_config = $this->getConfig();
|
$advanced_mailer_config = $this->getConfig();
|
||||||
$sending_methods = Rhymix\Framework\Mail::getSupportedDrivers();
|
$sending_methods = Rhymix\Framework\Mail::getSupportedDrivers();
|
||||||
|
|
@ -129,23 +122,23 @@ class Advanced_MailerAdminView extends Advanced_Mailer
|
||||||
Context::set('sending_method', config('mail.type'));
|
Context::set('sending_method', config('mail.type'));
|
||||||
|
|
||||||
$this->setTemplatePath($this->module_path.'tpl');
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
$this->setTemplateFile('test');
|
$this->setTemplateFile('mail_test');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the sent mail log.
|
* Display the mail log.
|
||||||
*/
|
*/
|
||||||
public function dispAdvanced_MailerAdminSentMail()
|
public function dispAdvanced_MailerAdminMailLog()
|
||||||
{
|
{
|
||||||
$obj = new stdClass();
|
$obj = new stdClass();
|
||||||
$obj->status = 'success';
|
$obj->status = 'success';
|
||||||
$obj->page = $page = Context::get('page') ?: 1;
|
$obj->page = $page = Context::get('page') ?: 1;
|
||||||
$maillog = executeQuery('advanced_mailer.getLogByType', $obj);
|
$maillog = executeQueryArray('advanced_mailer.getMailLogByType', $obj);
|
||||||
$maillog = $maillog->toBool() ? $this->procMailLog($maillog->data) : array();
|
$maillog = $maillog->toBool() ? $this->procMailLog($maillog->data) : array();
|
||||||
Context::set('advanced_mailer_log', $maillog);
|
Context::set('advanced_mailer_log', $maillog);
|
||||||
Context::set('advanced_mailer_status', 'success');
|
Context::set('advanced_mailer_status', 'success');
|
||||||
|
|
||||||
$paging = $this->procPaging('success', $page);
|
$paging = $this->procPaging('success', 'mail', $page);
|
||||||
Context::set('total_count', $paging->total_count);
|
Context::set('total_count', $paging->total_count);
|
||||||
Context::set('total_page', $paging->total_page);
|
Context::set('total_page', $paging->total_page);
|
||||||
Context::set('page', $paging->page);
|
Context::set('page', $paging->page);
|
||||||
|
|
@ -155,23 +148,23 @@ class Advanced_MailerAdminView extends Advanced_Mailer
|
||||||
Context::set('sending_methods', $sending_methods);
|
Context::set('sending_methods', $sending_methods);
|
||||||
|
|
||||||
$this->setTemplatePath($this->module_path.'tpl');
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
$this->setTemplateFile('view_log');
|
$this->setTemplateFile('mail_log');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the error log.
|
* Display the mail error log.
|
||||||
*/
|
*/
|
||||||
public function dispAdvanced_MailerAdminErrors()
|
public function dispAdvanced_MailerAdminMailErrors()
|
||||||
{
|
{
|
||||||
$obj = new stdClass();
|
$obj = new stdClass();
|
||||||
$obj->status = 'error';
|
$obj->status = 'error';
|
||||||
$obj->page = $page = Context::get('page') ?: 1;
|
$obj->page = $page = Context::get('page') ?: 1;
|
||||||
$maillog = executeQuery('advanced_mailer.getLogByType', $obj);
|
$maillog = executeQueryArray('advanced_mailer.getMailLogByType', $obj);
|
||||||
$maillog = $maillog->toBool() ? $this->procMailLog($maillog->data) : array();
|
$maillog = $maillog->toBool() ? $this->procMailLog($maillog->data) : array();
|
||||||
Context::set('advanced_mailer_log', $maillog);
|
Context::set('advanced_mailer_log', $maillog);
|
||||||
Context::set('advanced_mailer_status', 'error');
|
Context::set('advanced_mailer_status', 'error');
|
||||||
|
|
||||||
$paging = $this->procPaging('error', $page);
|
$paging = $this->procPaging('error', 'mail', $page);
|
||||||
Context::set('total_count', $paging->total_count);
|
Context::set('total_count', $paging->total_count);
|
||||||
Context::set('total_page', $paging->total_page);
|
Context::set('total_page', $paging->total_page);
|
||||||
Context::set('page', $paging->page);
|
Context::set('page', $paging->page);
|
||||||
|
|
@ -181,7 +174,75 @@ class Advanced_MailerAdminView extends Advanced_Mailer
|
||||||
Context::set('sending_methods', $sending_methods);
|
Context::set('sending_methods', $sending_methods);
|
||||||
|
|
||||||
$this->setTemplatePath($this->module_path.'tpl');
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
$this->setTemplateFile('view_log');
|
$this->setTemplateFile('mail_log');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the SMS test form.
|
||||||
|
*/
|
||||||
|
public function dispAdvanced_MailerAdminSMSTest()
|
||||||
|
{
|
||||||
|
$advanced_mailer_config = $this->getConfig();
|
||||||
|
$sending_methods = Rhymix\Framework\Mail::getSupportedDrivers();
|
||||||
|
|
||||||
|
Context::set('advanced_mailer_config', $advanced_mailer_config);
|
||||||
|
Context::set('sending_methods', $sending_methods);
|
||||||
|
Context::set('sending_method', config('mail.type'));
|
||||||
|
|
||||||
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
|
$this->setTemplateFile('sms_test');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the SMS log.
|
||||||
|
*/
|
||||||
|
public function dispAdvanced_MailerAdminSMSLog()
|
||||||
|
{
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->status = 'success';
|
||||||
|
$obj->page = $page = Context::get('page') ?: 1;
|
||||||
|
$smslog = executeQueryArray('advanced_mailer.getSMSLogByType', $obj);
|
||||||
|
$smslog = $smslog->toBool() ? $smslog->data : array();
|
||||||
|
Context::set('advanced_mailer_log', $smslog);
|
||||||
|
Context::set('advanced_mailer_status', 'success');
|
||||||
|
|
||||||
|
$paging = $this->procPaging('success', 'sms', $page);
|
||||||
|
Context::set('total_count', $paging->total_count);
|
||||||
|
Context::set('total_page', $paging->total_page);
|
||||||
|
Context::set('page', $paging->page);
|
||||||
|
Context::set('page_navigation', $paging->page_navigation);
|
||||||
|
|
||||||
|
$sending_methods = Rhymix\Framework\SMS::getSupportedDrivers();
|
||||||
|
Context::set('sending_methods', $sending_methods);
|
||||||
|
|
||||||
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
|
$this->setTemplateFile('sms_log');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the SMS error log.
|
||||||
|
*/
|
||||||
|
public function dispAdvanced_MailerAdminSMSErrors()
|
||||||
|
{
|
||||||
|
$obj = new stdClass();
|
||||||
|
$obj->status = 'error';
|
||||||
|
$obj->page = $page = Context::get('page') ?: 1;
|
||||||
|
$smslog = executeQueryArray('advanced_mailer.getSMSLogByType', $obj);
|
||||||
|
$smslog = $smslog->toBool() ? $smslog->data : array();
|
||||||
|
Context::set('advanced_mailer_log', $smslog);
|
||||||
|
Context::set('advanced_mailer_status', 'error');
|
||||||
|
|
||||||
|
$paging = $this->procPaging('error', 'sms', $page);
|
||||||
|
Context::set('total_count', $paging->total_count);
|
||||||
|
Context::set('total_page', $paging->total_page);
|
||||||
|
Context::set('page', $paging->page);
|
||||||
|
Context::set('page_navigation', $paging->page_navigation);
|
||||||
|
|
||||||
|
$sending_methods = Rhymix\Framework\SMS::getSupportedDrivers();
|
||||||
|
Context::set('sending_methods', $sending_methods);
|
||||||
|
|
||||||
|
$this->setTemplatePath($this->module_path.'tpl');
|
||||||
|
$this->setTemplateFile('sms_log');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -226,11 +287,18 @@ class Advanced_MailerAdminView extends Advanced_Mailer
|
||||||
/**
|
/**
|
||||||
* Process paging.
|
* Process paging.
|
||||||
*/
|
*/
|
||||||
public function procPaging($status, $page = 1)
|
public function procPaging($status, $type, $page = 1)
|
||||||
{
|
{
|
||||||
$args = new stdClass;
|
$args = new stdClass;
|
||||||
$args->status = $status;
|
$args->status = $status;
|
||||||
$count = executeQuery('advanced_mailer.countLogByType', $args);
|
if ($type === 'mail')
|
||||||
|
{
|
||||||
|
$count = executeQuery('advanced_mailer.countMailLogByType', $args);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$count = executeQuery('advanced_mailer.countSMSLogByType', $args);
|
||||||
|
}
|
||||||
$total_count = $count->data->count;
|
$total_count = $count->data->count;
|
||||||
$total_page = max(1, ceil($total_count / 20));
|
$total_page = max(1, ceil($total_count / 20));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,10 @@ class Advanced_Mailer extends ModuleObject
|
||||||
{
|
{
|
||||||
$oModuleController->insertTrigger('mail.send', 'advanced_mailer', 'controller', 'triggerAfterMailSend', 'after');
|
$oModuleController->insertTrigger('mail.send', 'advanced_mailer', 'controller', 'triggerAfterMailSend', 'after');
|
||||||
}
|
}
|
||||||
|
if (!$oModuleModel->getTrigger('sms.send', 'advanced_mailer', 'controller', 'triggerAfterSMSSend', 'after'))
|
||||||
|
{
|
||||||
|
$oModuleController->insertTrigger('sms.send', 'advanced_mailer', 'controller', 'triggerAfterSMSSend', 'after');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -225,6 +229,10 @@ class Advanced_Mailer extends ModuleObject
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (!$oModuleModel->getTrigger('sms.send', 'advanced_mailer', 'controller', 'triggerAfterSMSSend', 'after'))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,6 @@ class Advanced_MailerController extends Advanced_Mailer
|
||||||
if (toBool($config->log_sent_mail) || (toBool($config->log_errors) && count($mail->errors)))
|
if (toBool($config->log_sent_mail) || (toBool($config->log_errors) && count($mail->errors)))
|
||||||
{
|
{
|
||||||
$obj = new \stdClass();
|
$obj = new \stdClass();
|
||||||
$obj->mail_srl = getNextSequence();
|
|
||||||
$obj->mail_from = '';
|
$obj->mail_from = '';
|
||||||
$obj->mail_to = '';
|
$obj->mail_to = '';
|
||||||
|
|
||||||
|
|
@ -99,9 +98,9 @@ class Advanced_MailerController extends Advanced_Mailer
|
||||||
$obj->subject = $mail->message->getSubject();
|
$obj->subject = $mail->message->getSubject();
|
||||||
$obj->calling_script = $mail->getCaller();
|
$obj->calling_script = $mail->getCaller();
|
||||||
$obj->sending_method = strtolower(class_basename($mail->driver));
|
$obj->sending_method = strtolower(class_basename($mail->driver));
|
||||||
$obj->status = !count($mail->errors) ? 'success' : 'error';
|
$obj->status = !count($mail->getErrors()) ? 'success' : 'error';
|
||||||
$obj->errors = count($mail->errors) ? implode("\n", $mail->errors) : null;
|
$obj->errors = count($mail->getErrors()) ? implode("\n", $mail->getErrors()) : null;
|
||||||
$output = executeQuery('advanced_mailer.insertLog', $obj);
|
$output = executeQuery('advanced_mailer.insertMailLog', $obj);
|
||||||
if (!$output->toBool())
|
if (!$output->toBool())
|
||||||
{
|
{
|
||||||
return $output;
|
return $output;
|
||||||
|
|
@ -145,4 +144,41 @@ class Advanced_MailerController extends Advanced_Mailer
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After SMS send trigger.
|
||||||
|
*/
|
||||||
|
public function triggerAfterSMSSend($sms)
|
||||||
|
{
|
||||||
|
$config = $this->getConfig();
|
||||||
|
|
||||||
|
if (toBool($config->log_sent_sms) || (toBool($config->log_sms_errors) && count($sms->errors)))
|
||||||
|
{
|
||||||
|
$obj = new \stdClass();
|
||||||
|
$obj->sms_from = $sms->getFrom();
|
||||||
|
$obj->sms_to = array();
|
||||||
|
foreach ($sms->getRecipientsWithCountry() as $to)
|
||||||
|
{
|
||||||
|
if ($to->country)
|
||||||
|
{
|
||||||
|
$obj->sms_to[] = '+' . $to->country . '.' . $to->number;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$obj->sms_to[] = $to->number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$obj->sms_to = implode(', ', $obj->sms_to);
|
||||||
|
$obj->content = trim($sms->getSubject() . "\n" . $sms->getBody());
|
||||||
|
$obj->calling_script = $sms->getCaller();
|
||||||
|
$obj->sending_method = strtolower(class_basename($sms->driver));
|
||||||
|
$obj->status = !count($sms->getErrors()) ? 'success' : 'error';
|
||||||
|
$obj->errors = count($sms->getErrors()) ? implode("\n", $sms->getErrors()) : null;
|
||||||
|
$output = executeQuery('advanced_mailer.insertSMSLog', $obj);
|
||||||
|
if (!$output->toBool())
|
||||||
|
{
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module version="0.2">
|
<module version="0.2">
|
||||||
<title xml:lang="ko">고급 메일 발송 모듈</title>
|
<title xml:lang="ko">고급 메일 발송 모듈 (메일 및 SMS 관리)</title>
|
||||||
<title xml:lang="en">Advanced Mailer</title>
|
<title xml:lang="en">Advanced Mailer (with SMS)</title>
|
||||||
<description xml:lang="ko">
|
<description xml:lang="ko">
|
||||||
외부 SMTP 서버 또는 API를 사용하여 메일을 발송합니다.
|
라이믹스에서 발송하는 메일과 SMS를 기록하고 테스트하는 기능을 제공합니다.
|
||||||
</description>
|
</description>
|
||||||
<description xml:lang="en">
|
<description xml:lang="en">
|
||||||
Send mail using an external SMTP server or API service.
|
Log and test e-mails and SMS sent from Rhymix.
|
||||||
</description>
|
</description>
|
||||||
<version>2.0.0</version>
|
<version>2.1.0</version>
|
||||||
<date>2016-05-22</date>
|
<date>2016-12-14</date>
|
||||||
<author email_address="kijin@kijinsung.com" link="https://github.com/kijin">
|
<author link="https://www.poesis.org">
|
||||||
<name xml:lang="ko">Kijin Sung</name>
|
<name xml:lang="ko">포에시스</name>
|
||||||
<name xml:lang="en">Kijin Sung</name>
|
<name xml:lang="en">POESIS</name>
|
||||||
</author>
|
</author>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,19 @@
|
||||||
<action name="dispAdvanced_mailerAdminConfig" type="view" admin_index="true" menu_name="advanced_mailer" />
|
<action name="dispAdvanced_mailerAdminConfig" type="view" admin_index="true" menu_name="advanced_mailer" />
|
||||||
<action name="dispAdvanced_mailerAdminExceptions" type="view" />
|
<action name="dispAdvanced_mailerAdminExceptions" type="view" />
|
||||||
<action name="dispAdvanced_mailerAdminSpfDkim" type="view" />
|
<action name="dispAdvanced_mailerAdminSpfDkim" type="view" />
|
||||||
<action name="dispAdvanced_mailerAdminTestConfig" type="view" />
|
<action name="dispAdvanced_mailerAdminMailTest" type="view" />
|
||||||
<action name="dispAdvanced_mailerAdminSentMail" type="view" />
|
<action name="dispAdvanced_mailerAdminMailLog" type="view" />
|
||||||
<action name="dispAdvanced_mailerAdminErrors" type="view" />
|
<action name="dispAdvanced_mailerAdminMailErrors" type="view" />
|
||||||
|
<action name="dispAdvanced_mailerAdminSMSTest" type="view" />
|
||||||
|
<action name="dispAdvanced_mailerAdminSMSLog" type="view" />
|
||||||
|
<action name="dispAdvanced_mailerAdminSMSErrors" type="view" />
|
||||||
<action name="procAdvanced_mailerAdminInsertConfig" type="controller" />
|
<action name="procAdvanced_mailerAdminInsertConfig" type="controller" />
|
||||||
<action name="procAdvanced_mailerAdminInsertExceptions" type="controller" />
|
<action name="procAdvanced_mailerAdminInsertExceptions" type="controller" />
|
||||||
<action name="procAdvanced_mailerAdminCheckDNSRecord" type="controller" />
|
<action name="procAdvanced_mailerAdminCheckDNSRecord" type="controller" />
|
||||||
<action name="procAdvanced_mailerAdminClearSentMail" type="controller" />
|
<action name="procAdvanced_mailerAdminClearSentMail" type="controller" />
|
||||||
<action name="procAdvanced_mailerAdminTestSend" type="controller" />
|
<action name="procAdvanced_mailerAdminClearSentSMS" type="controller" />
|
||||||
|
<action name="procAdvanced_mailerAdminTestSendMail" type="controller" />
|
||||||
|
<action name="procAdvanced_mailerAdminTestSendSMS" type="controller" />
|
||||||
</actions>
|
</actions>
|
||||||
<menus>
|
<menus>
|
||||||
<menu name="advanced_mailer" type="all">
|
<menu name="advanced_mailer" type="all">
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
$lang->cmd_advanced_mailer = 'Advanced Mailer';
|
$lang->cmd_advanced_mailer = 'Advanced Mailer (with SMS)';
|
||||||
$lang->cmd_advanced_mailer_general_config = 'General settings';
|
$lang->cmd_advanced_mailer_general_config = 'General settings';
|
||||||
$lang->cmd_advanced_mailer_is_enabled = 'Enable module';
|
$lang->cmd_advanced_mailer_is_enabled = 'Enable module';
|
||||||
$lang->cmd_advanced_mailer_is_enabled_yes = 'Enabled';
|
$lang->cmd_advanced_mailer_is_enabled_yes = 'Enabled';
|
||||||
$lang->cmd_advanced_mailer_is_enabled_no = 'Disabled';
|
$lang->cmd_advanced_mailer_is_enabled_no = 'Disabled';
|
||||||
$lang->cmd_advanced_mailer_logging = 'Logging';
|
$lang->cmd_advanced_mailer_logging = 'Logging';
|
||||||
$lang->cmd_advanced_mailer_log_sent_mail = 'Log Sent Mail';
|
$lang->cmd_advanced_mailer_log_mail = 'Log Mail';
|
||||||
$lang->cmd_advanced_mailer_log_errors = 'Log Errors';
|
$lang->cmd_advanced_mailer_log_mail_errors = 'Log Mail Errors';
|
||||||
|
$lang->cmd_advanced_mailer_log_sms = 'Log SMS';
|
||||||
|
$lang->cmd_advanced_mailer_log_sms_errors = 'Log SMS Errors';
|
||||||
$lang->cmd_advanced_mailer_log_yes = 'Yes';
|
$lang->cmd_advanced_mailer_log_yes = 'Yes';
|
||||||
$lang->cmd_advanced_mailer_log_no = 'No';
|
$lang->cmd_advanced_mailer_log_no = 'No';
|
||||||
$lang->cmd_advanced_mailer_sending_method_config = 'Default Sending Method';
|
$lang->cmd_advanced_mailer_sending_method_config = 'Default Sending Method';
|
||||||
$lang->cmd_advanced_mailer_about_sending_method_config = 'Please fill all of the boxes.';
|
$lang->cmd_advanced_mailer_about_sending_method_config = 'Please fill all of the boxes.';
|
||||||
$lang->cmd_advanced_mailer_sending_method = 'Sending method';
|
$lang->cmd_advanced_mailer_sending_method = 'Sending method';
|
||||||
$lang->cmd_advanced_mailer_about_sending_method = 'This method will be used for all emails where the recipient\'s email address does not belong to an <a href="./index.php?module=admin&act=dispAdvanced_mailerAdminExceptions" target="_blank">exception domain</a>.';
|
$lang->cmd_advanced_mailer_about_sending_method = 'You can change the default sending method in the <a href="index.php?module=admin&act=dispAdminConfigNotification" target="_blank">Notification Settings</a> screen.';
|
||||||
$lang->cmd_advanced_mailer_sending_method_default = 'Default sending method';
|
$lang->cmd_advanced_mailer_sending_method_default = 'Default sending method';
|
||||||
$lang->cmd_advanced_mailer_sending_method_exceptions = 'Exceptions';
|
$lang->cmd_advanced_mailer_sending_method_exceptions = 'Exceptions';
|
||||||
$lang->cmd_advanced_mailer_smtp_manual_entry = 'Manual entry';
|
$lang->cmd_advanced_mailer_smtp_manual_entry = 'Manual entry';
|
||||||
|
|
@ -24,6 +26,8 @@ $lang->cmd_advanced_mailer_smtp_security_tls = 'TLS (STARTTLS)';
|
||||||
$lang->cmd_advanced_mailer_smtp_security_none = 'None';
|
$lang->cmd_advanced_mailer_smtp_security_none = 'None';
|
||||||
$lang->cmd_advanced_mailer_smtp_user = 'Username';
|
$lang->cmd_advanced_mailer_smtp_user = 'Username';
|
||||||
$lang->cmd_advanced_mailer_smtp_pass = 'Password';
|
$lang->cmd_advanced_mailer_smtp_pass = 'Password';
|
||||||
|
$lang->cmd_advanced_mailer_api_key = 'API key';
|
||||||
|
$lang->cmd_advanced_mailer_api_secret = 'API secret';
|
||||||
$lang->cmd_advanced_mailer_api_domain = 'Domain';
|
$lang->cmd_advanced_mailer_api_domain = 'Domain';
|
||||||
$lang->cmd_advanced_mailer_api_token = 'API token';
|
$lang->cmd_advanced_mailer_api_token = 'API token';
|
||||||
$lang->cmd_advanced_mailer_api_type = 'API type';
|
$lang->cmd_advanced_mailer_api_type = 'API type';
|
||||||
|
|
@ -31,8 +35,9 @@ $lang->cmd_advanced_mailer_api_type_free = 'Free account';
|
||||||
$lang->cmd_advanced_mailer_api_type_paid = 'Paid account';
|
$lang->cmd_advanced_mailer_api_type_paid = 'Paid account';
|
||||||
$lang->cmd_advanced_mailer_api_user = 'Username';
|
$lang->cmd_advanced_mailer_api_user = 'Username';
|
||||||
$lang->cmd_advanced_mailer_api_pass = 'Password';
|
$lang->cmd_advanced_mailer_api_pass = 'Password';
|
||||||
|
$lang->cmd_advanced_mailer_sender_key = 'Sender key';
|
||||||
$lang->cmd_advanced_mailer_sender_identity = 'Sender Identity';
|
$lang->cmd_advanced_mailer_sender_identity = 'Sender Identity';
|
||||||
$lang->cmd_advanced_mailer_about_sender_identity = 'Sender identity will be applied to the webmaster\'s name and email address in the <a href="./index.php?module=admin&act=dispMemberAdminConfig" target="_blank">member module</a> as well.';
|
$lang->cmd_advanced_mailer_about_sender_identity = 'You can change the sender\'s name and e-mail address in the <a href="index.php?module=admin&act=dispAdminConfigNotification" target="_blank">Notification Settings</a> screen.';
|
||||||
$lang->cmd_advanced_mailer_sender_name = 'Sender\'s name';
|
$lang->cmd_advanced_mailer_sender_name = 'Sender\'s name';
|
||||||
$lang->cmd_advanced_mailer_sender_email = 'Sender\'s email';
|
$lang->cmd_advanced_mailer_sender_email = 'Sender\'s email';
|
||||||
$lang->cmd_advanced_mailer_reply_to = 'Reply-To email';
|
$lang->cmd_advanced_mailer_reply_to = 'Reply-To email';
|
||||||
|
|
@ -59,7 +64,7 @@ $lang->cmd_advanced_mailer_other_info_mailgun_dkim = 'The DKIM hostname may be d
|
||||||
$lang->cmd_advanced_mailer_other_info_postmark_dkim = 'Please see the Sender Signatures page of your Postmark account for the exact DKIm hostname to use.';
|
$lang->cmd_advanced_mailer_other_info_postmark_dkim = 'Please see the Sender Signatures page of your Postmark account for the exact DKIm hostname to use.';
|
||||||
$lang->cmd_advanced_mailer_other_info_woorimail_dkim = 'Please log into Woorimail to see your DKIM settings.';
|
$lang->cmd_advanced_mailer_other_info_woorimail_dkim = 'Please log into Woorimail to see your DKIM settings.';
|
||||||
$lang->cmd_advanced_mailer_ellipsis = '(see API for full value)';
|
$lang->cmd_advanced_mailer_ellipsis = '(see API for full value)';
|
||||||
$lang->cmd_advanced_mailer_test = 'Mail Test';
|
$lang->cmd_advanced_mailer_mail_test = 'Mail Test';
|
||||||
$lang->cmd_advanced_mailer_recipient_name = 'Recipient\'s name';
|
$lang->cmd_advanced_mailer_recipient_name = 'Recipient\'s name';
|
||||||
$lang->cmd_advanced_mailer_recipient_email = 'Recipient\'s email';
|
$lang->cmd_advanced_mailer_recipient_email = 'Recipient\'s email';
|
||||||
$lang->cmd_advanced_mailer_send = 'Send';
|
$lang->cmd_advanced_mailer_send = 'Send';
|
||||||
|
|
@ -102,6 +107,7 @@ $lang->msg_advanced_mailer_log_is_empty = 'There are no entries to display.';
|
||||||
$lang->cmd_advanced_mailer_status_sender = 'Sender';
|
$lang->cmd_advanced_mailer_status_sender = 'Sender';
|
||||||
$lang->cmd_advanced_mailer_status_recipient = 'Recipient';
|
$lang->cmd_advanced_mailer_status_recipient = 'Recipient';
|
||||||
$lang->cmd_advanced_mailer_status_subject = 'Subject';
|
$lang->cmd_advanced_mailer_status_subject = 'Subject';
|
||||||
|
$lang->cmd_advanced_mailer_status_content = 'Content';
|
||||||
$lang->cmd_advanced_mailer_status_sending_method = 'Method';
|
$lang->cmd_advanced_mailer_status_sending_method = 'Method';
|
||||||
$lang->cmd_advanced_mailer_status_time = 'Time';
|
$lang->cmd_advanced_mailer_status_time = 'Time';
|
||||||
$lang->cmd_advanced_mailer_status = 'Status';
|
$lang->cmd_advanced_mailer_status = 'Status';
|
||||||
|
|
@ -112,3 +118,11 @@ $lang->cmd_advanced_mailer_status_calling_script = 'Called from';
|
||||||
$lang->cmd_advanced_mailer_clear_log_condition_all = 'Everything';
|
$lang->cmd_advanced_mailer_clear_log_condition_all = 'Everything';
|
||||||
$lang->cmd_advanced_mailer_clear_log_condition = 'Over %d days';
|
$lang->cmd_advanced_mailer_clear_log_condition = 'Over %d days';
|
||||||
$lang->cmd_advanced_mailer_clear_log_button = 'Clear old logs';
|
$lang->cmd_advanced_mailer_clear_log_button = 'Clear old logs';
|
||||||
|
$lang->cmd_advanced_mailer_sms_test = 'SMS Test';
|
||||||
|
$lang->cmd_advanced_mailer_recipient_number = 'Recipient\'s number';
|
||||||
|
$lang->cmd_advanced_mailer_country_code = 'Country code';
|
||||||
|
$lang->cmd_advanced_mailer_country_code_help = 'Please leave the country code empty if you are sending to a domestic number.';
|
||||||
|
$lang->cmd_advanced_mailer_test_content = 'This is an SMS test from Rhymix.';
|
||||||
|
$lang->msg_advanced_mailer_recipient_number_is_empty = 'Please enter a phone number for the recipient.';
|
||||||
|
$lang->msg_advanced_mailer_content_is_empty = 'Please enter the content for your test SMS.';
|
||||||
|
$lang->msg_advanced_mailer_test_success_sms = 'The test was successful. Please check your SMS.';
|
||||||
|
|
@ -1,18 +1,20 @@
|
||||||
<?php
|
<?php
|
||||||
$lang->cmd_advanced_mailer = '고급 메일 발송 모듈';
|
$lang->cmd_advanced_mailer = '고급 메일 발송 모듈 (메일 및 SMS 관리)';
|
||||||
$lang->cmd_advanced_mailer_general_config = '기본 설정';
|
$lang->cmd_advanced_mailer_general_config = '기본 설정';
|
||||||
$lang->cmd_advanced_mailer_is_enabled = '모듈 사용';
|
$lang->cmd_advanced_mailer_is_enabled = '모듈 사용';
|
||||||
$lang->cmd_advanced_mailer_is_enabled_yes = '사용';
|
$lang->cmd_advanced_mailer_is_enabled_yes = '사용';
|
||||||
$lang->cmd_advanced_mailer_is_enabled_no = '사용하지 않음';
|
$lang->cmd_advanced_mailer_is_enabled_no = '사용하지 않음';
|
||||||
$lang->cmd_advanced_mailer_logging = '발송 내역 기록';
|
$lang->cmd_advanced_mailer_logging = '발송 내역 기록';
|
||||||
$lang->cmd_advanced_mailer_log_sent_mail = '발송 내역';
|
$lang->cmd_advanced_mailer_log_mail = '메일 발송 내역';
|
||||||
$lang->cmd_advanced_mailer_log_errors = '에러 내역';
|
$lang->cmd_advanced_mailer_log_mail_errors = '메일 에러 내역';
|
||||||
|
$lang->cmd_advanced_mailer_log_sms = 'SMS 발송 내역';
|
||||||
|
$lang->cmd_advanced_mailer_log_sms_errors = 'SMS 에러 내역';
|
||||||
$lang->cmd_advanced_mailer_log_yes = '기록';
|
$lang->cmd_advanced_mailer_log_yes = '기록';
|
||||||
$lang->cmd_advanced_mailer_log_no = '기록하지 않음';
|
$lang->cmd_advanced_mailer_log_no = '기록하지 않음';
|
||||||
$lang->cmd_advanced_mailer_sending_method_config = '기본 발송 방법 설정';
|
$lang->cmd_advanced_mailer_sending_method_config = '기본 발송 방법 설정';
|
||||||
$lang->cmd_advanced_mailer_about_sending_method_config = '반드시 모든 항목을 입력하시기 바랍니다.';
|
$lang->cmd_advanced_mailer_about_sending_method_config = '반드시 모든 항목을 입력하시기 바랍니다.';
|
||||||
$lang->cmd_advanced_mailer_sending_method = '발송 방법';
|
$lang->cmd_advanced_mailer_sending_method = '발송 방법';
|
||||||
$lang->cmd_advanced_mailer_about_sending_method = '받는이의 주소가 <a href="./index.php?module=admin&act=dispAdvanced_mailerAdminExceptions" target="_blank">예외 도메인</a>에 해당하지 않을 경우 모두 이 방법으로 발송됩니다.';
|
$lang->cmd_advanced_mailer_about_sending_method = '기본 발송 방법은 <a href="index.php?module=admin&act=dispAdminConfigNotification" target="_blank">알림 설정</a> 화면에서 변경할 수 있습니다.';
|
||||||
$lang->cmd_advanced_mailer_sending_method_default = '기본 발송 방법';
|
$lang->cmd_advanced_mailer_sending_method_default = '기본 발송 방법';
|
||||||
$lang->cmd_advanced_mailer_sending_method_exceptions = '예외 발송 방법';
|
$lang->cmd_advanced_mailer_sending_method_exceptions = '예외 발송 방법';
|
||||||
$lang->cmd_advanced_mailer_smtp_manual_entry = '직접 입력';
|
$lang->cmd_advanced_mailer_smtp_manual_entry = '직접 입력';
|
||||||
|
|
@ -24,6 +26,8 @@ $lang->cmd_advanced_mailer_smtp_security_tls = 'TLS (STARTTLS)';
|
||||||
$lang->cmd_advanced_mailer_smtp_security_none = '사용하지 않음';
|
$lang->cmd_advanced_mailer_smtp_security_none = '사용하지 않음';
|
||||||
$lang->cmd_advanced_mailer_smtp_user = '아이디';
|
$lang->cmd_advanced_mailer_smtp_user = '아이디';
|
||||||
$lang->cmd_advanced_mailer_smtp_pass = '비밀번호';
|
$lang->cmd_advanced_mailer_smtp_pass = '비밀번호';
|
||||||
|
$lang->cmd_advanced_mailer_api_key = 'API 키';
|
||||||
|
$lang->cmd_advanced_mailer_api_secret = 'API 비밀';
|
||||||
$lang->cmd_advanced_mailer_api_domain = '도메인';
|
$lang->cmd_advanced_mailer_api_domain = '도메인';
|
||||||
$lang->cmd_advanced_mailer_api_token = 'API 토큰';
|
$lang->cmd_advanced_mailer_api_token = 'API 토큰';
|
||||||
$lang->cmd_advanced_mailer_api_type = 'API 구분';
|
$lang->cmd_advanced_mailer_api_type = 'API 구분';
|
||||||
|
|
@ -31,8 +35,9 @@ $lang->cmd_advanced_mailer_api_type_free = '무료';
|
||||||
$lang->cmd_advanced_mailer_api_type_paid = '유료';
|
$lang->cmd_advanced_mailer_api_type_paid = '유료';
|
||||||
$lang->cmd_advanced_mailer_api_user = '아이디';
|
$lang->cmd_advanced_mailer_api_user = '아이디';
|
||||||
$lang->cmd_advanced_mailer_api_pass = '비밀번호';
|
$lang->cmd_advanced_mailer_api_pass = '비밀번호';
|
||||||
|
$lang->cmd_advanced_mailer_sender_key = '센더 키';
|
||||||
$lang->cmd_advanced_mailer_sender_identity = '보낸이 설정';
|
$lang->cmd_advanced_mailer_sender_identity = '보낸이 설정';
|
||||||
$lang->cmd_advanced_mailer_about_sender_identity = '보낸이 설정은 <a href="./index.php?module=admin&act=dispMemberAdminConfig" target="_blank">회원 모듈</a>의 웹마스터 이름 및 메일 주소에도 동일하게 적용됩니다.';
|
$lang->cmd_advanced_mailer_about_sender_identity = '보낸이의 이름과 메일 주소는 <a href="index.php?module=admin&act=dispAdminConfigNotification" target="_blank">알림 설정</a> 화면에서 변경할 수 있습니다.';
|
||||||
$lang->cmd_advanced_mailer_sender_name = '보낸이 이름';
|
$lang->cmd_advanced_mailer_sender_name = '보낸이 이름';
|
||||||
$lang->cmd_advanced_mailer_sender_email = '보낸이 메일 주소';
|
$lang->cmd_advanced_mailer_sender_email = '보낸이 메일 주소';
|
||||||
$lang->cmd_advanced_mailer_reply_to = 'Reply-To 주소';
|
$lang->cmd_advanced_mailer_reply_to = 'Reply-To 주소';
|
||||||
|
|
@ -59,7 +64,7 @@ $lang->cmd_advanced_mailer_other_info_mailgun_dkim = 'DKIM 호스트명은 달
|
||||||
$lang->cmd_advanced_mailer_other_info_postmark_dkim = '정확한 DKIM 호스트명은 Postmark 계정의 Sender Signatures 페이지를 참고하시기 바랍니다.';
|
$lang->cmd_advanced_mailer_other_info_postmark_dkim = '정확한 DKIM 호스트명은 Postmark 계정의 Sender Signatures 페이지를 참고하시기 바랍니다.';
|
||||||
$lang->cmd_advanced_mailer_other_info_woorimail_dkim = 'DKIM 설정은 우리메일에 로그인하여 확인하십시오.';
|
$lang->cmd_advanced_mailer_other_info_woorimail_dkim = 'DKIM 설정은 우리메일에 로그인하여 확인하십시오.';
|
||||||
$lang->cmd_advanced_mailer_ellipsis = '(중략)';
|
$lang->cmd_advanced_mailer_ellipsis = '(중략)';
|
||||||
$lang->cmd_advanced_mailer_test = '발송 테스트';
|
$lang->cmd_advanced_mailer_mail_test = '메일 테스트';
|
||||||
$lang->cmd_advanced_mailer_recipient_name = '받는이 이름';
|
$lang->cmd_advanced_mailer_recipient_name = '받는이 이름';
|
||||||
$lang->cmd_advanced_mailer_recipient_email = '받는이 메일 주소';
|
$lang->cmd_advanced_mailer_recipient_email = '받는이 메일 주소';
|
||||||
$lang->cmd_advanced_mailer_send = '발송';
|
$lang->cmd_advanced_mailer_send = '발송';
|
||||||
|
|
@ -102,6 +107,7 @@ $lang->msg_advanced_mailer_log_is_empty = '표시할 항목이 없습니다.';
|
||||||
$lang->cmd_advanced_mailer_status_sender = '보낸이';
|
$lang->cmd_advanced_mailer_status_sender = '보낸이';
|
||||||
$lang->cmd_advanced_mailer_status_recipient = '받는이';
|
$lang->cmd_advanced_mailer_status_recipient = '받는이';
|
||||||
$lang->cmd_advanced_mailer_status_subject = '제목';
|
$lang->cmd_advanced_mailer_status_subject = '제목';
|
||||||
|
$lang->cmd_advanced_mailer_status_content = '내용';
|
||||||
$lang->cmd_advanced_mailer_status_sending_method = '발송 방법';
|
$lang->cmd_advanced_mailer_status_sending_method = '발송 방법';
|
||||||
$lang->cmd_advanced_mailer_status_time = '발송 시간';
|
$lang->cmd_advanced_mailer_status_time = '발송 시간';
|
||||||
$lang->cmd_advanced_mailer_status = '상태';
|
$lang->cmd_advanced_mailer_status = '상태';
|
||||||
|
|
@ -112,3 +118,11 @@ $lang->cmd_advanced_mailer_status_calling_script = '호출 위치';
|
||||||
$lang->cmd_advanced_mailer_clear_log_condition_all = '모두';
|
$lang->cmd_advanced_mailer_clear_log_condition_all = '모두';
|
||||||
$lang->cmd_advanced_mailer_clear_log_condition = '%d일 이상';
|
$lang->cmd_advanced_mailer_clear_log_condition = '%d일 이상';
|
||||||
$lang->cmd_advanced_mailer_clear_log_button = '오래된 기록 삭제';
|
$lang->cmd_advanced_mailer_clear_log_button = '오래된 기록 삭제';
|
||||||
|
$lang->cmd_advanced_mailer_sms_test = 'SMS 테스트';
|
||||||
|
$lang->cmd_advanced_mailer_recipient_number = '받는이 전화번호';
|
||||||
|
$lang->cmd_advanced_mailer_country_code = '국가코드';
|
||||||
|
$lang->cmd_advanced_mailer_country_code_help = '국내 번호로 발송하실 경우 국가코드는 비워 두시기 바랍니다.';
|
||||||
|
$lang->cmd_advanced_mailer_test_content = '라이믹스 SMS 발송 테스트입니다.';
|
||||||
|
$lang->msg_advanced_mailer_recipient_number_is_empty = '받는이 전화번호를 입력해 주십시오.';
|
||||||
|
$lang->msg_advanced_mailer_content_is_empty = 'SMS 내용을 입력해 주십시오.';
|
||||||
|
$lang->msg_advanced_mailer_test_success_sms = '테스트에 성공하였습니다. SMS를 확인해 보시기 바랍니다.';
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<query id="countLogByType" action="select">
|
<query id="countMailLogByType" action="select">
|
||||||
<tables>
|
<tables>
|
||||||
<table name="advanced_mailer_log" />
|
<table name="advanced_mailer_log" />
|
||||||
</tables>
|
</tables>
|
||||||
11
modules/advanced_mailer/queries/countSMSLogByType.xml
Normal file
11
modules/advanced_mailer/queries/countSMSLogByType.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<query id="countSMSLogByType" action="select">
|
||||||
|
<tables>
|
||||||
|
<table name="advanced_mailer_sms_log" />
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<column name="count(*)" alias="count" />
|
||||||
|
</columns>
|
||||||
|
<conditions>
|
||||||
|
<condition operation="equal" column="status" var="status" />
|
||||||
|
</conditions>
|
||||||
|
</query>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<query id="deleteLogs" action="delete">
|
<query id="deleteMailLogs" action="delete">
|
||||||
<tables>
|
<tables>
|
||||||
<table name="advanced_mailer_log" />
|
<table name="advanced_mailer_log" />
|
||||||
</tables>
|
</tables>
|
||||||
9
modules/advanced_mailer/queries/deleteSMSLogs.xml
Normal file
9
modules/advanced_mailer/queries/deleteSMSLogs.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<query id="deleteSMSLogs" action="delete">
|
||||||
|
<tables>
|
||||||
|
<table name="advanced_mailer_sms_log" />
|
||||||
|
</tables>
|
||||||
|
<conditions>
|
||||||
|
<condition operation="equal" column="status" var="status" />
|
||||||
|
<condition operation="less" column="regdate" var="regdate" pipe="and" />
|
||||||
|
</conditions>
|
||||||
|
</query>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<query id="getLogByType" action="select">
|
<query id="getMailLogByType" action="select">
|
||||||
<tables>
|
<tables>
|
||||||
<table name="advanced_mailer_log" />
|
<table name="advanced_mailer_log" />
|
||||||
</tables>
|
</tables>
|
||||||
17
modules/advanced_mailer/queries/getSMSLogByType.xml
Normal file
17
modules/advanced_mailer/queries/getSMSLogByType.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<query id="getSMSLogByType" action="select">
|
||||||
|
<tables>
|
||||||
|
<table name="advanced_mailer_sms_log" />
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<column name="*" />
|
||||||
|
</columns>
|
||||||
|
<conditions>
|
||||||
|
<condition operation="equal" column="status" var="status" />
|
||||||
|
</conditions>
|
||||||
|
<navigation>
|
||||||
|
<index var="sort_index" default="sms_id" order="desc" />
|
||||||
|
<list_count var="list_count" default="20" />
|
||||||
|
<page_count var="page_count" default="10" />
|
||||||
|
<page var="page" default="1" />
|
||||||
|
</navigation>
|
||||||
|
</query>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<query id="insertLog" action="insert">
|
<query id="insertMailLog" action="insert">
|
||||||
<tables>
|
<tables>
|
||||||
<table name="advanced_mailer_log" />
|
<table name="advanced_mailer_log" />
|
||||||
</tables>
|
</tables>
|
||||||
15
modules/advanced_mailer/queries/insertSMSLog.xml
Normal file
15
modules/advanced_mailer/queries/insertSMSLog.xml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
<query id="insertSMSLog" action="insert">
|
||||||
|
<tables>
|
||||||
|
<table name="advanced_mailer_sms_log" />
|
||||||
|
</tables>
|
||||||
|
<columns>
|
||||||
|
<column name="sms_from" var="sms_from" notnull="notnull" />
|
||||||
|
<column name="sms_to" var="sms_to" notnull="notnull" />
|
||||||
|
<column name="content" var="content" notnull="notnull" />
|
||||||
|
<column name="calling_script" var="calling_script" notnull="notnull" />
|
||||||
|
<column name="sending_method" var="sending_method" notnull="notnull" />
|
||||||
|
<column name="regdate" var="regdate" notnull="notnull" default="curdate()" />
|
||||||
|
<column name="status" var="status" notnull="notnull" default="success" />
|
||||||
|
<column name="errors" var="errors" />
|
||||||
|
</columns>
|
||||||
|
</query>
|
||||||
11
modules/advanced_mailer/schemas/advanced_mailer_sms_log.xml
Normal file
11
modules/advanced_mailer/schemas/advanced_mailer_sms_log.xml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
<table name="advanced_mailer_sms_log">
|
||||||
|
<column name="sms_id" type="number" size="11" notnull="notnull" primary_key="primary_key" auto_increment="auto_increment" />
|
||||||
|
<column name="sms_from" type="varchar" size="250" notnull="notnull" />
|
||||||
|
<column name="sms_to" type="text" notnull="notnull" />
|
||||||
|
<column name="content" type="text" notnull="notnull" />
|
||||||
|
<column name="calling_script" type="varchar" size="250" notnull="notnull" />
|
||||||
|
<column name="sending_method" type="varchar" size="40" notnull="notnull" />
|
||||||
|
<column name="regdate" type="date" notnull="notnull" index="idx_regdate" />
|
||||||
|
<column name="status" type="varchar" size="40" notnull="notnull" index="idx_status" />
|
||||||
|
<column name="errors" type="bigtext" />
|
||||||
|
</table>
|
||||||
|
|
@ -7,7 +7,10 @@
|
||||||
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminConfig'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminConfig')}">{$lang->cmd_advanced_mailer_general_config}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminConfig'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminConfig')}">{$lang->cmd_advanced_mailer_general_config}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminExceptions'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminExceptions')}">{$lang->cmd_advanced_mailer_exception_domains}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminExceptions'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminExceptions')}">{$lang->cmd_advanced_mailer_exception_domains}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminSpfDkim'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSpfDkim')}">{$lang->cmd_advanced_mailer_spf_dkim_setting}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminSpfDkim'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSpfDkim')}">{$lang->cmd_advanced_mailer_spf_dkim_setting}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminTestConfig'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminTestConfig')}">{$lang->cmd_advanced_mailer_test}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminMailTest'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminMailTest')}">{$lang->cmd_advanced_mailer_mail_test}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminSentMail'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSentMail')}">{$lang->cmd_advanced_mailer_log_sent_mail}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminMailLog'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminMailLog')}">{$lang->cmd_advanced_mailer_log_mail}</a></li>
|
||||||
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminErrors'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminErrors')}">{$lang->cmd_advanced_mailer_log_errors}</a></li>
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminMailErrors'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminMailErrors')}">{$lang->cmd_advanced_mailer_log_mail_errors}</a></li>
|
||||||
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminSMSTest'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSMSTest')}">{$lang->cmd_advanced_mailer_sms_test}</a></li>
|
||||||
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminSMSLog'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSMSLog')}">{$lang->cmd_advanced_mailer_log_sms}</a></li>
|
||||||
|
<li class="x_active"|cond="$act == 'dispAdvanced_mailerAdminSMSErrors'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdvanced_mailerAdminSMSErrors')}">{$lang->cmd_advanced_mailer_log_sms_errors}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -19,140 +19,6 @@
|
||||||
※ {$lang->cmd_advanced_mailer_about_sending_method}
|
※ {$lang->cmd_advanced_mailer_about_sending_method}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="x_control-group show-always">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_sending_method">{$lang->cmd_advanced_mailer_sending_method_default}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<select name="sending_method" id="advanced_mailer_sending_method">
|
|
||||||
<!--@foreach($sending_methods as $driver_name => $driver_definition)-->
|
|
||||||
<option value="{$driver_name}" selected="selected"|cond="$sending_method === $driver_name">{$driver_definition['name']}</option>
|
|
||||||
<!--@end-->
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var advanced_mailer_sending_methods = {json_encode($sending_methods)};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="x_control-group hidden-by-default show-for-dummy">
|
|
||||||
<label class="x_control-label"></label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<p class="x_help-block">{$lang->msg_advanced_mailer_about_dummy}<br />{$lang->msg_advanced_mailer_about_dummy_exceptions}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--@foreach($sending_methods as $driver_name => $driver_definition)-->
|
|
||||||
<!--@foreach($driver_definition['required'] as $conf_name)-->
|
|
||||||
{@ $conf_value = escape(config("mail.$driver_name.$conf_name"))}
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'smtp_host')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_smtp_host">{$lang->cmd_advanced_mailer_smtp_host}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="{$driver_name}_smtp_host" id="advanced_mailer_{$driver_name}_smtp_host" value="{$conf_value}" />
|
|
||||||
<select id="advanced_mailer_{$driver_name}_manual_entry">
|
|
||||||
<option value="">{$lang->cmd_advanced_mailer_smtp_manual_entry}</option>
|
|
||||||
<option value="gmail">Gmail</option>
|
|
||||||
<option value="hanmail">Hanmail</option>
|
|
||||||
<option value="naver">Naver</option>
|
|
||||||
<option value="worksmobile">Works Mobile</option>
|
|
||||||
<option value="outlook">Outlook.com</option>
|
|
||||||
<option value="yahoo">Yahoo</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'smtp_port')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_smtp_port">{$lang->cmd_advanced_mailer_smtp_port}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="{$driver_name}_smtp_port" id="advanced_mailer_{$driver_name}_smtp_port" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'smtp_security')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label">{$lang->cmd_advanced_mailer_smtp_security}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<label class="x_inline" for="advanced_mailer_{$driver_name}_security_none"><input type="radio" name="{$driver_name}_smtp_security" id="advanced_mailer_{$driver_name}_security_none" value="none" checked="checked"|cond="!in_array($conf_value, array('ssl', 'tls'))" /> {$lang->cmd_advanced_mailer_smtp_security_none}</label>
|
|
||||||
<label class="x_inline" for="advanced_mailer_{$driver_name}_security_ssl"><input type="radio" name="{$driver_name}_smtp_security" id="advanced_mailer_{$driver_name}_security_ssl" value="ssl" checked="checked"|cond="$conf_value === 'ssl'" /> {$lang->cmd_advanced_mailer_smtp_security_ssl}</label>
|
|
||||||
<label class="x_inline" for="advanced_mailer_{$driver_name}_security_tls"><input type="radio" name="{$driver_name}_smtp_security" id="advanced_mailer_{$driver_name}_security_tls" value="tls" checked="checked"|cond="$conf_value === 'tls'" /> {$lang->cmd_advanced_mailer_smtp_security_tls}</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'smtp_user')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_smtp_user">{$lang->cmd_advanced_mailer_smtp_user}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="{$driver_name}_smtp_user" id="advanced_mailer_{$driver_name}_smtp_user" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'smtp_pass')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_smtp_pass">{$lang->cmd_advanced_mailer_smtp_pass}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="smtp_pass" name="{$driver_name}_smtp_pass" id="advanced_mailer_{$driver_name}_smtp_pass" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'api_type')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_api_type">{$lang->cmd_advanced_mailer_api_type}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<select id="advanced_mailer_{$driver_name}_api_type" name="{$driver_name}_api_type">
|
|
||||||
<!--@foreach($driver_definition['api_types'] as $api_type)-->
|
|
||||||
<option value="{$api_type}" selected="selected"|cond="$api_type === $conf_value">{$api_type}</option>
|
|
||||||
<!--@end-->
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'api_domain')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_api_domain">{$lang->cmd_advanced_mailer_api_domain}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="{$driver_name}_api_domain" id="advanced_mailer_{$driver_name}_api_domain" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'api_token')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_api_token">{$lang->cmd_advanced_mailer_api_token}</label>
|
|
||||||
<div class="x_controls full-width">
|
|
||||||
<input type="text" name="{$driver_name}_api_token" id="advanced_mailer_{$driver_name}_api_token" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'api_user')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_api_user">{$lang->cmd_advanced_mailer_api_user}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="{$driver_name}_api_user" id="advanced_mailer_{$driver_name}_api_user" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@if($conf_name === 'api_pass')-->
|
|
||||||
<div class="x_control-group hidden-by-default show-for-{$driver_name}">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_{$driver_name}_api_pass">{$lang->cmd_advanced_mailer_api_pass}</label>
|
|
||||||
<div class="x_controls full-width">
|
|
||||||
<input type="password" name="{$driver_name}_api_pass" id="advanced_mailer_{$driver_name}_api_pass" value="{$conf_value}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
<!--@end-->
|
|
||||||
<!--@end-->
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
|
|
@ -162,38 +28,6 @@
|
||||||
<div class="advanced_mailer_description">
|
<div class="advanced_mailer_description">
|
||||||
※ {$lang->cmd_advanced_mailer_about_sender_identity}
|
※ {$lang->cmd_advanced_mailer_about_sender_identity}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="x_control-group">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_sender_name">{$lang->cmd_advanced_mailer_sender_name}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="sender_name" id="advanced_mailer_sender_name" value="{$webmaster_name}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="x_control-group">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_sender_email">{$lang->cmd_advanced_mailer_sender_email}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="sender_email" id="advanced_mailer_sender_email" value="{$webmaster_email}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="x_control-group">
|
|
||||||
<label class="x_control-label" for="advanced_mailer_reply_to">{$lang->cmd_advanced_mailer_reply_to}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<input type="text" name="reply_to" id="advanced_mailer_reply_to" value="{$advanced_mailer_config->reply_to}" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="x_control-group">
|
|
||||||
<label class="x_control-label">{$lang->cmd_advanced_mailer_force_sender}</label>
|
|
||||||
<div class="x_controls">
|
|
||||||
<label for="advanced_mailer_force_sender">
|
|
||||||
<input type="checkbox" name="force_sender" id="advanced_mailer_force_sender" value="Y" checked="checked"|cond="toBool($advanced_mailer_config->force_sender)" />
|
|
||||||
{$lang->cmd_advanced_mailer_about_force_sender}
|
|
||||||
</label>
|
|
||||||
<p>※ {$lang->cmd_advanced_mailer_about_force_sender_caution_line_1}<br />※ {$lang->cmd_advanced_mailer_about_force_sender_caution_line_2}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -202,7 +36,7 @@
|
||||||
<h2 style="padding-top:12px">{$lang->cmd_advanced_mailer_logging}</h2>
|
<h2 style="padding-top:12px">{$lang->cmd_advanced_mailer_logging}</h2>
|
||||||
|
|
||||||
<div class="x_control-group">
|
<div class="x_control-group">
|
||||||
<label class="x_control-label" for="advanced_mailer_log_sent_mail">{$lang->cmd_advanced_mailer_log_sent_mail}</label>
|
<label class="x_control-label" for="advanced_mailer_log_sent_mail">{$lang->cmd_advanced_mailer_log_mail}</label>
|
||||||
<div class="x_controls">
|
<div class="x_controls">
|
||||||
<select name="log_sent_mail" id="advanced_mailer_log_sent_mail">
|
<select name="log_sent_mail" id="advanced_mailer_log_sent_mail">
|
||||||
<option value="Y" selected="selected"|cond="toBool($advanced_mailer_config->log_sent_mail)" />{$lang->cmd_advanced_mailer_log_yes}</option>
|
<option value="Y" selected="selected"|cond="toBool($advanced_mailer_config->log_sent_mail)" />{$lang->cmd_advanced_mailer_log_yes}</option>
|
||||||
|
|
@ -212,7 +46,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="x_control-group">
|
<div class="x_control-group">
|
||||||
<label class="x_control-label">{$lang->cmd_advanced_mailer_log_errors}</label>
|
<label class="x_control-label">{$lang->cmd_advanced_mailer_log_mail_errors}</label>
|
||||||
<div class="x_controls">
|
<div class="x_controls">
|
||||||
<select name="log_errors" id="advanced_mailer_log_errors">
|
<select name="log_errors" id="advanced_mailer_log_errors">
|
||||||
<option value="Y" selected="selected"|cond="toBool($advanced_mailer_config->log_errors)" />{$lang->cmd_advanced_mailer_log_yes}</option>
|
<option value="Y" selected="selected"|cond="toBool($advanced_mailer_config->log_errors)" />{$lang->cmd_advanced_mailer_log_yes}</option>
|
||||||
|
|
@ -221,6 +55,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="advanced_mailer_log_sent_sms">{$lang->cmd_advanced_mailer_log_sms}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<select name="log_sent_sms" id="advanced_mailer_log_sent_sms">
|
||||||
|
<option value="Y" selected="selected"|cond="toBool($advanced_mailer_config->log_sent_sms)" />{$lang->cmd_advanced_mailer_log_yes}</option>
|
||||||
|
<option value="N" selected="selected"|cond="!toBool($advanced_mailer_config->log_sent_sms)" />{$lang->cmd_advanced_mailer_log_no}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label">{$lang->cmd_advanced_mailer_log_sms_errors}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<select name="log_sms_errors" id="advanced_mailer_log_sms_errors">
|
||||||
|
<option value="Y" selected="selected"|cond="toBool($advanced_mailer_config->log_sms_errors)" />{$lang->cmd_advanced_mailer_log_yes}</option>
|
||||||
|
<option value="N" selected="selected"|cond="!toBool($advanced_mailer_config->log_sms_errors)" />{$lang->cmd_advanced_mailer_log_no}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="btnArea x_clearfix">
|
<div class="btnArea x_clearfix">
|
||||||
|
|
|
||||||
|
|
@ -3,93 +3,38 @@
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
$("#advanced_mailer_sending_method").on("change", function() {
|
$("#advanced_mailer_test_send_mail").click(function(event) {
|
||||||
var sending_method = $(this).val();
|
|
||||||
$("div.x_control-group.hidden-by-default").not(".show-always").each(function() {
|
|
||||||
if ($(this).hasClass("show-for-" + sending_method)) {
|
|
||||||
$(this).show();
|
|
||||||
} else {
|
|
||||||
$(this).hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var reply_to = $("#advanced_mailer_reply_to").parents("div.x_control-group");
|
|
||||||
if (sending_method === "woorimail") {
|
|
||||||
reply_to.hide();
|
|
||||||
} else {
|
|
||||||
reply_to.show();
|
|
||||||
}
|
|
||||||
}).triggerHandler("change");
|
|
||||||
|
|
||||||
$("#advanced_mailer_smtp_manual_entry").on("change", function() {
|
|
||||||
var auto_fill = $(this).val();
|
|
||||||
if (auto_fill === 'gmail') {
|
|
||||||
$("#advanced_mailer_smtp_host").val('smtp.gmail.com');
|
|
||||||
$("#advanced_mailer_smtp_port").val('465');
|
|
||||||
$("#advanced_mailer_smtp_security_ssl").prop("checked", true).parent().addClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_tls").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_none").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_force_sender").prop("checked", true).parent().addClass("checked");
|
|
||||||
}
|
|
||||||
if (auto_fill === 'hanmail') {
|
|
||||||
$("#advanced_mailer_smtp_host").val('smtp.daum.net');
|
|
||||||
$("#advanced_mailer_smtp_port").val('465');
|
|
||||||
$("#advanced_mailer_smtp_security_ssl").prop("checked", true).parent().addClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_tls").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_none").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_force_sender").prop("checked", true).parent().addClass("checked");
|
|
||||||
}
|
|
||||||
if (auto_fill === 'naver') {
|
|
||||||
$("#advanced_mailer_smtp_host").val('smtp.naver.com');
|
|
||||||
$("#advanced_mailer_smtp_port").val('587');
|
|
||||||
$("#advanced_mailer_smtp_security_tls").prop("checked", true).parent().addClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_ssl").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_none").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_force_sender").prop("checked", true).parent().addClass("checked");
|
|
||||||
}
|
|
||||||
if (auto_fill === 'worksmobile') {
|
|
||||||
$("#advanced_mailer_smtp_host").val('smtp.worksmobile.com');
|
|
||||||
$("#advanced_mailer_smtp_port").val('587');
|
|
||||||
$("#advanced_mailer_smtp_security_tls").prop("checked", true).parent().addClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_ssl").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_none").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_force_sender").prop("checked", true).parent().addClass("checked");
|
|
||||||
}
|
|
||||||
if (auto_fill === 'outlook') {
|
|
||||||
$("#advanced_mailer_smtp_host").val('smtp-mail.outlook.com');
|
|
||||||
$("#advanced_mailer_smtp_port").val('587');
|
|
||||||
$("#advanced_mailer_smtp_security_tls").prop("checked", true).parent().addClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_ssl").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_none").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_force_sender").prop("checked", true).parent().addClass("checked");
|
|
||||||
}
|
|
||||||
if (auto_fill === 'yahoo') {
|
|
||||||
$("#advanced_mailer_smtp_host").val('smtp.mail.yahoo.com');
|
|
||||||
$("#advanced_mailer_smtp_port").val('465');
|
|
||||||
$("#advanced_mailer_smtp_security_ssl").prop("checked", true).parent().addClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_tls").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_smtp_security_none").parent().removeClass("checked");
|
|
||||||
$("#advanced_mailer_force_sender").prop("checked", true).parent().addClass("checked");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$("#advanced_mailer_woorimail_account_type_free,#advanced_mailer_woorimail_account_type_paid").on("change", function() {
|
|
||||||
if ($("#advanced_mailer_woorimail_account_type_paid").is(":checked")) {
|
|
||||||
$("#advanced_mailer_reply_to").attr("disabled", "disabled");
|
|
||||||
} else {
|
|
||||||
$("#advanced_mailer_reply_to").removeAttr("disabled");
|
|
||||||
}
|
|
||||||
}).triggerHandler("change");
|
|
||||||
|
|
||||||
$("#advanced_mailer_test_send").click(function(event) {
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$("#advanced_mailer_test_result").text("");
|
$("#advanced_mailer_test_result").text("");
|
||||||
$(this).attr("disabled", "disabled");
|
$(this).attr("disabled", "disabled");
|
||||||
var ajax_data = {
|
var ajax_data = {
|
||||||
recipient_name: $("#advanced_mailer_recipient_name").val(),
|
recipient_name: $("#advanced_mailer_recipient_name").val(),
|
||||||
recipient_email: $("#advanced_mailer_recipient_email").val(),
|
recipient_email: $("#advanced_mailer_recipient_email").val()
|
||||||
};
|
};
|
||||||
$.exec_json(
|
$.exec_json(
|
||||||
"advanced_mailer.procAdvanced_mailerAdminTestSend", ajax_data,
|
"advanced_mailer.procAdvanced_mailerAdminTestSendMail", ajax_data,
|
||||||
|
function(response) {
|
||||||
|
$("#advanced_mailer_test_result").html(response.test_result);
|
||||||
|
$("#advanced_mailer_test_send").removeAttr("disabled");
|
||||||
|
},
|
||||||
|
function(response) {
|
||||||
|
$("#advanced_mailer_test_result").text("AJAX Error");
|
||||||
|
$("#advanced_mailer_test_send").removeAttr("disabled");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#advanced_mailer_test_send_sms").click(function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
$("#advanced_mailer_test_result").text("");
|
||||||
|
$(this).attr("disabled", "disabled");
|
||||||
|
var ajax_data = {
|
||||||
|
recipient_number: $("#advanced_mailer_recipient_number").val(),
|
||||||
|
country_code: $("#advanced_mailer_country_code").val(),
|
||||||
|
content: $("#advanced_mailer_content").val()
|
||||||
|
};
|
||||||
|
$.exec_json(
|
||||||
|
"advanced_mailer.procAdvanced_mailerAdminTestSendSMS", ajax_data,
|
||||||
function(response) {
|
function(response) {
|
||||||
$("#advanced_mailer_test_result").html(response.test_result);
|
$("#advanced_mailer_test_result").html(response.test_result);
|
||||||
$("#advanced_mailer_test_send").removeAttr("disabled");
|
$("#advanced_mailer_test_send").removeAttr("disabled");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<form class="x_form-horizontal" action="./" method="post" id="advanced_mailer">
|
<form class="x_form-horizontal" action="./" method="post" id="advanced_mailer">
|
||||||
<input type="hidden" name="module" value="advanced_mailer" />
|
<input type="hidden" name="module" value="advanced_mailer" />
|
||||||
<input type="hidden" name="act" value="procAdvanced_mailerAdminTestConfig" />
|
<input type="hidden" name="act" value="procAdvanced_mailerAdminTestSendMail" />
|
||||||
<input type="hidden" name="success_return_url" value="{getRequestUriByServerEnviroment()}" />
|
<input type="hidden" name="success_return_url" value="{getRequestUriByServerEnviroment()}" />
|
||||||
|
|
||||||
<div cond="$XE_VALIDATOR_MESSAGE" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
|
<div cond="$XE_VALIDATOR_MESSAGE" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
|
|
||||||
<h2>{$lang->cmd_advanced_mailer_test}</h2>
|
<h2>{$lang->cmd_advanced_mailer_mail_test}</h2>
|
||||||
|
|
||||||
<div class="x_control-group">
|
<div class="x_control-group">
|
||||||
<label class="x_control-label" for="advanced_mailer_recipient_name">{$lang->cmd_advanced_mailer_recipient_name}</label>
|
<label class="x_control-label" for="advanced_mailer_recipient_name">{$lang->cmd_advanced_mailer_recipient_name}</label>
|
||||||
|
|
@ -39,7 +39,7 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="btnArea x_clearfix">
|
<div class="btnArea x_clearfix">
|
||||||
<button id="advanced_mailer_test_send" type="submit" class="x_btn x_btn-primary x_pull-right">{$lang->cmd_advanced_mailer_send}</button>
|
<button id="advanced_mailer_test_send_mail" type="submit" class="x_btn x_btn-primary x_pull-right">{$lang->cmd_advanced_mailer_send}</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
79
modules/advanced_mailer/tpl/sms_log.html
Normal file
79
modules/advanced_mailer/tpl/sms_log.html
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
<include target="./common.html" />
|
||||||
|
<load target="css/view_log.css" />
|
||||||
|
<load target="js/view_log.js" />
|
||||||
|
|
||||||
|
<table id="advanced_mailer_log" class="x_table x_table-striped x_table-hover">
|
||||||
|
<caption>
|
||||||
|
<strong>Total: {number_format($total_count)}, Page: {number_format($page)}/{number_format($total_page)}</strong>
|
||||||
|
</caption>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col" class="nowr">{$lang->cmd_advanced_mailer_status_sender}</th>
|
||||||
|
<th scope="col" class="nowr">{$lang->cmd_advanced_mailer_status_recipient}</th>
|
||||||
|
<th scope="col" class="nowr">{$lang->cmd_advanced_mailer_status_content}</th>
|
||||||
|
<th scope="col" class="nowr">{$lang->cmd_advanced_mailer_status_sending_method}</th>
|
||||||
|
<th scope="col" class="nowr">{$lang->cmd_advanced_mailer_status_time}</th>
|
||||||
|
<th scope="col" class="nowr">{$lang->cmd_advanced_mailer_status}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr loop="$advanced_mailer_log => $sms_id, $val">
|
||||||
|
<td class="nowr">
|
||||||
|
{htmlspecialchars($val->sms_from)}
|
||||||
|
</td>
|
||||||
|
<td class="nowr">
|
||||||
|
{htmlspecialchars($val->sms_to)}
|
||||||
|
</td>
|
||||||
|
<td class="nowr">{nl2br(htmlspecialchars($val->content))}</td>
|
||||||
|
<td class="nowr">
|
||||||
|
{@ if($val->sending_method === 'mail') $val->sending_method = 'mailfunction'}
|
||||||
|
{strval(isset($sending_methods[$val->sending_method]['name']) ? $sending_methods[$val->sending_method]['name'] : $val->sending_method)}
|
||||||
|
</td>
|
||||||
|
<td class="nowr">{(zdate($val->regdate, "Y-m-d\nH:i:s"))}</td>
|
||||||
|
<td class="nowr">
|
||||||
|
<!--@if($val->status === 'success')-->
|
||||||
|
{$lang->cmd_advanced_mailer_status_success}
|
||||||
|
<!--@else-->
|
||||||
|
<a href="javascript:void(0)" class="show-errors">{$lang->cmd_advanced_mailer_status_error}</a>
|
||||||
|
<div class="mail-log-errors">
|
||||||
|
<strong>{$lang->cmd_advanced_mailer_status_error_msg}:</strong><br />
|
||||||
|
{nl2br(htmlspecialchars(trim($val->errors)))}<br /><br />
|
||||||
|
<strong>{$lang->cmd_advanced_mailer_status_calling_script}:</strong><br />
|
||||||
|
{htmlspecialchars($val->calling_script)}
|
||||||
|
</div>
|
||||||
|
<!--@end-->
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr cond="!$advanced_mailer_log">
|
||||||
|
<td>{$lang->msg_advanced_mailer_log_is_empty}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="x_clearfix">
|
||||||
|
<form class="x_pagination x_pull-left" style="margin-top:8px" action="{Context::getUrl('')}" method="post" no-error-return-url="true">
|
||||||
|
<input loop="$param => $key, $val" cond="!in_array($key, array('mid', 'vid', 'act'))" type="hidden" name="{$key}" value="{$val}" />
|
||||||
|
<ul>
|
||||||
|
<li class="x_disabled"|cond="$page == 1"><a href="{getUrl('page', '')}">« {$lang->first_page}</a></li>
|
||||||
|
<!--@while($page_no = $page_navigation->getNextPage())-->
|
||||||
|
<li class="x_active"|cond="$page_no == $page"><a href="{getUrl('page', $page_no)}">{$page_no}</a></li>
|
||||||
|
<!--@end-->
|
||||||
|
<li class="x_disabled"|cond="$page == $page_navigation->last_page"><a href="{getUrl('page', $page_navigation->last_page)}">{$lang->last_page} »</a></li>
|
||||||
|
</ul>
|
||||||
|
</form>
|
||||||
|
<form class="x_pull-right x_input-append" style="margin-top:8px" action="{Context::getUrl('')}" method="post">
|
||||||
|
<input type="hidden" name="module" value="advanced_mailer" />
|
||||||
|
<input type="hidden" name="act" value="procAdvanced_mailerAdminClearSentSMS" />
|
||||||
|
<input type="hidden" name="status" value="{$advanced_mailer_status}" />
|
||||||
|
<select name="clear_before_days" style="width:120px">
|
||||||
|
<option value="0">{$lang->cmd_advanced_mailer_clear_log_condition_all}</option>
|
||||||
|
<option value="1">{sprintf($lang->cmd_advanced_mailer_clear_log_condition, 1)}</option>
|
||||||
|
<option value="3">{sprintf($lang->cmd_advanced_mailer_clear_log_condition, 3)}</option>
|
||||||
|
<option value="7" selected="selected">{sprintf($lang->cmd_advanced_mailer_clear_log_condition, 7)}</option>
|
||||||
|
<option value="14">{sprintf($lang->cmd_advanced_mailer_clear_log_condition, 14)}</option>
|
||||||
|
<option value="30">{sprintf($lang->cmd_advanced_mailer_clear_log_condition, 30)}</option>
|
||||||
|
<option value="60">{sprintf($lang->cmd_advanced_mailer_clear_log_condition, 60)}</option>
|
||||||
|
</select>
|
||||||
|
<button class="x_btn" type="submit" disabled="disabled"|cond="!count($advanced_mailer_log)">{$lang->cmd_advanced_mailer_clear_log_button}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
48
modules/advanced_mailer/tpl/sms_test.html
Normal file
48
modules/advanced_mailer/tpl/sms_test.html
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
<include target="./common.html" />
|
||||||
|
<load target="css/config.css" />
|
||||||
|
<load target="js/config.js" />
|
||||||
|
|
||||||
|
<form class="x_form-horizontal" action="./" method="post" id="advanced_mailer">
|
||||||
|
<input type="hidden" name="module" value="advanced_mailer" />
|
||||||
|
<input type="hidden" name="act" value="procAdvanced_mailerAdminTestSendSMS" />
|
||||||
|
<input type="hidden" name="success_return_url" value="{getRequestUriByServerEnviroment()}" />
|
||||||
|
|
||||||
|
<div cond="$XE_VALIDATOR_MESSAGE" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
|
||||||
|
<p>{$XE_VALIDATOR_MESSAGE}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
|
||||||
|
<h2>{$lang->cmd_advanced_mailer_sms_test}</h2>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="advanced_mailer_recipient_number">{$lang->cmd_advanced_mailer_recipient_number}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<input type="text" id="advanced_mailer_recipient_number" value="{config('sms.default_from')}" />
|
||||||
|
{$lang->cmd_advanced_mailer_country_code}
|
||||||
|
<input type="number" id="advanced_mailer_country_code" value="" />
|
||||||
|
<p class="x_help-block">{$lang->cmd_advanced_mailer_country_code_help}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label" for="advanced_mailer_content">{$lang->cmd_advanced_mailer_status_content}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<textarea id="advanced_mailer_content">{$lang->cmd_advanced_mailer_test_content}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label">{$lang->cmd_advanced_mailer_test_result}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<div id="advanced_mailer_test_result"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<div class="btnArea x_clearfix">
|
||||||
|
<button id="advanced_mailer_test_send_sms" type="submit" class="x_btn x_btn-primary x_pull-right">{$lang->cmd_advanced_mailer_send}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
@ -488,6 +488,7 @@ class autoinstallAdminView extends autoinstall
|
||||||
|
|
||||||
$security = new Security();
|
$security = new Security();
|
||||||
$security->encodeHTML('package.', 'package.depends..', 'item_list..');
|
$security->encodeHTML('package.', 'package.depends..', 'item_list..');
|
||||||
|
$security->encodeHTML('search_target', 'search_keyword');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ class boardController extends board
|
||||||
$obj->update_order = $obj->list_order = (getNextSequence() * -1);
|
$obj->update_order = $obj->list_order = (getNextSequence() * -1);
|
||||||
}
|
}
|
||||||
$obj->reason_update = escape($obj->reason_update);
|
$obj->reason_update = escape($obj->reason_update);
|
||||||
$output = $oDocumentController->updateDocument($oDocument, $obj, true);
|
$output = $oDocumentController->updateDocument($oDocument, $obj, $bAnonymous);
|
||||||
$msg_code = 'success_updated';
|
$msg_code = 'success_updated';
|
||||||
|
|
||||||
// insert a new document otherwise
|
// insert a new document otherwise
|
||||||
|
|
@ -196,8 +196,6 @@ class boardController extends board
|
||||||
$oMail->send();
|
$oMail->send();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -523,17 +521,13 @@ class boardController extends board
|
||||||
|
|
||||||
if($this->module_info->comment_delete_message === 'yes' && $instant_delete != 'Y')
|
if($this->module_info->comment_delete_message === 'yes' && $instant_delete != 'Y')
|
||||||
{
|
{
|
||||||
$comment->content = '';
|
|
||||||
$comment->status = 7;
|
|
||||||
$output = $oCommentController->updateCommentByDelete($comment, $this->grant->manager);
|
$output = $oCommentController->updateCommentByDelete($comment, $this->grant->manager);
|
||||||
}
|
}
|
||||||
elseif($this->module_info->comment_delete_message === 'only_commnet' && $instant_delete != 'Y')
|
elseif(starts_with('only_comm', $this->module_info->comment_delete_message) && $instant_delete != 'Y')
|
||||||
{
|
{
|
||||||
$childs = $oCommentModel->getChildComments($comment_srl);
|
$childs = $oCommentModel->getChildComments($comment_srl);
|
||||||
if(count($childs) > 0)
|
if(count($childs) > 0)
|
||||||
{
|
{
|
||||||
$comment->content = '';
|
|
||||||
$comment->status = 7;
|
|
||||||
$output = $oCommentController->updateCommentByDelete($comment, $this->grant->manager);
|
$output = $oCommentController->updateCommentByDelete($comment, $this->grant->manager);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -673,6 +673,7 @@ class boardView extends board
|
||||||
$group_srls_count = count($group_srls);
|
$group_srls_count = count($group_srls);
|
||||||
|
|
||||||
// check the grant after obtained the category list
|
// check the grant after obtained the category list
|
||||||
|
$category_list = array();
|
||||||
$normal_category_list = $oDocumentModel->getCategoryList($this->module_srl);
|
$normal_category_list = $oDocumentModel->getCategoryList($this->module_srl);
|
||||||
if(count($normal_category_list))
|
if(count($normal_category_list))
|
||||||
{
|
{
|
||||||
|
|
@ -689,7 +690,25 @@ class boardView extends board
|
||||||
if($is_granted) $category_list[$category_srl] = $category;
|
if($is_granted) $category_list[$category_srl] = $category;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Context::set('category_list', $category_list);
|
|
||||||
|
// check if at least one category is granted
|
||||||
|
$grant_exists = false;
|
||||||
|
foreach ($category_list as $category)
|
||||||
|
{
|
||||||
|
if ($category->grant)
|
||||||
|
{
|
||||||
|
$grant_exists = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($grant_exists)
|
||||||
|
{
|
||||||
|
Context::set('category_list', $category_list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->module_info->use_category = 'N';
|
||||||
|
Context::set('category_list', array());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET parameter document_srl from request
|
// GET parameter document_srl from request
|
||||||
|
|
@ -1191,6 +1210,69 @@ class boardView extends board
|
||||||
$this->setTemplateFile('update_view');
|
$this->setTemplateFile('update_view');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dispBoardVoteLog()
|
||||||
|
{
|
||||||
|
iF($this->grant->vote_log_view !== true)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_not_permitted');
|
||||||
|
}
|
||||||
|
|
||||||
|
$oMemberModel = getModel('member');
|
||||||
|
|
||||||
|
$target = Context::get('target');
|
||||||
|
$target_srl = Context::get('target_srl');
|
||||||
|
|
||||||
|
$args = new stdClass();
|
||||||
|
if($target === 'document')
|
||||||
|
{
|
||||||
|
$queryId = 'document.getDocumentVotedLog';
|
||||||
|
$args->document_srl = $target_srl;
|
||||||
|
}
|
||||||
|
elseif($target === 'comment')
|
||||||
|
{
|
||||||
|
$queryId = 'comment.getCommentVotedLog';
|
||||||
|
$args->comment_srl = $target_srl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_not_target');
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = executeQueryArray($queryId, $args);
|
||||||
|
if(!$output->toBool())
|
||||||
|
{
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
$vote_member_infos = array();
|
||||||
|
$blame_member_infos = array();
|
||||||
|
if(count($output->data) > 0)
|
||||||
|
{
|
||||||
|
foreach($output->data as $key => $log)
|
||||||
|
{
|
||||||
|
if($log->point > 0)
|
||||||
|
{
|
||||||
|
if($log->member_srl == $vote_member_infos[$log->member_srl]->member_srl)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$vote_member_infos[$log->member_srl] = $oMemberModel->getMemberInfoByMemberSrl($log->member_srl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if($log->member_srl == $blame_member_infos[$log->member_srl]->member_srl)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$blame_member_infos[$log->member_srl] = $oMemberModel->getMemberInfoByMemberSrl($log->member_srl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Context::set('vote_member_info', $vote_member_infos);
|
||||||
|
Context::set('blame_member_info', $blame_member_infos);
|
||||||
|
$this->setTemplateFile('vote_log');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief the method for displaying the warning messages
|
* @brief the method for displaying the warning messages
|
||||||
* display an error message if it has not a special design
|
* display an error message if it has not a special design
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@
|
||||||
<grant name="update_view" default="guest">
|
<grant name="update_view" default="guest">
|
||||||
<title xml:lang="ko">수정내역 조회</title>
|
<title xml:lang="ko">수정내역 조회</title>
|
||||||
</grant>
|
</grant>
|
||||||
|
<grant name="vote_log_view" default="guest">
|
||||||
|
<title xml:lang="ko">추천인 조회</title>
|
||||||
|
</grant>
|
||||||
<grant name="write_document" default="guest">
|
<grant name="write_document" default="guest">
|
||||||
<title xml:lang="ko">글 작성</title>
|
<title xml:lang="ko">글 작성</title>
|
||||||
<title xml:lang="zh-CN">发表新主题</title>
|
<title xml:lang="zh-CN">发表新主题</title>
|
||||||
|
|
@ -72,6 +75,7 @@
|
||||||
<action name="dispBoardContentCommentList" type="view" />
|
<action name="dispBoardContentCommentList" type="view" />
|
||||||
<action name="dispBoardContentFileList" type="view" />
|
<action name="dispBoardContentFileList" type="view" />
|
||||||
<action name="dispBoardUpdateLog" type="view" />
|
<action name="dispBoardUpdateLog" type="view" />
|
||||||
|
<action name="dispBoardVoteLog" type="view" />
|
||||||
|
|
||||||
<action name="dispBoardTagList" type="view" />
|
<action name="dispBoardTagList" type="view" />
|
||||||
<action name="dispBoardWrite" type="view" standalone="false" />
|
<action name="dispBoardWrite" type="view" standalone="false" />
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,21 @@ $lang->comment_status = 'Comments';
|
||||||
$lang->category_settings = 'Category settings';
|
$lang->category_settings = 'Category settings';
|
||||||
$lang->hide_category = 'Hide categories';
|
$lang->hide_category = 'Hide categories';
|
||||||
$lang->about_hide_category = 'You can disable a category feature.';
|
$lang->about_hide_category = 'You can disable a category feature.';
|
||||||
$lang->protect_content = 'Protect contents';
|
$lang->protect_content = 'Protect Content';
|
||||||
$lang->about_protect_content = 'If there is any comment on document, document\'s owner cannot modify or delete that.';
|
$lang->protect_comment = 'Protect Comment';
|
||||||
$lang->msg_protect_content = 'You cannot modify or delete document which has any comment on it.';
|
$lang->protect_regdate = 'Update/Delete Time Limit';
|
||||||
|
$lang->about_protect_regdate = 'Prevent updating or deleting a document or comment after a certain amount of time has passed. (Unit: day)';
|
||||||
|
$lang->about_protect_content = 'Prevent updating a document if there are comments on it.';
|
||||||
|
$lang->msg_protect_delete_content = 'You cannot delete a document with comments on it.';
|
||||||
|
$lang->msg_protect_update_content = 'You cannot update a document with comments on it.';
|
||||||
|
$lang->msg_admin_document_no_modify = 'You cannot edit the administrator\'s document.';
|
||||||
|
$lang->msg_admin_comment_no_modify = 'You cannot edit the administrator\'s comment.';
|
||||||
|
$lang->msg_board_delete_protect_comment = 'You cannot delete a comment when there are replies.';
|
||||||
|
$lang->msg_board_update_protect_comment = 'You cannot update a comment when there are replies.';
|
||||||
|
$lang->msg_protect_regdate_document = 'You cannot update or delete a document after %d days.';
|
||||||
|
$lang->msg_protect_regdate_comment = 'You cannot update or delete a comment after %d days.';
|
||||||
|
$lang->msg_dont_have_update_log = 'This document has no update log.';
|
||||||
|
$lang->original_letter = 'Original';
|
||||||
$lang->comment_delete_message = 'Leave Placeholder for Deleted Comment';
|
$lang->comment_delete_message = 'Leave Placeholder for Deleted Comment';
|
||||||
$lang->about_comment_delete_message = 'When a comment is deleted, leave a placeholder saying that it has been deleted.';
|
$lang->about_comment_delete_message = 'When a comment is deleted, leave a placeholder saying that it has been deleted.';
|
||||||
$lang->cmd_only_p_comment = 'Only if there are replies';
|
$lang->cmd_only_p_comment = 'Only if there are replies';
|
||||||
|
|
|
||||||
|
|
@ -48,16 +48,17 @@ $lang->about_hide_category = '임시로 분류를 사용하지 않으려면 체
|
||||||
$lang->protect_content = '글 보호 기능';
|
$lang->protect_content = '글 보호 기능';
|
||||||
$lang->protect_comment = '댓글 보호 기능';
|
$lang->protect_comment = '댓글 보호 기능';
|
||||||
$lang->protect_regdate = '기간 제한 기능';
|
$lang->protect_regdate = '기간 제한 기능';
|
||||||
$lang->about_protect_regdate = '작성된 글이나 댓글의 작성기간이 설정한 기간보다 이전일일 경우 글을 수정 또는 삭제할 수 없도록 합니다. (단위 : day)';
|
$lang->non_login_vote = '비 로그인 추천기능';
|
||||||
$lang->about_protect_content = '작성된 글에 댓글이 작성된 경우 글 작성자는 해당 글을 수정 또는 삭제를 할 수 없습니다.';
|
$lang->about_protect_regdate = '글이나 댓글을 작성한 후 일정 기간이 지나면 수정 또는 삭제할 수 없도록 합니다. (단위 : day)';
|
||||||
$lang->msg_protect_delete_content = '작성된 글에 댓글이 작성된 경우 글 작성자는 해당 글을 삭제할 수 없습니다. ';
|
$lang->about_protect_content = '댓글이 달린 글은 수정 또는 삭제할 수 없도록 합니다.';
|
||||||
$lang->msg_protect_update_content = '작성된 글에 댓글이 작성된 경우 글 작성자는 해당 글을 수정할 수 없습니다. ';
|
$lang->msg_protect_delete_content = '댓글이 달린 글은 삭제할 수 없습니다.';
|
||||||
|
$lang->msg_protect_update_content = '댓글이 달린 글은 수정할 수 없습니다.';
|
||||||
$lang->msg_admin_document_no_modify = '최고관리자의 게시물을 수정할 권한이 없습니다.';
|
$lang->msg_admin_document_no_modify = '최고관리자의 게시물을 수정할 권한이 없습니다.';
|
||||||
$lang->msg_admin_comment_no_modify = '최고관리자의 댓글을 수정할 권한이 없습니다.';
|
$lang->msg_admin_comment_no_modify = '최고관리자의 댓글을 수정할 권한이 없습니다.';
|
||||||
$lang->msg_board_delete_protect_comment = '댓글이 작성된 댓글의 글을 삭제할 수 없습니다.';
|
$lang->msg_board_delete_protect_comment = '대댓글이 달린 댓글은 삭제할 수 없습니다.';
|
||||||
$lang->msg_board_update_protect_comment = '댓글이 작성된 댓글의 글을 수정할 수 없습니다.';
|
$lang->msg_board_update_protect_comment = '대댓글이 달린 댓글은 수정할 수 없습니다.';
|
||||||
$lang->msg_protect_regdate_document = '%s일 이전의 게시글은 수정 또는 삭제 할 수 없습니다.';
|
$lang->msg_protect_regdate_document = '%d일 이상 지난 글은 수정 또는 삭제할 수 없습니다.';
|
||||||
$lang->msg_protect_regdate_comment = '%s일 이전의 댓글은 수정 또는 삭제 할 수 없습니다.';
|
$lang->msg_protect_regdate_comment = '%d일 이상 지난 댓글은 수정 또는 삭제할 수 없습니다.';
|
||||||
$lang->msg_dont_have_update_log = '업데이트 로그가 기록되어 있지 않은 게시글입니다.';
|
$lang->msg_dont_have_update_log = '업데이트 로그가 기록되어 있지 않은 게시글입니다.';
|
||||||
$lang->original_letter = '원본글';
|
$lang->original_letter = '원본글';
|
||||||
$lang->msg_warning_update_log = '<span class="x_label x_label-important">주의!</span> 사용시 디비가 많이 늘어날 수 있습니다.';
|
$lang->msg_warning_update_log = '<span class="x_label x_label-important">주의!</span> 사용시 디비가 많이 늘어날 수 있습니다.';
|
||||||
|
|
@ -78,3 +79,6 @@ $lang->cmd_all_comment_message = '모든 댓글에 남김';
|
||||||
$lang->cmd_do_not_message = '남기지 않음';
|
$lang->cmd_do_not_message = '남기지 않음';
|
||||||
$lang->delete_placeholder = '완전 삭제';
|
$lang->delete_placeholder = '완전 삭제';
|
||||||
$lang->msg_document_notify_mail = '[%s] 새로운 게시글이 등록되었습니다 : %s';
|
$lang->msg_document_notify_mail = '[%s] 새로운 게시글이 등록되었습니다 : %s';
|
||||||
|
$lang->cmd_document_vote_user = '이 글의 추천인 목록';
|
||||||
|
$lang->cmd_comment_vote_user = '이 댓글의 추천인 목록';
|
||||||
|
$lang->msg_not_target = '문서 또는 댓글의 추천인목록만 조회가능합니다.';
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,7 @@
|
||||||
<input type="hidden" name="comment_srl" value="{$comment->get('comment_srl')}" />
|
<input type="hidden" name="comment_srl" value="{$comment->get('comment_srl')}" />
|
||||||
</form>
|
</form>
|
||||||
<!--@else-->
|
<!--@else-->
|
||||||
<div class="xe_content">
|
{$comment->getContent(false)}
|
||||||
<!--@if($comment->status == 7)-->
|
|
||||||
{$lang->msg_deleted_comment}
|
|
||||||
<!--@elseif($comment->status == 8)-->
|
|
||||||
{$lang->msg_admin_deleted_comment}
|
|
||||||
<!--@end-->
|
|
||||||
</div>
|
|
||||||
<block cond="$comment->status < 7">
|
|
||||||
{$comment->getContent(false)}
|
|
||||||
</block>
|
|
||||||
<!--@end-->
|
<!--@end-->
|
||||||
<div cond="$comment->hasUploadedFiles()" class="fileList">
|
<div cond="$comment->hasUploadedFiles()" class="fileList">
|
||||||
<button type="button" class="toggleFile" onclick="jQuery(this).next('ul.files').toggle();"><i class="xi-diskette"></i> {$lang->uploaded_file} [<strong>{$comment->get('uploaded_count')}</strong>]</button>
|
<button type="button" class="toggleFile" onclick="jQuery(this).next('ul.files').toggle();"><i class="xi-diskette"></i> {$lang->uploaded_file} [<strong>{$comment->get('uploaded_count')}</strong>]</button>
|
||||||
|
|
@ -42,7 +33,8 @@
|
||||||
<li loop="$comment->getUploadedFiles()=>$key,$file"><a href="{getUrl('')}{$file->download_url}">{$file->source_filename} <span class="fileSize">[File Size:{FileHandler::filesize($file->file_size)}/Download:{number_format($file->download_count)}]</span></a></li>
|
<li loop="$comment->getUploadedFiles()=>$key,$file"><a href="{getUrl('')}{$file->download_url}">{$file->source_filename} <span class="fileSize">[File Size:{FileHandler::filesize($file->file_size)}/Download:{number_format($file->download_count)}]</span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p class="action" cond="$comment->status < 7">
|
<p class="action" cond="!$comment->isDeleted()">
|
||||||
|
<a href="{getUrl('act','dispBoardVoteLog','target_srl',$comment->comment_srl,'target','comment')}">{$lang->cmd_comment_vote_user}</a>
|
||||||
<a cond="$comment->getVote() === false || $comment->getVote() < 0" href="#" onclick="doCallModuleAction('comment','procCommentVoteUp','{$comment->comment_srl}');return false;"|cond="$is_logged" class="voted"><i class="xi-thumbs-up"></i>{$lang->cmd_vote}{$comment->get('voted_count')}</a>
|
<a cond="$comment->getVote() === false || $comment->getVote() < 0" href="#" onclick="doCallModuleAction('comment','procCommentVoteUp','{$comment->comment_srl}');return false;"|cond="$is_logged" class="voted"><i class="xi-thumbs-up"></i>{$lang->cmd_vote}{$comment->get('voted_count')}</a>
|
||||||
<a cond="$comment->getVote() > 0" href="#" onclick="doCallModuleAction('comment','procCommentVoteUpCancel','{$comment->comment_srl}');return false;"|cond="$is_logged" class="voted"><i class="xi-thumbs-up"></i>{$lang->cmd_vote}{$comment->get('voted_count')}</a>
|
<a cond="$comment->getVote() > 0" href="#" onclick="doCallModuleAction('comment','procCommentVoteUpCancel','{$comment->comment_srl}');return false;"|cond="$is_logged" class="voted"><i class="xi-thumbs-up"></i>{$lang->cmd_vote}{$comment->get('voted_count')}</a>
|
||||||
<a cond="$comment->getVote() === false || $comment->getVote() > 0" href="#" onclick="doCallModuleAction('comment','procCommentVoteDown','{$comment->comment_srl}');return false;"|cond="$is_logged" class="voted"><i class="xi-thumbs-up"></i>{$lang->cmd_vote_down}{$comment->get('blamed_count')}</a>
|
<a cond="$comment->getVote() === false || $comment->getVote() > 0" href="#" onclick="doCallModuleAction('comment','procCommentVoteDown','{$comment->comment_srl}');return false;"|cond="$is_logged" class="voted"><i class="xi-thumbs-up"></i>{$lang->cmd_vote_down}{$comment->get('blamed_count')}</a>
|
||||||
|
|
@ -52,7 +44,7 @@
|
||||||
<a cond="$comment->isGranted()||!$comment->get('member_srl')" href="{getUrl('act','dispBoardDeleteComment','comment_srl',$comment->comment_srl)}" class="delete"><i class="xi-trash"></i> {$lang->cmd_delete}</a>
|
<a cond="$comment->isGranted()||!$comment->get('member_srl')" href="{getUrl('act','dispBoardDeleteComment','comment_srl',$comment->comment_srl)}" class="delete"><i class="xi-trash"></i> {$lang->cmd_delete}</a>
|
||||||
<a cond="$is_logged" class="comment_{$comment->comment_srl} this" href="#popup_menu_area" onclick="return false">{$lang->cmd_comment_do}</a>
|
<a cond="$is_logged" class="comment_{$comment->comment_srl} this" href="#popup_menu_area" onclick="return false">{$lang->cmd_comment_do}</a>
|
||||||
</p>
|
</p>
|
||||||
<p class="action" cond="$comment->status >= 7">
|
<p class="action" cond="$comment->isDeleted()">
|
||||||
<a cond="$grant->manager" href="{getUrl('act','dispBoardDeleteComment','comment_srl',$comment->comment_srl)}" class="delete"><i class="xi-trash"></i> {$lang->delete_placeholder}</a>
|
<a cond="$grant->manager" href="{getUrl('act','dispBoardDeleteComment','comment_srl',$comment->comment_srl)}" class="delete"><i class="xi-trash"></i> {$lang->delete_placeholder}</a>
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
||||||
|
|
@ -84,12 +84,12 @@
|
||||||
<div class="vote">
|
<div class="vote">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a cond="$oDocument->getVoted() === false || $oDocument->getVoted() < 0" href="#" onclick="doCallModuleAction('document','procDocumentVoteUp','{$oDocument->document_srl}');return false;"|cond="$is_logged" class="voted"> <i class="xi-thumbs-up"></i><br>{$lang->cmd_vote} {$oDocument->get('voted_count')}</a>
|
<a cond="$oDocument->getVoted() === false || $oDocument->getVoted() < 0" href="#" onclick="doCallModuleAction('document','procDocumentVoteUp','{$oDocument->document_srl}');return false;" class="voted"> <i class="xi-thumbs-up"></i><br>{$lang->cmd_vote} {$oDocument->get('voted_count')}</a>
|
||||||
<a cond="$oDocument->getVoted() > 0" href="#" onclick="doCallModuleAction('document','procDocumentVoteUpCancel','{$oDocument->document_srl}');return false;"|cond="$is_logged" class="voted"> <i class="xi-thumbs-up"></i><br>{$lang->cmd_vote} {$oDocument->get('voted_count')}</a>
|
<a cond="$oDocument->getVoted() > 0" href="#" onclick="doCallModuleAction('document','procDocumentVoteUpCancel','{$oDocument->document_srl}');return false;" class="voted"> <i class="xi-thumbs-up"></i><br>{$lang->cmd_vote} {$oDocument->get('voted_count')}</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a cond="$oDocument->getVoted() === false || $oDocument->getVoted() > 0" herf="#" onclick="doCallModuleAction('document','procDocumentVoteDown','{$oDocument->document_srl}');return false;"|cond="$is_logged" class="voted"> <i class="xi-thumbs-down"></i><br>{$lang->cmd_vote_down} {$oDocument->get('blamed_count')}</a>
|
<a cond="$oDocument->getVoted() === false || $oDocument->getVoted() > 0" herf="#" onclick="doCallModuleAction('document','procDocumentVoteDown','{$oDocument->document_srl}');return false;" class="voted"> <i class="xi-thumbs-down"></i><br>{$lang->cmd_vote_down} {$oDocument->get('blamed_count')}</a>
|
||||||
<a cond="$oDocument->getVoted() < 0" herf="#" onclick="doCallModuleAction('document','procDocumentVoteDownCancel','{$oDocument->document_srl}');return false;"|cond="$is_logged" class="voted"> <i class="xi-thumbs-down"></i><br>{$lang->cmd_vote_down} {$oDocument->get('blamed_count')}</a>
|
<a cond="$oDocument->getVoted() < 0" herf="#" onclick="doCallModuleAction('document','procDocumentVoteDownCancel','{$oDocument->document_srl}');return false;" class="voted"> <i class="xi-thumbs-down"></i><br>{$lang->cmd_vote_down} {$oDocument->get('blamed_count')}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -115,6 +115,7 @@
|
||||||
<div cond="$oDocument->getSignature()" class="tx">{$oDocument->getSignature()}</div>
|
<div cond="$oDocument->getSignature()" class="tx">{$oDocument->getSignature()}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="btnArea">
|
<div class="btnArea">
|
||||||
|
<a class="btn" href="{getUrl('act','dispBoardVoteLog','target_srl',$oDocument->document_srl,'target','document')}"><i class="xi-list-ul"></i>{$lang->cmd_document_vote_user}</a>
|
||||||
<a cond="$update_view" class="btn" href="{getUrl('act','dispBoardUpdateLog','document_srl',$oDocument->document_srl,'comment_srl','')}"><i class="xi-list-ul"></i>{$lang->update_log}</a>
|
<a cond="$update_view" class="btn" href="{getUrl('act','dispBoardUpdateLog','document_srl',$oDocument->document_srl,'comment_srl','')}"><i class="xi-list-ul"></i>{$lang->update_log}</a>
|
||||||
<a cond="$oDocument->isEditable()" class="btn" href="{getUrl('act','dispBoardWrite','document_srl',$oDocument->document_srl,'comment_srl','')}"><i class="xi-eraser"></i>{$lang->cmd_modify}</a>
|
<a cond="$oDocument->isEditable()" class="btn" href="{getUrl('act','dispBoardWrite','document_srl',$oDocument->document_srl,'comment_srl','')}"><i class="xi-eraser"></i>{$lang->cmd_modify}</a>
|
||||||
<a cond="$oDocument->isEditable()" class="btn" href="{getUrl('act','dispBoardDelete','document_srl',$oDocument->document_srl,'comment_srl','')}"><i class="xi-trash"></i>{$lang->cmd_delete}</a>
|
<a cond="$oDocument->isEditable()" class="btn" href="{getUrl('act','dispBoardDelete','document_srl',$oDocument->document_srl,'comment_srl','')}"><i class="xi-trash"></i>{$lang->cmd_delete}</a>
|
||||||
|
|
|
||||||
|
|
@ -737,6 +737,10 @@
|
||||||
.feedback .xe_content *:first-child {
|
.feedback .xe_content *:first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
.feedback .xe_content.is_deleted,
|
||||||
|
.feedback .xe_content.is_secret {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
#trackback .xe_content {
|
#trackback .xe_content {
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
@ -1127,4 +1131,25 @@
|
||||||
.board .secretForm .btn {border-radius: 0 2px 2px 0; }
|
.board .secretForm .btn {border-radius: 0 2px 2px 0; }
|
||||||
.board .secretForm p {margin-bottom:5px;}
|
.board .secretForm p {margin-bottom:5px;}
|
||||||
|
|
||||||
|
.vote-list {
|
||||||
|
display:block;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
margin: 0px !important;
|
||||||
|
padding: 20px;
|
||||||
|
color: rgb(34, 34, 34);
|
||||||
|
font-size: 15px;
|
||||||
|
font-family: "Open Sans","나눔바른고딕",NanumBarunGothic,"맑은 고딕","Malgun Gothic","돋움",Dotum,"애플 SD 산돌고딕 Neo","Apple SD Gothic Neo",AppleGothic,Helvetica,sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
background: rgb(255, 255, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
.votelog {
|
||||||
|
display:inline-block;
|
||||||
|
padding:2px 15px;
|
||||||
|
background:#00b0a2;
|
||||||
|
border-radius: 23px;
|
||||||
|
color:#fff;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
14
modules/board/skins/xedition/vote_log.html
Normal file
14
modules/board/skins/xedition/vote_log.html
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
<include target="_header.html" />
|
||||||
|
|
||||||
|
<div class="vote-list">
|
||||||
|
<h2>추천인</h2>
|
||||||
|
<block loop="$vote_member_info => $val">
|
||||||
|
<a href="#popup_menu_area" class="votelog member_{$val->member_srl}" onclick="return false">{$val->nick_name}</a>
|
||||||
|
</block>
|
||||||
|
<h2>비추천인</h2>
|
||||||
|
<block loop="$blame_member_info => $val">
|
||||||
|
<a href="#popup_menu_area" class="votelog member_{$val->member_srl}" onclick="return false">{$val->nick_name}</a>
|
||||||
|
</block>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<include target="_footer.html" />
|
||||||
|
|
@ -280,12 +280,11 @@
|
||||||
<select name="comment_delete_message" id="comment_delete_message">
|
<select name="comment_delete_message" id="comment_delete_message">
|
||||||
<option value="no" selected="selected"|cond="$module_info->comment_delete_message == 'no'">{$lang->cmd_do_not_message}</option>
|
<option value="no" selected="selected"|cond="$module_info->comment_delete_message == 'no'">{$lang->cmd_do_not_message}</option>
|
||||||
<option value="yes" selected="selected"|cond="$module_info->comment_delete_message == 'yes'">{$lang->cmd_all_comment_message}</option>
|
<option value="yes" selected="selected"|cond="$module_info->comment_delete_message == 'yes'">{$lang->cmd_all_comment_message}</option>
|
||||||
<option value="only_commnet" selected="selected"|cond="$module_info->comment_delete_message == 'only_commnet'">{$lang->cmd_only_p_comment}</option>
|
<option value="only_comment" selected="selected"|cond="starts_with('only_comm', $module_info->comment_delete_message)">{$lang->cmd_only_p_comment}</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="x_help-block">{$lang->about_comment_delete_message}</p>
|
<p class="x_help-block">{$lang->about_comment_delete_message}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="x_control-group">
|
<div class="x_control-group">
|
||||||
<label class="x_control-label">{$lang->status}</label>
|
<label class="x_control-label">{$lang->status}</label>
|
||||||
<div class="x_controls">
|
<div class="x_controls">
|
||||||
|
|
@ -299,6 +298,18 @@
|
||||||
<p class="x_help-block">{$lang->about_use_status}</p>
|
<p class="x_help-block">{$lang->about_use_status}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="x_control-group">
|
||||||
|
<label class="x_control-label">{$lang->non_login_vote}</label>
|
||||||
|
<div class="x_controls">
|
||||||
|
<label class="x_inline">
|
||||||
|
<input type="radio" id="non_login_vote_y" name="non_login_vote" value="Y" checked="checked"|cond="$module_info->non_login_vote == 'Y'" /> {$lang->use}
|
||||||
|
</label>
|
||||||
|
<label class="x_inline">
|
||||||
|
<input type="radio" id="non_login_vote_n" name="non_login_vote" value="N" checked="checked"|cond="$module_info->non_login_vote != 'Y'" /> {$lang->notuse}
|
||||||
|
</label>
|
||||||
|
<p class="x_help-block">{$lang->about_document_force_to_move}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="x_control-group">
|
<div class="x_control-group">
|
||||||
<label class="x_control-label" for="admin_mail">{$lang->admin_mail}</label>
|
<label class="x_control-label" for="admin_mail">{$lang->admin_mail}</label>
|
||||||
<div class="x_controls">
|
<div class="x_controls">
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@
|
||||||
<option value="mid" selected="selected"|cond="$search_target=='mid'">{$lang->mid}</option>
|
<option value="mid" selected="selected"|cond="$search_target=='mid'">{$lang->mid}</option>
|
||||||
<option value="browser_title" selected="selected"|cond="$search_target=='browser_title'">{$lang->browser_title}</option>
|
<option value="browser_title" selected="selected"|cond="$search_target=='browser_title'">{$lang->browser_title}</option>
|
||||||
</select>
|
</select>
|
||||||
<input type="search" required name="search_keyword" value="{htmlspecialchars($search_keyword)}" />
|
<input type="search" name="search_keyword" value="{htmlspecialchars($search_keyword)}" />
|
||||||
<button class="x_btn x_btn-inverse" type="submit">{$lang->cmd_search}</button>
|
<button class="x_btn x_btn-inverse" type="submit">{$lang->cmd_search}</button>
|
||||||
<a class="x_btn" href="{getUrl('', 'module', $module, 'act', $act)}">{$lang->cmd_cancel}</a>
|
<a class="x_btn" href="{getUrl('', 'module', $module, 'act', $act)}">{$lang->cmd_cancel}</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,9 @@ class commentAdminView extends comment
|
||||||
}
|
}
|
||||||
Context::set('member_nick_name', $member_nick_neme);
|
Context::set('member_nick_name', $member_nick_neme);
|
||||||
|
|
||||||
|
$security = new Security();
|
||||||
|
$security->encodeHTML('search_target', 'search_keyword');
|
||||||
|
|
||||||
// set the template
|
// set the template
|
||||||
$this->setTemplatePath($this->module_path . 'tpl');
|
$this->setTemplatePath($this->module_path . 'tpl');
|
||||||
$this->setTemplateFile('comment_list');
|
$this->setTemplateFile('comment_list');
|
||||||
|
|
|
||||||
|
|
@ -912,23 +912,36 @@ class commentController extends comment
|
||||||
*/
|
*/
|
||||||
function updateCommentByDelete($obj, $is_admin = FALSE)
|
function updateCommentByDelete($obj, $is_admin = FALSE)
|
||||||
{
|
{
|
||||||
$logged_info = Context::get('logged_info');
|
if (!$obj->comment_srl)
|
||||||
|
{
|
||||||
|
return new Object(-1, 'msg_invalid_request');
|
||||||
|
}
|
||||||
|
|
||||||
|
// call a trigger (before)
|
||||||
|
$output = ModuleHandler::triggerCall('comment.deleteComment', 'before', $comment);
|
||||||
|
if(!$output->toBool())
|
||||||
|
{
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
// begin transaction
|
// begin transaction
|
||||||
$oDB = DB::getInstance();
|
$oDB = DB::getInstance();
|
||||||
$oDB->begin();
|
$oDB->begin();
|
||||||
|
|
||||||
// If the case manager to delete comments, it indicated that the administrator deleted.
|
// If the case manager to delete comments, it indicated that the administrator deleted.
|
||||||
|
$logged_info = Context::get('logged_info');
|
||||||
if($is_admin === true && $obj->member_srl !== $logged_info->member_srl)
|
if($is_admin === true && $obj->member_srl !== $logged_info->member_srl)
|
||||||
{
|
{
|
||||||
$obj->content = lang('msg_admin_deleted_comment');
|
$obj->content = lang('msg_admin_deleted_comment');
|
||||||
$obj->status = 8;
|
$obj->status = RX_STATUS_DELETED_BY_ADMIN;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$obj->content = lang('msg_deleted_comment');
|
$obj->content = lang('msg_deleted_comment');
|
||||||
|
$obj->status = RX_STATUS_DELETED;
|
||||||
}
|
}
|
||||||
$obj->member_srl = 0;
|
$obj->member_srl = 0;
|
||||||
|
unset($obj->last_update);
|
||||||
$output = executeQuery('comment.updateCommentByDelete', $obj);
|
$output = executeQuery('comment.updateCommentByDelete', $obj);
|
||||||
if(!$output->toBool())
|
if(!$output->toBool())
|
||||||
{
|
{
|
||||||
|
|
@ -936,8 +949,8 @@ class commentController extends comment
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
// call a trigger by delete (after)
|
// call a trigger (after)
|
||||||
ModuleHandler::triggerCall('comment.updateCommentByDelete', 'after', $obj);
|
ModuleHandler::triggerCall('comment.deleteComment', 'after', $obj);
|
||||||
|
|
||||||
// update the number of comments
|
// update the number of comments
|
||||||
$oCommentModel = getModel('comment');
|
$oCommentModel = getModel('comment');
|
||||||
|
|
@ -1116,6 +1129,9 @@ class commentController extends comment
|
||||||
$output = executeQuery('file.updateFileValid', $args);
|
$output = executeQuery('file.updateFileValid', $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the thumbnail file
|
||||||
|
Rhymix\Framework\Storage::deleteEmptyDirectory(RX_BASEDIR . sprintf('files/thumbnails/%s', getNumberingPath($comment_srl, 3)), true);
|
||||||
|
|
||||||
// commit
|
// commit
|
||||||
$oDB->commit();
|
$oDB->commit();
|
||||||
|
|
||||||
|
|
@ -1372,13 +1388,15 @@ class commentController extends comment
|
||||||
{
|
{
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
$declared_count = ($output->data->declared_count) ? $output->data->declared_count : 0;
|
$declared_count = ($output->data->declared_count) ? $output->data->declared_count : 0;
|
||||||
|
$declare_message = trim(htmlspecialchars($declare_message));
|
||||||
|
|
||||||
$trigger_obj = new stdClass();
|
$trigger_obj = new stdClass();
|
||||||
$trigger_obj->comment_srl = $comment_srl;
|
$trigger_obj->comment_srl = $comment_srl;
|
||||||
$trigger_obj->declared_count = $declared_count;
|
$trigger_obj->declared_count = $declared_count;
|
||||||
|
$trigger_obj->declare_message = $declare_message;
|
||||||
|
|
||||||
// Call a trigger (before)
|
// Call a trigger (before)
|
||||||
$trigger_output = ModuleHandler::triggerCall('comment.declaredComment', 'before', $trigger_obj);
|
$trigger_output = ModuleHandler::triggerCall('comment.declaredComment', 'before', $trigger_obj);
|
||||||
if(!$trigger_output->toBool())
|
if(!$trigger_output->toBool())
|
||||||
|
|
@ -1423,7 +1441,7 @@ class commentController extends comment
|
||||||
}
|
}
|
||||||
|
|
||||||
$args->comment_srl = $comment_srl;
|
$args->comment_srl = $comment_srl;
|
||||||
$args->declare_message = trim(htmlspecialchars($declare_message));
|
$args->declare_message = $declare_message;
|
||||||
$log_output = executeQuery('comment.getCommentDeclaredLogInfo', $args);
|
$log_output = executeQuery('comment.getCommentDeclaredLogInfo', $args);
|
||||||
|
|
||||||
// session registered if log info contains report log.
|
// session registered if log info contains report log.
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,16 @@ class commentItem extends Object
|
||||||
return $this->get('is_secret') == 'Y' ? TRUE : FALSE;
|
return $this->get('is_secret') == 'Y' ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDeleted()
|
||||||
|
{
|
||||||
|
return $this->get('status') == RX_STATUS_DELETED || $this->get('status') == RX_STATUS_DELETED_BY_ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDeletedByAdmin()
|
||||||
|
{
|
||||||
|
return $this->get('status') == RX_STATUS_DELETED_BY_ADMIN;
|
||||||
|
}
|
||||||
|
|
||||||
function isAccessible()
|
function isAccessible()
|
||||||
{
|
{
|
||||||
if($_SESSION['accessibled_comment'][$this->comment_srl])
|
if($_SESSION['accessibled_comment'][$this->comment_srl])
|
||||||
|
|
@ -311,12 +321,22 @@ class commentItem extends Object
|
||||||
*/
|
*/
|
||||||
function getContentText($strlen = 0)
|
function getContentText($strlen = 0)
|
||||||
{
|
{
|
||||||
if($this->isSecret() && !$this->isAccessible())
|
if($this->isDeletedByAdmin())
|
||||||
{
|
{
|
||||||
return lang('msg_is_secret');
|
$content = lang('msg_admin_deleted_comment');
|
||||||
|
}
|
||||||
|
elseif($this->isDeleted())
|
||||||
|
{
|
||||||
|
$content = lang('msg_deleted_comment');
|
||||||
|
}
|
||||||
|
elseif($this->isSecret() && !$this->isAccessible())
|
||||||
|
{
|
||||||
|
$content = lang('msg_is_secret');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$content = $this->get('content');
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = $this->get('content');
|
|
||||||
|
|
||||||
if($strlen)
|
if($strlen)
|
||||||
{
|
{
|
||||||
|
|
@ -332,13 +352,27 @@ class commentItem extends Object
|
||||||
*/
|
*/
|
||||||
function getContent($add_popup_menu = TRUE, $add_content_info = TRUE, $add_xe_content_class = TRUE)
|
function getContent($add_popup_menu = TRUE, $add_content_info = TRUE, $add_xe_content_class = TRUE)
|
||||||
{
|
{
|
||||||
if($this->isSecret() && !$this->isAccessible())
|
if($this->isDeletedByAdmin())
|
||||||
{
|
{
|
||||||
return lang('msg_is_secret');
|
$content = lang('msg_admin_deleted_comment');
|
||||||
|
$additional_class = ' is_deleted is_deleted_by_admin';
|
||||||
|
}
|
||||||
|
elseif($this->isDeleted())
|
||||||
|
{
|
||||||
|
$content = lang('msg_deleted_comment');
|
||||||
|
$additional_class = ' is_deleted';
|
||||||
|
}
|
||||||
|
elseif($this->isSecret() && !$this->isAccessible())
|
||||||
|
{
|
||||||
|
$content = lang('msg_is_secret');
|
||||||
|
$additional_class = ' is_secret';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$content = $this->get('content');
|
||||||
|
$additional_class = '';
|
||||||
|
stripEmbedTagForAdmin($content, $this->get('member_srl'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = $this->get('content');
|
|
||||||
stripEmbedTagForAdmin($content, $this->get('member_srl'));
|
|
||||||
|
|
||||||
// when displaying the comment on the pop-up menu
|
// when displaying the comment on the pop-up menu
|
||||||
if($add_popup_menu && Context::get('is_logged'))
|
if($add_popup_menu && Context::get('is_logged'))
|
||||||
|
|
@ -351,21 +385,20 @@ class commentItem extends Object
|
||||||
// if additional information which can access contents is set
|
// if additional information which can access contents is set
|
||||||
if($add_content_info)
|
if($add_content_info)
|
||||||
{
|
{
|
||||||
$memberSrl = $this->get('member_srl');
|
$member_srl = $this->get('member_srl');
|
||||||
if($memberSrl < 0)
|
if($member_srl < 0)
|
||||||
{
|
{
|
||||||
$memberSrl = 0;
|
$member_srl = 0;
|
||||||
}
|
}
|
||||||
$content = sprintf(
|
$content = vsprintf('<!--BeforeComment(%d,%d)--><div class="comment_%d_%d xe_content%s">%s</div><!--AfterComment(%d,%d)-->', array(
|
||||||
'<!--BeforeComment(%d,%d)--><div class="comment_%d_%d xe_content">%s</div><!--AfterComment(%d,%d)-->', $this->comment_srl, $memberSrl, $this->comment_srl, $memberSrl, $content, $this->comment_srl, $memberSrl
|
$this->comment_srl, $member_srl, $this->comment_srl, $member_srl, $additional_class, $content, $this->comment_srl, $member_srl
|
||||||
);
|
));
|
||||||
// xe_content class name should be specified although content access is not necessary.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if($add_xe_content_class)
|
if($add_xe_content_class)
|
||||||
{
|
{
|
||||||
$content = sprintf('<div class="xe_content">%s</div>', $content);
|
$content = sprintf('<div class="xe_content%s">%s</div>', $additional_class, $content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -567,6 +600,24 @@ class commentItem extends Object
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get thumbnai_type information from document module's configuration
|
||||||
|
if(!in_array($thumbnail_type, array('crop', 'ratio', 'none')))
|
||||||
|
{
|
||||||
|
$config = $GLOBALS['__document_config__'];
|
||||||
|
if(!$config)
|
||||||
|
{
|
||||||
|
$oDocumentModel = getModel('document');
|
||||||
|
$config = $oDocumentModel->getDocumentConfig();
|
||||||
|
$GLOBALS['__document_config__'] = $config;
|
||||||
|
}
|
||||||
|
$thumbnail_type = $config->thumbnail_type ?: 'crop';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($thumbnail_type === 'none')
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if($this->isSecret() && !$this->isGranted())
|
if($this->isSecret() && !$this->isGranted())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -584,12 +635,6 @@ class commentItem extends Object
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get thumbail generation info on the doc module configuration.
|
|
||||||
if(!in_array($thumbnail_type, array('crop', 'ratio')))
|
|
||||||
{
|
|
||||||
$thumbnail_type = 'crop';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define thumbnail information
|
// Define thumbnail information
|
||||||
$thumbnail_path = sprintf('files/thumbnails/%s', getNumberingPath($this->comment_srl, 3));
|
$thumbnail_path = sprintf('files/thumbnails/%s', getNumberingPath($this->comment_srl, 3));
|
||||||
$thumbnail_file = sprintf('%s%dx%d.%s.jpg', $thumbnail_path, $width, $height, $thumbnail_type);
|
$thumbnail_file = sprintf('%s%dx%d.%s.jpg', $thumbnail_path, $width, $height, $thumbnail_type);
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,8 @@
|
||||||
<table name="comments" />
|
<table name="comments" />
|
||||||
</tables>
|
</tables>
|
||||||
<columns>
|
<columns>
|
||||||
<column name="module_srl" var="module_srl" filter="number" default="0" />
|
|
||||||
<column name="member_srl" var="member_srl" />
|
<column name="member_srl" var="member_srl" />
|
||||||
<column name="parent_srl" var="parent_srl" filter="number" />
|
|
||||||
<column name="is_secret" var="is_secret" default="N" />
|
|
||||||
<column name="notify_message" var="notify_message" default="N" />
|
|
||||||
<column name="content" var="content" notnull="notnull" />
|
<column name="content" var="content" notnull="notnull" />
|
||||||
<column name="password" var="password" minlength="2" maxlength="60" />
|
|
||||||
<column name="user_id" var="user_id" />
|
|
||||||
<column name="user_name" var="user_name" default="" />
|
|
||||||
<column name="nick_name" var="nick_name" notnull="notnull" minlength="1" maxlength="40" />
|
|
||||||
<column name="email_address" var="email_address" filter="email" maxlength="250" />
|
|
||||||
<column name="homepage" var="homepage" filter="homepage" maxlength="250" />
|
|
||||||
<column name="uploaded_count" var="uploaded_count" default="0" />
|
|
||||||
<column name="last_update" var="last_update" default="curdate()" />
|
<column name="last_update" var="last_update" default="curdate()" />
|
||||||
<column name="status" var="status" default="1" />
|
<column name="status" var="status" default="1" />
|
||||||
</columns>
|
</columns>
|
||||||
|
|
|
||||||
|
|
@ -835,6 +835,10 @@ class communicationController extends communication
|
||||||
{
|
{
|
||||||
return new Object();
|
return new Object();
|
||||||
}
|
}
|
||||||
|
if(!$oCommunicationModel->checkGrant($config->grant_send))
|
||||||
|
{
|
||||||
|
return new Object();
|
||||||
|
}
|
||||||
|
|
||||||
$mid = Context::get('cur_mid');
|
$mid = Context::get('cur_mid');
|
||||||
$member_srl = Context::get('target_srl');
|
$member_srl = Context::get('target_srl');
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,10 @@ class communicationView extends communication
|
||||||
{
|
{
|
||||||
return $this->stop('msg_invalid_request');
|
return $this->stop('msg_invalid_request');
|
||||||
}
|
}
|
||||||
|
if(!getModel('communication')->checkGrant($this->config->grant_send))
|
||||||
|
{
|
||||||
|
return $this->stop('msg_not_permitted');
|
||||||
|
}
|
||||||
|
|
||||||
// Error appears if not logged-in
|
// Error appears if not logged-in
|
||||||
if(!Context::get('is_logged'))
|
if(!Context::get('is_logged'))
|
||||||
|
|
@ -230,7 +234,7 @@ class communicationView extends communication
|
||||||
|
|
||||||
// set a signiture by calling getEditor of the editor module
|
// set a signiture by calling getEditor of the editor module
|
||||||
$oEditorModel = getModel('editor');
|
$oEditorModel = getModel('editor');
|
||||||
$option = new stdClass();
|
$option = $oEditorModel->getEditorConfig();
|
||||||
$option->primary_key_name = 'receiver_srl';
|
$option->primary_key_name = 'receiver_srl';
|
||||||
$option->content_key_name = 'content';
|
$option->content_key_name = 'content';
|
||||||
$option->allow_fileupload = FALSE;
|
$option->allow_fileupload = FALSE;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ $lang->communication = '커뮤니케이션';
|
||||||
$lang->about_communication = '회원 간의 쪽지나 친구 관리 등 커뮤니케이션 기능을 수행합니다. 이 기능을 사용하려면 [설치된 애드온] > [커뮤니케이션] 애드온을 활성화 하세요.';
|
$lang->about_communication = '회원 간의 쪽지나 친구 관리 등 커뮤니케이션 기능을 수행합니다. 이 기능을 사용하려면 [설치된 애드온] > [커뮤니케이션] 애드온을 활성화 하세요.';
|
||||||
$lang->allow_message = '쪽지 수신 허용';
|
$lang->allow_message = '쪽지 수신 허용';
|
||||||
$lang->allow_message_type['Y'] = '전체 수신';
|
$lang->allow_message_type['Y'] = '전체 수신';
|
||||||
$lang->allow_message_type['N'] = '거부';
|
$lang->allow_message_type['N'] = '수신 거부';
|
||||||
$lang->allow_message_type['F'] = '친구만 허용';
|
$lang->allow_message_type['F'] = '친구만 허용';
|
||||||
$lang->message_box['R'] = '받은 쪽지함';
|
$lang->message_box['R'] = '받은 쪽지함';
|
||||||
$lang->message_box['S'] = '보낸 쪽지함';
|
$lang->message_box['S'] = '보낸 쪽지함';
|
||||||
|
|
@ -14,12 +14,12 @@ $lang->receiver = '받는이';
|
||||||
$lang->friend_group = '친구 그룹';
|
$lang->friend_group = '친구 그룹';
|
||||||
$lang->default_friend_group = '그룹 미지정';
|
$lang->default_friend_group = '그룹 미지정';
|
||||||
$lang->cmd_send_message = '쪽지 보내기';
|
$lang->cmd_send_message = '쪽지 보내기';
|
||||||
$lang->cmd_reply_message = '쪽지 답장';
|
$lang->cmd_reply_message = '답장 보내기';
|
||||||
$lang->cmd_view_friend = '친구 보기';
|
$lang->cmd_view_friend = '친구 보기';
|
||||||
$lang->cmd_add_friend = '친구 등록';
|
$lang->cmd_add_friend = '친구 등록';
|
||||||
$lang->cmd_message_box = '쪽지함';
|
$lang->cmd_message_box = '쪽지함';
|
||||||
$lang->cmd_view_message_box = '쪽지함 보기';
|
$lang->cmd_view_message_box = '쪽지함 보기';
|
||||||
$lang->cmd_store = '보관';
|
$lang->cmd_store = '보관함 이동';
|
||||||
$lang->cmd_add_friend_group = '친구 그룹 추가';
|
$lang->cmd_add_friend_group = '친구 그룹 추가';
|
||||||
$lang->cmd_rename_friend_group = '친구 그룹 이름 변경';
|
$lang->cmd_rename_friend_group = '친구 그룹 이름 변경';
|
||||||
$lang->cmd_delete_friend_group = '친구 그룹 삭제';
|
$lang->cmd_delete_friend_group = '친구 그룹 삭제';
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue