Commit 6bdfa922 authored by Liang Ding's avatar Liang Ding

Fix #12041

parent 017f9fda
......@@ -43,9 +43,10 @@ import org.b3log.solo.event.rhythm.ArticleUpdater;
import org.b3log.solo.event.symphony.CommentSender;
import org.b3log.solo.model.Preference;
import org.b3log.solo.model.Skin;
import org.b3log.solo.repository.PreferenceRepository;
import org.b3log.solo.repository.impl.PreferenceRepositoryImpl;
import org.b3log.solo.repository.OptionRepository;
import org.b3log.solo.repository.impl.OptionRepositoryImpl;
import org.b3log.solo.service.PreferenceMgmtService;
import org.b3log.solo.service.PreferenceQueryService;
import org.b3log.solo.service.StatisticMgmtService;
import org.b3log.solo.service.UpgradeService;
import org.b3log.solo.util.Skins;
......@@ -55,7 +56,7 @@ import org.json.JSONObject;
* Solo Servlet listener.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.6.0.9, Nov 5, 2015
* @version 1.7.0.9, Nov 8, 2015
* @since 0.3.1
*/
public final class SoloServletListener extends AbstractServletListener {
......@@ -123,9 +124,9 @@ public final class SoloServletListener extends AbstractServletListener {
// Set default skin, loads from preference later
Skins.setDirectoryForTemplateLoading(Preference.Default.DEFAULT_SKIN_DIR_NAME);
final PreferenceRepository preferenceRepository = beanManager.getReference(PreferenceRepositoryImpl.class);
final OptionRepository optionRepository = beanManager.getReference(OptionRepositoryImpl.class);
final Transaction transaction = preferenceRepository.beginTransaction();
final Transaction transaction = optionRepository.beginTransaction();
try {
loadPreference();
......@@ -218,11 +219,11 @@ public final class SoloServletListener extends AbstractServletListener {
LOGGER.debug("Loading preference....");
final PreferenceRepository preferenceRepository = beanManager.getReference(PreferenceRepositoryImpl.class);
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
JSONObject preference;
try {
preference = preferenceRepository.get(Preference.PREFERENCE);
preference = preferenceQueryService.getPreference();
if (null == preference) {
LOGGER.warn("Can't not init default skin, please init Solo first");
return;
......@@ -282,8 +283,8 @@ public final class SoloServletListener extends AbstractServletListener {
*/
private void resolveSkinDir(final HttpServletRequest httpServletRequest) {
try {
final PreferenceRepository preferenceRepository = beanManager.getReference(PreferenceRepositoryImpl.class);
final JSONObject preference = preferenceRepository.get(Preference.PREFERENCE);
final PreferenceQueryService preferenceQueryService = beanManager.getReference(PreferenceQueryService.class);
final JSONObject preference = preferenceQueryService.getPreference();
if (null == preference) { // Did not initialize yet
return;
......
......@@ -19,7 +19,7 @@ package org.b3log.solo.model;
* This class defines option model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.1, Nov 7, 2015
* @version 1.2.0.1, Nov 8, 2015
* @since 0.6.0
*/
public final class Option {
......@@ -70,6 +70,201 @@ public final class Option {
*/
public static final String ID_C_QINIU_BUCKET = "qiniuBucket";
/**
* Key of blog title.
*/
public static final String ID_C_BLOG_TITLE = "blogTitle";
/**
* Key of blog subtitle.
*/
public static final String ID_C_BLOG_SUBTITLE = "blogSubtitle";
/**
* Key of relevant articles display count.
*/
public static final String ID_C_RELEVANT_ARTICLES_DISPLAY_CNT = "relevantArticlesDisplayCount";
/**
* Key of random articles display count.
*/
public static final String ID_C_RANDOM_ARTICLES_DISPLAY_CNT = "randomArticlesDisplayCount";
/**
* Key of external relevant articles display count.
*/
public static final String ID_C_EXTERNAL_RELEVANT_ARTICLES_DISPLAY_CNT = "externalRelevantArticlesDisplayCount";
/**
* Key of recent article display count.
*/
public static final String ID_C_RECENT_ARTICLE_DISPLAY_CNT = "recentArticleDisplayCount";
/**
* Key of recent comment display count.
*/
public static final String ID_C_RECENT_COMMENT_DISPLAY_CNT = "recentCommentDisplayCount";
/**
* Key of most used tag display count.
*/
public static final String ID_C_MOST_USED_TAG_DISPLAY_CNT = "mostUsedTagDisplayCount";
/**
* Key of most comment article display count.
*/
public static final String ID_C_MOST_COMMENT_ARTICLE_DISPLAY_CNT = "mostCommentArticleDisplayCount";
/**
* Key of most view article display count.
*/
public static final String ID_C_MOST_VIEW_ARTICLE_DISPLAY_CNT = "mostViewArticleDisplayCount";
/**
* Key of article list display count.
*/
public static final String ID_C_ARTICLE_LIST_DISPLAY_COUNT = "articleListDisplayCount";
/**
* Key of article list pagination window size.
*/
public static final String ID_C_ARTICLE_LIST_PAGINATION_WINDOW_SIZE = "articleListPaginationWindowSize";
/**
* Key of administrator's email.
*/
public static final String ID_C_ADMIN_EMAIL = "adminEmail";
/**
* Key of locale string.
*/
public static final String ID_C_LOCALE_STRING = "localeString";
/**
* Key of time zone id.
*/
public static final String ID_C_TIME_ZONE_ID = "timeZoneId";
/**
* Key of notice board.
*/
public static final String ID_C_NOTICE_BOARD = "noticeBoard";
/**
* Key of HTML head.
*/
public static final String ID_C_HTML_HEAD = "htmlHead";
/**
* Key of meta keywords.
*/
public static final String ID_C_META_KEYWORDS = "metaKeywords";
/**
* Key of meta description.
*/
public static final String ID_C_META_DESCRIPTION = "metaDescription";
/**
* Key of article update hint flag.
*/
public static final String ID_C_ENABLE_ARTICLE_UPDATE_HINT = "enableArticleUpdateHint";
/**
* Key of signs.
*/
public static final String ID_C_SIGNS = "signs";
/**
* Key of key of Solo.
*/
public static final String ID_C_KEY_OF_SOLO = "keyOfSolo";
/**
* Key of allow visit draft via permalink.
*/
public static final String ID_C_ALLOW_VISIT_DRAFT_VIA_PERMALINK = "allowVisitDraftViaPermalink";
/**
* Key of version.
*/
public static final String ID_C_VERSION = "version";
/**
* Key of article list display style.
*
* <p>
* Optional values:
* <ul>
* <li>"titleOnly"</li>
* <li>"titleAndContent"</li>
* <li>"titleAndAbstract"</li>
* </ul>
* </p>
*/
public static final String ID_C_ARTICLE_LIST_STYLE = "articleListStyle";
/**
* Key of article/page comment-able.
*/
public static final String ID_C_COMMENTABLE = "commentable";
/**
* Key of feed (Atom/RSS) output mode.
*
* <p>
* Optional values:
* <ul>
* <li>"abstract"</li>
* <li>"fullContent"</li>
* </ul>
* </p>
*/
public static final String ID_C_FEED_OUTPUT_MODE = "feedOutputMode";
/**
* Key of feed (Atom/RSS) output entry count.
*/
public static final String ID_C_FEED_OUTPUT_CNT = "feedOutputCnt";
/**
* Key of editor type.
*
* Optional values:
* <p>
* <ul>
* <li>"tinyMCE"</li>
* <li>"CodeMirror-Markdown"</li>
* </ul>
* </p>
*/
public static final String ID_C_EDITOR_TYPE = "editorType";
/**
* Key of skins.
*/
public static final String ID_C_SKINS = "skins";
/**
* Key of skin dir name.
*/
public static final String ID_C_SKIN_DIR_NAME = "skinDirName";
/**
* Key of skin name.
*/
public static final String ID_C_SKIN_NAME = "skinName";
/**
* Key of reply notification template body.
*/
public static final String ID_C_REPLY_NOTI_TPL_BODY = "replyNotiTplBody";
/**
* Key of reply notification template subject.
*/
public static final String ID_C_REPLY_NOTI_TPL_SUBJECT = "replyNotiTplSubject";
/**
* Key of footer content.
*/
......
......@@ -27,7 +27,7 @@ import org.json.JSONObject;
* This class defines all comment model relevant keys.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.10, Jun 18, 2015
* @version 1.2.0.10, Nov 8, 2015
* @since 0.3.1
*/
public final class Preference {
......@@ -291,7 +291,7 @@ public final class Preference {
/**
* Default enable article update hint.
*/
public static final boolean DEFAULT_ENABLE_ARTICLE_UPDATE_HINT = true;
public static final String DEFAULT_ENABLE_ARTICLE_UPDATE_HINT = "true";
/**
* Default notice board.
......@@ -313,6 +313,11 @@ public final class Preference {
*/
public static final String DEFAULT_HTML_HEAD = "";
/**
* Default footer content.
*/
public static final String DEFAULT_FOOTER_CONTENT = "";
/**
* Default relevant articles display count.
*/
......@@ -341,12 +346,12 @@ public final class Preference {
/**
* Default allow visit draft via permalink.
*/
public static final boolean DEFAULT_ALLOW_VISIT_DRAFT_VIA_PERMALINK = false;
public static final String DEFAULT_ALLOW_VISIT_DRAFT_VIA_PERMALINK = "false";
/**
* Default allow comment article/page.
*/
public static final boolean DEFAULT_COMMENTABLE = true;
public static final String DEFAULT_COMMENTABLE = "true";
/**
* Default administrator's password.
......@@ -404,7 +409,6 @@ public final class Preference {
final JSONObject replyNotificationTemplate = new JSONObject();
replyNotificationTemplate.put(Keys.OBJECT_ID, Preference.REPLY_NOTIFICATION_TEMPLATE);
replyNotificationTemplate.put("subject", "${blogTitle}: New reply of your comment");
replyNotificationTemplate.put("body",
"Your comment on post[<a href='${postLink}'>" + "${postTitle}</a>] received an reply: <p>${replier}"
......
......@@ -15,7 +15,6 @@
*/
package org.b3log.solo.processor;
import java.io.IOException;
import java.util.List;
import java.util.Set;
......@@ -48,9 +47,9 @@ import org.b3log.solo.repository.impl.ArchiveDateRepositoryImpl;
import org.b3log.solo.repository.impl.ArticleRepositoryImpl;
import org.b3log.solo.repository.impl.CommentRepositoryImpl;
import org.b3log.solo.repository.impl.LinkRepositoryImpl;
import org.b3log.solo.repository.impl.OptionRepositoryImpl;
import org.b3log.solo.repository.impl.PageRepositoryImpl;
import org.b3log.solo.repository.impl.PluginRepositoryImpl;
import org.b3log.solo.repository.impl.PreferenceRepositoryImpl;
import org.b3log.solo.repository.impl.StatisticRepositoryImpl;
import org.b3log.solo.repository.impl.TagArticleRepositoryImpl;
import org.b3log.solo.repository.impl.TagRepositoryImpl;
......@@ -62,14 +61,14 @@ import org.b3log.solo.service.StatisticQueryService;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Provides patches on some special issues.
*
* <p>See AuthFilter filter configurations in web.xml for authentication.</p>
* <p>
* See AuthFilter filter configurations in web.xml for authentication.</p>
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.10, Oct 26, 2013
* @version 1.2.0.10, Nov 8, 2015
* @since 0.3.1
*/
@RequestProcessor
......@@ -173,7 +172,7 @@ public class RepairProcessor {
articleRepository.update(article.getString(Keys.OBJECT_ID), article);
LOGGER.log(Level.INFO, "Found an article[id={0}] exists unused properties[{1}]",
new Object[] {article.getString(Keys.OBJECT_ID), nameSet});
new Object[]{article.getString(Keys.OBJECT_ID), nameSet});
}
}
......@@ -193,10 +192,10 @@ public class RepairProcessor {
*
* <p>
* <ul>
* <li>Uses the value of {@link Statistic#STATISTIC_PUBLISHED_BLOG_COMMENT_COUNT}
* for {@link Statistic#STATISTIC_BLOG_COMMENT_COUNT}</li>
* <li>Uses the value of {@link Statistic#STATISTIC_PUBLISHED_ARTICLE_COUNT}
* for {@link Statistic#STATISTIC_BLOG_ARTICLE_COUNT}</li>
* <li>Uses the value of {@link Statistic#STATISTIC_PUBLISHED_BLOG_COMMENT_COUNT} for
* {@link Statistic#STATISTIC_BLOG_COMMENT_COUNT}</li>
* <li>Uses the value of {@link Statistic#STATISTIC_PUBLISHED_ARTICLE_COUNT} for
* {@link Statistic#STATISTIC_BLOG_ARTICLE_COUNT}</li>
* </ul>
* </p>
*
......@@ -316,7 +315,7 @@ public class RepairProcessor {
tagRepository.update(tagId, tag);
LOGGER.log(Level.INFO, "Repaired tag[title={0}, refCnt={1}, publishedTagRefCnt={2}]",
new Object[] {tag.getString(Tag.TAG_TITLE), tagRefCnt, publishedTagRefCnt});
new Object[]{tag.getString(Tag.TAG_TITLE), tagRefCnt, publishedTagRefCnt});
}
renderer.setContent("Repair sucessfully!");
......@@ -382,13 +381,13 @@ public class RepairProcessor {
remove(beanManager.getReference(ArticleRepositoryImpl.class));
remove(beanManager.getReference(CommentRepositoryImpl.class));
remove(beanManager.getReference(LinkRepositoryImpl.class));
remove(beanManager.getReference(OptionRepositoryImpl.class));
remove(beanManager.getReference(PageRepositoryImpl.class));
remove(beanManager.getReference(PreferenceRepositoryImpl.class));
remove(beanManager.getReference(PluginRepositoryImpl.class));
remove(beanManager.getReference(StatisticRepositoryImpl.class));
remove(beanManager.getReference(TagArticleRepositoryImpl.class));
remove(beanManager.getReference(TagRepositoryImpl.class));
remove(beanManager.getReference(UserRepositoryImpl.class));
remove(beanManager.getReference(PluginRepositoryImpl.class));
succeed = true;
} catch (final Exception e) {
......
......@@ -25,5 +25,7 @@ import org.b3log.latke.repository.Repository;
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Aug 14, 2010
* @since 0.3.1
* @deprecated this class will be removed in 1.3.0, see issue <a href="https://github.com/b3log/solo/issues/12042">#12042</a>
* for more details
*/
public interface PreferenceRepository extends Repository {}
......@@ -30,6 +30,8 @@ import org.json.JSONObject;
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.3, Feb 28, 2012
* @since 0.3.1
* @deprecated this class will be removed in 1.3.0, see issue <a href="https://github.com/b3log/solo/issues/12042">#12042</a>
* for more details
*/
@Repository
public class PreferenceRepositoryImpl extends AbstractRepository implements PreferenceRepository {
......
......@@ -15,23 +15,28 @@
*/
package org.b3log.solo.service;
import javax.inject.Inject;
import org.b3log.latke.Keys;
import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger;
import org.b3log.latke.repository.FilterOperator;
import org.b3log.latke.repository.PropertyFilter;
import org.b3log.latke.repository.Query;
import org.b3log.latke.repository.RepositoryException;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.service.annotation.Service;
import org.b3log.solo.model.Option;
import org.b3log.solo.model.Preference;
import org.b3log.solo.repository.OptionRepository;
import org.b3log.solo.repository.PreferenceRepository;
import org.json.JSONArray;
import org.json.JSONObject;
/**
* Preference query service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, Oct 31, 2011
* @version 1.1.0.1, Nov 8, 2015
* @since 0.4.0
*/
@Service
......@@ -48,6 +53,12 @@ public class PreferenceQueryService {
@Inject
private PreferenceRepository preferenceRepository;
/**
* Option repository.
*/
@Inject
private OptionRepository optionRepository;
/**
* Gets the reply notification template.
*
......@@ -56,7 +67,13 @@ public class PreferenceQueryService {
*/
public JSONObject getReplyNotificationTemplate() throws ServiceException {
try {
return preferenceRepository.get(Preference.REPLY_NOTIFICATION_TEMPLATE);
final JSONObject ret = new JSONObject();
final JSONObject preference = getPreference();
ret.put("subject", preference.optString(Option.ID_C_REPLY_NOTI_TPL_SUBJECT));
ret.put("body", preference.optString(Option.ID_C_REPLY_NOTI_TPL_BODY));
return ret;
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Updates reply notification template failed", e);
throw new ServiceException(e);
......@@ -66,26 +83,30 @@ public class PreferenceQueryService {
/**
* Gets the user preference.
*
* <p>
* <b>Note</b>: Invoking the method will not load skin.
* </p>
*
* @return user preference, returns {@code null} if not found
* @throws ServiceException if repository exception
*/
public JSONObject getPreference() throws ServiceException {
try {
final JSONObject ret = preferenceRepository.get(Preference.PREFERENCE);
if (null == ret) {
LOGGER.log(Level.WARN, "Can not load preference from datastore");
final JSONObject checkInit = optionRepository.get(Option.ID_C_ADMIN_EMAIL);
if (null == checkInit) {
return null;
}
final Query query = new Query();
query.setFilter(new PropertyFilter(Option.OPTION_CATEGORY, FilterOperator.EQUAL, Option.CATEGORY_C_PREFERENCE));
final JSONArray opts = optionRepository.get(query).optJSONArray(Keys.RESULTS);
final JSONObject ret = new JSONObject();
for (int i = 0; i < opts.length(); i++) {
final JSONObject opt = opts.optJSONObject(i);
ret.put(opt.optString(Keys.OBJECT_ID), opt.opt(Option.OPTION_VALUE));
}
return ret;
} catch (final RepositoryException e) {
LOGGER.log(Level.ERROR, e.getMessage(), e);
throw new IllegalStateException(e);
return null;
}
}
......
......@@ -212,7 +212,7 @@
return;
}
window.location.href = "${servePath}/admin-index.do#tools/user-list";
window.location.href = "${servePath}/admin-index.do#main";
}
});
}
......
......@@ -58,10 +58,8 @@ public class PreferenceMgmtServiceTestCase extends AbstractTestCase {
*/
@Test(dependsOnMethods = "init")
public void updatePreference() throws Exception {
final PreferenceMgmtService preferenceMgmtService =
getPreferenceMgmtService();
final PreferenceQueryService preferenceQueryService =
getPreferenceQueryService();
final PreferenceMgmtService preferenceMgmtService = getPreferenceMgmtService();
final PreferenceQueryService preferenceQueryService = getPreferenceQueryService();
JSONObject preference = preferenceQueryService.getPreference();
Assert.assertEquals(preference.getString(Preference.BLOG_TITLE),
......@@ -71,8 +69,7 @@ public class PreferenceMgmtServiceTestCase extends AbstractTestCase {
preferenceMgmtService.updatePreference(preference);
preference = preferenceQueryService.getPreference();
Assert.assertEquals(preference.getString(Preference.BLOG_TITLE),
"updated blog title");
Assert.assertEquals(preference.getString(Preference.BLOG_TITLE), "updated blog title");
}
/**
......@@ -82,12 +79,12 @@ public class PreferenceMgmtServiceTestCase extends AbstractTestCase {
*/
@Test(dependsOnMethods = "init")
public void updateReplyNotificationTemplate() throws Exception {
final PreferenceMgmtService preferenceMgmtService =
getPreferenceMgmtService();
final PreferenceQueryService preferenceQueryService =
getPreferenceQueryService();
JSONObject replyNotificationTemplate =
preferenceQueryService.getReplyNotificationTemplate();
final PreferenceMgmtService preferenceMgmtService
= getPreferenceMgmtService();
final PreferenceQueryService preferenceQueryService
= getPreferenceQueryService();
JSONObject replyNotificationTemplate
= preferenceQueryService.getReplyNotificationTemplate();
Assert.assertEquals(replyNotificationTemplate.toString(),
Preference.Default.DEFAULT_REPLY_NOTIFICATION_TEMPLATE);
......@@ -96,8 +93,8 @@ public class PreferenceMgmtServiceTestCase extends AbstractTestCase {
preferenceMgmtService.updateReplyNotificationTemplate(
replyNotificationTemplate);
replyNotificationTemplate =
preferenceQueryService.getReplyNotificationTemplate();
replyNotificationTemplate
= preferenceQueryService.getReplyNotificationTemplate();
Assert.assertEquals(replyNotificationTemplate.getString(
"subject"), "updated subject");
}
......
......@@ -31,3 +31,5 @@ helloWorld.content=\u6b22\u8fce\u4f7f\u7528 \
<span style="color: orangered; font-weight: bold;">Solo</span></a>\
\u3002\u8fd9\u662f\u7cfb\u7edf\u81ea\u52a8\u751f\u6210\u7684\u6f14\u793a\u6587\u7ae0\u3002\u7f16\u8f91\u6216\u8005\u5220\u9664\u5b83\uff0c\u7136\u540e\u5f00\u59cb\u60a8\u7684\u535a\u5ba2\uff01
helloWorld.comment.content=\u60a8\u597d\uff0c\u8fd9\u662f\u4e00\u6761\u8bc4\u8bba\u3002_esc_enter_88250_\u8981\u5220\u9664\u8bc4\u8bba\uff0c\u8bf7\u5148\u767b\u5f55\uff0c\u7136\u540e\u518d\u67e5\u770b\u8fd9\u7bc7\u6587\u7ae0\u7684\u8bc4\u8bba\u3002\u5728\u90a3\u91cc\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u7f16\u8f91\u6216\u8005\u5220\u9664\u8bc4\u8bba\u7684\u9009\u9879\u3002
updateFailLabel=\u66f4\u65b0\u5931\u8d25
\ No newline at end of file
#
# Copyright (c) 2010-2015, b3log.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# Description: Finding skin.
# Version: 1.1.0.0, Sep 16, 2015
# Author: Liyuan Li
#
name=Finding
version=1.0.1
forSolo=1.1.0
memo=http://demo.ghost.io
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment