diff options
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/prefs/DotComSiteSettings.java')
-rw-r--r-- | WordPress/src/main/java/org/wordpress/android/ui/prefs/DotComSiteSettings.java | 383 |
1 files changed, 383 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/DotComSiteSettings.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/DotComSiteSettings.java new file mode 100644 index 000000000..b59174ab5 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/DotComSiteSettings.java @@ -0,0 +1,383 @@ +package org.wordpress.android.ui.prefs; + +import android.app.Activity; + +import com.android.volley.VolleyError; +import com.wordpress.rest.RestRequest; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.wordpress.android.WordPress; +import org.wordpress.android.analytics.AnalyticsTracker; +import org.wordpress.android.datasets.SiteSettingsTable; +import org.wordpress.android.models.Blog; +import org.wordpress.android.models.CategoryModel; +import org.wordpress.android.util.AnalyticsUtils; +import org.wordpress.android.util.AppLog; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +class DotComSiteSettings extends SiteSettingsInterface { + // WP.com REST keys used in response to a settings GET and POST request + public static final String LANGUAGE_ID_KEY = "lang_id"; + public static final String PRIVACY_KEY = "blog_public"; + public static final String URL_KEY = "URL"; + public static final String DEF_CATEGORY_KEY = "default_category"; + public static final String DEF_POST_FORMAT_KEY = "default_post_format"; + public static final String RELATED_POSTS_ALLOWED_KEY = "jetpack_relatedposts_allowed"; + public static final String RELATED_POSTS_ENABLED_KEY = "jetpack_relatedposts_enabled"; + public static final String RELATED_POSTS_HEADER_KEY = "jetpack_relatedposts_show_headline"; + public static final String RELATED_POSTS_IMAGES_KEY = "jetpack_relatedposts_show_thumbnails"; + public static final String ALLOW_COMMENTS_KEY = "default_comment_status"; + public static final String SEND_PINGBACKS_KEY = "default_pingback_flag"; + public static final String RECEIVE_PINGBACKS_KEY = "default_ping_status"; + public static final String CLOSE_OLD_COMMENTS_KEY = "close_comments_for_old_posts"; + public static final String CLOSE_OLD_COMMENTS_DAYS_KEY = "close_comments_days_old"; + public static final String THREAD_COMMENTS_KEY = "thread_comments"; + public static final String THREAD_COMMENTS_DEPTH_KEY = "thread_comments_depth"; + public static final String PAGE_COMMENTS_KEY = "page_comments"; + public static final String PAGE_COMMENT_COUNT_KEY = "comments_per_page"; + public static final String COMMENT_SORT_ORDER_KEY = "comment_order"; + public static final String COMMENT_MODERATION_KEY = "comment_moderation"; + public static final String REQUIRE_IDENTITY_KEY = "require_name_email"; + public static final String REQUIRE_USER_ACCOUNT_KEY = "comment_registration"; + public static final String WHITELIST_KNOWN_USERS_KEY = "comment_whitelist"; + public static final String MAX_LINKS_KEY = "comment_max_links"; + public static final String MODERATION_KEYS_KEY = "moderation_keys"; + public static final String BLACKLIST_KEYS_KEY = "blacklist_keys"; + + // WP.com REST keys used to GET certain site settings + public static final String GET_TITLE_KEY = "name"; + public static final String GET_DESC_KEY = "description"; + + // WP.com REST keys used to POST updates to site settings + private static final String SET_TITLE_KEY = "blogname"; + private static final String SET_DESC_KEY = "blogdescription"; + + // JSON response keys + private static final String SETTINGS_KEY = "settings"; + private static final String UPDATED_KEY = "updated"; + + // WP.com REST keys used in response to a categories GET request + private static final String CAT_ID_KEY = "ID"; + private static final String CAT_NAME_KEY = "name"; + private static final String CAT_SLUG_KEY = "slug"; + private static final String CAT_DESC_KEY = "description"; + private static final String CAT_PARENT_ID_KEY = "parent"; + private static final String CAT_POST_COUNT_KEY = "post_count"; + private static final String CAT_NUM_POSTS_KEY = "found"; + private static final String CATEGORIES_KEY = "categories"; + + /** + * Only instantiated by {@link SiteSettingsInterface}. + */ + DotComSiteSettings(Activity host, Blog blog, SiteSettingsListener listener) { + super(host, blog, listener); + } + + @Override + public void saveSettings() { + super.saveSettings(); + + final Map<String, String> params = serializeDotComParams(); + if (params == null || params.isEmpty()) return; + + WordPress.getRestClientUtils().setGeneralSiteSettings( + String.valueOf(mBlog.getRemoteBlogId()), new RestRequest.Listener() { + @Override + public void onResponse(JSONObject response) { + AppLog.d(AppLog.T.API, "Site Settings saved remotely"); + notifySavedOnUiThread(null); + mRemoteSettings.copyFrom(mSettings); + + if (response != null) { + JSONObject updated = response.optJSONObject(UPDATED_KEY); + if (updated == null) return; + HashMap<String, Object> properties = new HashMap<>(); + Iterator<String> keys = updated.keys(); + while (keys.hasNext()) { + String currentKey = keys.next(); + Object currentValue = updated.opt(currentKey); + if (currentValue != null) { + properties.put(SAVED_ITEM_PREFIX + currentKey, currentValue); + } + } + AnalyticsUtils.trackWithCurrentBlogDetails( + AnalyticsTracker.Stat.SITE_SETTINGS_SAVED_REMOTELY, properties); + } + } + }, new RestRequest.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + AppLog.w(AppLog.T.API, "Error POSTing site settings changes: " + error); + notifySavedOnUiThread(error); + } + }, params); + } + + /** + * Request remote site data via the WordPress REST API. + */ + @Override + protected void fetchRemoteData() { + fetchCategories(); + WordPress.getRestClientUtils().getGeneralSettings( + String.valueOf(mBlog.getRemoteBlogId()), new RestRequest.Listener() { + @Override + public void onResponse(JSONObject response) { + AppLog.d(AppLog.T.API, "Received response to Settings REST request."); + credentialsVerified(true); + + mRemoteSettings.localTableId = mBlog.getRemoteBlogId(); + deserializeDotComRestResponse(mBlog, response); + if (!mRemoteSettings.equals(mSettings)) { + // postFormats setting is not returned by this api call so copy it over + final Map<String, String> currentPostFormats = mSettings.postFormats; + + mSettings.copyFrom(mRemoteSettings); + + mSettings.postFormats = currentPostFormats; + + SiteSettingsTable.saveSettings(mSettings); + notifyUpdatedOnUiThread(null); + } + } + }, new RestRequest.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + AppLog.w(AppLog.T.API, "Error response to Settings REST request: " + error); + notifyUpdatedOnUiThread(error); + } + }); + } + + /** + * Sets values from a .com REST response object. + */ + public void deserializeDotComRestResponse(Blog blog, JSONObject response) { + if (blog == null || response == null) return; + JSONObject settingsObject = response.optJSONObject(SETTINGS_KEY); + + mRemoteSettings.username = blog.getUsername(); + mRemoteSettings.password = blog.getPassword(); + mRemoteSettings.address = response.optString(URL_KEY, ""); + mRemoteSettings.title = response.optString(GET_TITLE_KEY, ""); + mRemoteSettings.tagline = response.optString(GET_DESC_KEY, ""); + mRemoteSettings.languageId = settingsObject.optInt(LANGUAGE_ID_KEY, -1); + mRemoteSettings.privacy = settingsObject.optInt(PRIVACY_KEY, -2); + mRemoteSettings.defaultCategory = settingsObject.optInt(DEF_CATEGORY_KEY, 0); + mRemoteSettings.defaultPostFormat = settingsObject.optString(DEF_POST_FORMAT_KEY, "0"); + mRemoteSettings.language = languageIdToLanguageCode(Integer.toString(mRemoteSettings.languageId)); + mRemoteSettings.allowComments = settingsObject.optBoolean(ALLOW_COMMENTS_KEY, true); + mRemoteSettings.sendPingbacks = settingsObject.optBoolean(SEND_PINGBACKS_KEY, false); + mRemoteSettings.receivePingbacks = settingsObject.optBoolean(RECEIVE_PINGBACKS_KEY, true); + mRemoteSettings.shouldCloseAfter = settingsObject.optBoolean(CLOSE_OLD_COMMENTS_KEY, false); + mRemoteSettings.closeCommentAfter = settingsObject.optInt(CLOSE_OLD_COMMENTS_DAYS_KEY, 0); + mRemoteSettings.shouldThreadComments = settingsObject.optBoolean(THREAD_COMMENTS_KEY, false); + mRemoteSettings.threadingLevels = settingsObject.optInt(THREAD_COMMENTS_DEPTH_KEY, 0); + mRemoteSettings.shouldPageComments = settingsObject.optBoolean(PAGE_COMMENTS_KEY, false); + mRemoteSettings.commentsPerPage = settingsObject.optInt(PAGE_COMMENT_COUNT_KEY, 0); + mRemoteSettings.commentApprovalRequired = settingsObject.optBoolean(COMMENT_MODERATION_KEY, false); + mRemoteSettings.commentsRequireIdentity = settingsObject.optBoolean(REQUIRE_IDENTITY_KEY, false); + mRemoteSettings.commentsRequireUserAccount = settingsObject.optBoolean(REQUIRE_USER_ACCOUNT_KEY, true); + mRemoteSettings.commentAutoApprovalKnownUsers = settingsObject.optBoolean(WHITELIST_KNOWN_USERS_KEY, false); + mRemoteSettings.maxLinks = settingsObject.optInt(MAX_LINKS_KEY, 0); + mRemoteSettings.holdForModeration = new ArrayList<>(); + mRemoteSettings.blacklist = new ArrayList<>(); + + String modKeys = settingsObject.optString(MODERATION_KEYS_KEY, ""); + if (modKeys.length() > 0) { + Collections.addAll(mRemoteSettings.holdForModeration, modKeys.split("\n")); + } + String blacklistKeys = settingsObject.optString(BLACKLIST_KEYS_KEY, ""); + if (blacklistKeys.length() > 0) { + Collections.addAll(mRemoteSettings.blacklist, blacklistKeys.split("\n")); + } + + if (settingsObject.optString(COMMENT_SORT_ORDER_KEY, "").equals("asc")) { + mRemoteSettings.sortCommentsBy = ASCENDING_SORT; + } else { + mRemoteSettings.sortCommentsBy = DESCENDING_SORT; + } + + if (settingsObject.optBoolean(RELATED_POSTS_ALLOWED_KEY, false)) { + mRemoteSettings.showRelatedPosts = settingsObject.optBoolean(RELATED_POSTS_ENABLED_KEY, false); + mRemoteSettings.showRelatedPostHeader = settingsObject.optBoolean(RELATED_POSTS_HEADER_KEY, false); + mRemoteSettings.showRelatedPostImages = settingsObject.optBoolean(RELATED_POSTS_IMAGES_KEY, false); + } + } + + /** + * Helper method to create the parameters for the site settings POST request + * + * Using undocumented endpoint WPCOM_JSON_API_Site_Settings_Endpoint + * https://wpcom.trac.automattic.com/browser/trunk/public.api/rest/json-endpoints.php#L1903 + */ + public Map<String, String> serializeDotComParams() { + Map<String, String> params = new HashMap<>(); + + if (mSettings.title!= null && !mSettings.title.equals(mRemoteSettings.title)) { + params.put(SET_TITLE_KEY, mSettings.title); + } + if (mSettings.tagline != null && !mSettings.tagline.equals(mRemoteSettings.tagline)) { + params.put(SET_DESC_KEY, mSettings.tagline); + } + if (mSettings.languageId != mRemoteSettings.languageId) { + params.put(LANGUAGE_ID_KEY, String.valueOf((mSettings.languageId))); + } + if (mSettings.privacy != mRemoteSettings.privacy) { + params.put(PRIVACY_KEY, String.valueOf((mSettings.privacy))); + } + if (mSettings.defaultCategory != mRemoteSettings.defaultCategory) { + params.put(DEF_CATEGORY_KEY, String.valueOf(mSettings.defaultCategory)); + } + if (mSettings.defaultPostFormat != null && !mSettings.defaultPostFormat.equals(mRemoteSettings.defaultPostFormat)) { + params.put(DEF_POST_FORMAT_KEY, mSettings.defaultPostFormat); + } + if (mSettings.showRelatedPosts != mRemoteSettings.showRelatedPosts || + mSettings.showRelatedPostHeader != mRemoteSettings.showRelatedPostHeader || + mSettings.showRelatedPostImages != mRemoteSettings.showRelatedPostImages) { + params.put(RELATED_POSTS_ENABLED_KEY, String.valueOf(mSettings.showRelatedPosts)); + params.put(RELATED_POSTS_HEADER_KEY, String.valueOf(mSettings.showRelatedPostHeader)); + params.put(RELATED_POSTS_IMAGES_KEY, String.valueOf(mSettings.showRelatedPostImages)); + } + if (mSettings.allowComments != mRemoteSettings.allowComments) { + params.put(ALLOW_COMMENTS_KEY, String.valueOf(mSettings.allowComments)); + } + if (mSettings.sendPingbacks != mRemoteSettings.sendPingbacks) { + params.put(SEND_PINGBACKS_KEY, String.valueOf(mSettings.sendPingbacks)); + } + if (mSettings.receivePingbacks != mRemoteSettings.receivePingbacks) { + params.put(RECEIVE_PINGBACKS_KEY, String.valueOf(mSettings.receivePingbacks)); + } + if (mSettings.commentApprovalRequired != mRemoteSettings.commentApprovalRequired) { + params.put(COMMENT_MODERATION_KEY, String.valueOf(mSettings.commentApprovalRequired)); + } + if (mSettings.closeCommentAfter != mRemoteSettings.closeCommentAfter + || mSettings.shouldCloseAfter != mRemoteSettings.shouldCloseAfter) { + params.put(CLOSE_OLD_COMMENTS_KEY, String.valueOf(mSettings.shouldCloseAfter)); + params.put(CLOSE_OLD_COMMENTS_DAYS_KEY, String.valueOf(mSettings.closeCommentAfter)); + } + if (mSettings.sortCommentsBy != mRemoteSettings.sortCommentsBy) { + if (mSettings.sortCommentsBy == ASCENDING_SORT) { + params.put(COMMENT_SORT_ORDER_KEY, "asc"); + } else if (mSettings.sortCommentsBy == DESCENDING_SORT) { + params.put(COMMENT_SORT_ORDER_KEY, "desc"); + } + } + if (mSettings.threadingLevels != mRemoteSettings.threadingLevels + || mSettings.shouldThreadComments != mRemoteSettings.shouldThreadComments) { + params.put(THREAD_COMMENTS_KEY, String.valueOf(mSettings.shouldThreadComments)); + params.put(THREAD_COMMENTS_DEPTH_KEY, String.valueOf(mSettings.threadingLevels)); + } + if (mSettings.commentsPerPage != mRemoteSettings.commentsPerPage + || mSettings.shouldPageComments != mRemoteSettings.shouldPageComments) { + params.put(PAGE_COMMENTS_KEY, String.valueOf(mSettings.shouldPageComments)); + params.put(PAGE_COMMENT_COUNT_KEY, String.valueOf(mSettings.commentsPerPage)); + } + if (mSettings.commentsRequireIdentity != mRemoteSettings.commentsRequireIdentity) { + params.put(REQUIRE_IDENTITY_KEY, String.valueOf(mSettings.commentsRequireIdentity)); + } + if (mSettings.commentsRequireUserAccount != mRemoteSettings.commentsRequireUserAccount) { + params.put(REQUIRE_USER_ACCOUNT_KEY, String.valueOf(mSettings.commentsRequireUserAccount)); + } + if (mSettings.commentAutoApprovalKnownUsers != mRemoteSettings.commentAutoApprovalKnownUsers) { + params.put(WHITELIST_KNOWN_USERS_KEY, String.valueOf(mSettings.commentAutoApprovalKnownUsers)); + } + if (mSettings.maxLinks != mRemoteSettings.maxLinks) { + params.put(MAX_LINKS_KEY, String.valueOf(mSettings.maxLinks)); + } + if (mSettings.holdForModeration != null && !mSettings.holdForModeration.equals(mRemoteSettings.holdForModeration)) { + StringBuilder builder = new StringBuilder(); + for (String key : mSettings.holdForModeration) { + builder.append(key); + builder.append("\n"); + } + if (builder.length() > 1) { + params.put(MODERATION_KEYS_KEY, builder.substring(0, builder.length() - 1)); + } else { + params.put(MODERATION_KEYS_KEY, ""); + } + } + if (mSettings.blacklist != null && !mSettings.blacklist.equals(mRemoteSettings.blacklist)) { + StringBuilder builder = new StringBuilder(); + for (String key : mSettings.blacklist) { + builder.append(key); + builder.append("\n"); + } + if (builder.length() > 1) { + params.put(BLACKLIST_KEYS_KEY, builder.substring(0, builder.length() - 1)); + } else { + params.put(BLACKLIST_KEYS_KEY, ""); + } + } + + return params; + } + + /** + * Request a list of post categories for a site via the WordPress REST API. + */ + private void fetchCategories() { + WordPress.getRestClientUtilsV1_1().getCategories(String.valueOf(mBlog.getRemoteBlogId()), + new RestRequest.Listener() { + @Override + public void onResponse(JSONObject response) { + AppLog.d(AppLog.T.API, "Received response to Categories REST request."); + credentialsVerified(true); + + CategoryModel[] models = deserializeJsonRestResponse(response); + if (models == null) return; + + SiteSettingsTable.saveCategories(models); + mRemoteSettings.categories = models; + mSettings.categories = models; + notifyUpdatedOnUiThread(null); + } + }, new RestRequest.ErrorListener() { + @Override + public void onErrorResponse(VolleyError error) { + AppLog.d(AppLog.T.API, "Error fetching WP.com categories:" + error); + } + }); + } + + private CategoryModel deserializeCategoryFromJson(JSONObject category) throws JSONException { + if (category == null) return null; + + CategoryModel model = new CategoryModel(); + model.id = category.getInt(CAT_ID_KEY); + model.name = category.getString(CAT_NAME_KEY); + model.slug = category.getString(CAT_SLUG_KEY); + model.description = category.getString(CAT_DESC_KEY); + model.parentId = category.getInt(CAT_PARENT_ID_KEY); + model.postCount = category.getInt(CAT_POST_COUNT_KEY); + + return model; + } + + private CategoryModel[] deserializeJsonRestResponse(JSONObject response) { + try { + int num = response.getInt(CAT_NUM_POSTS_KEY); + JSONArray categories = response.getJSONArray(CATEGORIES_KEY); + CategoryModel[] models = new CategoryModel[num]; + + for (int i = 0; i < num; ++i) { + JSONObject category = categories.getJSONObject(i); + models[i] = deserializeCategoryFromJson(category); + } + + AppLog.d(AppLog.T.API, "Successfully fetched WP.com categories"); + + return models; + } catch (JSONException exception) { + AppLog.d(AppLog.T.API, "Error parsing WP.com categories response:" + response); + return null; + } + } +} |