Merge branch 'develop' into pr/advanced-mailer

This commit is contained in:
Kijin Sung 2016-05-10 14:00:26 +09:00
commit b971ea19ca
34 changed files with 798 additions and 108 deletions

View file

@ -92,6 +92,12 @@ class Context
*/
public $meta_tags = array();
/**
* OpenGraph metadata
* @var array
*/
public $opengraph_metadata = array();
/**
* path of Xpress Engine
* @var string
@ -810,24 +816,46 @@ class Context
}
/**
* Add string to browser title
* Append string to browser title
*
* @param string $site_title Browser title to be added
* @param string $site_title Browser title to be appended
* @return void
*/
public static function addBrowserTitle($site_title)
public static function addBrowserTitle($title)
{
if(!$site_title)
if(!$title)
{
return;
}
if(self::$_instance->site_title)
{
self::$_instance->site_title .= ' - ' . $site_title;
self::$_instance->site_title .= ' - ' . $title;
}
else
{
self::$_instance->site_title = $site_title;
self::$_instance->site_title = $title;
}
}
/**
* Prepend string to browser title
*
* @param string $site_title Browser title to be prepended
* @return void
*/
public static function prependBrowserTitle($title)
{
if(!$title)
{
return;
}
if(self::$_instance->site_title)
{
self::$_instance->site_title = $title . ' - ' . self::$_instance->site_title;
}
else
{
self::$_instance->site_title = $title;
}
}
@ -835,15 +863,22 @@ class Context
* Set string to browser title
*
* @param string $site_title Browser title to be set
* @param array $vars
* @return void
*/
public static function setBrowserTitle($site_title)
public static function setBrowserTitle($title, $vars = array())
{
if(!$site_title)
if (!$title)
{
return;
}
self::$_instance->site_title = $site_title;
if (count($vars))
{
$title = trim(trim(preg_replace_callback('/\\$(\w+)/', function($matches) use($vars) {
return isset($vars[strtolower($matches[1])]) ? $vars[strtolower($matches[1])] : $matches[0];
}, $title), ' -'));
}
self::$_instance->site_title = $title;
}
/**
@ -853,26 +888,52 @@ class Context
*/
public static function getBrowserTitle()
{
$oModuleController = getController('module');
$oModuleController->replaceDefinedLangCode(self::$_instance->site_title);
if (!self::$_instance->site_title)
{
return '';
}
getController('module')->replaceDefinedLangCode(self::$_instance->site_title);
return htmlspecialchars(self::$_instance->site_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', FALSE);
}
/**
* Return layout's title
* @return string layout's title
* Return site title
*
* @return string
*/
public static function getSiteTitle()
{
$oModuleModel = getModel('module');
$moduleConfig = $oModuleModel->getModuleConfig('module');
if(isset($moduleConfig->siteTitle))
$moduleConfig = getModel('module')->getModuleConfig('module');
if (isset($moduleConfig->siteTitle))
{
return $moduleConfig->siteTitle;
$title = trim($moduleConfig->siteTitle);
getController('module')->replaceDefinedLangCode($title);
return $title;
}
else
{
return '';
}
}
/**
* Return site subtitle
*
* @return string
*/
public static function getSiteSubtitle()
{
$moduleConfig = getModel('module')->getModuleConfig('module');
if (isset($moduleConfig->siteSubtitle))
{
$subtitle = trim($moduleConfig->siteSubtitle);
getController('module')->replaceDefinedLangCode($subtitle);
return $subtitle;
}
else
{
return '';
}
return '';
}
/**
@ -2660,33 +2721,91 @@ class Context
/**
* Get meta tag
*
* @param string $name (optional)
* @return array The list of meta tags
*/
public static function getMetaTag()
public static function getMetaTag($name = null)
{
$ret = array();
foreach(self::$_instance->meta_tags as $key => $val)
if ($name !== null)
{
list($name, $is_http_equiv) = explode("\t", $key);
$ret[] = array('name' => $name, 'is_http_equiv' => $is_http_equiv, 'content' => $val);
return isset(self::$_instance->meta_tags[$name]) ? self::$_instance->meta_tags[$name]['content'] : null;
}
$ret = array();
foreach(self::$_instance->meta_tags as $name => $content)
{
$ret[] = array('name' => $name, 'is_http_equiv' => $content['is_http_equiv'], 'content' => escape($content['content'], false));
}
return $ret;
}
/**
* Add the meta tag
* Add meta tag
*
* @param string $name name of meta tag
* @param string $content content of meta tag
* @param mixed $is_http_equiv value of http_equiv
* @return void
*/
public static function addMetaTag($name, $content, $is_http_equiv = FALSE)
public static function addMetaTag($name, $content, $is_http_equiv = false)
{
self::$_instance->meta_tags[$name . "\t" . ($is_http_equiv ? '1' : '0')] = $content;
getController('module')->replaceDefinedLangCode($content);
self::$_instance->meta_tags[$name] = array('is_http_equiv' => (bool)$is_http_equiv, 'content' => $content);
}
/**
* Get OpenGraph metadata
*
* @return array
*/
public static function getOpenGraphData()
{
$ret = array();
foreach(self::$_instance->opengraph_metadata as $key => $val)
{
if ($val[1] === false || $val[1] === null)
{
continue;
}
$ret[] = array('property' => escape($val[0], false), 'content' => escape($val[1], false));
}
return $ret;
}
/**
* Add OpenGraph metadata
*
* @param string $name
* @param mixed $content
* @return void
*/
public static function addOpenGraphData($name, $content)
{
if (is_array($content))
{
foreach ($content as $key => $val)
{
self::addOpenGraphData("$name:$key", $val);
}
}
else
{
self::$_instance->opengraph_metadata[] = array($name, $content);
}
}
/**
* Set canonical URL
*
* @param string $url
* @return void
*/
public static function setCanonicalURL($url)
{
self::addHtmlHeader(sprintf('<link rel="canonical" href="%s" />', escape($url)));
}
}
/* End of file Context.class.php */
/* Location: ./classes/context/Context.class.php */

View file

@ -213,6 +213,12 @@ class HTMLDisplayHandler
// Remove unnecessary information
$output = preg_replace('/member\_\-([0-9]+)/s', 'member_0', $output);
// Add OpenGraph metadata
if (config('seo.og_enabled') && Context::get('module') !== 'admin')
{
$this->_addOpenGraphMetadata();
}
// set icon
$oAdminModel = getAdminModel('admin');
@ -380,6 +386,140 @@ class HTMLDisplayHandler
}
Context::loadFile($matches[2]);
}
/**
* Add OpenGraph metadata tags.
*
* @param string $output
* @return void
*/
function _addOpenGraphMetadata()
{
// Get information about the current request.
$page_type = 'website';
$current_module_info = Context::get('current_module_info');
$site_module_info = Context::get('site_module_info');
$document_srl = Context::get('document_srl');
if ($document_srl)
{
$oDocument = Context::get('oDocument') ?: getModel('document')->getDocument($document_srl, false, false);
if ($oDocument instanceof documentItem && $oDocument->document_srl == $document_srl && !$oDocument->isSecret())
{
$page_type = 'article';
}
}
// Add basic metadata.
Context::addOpenGraphData('og:title', Context::getBrowserTitle());
Context::addOpenGraphData('og:site_name', Context::getSiteTitle());
if ($page_type === 'article' && config('seo.og_extract_description'))
{
Context::addOpenGraphData('og:description', trim(utf8_normalize_spaces($oDocument->getContentText(200))));
}
else
{
Context::addOpenGraphData('og:description', Context::getMetaTag('description'));
}
// Add metadata about this page.
Context::addOpenGraphData('og:type', $page_type);
if ($page_type === 'article')
{
$document_canonical_url = getFullUrl('', 'mid', $current_module_info->mid, 'document_srl', $document_srl);
Context::addOpenGraphData('og:url', $document_canonical_url);
}
elseif (($page = Context::get('page')) > 1)
{
Context::addOpenGraphData('og:url', getFullUrl('', 'mid', $current_module_info->mid, 'page', $page));
}
elseif ($current_module_info->module_srl == $site_module_info->module_srl)
{
Context::addOpenGraphData('og:url', Rhymix\Framework\URL::getCurrentDomainURL(\RX_BASEURL));
}
else
{
Context::addOpenGraphData('og:url', getFullUrl('', 'mid', $current_module_info->mid));
}
// Add metadata about the locale.
$lang_type = Context::getLangType();
$locales = (include \RX_BASEDIR . 'common/defaults/locales.php');
if (isset($locales[$lang_type]))
{
Context::addOpenGraphData('og:locale', $locales[$lang_type]);
}
if ($page_type === 'article' && $oDocument->getLangCode() !== $lang_type && isset($locales[$oDocument->getLangCode()]))
{
Context::addOpenGraphData('og:locale:alternate', $locales[$oDocument->getLangCode()]);
}
// Add image.
if ($page_type === 'article' && config('seo.og_extract_images'))
{
if (($document_images = Rhymix\Framework\Cache::get("seo:document_images:$document_srl")) === null)
{
$document_images = array();
if ($oDocument->hasUploadedFiles())
{
foreach ($oDocument->getUploadedFiles() as $file)
{
if ($file->isvalid !== 'Y' || !preg_match('/\.(?:bmp|gif|jpe?g|png)$/i', $file->uploaded_filename))
{
continue;
}
list($width, $height) = @getimagesize($file->uploaded_filename);
if ($width < 100 && $height < 100)
{
continue;
}
$image = array('filepath' => $file->uploaded_filename, 'width' => $width, 'height' => $height);
if ($file->cover_image === 'Y')
{
array_unshift($document_images, $image);
}
else
{
$document_images[] = $image;
}
if (count($document_images) >= 1)
{
break;
}
}
}
Rhymix\Framework\Cache::set("seo:document_images:$document_srl", $document_images, 0, true);
}
}
else
{
$document_images = null;
}
if ($document_images)
{
$first_image = reset($document_images);
$first_image['filepath'] = preg_replace('/^.\\/files\\//', \RX_BASEURL . 'files/', $first_image['filepath']);
Context::addOpenGraphData('og:image', Rhymix\Framework\URL::getCurrentDomainURL($first_image['filepath']));
Context::addOpenGraphData('og:image:width', $first_image['width']);
Context::addOpenGraphData('og:image:height', $first_image['height']);
}
elseif ($default_image = getAdminModel('admin')->getSiteDefaultImageUrl($width, $height))
{
Context::addOpenGraphData('og:image', Rhymix\Framework\URL::getCurrentDomainURL($default_image));
if ($width && $height)
{
Context::addOpenGraphData('og:image:width', $width);
Context::addOpenGraphData('og:image:height', $height);
}
}
// Add datetime for articles.
if ($page_type === 'article' && config('seo.og_use_timestamps'))
{
Context::addOpenGraphData('article:published_time', $oDocument->getRegdate('c'));
Context::addOpenGraphData('article:modified_time', $oDocument->getUpdate('c'));
}
}
/**
* import basic .js files.

View file

@ -442,7 +442,7 @@ class FrontEndFileHandler extends Handler
}
// Enable HTTP/2 server push for CSS resources.
if ($finalize && config('view.server_push') && strncmp($_SERVER['SERVER_PROTOCOL'], 'HTTP/2', 6) === 0)
if ($finalize && $this->_isServerPushEnabled())
{
foreach ($result as $resource)
{
@ -546,7 +546,7 @@ class FrontEndFileHandler extends Handler
}
// Enable HTTP/2 server push for JS resources.
if ($type === 'head' && $finalize && config('view.server_push') && strncmp($_SERVER['SERVER_PROTOCOL'], 'HTTP/2', 6) === 0)
if ($type === 'head' && $finalize && $this->_isServerPushEnabled())
{
foreach ($result as $resource)
{
@ -667,6 +667,31 @@ class FrontEndFileHandler extends Handler
$cssSortList = array('common' => -100000, 'layouts' => -90000, 'modules' => -80000, 'widgets' => -70000, 'addons' => -60000);
$file->index = $cssSortList[$tmp[0]];
}
/**
* Check if server push is enabled.
*
* @return bool
*/
protected function _isServerPushEnabled()
{
if (!config('view.server_push'))
{
return false;
}
elseif (strncmp($_SERVER['SERVER_PROTOCOL'], 'HTTP/2', 6) === 0)
{
return true;
}
elseif (isset($_SERVER['HTTP_CF_VISITOR']) && \RX_SSL)
{
return true;
}
else
{
return false;
}
}
}
/* End of file FrontEndFileHandler.class.php */
/* Location: ./classes/frontendfile/FrontEndFileHandler.class.php */

View file

@ -285,7 +285,41 @@ class ModuleHandler extends Handler
$this->module = $module_info->module;
$this->mid = $module_info->mid;
$this->module_info = $module_info;
Context::setBrowserTitle($module_info->browser_title);
if ($module_info->mid == $site_module_info->mid)
{
$seo_title = config('seo.main_title') ?: '$SITE_TITLE - $SITE_SUBTITLE';
}
else
{
$seo_title = config('seo.subpage_title') ?: '$SITE_TITLE - $SUBPAGE_TITLE';
}
getController('module')->replaceDefinedLangCode($seo_title);
Context::setBrowserTitle($seo_title, array(
'site_title' => Context::getSiteTitle(),
'site_subtitle' => Context::getSiteSubtitle(),
'subpage_title' => $module_info->browser_title,
'page' => Context::get('page') ?: 1,
));
$module_config = $oModuleModel->getModuleConfig('module');
if ($module_info->meta_keywords)
{
Context::addMetaTag('keywords', $module_info->meta_keywords);
}
elseif($module_config->meta_keywords)
{
Context::addMetaTag('keywords', $module_config->meta_keywords);
}
if ($module_info->meta_description)
{
Context::addMetaTag('description', $module_info->meta_description);
}
elseif($module_config->meta_description)
{
Context::addMetaTag('description', $module_config->meta_description);
}
$viewType = (Mobile::isFromMobilePhone()) ? 'M' : 'P';
$targetSrl = (Mobile::isFromMobilePhone()) ? 'mlayout_srl' : 'layout_srl';
@ -764,8 +798,7 @@ class ModuleHandler extends Handler
}
if($module_config->siteTitle)
{
$siteTitle = Context::getBrowserTitle();
if(!$siteTitle)
if(!Context::getBrowserTitle())
{
Context::setBrowserTitle($module_config->siteTitle);
}

View file

@ -10,6 +10,7 @@ return array(
'errorlogger' => true,
'fix_mysql_utf8' => true,
'member_communication' => true,
'seo' => true,
'smartphone' => true,
'zipperupper' => true,
);

View file

@ -99,6 +99,15 @@ return array(
'display_to' => 'admin',
'allow' => array(),
),
'seo' => array(
'main_title' => '',
'subpage_title' => '',
'document_title' => '',
'og_enabled' => false,
'og_extract_description' => false,
'og_extract_images' => false,
'og_use_timestamps' => false,
),
'mediafilter' => array(
'iframe' => array(),
'object' => array(),

View file

@ -0,0 +1,21 @@
<?php
/**
* Conversion map from languages to locales
*
* Copyright (c) Rhymix Developers and Contributors
*/
return array(
'ko' => 'ko_KR',
'en' => 'en_US',
'ja' => 'ja_JP',
'zh-CN' => 'zh_CN',
'zh-TW' => 'zh_TW',
'de' => 'de_DE',
'es' => 'es_ES',
'fr' => 'fr_FR',
'mn' => 'mn_MN',
'ru' => 'ru_RU',
'tr' => 'tr_TR',
'vi' => 'vi_VN',
);

View file

@ -309,7 +309,14 @@ class Storage
if ($destination_perms === null)
{
@chmod($destination, 0777 & @fileperms($source));
if (is_uploaded_file($source))
{
@chmod($destination, 0666 ^ intval(config('file.umask'), 8));
}
else
{
@chmod($destination, 0777 & @fileperms($source));
}
}
else
{

View file

@ -165,6 +165,8 @@ $lang->first_page = 'First Page';
$lang->last_page = 'Last Page';
$lang->search_target = 'Target for Search';
$lang->search_keyword = 'Keyword';
$lang->meta_keywords = 'SEO Keywords';
$lang->meta_description = 'SEO Description';
$lang->is_default = 'Default';
$lang->no_documents = 'No Articles';
$lang->board_manager = 'Board Settings';
@ -310,7 +312,7 @@ $lang->find_site = 'Find Site';
$lang->captcha = 'Captcha';
$lang->reload = 'reload';
$lang->play = 'play';
$lang->use_and_display = 'Use+Display';
$lang->use_and_display = 'Use and Display Vote List';
$lang->mobile = 'Mobile';
$lang->mobile_view = 'Mobile View';
$lang->about_mobile_view = 'Mobile View will display the best layout when you access the website with your smart phone.';

View file

@ -303,7 +303,7 @@ $lang->find_site = 'サイト検索';
$lang->captcha = 'キャプチャ';
$lang->reload = '再読み込み';
$lang->play = 'プレイ';
$lang->use_and_display = '使用+ディスプレイ';
$lang->use_and_display = '使用+推奨履歴公開';
$lang->mobile = 'モバイル';
$lang->mobile_view = 'モバイルスキン使用';
$lang->about_mobile_view = 'スマートフォンなどを利用してサイトに接続した場合、モバイル画面に最適化されたレイアウトを使用するよう設定します。';

View file

@ -165,6 +165,8 @@ $lang->first_page = '첫 페이지';
$lang->last_page = '끝 페이지';
$lang->search_target = '검색대상';
$lang->search_keyword = '검색어';
$lang->meta_keywords = 'SEO 키워드';
$lang->meta_description = 'SEO 설명';
$lang->is_default = '기본';
$lang->no_documents = '등록된 글이 없습니다.';
$lang->board_manager = '게시판 관리';
@ -311,7 +313,7 @@ $lang->find_site = '사이트 찾기';
$lang->captcha = 'Captcha';
$lang->reload = '새로고침';
$lang->play = '음성재생';
$lang->use_and_display = '사용+노출';
$lang->use_and_display = '사용 + 추천내역 공개';
$lang->mobile = '모바일';
$lang->mobile_view = '모바일 뷰 사용';
$lang->about_mobile_view = '스마트폰 등을 이용하여 접속할 때 모바일 화면에 최적화된 레이아웃을 이용하도록 합니다.';

View file

@ -286,7 +286,7 @@ $lang->find_site = '查找站点';
$lang->captcha = '图形验证码';
$lang->reload = '重新加载';
$lang->play = '播放';
$lang->use_and_display = '使用+显示';
$lang->use_and_display = '使用+专题刊物历史';
$lang->mobile_view = '开启移动版';
$lang->about_mobile_view = '为智能手机访问网站,提供最佳视觉效果。';
$lang->simple_view = '预览';

View file

@ -286,7 +286,7 @@ $lang->find_site = '尋找網站';
$lang->captcha = '圖形驗證';
$lang->reload = '重新讀取';
$lang->play = '播放';
$lang->use_and_display = '使用+顯示';
$lang->use_and_display = '使用+專題刊物歷史';
$lang->mobile_view = '手機瀏覽';
$lang->about_mobile_view = '使用手機瀏覽時將會顯示最適當的畫面。';
$lang->more = '更多';

View file

@ -8,7 +8,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes" cond="$m" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<block loop="Context::getMetaTag() => $no, $val">
<meta http-equiv="{$val['name']}"|cond="$val['is_http_equiv']" name="{$val['name']}"|cond="!$val['is_http_equiv']" content="{$val['content']}">
<meta http-equiv="{$val['name']}"|cond="$val['is_http_equiv']" name="{$val['name']}"|cond="!$val['is_http_equiv']" content="{$val['content']}" />
</block>
<!-- TITLE -->
@ -39,6 +39,9 @@
<link cond="$mobicon_url" rel="apple-touch-icon" href="{$mobicon_url}" />
<!-- OTHER HEADERS -->
<block loop="Context::getOpenGraphData() => $og_metadata">
<meta property="{$og_metadata['property']}" content="{$og_metadata['content']}" />
</block>
{Context::getHtmlHeader()}
<!-- COMMON JS VARIABLES -->

View file

@ -2,6 +2,7 @@
<h1>{$lang->installed_addons}</h1>
</div>
<h2>{$addon_info->title}</h2>
<table class="x_table">
<tbody>
<tr>
@ -30,6 +31,9 @@
</tr>
</tbody>
</table>
<div cond="Context::isBlacklistedPlugin($addon_info->addon_name)" class="message error">
<p><em class="x_label x_label-important">{$lang->msg_warning}</em> {$lang->msg_blacklisted_module}</p>
</div>
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/addon/tpl/setup_addon/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>

View file

@ -511,6 +511,7 @@ class adminAdminController extends admin
// Site title and HTML footer
$args = new stdClass;
$args->siteTitle = $vars->site_title;
$args->siteSubtitle = $vars->site_subtitle;
$args->htmlFooter = $vars->html_footer;
$oModuleController->updateModuleConfig('module', $args);
@ -521,11 +522,6 @@ class adminAdminController extends admin
$site_args->default_language = $vars->default_lang;
$oModuleController->updateSite($site_args);
// Thumbnail settings
$args = new stdClass;
$args->thumbnail_type = $vars->thumbnail_type === 'ratio' ? 'ratio' : 'crop';
$oModuleController->insertModuleConfig('document', $args);
// Default and enabled languages
$enabled_lang = $vars->enabled_lang;
if (!in_array($vars->default_lang, $enabled_lang))
@ -545,6 +541,7 @@ class adminAdminController extends admin
// Favicon and mobicon
$this->_saveFavicon('favicon.ico', $vars->is_delete_favicon);
$this->_saveFavicon('mobicon.png', $vars->is_delete_mobicon);
$this->_saveDefaultImage($vars->is_delete_site_default_image);
// Save
Rhymix\Framework\Config::save();
@ -693,6 +690,12 @@ class adminAdminController extends admin
Rhymix\Framework\Config::set('cache', array());
}
// Thumbnail settings
$args = new stdClass;
$args->thumbnail_type = $vars->thumbnail_type === 'ratio' ? 'ratio' : 'crop';
$oModuleController = getController('module');
$oModuleController->insertModuleConfig('document', $args);
// Other settings
Rhymix\Framework\Config::set('use_rewrite', $vars->use_rewrite === 'Y');
Rhymix\Framework\Config::set('use_sso', $vars->use_sso === 'Y');
@ -768,6 +771,35 @@ class adminAdminController extends admin
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigDebug'));
}
/**
* Update SEO configuration.
*/
function procAdminUpdateSEO()
{
$vars = Context::getRequestVars();
$args = new stdClass;
$args->meta_keywords = $vars->site_meta_keywords ? implode(', ', array_map('trim', explode(',', $vars->site_meta_keywords))) : '';
$args->meta_description = trim(utf8_normalize_spaces($vars->site_meta_description));
$oModuleController = getController('module');
$oModuleController->updateModuleConfig('module', $args);
Rhymix\Framework\Config::set('seo.main_title', trim(utf8_normalize_spaces($vars->seo_main_title)));
Rhymix\Framework\Config::set('seo.subpage_title', trim(utf8_normalize_spaces($vars->seo_subpage_title)));
Rhymix\Framework\Config::set('seo.document_title', trim(utf8_normalize_spaces($vars->seo_document_title)));
Rhymix\Framework\Config::set('seo.og_enabled', $vars->og_enabled === 'Y');
Rhymix\Framework\Config::set('seo.og_extract_description', $vars->og_extract_description === 'Y');
Rhymix\Framework\Config::set('seo.og_extract_images', $vars->og_extract_images === 'Y');
Rhymix\Framework\Config::set('seo.og_use_timestamps', $vars->og_use_timestamps === 'Y');
// Save
Rhymix\Framework\Config::save();
$this->setMessage('success_updated');
$this->setRedirectUrl(Context::get('success_return_url') ?: getNotEncodedUrl('', 'module', 'admin', 'act', 'dispAdminConfigSEO'));
}
/**
* Update sitelock configuration.
*/
@ -910,6 +942,11 @@ class adminAdminController extends admin
$name = 'mobicon';
$tmpFileName = $this->_saveFaviconTemp($mobicon, 'mobicon.png');
}
elseif ($default_image = Context::get('default_image'))
{
$name = 'default_image';
$tmpFileName = $this->_saveFaviconTemp($default_image, 'default_image.png');
}
else
{
$name = $tmpFileName = '';
@ -922,7 +959,7 @@ class adminAdminController extends admin
$this->setTemplateFile("favicon_upload.html");
}
private function _saveFaviconTemp($icon, $iconname)
protected function _saveFaviconTemp($icon, $iconname)
{
$site_info = Context::get('site_module_info');
$virtual_site = '';
@ -934,9 +971,9 @@ class adminAdminController extends admin
$original_filename = $icon['tmp_name'];
$type = $icon['type'];
$relative_filename = 'files/attach/xeicon/'.$virtual_site.'tmp/'.$iconname;
$target_filename = RX_BASEDIR . $relative_filename;
$target_filename = \RX_BASEDIR . $relative_filename;
if ($iconname !== 'favicon.ico' && $iconname !== 'mobicon.png')
if (!preg_match('/^(favicon|mobicon|default_image)\.(ico|png|jpe?g)$/', $iconname))
{
Context::set('msg', lang('msg_invalid_format'));
return;
@ -946,28 +983,63 @@ class adminAdminController extends admin
return $relative_filename;
}
private function _saveFavicon($iconname, $deleteIcon = false)
protected function _saveFavicon($iconname, $deleteIcon = false)
{
$image_filepath = 'files/attach/xeicon/';
$site_info = Context::get('site_module_info');
$virtual_site = '';
if ($site_info->site_srl)
if ($site_info->site_srl)
{
$virtual_site = $site_info->site_srl . '/';
$image_filepath .= $site_info->site_srl . '/';
}
$image_filepath = RX_BASEDIR . 'files/attach/xeicon/' . $virtual_site;
if ($deleteIcon)
{
Rhymix\Framework\Storage::delete($image_filepath.$iconname);
Rhymix\Framework\Storage::delete(\RX_BASEDIR . $image_filepath . $iconname);
return;
}
$tmpicon_filepath = $image_filepath.'tmp/'.$iconname;
$icon_filepath = $image_filepath.$iconname;
$tmpicon_filepath = $image_filepath . 'tmp/' . $iconname;
$icon_filepath = $image_filepath . $iconname;
if (file_exists(\RX_BASEDIR . $tmpicon_filepath))
{
Rhymix\Framework\Storage::move(\RX_BASEDIR . $tmpicon_filepath, \RX_BASEDIR . $icon_filepath);
}
}
protected function _saveDefaultImage($deleteIcon = false)
{
$image_filepath = 'files/attach/xeicon/';
$site_info = Context::get('site_module_info');
if ($site_info->site_srl)
{
$image_filepath .= $site_info->site_srl . '/';
}
if ($deleteIcon)
{
$info = Rhymix\Framework\Storage::readPHPData($image_filepath . 'default_image.php');
if ($info['filename'])
{
Rhymix\Framework\Storage::delete(\RX_BASEDIR . $info['filename']);
}
Rhymix\Framework\Storage::delete($image_filepath . 'default_image.php');
return;
}
$tmpicon_filepath = \RX_BASEDIR . $image_filepath . 'tmp/default_image.png';
if (file_exists($tmpicon_filepath))
{
Rhymix\Framework\Storage::move($tmpicon_filepath, $icon_filepath);
list($width, $height, $type) = @getimagesize($tmpicon_filepath);
switch ($type)
{
case 'image/gif': $target_filename = $image_filepath . 'default_image.gif'; break;
case 'image/jpeg': $target_filename = $image_filepath . 'default_image.jpg'; break;
case 'image/png': default: $target_filename = $image_filepath . 'default_image.png';
}
Rhymix\Framework\Storage::move($tmpicon_filepath, \RX_BASEDIR . $target_filename);
Rhymix\Framework\Storage::writePHPData(\RX_BASEDIR . 'files/attach/xeicon/' . $virtual_site . 'default_image.php', array(
'filename' => $target_filename, 'width' => $width, 'height' => $height,
));
}
}
}

View file

@ -940,6 +940,31 @@ class adminAdminModel extends admin
{
return $this->iconUrlCheck('mobicon.png', 'mobiconSample.png', $default);
}
function getSiteDefaultImageUrl(&$width = 0, &$height = 0)
{
$site_info = Context::get('site_module_info');
if ($site_info->site_srl)
{
$virtual_site = $site_info->site_srl . '/';
}
else
{
$virtual_site = '';
}
$info = Rhymix\Framework\Storage::readPHPData(\RX_BASEDIR . 'files/attach/xeicon/' . $virtual_site . 'default_image.php');
if ($info && Rhymix\Framework\Storage::exists(\RX_BASEDIR . $info['filename']))
{
$width = $info['width'];
$height = $info['height'];
return \RX_BASEURL . $info['filename'] . '?' . date('YmdHis', filemtime(\RX_BASEDIR . $info['filename']));
}
else
{
return false;
}
}
function iconUrlCheck($iconname, $default_icon_name, $default)
{

View file

@ -203,7 +203,7 @@ class adminAdminView extends admin
$gnbTitleInfo->adminTitle = $objConfig->adminTitle ? $objConfig->adminTitle : 'Admin';
$gnbTitleInfo->adminLogo = $objConfig->adminLogo ? $objConfig->adminLogo : '';
$browserTitle = ($subMenuTitle ? $subMenuTitle : 'Dashboard') . ' - ' . $gnbTitleInfo->adminTitle;
$browserTitle = $gnbTitleInfo->adminTitle . ' - ' . ($subMenuTitle ? $subMenuTitle : 'Dashboard');
// Get list of favorite
$oAdminAdminModel = getAdminModel('admin');
@ -255,7 +255,7 @@ class adminAdminView extends admin
Context::set('gnbUrlList', $menu->list);
Context::set('parentSrl', $parentSrl);
Context::set('gnb_title_info', $gnbTitleInfo);
Context::setBrowserTitle($browserTitle);
Context::addBrowserTitle($browserTitle);
}
/**
@ -416,7 +416,8 @@ class adminAdminView extends admin
// Site title and HTML footer
$oModuleModel = getModel('module');
$config = $oModuleModel->getModuleConfig('module');
Context::set('site_title', escape($config->siteTitle));
Context::set('var_site_title', escape($config->siteTitle));
Context::set('var_site_subtitle', escape($config->siteSubtitle));
Context::set('all_html_footer', escape($config->htmlFooter));
// Index module
@ -424,11 +425,6 @@ class adminAdminView extends admin
$start_module = $oModuleModel->getSiteInfo(0, $columnList);
Context::set('start_module', $start_module);
// Thumbnail settings
$oDocumentModel = getModel('document');
$config = $oDocumentModel->getDocumentConfig();
Context::set('thumbnail_type', $config->thumbnail_type ?: 'crop');
// Default time zone
Context::set('timezones', Rhymix\Framework\DateTime::getTimezoneList());
Context::set('selected_timezone', Rhymix\Framework\Config::get('locale.default_timezone'));
@ -436,12 +432,14 @@ class adminAdminView extends admin
// Mobile view
Context::set('use_mobile_view', config('use_mobile_view') ? 'Y' : 'N');
// Favicon and mobicon
// Favicon and mobicon and site default image
$oAdminModel = getAdminModel('admin');
$favicon_url = $oAdminModel->getFaviconUrl(false) ?: $oAdminModel->getFaviconUrl();
$mobicon_url = $oAdminModel->getMobileIconUrl(false) ?: $oAdminModel->getMobileIconUrl();
$site_default_image_url = $oAdminModel->getSiteDefaultImageUrl();
Context::set('favicon_url', $favicon_url);
Context::set('mobicon_url', $mobicon_url);
Context::set('site_default_image_url', $site_default_image_url);
$this->setTemplateFile('config_general');
}
@ -523,6 +521,11 @@ class adminAdminView extends admin
Context::set('object_cache_port', null);
}
// Thumbnail settings
$oDocumentModel = getModel('document');
$config = $oDocumentModel->getDocumentConfig();
Context::set('thumbnail_type', $config->thumbnail_type ?: 'crop');
// Other settings
Context::set('use_mobile_view', Rhymix\Framework\Config::get('use_mobile_view'));
Context::set('use_rewrite', Rhymix\Framework\Config::get('use_rewrite'));
@ -561,6 +564,32 @@ class adminAdminView extends admin
$this->setTemplateFile('config_debug');
}
/**
* Display Debug Settings page
* @return void
*/
function dispAdminConfigSEO()
{
// Meta keywords and description
$oModuleModel = getModel('module');
$config = $oModuleModel->getModuleConfig('module');
Context::set('site_meta_keywords', escape($config->meta_keywords));
Context::set('site_meta_description', escape($config->meta_description));
// Titles
Context::set('seo_main_title', escape(Rhymix\Framework\Config::get('seo.main_title') ?: '$SITE_TITLE - $SITE_SUBTITLE'));
Context::set('seo_subpage_title', escape(Rhymix\Framework\Config::get('seo.subpage_title') ?: '$SITE_TITLE - $SUBPAGE_TITLE'));
Context::set('seo_document_title', escape(Rhymix\Framework\Config::get('seo.document_title') ?: '$SITE_TITLE - $DOCUMENT_TITLE'));
// OpenGraph metadata
Context::set('og_enabled', Rhymix\Framework\Config::get('seo.og_enabled'));
Context::set('og_extract_description', Rhymix\Framework\Config::get('seo.og_extract_description'));
Context::set('og_extract_images', Rhymix\Framework\Config::get('seo.og_extract_images'));
Context::set('og_use_timestamps', Rhymix\Framework\Config::get('seo.og_use_timestamps'));
$this->setTemplateFile('config_seo');
}
/**
* Display Sitelock Settings page
* @return void

View file

@ -8,6 +8,7 @@
<action name="dispAdminConfigSecurity" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigAdvanced" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigDebug" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigSEO" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigSitelock" type="view" menu_name="adminConfigurationGeneral" />
<action name="dispAdminConfigFtp" type="view" menu_name="adminConfigurationFtp" menu_index="true" />
<action name="dispAdminSetup" type="view" menu_name="adminMenuSetup" menu_index="true" />
@ -26,6 +27,7 @@
<action name="procAdminUpdateSecurity" type="controller" />
<action name="procAdminUpdateAdvanced" type="controller" />
<action name="procAdminUpdateDebug" type="controller" />
<action name="procAdminUpdateSEO" type="controller" />
<action name="procAdminUpdateSitelock" type="controller" />
<action name="procAdminUpdateFTPInfo" type="controller" />
<action name="procAdminRemoveFTPInfo" type="controller" />

View file

@ -5,6 +5,7 @@ $lang->subtitle_primary = 'General Settings';
$lang->subtitle_security = 'Security Settings';
$lang->subtitle_advanced = 'Advanced Settings';
$lang->subtitle_debug = 'Debug Settings';
$lang->subtitle_seo = 'SEO Settings';
$lang->subtitle_etc = 'Other Settings';
$lang->current_state = 'Current state';
$lang->latest_documents = 'Latest Documents';
@ -15,10 +16,9 @@ $lang->favorites = 'Favorites';
$lang->admin_info = 'Administrator Info';
$lang->admin_index = 'Index Admin Page';
$lang->control_panel = 'Dashboard';
$lang->site_title = 'Site title';
$lang->site_title = 'Site Title';
$lang->site_title = 'Site Subtitle';
$lang->start_module = 'Homepage';
$lang->about_site_title = 'This is the title which is exposed when the site title is not set at detail setting.';
$lang->about_start_module = 'You can specify the default page for the site.';
$lang->select_site = 'Site';
$lang->select_module_type = 'Module Type';
$lang->select_module_instance = 'Select Page';
@ -60,6 +60,12 @@ $lang->cmd_shortcut_management = 'Edit Menu';
$lang->msg_is_not_administrator = 'Only administrator can access this page.';
$lang->msg_manage_module_cannot_delete = 'Shortcuts of module, addon, layout, widget cannot be removed.';
$lang->msg_default_act_is_null = 'Shortcut cannot be registered because the default admin Action is not set.';
$lang->msg_blacklisted_plugin = 'This plugin has been disabled because it conflicts with a feature that Rhymix supports by default, or is known to have other compatibility problems.';
$lang->msg_blacklisted_module = 'This module has been disabled because it conflicts with a feature that Rhymix supports by default, or is known to have other compatibility problems.';
$lang->msg_blacklisted_addon = 'This addon has been disabled because it conflicts with a feature that Rhymix supports by default, or is known to have other compatibility problems.';
$lang->msg_blacklisted_widget = 'This widget has been disabled because it conflicts with a feature that Rhymix supports by default, or is known to have other compatibility problems.';
$lang->msg_blacklisted_layout = 'This layout has been disabled because it conflicts with a feature that Rhymix supports by default, or is known to have other compatibility problems.';
$lang->msg_warning = 'Warning';
$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->xe_license = 'Rhymix complies with the GPL.';
@ -137,6 +143,22 @@ $lang->debug_log_filename = 'Log filename';
$lang->about_debug_log_filename = 'YYYYMMDD in the filename will be replaced with the current date.<br>It is recommended to split the log file by date to prevent it from getting too large.';
$lang->msg_debug_log_filename_not_writable = 'Rhymix cannot write log files in the specified path.';
$lang->debug_allowed_ip = 'Allowed IP addresses';
$lang->seo_main_title = 'Main Page Title';
$lang->about_seo_main_title = 'This format will be used for the title of the main page.<br>The following variables are available: <b>$SITE_TITLE</b>, <b>$SITE_SUBTITLE</b>, <b>$SUBPAGE_TITLE</b>.';
$lang->seo_subpage_title = 'Subpage Title';
$lang->about_seo_subpage_title = 'This format will be used for the title of lists and other major components of your website.<br>In additions to the variables above, you can use <b>$PAGE</b>.';
$lang->seo_document_title = 'Document Page Title';
$lang->about_seo_document_title = 'This format will be used for the title of individual documents.<br>In additions to the variables above, you can use <b>$DOCUMENT_TITLE</b>.';
$lang->site_meta_keywords = 'SEO Keywords';
$lang->about_site_meta_keywords = 'These keywords will be used on pages that do not have their own keywords.';
$lang->site_meta_description = 'SEO Description';
$lang->about_site_meta_description = 'This description will be used on pages that do not have their own description.';
$lang->og_enabled = 'Add OpenGraph Tags';
$lang->og_extract_description = 'Extract Description from Document';
$lang->og_extract_description_fallback = 'Use general description only';
$lang->og_extract_images = 'Extract Images from Document';
$lang->og_extract_images_fallback = 'Use site default image only';
$lang->og_use_timestamps = 'Include Timestamps';
$lang->autoinstall = 'EasyInstall';
$lang->last_week = 'Last Week';
$lang->this_week = 'This Week';
@ -151,8 +173,8 @@ $lang->about_use_mobile_view = 'Show mobile page when visitors access with mobil
$lang->thumbnail_type = 'Select thumbnail type.';
$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->corp = 'Crop(Cut)';
$lang->ratio = 'Ratio(Keep Aspect)';
$lang->corp = 'Crop (Cut)';
$lang->ratio = 'Ratio (Keep Aspect Ratio)';
$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->local_ip_address = 'Local IP address';
@ -160,10 +182,12 @@ $lang->about_admin_ip_allow = 'If this list is not empty, the administrator will
$lang->about_admin_ip_deny = 'This list can be used to designate IP addresses that are not allowed to log in as administrator.';
$lang->msg_current_ip_will_be_denied = 'The given IP list cannot be applied, as they would block your own IP address.';
$lang->detail_about_ftp_info = 'FTP information is needed for easyinstall when save_mode = on.';
$lang->allow_use_favicon = 'Do you want to use favicon?';
$lang->allow_use_favicon = 'Favicon';
$lang->about_use_favicon = 'The favicon should be 16x16 or 32x32, either ico or png format.';
$lang->allow_use_mobile_icon = 'Do you want to use the mobile home screen icon?';
$lang->allow_use_mobile_icon = 'Home Screen Icon';
$lang->detail_use_mobile_icon = 'The mobile icon should be 57x57 or 114x114, only png format.';
$lang->cmd_site_default_image = 'Default Image';
$lang->about_site_default_image = 'This image will be shown when your site is linked to in various social networks. It should be 200x200, either jpg or png format.';
$lang->use_sso = 'Use <abbr title="Single Sign On">SSO</abbr>?';
$lang->about_use_sso = 'SSO will enable users to sign in just once for both default and virtual site. You will need this only if you are using virtual sites.';
$lang->about_arrange_session = 'Do you want to clean up session?';

View file

@ -5,6 +5,7 @@ $lang->subtitle_primary = '기본 설정';
$lang->subtitle_security = '보안 설정';
$lang->subtitle_advanced = '고급 설정';
$lang->subtitle_debug = '디버그 설정';
$lang->subtitle_seo = 'SEO 설정';
$lang->subtitle_etc = '기타';
$lang->current_state = '현황';
$lang->latest_documents = '최근 글';
@ -16,9 +17,8 @@ $lang->admin_info = '관리자 정보';
$lang->admin_index = '관리자 초기 페이지';
$lang->control_panel = '대시보드';
$lang->site_title = '사이트 제목';
$lang->start_module = '홈페이지';
$lang->about_site_title = '세부 설정에서 사이트제목을 설정하지 않았을 경우 노출되는 제목입니다.';
$lang->about_start_module = '사이트 접속 시 기본으로 호출될 페이지 지정할 수 있습니다.';
$lang->site_subtitle = '사이트 부제목';
$lang->start_module = '메인화면 모듈 선택';
$lang->select_site = '사이트 선택';
$lang->select_module_type = '분류 선택';
$lang->select_module_instance = '페이지 선택';
@ -60,6 +60,12 @@ $lang->cmd_shortcut_management = '메뉴 편집하기';
$lang->msg_is_not_administrator = '관리자만 접속이 가능합니다.';
$lang->msg_manage_module_cannot_delete = '모듈, 애드온, 레이아웃, 위젯 모듈의 바로가기는 삭제 불가능합니다.';
$lang->msg_default_act_is_null = '기본 관리자 Action이 지정되어 있지 않아 바로가기 등록을 할 수 없습니다.';
$lang->msg_blacklisted_plugin = '이 플러그인은 Rhymix에서 기본 제공하는 기능과 충돌하거나 그 밖의 호환성 문제가 있으므로 사용이 중단되었습니다.';
$lang->msg_blacklisted_module = '이 모듈은 Rhymix에서 기본 제공하는 기능과 충돌하거나 그 밖의 호환성 문제가 있으므로 사용이 중단되었습니다.';
$lang->msg_blacklisted_addon = '이 애드온은 Rhymix에서 기본 제공하는 기능과 충돌하거나 그 밖의 호환성 문제가 있으므로 사용이 중단되었습니다.';
$lang->msg_blacklisted_widget = '이 위젯은 Rhymix에서 기본 제공하는 기능과 충돌하거나 그 밖의 호환성 문제가 있으므로 사용이 중단되었습니다.';
$lang->msg_blacklisted_layout = '이 레이아웃은 Rhymix에서 기본 제공하는 기능과 충돌하거나 그 밖의 호환성 문제가 있으므로 사용이 중단되었습니다.';
$lang->msg_warning = '경고';
$lang->welcome_to_xe = 'Rhymix 관리자';
$lang->about_lang_env = '처음 방문하는 사용자들의 언어 설정을 동일하게 하려면, 원하는 언어로 변경 후 아래 [저장] 버튼을 클릭하면 됩니다.';
$lang->xe_license = 'Rhymix는 GPL을 따릅니다.';
@ -140,6 +146,22 @@ $lang->debug_log_filename = '디버그 정보 기록 파일';
$lang->about_debug_log_filename = '파일명에 YYYYMMDD가 포함된 경우 날짜별로 파일을 분리하여 기록합니다.<br>파일을 분리하지 않으면 용량이 매우 커질 수 있으니 주의하십시오.';
$lang->msg_debug_log_filename_not_writable = '지정한 경로에 로그 파일을 작성할 수 없습니다.';
$lang->debug_allowed_ip = '디버그 허용 IP';
$lang->seo_main_title = '메인화면 제목';
$lang->about_seo_main_title = '사이트 메인 화면에 표시되는 제목 형태입니다. 아래와 같은 변수를 사용할 수 있습니다.<br><b>$SITE_TITLE</b> (사이트 제목), <b>$SITE_SUBTITLE</b> (사이트 부제목), <b>$SUBPAGE_TITLE</b> (서브페이지 제목)';
$lang->seo_subpage_title = '서브페이지 제목';
$lang->about_seo_subpage_title = '문서 목록, 페이지 등 주요 메뉴를 방문하면 표시되는 제목 형태입니다. 위의 변수들과 함께 <b>$PAGE</b> (페이지)도 사용할 수 있습니다.';
$lang->seo_document_title = '개별 문서 페이지 제목';
$lang->about_seo_document_title = '게시물을 읽는 화면에서 표시되는 제목 형태입니다. 위에 변수들과 함께 <b>$DOCUMENT_TITLE</b> (문서 제목)도 사용할 수 있습니다.';
$lang->site_meta_keywords = 'SEO 키워드';
$lang->about_site_meta_keywords = '별도의 키워드를 지정하지 않은 페이지에서는 이 키워드 목록이 표시됩니다.';
$lang->site_meta_description = 'SEO 설명';
$lang->about_site_meta_description = '별도의 설명을 지정하지 않은 페이지에서는 이 설명이 표시됩니다.';
$lang->og_enabled = 'OpenGraph 태그 사용';
$lang->og_extract_description = '본문에서 설명 추출';
$lang->og_extract_description_fallback = '모듈 또는 사이트 전체 설명만 사용';
$lang->og_extract_images = '본문에서 이미지 추출';
$lang->og_extract_images_fallback = '사이트 대표 이미지 사용';
$lang->og_use_timestamps = '글 작성/수정 시각 표시';
$lang->autoinstall = '쉬운 설치';
$lang->last_week = '지난주';
$lang->this_week = '이번주';
@ -154,8 +176,8 @@ $lang->about_use_mobile_view = '모바일 기기로 접속시 모바일 페이
$lang->thumbnail_type = '썸네일 생성 방식';
$lang->input_footer_script = '하단(footer) 스크립트';
$lang->detail_input_footer_script = '최하단에 코드를 삽입합니다. 관리자 페이지에서는 수행되지 않습니다.';
$lang->corp = 'Crop(잘라내기)';
$lang->ratio = 'Ratio(비율 맞추기)';
$lang->corp = 'Crop (잘라내기)';
$lang->ratio = 'Ratio (비율 맞추기)';
$lang->admin_ip_allow = '관리자 로그인 허용 IP';
$lang->admin_ip_deny = '관리자 로그인 금지 IP';
$lang->local_ip_address = '로컬 IP 주소';
@ -163,10 +185,12 @@ $lang->about_admin_ip_allow = '여기에 IP 주소를 나열하면 해당 IP에
$lang->about_admin_ip_deny = '여기에 나열된 IP 주소에서는 관리자 로그인이 금지됩니다.';
$lang->msg_current_ip_will_be_denied = '주어진 설정에 따르면 현재 로그인하신 관리자의 IP 주소도 차단됩니다. 다시 확인해 주십시오.';
$lang->detail_about_ftp_info = 'safe_mode = on 상태에서 쉬운설치를 사용하려면 FTP 정보를 입력해야 합니다.';
$lang->allow_use_favicon = '파비콘 지정';
$lang->allow_use_favicon = '파비콘';
$lang->about_use_favicon = '16x16 또는 32x32 크기의 ico 또는 png 파일을 권장합니다.';
$lang->allow_use_mobile_icon = '모바일 홈 화면 아이콘';
$lang->detail_use_mobile_icon = '57x57 또는 114x114 크기의 png 파일을 권장합니다.';
$lang->cmd_site_default_image = '사이트 대표 이미지';
$lang->about_site_default_image = 'SNS 등에 이 사이트가 링크되었을 때 표시되는 이미지입니다. 200x200 크기의 jpg 또는 png 파일을 권장합니다.';
$lang->use_sso = '<abbr title="Single Sign On">SSO</abbr> 사용';
$lang->about_use_sso = '사용자가 한 번만 로그인하면 기본 사이트와 가상 사이트에 동시에 로그인이 됩니다. 가상 사이트를 사용할 때만 필요합니다.';
$lang->about_arrange_session = '세션을 정리하시겠습니까?';

View file

@ -58,6 +58,19 @@
<label for="use_db_session_n" class="x_inline"><input type="radio" name="use_db_session" id="use_db_session_n" value="N" checked="checked"|cond="!$use_db_session" /> {$lang->cmd_no}</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->thumbnail_type}</label>
<div class="x_controls">
<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'" />
{$lang->corp}
</label>
<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'" />
{$lang->ratio}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->use_object_cache}</label>
<div class="x_controls">

View file

@ -11,13 +11,19 @@
</form>
<div class="x_form-horizontal" id="admin_config">
<div class="x_control-group">
<label class="x_control-label">{$lang->site_title} <a class="x_icon-question-sign" href="./common/manual/admin/index.html#UMAN_config_general_site_title" target="_blank">{$lang->help}</a></label>
<label class="x_control-label">{$lang->site_title}</label>
<div class="x_controls">
<input type="text" name="site_title" value="{$site_title}" />
<input type="text" name="site_title" value="{$var_site_title}" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="_target_module">{$lang->start_module} <a class="x_icon-question-sign" href="./common/manual/admin/index.html#UMAN_config_general_homepage" target="_blank">{$lang->help}</a></label>
<label class="x_control-label">{$lang->site_subtitle}</label>
<div class="x_controls">
<input type="text" name="site_subtitle" value="{$var_site_subtitle}" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="_target_module">{$lang->start_module}</label>
<div class="x_controls">
<input class="module_search" type="text" name="index_module_srl" value="{$start_module->index_module_srl}" />
</div>
@ -81,25 +87,12 @@
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->thumbnail_type}</label>
<div class="x_controls">
<label for="thumbnail_type_crop" class="x_inline">
<input type="radio" name="thumbnail_type" id="thumbnail_type_crop" value="corp" checked="checked"|cond="$thumbnail_type != 'ratio'" />
{$lang->corp}
</label>
<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'" />
{$lang->ratio}
</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->allow_use_favicon}</label>
<div class="x_controls">
<p id="faviconPreview">
<img src="{$favicon_url}" alt="favicon" class="fn1" style="width:16px;height:16px">
<img src="{$favicon_url}" alt="favicon Image" class="fn2" style="width:16px;height:16px">
<img src="{$favicon_url}" alt="Favicon" class="fn1" style="width:16px;height:16px">
<img src="{$favicon_url}" alt="Favicon" class="fn2" style="width:16px;height:16px">
</p>
<label><input type="checkbox" name="is_delete_favicon" value="1" /> {$lang->cmd_delete}</label>
<form action="./" enctype="multipart/form-data" method="post" target="hiddenIframe" class="imageUpload" style="margin:0">
@ -132,6 +125,24 @@
<span class="x_help-block">{$lang->detail_use_mobile_icon}</span>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->cmd_site_default_image}</label>
<div class="x_controls">
<p id="default_imagePreview">
<img src="{$site_default_image_url}" alt="Default Image" style="width:200px;height:auto" />
</p>
<label><input type="checkbox" name="is_delete_site_default_image" value="1" /> {$lang->cmd_delete}</label>
<form action="./" enctype="multipart/form-data" method="post" target="hiddenIframe" class="imageUpload" style="margin:0">
<input type="hidden" name="module" value="admin">
<input type="hidden" name="act" value="procAdminFaviconUpload">
<p>
<input type="file" name="default_image" id="default_image" title="Site default image"/>
<input class="x_btn" type="submit" value="{$lang->cmd_upload}" style="vertical-align:top">
</p>
</form>
<span class="x_help-block">{$lang->about_site_default_image}</span>
</div>
</div>
<div class="x_clearfix btnArea">
<div class="x_pull-right">
<button type="submit" class="x_btn x_btn-primary" onclick="doSubmitConfig()">{$lang->cmd_save}</button>
@ -142,10 +153,10 @@
<iframe name="hiddenIframe" src="about:blank" hidden></iframe>
<script>
function afterUploadConfigImage(name, fileName, tmpFileName)
{
function afterUploadConfigImage(name, tmpFileName) {
jQuery('#' + name + 'Preview img').attr('src', tmpFileName);
jQuery('#' + name).val('');
jQuery("input[name='is_delete_'" + name + "']").prop('checked', false);
}
function alertUploadMessage(msg) {

View file

@ -8,5 +8,6 @@
<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 == 'dispAdminConfigDebug'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigDebug')}">{$lang->subtitle_debug}</a></li>
<li class="x_active"|cond="$act == 'dispAdminConfigSEO'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigSEO')}">{$lang->subtitle_seo}</a></li>
<li class="x_active"|cond="$act == 'dispAdminConfigSitelock'"><a href="{getUrl('', 'module', 'admin', 'act', 'dispAdminConfigSitelock')}">{$lang->subtitle_sitelock}</a></li>
</ul>

View file

@ -0,0 +1,79 @@
<include target="config_header.html" />
<div cond="$XE_VALIDATOR_MESSAGE && $XE_VALIDATOR_ID == 'modules/admin/tpl/config_seo/1'" class="message {$XE_VALIDATOR_MESSAGE_TYPE}">
<p>{$XE_VALIDATOR_MESSAGE}</p>
</div>
<section class="section">
<form action="./" method="post" class="x_form-horizontal">
<input type="hidden" name="module" value="admin" />
<input type="hidden" name="act" value="procAdminUpdateSEO" />
<input type="hidden" name="xe_validator_id" value="modules/admin/tpl/config_seo/1" />
<div class="x_control-group">
<label class="x_control-label" for="seo_main_title">{$lang->seo_main_title}</label>
<div class="x_controls">
<input type="text" name="seo_main_title" id="seo_main_title" value="{$seo_main_title}" style="min-width: 80%" class="lang_code" />
<p class="x_help-block">{$lang->about_seo_main_title}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="seo_subpage_title">{$lang->seo_subpage_title}</label>
<div class="x_controls">
<input type="text" name="seo_subpage_title" id="seo_subpage_title" value="{$seo_subpage_title}" style="min-width: 80%" class="lang_code" />
<p class="x_help-block">{$lang->about_seo_subpage_title}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="seo_document_title">{$lang->seo_document_title}</label>
<div class="x_controls">
<input type="text" name="seo_document_title" id="seo_document_title" value="{$seo_document_title}" style="min-width: 80%" class="lang_code" />
<p class="x_help-block">{$lang->about_seo_document_title}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="site_meta_keywords">{$lang->site_meta_keywords}</label>
<div class="x_controls">
<input type="text" name="site_meta_keywords" id="site_meta_keywords" value="{$site_meta_keywords}" style="min-width: 80%" class="lang_code" />
<p class="x_help-block">{$lang->about_site_meta_keywords}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="site_meta_description">{$lang->site_meta_description}</label>
<div class="x_controls">
<input type="text" name="site_meta_description" id="site_meta_description" value="{$site_meta_description}" style="min-width: 80%" class="lang_code" />
<p class="x_help-block">{$lang->about_site_meta_description}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->og_enabled}</label>
<div class="x_controls">
<label for="og_enabled_y" class="x_inline"><input type="radio" name="og_enabled" id="og_enabled_y" value="Y" checked="checked"|cond="$og_enabled" /> {$lang->cmd_yes}</label>
<label for="og_enabled_n" class="x_inline"><input type="radio" name="og_enabled" id="og_enabled_n" value="N" checked="checked"|cond="!$og_enabled" /> {$lang->cmd_no}</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->og_extract_description}</label>
<div class="x_controls">
<label for="og_extract_description_y" class="x_inline"><input type="radio" name="og_extract_description" id="og_extract_description_y" value="Y" checked="checked"|cond="$og_extract_description" /> {$lang->cmd_yes}</label>
<label for="og_extract_description_n" class="x_inline"><input type="radio" name="og_extract_description" id="og_extract_description_n" value="N" checked="checked"|cond="!$og_extract_description" /> {$lang->cmd_no} ({$lang->og_extract_description_fallback})</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->og_extract_images}</label>
<div class="x_controls">
<label for="og_extract_images_y" class="x_inline"><input type="radio" name="og_extract_images" id="og_extract_images_y" value="Y" checked="checked"|cond="$og_extract_images" /> {$lang->cmd_yes}</label>
<label for="og_extract_images_n" class="x_inline"><input type="radio" name="og_extract_images" id="og_extract_images_n" value="N" checked="checked"|cond="!$og_extract_images" /> {$lang->cmd_no} ({$lang->og_extract_images_fallback})</label>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label">{$lang->og_use_timestamps}</label>
<div class="x_controls">
<label for="og_use_timestamps_y" class="x_inline"><input type="radio" name="og_use_timestamps" id="og_use_timestamps_y" value="Y" checked="checked"|cond="$og_use_timestamps" /> {$lang->cmd_yes}</label>
<label for="og_use_timestamps_n" class="x_inline"><input type="radio" name="og_use_timestamps" id="og_use_timestamps_n" value="N" checked="checked"|cond="!$og_use_timestamps" /> {$lang->cmd_no}</label>
</div>
</div>
<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>
</section>

View file

@ -2,6 +2,6 @@
<!--@if($msg)-->
parent.alertUploadMessage('{$msg}');
<!--@else-->
parent.afterUploadConfigImage('{$name}', '{$fileName}', '{$tmpFileName}');
parent.afterUploadConfigImage('{$name}', '{$tmpFileName}');
<!--@end-->
</script>

View file

@ -1627,7 +1627,7 @@ jQuery(function($){
$textareas.each(function(){
var $this = $(this);
var value = data.langs[$this.data('lang')];
var pattern = /^\$user_lang->/;
var pattern = /^\$user_lang-(?:>|&(?:amp;)?gt;)/;
if(pattern.test(value)){
$this.val('').data('value', '');
@ -1911,7 +1911,7 @@ jQuery(function($){
//var $displayInput = $this.siblings('.lang_code');
if($displayInput.data('active')){
$multilingualWindow.trigger('before-open.g11n', $displayInput.prev('.lang_code').val().replace('$user_lang->', ''));
$multilingualWindow.trigger('before-open.g11n', $displayInput.prev('.lang_code').val().replace(/\$user_lang-(?:>|&(?:amp;)?gt;)/, ''));
}else{
$multilingualWindow.trigger('before-open.g11n');
}
@ -1964,7 +1964,7 @@ jQuery(function($){
// load value
function loadValue(){
reset();
var pattern = /^\$user_lang->/;
var pattern = /^\$user_lang-(?:>|&(?:amp;)?gt;)/;
function on_complete2(data){
if(!data || !data.langs) return;
@ -1977,7 +1977,7 @@ jQuery(function($){
if(pattern.test($displayInput.val())){
$.exec_json('module.getModuleAdminLangCode', {
'name': $displayInput.val().replace('$user_lang->', ''),
'name': $displayInput.val().replace(pattern, ''),
'mid': current_url.getQuery('mid')
}, on_complete2);
}

View file

@ -1,5 +1,8 @@
<include target="./_header.html" />
<div class="content" id="content">
<div cond="Context::isBlacklistedPlugin(strtolower(preg_replace('/^disp([A-Z][a-z0-9_]+)[A-Z].+$/', '$1', $act)))" class="message error" style="margin-top:15px">
<p><em class="x_label x_label-important">{$lang->msg_warning}</em> {$lang->msg_blacklisted_module}</p>
</div>
{$content}
</div>
<include target="./_footer.html" />

View file

@ -49,6 +49,10 @@ class boardAdminController extends board {
if($args->protect_content!= 'Y') $args->protect_content = 'N';
if(!in_array($args->order_target,$this->order_target) && !array_key_exists($args->order_target, $extra_order_target)) $args->order_target = 'list_order';
if(!in_array($args->order_type, array('asc', 'desc'))) $args->order_type = 'asc';
$args->browser_title = trim(utf8_normalize_spaces($args->browser_title));
$args->meta_keywords = $args->meta_keywords ? implode(', ', array_map('trim', explode(',', $args->meta_keywords))) : '';
$args->meta_description = trim(utf8_normalize_spaces($args->meta_description));
// if there is an existed module
if($args->module_srl) {

View file

@ -317,7 +317,16 @@ class boardView extends board
else
{
// add the document title to the browser
Context::addBrowserTitle($oDocument->getTitleText());
Context::setCanonicalURL($oDocument->getPermanentUrl());
$seo_title = config('seo.document_title') ?: '$SITE_TITLE - $DOCUMENT_TITLE';
getController('module')->replaceDefinedLangCode($seo_title);
Context::setBrowserTitle($seo_title, array(
'site_title' => Context::getSiteTitle(),
'site_subtitle' => Context::getSiteSubtitle(),
'subpage_title' => $module_info->browser_title,
'document_title' => $oDocument->getTitleText(),
'page' => Context::get('page') ?: 1,
));
// update the document view count (if the document is not secret)
if(!$oDocument->isSecret() || $oDocument->isGranted())

View file

@ -29,6 +29,18 @@
<p id="browser_title_help" class="x_help-block" hidden>{$lang->about_browser_title}</p>
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="lang_meta_keywords">{$lang->meta_keywords}</label>
<div class="x_controls">
<input type="text" name="meta_keywords" id="meta_keywords" value="<!--@if(strpos($module_info->meta_keywords, '$user_lang->') === false)-->{$module_info->meta_keywords}<!--@else-->{htmlspecialchars($module_info->meta_keywords)}<!--@end-->" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="lang_meta_description">{$lang->meta_description}</label>
<div class="x_controls">
<input type="text" name="meta_description" id="meta_description" value="<!--@if(strpos($module_info->meta_description, '$user_lang->') === false)-->{$module_info->meta_description}<!--@else-->{htmlspecialchars($module_info->meta_description)}<!--@end-->" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="layout_srl">{$lang->layout}</label>
<div class="x_controls">

View file

@ -626,7 +626,7 @@ class documentItem extends Object
function getPermanentUrl()
{
return getFullUrl('','document_srl',$this->get('document_srl'));
return getFullUrl('', 'mid', $this->getDocumentMid(), 'document_srl', $this->get('document_srl'));
}
function getTrackbackUrl()

View file

@ -31,6 +31,10 @@ class pageAdminController extends page
unset($args->page_name);
if($args->use_mobile != 'Y') $args->use_mobile = '';
$args->browser_title = trim(utf8_normalize_spaces($args->browser_title));
$args->meta_keywords = $args->meta_keywords ? implode(', ', array_map('trim', explode(',', $args->meta_keywords))) : '';
$args->meta_description = trim(utf8_normalize_spaces($args->meta_description));
// Check if an original module exists by using module_srl
if($args->module_srl)
{

View file

@ -39,6 +39,18 @@
<input type="text" name="browser_title" id="browser_title" value="<!--@if(strpos($module_info->browser_title, '$user_lang->') === false)-->{$module_info->browser_title}<!--@else-->{htmlspecialchars($module_info->browser_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false)}<!--@end-->" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="lang_meta_keywords">{$lang->meta_keywords}</label>
<div class="x_controls">
<input type="text" name="meta_keywords" id="meta_keywords" value="<!--@if(strpos($module_info->meta_keywords, '$user_lang->') === false)-->{$module_info->meta_keywords}<!--@else-->{htmlspecialchars($module_info->meta_keywords)}<!--@end-->" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="lang_meta_description">{$lang->meta_description}</label>
<div class="x_controls">
<input type="text" name="meta_description" id="meta_description" value="<!--@if(strpos($module_info->meta_description, '$user_lang->') === false)-->{$module_info->meta_description}<!--@else-->{htmlspecialchars($module_info->meta_description)}<!--@end-->" class="lang_code" />
</div>
</div>
<div class="x_control-group">
<label class="x_control-label" for="layout_srl">{$lang->layout}</label>
<div class="x_controls">