-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathGutenbergGalleryUploadProcessor.swift
More file actions
145 lines (121 loc) · 4.8 KB
/
Copy pathGutenbergGalleryUploadProcessor.swift
File metadata and controls
145 lines (121 loc) · 4.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import Foundation
import SwiftSoup
public class GutenbergGalleryUploadProcessor: GutenbergProcessor {
let mediaUploadID: Int32
let remoteURLString: String
let serverMediaID: Int
let mediaLink: String
private var linkToURL: String?
static let imgClassIDPrefixAttribute = "wp-image-"
public init(mediaUploadID: Int32, serverMediaID: Int, remoteURLString: String, mediaLink: String) {
self.mediaUploadID = mediaUploadID
self.serverMediaID = serverMediaID
self.remoteURLString = remoteURLString
self.mediaLink = mediaLink
}
private struct ImageKeys {
static let name = "img"
static let classAttributes = "class"
static let classIDPrefix = "wp-image-"
static let dataID = "data-id"
static let dataFullURL = "data-full-url"
static let dataLink = "data-link"
}
func processImgPostMediaUpload(_ element: Element) {
guard let imgTags = try? element.select(ImageKeys.name) else {
return
}
imgTags.forEach {imgTag in
guard let imgClass = try? imgTag.attr(ImageKeys.classAttributes) else {
return
}
let classAttributes = imgClass.components(separatedBy: " ")
guard let imageIDAttribute = classAttributes.first(where: { value -> Bool in
value.hasPrefix(GutenbergImgUploadProcessor.imgClassIDPrefixAttribute)
}) else {
return
}
let imageIDString = String(imageIDAttribute.dropFirst(ImageKeys.classIDPrefix.count))
let imgUploadID = Int32(imageIDString)
guard imgUploadID == self.mediaUploadID else {
return
}
let newImgClassAttributes = imgClass.replacingOccurrences(of: imageIDAttribute, with: ImageKeys.classIDPrefix + String(self.serverMediaID))
_ = try? imgTag.attr("src", self.remoteURLString)
_ = try? imgTag.attr("class", newImgClassAttributes)
_ = try? imgTag.attr(ImageKeys.dataID, String(self.serverMediaID))
_ = try? imgTag.attr(ImageKeys.dataFullURL, self.remoteURLString)
if let _ = try? imgTag.attr(ImageKeys.dataLink) {
_ = try? imgTag.attr(ImageKeys.dataLink, self.mediaLink)
}
}
}
private struct LinkKeys {
static let name = "a"
}
func processLinkPostMediaUpload(_ block: GutenbergParsedBlock) {
guard let aTags = try? block.elements.select(LinkKeys.name) else {
return
}
aTags.forEach { aTag in
guard let linkOriginalContent = try? aTag.html() else {
return
}
processImgPostMediaUpload(aTag)
let linkUpdatedContent = try? aTag.html()
guard linkUpdatedContent != linkOriginalContent else {
return
}
if let linkToURL = self.linkToURL {
_ = try? aTag.attr("href", linkToURL)
} else {
_ = try? aTag.attr("href", self.remoteURLString)
}
}
}
private struct GalleryBlockKeys {
static let name = "wp:gallery"
static let ids = "ids"
static let linkTo = "linkTo"
}
private func convertToIntArray(_ idsAny: [Any]) -> [Int32] {
var ids = [Int32]()
for id in idsAny {
if let idInt = id as? Int32 {
ids.append(idInt)
} else if let idString = id as? String, let idInt = Int32(idString) {
ids.append(idInt)
}
}
return ids
}
func processGalleryBlocks(_ blocks: [GutenbergParsedBlock]) {
let galleryBlocks = blocks.filter { $0.name == GalleryBlockKeys.name }
galleryBlocks.forEach { block in
guard let idsAny = block.attributes[GalleryBlockKeys.ids] as? [Any] else {
return
}
var ids = self.convertToIntArray(idsAny)
guard ids.contains(self.mediaUploadID) else {
return
}
if let index = ids.firstIndex(of: self.mediaUploadID ) {
ids[index] = Int32(self.serverMediaID)
}
block.attributes[GalleryBlockKeys.ids] = ids
if let linkTo = block.attributes[GalleryBlockKeys.linkTo] as? String, linkTo != "none" {
if linkTo == "file" {
self.linkToURL = self.remoteURLString
} else if linkTo == "post" {
self.linkToURL = self.mediaLink
}
processLinkPostMediaUpload(block)
} else {
block.elements.forEach { processImgPostMediaUpload($0) }
}
}
}
public func process(_ blocks: [GutenbergParsedBlock]) {
processGalleryBlocks(blocks)
}
}