diff --git a/WKData/Sources/WKData/Data Controllers/Watchlist/WKWatchlistDataController.swift b/WKData/Sources/WKData/Data Controllers/Watchlist/WKWatchlistDataController.swift index 91d2070296b..42712b1c6aa 100644 --- a/WKData/Sources/WKData/Data Controllers/Watchlist/WKWatchlistDataController.swift +++ b/WKData/Sources/WKData/Data Controllers/Watchlist/WKWatchlistDataController.swift @@ -447,7 +447,7 @@ public class WKWatchlistDataController { // MARK: POST Rollback Page - public func rollback(title: String, project: WKProject, username: String, editSummaryTag: WKEditSummaryTag, completion: @escaping (Result) -> Void) { + public func rollback(title: String, project: WKProject, username: String, completion: @escaping (Result) -> Void) { guard let service else { completion(.failure(WKDataControllerError.mediaWikiServiceUnavailable)) @@ -458,7 +458,7 @@ public class WKWatchlistDataController { "action": "rollback", "title": title, "user": username, - "summary": editSummaryTag.rawValue, + "matags": WKEditTag.appRollback.rawValue, "format": "json", "formatversion": "2", "errorformat": "html", @@ -490,7 +490,7 @@ public class WKWatchlistDataController { // MARK: POST Undo Revision - public func undo(title: String, revisionID: UInt, summary: String, username: String, editSummaryTag: WKEditSummaryTag, project: WKProject, completion: @escaping (Result) -> Void) { + public func undo(title: String, revisionID: UInt, summary: String, username: String, project: WKProject, completion: @escaping (Result) -> Void) { guard let service else { completion(.failure(WKDataControllerError.mediaWikiServiceUnavailable)) @@ -501,13 +501,14 @@ public class WKWatchlistDataController { switch result { case .success(let summaryPrefix): - let finalSummary = summaryPrefix + " " + summary + " " + editSummaryTag.rawValue + let finalSummary = summaryPrefix + " " + summary let parameters = [ "action": "edit", "title": title, "summary": finalSummary, "undo": String(revisionID), + "matags": WKEditTag.appUndo.rawValue, "format": "json", "formatversion": "2", "errorformat": "html", diff --git a/WKData/Sources/WKData/Models/Shared/WKEditSummaryTag.swift b/WKData/Sources/WKData/Models/Shared/WKEditSummaryTag.swift index 8e6d75f7023..7202cb56ed2 100644 --- a/WKData/Sources/WKData/Models/Shared/WKEditSummaryTag.swift +++ b/WKData/Sources/WKData/Models/Shared/WKEditSummaryTag.swift @@ -1,6 +1,7 @@ import Foundation /// Hashtags appended to edit summaries throughout the app, for identification in mediawiki history. +@available(*, deprecated, message: "Please use WKEditTag instead.") public enum WKEditSummaryTag: String { case articleSectionSourceEditor = "#article-section-source-editor" case articleFullSourceEditor = "#article-full-source-editor" @@ -14,3 +15,12 @@ public enum WKEditSummaryTag: String { case talkTopic = "#talk-topic" case suggestedEditsAddImageTop = "#app-image-add-top" } + +/// Edit tags added to all MediaWiki API edit calls +public enum WKEditTag: String { + case appSuggestedEdit = "app-suggestededit" + case appUndo = "app-undo" + case appRollback = "app-rollback" + case appDescriptionAdd = "app-description-add" + case appDescriptionChange = "app-description-change" +} diff --git a/WKData/Tests/WKDataTests/WKWatchlistDataControllerTests.swift b/WKData/Tests/WKDataTests/WKWatchlistDataControllerTests.swift index 88e593c46e2..b2be25c88fc 100644 --- a/WKData/Tests/WKDataTests/WKWatchlistDataControllerTests.swift +++ b/WKData/Tests/WKDataTests/WKWatchlistDataControllerTests.swift @@ -423,7 +423,7 @@ final class WKWatchlistDataControllerTests: XCTestCase { let expectation = XCTestExpectation(description: "Post Rollback Article") var resultToTest: Result? - controller.rollback(title: "Cat", project: enProject, username: "Amigao", editSummaryTag: .diffRollback) { result in + controller.rollback(title: "Cat", project: enProject, username: "Amigao") { result in resultToTest = result expectation.fulfill() } @@ -449,7 +449,7 @@ final class WKWatchlistDataControllerTests: XCTestCase { let expectation = XCTestExpectation(description: "Post Undo Article") var resultToTest: Result? - controller.undo(title: "Cat", revisionID: 1155871225, summary: "Testing", username: "Amigao", editSummaryTag: .diffUndo, project: enProject) { result in + controller.undo(title: "Cat", revisionID: 1155871225, summary: "Testing", username: "Amigao", project: enProject) { result in resultToTest = result expectation.fulfill() } diff --git a/Wikipedia/Code/Controllers/ShortDescriptionController.swift b/Wikipedia/Code/Controllers/ShortDescriptionController.swift index c64d0ac3700..0defbe39c5d 100644 --- a/Wikipedia/Code/Controllers/ShortDescriptionController.swift +++ b/Wikipedia/Code/Controllers/ShortDescriptionController.swift @@ -151,7 +151,7 @@ private extension ShortDescriptionController { let newTemplateToPrepend = "{{Short description|\(newDescription)}}\n" - let editSummaryTag = editType == .add ? WKEditSummaryTag.articleDescriptionAdd.rawValue : WKEditSummaryTag.articleDescriptionChange.rawValue + let editTag = editType == .add ? WKEditTag.appDescriptionAdd.rawValue : WKEditTag.appDescriptionChange.rawValue sectionUploader.prepend( toSectionID: "\(sectionID)", @@ -160,7 +160,7 @@ private extension ShortDescriptionController { summary: CommonStrings.editSummaryShortDescriptionAdded(with: languageCode), isMinorEdit: true, baseRevID: baseRevisionID as NSNumber, - editSummaryTag: editSummaryTag, + editTags: [editTag], completion: { [weak self] (result, error) in guard let self = self else { @@ -190,8 +190,7 @@ private extension ShortDescriptionController { let updatedWikitext = try wikitext.replacingShortDescription(with: newDescription) - let editSummaryTag = editType == .add ? WKEditSummaryTag.articleDescriptionAdd.rawValue : WKEditSummaryTag.articleDescriptionChange.rawValue - + let editTag = editType == .add ? WKEditTag.appDescriptionAdd.rawValue : WKEditTag.appDescriptionChange.rawValue sectionUploader.uploadWikiText( updatedWikitext, @@ -203,7 +202,8 @@ private extension ShortDescriptionController { baseRevID: baseRevisionID as NSNumber, captchaId: nil, captchaWord: nil, - editSummaryTag: editSummaryTag, + editSummaryTag: nil, + editTags: [editTag], completion: { [weak self] (result, error) in guard let self = self else { diff --git a/Wikipedia/Code/Controllers/WikidataDescriptionController.swift b/Wikipedia/Code/Controllers/WikidataDescriptionController.swift index 6c7ffb6410a..c95e065e8a4 100644 --- a/Wikipedia/Code/Controllers/WikidataDescriptionController.swift +++ b/Wikipedia/Code/Controllers/WikidataDescriptionController.swift @@ -36,9 +36,9 @@ class WikidataDescriptionController: ArticleDescriptionControlling { func publishDescription(_ description: String, editType: ArticleDescriptionEditType, completion: @escaping (Result) -> Void) { - let editSummaryTag: WKEditSummaryTag = editType == .add ? .articleDescriptionAdd : .articleDescriptionChange + let editTag: WKEditTag = editType == .add ? .appDescriptionAdd : .appDescriptionChange - fetcher.publish(newWikidataDescription: description, from: descriptionSource, forWikidataID: wikiDataID, languageCode: articleLanguageCode, editSummaryTag: editSummaryTag) { (error) in + fetcher.publish(newWikidataDescription: description, from: descriptionSource, forWikidataID: wikiDataID, languageCode: articleLanguageCode, editTags: [editTag]) { (error) in if let error = error { completion(.failure(error)) return diff --git a/Wikipedia/Code/DiffContainerViewController.swift b/Wikipedia/Code/DiffContainerViewController.swift index b58d1f3adbf..d3f971842bb 100644 --- a/Wikipedia/Code/DiffContainerViewController.swift +++ b/Wikipedia/Code/DiffContainerViewController.swift @@ -1342,7 +1342,7 @@ extension DiffContainerViewController: DiffToolbarViewDelegate { EditAttemptFunnel.shared.logSaveAttempt(pageURL: pageURL) } - WKWatchlistDataController().undo(title: title, revisionID: UInt(revisionID), summary: summary, username: username, editSummaryTag: .diffUndo, project: wkProject) { [weak self] result in + WKWatchlistDataController().undo(title: title, revisionID: UInt(revisionID), summary: summary, username: username, project: wkProject) { [weak self] result in DispatchQueue.main.async { self?.completeRollbackOrUndo(result: result, isRollback: false) } @@ -1386,7 +1386,7 @@ extension DiffContainerViewController: DiffToolbarViewDelegate { EditAttemptFunnel.shared.logSaveAttempt(pageURL: pageURL) } - WKWatchlistDataController().rollback(title: title, project: wkProject, username: username, editSummaryTag: .diffRollback) { [weak self] result in + WKWatchlistDataController().rollback(title: title, project: wkProject, username: username) { [weak self] result in DispatchQueue.main.async { self?.completeRollbackOrUndo(result: result, isRollback: true) } diff --git a/Wikipedia/Code/EditSaveViewController.swift b/Wikipedia/Code/EditSaveViewController.swift index a57bf463352..d8307113d56 100644 --- a/Wikipedia/Code/EditSaveViewController.swift +++ b/Wikipedia/Code/EditSaveViewController.swift @@ -384,7 +384,7 @@ class EditSaveViewController: WMFScrollViewController, Themeable, UITextFieldDel return } - wikiTextSectionUploader.uploadWikiText(wikitext, forArticleURL: editURL, section: section, summary: summaryText, isMinorEdit: minorEditToggle.isOn, addToWatchlist: addToWatchlistToggle.isOn, baseRevID: nil, captchaId: captchaViewController?.captcha?.captchaID, captchaWord: captchaViewController?.solution, editSummaryTag: editSummaryTag?.rawValue, completion: { (result, error) in + wikiTextSectionUploader.uploadWikiText(wikitext, forArticleURL: editURL, section: section, summary: summaryText, isMinorEdit: minorEditToggle.isOn, addToWatchlist: addToWatchlistToggle.isOn, baseRevID: nil, captchaId: captchaViewController?.captcha?.captchaID, captchaWord: captchaViewController?.solution, editSummaryTag: editSummaryTag?.rawValue, editTags: nil, completion: { (result, error) in DispatchQueue.main.async { if let error = error { self.handleEditFailure(with: error) diff --git a/Wikipedia/Code/WikiTextSectionUploader.h b/Wikipedia/Code/WikiTextSectionUploader.h index 7887164b65e..470cc00874e 100644 --- a/Wikipedia/Code/WikiTextSectionUploader.h +++ b/Wikipedia/Code/WikiTextSectionUploader.h @@ -29,6 +29,7 @@ extern NSString *const NSErrorUserInfoDisplayError; captchaId:(nullable NSString *)captchaId captchaWord:(nullable NSString *)captchaWord editSummaryTag:(nullable NSString *)editSummaryTag + editTags:(nullable NSArray *)editTags completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion; - (void)addSectionWithSummary:(NSString *)summary @@ -45,9 +46,9 @@ extern NSString *const NSErrorUserInfoDisplayError; text:(NSString *)text forArticleURL:(NSURL *)articleURL summary:(nullable NSString *)summary - isMinorEdit:(BOOL)isMinorEdit + isMinorEdit:(BOOL)isMinorEdit baseRevID:(nullable NSNumber *)baseRevID - editSummaryTag:(nullable NSString *)editSummaryTag + editTags:(nullable NSArray *)editTags completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion; @end diff --git a/Wikipedia/Code/WikiTextSectionUploader.m b/Wikipedia/Code/WikiTextSectionUploader.m index 6ddd2924a2b..edcfc8fc1e9 100644 --- a/Wikipedia/Code/WikiTextSectionUploader.m +++ b/Wikipedia/Code/WikiTextSectionUploader.m @@ -70,7 +70,7 @@ - (void)prependToSectionID:(NSString *)sectionID summary:(nullable NSString *)summary isMinorEdit:(BOOL)isMinorEdit baseRevID:(nullable NSNumber *)baseRevID - editSummaryTag:(nullable NSString *)editSummaryTag + editTags:(nullable NSArray *)editTags completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion { NSString *title = articleURL.wmf_title; @@ -79,14 +79,12 @@ - (void)prependToSectionID:(NSString *)sectionID return; } - NSString *finalSummary = appendTagToEditSummary(editSummaryTag, summary); - NSMutableDictionary *params = @{ @"action": @"edit", @"prependtext": text, @"section": sectionID, - @"summary": finalSummary, + @"summary": summary, @"title": articleURL.wmf_title, @"errorformat": @"html", @"errorsuselocal": @"1", @@ -102,6 +100,10 @@ - (void)prependToSectionID:(NSString *)sectionID if (baseRevID) { params[@"baserevid"] = [NSString stringWithFormat:@"%@", baseRevID]; } + + if (editTags && editTags.count > 0) { + params[@"matags"] = [editTags componentsJoinedByString:@","]; + } [self updateWithArticleURL:articleURL parameters:params captchaWord:nil completion:completion]; } @@ -116,6 +118,7 @@ - (void)uploadWikiText:(nullable NSString *)wikiText captchaId:(nullable NSString *)captchaId captchaWord:(nullable NSString *)captchaWord editSummaryTag:(nullable NSString *)editSummaryTag + editTags:(nullable NSArray *)editTags completion:(void (^)(NSDictionary * _Nullable result, NSError * _Nullable error))completion { wikiText = wikiText ? wikiText : @""; @@ -162,6 +165,10 @@ - (void)uploadWikiText:(nullable NSString *)wikiText params[@"captchaword"] = captchaWord; } + if (editTags && editTags.count > 0) { + params[@"matags"] = [editTags componentsJoinedByString:@","]; + } + [self updateWithArticleURL:articleURL parameters:params captchaWord:captchaWord completion:completion]; } diff --git a/Wikipedia/Code/WikidataFetcher.swift b/Wikipedia/Code/WikidataFetcher.swift index 36af55a2fc4..2e1e1492597 100644 --- a/Wikipedia/Code/WikidataFetcher.swift +++ b/Wikipedia/Code/WikidataFetcher.swift @@ -137,7 +137,7 @@ public enum ArticleDescriptionSource: String { /// - languageCode: language code of the page's wiki, e.g., "en". /// - completion: completion block called when operation is completed. - public func publish(newWikidataDescription: String, from source: ArticleDescriptionSource, forWikidataID wikidataID: String, languageCode: String, editSummaryTag: WKEditSummaryTag, completion: @escaping (Error?) -> Void) { + public func publish(newWikidataDescription: String, from source: ArticleDescriptionSource, forWikidataID wikidataID: String, languageCode: String, editTags: [WKEditTag]?, completion: @escaping (Error?) -> Void) { guard source != .local else { completion(WikidataPublishingError.notEditable) return @@ -150,13 +150,17 @@ public enum ArticleDescriptionSource: String { session.jsonDecodableTask(with: languageCodeComponents.url) { (siteInfo: MediaWikiSiteInfoResult?, _, _) in let normalizedLanguage = siteInfo?.query.general.lang ?? "en" - let queryParameters: [String: Any] = ["action": "wbsetdescription", - "summary": editSummaryTag.rawValue, + var queryParameters: [String: Any] = ["action": "wbsetdescription", "errorformat": "html", "erroruselocal": 1, "format": "json", "formatversion": "2"] + if let editTags, + !editTags.isEmpty { + queryParameters["matags"] = editTags.map { $0.rawValue }.joined(separator: ",") + } + let components = self.configuration.wikidataAPIURLComponents(with: queryParameters) let wikidataURL = components.url self.requestMediaWikiAPIAuthToken(for: wikidataURL, type: .csrf) { (result) in