Version Description
- New: added privacy integration (erasure, export, policy content suggestion)
- Fix: typo in readme
- Fix: output of html comments in emails
- Tweak: performance (duplicate queries of installation state)
=
Download this release
Release Info
Developer | No3x |
Plugin | WP Mail Logging |
Version | 1.8.5 |
Comparing to | |
See all releases |
Code changes from version 1.8.4 to 1.8.5
- languages/wp-mail-logging-de_DE.mo +0 -0
- languages/wp-mail-logging-de_DE.po +5 -5
- languages/wp-mail-logging-zh_CN.mo +0 -0
- languages/wp-mail-logging-zh_CN.po +2 -2
- languages/wp-mail-logging.pot +100 -82
- lib/vendor/brandonwamboldt/wp-orm/README.md +281 -0
- lib/vendor/brandonwamboldt/wp-orm/src/BaseModel.php +18 -1
- lib/vendor/brandonwamboldt/wp-orm/src/DefaultQueryFactory.php +10 -0
- lib/vendor/brandonwamboldt/wp-orm/src/QueryFactory.php +8 -0
- readme.txt +13 -5
- {model → src/Model}/WPML_Mail.php +2 -3
- WPML_API_Example.php → src/WPML_API_Example.php +85 -85
- WPML_DI_Container.php → src/WPML_DI_Container.php +24 -24
- WPML_Email_Dispatcher.php → src/WPML_Email_Dispatcher.php +18 -18
- WPML_Email_Log_List.php → src/WPML_Email_Log_List.php +509 -510
- WPML_Email_Resender.php → src/WPML_Email_Resender.php +29 -29
- src/WPML_Hook_Remover.php +93 -0
- WPML_Init.php → src/WPML_Init.php +161 -158
- WPML_InstallIndicator.php → src/WPML_InstallIndicator.php +186 -171
- WPML_LifeCycle.php → src/WPML_LifeCycle.php +211 -211
- WPML_LogRotation.php → src/WPML_LogRotation.php +131 -131
- src/WPML_MailExtractor.php +96 -0
- src/WPML_MessageSanitizer.php +60 -0
- WPML_OptionsManager.php → src/WPML_OptionsManager.php +604 -604
- WPML_Plugin.php → src/WPML_Plugin.php +19 -57
- src/WPML_PrivacyController.php +157 -0
- WPML_Utils.php → src/WPML_Utils.php +118 -118
- {inc → src/inc}/class-wp-list-table.php +0 -0
- {inc → src/inc}/redux/WPML_Redux_Framework_config.php +359 -359
- {inc → src/inc}/redux/admin-init.php +2 -2
- wp-mail-logging.php +4 -5
languages/wp-mail-logging-de_DE.mo
CHANGED
Binary file
|
languages/wp-mail-logging-de_DE.po
CHANGED
@@ -4,15 +4,15 @@ msgid ""
|
|
4 |
msgstr ""
|
5 |
"Project-Id-Version: WP Mail Logging 1.8.0\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-logging\n"
|
7 |
-
"POT-Creation-Date: 2017-
|
8 |
-
"PO-Revision-Date: 2018-
|
9 |
"Last-Translator: \n"
|
10 |
"Language-Team: \n"
|
11 |
"Language: de_DE\n"
|
12 |
"MIME-Version: 1.0\n"
|
13 |
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
"Content-Transfer-Encoding: 8bit\n"
|
15 |
-
"X-Generator: Poedit 2.
|
16 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
|
18 |
#: WPML_Email_Log_List.php:59
|
@@ -66,8 +66,8 @@ msgstr "Anhang %s ist nicht vorhanden"
|
|
66 |
#: WPML_Email_Log_List.php:495
|
67 |
msgid "Fallback to raw format because html is not convertible to json."
|
68 |
msgstr ""
|
69 |
-
"Darstellung in raw-Format, da eine html Nachricht nicht als json "
|
70 |
-
"
|
71 |
|
72 |
#: WPML_LifeCycle.php:205
|
73 |
msgid "Settings"
|
4 |
msgstr ""
|
5 |
"Project-Id-Version: WP Mail Logging 1.8.0\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-logging\n"
|
7 |
+
"POT-Creation-Date: 2017-02-12 02:34+0800\n"
|
8 |
+
"PO-Revision-Date: 2018-09-13 15:03+0200\n"
|
9 |
"Last-Translator: \n"
|
10 |
"Language-Team: \n"
|
11 |
"Language: de_DE\n"
|
12 |
"MIME-Version: 1.0\n"
|
13 |
"Content-Type: text/plain; charset=UTF-8\n"
|
14 |
"Content-Transfer-Encoding: 8bit\n"
|
15 |
+
"X-Generator: Poedit 2.1.1\n"
|
16 |
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
|
18 |
#: WPML_Email_Log_List.php:59
|
66 |
#: WPML_Email_Log_List.php:495
|
67 |
msgid "Fallback to raw format because html is not convertible to json."
|
68 |
msgstr ""
|
69 |
+
"Darstellung in raw-Format, da eine html Nachricht nicht als json dargestellt "
|
70 |
+
"werden kann."
|
71 |
|
72 |
#: WPML_LifeCycle.php:205
|
73 |
msgid "Settings"
|
languages/wp-mail-logging-zh_CN.mo
CHANGED
Binary file
|
languages/wp-mail-logging-zh_CN.po
CHANGED
@@ -8,9 +8,9 @@ msgstr ""
|
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
-
"PO-Revision-Date: 2018-
|
12 |
"Language-Team: \n"
|
13 |
-
"X-Generator: Poedit 2.
|
14 |
"Plural-Forms: nplurals=1; plural=0;\n"
|
15 |
"Language: zh_CN\n"
|
16 |
"Last-Translator: \n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=UTF-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
11 |
+
"PO-Revision-Date: 2018-09-13 14:54+0200\n"
|
12 |
"Language-Team: \n"
|
13 |
+
"X-Generator: Poedit 2.1.1\n"
|
14 |
"Plural-Forms: nplurals=1; plural=0;\n"
|
15 |
"Language: zh_CN\n"
|
16 |
"Last-Translator: \n"
|
languages/wp-mail-logging.pot
CHANGED
@@ -2,9 +2,9 @@
|
|
2 |
# This file is distributed under the GPLv3.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
-
"Project-Id-Version: WP Mail Logging 1.8.
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-logging\n"
|
7 |
-
"POT-Creation-Date: 2018-
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=utf-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
@@ -14,295 +14,313 @@ msgstr ""
|
|
14 |
"X-Generator: grunt-wp-i18n 0.5.4\n"
|
15 |
"Language: en_GB\n"
|
16 |
|
17 |
-
#: WPML_Email_Log_List.php:
|
18 |
msgid "No email found."
|
19 |
msgstr ""
|
20 |
|
21 |
-
#: WPML_Email_Log_List.php:
|
22 |
msgid "ID"
|
23 |
msgstr ""
|
24 |
|
25 |
-
#: WPML_Email_Log_List.php:
|
|
|
26 |
msgid "Time"
|
27 |
msgstr ""
|
28 |
|
29 |
-
#: WPML_Email_Log_List.php:
|
30 |
msgid "Receiver"
|
31 |
msgstr ""
|
32 |
|
33 |
-
#: WPML_Email_Log_List.php:
|
34 |
msgid "Subject"
|
35 |
msgstr ""
|
36 |
|
37 |
-
#: WPML_Email_Log_List.php:
|
38 |
msgid "Message"
|
39 |
msgstr ""
|
40 |
|
41 |
-
#: WPML_Email_Log_List.php:
|
42 |
msgid "Headers"
|
43 |
msgstr ""
|
44 |
|
45 |
-
#: WPML_Email_Log_List.php:
|
46 |
msgid "Attachments"
|
47 |
msgstr ""
|
48 |
|
49 |
-
#: WPML_Email_Log_List.php:
|
50 |
msgid "Error"
|
51 |
msgstr ""
|
52 |
|
53 |
-
#: WPML_Email_Log_List.php:
|
54 |
msgid "Plugin Version"
|
55 |
msgstr ""
|
56 |
|
57 |
-
#: WPML_Email_Log_List.php:
|
58 |
msgid "Host"
|
59 |
msgstr ""
|
60 |
|
61 |
-
#: WPML_Email_Log_List.php:
|
62 |
msgid "Attachment %s is not present"
|
63 |
msgstr ""
|
64 |
|
65 |
-
#: WPML_Email_Log_List.php:
|
66 |
msgid "Fallback to raw format because html is not convertible to json."
|
67 |
msgstr ""
|
68 |
|
69 |
-
#: WPML_LifeCycle.php:205
|
70 |
msgid "Settings"
|
71 |
msgstr ""
|
72 |
|
73 |
-
#: WPML_OptionsManager.php:321 WPML_OptionsManager.php:322
|
74 |
msgid "WP Mail Log"
|
75 |
msgstr ""
|
76 |
|
77 |
-
#: WPML_OptionsManager.php:333 WPML_OptionsManager.php:334
|
78 |
-
#: WPML_OptionsManager.php:345
|
79 |
msgid "About"
|
80 |
msgstr ""
|
81 |
|
82 |
-
#: WPML_OptionsManager.php:422
|
83 |
msgid "About Plugin"
|
84 |
msgstr ""
|
85 |
|
86 |
-
#: WPML_OptionsManager.php:431
|
87 |
msgid "More information"
|
88 |
msgstr ""
|
89 |
|
90 |
-
#: WPML_OptionsManager.php:432
|
91 |
msgid "Plugin Homepage/support"
|
92 |
msgstr ""
|
93 |
|
94 |
-
#: WPML_OptionsManager.php:433
|
95 |
msgid "Plugin author's blog"
|
96 |
msgstr ""
|
97 |
|
98 |
-
#: WPML_OptionsManager.php:440
|
99 |
msgid "Entries per page"
|
100 |
msgstr ""
|
101 |
|
102 |
-
#: WPML_OptionsManager.php:462
|
103 |
msgid "You do not have sufficient permissions to access this page."
|
104 |
msgstr ""
|
105 |
|
106 |
-
#: WPML_OptionsManager.php:471
|
107 |
msgid "Log"
|
108 |
msgstr ""
|
109 |
|
110 |
-
#: WPML_OptionsManager.php:515
|
111 |
msgid "Close"
|
112 |
msgstr ""
|
113 |
|
114 |
-
#: WPML_OptionsManager.php:529
|
115 |
msgid "Search"
|
116 |
msgstr ""
|
117 |
|
118 |
-
#: WPML_OptionsManager.php:554
|
119 |
msgid "true"
|
120 |
msgstr ""
|
121 |
|
122 |
-
#: WPML_OptionsManager.php:556
|
123 |
msgid "false"
|
124 |
msgstr ""
|
125 |
|
126 |
-
#: WPML_OptionsManager.php:559
|
127 |
msgid "Administrator"
|
128 |
msgstr ""
|
129 |
|
130 |
-
#: WPML_OptionsManager.php:561
|
131 |
msgid "Editor"
|
132 |
msgstr ""
|
133 |
|
134 |
-
#: WPML_OptionsManager.php:563
|
135 |
msgid "Author"
|
136 |
msgstr ""
|
137 |
|
138 |
-
#: WPML_OptionsManager.php:565
|
139 |
msgid "Contributor"
|
140 |
msgstr ""
|
141 |
|
142 |
-
#: WPML_OptionsManager.php:567
|
143 |
msgid "Subscriber"
|
144 |
msgstr ""
|
145 |
|
146 |
-
#: WPML_OptionsManager.php:569
|
147 |
msgid "Anyone"
|
148 |
msgstr ""
|
149 |
|
150 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
msgid "No items found."
|
152 |
msgstr ""
|
153 |
|
154 |
-
#: inc/class-wp-list-table.php:315
|
155 |
msgid "Bulk Actions"
|
156 |
msgstr ""
|
157 |
|
158 |
-
#: inc/class-wp-list-table.php:325
|
159 |
msgid "Apply"
|
160 |
msgstr ""
|
161 |
|
162 |
-
#: inc/class-wp-list-table.php:409
|
163 |
msgid "Show all dates"
|
164 |
msgstr ""
|
165 |
|
166 |
-
#: inc/class-wp-list-table.php:422
|
167 |
#. translators: 1: month name, 2: 4-digit year
|
168 |
msgid "%1$s %2$d"
|
169 |
msgstr ""
|
170 |
|
171 |
-
#: inc/class-wp-list-table.php:438
|
172 |
msgid "List View"
|
173 |
msgstr ""
|
174 |
|
175 |
-
#: inc/class-wp-list-table.php:439
|
176 |
msgid "Excerpt View"
|
177 |
msgstr ""
|
178 |
|
179 |
-
#: inc/class-wp-list-table.php:465
|
180 |
msgid "%s pending"
|
181 |
msgstr ""
|
182 |
|
183 |
-
#: inc/class-wp-list-table.php:533 inc/class-wp-list-table.php:948
|
184 |
msgid "1 item"
|
185 |
msgid_plural "%s items"
|
186 |
msgstr[0] ""
|
187 |
msgstr[1] ""
|
188 |
|
189 |
-
#: inc/class-wp-list-table.php:551
|
190 |
msgid "Go to the first page"
|
191 |
msgstr ""
|
192 |
|
193 |
-
#: inc/class-wp-list-table.php:558
|
194 |
msgid "Go to the previous page"
|
195 |
msgstr ""
|
196 |
|
197 |
-
#: inc/class-wp-list-table.php:567
|
198 |
msgid "Current page"
|
199 |
msgstr ""
|
200 |
|
201 |
-
#: inc/class-wp-list-table.php:577
|
202 |
msgid "Go to the next page"
|
203 |
msgstr ""
|
204 |
|
205 |
-
#: inc/class-wp-list-table.php:584
|
206 |
msgid "Go to the last page"
|
207 |
msgstr ""
|
208 |
|
209 |
-
#: inc/class-wp-list-table.php:720
|
210 |
msgid "Select All"
|
211 |
msgstr ""
|
212 |
|
213 |
-
#: inc/redux/WPML_Redux_Framework_config.php:92
|
214 |
msgid "General Settings"
|
215 |
msgstr ""
|
216 |
|
217 |
-
#: inc/redux/WPML_Redux_Framework_config.php:101
|
218 |
msgid "Cleanup"
|
219 |
msgstr ""
|
220 |
|
221 |
-
#: inc/redux/WPML_Redux_Framework_config.php:102
|
222 |
msgid "Delete all data on deactivation? (emails and settings)?"
|
223 |
msgstr ""
|
224 |
|
225 |
-
#: inc/redux/WPML_Redux_Framework_config.php:112
|
226 |
msgid "Can See Submission data"
|
227 |
msgstr ""
|
228 |
|
229 |
-
#: inc/redux/WPML_Redux_Framework_config.php:113
|
230 |
msgid "Select the minimum role."
|
231 |
msgstr ""
|
232 |
|
233 |
-
#: inc/redux/WPML_Redux_Framework_config.php:118
|
234 |
msgid "WordPress Date Time Format"
|
235 |
msgstr ""
|
236 |
|
237 |
-
#: inc/redux/WPML_Redux_Framework_config.php:119
|
238 |
msgid "Use format from WordPress settings (%s)"
|
239 |
msgstr ""
|
240 |
|
241 |
-
#: inc/redux/WPML_Redux_Framework_config.php:121
|
242 |
-
#: inc/redux/WPML_Redux_Framework_config.php:146
|
243 |
-
#: inc/redux/WPML_Redux_Framework_config.php:162
|
244 |
-
#: inc/redux/WPML_Redux_Framework_config.php:184
|
245 |
msgid "Enabled"
|
246 |
msgstr ""
|
247 |
|
248 |
-
#: inc/redux/WPML_Redux_Framework_config.php:122
|
249 |
-
#: inc/redux/WPML_Redux_Framework_config.php:147
|
250 |
-
#: inc/redux/WPML_Redux_Framework_config.php:163
|
251 |
-
#: inc/redux/WPML_Redux_Framework_config.php:185
|
252 |
msgid "Disabled"
|
253 |
msgstr ""
|
254 |
|
255 |
-
#: inc/redux/WPML_Redux_Framework_config.php:133
|
256 |
msgid "Default Format for Message"
|
257 |
msgstr ""
|
258 |
|
259 |
-
#: inc/redux/WPML_Redux_Framework_config.php:134
|
260 |
msgid "Select your preferred display format."
|
261 |
msgstr ""
|
262 |
|
263 |
-
#: inc/redux/WPML_Redux_Framework_config.php:139
|
264 |
msgid "Display Host"
|
265 |
msgstr ""
|
266 |
|
267 |
-
#: inc/redux/WPML_Redux_Framework_config.php:140
|
268 |
msgid "Display host column in list."
|
269 |
msgstr ""
|
270 |
|
271 |
-
#: inc/redux/WPML_Redux_Framework_config.php:152
|
272 |
msgid "Log Rotation"
|
273 |
msgstr ""
|
274 |
|
275 |
-
#: inc/redux/WPML_Redux_Framework_config.php:153
|
276 |
msgid "Save space by deleting logs regularly."
|
277 |
msgstr ""
|
278 |
|
279 |
-
#: inc/redux/WPML_Redux_Framework_config.php:159
|
280 |
msgid "Cleanup by Amount"
|
281 |
msgstr ""
|
282 |
|
283 |
-
#: inc/redux/WPML_Redux_Framework_config.php:160
|
284 |
-
#: inc/redux/WPML_Redux_Framework_config.php:182
|
285 |
msgid "Setup a automated cleanup routine!"
|
286 |
msgstr ""
|
287 |
|
288 |
-
#: inc/redux/WPML_Redux_Framework_config.php:169
|
289 |
msgid "Amount"
|
290 |
msgstr ""
|
291 |
|
292 |
-
#: inc/redux/WPML_Redux_Framework_config.php:170
|
293 |
-
#: inc/redux/WPML_Redux_Framework_config.php:192
|
294 |
msgid "When should mails are deleted?"
|
295 |
msgstr ""
|
296 |
|
297 |
-
#: inc/redux/WPML_Redux_Framework_config.php:171
|
298 |
msgid "Cleanup when the stored mails exceed..."
|
299 |
msgstr ""
|
300 |
|
301 |
-
#: inc/redux/WPML_Redux_Framework_config.php:181
|
302 |
msgid "Cleanup by Time"
|
303 |
msgstr ""
|
304 |
|
305 |
-
#: inc/redux/WPML_Redux_Framework_config.php:193
|
306 |
msgid "Delete mails older than days..."
|
307 |
msgstr ""
|
308 |
|
@@ -324,7 +342,7 @@ msgstr ""
|
|
324 |
msgid "Logs each email sent by WordPress."
|
325 |
msgstr ""
|
326 |
|
327 |
-
#: inc/class-wp-list-table.php:573
|
328 |
msgctxt "paging"
|
329 |
msgid "%1$s of %2$s"
|
330 |
msgstr ""
|
2 |
# This file is distributed under the GPLv3.
|
3 |
msgid ""
|
4 |
msgstr ""
|
5 |
+
"Project-Id-Version: WP Mail Logging 1.8.5\n"
|
6 |
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/wp-mail-logging\n"
|
7 |
+
"POT-Creation-Date: 2018-09-13 13:01:17+00:00\n"
|
8 |
"MIME-Version: 1.0\n"
|
9 |
"Content-Type: text/plain; charset=utf-8\n"
|
10 |
"Content-Transfer-Encoding: 8bit\n"
|
14 |
"X-Generator: grunt-wp-i18n 0.5.4\n"
|
15 |
"Language: en_GB\n"
|
16 |
|
17 |
+
#: src/WPML_Email_Log_List.php:67
|
18 |
msgid "No email found."
|
19 |
msgstr ""
|
20 |
|
21 |
+
#: src/WPML_Email_Log_List.php:79
|
22 |
msgid "ID"
|
23 |
msgstr ""
|
24 |
|
25 |
+
#: src/WPML_Email_Log_List.php:80
|
26 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:191
|
27 |
msgid "Time"
|
28 |
msgstr ""
|
29 |
|
30 |
+
#: src/WPML_Email_Log_List.php:81
|
31 |
msgid "Receiver"
|
32 |
msgstr ""
|
33 |
|
34 |
+
#: src/WPML_Email_Log_List.php:82
|
35 |
msgid "Subject"
|
36 |
msgstr ""
|
37 |
|
38 |
+
#: src/WPML_Email_Log_List.php:83 src/WPML_OptionsManager.php:497
|
39 |
msgid "Message"
|
40 |
msgstr ""
|
41 |
|
42 |
+
#: src/WPML_Email_Log_List.php:84
|
43 |
msgid "Headers"
|
44 |
msgstr ""
|
45 |
|
46 |
+
#: src/WPML_Email_Log_List.php:85
|
47 |
msgid "Attachments"
|
48 |
msgstr ""
|
49 |
|
50 |
+
#: src/WPML_Email_Log_List.php:86
|
51 |
msgid "Error"
|
52 |
msgstr ""
|
53 |
|
54 |
+
#: src/WPML_Email_Log_List.php:87
|
55 |
msgid "Plugin Version"
|
56 |
msgstr ""
|
57 |
|
58 |
+
#: src/WPML_Email_Log_List.php:98
|
59 |
msgid "Host"
|
60 |
msgstr ""
|
61 |
|
62 |
+
#: src/WPML_Email_Log_List.php:266 src/WPML_Email_Log_List.php:300
|
63 |
msgid "Attachment %s is not present"
|
64 |
msgstr ""
|
65 |
|
66 |
+
#: src/WPML_Email_Log_List.php:494
|
67 |
msgid "Fallback to raw format because html is not convertible to json."
|
68 |
msgstr ""
|
69 |
|
70 |
+
#: src/WPML_LifeCycle.php:205
|
71 |
msgid "Settings"
|
72 |
msgstr ""
|
73 |
|
74 |
+
#: src/WPML_OptionsManager.php:321 src/WPML_OptionsManager.php:322
|
75 |
msgid "WP Mail Log"
|
76 |
msgstr ""
|
77 |
|
78 |
+
#: src/WPML_OptionsManager.php:333 src/WPML_OptionsManager.php:334
|
79 |
+
#: src/WPML_OptionsManager.php:345
|
80 |
msgid "About"
|
81 |
msgstr ""
|
82 |
|
83 |
+
#: src/WPML_OptionsManager.php:422
|
84 |
msgid "About Plugin"
|
85 |
msgstr ""
|
86 |
|
87 |
+
#: src/WPML_OptionsManager.php:431
|
88 |
msgid "More information"
|
89 |
msgstr ""
|
90 |
|
91 |
+
#: src/WPML_OptionsManager.php:432
|
92 |
msgid "Plugin Homepage/support"
|
93 |
msgstr ""
|
94 |
|
95 |
+
#: src/WPML_OptionsManager.php:433
|
96 |
msgid "Plugin author's blog"
|
97 |
msgstr ""
|
98 |
|
99 |
+
#: src/WPML_OptionsManager.php:440
|
100 |
msgid "Entries per page"
|
101 |
msgstr ""
|
102 |
|
103 |
+
#: src/WPML_OptionsManager.php:462
|
104 |
msgid "You do not have sufficient permissions to access this page."
|
105 |
msgstr ""
|
106 |
|
107 |
+
#: src/WPML_OptionsManager.php:471
|
108 |
msgid "Log"
|
109 |
msgstr ""
|
110 |
|
111 |
+
#: src/WPML_OptionsManager.php:515
|
112 |
msgid "Close"
|
113 |
msgstr ""
|
114 |
|
115 |
+
#: src/WPML_OptionsManager.php:529
|
116 |
msgid "Search"
|
117 |
msgstr ""
|
118 |
|
119 |
+
#: src/WPML_OptionsManager.php:554
|
120 |
msgid "true"
|
121 |
msgstr ""
|
122 |
|
123 |
+
#: src/WPML_OptionsManager.php:556
|
124 |
msgid "false"
|
125 |
msgstr ""
|
126 |
|
127 |
+
#: src/WPML_OptionsManager.php:559
|
128 |
msgid "Administrator"
|
129 |
msgstr ""
|
130 |
|
131 |
+
#: src/WPML_OptionsManager.php:561
|
132 |
msgid "Editor"
|
133 |
msgstr ""
|
134 |
|
135 |
+
#: src/WPML_OptionsManager.php:563
|
136 |
msgid "Author"
|
137 |
msgstr ""
|
138 |
|
139 |
+
#: src/WPML_OptionsManager.php:565
|
140 |
msgid "Contributor"
|
141 |
msgstr ""
|
142 |
|
143 |
+
#: src/WPML_OptionsManager.php:567
|
144 |
msgid "Subscriber"
|
145 |
msgstr ""
|
146 |
|
147 |
+
#: src/WPML_OptionsManager.php:569
|
148 |
msgid "Anyone"
|
149 |
msgstr ""
|
150 |
|
151 |
+
#: src/WPML_PrivacyController.php:43
|
152 |
+
msgid ""
|
153 |
+
"When you use this site several actions (e.g. commenting) trigger the "
|
154 |
+
"dispatch of emails. They contain information about you associated with your "
|
155 |
+
"email address. Which data are part of these emails depends on the action "
|
156 |
+
"performed. These emails are stored and accessible to the site management as "
|
157 |
+
"log."
|
158 |
+
msgstr ""
|
159 |
+
|
160 |
+
#: src/WPML_PrivacyController.php:101
|
161 |
+
msgid "Mails"
|
162 |
+
msgstr ""
|
163 |
+
|
164 |
+
#: src/WPML_PrivacyController.php:137
|
165 |
+
msgid "A mail with the id %d was unable to be removed at this time."
|
166 |
+
msgstr ""
|
167 |
+
|
168 |
+
#: src/inc/class-wp-list-table.php:191
|
169 |
msgid "No items found."
|
170 |
msgstr ""
|
171 |
|
172 |
+
#: src/inc/class-wp-list-table.php:315
|
173 |
msgid "Bulk Actions"
|
174 |
msgstr ""
|
175 |
|
176 |
+
#: src/inc/class-wp-list-table.php:325
|
177 |
msgid "Apply"
|
178 |
msgstr ""
|
179 |
|
180 |
+
#: src/inc/class-wp-list-table.php:409
|
181 |
msgid "Show all dates"
|
182 |
msgstr ""
|
183 |
|
184 |
+
#: src/inc/class-wp-list-table.php:422
|
185 |
#. translators: 1: month name, 2: 4-digit year
|
186 |
msgid "%1$s %2$d"
|
187 |
msgstr ""
|
188 |
|
189 |
+
#: src/inc/class-wp-list-table.php:438
|
190 |
msgid "List View"
|
191 |
msgstr ""
|
192 |
|
193 |
+
#: src/inc/class-wp-list-table.php:439
|
194 |
msgid "Excerpt View"
|
195 |
msgstr ""
|
196 |
|
197 |
+
#: src/inc/class-wp-list-table.php:465
|
198 |
msgid "%s pending"
|
199 |
msgstr ""
|
200 |
|
201 |
+
#: src/inc/class-wp-list-table.php:533 src/inc/class-wp-list-table.php:948
|
202 |
msgid "1 item"
|
203 |
msgid_plural "%s items"
|
204 |
msgstr[0] ""
|
205 |
msgstr[1] ""
|
206 |
|
207 |
+
#: src/inc/class-wp-list-table.php:551
|
208 |
msgid "Go to the first page"
|
209 |
msgstr ""
|
210 |
|
211 |
+
#: src/inc/class-wp-list-table.php:558
|
212 |
msgid "Go to the previous page"
|
213 |
msgstr ""
|
214 |
|
215 |
+
#: src/inc/class-wp-list-table.php:567
|
216 |
msgid "Current page"
|
217 |
msgstr ""
|
218 |
|
219 |
+
#: src/inc/class-wp-list-table.php:577
|
220 |
msgid "Go to the next page"
|
221 |
msgstr ""
|
222 |
|
223 |
+
#: src/inc/class-wp-list-table.php:584
|
224 |
msgid "Go to the last page"
|
225 |
msgstr ""
|
226 |
|
227 |
+
#: src/inc/class-wp-list-table.php:720
|
228 |
msgid "Select All"
|
229 |
msgstr ""
|
230 |
|
231 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:92
|
232 |
msgid "General Settings"
|
233 |
msgstr ""
|
234 |
|
235 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:101
|
236 |
msgid "Cleanup"
|
237 |
msgstr ""
|
238 |
|
239 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:102
|
240 |
msgid "Delete all data on deactivation? (emails and settings)?"
|
241 |
msgstr ""
|
242 |
|
243 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:112
|
244 |
msgid "Can See Submission data"
|
245 |
msgstr ""
|
246 |
|
247 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:113
|
248 |
msgid "Select the minimum role."
|
249 |
msgstr ""
|
250 |
|
251 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:118
|
252 |
msgid "WordPress Date Time Format"
|
253 |
msgstr ""
|
254 |
|
255 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:119
|
256 |
msgid "Use format from WordPress settings (%s)"
|
257 |
msgstr ""
|
258 |
|
259 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:121
|
260 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:146
|
261 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:162
|
262 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:184
|
263 |
msgid "Enabled"
|
264 |
msgstr ""
|
265 |
|
266 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:122
|
267 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:147
|
268 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:163
|
269 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:185
|
270 |
msgid "Disabled"
|
271 |
msgstr ""
|
272 |
|
273 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:133
|
274 |
msgid "Default Format for Message"
|
275 |
msgstr ""
|
276 |
|
277 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:134
|
278 |
msgid "Select your preferred display format."
|
279 |
msgstr ""
|
280 |
|
281 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:139
|
282 |
msgid "Display Host"
|
283 |
msgstr ""
|
284 |
|
285 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:140
|
286 |
msgid "Display host column in list."
|
287 |
msgstr ""
|
288 |
|
289 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:152
|
290 |
msgid "Log Rotation"
|
291 |
msgstr ""
|
292 |
|
293 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:153
|
294 |
msgid "Save space by deleting logs regularly."
|
295 |
msgstr ""
|
296 |
|
297 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:159
|
298 |
msgid "Cleanup by Amount"
|
299 |
msgstr ""
|
300 |
|
301 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:160
|
302 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:182
|
303 |
msgid "Setup a automated cleanup routine!"
|
304 |
msgstr ""
|
305 |
|
306 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:169
|
307 |
msgid "Amount"
|
308 |
msgstr ""
|
309 |
|
310 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:170
|
311 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:192
|
312 |
msgid "When should mails are deleted?"
|
313 |
msgstr ""
|
314 |
|
315 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:171
|
316 |
msgid "Cleanup when the stored mails exceed..."
|
317 |
msgstr ""
|
318 |
|
319 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:181
|
320 |
msgid "Cleanup by Time"
|
321 |
msgstr ""
|
322 |
|
323 |
+
#: src/inc/redux/WPML_Redux_Framework_config.php:193
|
324 |
msgid "Delete mails older than days..."
|
325 |
msgstr ""
|
326 |
|
342 |
msgid "Logs each email sent by WordPress."
|
343 |
msgstr ""
|
344 |
|
345 |
+
#: src/inc/class-wp-list-table.php:573
|
346 |
msgctxt "paging"
|
347 |
msgid "%1$s of %2$s"
|
348 |
msgstr ""
|
lib/vendor/brandonwamboldt/wp-orm/README.md
ADDED
@@ -0,0 +1,281 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
WordPress ORM
|
2 |
+
=============
|
3 |
+
|
4 |
+
WordPress ORM is a small library that adds a basic ORM into WordPress, which is easily extendable and includes models for core WordPress models such as posts, pages, comments and users. It's designed to allow you to easily add new models other than custom post types, and not have to write a lot of manual SQL.
|
5 |
+
|
6 |
+
Installation
|
7 |
+
------------
|
8 |
+
|
9 |
+
While you can install and activate it like a normal plugin, I'd recommend putting it in the `/wp-content/mu-plugins` folder and adding a script called `wp-orm.php` to load the main plugin file (only top level `.php` files are loaded from `mu-plugins`).
|
10 |
+
|
11 |
+
`wp-orm.php`:
|
12 |
+
|
13 |
+
```php
|
14 |
+
<?php require 'wp-orm/wp-orm.php';
|
15 |
+
```
|
16 |
+
|
17 |
+
Examples
|
18 |
+
--------
|
19 |
+
|
20 |
+
#### Get 5 published pages, ordered by post title.
|
21 |
+
|
22 |
+
```php
|
23 |
+
use WordPress\ORM\Model\Page;
|
24 |
+
|
25 |
+
$pages = Page::query()
|
26 |
+
->limit(5)
|
27 |
+
->where('post_status', 'publish')
|
28 |
+
->sort_by('post_title')
|
29 |
+
->order('ASC')
|
30 |
+
->find();
|
31 |
+
```
|
32 |
+
|
33 |
+
#### Find a user by their login
|
34 |
+
|
35 |
+
```php
|
36 |
+
use WordPress\ORM\Model\User;
|
37 |
+
|
38 |
+
$user = User::find_one_by('user_login', 'brandon');
|
39 |
+
|
40 |
+
echo $user->get_user_login();
|
41 |
+
|
42 |
+
print_r($user->to_array());
|
43 |
+
```
|
44 |
+
|
45 |
+
#### Example of a more complex query
|
46 |
+
|
47 |
+
```php
|
48 |
+
use WordPress\ORM\Model\Post;
|
49 |
+
|
50 |
+
$posts = Post::query()
|
51 |
+
->limit(15)
|
52 |
+
->offset(0)
|
53 |
+
->where_all(['post_status' => 'publish', 'post_type' => 'post'])
|
54 |
+
->where_like('post_title', '%Hello world%')
|
55 |
+
->sort_by('post_title')
|
56 |
+
->order('ASC')
|
57 |
+
->find();
|
58 |
+
```
|
59 |
+
|
60 |
+
#### Updating a model
|
61 |
+
|
62 |
+
```php
|
63 |
+
use WordPress\ORM\Model\Post;
|
64 |
+
|
65 |
+
$post = Post::find_one(1204);
|
66 |
+
$post->set_post_title('What an amazing post!');
|
67 |
+
$post->save();
|
68 |
+
```
|
69 |
+
|
70 |
+
#### Meta data
|
71 |
+
|
72 |
+
Users, posts, pages and comments all support meta data.
|
73 |
+
|
74 |
+
```php
|
75 |
+
$post = Post::find_one(1337);
|
76 |
+
$post->get_metadata('_edit_lock');
|
77 |
+
$post->update_metadata('_edit_lock', '');
|
78 |
+
$post->delete_metadata('_edit_lock');
|
79 |
+
```
|
80 |
+
|
81 |
+
Meta data is saved immediately using WordPress meta data functions under the hood. Calling `save()` is not needed.
|
82 |
+
|
83 |
+
Custom Models
|
84 |
+
-------------
|
85 |
+
|
86 |
+
```php
|
87 |
+
<?php
|
88 |
+
|
89 |
+
namespace WordPress\ORM;
|
90 |
+
|
91 |
+
class Venue extends BaseModel
|
92 |
+
{
|
93 |
+
protected $id;
|
94 |
+
protected $venue_title;
|
95 |
+
protected $description;
|
96 |
+
protected $now_playing;
|
97 |
+
protected $location;
|
98 |
+
protected $avg_rating;
|
99 |
+
|
100 |
+
public static function get_primary_key()
|
101 |
+
{
|
102 |
+
return 'id';
|
103 |
+
}
|
104 |
+
|
105 |
+
public static function get_table()
|
106 |
+
{
|
107 |
+
return 'wp_venues';
|
108 |
+
}
|
109 |
+
|
110 |
+
public static function get_searchable_fields()
|
111 |
+
{
|
112 |
+
return ['venue_title', 'description', 'now_playing'];
|
113 |
+
}
|
114 |
+
}
|
115 |
+
```
|
116 |
+
|
117 |
+
You can now use this venue, persist it, and use the custom query DSL shown above to query it.
|
118 |
+
|
119 |
+
Model Methods
|
120 |
+
-------------
|
121 |
+
|
122 |
+
##### Model::get_table()
|
123 |
+
|
124 |
+
This is a static method that you must define in your models, and should return the table to persist data to.
|
125 |
+
|
126 |
+
##### Model::get_searchable_fields()
|
127 |
+
|
128 |
+
This is a static method that you must define in your models, and should return an array of properties to search when doing a search query.
|
129 |
+
|
130 |
+
##### Model::get_primary_key()
|
131 |
+
|
132 |
+
Return's the property used as a primary key. Defaults to `id`.
|
133 |
+
|
134 |
+
##### Model::create(array $properties)
|
135 |
+
|
136 |
+
Create a new model from an array of properties.
|
137 |
+
|
138 |
+
##### Model::find_one_by(string $property, mixed $value)
|
139 |
+
|
140 |
+
Find a single model with the specified property value.
|
141 |
+
|
142 |
+
##### Model::find_one(integer $id)
|
143 |
+
|
144 |
+
Find a single model who's primary key is equal to the given ID.
|
145 |
+
|
146 |
+
##### Model::query()
|
147 |
+
|
148 |
+
Return a new `WordPress\ORM\Query` object.
|
149 |
+
|
150 |
+
##### Model::all()
|
151 |
+
|
152 |
+
Return every single model in the database.
|
153 |
+
|
154 |
+
##### $model->primary_key()
|
155 |
+
|
156 |
+
Return the model's primary key (the value, not the property name).
|
157 |
+
|
158 |
+
##### $model->to_array()
|
159 |
+
|
160 |
+
Return all of the model's properties as an array.
|
161 |
+
|
162 |
+
##### $model->flatten_props(array $props)
|
163 |
+
|
164 |
+
Call right before `save()`, should flatten any objects in the properties into strings so they can be persisted. Defaults to flattening `DateTime` objects into a timestamp and arrays into a serialized array.
|
165 |
+
|
166 |
+
##### $model->save()
|
167 |
+
|
168 |
+
Save your model to the database. Creates a new row if the model doesn't have an ID, or updates an existing row if their is an ID.
|
169 |
+
|
170 |
+
##### $model->delete()
|
171 |
+
|
172 |
+
Delete the model from the database. Returns `true` if it was successful or `false` if it was not.
|
173 |
+
|
174 |
+
ORM Queries
|
175 |
+
-----------
|
176 |
+
|
177 |
+
Below are the functions you have access to after you call the `Model::query()` function.
|
178 |
+
|
179 |
+
##### $query->limit(integer $limit)
|
180 |
+
|
181 |
+
Limits the number of results returned using an SQL `LIMIT` clause.
|
182 |
+
|
183 |
+
##### $query->offset(integer $offset)
|
184 |
+
|
185 |
+
Offset the results returned, used with pagination. Uses the SQL `OFFSET` clause.
|
186 |
+
|
187 |
+
##### $query->sort_by(string $property)
|
188 |
+
|
189 |
+
Sort results by the specified property. Can also be a MySQL function such as `RAND()`.
|
190 |
+
|
191 |
+
##### $query->order(string $order)
|
192 |
+
|
193 |
+
Order the results in the given order. Can be one of `ASC` or `DESC`.
|
194 |
+
|
195 |
+
##### $query->search(string $search_term)
|
196 |
+
|
197 |
+
Limit results to items matching the given search term. Searches the properties returned by `Model::get_searchable_fields`.
|
198 |
+
|
199 |
+
##### $query->where(string $property, string $value)
|
200 |
+
|
201 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property = '$value'`. `$value` is automatically escaped.
|
202 |
+
|
203 |
+
##### $query->where_not(string $property, string $value)
|
204 |
+
|
205 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property != '$value'`. `$value` is automatically escaped.
|
206 |
+
|
207 |
+
##### $query->where_like(string $property, string $value)
|
208 |
+
|
209 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property LIKE '$value'`. `$value` is automatically escaped.
|
210 |
+
|
211 |
+
##### $query->where_not_like(string $property, string $value)
|
212 |
+
|
213 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property NOT LIKE '$value'`. `$value` is automatically escaped.
|
214 |
+
|
215 |
+
##### $query->where_lt(string $property, string $value)
|
216 |
+
|
217 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property < '$value'`. `$value` is automatically escaped.
|
218 |
+
|
219 |
+
##### $query->where_lte(string $property, string $value)
|
220 |
+
|
221 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property <= '$value'`. `$value` is automatically escaped.
|
222 |
+
|
223 |
+
##### $query->where_gt(string $property, string $value)
|
224 |
+
|
225 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property > '$value'`. `$value` is automatically escaped.
|
226 |
+
|
227 |
+
##### $query->where_gte(string $property, string $value)
|
228 |
+
|
229 |
+
Add a parameter to the where clause. Equivalent to ` WHERE $property >= '$value'`. `$value` is automatically escaped.
|
230 |
+
|
231 |
+
##### $query->where_in(string $column, array $in)
|
232 |
+
|
233 |
+
Limit results to items where the given column is one of the given values. Equivalent to ` WHERE $property IN ('value1', 'value2')` where `value1` and `value2` are values in the array.
|
234 |
+
|
235 |
+
##### $query->where_not_in(string $column, array $in)
|
236 |
+
|
237 |
+
Limit results to items where the given column is not one of the given values. Equivalent to ` WHERE $property NOT IN ('value1', 'value2')` where `value1` and `value2` are values in the array.
|
238 |
+
|
239 |
+
##### $query->where_any(array $where)
|
240 |
+
|
241 |
+
Limit results to items that match any of the property/value pairs given in the array. Must match at least one.
|
242 |
+
|
243 |
+
##### $query->where_all(array $where)
|
244 |
+
|
245 |
+
Limit results to items that match all of the property/value pairs given in the array.
|
246 |
+
|
247 |
+
Actions & Filters
|
248 |
+
-----------------
|
249 |
+
|
250 |
+
#### wporm_query($sql, $model_class)
|
251 |
+
|
252 |
+
Manipulate the raw SQL query created by the Query class.
|
253 |
+
|
254 |
+
```php
|
255 |
+
add_filter('wporm_query', function($sql, $model_class) {
|
256 |
+
if ($model_class == 'WordPress\ORM\Model\Page') {
|
257 |
+
$sql = str_replace('wp_posts', 'wp2_posts', $sql);
|
258 |
+
}
|
259 |
+
|
260 |
+
return $sql;
|
261 |
+
}, 10, 2);
|
262 |
+
```
|
263 |
+
|
264 |
+
#### wporm_count_query($sql, $model_class)
|
265 |
+
|
266 |
+
Manipulate the raw SQL query created by the Query class (the row count variation).
|
267 |
+
|
268 |
+
```php
|
269 |
+
add_filter('wporm_count_query', function($sql, $model_class) {
|
270 |
+
if ($model_class == 'WordPress\ORM\Model\Page') {
|
271 |
+
$sql = str_replace('wp_posts', 'wp2_posts', $sql);
|
272 |
+
}
|
273 |
+
|
274 |
+
return $sql;
|
275 |
+
}, 10, 2);
|
276 |
+
```
|
277 |
+
|
278 |
+
License
|
279 |
+
-------
|
280 |
+
|
281 |
+
This code is licensed under the MIT license.
|
lib/vendor/brandonwamboldt/wp-orm/src/BaseModel.php
CHANGED
@@ -9,6 +9,12 @@ namespace No3x\WPML\ORM;
|
|
9 |
*/
|
10 |
abstract class BaseModel implements ModelInterface
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Get the column used as the primary key, defaults to 'id'.
|
14 |
*
|
@@ -211,13 +217,24 @@ abstract class BaseModel implements ModelInterface
|
|
211 |
*/
|
212 |
public static function query()
|
213 |
{
|
214 |
-
$query =
|
215 |
$query->set_searchable_fields(static::get_searchable_fields());
|
216 |
$query->set_primary_key(static::get_primary_key());
|
217 |
|
218 |
return $query;
|
219 |
}
|
220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
/**
|
222 |
* Return EVERY instance of this model from the database, with NO filtering.
|
223 |
*
|
9 |
*/
|
10 |
abstract class BaseModel implements ModelInterface
|
11 |
{
|
12 |
+
|
13 |
+
/**
|
14 |
+
* @var QueryFactory
|
15 |
+
*/
|
16 |
+
private static $queryFactory;
|
17 |
+
|
18 |
/**
|
19 |
* Get the column used as the primary key, defaults to 'id'.
|
20 |
*
|
217 |
*/
|
218 |
public static function query()
|
219 |
{
|
220 |
+
$query = self::getQueryFactory()->buildQuery(get_called_class());
|
221 |
$query->set_searchable_fields(static::get_searchable_fields());
|
222 |
$query->set_primary_key(static::get_primary_key());
|
223 |
|
224 |
return $query;
|
225 |
}
|
226 |
|
227 |
+
public static function getQueryFactory() {
|
228 |
+
if (!isset(self::$queryFactory)) {
|
229 |
+
self::$queryFactory = new DefaultQueryFactory();
|
230 |
+
}
|
231 |
+
return self::$queryFactory;
|
232 |
+
}
|
233 |
+
|
234 |
+
public static function setQueryFactory(QueryFactory $queryFactory) {
|
235 |
+
self::$queryFactory = $queryFactory;
|
236 |
+
}
|
237 |
+
|
238 |
/**
|
239 |
* Return EVERY instance of this model from the database, with NO filtering.
|
240 |
*
|
lib/vendor/brandonwamboldt/wp-orm/src/DefaultQueryFactory.php
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\ORM;
|
4 |
+
|
5 |
+
|
6 |
+
class DefaultQueryFactory implements QueryFactory {
|
7 |
+
public function buildQuery($modelClass) {
|
8 |
+
return new Query($modelClass);
|
9 |
+
}
|
10 |
+
}
|
lib/vendor/brandonwamboldt/wp-orm/src/QueryFactory.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\ORM;
|
4 |
+
|
5 |
+
|
6 |
+
interface QueryFactory {
|
7 |
+
public function buildQuery($modelClass);
|
8 |
+
}
|
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: mail, email, log, logging, debug, list, store, collect, view
|
|
5 |
License: GPLv3
|
6 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
7 |
Requires at least: 3.0
|
8 |
-
Tested up to: 4.9.
|
9 |
Stable tag: 1.8.4
|
10 |
|
11 |
Logs each email sent by WordPress.
|
@@ -41,7 +41,7 @@ I recommend the following plugins if you want to send mails via SMTP because the
|
|
41 |
== Frequently Asked Questions ==
|
42 |
= How do I know the mail was sent? =
|
43 |
If there is no error logged chances are high the mail was sent. There are plugins that overwrite (do not customize) the default mailing mechanism of WordPress - they maybe do not inform about failure so it can't be logged by WP Mail Logging.
|
44 |
-
= How do I know the
|
45 |
The logged email has been sent by WordPress but please note this does NOT mean it has been delivered. With the given functionality of WordPress you can't determine if a mail was delivered successfully.
|
46 |
|
47 |
== Screenshots ==
|
@@ -50,12 +50,20 @@ The logged email has been sent by WordPress but please note this does NOT mean i
|
|
50 |
3. The Settings
|
51 |
|
52 |
== Upgrade Notice ==
|
53 |
-
= 1.8.
|
54 |
-
-
|
55 |
-
- Fix:
|
|
|
|
|
56 |
|
57 |
== Changelog ==
|
58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
= 1.8.4, June 22, 2018 =
|
60 |
- Fix: transient bug
|
61 |
- Fix: notice when attachments not set
|
5 |
License: GPLv3
|
6 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
7 |
Requires at least: 3.0
|
8 |
+
Tested up to: 4.9.8
|
9 |
Stable tag: 1.8.4
|
10 |
|
11 |
Logs each email sent by WordPress.
|
41 |
== Frequently Asked Questions ==
|
42 |
= How do I know the mail was sent? =
|
43 |
If there is no error logged chances are high the mail was sent. There are plugins that overwrite (do not customize) the default mailing mechanism of WordPress - they maybe do not inform about failure so it can't be logged by WP Mail Logging.
|
44 |
+
= How do I know the mail was delivered? =
|
45 |
The logged email has been sent by WordPress but please note this does NOT mean it has been delivered. With the given functionality of WordPress you can't determine if a mail was delivered successfully.
|
46 |
|
47 |
== Screenshots ==
|
50 |
3. The Settings
|
51 |
|
52 |
== Upgrade Notice ==
|
53 |
+
= 1.8.5 =
|
54 |
+
- New: added privacy integration (erasure, export, policy content suggestion)
|
55 |
+
- Fix: typo in readme
|
56 |
+
- Fix: output of html comments in emails
|
57 |
+
- Tweak: performance (duplicate queries of installation state)
|
58 |
|
59 |
== Changelog ==
|
60 |
|
61 |
+
= 1.8.5, September 13, 2018 =
|
62 |
+
- New: added privacy integration (erasure, export, policy content suggestion)
|
63 |
+
- Fix: typo in readme
|
64 |
+
- Fix: output of html comments in emails
|
65 |
+
- Tweak: performance (duplicate queries of installation state)
|
66 |
+
|
67 |
= 1.8.4, June 22, 2018 =
|
68 |
- Fix: transient bug
|
69 |
- Fix: notice when attachments not set
|
{model → src/Model}/WPML_Mail.php
RENAMED
@@ -66,9 +66,8 @@ class WPML_Mail extends BaseModel
|
|
66 |
protected $plugin_version;
|
67 |
|
68 |
/**
|
69 |
-
* @
|
70 |
*/
|
71 |
-
|
72 |
public function __construct(array $properties = array())
|
73 |
{
|
74 |
parent::__construct($properties);
|
@@ -104,4 +103,4 @@ class WPML_Mail extends BaseModel
|
|
104 |
{
|
105 |
return array('receiver', 'subject', 'headers', 'message', 'attachments', 'host');
|
106 |
}
|
107 |
-
}
|
66 |
protected $plugin_version;
|
67 |
|
68 |
/**
|
69 |
+
* @param array $properties
|
70 |
*/
|
|
|
71 |
public function __construct(array $properties = array())
|
72 |
{
|
73 |
parent::__construct($properties);
|
103 |
{
|
104 |
return array('receiver', 'subject', 'headers', 'message', 'attachments', 'host');
|
105 |
}
|
106 |
+
}
|
WPML_API_Example.php → src/WPML_API_Example.php
RENAMED
@@ -1,85 +1,85 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace No3x\WPML;
|
4 |
-
|
5 |
-
// Exit if accessed directly.
|
6 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* @author No3x
|
10 |
-
* @since 1.0
|
11 |
-
* The Plugin provides mechanisms to extend the displayed data.
|
12 |
-
* This class is not an API class. It is just an example how to hook in.
|
13 |
-
* If you consider writing a plugin please contact me for better hook support/documentation.
|
14 |
-
*/
|
15 |
-
class WPML_API_Example {
|
16 |
-
|
17 |
-
// require_once('WPML_API_Example.php');
|
18 |
-
// $aAPI = new WPML_API_Example();
|
19 |
-
|
20 |
-
public function addActionsAndFilters() {
|
21 |
-
// In this example we are going to add a column 'test' in add_column.
|
22 |
-
add_filter( WPML_Plugin::HOOK_LOGGING_COLUMNS, array( &$this, 'add_column' ) );
|
23 |
-
add_filter( WPML_Plugin::HOOK_LOGGING_COLUMNS_RENDER, array( &$this, 'render_column' ), 10, 2 );
|
24 |
-
// Change the supported formats of modal e.g. dashed:
|
25 |
-
add_filter( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, array( &$this, 'add_supported_format') );
|
26 |
-
// Change content of format dashed HOOK_LOGGING_FORMAT_CONTENT_{$your_format} e.g. dashed:
|
27 |
-
add_filter( WPML_Plugin::HOOK_LOGGING_FORMAT_CONTENT . '_dashed', array( &$this, 'supported_format_dashed') );
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Is called when List Table is gathering columns.
|
32 |
-
* @since 1.0
|
33 |
-
* @param array $columns Array of columns.
|
34 |
-
* @return array $columns Updated array of columns.
|
35 |
-
*/
|
36 |
-
public function add_column( $columns ) {
|
37 |
-
return $columns = array_merge( $columns,
|
38 |
-
array( 'test' => 'test' )
|
39 |
-
//,array('test2' => 'wp-mail-logging' ) // ...
|
40 |
-
);
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Is called when the List Table could not find the column. So we can hook in and modify the column.
|
45 |
-
* @since 1.0
|
46 |
-
* @param array $item A singular item (one full row's worth of data).
|
47 |
-
* @param array $column_name The name/slug of the column to be processed.
|
48 |
-
* @return string Text or HTML to be placed inside the column <td>
|
49 |
-
*/
|
50 |
-
public function render_column( $item, $column_name ) {
|
51 |
-
switch ( $column_name ) {
|
52 |
-
case 'test':
|
53 |
-
return 'display relevant data. item contains all information you need about the row. You can process the data and add the result to this column. You can access it like this: $item[$column_name]';
|
54 |
-
default:
|
55 |
-
return '';
|
56 |
-
}
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Is called when supported formats are collected. You can add a format here then you can provide a content function.
|
61 |
-
* @since 1.6.0
|
62 |
-
* @param array $formats supported formats
|
63 |
-
* @return array supported formats + your additional formats
|
64 |
-
* @see WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS
|
65 |
-
*/
|
66 |
-
public function add_supported_format( $formats ) {
|
67 |
-
$formats[] = 'dashed';
|
68 |
-
return $formats;
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* This function is called for each of your additional formats. Change the content of the modal here.
|
73 |
-
* For example I add some dashes.
|
74 |
-
* @since 1.6.0
|
75 |
-
* @param $mail
|
76 |
-
* @return string
|
77 |
-
* @see WPML_Plugin::HOOK_LOGGING_FORMAT_CONTENT
|
78 |
-
*/
|
79 |
-
public function supported_format_dashed( $mail ) {
|
80 |
-
$dashedAppend = '';
|
81 |
-
foreach( $mail as $property => $value )
|
82 |
-
$dashedAppend .= str_replace(' ', '-', $value);
|
83 |
-
return $dashedAppend;
|
84 |
-
}
|
85 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
// Exit if accessed directly.
|
6 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* @author No3x
|
10 |
+
* @since 1.0
|
11 |
+
* The Plugin provides mechanisms to extend the displayed data.
|
12 |
+
* This class is not an API class. It is just an example how to hook in.
|
13 |
+
* If you consider writing a plugin please contact me for better hook support/documentation.
|
14 |
+
*/
|
15 |
+
class WPML_API_Example {
|
16 |
+
|
17 |
+
// require_once('WPML_API_Example.php');
|
18 |
+
// $aAPI = new WPML_API_Example();
|
19 |
+
|
20 |
+
public function addActionsAndFilters() {
|
21 |
+
// In this example we are going to add a column 'test' in add_column.
|
22 |
+
add_filter( WPML_Plugin::HOOK_LOGGING_COLUMNS, array( &$this, 'add_column' ) );
|
23 |
+
add_filter( WPML_Plugin::HOOK_LOGGING_COLUMNS_RENDER, array( &$this, 'render_column' ), 10, 2 );
|
24 |
+
// Change the supported formats of modal e.g. dashed:
|
25 |
+
add_filter( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, array( &$this, 'add_supported_format') );
|
26 |
+
// Change content of format dashed HOOK_LOGGING_FORMAT_CONTENT_{$your_format} e.g. dashed:
|
27 |
+
add_filter( WPML_Plugin::HOOK_LOGGING_FORMAT_CONTENT . '_dashed', array( &$this, 'supported_format_dashed') );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Is called when List Table is gathering columns.
|
32 |
+
* @since 1.0
|
33 |
+
* @param array $columns Array of columns.
|
34 |
+
* @return array $columns Updated array of columns.
|
35 |
+
*/
|
36 |
+
public function add_column( $columns ) {
|
37 |
+
return $columns = array_merge( $columns,
|
38 |
+
array( 'test' => 'test' )
|
39 |
+
//,array('test2' => 'wp-mail-logging' ) // ...
|
40 |
+
);
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Is called when the List Table could not find the column. So we can hook in and modify the column.
|
45 |
+
* @since 1.0
|
46 |
+
* @param array $item A singular item (one full row's worth of data).
|
47 |
+
* @param array $column_name The name/slug of the column to be processed.
|
48 |
+
* @return string Text or HTML to be placed inside the column <td>
|
49 |
+
*/
|
50 |
+
public function render_column( $item, $column_name ) {
|
51 |
+
switch ( $column_name ) {
|
52 |
+
case 'test':
|
53 |
+
return 'display relevant data. item contains all information you need about the row. You can process the data and add the result to this column. You can access it like this: $item[$column_name]';
|
54 |
+
default:
|
55 |
+
return '';
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Is called when supported formats are collected. You can add a format here then you can provide a content function.
|
61 |
+
* @since 1.6.0
|
62 |
+
* @param array $formats supported formats
|
63 |
+
* @return array supported formats + your additional formats
|
64 |
+
* @see WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS
|
65 |
+
*/
|
66 |
+
public function add_supported_format( $formats ) {
|
67 |
+
$formats[] = 'dashed';
|
68 |
+
return $formats;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* This function is called for each of your additional formats. Change the content of the modal here.
|
73 |
+
* For example I add some dashes.
|
74 |
+
* @since 1.6.0
|
75 |
+
* @param $mail
|
76 |
+
* @return string
|
77 |
+
* @see WPML_Plugin::HOOK_LOGGING_FORMAT_CONTENT
|
78 |
+
*/
|
79 |
+
public function supported_format_dashed( $mail ) {
|
80 |
+
$dashedAppend = '';
|
81 |
+
foreach( $mail as $property => $value )
|
82 |
+
$dashedAppend .= str_replace(' ', '-', $value);
|
83 |
+
return $dashedAppend;
|
84 |
+
}
|
85 |
+
}
|
WPML_DI_Container.php → src/WPML_DI_Container.php
RENAMED
@@ -1,24 +1,24 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* User: No3x
|
4 |
-
* Date: 06.09.15
|
5 |
-
* Time: 12:47
|
6 |
-
*/
|
7 |
-
|
8 |
-
namespace No3x\WPML;
|
9 |
-
use No3x\WPML\Pimple\Container;
|
10 |
-
|
11 |
-
class WPML_DI_Container extends Container {
|
12 |
-
|
13 |
-
public function addActionsAndFilters() {
|
14 |
-
foreach ( $this->keys() as $key ) {
|
15 |
-
$content = $this[ $key ];
|
16 |
-
if ( is_object( $content ) ) {
|
17 |
-
$reflection = new \ReflectionClass( $content );
|
18 |
-
if ( $reflection->hasMethod( 'addActionsAndFilters' ) ) {
|
19 |
-
$content->addActionsAndFilters();
|
20 |
-
}
|
21 |
-
}
|
22 |
-
}
|
23 |
-
}
|
24 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* User: No3x
|
4 |
+
* Date: 06.09.15
|
5 |
+
* Time: 12:47
|
6 |
+
*/
|
7 |
+
|
8 |
+
namespace No3x\WPML;
|
9 |
+
use No3x\WPML\Pimple\Container;
|
10 |
+
|
11 |
+
class WPML_DI_Container extends Container {
|
12 |
+
|
13 |
+
public function addActionsAndFilters() {
|
14 |
+
foreach ( $this->keys() as $key ) {
|
15 |
+
$content = $this[ $key ];
|
16 |
+
if ( is_object( $content ) ) {
|
17 |
+
$reflection = new \ReflectionClass( $content );
|
18 |
+
if ( $reflection->hasMethod( 'addActionsAndFilters' ) ) {
|
19 |
+
$content->addActionsAndFilters();
|
20 |
+
}
|
21 |
+
}
|
22 |
+
}
|
23 |
+
}
|
24 |
+
}
|
WPML_Email_Dispatcher.php → src/WPML_Email_Dispatcher.php
RENAMED
@@ -1,18 +1,18 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Created by IntelliJ IDEA.
|
4 |
-
* User: czoeller
|
5 |
-
* Date: 08.06.17
|
6 |
-
* Time: 15:48
|
7 |
-
*/
|
8 |
-
|
9 |
-
namespace No3x\WPML;
|
10 |
-
|
11 |
-
|
12 |
-
class WPML_Email_Dispatcher {
|
13 |
-
|
14 |
-
public function dispatch( $to, $subject, $message, $headers = '', $attachments = array() )
|
15 |
-
{
|
16 |
-
wp_mail( $to, $subject, $message, $headers, $attachments);
|
17 |
-
}
|
18 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Created by IntelliJ IDEA.
|
4 |
+
* User: czoeller
|
5 |
+
* Date: 08.06.17
|
6 |
+
* Time: 15:48
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace No3x\WPML;
|
10 |
+
|
11 |
+
|
12 |
+
class WPML_Email_Dispatcher {
|
13 |
+
|
14 |
+
public function dispatch( $to, $subject, $message, $headers = '', $attachments = array() )
|
15 |
+
{
|
16 |
+
wp_mail( $to, $subject, $message, $headers, $attachments);
|
17 |
+
}
|
18 |
+
}
|
WPML_Email_Log_List.php → src/WPML_Email_Log_List.php
RENAMED
@@ -1,510 +1,509 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace No3x\WPML;
|
4 |
-
|
5 |
-
use No3x\WPML\Model\WPML_Mail as Mail;
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
require_once(
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
*
|
20 |
-
* @
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
*
|
33 |
-
* @
|
34 |
-
* @param
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
$this->
|
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 |
-
array_slice( $columns, $posAfterTimestamp
|
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 |
-
|
146 |
-
|
147 |
-
|
148 |
-
*
|
149 |
-
* @
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
$
|
156 |
-
|
157 |
-
$
|
158 |
-
$
|
159 |
-
|
160 |
-
$this->
|
161 |
-
|
162 |
-
$
|
163 |
-
|
164 |
-
$
|
165 |
-
|
166 |
-
$
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
->
|
174 |
-
->
|
175 |
-
->
|
176 |
-
->
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
*
|
193 |
-
*
|
194 |
-
* @
|
195 |
-
* @
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
$column_content = $
|
205 |
-
}
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
*
|
217 |
-
* @
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
$
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
*
|
228 |
-
* @
|
229 |
-
* @
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
$
|
234 |
-
$message
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
*
|
240 |
-
* @
|
241 |
-
* @
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
*
|
250 |
-
* @
|
251 |
-
* @
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
$
|
256 |
-
$attachments =
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
$
|
262 |
-
$
|
263 |
-
$
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
$
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
*
|
277 |
-
* @
|
278 |
-
* @
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
$
|
288 |
-
$attachments =
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
$
|
294 |
-
$
|
295 |
-
$
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
$
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
*
|
311 |
-
* @
|
312 |
-
* @
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
$error
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
*
|
324 |
-
* @
|
325 |
-
* @
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
$
|
330 |
-
|
331 |
-
|
332 |
-
$
|
333 |
-
$
|
334 |
-
$
|
335 |
-
$
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
*
|
355 |
-
* @
|
356 |
-
* @
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
$
|
361 |
-
|
362 |
-
|
363 |
-
$
|
364 |
-
$
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
*
|
377 |
-
* @
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
'
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
*
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
*
|
421 |
-
* @
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
*
|
430 |
-
* @
|
431 |
-
* @
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
*
|
443 |
-
* @
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
'
|
450 |
-
'
|
451 |
-
'
|
452 |
-
'
|
453 |
-
'
|
454 |
-
'
|
455 |
-
'
|
456 |
-
'
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
*
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
$
|
482 |
-
$
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
$mailAppend .=
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
use No3x\WPML\Model\WPML_Mail as Mail;
|
6 |
+
|
7 |
+
// Exit if accessed directly.
|
8 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
9 |
+
|
10 |
+
require_once(ABSPATH . 'wp-admin/includes/screen.php');
|
11 |
+
require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php');
|
12 |
+
|
13 |
+
if ( ! class_exists( 'WP_List_Table' ) ) {
|
14 |
+
require_once( plugin_dir_path( __FILE__ ) . 'inc/class-wp-list-table.php' );
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Renders the mails in a table list.
|
19 |
+
* @author No3x
|
20 |
+
* @since 1.0
|
21 |
+
*/
|
22 |
+
class WPML_Email_Log_List extends \WP_List_Table {
|
23 |
+
|
24 |
+
const NONCE_LIST_TABLE = 'wpml-list_table';
|
25 |
+
private $supported_formats = array();
|
26 |
+
/** @var WPML_Email_Resender $emailResender */
|
27 |
+
private $emailResender;
|
28 |
+
/** @var WPML_MessageSanitizer $messageSanitizer */
|
29 |
+
private $messageSanitizer;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Initializes the List Table
|
33 |
+
* @since 1.0
|
34 |
+
* @param array $supported_formats
|
35 |
+
* @param WPML_Email_Resender $emailResender
|
36 |
+
*/
|
37 |
+
function __construct( $supported_formats = array(), $emailResender ) {
|
38 |
+
$this->supported_formats = $supported_formats;
|
39 |
+
$this->emailResender = $emailResender;
|
40 |
+
$this->messageSanitizer = new WPML_MessageSanitizer();
|
41 |
+
}
|
42 |
+
|
43 |
+
function addActionsAndFilters() {
|
44 |
+
add_action( 'admin_init', array( $this, 'init') );
|
45 |
+
add_filter( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, function() {
|
46 |
+
return $this->supported_formats;
|
47 |
+
} );
|
48 |
+
add_action( 'wp_ajax_wpml_email_get', __CLASS__ . '::ajax_wpml_email_get' );
|
49 |
+
}
|
50 |
+
|
51 |
+
function init() {
|
52 |
+
global $status, $page, $hook_suffix;
|
53 |
+
|
54 |
+
parent::__construct( array(
|
55 |
+
'singular' => 'email', // singular name of the listed records
|
56 |
+
'plural' => 'emails', // plural name of the listed records
|
57 |
+
'ajax' => false, // does this table support ajax?
|
58 |
+
) );
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Is displayed if no item is available to render
|
63 |
+
* @since 1.0
|
64 |
+
* @see WP_List_Table::no_items()
|
65 |
+
*/
|
66 |
+
function no_items() {
|
67 |
+
_e( 'No email found.', 'wp-mail-logging' );
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Defines the available columns.
|
73 |
+
* @since 1.0
|
74 |
+
* @see WP_List_Table::get_columns()
|
75 |
+
*/
|
76 |
+
function get_columns() {
|
77 |
+
$columns = array(
|
78 |
+
'cb' => '<input type="checkbox" />',
|
79 |
+
'mail_id' => __( 'ID', 'wp-mail-logging' ),
|
80 |
+
'timestamp' => __( 'Time', 'wp-mail-logging' ),
|
81 |
+
'receiver' => __( 'Receiver', 'wp-mail-logging' ),
|
82 |
+
'subject' => __( 'Subject', 'wp-mail-logging' ),
|
83 |
+
'message' => __( 'Message', 'wp-mail-logging' ),
|
84 |
+
'headers' => __( 'Headers', 'wp-mail-logging' ),
|
85 |
+
'attachments' => __( 'Attachments', 'wp-mail-logging' ),
|
86 |
+
'error' => __( 'Error', 'wp-mail-logging' ),
|
87 |
+
'plugin_version' => __( 'Plugin Version', 'wp-mail-logging' ),
|
88 |
+
);
|
89 |
+
|
90 |
+
/* @var $instance WPML_Plugin */
|
91 |
+
$instance = WPML_Init::getInstance()->getService( 'plugin' );
|
92 |
+
|
93 |
+
$switch = $instance->getSetting('display-host', false );
|
94 |
+
if( true == $switch ) {
|
95 |
+
$posAfterTimestamp = array_search('timestamp', array_keys($columns) ) + 1;
|
96 |
+
$columns = array_merge(
|
97 |
+
array_slice( $columns, 0, $posAfterTimestamp),
|
98 |
+
[ 'host' => __( 'Host', 'wp-mail-logging' ) ],
|
99 |
+
array_slice( $columns, $posAfterTimestamp )
|
100 |
+
);
|
101 |
+
}
|
102 |
+
|
103 |
+
// Give a plugin the chance to edit the columns.
|
104 |
+
$columns = apply_filters( WPML_Plugin::HOOK_LOGGING_COLUMNS, $columns );
|
105 |
+
|
106 |
+
$reserved = array( '_title', 'comment', 'media', 'name', 'title', 'username', 'blogname' );
|
107 |
+
|
108 |
+
// Show message for reserved column names.
|
109 |
+
foreach ( $reserved as $reserved_key ) {
|
110 |
+
if ( array_key_exists( $reserved_key, $columns ) ) {
|
111 |
+
echo "You should avoid $reserved_key as keyname since it is treated by WordPress specially: Your table would still work, but you won't be able to show/hide the columns. You can prefix your columns!";
|
112 |
+
break;
|
113 |
+
}
|
114 |
+
}
|
115 |
+
return $columns;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Define which columns are hidden
|
120 |
+
* @since 1.0
|
121 |
+
* @return array
|
122 |
+
*/
|
123 |
+
function get_hidden_columns() {
|
124 |
+
return array(
|
125 |
+
'plugin_version',
|
126 |
+
'mail_id',
|
127 |
+
);
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* Sanitize orderby parameter.
|
132 |
+
* @s
|
133 |
+
* @return string sanitized orderby parameter
|
134 |
+
*/
|
135 |
+
private function sanitize_orderby() {
|
136 |
+
return WPML_Utils::sanitize_expected_value( ( !empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : null, $this->get_sortable_columns(), 'mail_id');
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Sanitize order parameter.
|
141 |
+
* @return string sanitized order parameter
|
142 |
+
*/
|
143 |
+
private function sanitize_order() {
|
144 |
+
return WPML_Utils::sanitize_expected_value( ( !empty( $_GET['order'] ) ) ? $_GET['order'] : null, array('desc', 'asc'), 'desc');
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Prepares the items for rendering
|
149 |
+
* @since 1.0
|
150 |
+
* @param string|boolean $search string you want to search for. Default false.
|
151 |
+
* @see WP_List_Table::prepare_items()
|
152 |
+
*/
|
153 |
+
function prepare_items( $search = false ) {
|
154 |
+
$orderby = $this->sanitize_orderby();
|
155 |
+
$order = $this->sanitize_order();
|
156 |
+
|
157 |
+
$columns = $this->get_columns();
|
158 |
+
$hidden = $this->get_hidden_columns();
|
159 |
+
$sortable = $this->get_sortable_columns();
|
160 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
161 |
+
|
162 |
+
$this->process_bulk_action();
|
163 |
+
|
164 |
+
$per_page = $this->get_items_per_page( 'per_page', 25 );
|
165 |
+
$current_page = $this->get_pagenum();
|
166 |
+
$offset = ( $current_page - 1 ) * $per_page;
|
167 |
+
|
168 |
+
$total_items = Mail::query()
|
169 |
+
->search( $search )
|
170 |
+
->find( true );
|
171 |
+
|
172 |
+
$mails = Mail::query()
|
173 |
+
->search( $search )
|
174 |
+
->sort_by( $orderby )
|
175 |
+
->order( $order )
|
176 |
+
->limit( $per_page )
|
177 |
+
->offset( $offset )
|
178 |
+
->find();
|
179 |
+
|
180 |
+
foreach ( $mails as $mail ) {
|
181 |
+
/* @var $mail Mail */
|
182 |
+
$this->items[] = $mail->to_array();
|
183 |
+
}
|
184 |
+
|
185 |
+
$this->set_pagination_args( array(
|
186 |
+
'total_items' => $total_items, // The total number of items.
|
187 |
+
'per_page' => $per_page, // Number of items per page.
|
188 |
+
) );
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Renders the cell.
|
193 |
+
* Note: We can easily add filter for all columns if you want to / need to manipulate the content. (currently only additional column manipulation is supported)
|
194 |
+
* @since 1.0
|
195 |
+
* @param array $item The current item.
|
196 |
+
* @param string $column_name The current column name.
|
197 |
+
* @return string The cell content
|
198 |
+
*/
|
199 |
+
function column_default( $item, $column_name ) {
|
200 |
+
$column_content = '';
|
201 |
+
|
202 |
+
// colmn_message is handled called directly by the list table by naming it colmn_$name. All other columns pass this function and might be named column_overridden_$column_name for further adaptation on output.
|
203 |
+
if ( method_exists( $this, 'column_overridden_' . $column_name ) ) {
|
204 |
+
$column_content = call_user_func( array( $this, 'column_overridden_' . $column_name ), $item );
|
205 |
+
} elseif( array_key_exists( $column_name, $item ) ) {
|
206 |
+
$column_content = $item[ $column_name ];
|
207 |
+
} else {
|
208 |
+
// If we don't know this column maybe a hook does - if no hook extracted data (string) out of the array we can avoid the output of 'Array()' (array).
|
209 |
+
$column_content = ( is_array( $res = apply_filters( WPML_Plugin::HOOK_LOGGING_COLUMNS_RENDER, $item, $column_name ) ) ) ? '' : $res;
|
210 |
+
}
|
211 |
+
|
212 |
+
return $this->sanitize_text($column_content);
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Sanitize text to remove unsafe html.
|
217 |
+
* @since 1.5.1
|
218 |
+
* @param string $message unsafe text.
|
219 |
+
* @return string safe text.
|
220 |
+
*/
|
221 |
+
function sanitize_text( $message ) {
|
222 |
+
return $this->messageSanitizer->sanitize($message);
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Renders the message column.
|
227 |
+
* @since 1.3
|
228 |
+
* @param array $item The current item.
|
229 |
+
* @return string
|
230 |
+
*/
|
231 |
+
function column_message( $item ) {
|
232 |
+
$content = $item['mail_id'];
|
233 |
+
$message = '<a class="wp-mail-logging-view-message button button-secondary" href="#" data-mail-id="' . esc_attr( $content ) . '">View</a>';
|
234 |
+
return $message;
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Renders the timestamp column.
|
239 |
+
* @since 1.5.0
|
240 |
+
* @param array $item The current item.
|
241 |
+
* @return string
|
242 |
+
*/
|
243 |
+
function column_overridden_timestamp( $item ) {
|
244 |
+
return date_i18n( apply_filters( 'wpml_get_date_time_format', '' ), strtotime( $item['timestamp'] ) );
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Renders the attachment column in compbat mode for mails prior 1.6.0.
|
249 |
+
* @since 1.6.0
|
250 |
+
* @param array $item The current item.
|
251 |
+
* @return string The attachment column.
|
252 |
+
*/
|
253 |
+
function column_attachments_compat_152( $item ) {
|
254 |
+
$attachment_append = '';
|
255 |
+
$attachments = explode( ',\n', $item['attachments'] );
|
256 |
+
$attachments = is_array( $attachments ) ? $attachments : array( $attachments );
|
257 |
+
foreach ( $attachments as $attachment ) {
|
258 |
+
// $attachment can be an empty string ''.
|
259 |
+
if ( ! empty( $attachment ) ) {
|
260 |
+
$filename = basename( $attachment );
|
261 |
+
$attachment_path = WP_CONTENT_DIR . $attachment;
|
262 |
+
$attachment_url = WP_CONTENT_URL . $attachment;
|
263 |
+
if ( is_file( $attachment_path ) ) {
|
264 |
+
$attachment_append .= '<a href="' . $attachment_url . '" title="' . $filename . '">' . WPML_Utils::generate_attachment_icon( $attachment_path ) . '</a> ';
|
265 |
+
} else {
|
266 |
+
$message = sprintf( __( 'Attachment %s is not present', 'wp-mail-logging' ), $filename );
|
267 |
+
$attachment_append .= '<i class="fa fa-times" title="' . $message . '"></i>';
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
return $attachment_append;
|
272 |
+
}
|
273 |
+
|
274 |
+
/**
|
275 |
+
* Renders the attachment column.
|
276 |
+
* @since 1.3
|
277 |
+
* @param array $item The current item.
|
278 |
+
* @return string The attachment column.
|
279 |
+
*/
|
280 |
+
function column_overridden_attachments( $item ) {
|
281 |
+
|
282 |
+
if ( version_compare( trim( $item ['plugin_version'] ), '1.6.0', '<' ) ) {
|
283 |
+
return $this->column_attachments_compat_152( $item );
|
284 |
+
}
|
285 |
+
|
286 |
+
$attachment_append = '';
|
287 |
+
$attachments = explode( ',\n', $item['attachments'] );
|
288 |
+
$attachments = is_array( $attachments ) ? $attachments : array( $attachments );
|
289 |
+
foreach ( $attachments as $attachment ) {
|
290 |
+
// $attachment can be an empty string ''.
|
291 |
+
if ( ! empty( $attachment ) ) {
|
292 |
+
$filename = basename( $attachment );
|
293 |
+
$basename = '/uploads';
|
294 |
+
$attachment_path = WP_CONTENT_DIR . $basename . $attachment;
|
295 |
+
$attachment_url = WP_CONTENT_URL . $basename . $attachment;
|
296 |
+
|
297 |
+
if ( is_file( $attachment_path ) ) {
|
298 |
+
$attachment_append .= '<a href="' . $attachment_url . '" title="' . $filename . '">' . WPML_Utils::generate_attachment_icon( $attachment_path ) . '</a> ';
|
299 |
+
} else {
|
300 |
+
$message = sprintf( __( 'Attachment %s is not present', 'wp-mail-logging' ), $filename );
|
301 |
+
$attachment_append .= '<i class="fa fa-times" title="' . $message . '"></i>';
|
302 |
+
}
|
303 |
+
}
|
304 |
+
}
|
305 |
+
return $attachment_append;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Renders the error column.
|
310 |
+
* @since 1.8.0
|
311 |
+
* @param $item
|
312 |
+
* @return string
|
313 |
+
*/
|
314 |
+
function column_overridden_error($item ) {
|
315 |
+
$error = $item['error'];
|
316 |
+
if( empty($error)) return "";
|
317 |
+
$errorMessage = is_array($error) ? join(',', $error) : $error;
|
318 |
+
return "<i class='fa fa-exclamation-circle' title='{$errorMessage}' aria-hidden='true'></i>";
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Renders all components of the mail.
|
323 |
+
* @since 1.3
|
324 |
+
* @param array $item The current item.
|
325 |
+
* @return string The mail as html
|
326 |
+
*/
|
327 |
+
function render_mail( $item ) {
|
328 |
+
$mailAppend = '';
|
329 |
+
foreach ( $item as $key => $value ) {
|
330 |
+
if ( array_key_exists( $key, $this->get_columns() ) && ! in_array( $key, $this->get_hidden_columns() ) ) {
|
331 |
+
$display = $this->get_columns();
|
332 |
+
$column_name = $key;
|
333 |
+
$title = "<span class=\"title\">{$display[$key]}: </span>";
|
334 |
+
$content = '';
|
335 |
+
if ( 'message' !== $column_name && method_exists( $this, 'column_' . $column_name ) ) {
|
336 |
+
if( 'error' === $column_name || 'attachments' === $column_name ) {
|
337 |
+
// don't render with icons and stuff, just plain
|
338 |
+
$content .= is_array($item[$column_name]) ? join("\n", $item[$column_name]) : $item[$column_name];
|
339 |
+
} else {
|
340 |
+
$content .= call_user_func( array( $this, 'column_' . $column_name ), $item );
|
341 |
+
}
|
342 |
+
} else {
|
343 |
+
$content .= $this->column_default( $item, $column_name );
|
344 |
+
}
|
345 |
+
$mailAppend .= $title . htmlentities( $content );
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
return $mailAppend;
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Renders all components of the mail.
|
354 |
+
* @since 1.6.0
|
355 |
+
* @param array $item The current item.
|
356 |
+
* @return string The mail as html
|
357 |
+
*/
|
358 |
+
function render_mail_html( $item ) {
|
359 |
+
$mailAppend = '';
|
360 |
+
foreach ( $item as $key => $value ) {
|
361 |
+
if ( array_key_exists( $key, $this->get_columns() ) && ! in_array( $key, $this->get_hidden_columns() ) ) {
|
362 |
+
$display = $this->get_columns();
|
363 |
+
$column_name = $key;
|
364 |
+
$mailAppend .= "<span class=\"title\">{$display[$key]}: </span>";
|
365 |
+
if ( 'message' !== $column_name && method_exists( $this, 'column_' . $column_name ) ) {
|
366 |
+
$mailAppend .= call_user_func( array( $this, 'column_' . $column_name ), $item );
|
367 |
+
} else {
|
368 |
+
$mailAppend .= $this->column_default( $item, $column_name );
|
369 |
+
}
|
370 |
+
}
|
371 |
+
}
|
372 |
+
return $mailAppend;
|
373 |
+
}
|
374 |
+
/**
|
375 |
+
* Defines available bulk actions.
|
376 |
+
* @since 1.0
|
377 |
+
* @see WP_List_Table::get_bulk_actions()
|
378 |
+
*/
|
379 |
+
function get_bulk_actions() {
|
380 |
+
$actions = array(
|
381 |
+
'delete' => 'Delete',
|
382 |
+
'resend' => 'Resend'
|
383 |
+
);
|
384 |
+
return $actions;
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Processes bulk actions.
|
389 |
+
* @since 1.0
|
390 |
+
*/
|
391 |
+
function process_bulk_action() {
|
392 |
+
if ( false === $this->current_action() ) {
|
393 |
+
return;
|
394 |
+
}
|
395 |
+
|
396 |
+
if ( check_admin_referer( WPML_Email_Log_List::NONCE_LIST_TABLE, WPML_Email_Log_List::NONCE_LIST_TABLE . '_nonce' ) ) {
|
397 |
+
$name = $this->_args['singular'];
|
398 |
+
|
399 |
+
// Detect when a bulk action is being triggered.
|
400 |
+
if ( 'delete' === $this->current_action() ) {
|
401 |
+
foreach ( $_REQUEST[$name] as $item_id ) {
|
402 |
+
$mail = Mail::find_one( $item_id );
|
403 |
+
if ( false !== $mail ) {
|
404 |
+
$mail->delete();
|
405 |
+
}
|
406 |
+
}
|
407 |
+
} else if ( 'resend' == $this->current_action() ) {
|
408 |
+
foreach ( $_REQUEST[$name] as $item_id ) {
|
409 |
+
$mail = Mail::find_one( $item_id );
|
410 |
+
if ( false !== $mail ) {
|
411 |
+
$this->resend_email( $mail );
|
412 |
+
}
|
413 |
+
}
|
414 |
+
}
|
415 |
+
}
|
416 |
+
}
|
417 |
+
|
418 |
+
/**
|
419 |
+
* Send logged email via wp_mail
|
420 |
+
* @param Mail $mail the email object to resend
|
421 |
+
* @since 1.8.0
|
422 |
+
*/
|
423 |
+
function resend_email( $mail ) {
|
424 |
+
$this->emailResender->resendMail( $mail );
|
425 |
+
}
|
426 |
+
|
427 |
+
/**
|
428 |
+
* Render the cb column
|
429 |
+
* @since 1.0
|
430 |
+
* @param array $item The current item.
|
431 |
+
* @return string the rendered cb cell content
|
432 |
+
*/
|
433 |
+
function column_cb($item) {
|
434 |
+
$name = $this->_args['singular'];
|
435 |
+
return sprintf(
|
436 |
+
'<input type="checkbox" name="%1$s[]" value="%2$s" />', $name, $item['mail_id']
|
437 |
+
);
|
438 |
+
}
|
439 |
+
|
440 |
+
/**
|
441 |
+
* Define the sortable columns
|
442 |
+
* @since 1.0
|
443 |
+
* @return array
|
444 |
+
*/
|
445 |
+
function get_sortable_columns() {
|
446 |
+
return array(
|
447 |
+
// Description: column_name => array( 'display_name', true[asc] | false[desc] ).
|
448 |
+
'mail_id' => array( 'mail_id', false ),
|
449 |
+
'timestamp' => array( 'timestamp', true ),
|
450 |
+
'host' => array( 'host', true ),
|
451 |
+
'receiver' => array( 'receiver', true ),
|
452 |
+
'subject' => array( 'subject', true ),
|
453 |
+
'message' => array( 'message', true ),
|
454 |
+
'headers' => array( 'headers', true ),
|
455 |
+
'attachments' => array( 'attachments', true ),
|
456 |
+
'plugin_version'=> array( 'plugin_version', true ),
|
457 |
+
);
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* Ajax function to retrieve rendered mail in certain format.
|
462 |
+
* @since 1.6.0
|
463 |
+
*/
|
464 |
+
public static function ajax_wpml_email_get() {
|
465 |
+
$formats = is_array( $additional = apply_filters( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, array() ) ) ? $additional : array();
|
466 |
+
|
467 |
+
check_ajax_referer( 'wpml-modal-show', 'ajax_nonce', true );
|
468 |
+
|
469 |
+
if( ! isset( $_POST['id'] ) )
|
470 |
+
wp_die( "huh?" );
|
471 |
+
$id = intval( $_POST['id'] );
|
472 |
+
|
473 |
+
$format_requested = isset( $_POST['format'] ) ? $_POST['format'] : 'html';
|
474 |
+
if ( ! in_array( $format_requested, $formats ) ) {
|
475 |
+
echo "Unsupported Format. Using html as fallback.";
|
476 |
+
$format_requested = WPML_Utils::sanitize_expected_value($format_requested, $formats, 'html');
|
477 |
+
}
|
478 |
+
$mail = Mail::find_one( $id );
|
479 |
+
/* @var $instance WPML_Email_Log_List */
|
480 |
+
$instance = WPML_Init::getInstance()->getService( 'emailLogList' );
|
481 |
+
$mailAppend = '';
|
482 |
+
switch( $format_requested ) {
|
483 |
+
case 'html': {
|
484 |
+
$mailAppend .= $instance->render_mail_html( $mail->to_array() );
|
485 |
+
break;
|
486 |
+
}
|
487 |
+
case 'raw': {
|
488 |
+
$mailAppend .= $instance->render_mail( $mail->to_array() );
|
489 |
+
break;
|
490 |
+
}
|
491 |
+
case 'json': {
|
492 |
+
if( stristr( str_replace(' ', '', $mail->get_headers()), "Content-Type:text/html")) {
|
493 |
+
// Fallback to raw in case it is a html mail
|
494 |
+
$mailAppend .= sprintf("<span class='info'>%s</span>", __("Fallback to raw format because html is not convertible to json.", 'wp-mail-logging' ) );
|
495 |
+
$mailAppend .= $instance->render_mail( $mail->to_array() );
|
496 |
+
} else {
|
497 |
+
$mailAppend .= "<pre>" . json_encode( $mail->to_array(), JSON_PRETTY_PRINT ) . "</pre>";
|
498 |
+
}
|
499 |
+
break;
|
500 |
+
}
|
501 |
+
default:
|
502 |
+
$mailAppend .= apply_filters( WPML_Plugin::HOOK_LOGGING_FORMAT_CONTENT . "_{$format_requested}", $mail->to_array() );
|
503 |
+
break;
|
504 |
+
}
|
505 |
+
|
506 |
+
echo $instance->sanitize_text($mailAppend);
|
507 |
+
wp_die(); // this is required to terminate immediately and return a proper response
|
508 |
+
}
|
509 |
+
}
|
|
WPML_Email_Resender.php → src/WPML_Email_Resender.php
RENAMED
@@ -1,29 +1,29 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace No3x\WPML;
|
4 |
-
|
5 |
-
use No3x\WPML\Model\WPML_Mail;
|
6 |
-
|
7 |
-
class WPML_Email_Resender {
|
8 |
-
|
9 |
-
/** @var WPML_Email_Dispatcher $dispatcher */
|
10 |
-
private $dispatcher;
|
11 |
-
|
12 |
-
public function __construct($dispatcher) {
|
13 |
-
$this->dispatcher = $dispatcher;
|
14 |
-
}
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Resend mail
|
18 |
-
* @param WPML_Mail $mail
|
19 |
-
*/
|
20 |
-
public function resendMail($mail) {
|
21 |
-
$headers = explode( "\\n", str_replace( "\\r\\n", "\\n", $mail->get_headers() ) );
|
22 |
-
$headers = array_map(function ($header) {
|
23 |
-
return rtrim($header, ",");
|
24 |
-
}, $headers);
|
25 |
-
|
26 |
-
$this->dispatcher->dispatch($mail->get_receiver(), $mail->get_subject(), $mail->get_message(), $headers, $mail->get_attachments() );
|
27 |
-
}
|
28 |
-
|
29 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
use No3x\WPML\Model\WPML_Mail;
|
6 |
+
|
7 |
+
class WPML_Email_Resender {
|
8 |
+
|
9 |
+
/** @var WPML_Email_Dispatcher $dispatcher */
|
10 |
+
private $dispatcher;
|
11 |
+
|
12 |
+
public function __construct($dispatcher) {
|
13 |
+
$this->dispatcher = $dispatcher;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Resend mail
|
18 |
+
* @param WPML_Mail $mail
|
19 |
+
*/
|
20 |
+
public function resendMail($mail) {
|
21 |
+
$headers = explode( "\\n", str_replace( "\\r\\n", "\\n", $mail->get_headers() ) );
|
22 |
+
$headers = array_map(function ($header) {
|
23 |
+
return rtrim($header, ",");
|
24 |
+
}, $headers);
|
25 |
+
|
26 |
+
$this->dispatcher->dispatch($mail->get_receiver(), $mail->get_subject(), $mail->get_message(), $headers, $mail->get_attachments() );
|
27 |
+
}
|
28 |
+
|
29 |
+
}
|
src/WPML_Hook_Remover.php
ADDED
@@ -0,0 +1,93 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class for removing hooks by class name
|
7 |
+
* https://gist.github.com/tripflex/c6518efc1753cf2392559866b4bd1a53
|
8 |
+
*/
|
9 |
+
class WPML_Hook_Remover {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Remove Class Filter Without Access to Class Object
|
13 |
+
*
|
14 |
+
* In order to use the core WordPress remove_filter() on a filter added with the callback
|
15 |
+
* to a class, you either have to have access to that class object, or it has to be a call
|
16 |
+
* to a static method. This method allows you to remove filters with a callback to a class
|
17 |
+
* you don't have access to.
|
18 |
+
*
|
19 |
+
* Works with WordPress 1.2+ (4.7+ support added 9-19-2016)
|
20 |
+
* Updated 2-27-2017 to use internal WordPress removal for 4.7+ (to prevent PHP warnings output)
|
21 |
+
*
|
22 |
+
* @param string $tag Filter to remove
|
23 |
+
* @param string $class_name Class name for the filter's callback
|
24 |
+
* @param string $method_name Method name for the filter's callback
|
25 |
+
* @param int $priority Priority of the filter (default 10)
|
26 |
+
*
|
27 |
+
* @return bool Whether the function is removed.
|
28 |
+
*/
|
29 |
+
function remove_class_hook( $tag, $class_name = '', $method_name = '', $priority = 10 ) {
|
30 |
+
global $wp_filter;
|
31 |
+
// Check that filter actually exists first
|
32 |
+
if ( ! isset( $wp_filter[ $tag ] ) ) {
|
33 |
+
return FALSE;
|
34 |
+
}
|
35 |
+
/**
|
36 |
+
* If filter config is an object, means we're using WordPress 4.7+ and the config is no longer
|
37 |
+
* a simple array, rather it is an object that implements the ArrayAccess interface.
|
38 |
+
*
|
39 |
+
* To be backwards compatible, we set $callbacks equal to the correct array as a reference (so $wp_filter is updated)
|
40 |
+
*
|
41 |
+
* @see https://make.wordpress.org/core/2016/09/08/wp_hook-next-generation-actions-and-filters/
|
42 |
+
*/
|
43 |
+
if ( is_object( $wp_filter[ $tag ] ) && isset( $wp_filter[ $tag ]->callbacks ) ) {
|
44 |
+
// Create $fob object from filter tag, to use below
|
45 |
+
$fob = $wp_filter[ $tag ];
|
46 |
+
$callbacks = &$wp_filter[ $tag ]->callbacks;
|
47 |
+
} else {
|
48 |
+
$callbacks = &$wp_filter[ $tag ];
|
49 |
+
}
|
50 |
+
// Exit if there aren't any callbacks for specified priority
|
51 |
+
if ( ! isset( $callbacks[ $priority ] ) || empty( $callbacks[ $priority ] ) ) {
|
52 |
+
return FALSE;
|
53 |
+
}
|
54 |
+
// Loop through each filter for the specified priority, looking for our class & method
|
55 |
+
foreach ( (array) $callbacks[ $priority ] as $filter_id => $filter ) {
|
56 |
+
// Filter should always be an array - array( $this, 'method' ), if not goto next
|
57 |
+
if ( ! isset( $filter['function'] ) || ! is_array( $filter['function'] ) ) {
|
58 |
+
continue;
|
59 |
+
}
|
60 |
+
// If first value in array is not an object, it can't be a class
|
61 |
+
if ( ! is_object( $filter['function'][0] ) ) {
|
62 |
+
continue;
|
63 |
+
}
|
64 |
+
// Method doesn't match the one we're looking for, goto next
|
65 |
+
if ( $filter['function'][1] !== $method_name ) {
|
66 |
+
continue;
|
67 |
+
}
|
68 |
+
// Method matched, now let's check the Class
|
69 |
+
if ( get_class( $filter['function'][0] ) === $class_name ) {
|
70 |
+
// WordPress 4.7+ use core remove_filter() since we found the class object
|
71 |
+
if ( isset( $fob ) ) {
|
72 |
+
// Handles removing filter, reseting callback priority keys mid-iteration, etc.
|
73 |
+
$fob->remove_filter( $tag, $filter['function'], $priority );
|
74 |
+
} else {
|
75 |
+
// Use legacy removal process (pre 4.7)
|
76 |
+
unset( $callbacks[ $priority ][ $filter_id ] );
|
77 |
+
// and if it was the only filter in that priority, unset that priority
|
78 |
+
if ( empty( $callbacks[ $priority ] ) ) {
|
79 |
+
unset( $callbacks[ $priority ] );
|
80 |
+
}
|
81 |
+
// and if the only filter for that tag, set the tag to an empty array
|
82 |
+
if ( empty( $callbacks ) ) {
|
83 |
+
$callbacks = array();
|
84 |
+
}
|
85 |
+
// Remove this filter from merged_filters, which specifies if filters have been sorted
|
86 |
+
unset( $GLOBALS['merged_filters'][ $tag ] );
|
87 |
+
}
|
88 |
+
return TRUE;
|
89 |
+
}
|
90 |
+
}
|
91 |
+
return FALSE;
|
92 |
+
}
|
93 |
+
}
|
WPML_Init.php → src/WPML_Init.php
RENAMED
@@ -1,158 +1,161 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
-
|
5 |
-
This file is part of WordPress Plugin Template for WordPress.
|
6 |
-
|
7 |
-
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
-
it under the terms of the GNU General Public License as published by
|
9 |
-
the Free Software Foundation, either version 3 of the License, or
|
10 |
-
(at your option) any later version.
|
11 |
-
|
12 |
-
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
GNU General Public License for more details.
|
16 |
-
|
17 |
-
You should have received a copy of the GNU General Public License
|
18 |
-
along with Contact Form to Database Extension.
|
19 |
-
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
-
*/
|
21 |
-
|
22 |
-
namespace No3x\WPML;
|
23 |
-
|
24 |
-
use No3x\WPML\Settings\WPML_Redux_Framework_config;
|
25 |
-
|
26 |
-
// Exit if accessed directly.
|
27 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
28 |
-
|
29 |
-
class WPML_Init {
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @var Singleton The reference to *Singleton* instance of this class
|
33 |
-
*/
|
34 |
-
private static $instance;
|
35 |
-
/**
|
36 |
-
* @var WPML_DI_Container The DI Container
|
37 |
-
*/
|
38 |
-
private $container;
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Returns the *Singleton* instance of this class.
|
42 |
-
*
|
43 |
-
* @return WPML_Init The *Singleton* instance.
|
44 |
-
*/
|
45 |
-
public static function getInstance() {
|
46 |
-
if (null === static::$instance) {
|
47 |
-
static::$instance = new static();
|
48 |
-
}
|
49 |
-
|
50 |
-
return static::$instance;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Protected constructor to prevent creating a new instance of the
|
55 |
-
* *Singleton* via the `new` operator from outside of this class.
|
56 |
-
*/
|
57 |
-
protected function __construct() {
|
58 |
-
$this->container = new WPML_DI_Container();
|
59 |
-
}
|
60 |
-
|
61 |
-
public function getClosure() {
|
62 |
-
return function ($prop) {
|
63 |
-
return $this->$prop;
|
64 |
-
};
|
65 |
-
}
|
66 |
-
|
67 |
-
public function init( $file ) {
|
68 |
-
|
69 |
-
$this->container['plugin'] = function ($c) {
|
70 |
-
return new WPML_Plugin();
|
71 |
-
};
|
72 |
-
$this->container['plugin-meta'] = function ($c) {
|
73 |
-
/* @var $plugin WPML_Plugin */
|
74 |
-
$plugin = $c['plugin'];
|
75 |
-
return array(
|
76 |
-
'path' => realpath( plugin_dir_path( __FILE__ ) ) . DIRECTORY_SEPARATOR,
|
77 |
-
'uri' => plugin_dir_url( __FILE__ ),
|
78 |
-
'display_name' => $plugin->getPluginDisplayName(),
|
79 |
-
'slug' => $plugin->getPluginSlug(),
|
80 |
-
'main_file' => $plugin->getMainPluginFileName(),
|
81 |
-
'description' => $plugin->getPluginHeaderValue( 'Description' ),
|
82 |
-
'version' => $plugin->getVersion(),
|
83 |
-
'version_installed' => $plugin->getVersionSaved(),
|
84 |
-
'author_name' => $plugin->getPluginHeaderValue( 'Author' ),
|
85 |
-
'author_uri' => $plugin->getPluginHeaderValue( 'Author URI' ),
|
86 |
-
'wp_uri' => $plugin->getPluginHeaderValue( 'Plugin URI' ),
|
87 |
-
'support_uri' => $plugin->getPluginHeaderValue( 'Support URI' ),
|
88 |
-
'license' => $plugin->getPluginHeaderValue( 'License' ),
|
89 |
-
);
|
90 |
-
};
|
91 |
-
$this->container['emailLogList-supported-formats'] = function ($c) {
|
92 |
-
return array(
|
93 |
-
'html',
|
94 |
-
'raw',
|
95 |
-
'json'
|
96 |
-
);
|
97 |
-
};
|
98 |
-
$this->container['emailLogList'] = function ($c) {
|
99 |
-
return new WPML_Email_Log_List( $c['emailLogList-supported-formats'], $c['emailResender'] );
|
100 |
-
};
|
101 |
-
$this->container['emailResender'] = function ($c) {
|
102 |
-
return new WPML_Email_Resender( $c['emailDispatcher'] );
|
103 |
-
};
|
104 |
-
$this->container['emailDispatcher'] = function () {
|
105 |
-
return new WPML_Email_Dispatcher();
|
106 |
-
};
|
107 |
-
$this->container['redux'] = function ($c) {
|
108 |
-
return new WPML_Redux_Framework_config( $c['plugin-meta'] );
|
109 |
-
};
|
110 |
-
$this->container['logRotation'] = function ($c) {
|
111 |
-
return new WPML_LogRotation( $c['plugin-meta'] );
|
112 |
-
};
|
113 |
-
$this->container['
|
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 |
-
$this->container['plugin']->
|
140 |
-
}
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
// Register the Plugin
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
}
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
+
|
5 |
+
This file is part of WordPress Plugin Template for WordPress.
|
6 |
+
|
7 |
+
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
+
it under the terms of the GNU General Public License as published by
|
9 |
+
the Free Software Foundation, either version 3 of the License, or
|
10 |
+
(at your option) any later version.
|
11 |
+
|
12 |
+
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
GNU General Public License for more details.
|
16 |
+
|
17 |
+
You should have received a copy of the GNU General Public License
|
18 |
+
along with Contact Form to Database Extension.
|
19 |
+
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
+
*/
|
21 |
+
|
22 |
+
namespace No3x\WPML;
|
23 |
+
|
24 |
+
use No3x\WPML\Settings\WPML_Redux_Framework_config;
|
25 |
+
|
26 |
+
// Exit if accessed directly.
|
27 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
28 |
+
|
29 |
+
class WPML_Init {
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var Singleton The reference to *Singleton* instance of this class
|
33 |
+
*/
|
34 |
+
private static $instance;
|
35 |
+
/**
|
36 |
+
* @var WPML_DI_Container The DI Container
|
37 |
+
*/
|
38 |
+
private $container;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Returns the *Singleton* instance of this class.
|
42 |
+
*
|
43 |
+
* @return WPML_Init The *Singleton* instance.
|
44 |
+
*/
|
45 |
+
public static function getInstance() {
|
46 |
+
if (null === static::$instance) {
|
47 |
+
static::$instance = new static();
|
48 |
+
}
|
49 |
+
|
50 |
+
return static::$instance;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Protected constructor to prevent creating a new instance of the
|
55 |
+
* *Singleton* via the `new` operator from outside of this class.
|
56 |
+
*/
|
57 |
+
protected function __construct() {
|
58 |
+
$this->container = new WPML_DI_Container();
|
59 |
+
}
|
60 |
+
|
61 |
+
public function getClosure() {
|
62 |
+
return function ($prop) {
|
63 |
+
return $this->$prop;
|
64 |
+
};
|
65 |
+
}
|
66 |
+
|
67 |
+
public function init( $file ) {
|
68 |
+
|
69 |
+
$this->container['plugin'] = function ($c) {
|
70 |
+
return new WPML_Plugin();
|
71 |
+
};
|
72 |
+
$this->container['plugin-meta'] = function ($c) {
|
73 |
+
/* @var $plugin WPML_Plugin */
|
74 |
+
$plugin = $c['plugin'];
|
75 |
+
return array(
|
76 |
+
'path' => realpath( plugin_dir_path( __FILE__ ) ) . DIRECTORY_SEPARATOR,
|
77 |
+
'uri' => plugin_dir_url( __FILE__ ),
|
78 |
+
'display_name' => $plugin->getPluginDisplayName(),
|
79 |
+
'slug' => $plugin->getPluginSlug(),
|
80 |
+
'main_file' => $plugin->getMainPluginFileName(),
|
81 |
+
'description' => $plugin->getPluginHeaderValue( 'Description' ),
|
82 |
+
'version' => $plugin->getVersion(),
|
83 |
+
'version_installed' => $plugin->getVersionSaved(),
|
84 |
+
'author_name' => $plugin->getPluginHeaderValue( 'Author' ),
|
85 |
+
'author_uri' => $plugin->getPluginHeaderValue( 'Author URI' ),
|
86 |
+
'wp_uri' => $plugin->getPluginHeaderValue( 'Plugin URI' ),
|
87 |
+
'support_uri' => $plugin->getPluginHeaderValue( 'Support URI' ),
|
88 |
+
'license' => $plugin->getPluginHeaderValue( 'License' ),
|
89 |
+
);
|
90 |
+
};
|
91 |
+
$this->container['emailLogList-supported-formats'] = function ($c) {
|
92 |
+
return array(
|
93 |
+
'html',
|
94 |
+
'raw',
|
95 |
+
'json'
|
96 |
+
);
|
97 |
+
};
|
98 |
+
$this->container['emailLogList'] = function ($c) {
|
99 |
+
return new WPML_Email_Log_List( $c['emailLogList-supported-formats'], $c['emailResender'] );
|
100 |
+
};
|
101 |
+
$this->container['emailResender'] = function ($c) {
|
102 |
+
return new WPML_Email_Resender( $c['emailDispatcher'] );
|
103 |
+
};
|
104 |
+
$this->container['emailDispatcher'] = function () {
|
105 |
+
return new WPML_Email_Dispatcher();
|
106 |
+
};
|
107 |
+
$this->container['redux'] = function ($c) {
|
108 |
+
return new WPML_Redux_Framework_config( $c['plugin-meta'] );
|
109 |
+
};
|
110 |
+
$this->container['logRotation'] = function ($c) {
|
111 |
+
return new WPML_LogRotation( $c['plugin-meta'] );
|
112 |
+
};
|
113 |
+
$this->container['privacyController'] = function ($c) {
|
114 |
+
return new WPML_PrivacyController($c['plugin-meta']);
|
115 |
+
};
|
116 |
+
$this->container['api'] = function ($c) {
|
117 |
+
// Uncomment for an API Example
|
118 |
+
// return new WPML_API_Example();
|
119 |
+
};
|
120 |
+
$this->container->addActionsAndFilters();
|
121 |
+
|
122 |
+
add_filter( 'wpml_get_di_container', function() {
|
123 |
+
return $this->container;
|
124 |
+
} );
|
125 |
+
|
126 |
+
add_filter( 'wpml_get_di_service', function( $service ) {
|
127 |
+
return $this->getService( $service );
|
128 |
+
} );
|
129 |
+
|
130 |
+
/*
|
131 |
+
* Install the plugin
|
132 |
+
* NOTE: this file gets run each time you *activate* the plugin.
|
133 |
+
* So in WP when you "install" the plugin, all that does it dump its files in the plugin-templates directory
|
134 |
+
* but it does not call any of its code.
|
135 |
+
* So here, the plugin tracks whether or not it has run its install operation, and we ensure it is run only once
|
136 |
+
* on the first activation
|
137 |
+
*/
|
138 |
+
if ( ! $this->container['plugin']->isInstalled() ) {
|
139 |
+
$this->container['plugin']->install();
|
140 |
+
} else {
|
141 |
+
// Perform any version-upgrade activities prior to activation (e.g. database changes).
|
142 |
+
$this->container['plugin']->upgrade();
|
143 |
+
}
|
144 |
+
|
145 |
+
if ( ! $file ) {
|
146 |
+
$file = __FILE__;
|
147 |
+
}
|
148 |
+
// Register the Plugin Activation Hook.
|
149 |
+
register_activation_hook( $file, array( &$this->container['plugin'], 'activate' ) );
|
150 |
+
|
151 |
+
// Register the Plugin Deactivation Hook.
|
152 |
+
register_deactivation_hook( $file, array( &$this->container['plugin'], 'deactivate' ) );
|
153 |
+
}
|
154 |
+
|
155 |
+
public function getService( $key ) {
|
156 |
+
if( in_array( $key, $this->container->keys() ) ) {
|
157 |
+
return $this->container[ $key ];
|
158 |
+
}
|
159 |
+
throw new \Exception("Service '{$key}' is not registered");
|
160 |
+
}
|
161 |
+
}
|
WPML_InstallIndicator.php → src/WPML_InstallIndicator.php
RENAMED
@@ -1,171 +1,186 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
-
|
5 |
-
This file is part of WordPress Plugin Template for WordPress.
|
6 |
-
|
7 |
-
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
-
it under the terms of the GNU General Public License as published by
|
9 |
-
the Free Software Foundation, either version 3 of the License, or
|
10 |
-
(at your option) any later version.
|
11 |
-
|
12 |
-
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
GNU General Public License for more details.
|
16 |
-
|
17 |
-
You should have received a copy of the GNU General Public License
|
18 |
-
along with Contact Form to Database Extension.
|
19 |
-
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
-
*/
|
21 |
-
|
22 |
-
namespace No3x\WPML;
|
23 |
-
|
24 |
-
// Exit if accessed directly.
|
25 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
-
|
27 |
-
class WPML_InstallIndicator extends WPML_OptionsManager {
|
28 |
-
|
29 |
-
const optionInstalled = '_installed';
|
30 |
-
const optionVersion = '_version';
|
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 |
-
|
146 |
-
|
147 |
-
*
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
+
|
5 |
+
This file is part of WordPress Plugin Template for WordPress.
|
6 |
+
|
7 |
+
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
+
it under the terms of the GNU General Public License as published by
|
9 |
+
the Free Software Foundation, either version 3 of the License, or
|
10 |
+
(at your option) any later version.
|
11 |
+
|
12 |
+
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
GNU General Public License for more details.
|
16 |
+
|
17 |
+
You should have received a copy of the GNU General Public License
|
18 |
+
along with Contact Form to Database Extension.
|
19 |
+
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
+
*/
|
21 |
+
|
22 |
+
namespace No3x\WPML;
|
23 |
+
|
24 |
+
// Exit if accessed directly.
|
25 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
+
|
27 |
+
class WPML_InstallIndicator extends WPML_OptionsManager {
|
28 |
+
|
29 |
+
const optionInstalled = '_installed';
|
30 |
+
const optionVersion = '_version';
|
31 |
+
const CACHE_GROUP = 'wp_mail_logging';
|
32 |
+
const CACHE_INSTALLED_KEY = 'installed';
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Checks if the plugin is installed.
|
36 |
+
* @return bool indicating if the plugin is installed already
|
37 |
+
*/
|
38 |
+
public function isInstalled() {
|
39 |
+
$installed = false;
|
40 |
+
|
41 |
+
// We don't use the cached value, only its presence.
|
42 |
+
// This is because we never cache not installed state.
|
43 |
+
wp_cache_get(self::CACHE_INSTALLED_KEY, self::CACHE_GROUP, false, $installed);
|
44 |
+
if (!$installed) {
|
45 |
+
global $wpdb;
|
46 |
+
|
47 |
+
$mails = $this->getTablename('mails');
|
48 |
+
$query = $wpdb->query("SHOW TABLES LIKE \"$mails\"");
|
49 |
+
$installed = (bool) $query;
|
50 |
+
|
51 |
+
if ($installed) {
|
52 |
+
wp_cache_set(self::CACHE_INSTALLED_KEY, true, self::CACHE_GROUP, 3600);
|
53 |
+
}
|
54 |
+
}
|
55 |
+
return $installed;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Set a version string in the options. This is useful if you install upgrade and
|
60 |
+
* need to check if an older version was installed to see if you need to do certain
|
61 |
+
* upgrade housekeeping (e.g. changes to DB schema).
|
62 |
+
* @return null
|
63 |
+
*/
|
64 |
+
protected function getVersionSaved() {
|
65 |
+
return $this->getOption( self::optionVersion );
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Set a version string in the options.
|
70 |
+
* need to check if
|
71 |
+
* @param string $version string best practice: use a dot-delimited string like '1.2.3' so version strings can be easily
|
72 |
+
* compared using version_compare (http://php.net/manual/en/function.version-compare.php)
|
73 |
+
* @return null
|
74 |
+
*/
|
75 |
+
protected function setVersionSaved( $version ) {
|
76 |
+
return $this->updateOption( self::optionVersion, $version );
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* @return string name of the main plugin file that has the header section with
|
81 |
+
* "Plugin Name", "Version", "Description", "Text Domain", etc.
|
82 |
+
*/
|
83 |
+
protected function getMainPluginFileName() {
|
84 |
+
return basename( dirname( __FILE__ ) ) . 'php';
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Get a value for input key in the header section of main plugin file.
|
89 |
+
* E.g. "Plugin Name", "Version", "Description", "Text Domain", etc.
|
90 |
+
* @param $key string plugin header key
|
91 |
+
* @return string if found, otherwise null
|
92 |
+
*/
|
93 |
+
public function getPluginHeaderValue($key) {
|
94 |
+
// Read the string from the comment header of the main plugin file.
|
95 |
+
$data = file_get_contents( $this->getPluginDir() . DIRECTORY_SEPARATOR . $this->getMainPluginFileName() );
|
96 |
+
$match = array();
|
97 |
+
preg_match( '/' . $key . ':\s*(.*)/', $data, $match );
|
98 |
+
if ( count( $match ) >= 1 ) {
|
99 |
+
return $match[1];
|
100 |
+
}
|
101 |
+
return null;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* If your subclass of this class lives in a different directory,
|
106 |
+
* override this method with the exact same code. Since __FILE__ will
|
107 |
+
* be different, you will then get the right dir returned.
|
108 |
+
* @return string
|
109 |
+
*/
|
110 |
+
protected function getPluginDir() {
|
111 |
+
return dirname( dirname( __FILE__ ) );
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Version of this code.
|
116 |
+
* Best practice: define version strings to be easily compared using version_compare()
|
117 |
+
* (http://php.net/manual/en/function.version-compare.php)
|
118 |
+
* NOTE: You should manually make this match the SVN tag for your main plugin file 'Version' release and 'Stable tag' in readme.txt
|
119 |
+
* @return string
|
120 |
+
*/
|
121 |
+
public function getVersion() {
|
122 |
+
return $this->getPluginHeaderValue( 'Version' );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Useful when checking for upgrades, can tell if the currently installed version is earlier than the
|
127 |
+
* newly installed code. This case indicates that an upgrade has been installed and this is the first time it
|
128 |
+
* has been activated, so any upgrade actions should be taken.
|
129 |
+
* @return bool true if the version saved in the options is earlier than the version declared in getVersion().
|
130 |
+
* true indicates that new code is installed and this is the first time it is activated, so upgrade actions
|
131 |
+
* should be taken. Assumes that version string comparable by version_compare, examples: '1', '1.1', '1.1.1', '2.0', etc.
|
132 |
+
*/
|
133 |
+
public function isInstalledCodeAnUpgrade() {
|
134 |
+
return $this->isSavedVersionLessThan( $this->getVersion() );
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Used to see if the installed code is an earlier version than the input version
|
139 |
+
* @param string $aVersion version string.
|
140 |
+
* @return bool true if the saved version is earlier (by natural order) than the input version
|
141 |
+
*/
|
142 |
+
public function isSavedVersionLessThan( $aVersion ) {
|
143 |
+
return $this->isVersionLessThan( $this->getVersionSaved(), $aVersion );
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Used to see if the installed code is the same or earlier than the input version.
|
148 |
+
* Useful when checking for an upgrade. If you haven't specified the number of the newer version yet,
|
149 |
+
* but the last version (installed) was 2.3 (for example) you could check if
|
150 |
+
* For example, $this->isSavedVersionLessThanEqual('2.3') == true indicates that the saved version is not upgraded
|
151 |
+
* past 2.3 yet and therefore you would perform some appropriate upgrade action.
|
152 |
+
* @param string $aVersion version string.
|
153 |
+
* @return bool true if the saved version is earlier (by natural order) than the input version
|
154 |
+
*/
|
155 |
+
public function isSavedVersionLessThanEqual( $aVersion ) {
|
156 |
+
return $this->isVersionLessThanEqual( $this->getVersionSaved(), $aVersion );
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* @param string $version1 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
161 |
+
* @param string $version2 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
162 |
+
* @return bool true if version_compare of $versions1 and $version2 shows $version1 as the same or earlier
|
163 |
+
*/
|
164 |
+
public function isVersionLessThanEqual( $version1, $version2 ) {
|
165 |
+
return ( version_compare( $version1, $version2 ) <= 0 );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @param string $version1 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
170 |
+
* @param string $version2 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
171 |
+
* @return bool true if version_compare of $versions1 and $version2 shows $version1 as earlier
|
172 |
+
*/
|
173 |
+
public function isVersionLessThan( $version1, $version2 ) {
|
174 |
+
return ( version_compare( $version1, $version2 ) < 0 );
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Record the installed version to options.
|
179 |
+
* This helps track was version is installed so when an upgrade is installed, it should call this when finished
|
180 |
+
* upgrading to record the new current version
|
181 |
+
* @return void
|
182 |
+
*/
|
183 |
+
protected function saveInstalledVersion() {
|
184 |
+
$this->setVersionSaved( $this->getVersion() );
|
185 |
+
}
|
186 |
+
}
|
WPML_LifeCycle.php → src/WPML_LifeCycle.php
RENAMED
@@ -1,211 +1,211 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
-
|
5 |
-
This file is part of WordPress Plugin Template for WordPress.
|
6 |
-
|
7 |
-
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
-
it under the terms of the GNU General Public License as published by
|
9 |
-
the Free Software Foundation, either version 3 of the License, or
|
10 |
-
(at your option) any later version.
|
11 |
-
|
12 |
-
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
GNU General Public License for more details.
|
16 |
-
|
17 |
-
You should have received a copy of the GNU General Public License
|
18 |
-
along with Contact Form to Database Extension.
|
19 |
-
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
-
*/
|
21 |
-
|
22 |
-
namespace No3x\WPML;
|
23 |
-
|
24 |
-
// Exit if accessed directly.
|
25 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
-
|
27 |
-
class WPML_LifeCycle extends WPML_InstallIndicator {
|
28 |
-
|
29 |
-
public function install() {
|
30 |
-
|
31 |
-
// Initialize Plugin Options
|
32 |
-
$this->initOptions();
|
33 |
-
|
34 |
-
// Initialize DB Tables used by the plugin
|
35 |
-
$this->installDatabaseTables();
|
36 |
-
|
37 |
-
// Other Plugin initialization - for the plugin writer to override as needed
|
38 |
-
$this->otherInstall();
|
39 |
-
|
40 |
-
// Record the installed version
|
41 |
-
$this->saveInstalledVersion();
|
42 |
-
|
43 |
-
}
|
44 |
-
|
45 |
-
public function uninstall() {
|
46 |
-
$this->otherUninstall();
|
47 |
-
|
48 |
-
if ( $this->getSetting('delete-on-deactivation', false) == true ) {
|
49 |
-
//TOOD: is multi site?
|
50 |
-
$this->unInstallDatabaseTables();
|
51 |
-
$this->deleteSavedOptions();
|
52 |
-
$this->deleteVersionOption();
|
53 |
-
}
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Perform any version-upgrade activities prior to activation (e.g. database changes)
|
58 |
-
* @return void
|
59 |
-
*/
|
60 |
-
public function upgrade() {
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* See: http://plugin.michael-simpson.com/?page_id=105
|
65 |
-
* @return void
|
66 |
-
*/
|
67 |
-
public function activate() {
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* See: http://plugin.michael-simpson.com/?page_id=105
|
72 |
-
* @return void
|
73 |
-
*/
|
74 |
-
public function deactivate() {
|
75 |
-
$this->uninstall();
|
76 |
-
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* See: http://plugin.michael-simpson.com/?page_id=31
|
80 |
-
* @return void
|
81 |
-
*/
|
82 |
-
protected function initOptions() {
|
83 |
-
}
|
84 |
-
|
85 |
-
public function addActionsAndFilters() {
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* See: http://plugin.michael-simpson.com/?page_id=101
|
90 |
-
* Called by install() to create any database tables if needed.
|
91 |
-
* Best Practice:
|
92 |
-
* (1) Prefix all table names with $wpdb->prefix
|
93 |
-
* (2) make table names lower case only
|
94 |
-
* @return void
|
95 |
-
*/
|
96 |
-
protected function installDatabaseTables() {
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* See: http://plugin.michael-simpson.com/?page_id=101
|
101 |
-
* Drop plugin-created tables on uninstall.
|
102 |
-
* @return void
|
103 |
-
*/
|
104 |
-
protected function unInstallDatabaseTables() {
|
105 |
-
}
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Override to add any additional actions to be done at install time
|
109 |
-
* See: http://plugin.michael-simpson.com/?page_id=33
|
110 |
-
* @return void
|
111 |
-
*/
|
112 |
-
protected function otherInstall() {
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Override to add any additional actions to be done at uninstall time
|
117 |
-
* See: http://plugin.michael-simpson.com/?page_id=33
|
118 |
-
* @return void
|
119 |
-
*/
|
120 |
-
protected function otherUninstall() {
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Puts the configuration page in the Plugins menu by default.
|
125 |
-
* Override to put it elsewhere or create a set of submenus
|
126 |
-
* Override with an empty implementation if you don't want a configuration page
|
127 |
-
* @return void
|
128 |
-
*/
|
129 |
-
public function addSettingsSubMenuPage() {
|
130 |
-
$this->addSettingsSubMenuPageToPluginsMenu();
|
131 |
-
//$this->addSettingsSubMenuPageToSettingsMenu();
|
132 |
-
}
|
133 |
-
|
134 |
-
|
135 |
-
protected function requireExtraPluginFiles() {
|
136 |
-
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
137 |
-
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
138 |
-
}
|
139 |
-
|
140 |
-
/**
|
141 |
-
* @return string Slug name for the URL to the Setting page
|
142 |
-
* (i.e. the page for setting options)
|
143 |
-
*/
|
144 |
-
protected function getSettingsSlug() {
|
145 |
-
return get_class($this) . 'Settings';
|
146 |
-
}
|
147 |
-
|
148 |
-
protected function addSettingsSubMenuPageToPluginsMenu() {
|
149 |
-
$this->requireExtraPluginFiles();
|
150 |
-
$displayName = $this->getPluginDisplayName();
|
151 |
-
add_submenu_page('plugins.php',
|
152 |
-
$displayName,
|
153 |
-
$displayName,
|
154 |
-
'manage_options',
|
155 |
-
$this->getSettingsSlug(),
|
156 |
-
array(&$this, 'settingsPage'));
|
157 |
-
}
|
158 |
-
|
159 |
-
|
160 |
-
protected function addSettingsSubMenuPageToSettingsMenu() {
|
161 |
-
$this->requireExtraPluginFiles();
|
162 |
-
$displayName = $this->getPluginDisplayName();
|
163 |
-
add_options_page($displayName,
|
164 |
-
$displayName,
|
165 |
-
'manage_options',
|
166 |
-
$this->getSettingsSlug(),
|
167 |
-
array(&$this, 'settingsPage'));
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* @param $name string name of a database table
|
172 |
-
* @return string input prefixed with the WordPress DB table prefix
|
173 |
-
* plus the prefix for this plugin (lower-cased) to avoid table name collisions.
|
174 |
-
* The plugin prefix is lower-cases as a best practice that all DB table names are lower case to
|
175 |
-
* avoid issues on some platforms
|
176 |
-
*/
|
177 |
-
protected function prefixTableName($name) {
|
178 |
-
global $wpdb;
|
179 |
-
return $wpdb->prefix . strtolower($this->prefix($name));
|
180 |
-
}
|
181 |
-
|
182 |
-
|
183 |
-
/**
|
184 |
-
* Convenience function for creating AJAX URLs.
|
185 |
-
*
|
186 |
-
* @param $actionName string the name of the ajax action registered in a call like
|
187 |
-
* add_action('wp_ajax_actionName', array(&$this, 'functionName'));
|
188 |
-
* and/or
|
189 |
-
* add_action('wp_ajax_nopriv_actionName', array(&$this, 'functionName'));
|
190 |
-
*
|
191 |
-
* If have an additional parameters to add to the Ajax call, e.g. an "id" parameter,
|
192 |
-
* you could call this function and append to the returned string like:
|
193 |
-
* $url = $this->getAjaxUrl('myaction&id=') . urlencode($id);
|
194 |
-
* or more complex:
|
195 |
-
* $url = sprintf($this->getAjaxUrl('myaction&id=%s&var2=%s&var3=%s'), urlencode($id), urlencode($var2), urlencode($var3));
|
196 |
-
*
|
197 |
-
* @return string URL that can be used in a web page to make an Ajax call to $this->functionName
|
198 |
-
*/
|
199 |
-
public function getAjaxUrl($actionName) {
|
200 |
-
return admin_url('admin-ajax.php') . '?action=' . $actionName;
|
201 |
-
}
|
202 |
-
|
203 |
-
public function registerPluginActionLinks( $actions, $plugin_file ) {
|
204 |
-
if ($this->getMainPluginFileName() == basename($plugin_file)) {
|
205 |
-
$settings = array('settings' => '<a href="admin.php?page=wpml_plugin_settings">' . __('Settings', 'General') . '</a>');
|
206 |
-
$actions = array_merge($settings, $actions);
|
207 |
-
}
|
208 |
-
return $actions;
|
209 |
-
}
|
210 |
-
|
211 |
-
}
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
+
|
5 |
+
This file is part of WordPress Plugin Template for WordPress.
|
6 |
+
|
7 |
+
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
+
it under the terms of the GNU General Public License as published by
|
9 |
+
the Free Software Foundation, either version 3 of the License, or
|
10 |
+
(at your option) any later version.
|
11 |
+
|
12 |
+
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
GNU General Public License for more details.
|
16 |
+
|
17 |
+
You should have received a copy of the GNU General Public License
|
18 |
+
along with Contact Form to Database Extension.
|
19 |
+
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
+
*/
|
21 |
+
|
22 |
+
namespace No3x\WPML;
|
23 |
+
|
24 |
+
// Exit if accessed directly.
|
25 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
+
|
27 |
+
class WPML_LifeCycle extends WPML_InstallIndicator {
|
28 |
+
|
29 |
+
public function install() {
|
30 |
+
|
31 |
+
// Initialize Plugin Options
|
32 |
+
$this->initOptions();
|
33 |
+
|
34 |
+
// Initialize DB Tables used by the plugin
|
35 |
+
$this->installDatabaseTables();
|
36 |
+
|
37 |
+
// Other Plugin initialization - for the plugin writer to override as needed
|
38 |
+
$this->otherInstall();
|
39 |
+
|
40 |
+
// Record the installed version
|
41 |
+
$this->saveInstalledVersion();
|
42 |
+
|
43 |
+
}
|
44 |
+
|
45 |
+
public function uninstall() {
|
46 |
+
$this->otherUninstall();
|
47 |
+
|
48 |
+
if ( $this->getSetting('delete-on-deactivation', false) == true ) {
|
49 |
+
//TOOD: is multi site?
|
50 |
+
$this->unInstallDatabaseTables();
|
51 |
+
$this->deleteSavedOptions();
|
52 |
+
$this->deleteVersionOption();
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Perform any version-upgrade activities prior to activation (e.g. database changes)
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function upgrade() {
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* See: http://plugin.michael-simpson.com/?page_id=105
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
public function activate() {
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* See: http://plugin.michael-simpson.com/?page_id=105
|
72 |
+
* @return void
|
73 |
+
*/
|
74 |
+
public function deactivate() {
|
75 |
+
$this->uninstall();
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* See: http://plugin.michael-simpson.com/?page_id=31
|
80 |
+
* @return void
|
81 |
+
*/
|
82 |
+
protected function initOptions() {
|
83 |
+
}
|
84 |
+
|
85 |
+
public function addActionsAndFilters() {
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* See: http://plugin.michael-simpson.com/?page_id=101
|
90 |
+
* Called by install() to create any database tables if needed.
|
91 |
+
* Best Practice:
|
92 |
+
* (1) Prefix all table names with $wpdb->prefix
|
93 |
+
* (2) make table names lower case only
|
94 |
+
* @return void
|
95 |
+
*/
|
96 |
+
protected function installDatabaseTables() {
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* See: http://plugin.michael-simpson.com/?page_id=101
|
101 |
+
* Drop plugin-created tables on uninstall.
|
102 |
+
* @return void
|
103 |
+
*/
|
104 |
+
protected function unInstallDatabaseTables() {
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Override to add any additional actions to be done at install time
|
109 |
+
* See: http://plugin.michael-simpson.com/?page_id=33
|
110 |
+
* @return void
|
111 |
+
*/
|
112 |
+
protected function otherInstall() {
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Override to add any additional actions to be done at uninstall time
|
117 |
+
* See: http://plugin.michael-simpson.com/?page_id=33
|
118 |
+
* @return void
|
119 |
+
*/
|
120 |
+
protected function otherUninstall() {
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Puts the configuration page in the Plugins menu by default.
|
125 |
+
* Override to put it elsewhere or create a set of submenus
|
126 |
+
* Override with an empty implementation if you don't want a configuration page
|
127 |
+
* @return void
|
128 |
+
*/
|
129 |
+
public function addSettingsSubMenuPage() {
|
130 |
+
$this->addSettingsSubMenuPageToPluginsMenu();
|
131 |
+
//$this->addSettingsSubMenuPageToSettingsMenu();
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
protected function requireExtraPluginFiles() {
|
136 |
+
require_once(ABSPATH . 'wp-includes/pluggable.php');
|
137 |
+
require_once(ABSPATH . 'wp-admin/includes/plugin.php');
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @return string Slug name for the URL to the Setting page
|
142 |
+
* (i.e. the page for setting options)
|
143 |
+
*/
|
144 |
+
protected function getSettingsSlug() {
|
145 |
+
return get_class($this) . 'Settings';
|
146 |
+
}
|
147 |
+
|
148 |
+
protected function addSettingsSubMenuPageToPluginsMenu() {
|
149 |
+
$this->requireExtraPluginFiles();
|
150 |
+
$displayName = $this->getPluginDisplayName();
|
151 |
+
add_submenu_page('plugins.php',
|
152 |
+
$displayName,
|
153 |
+
$displayName,
|
154 |
+
'manage_options',
|
155 |
+
$this->getSettingsSlug(),
|
156 |
+
array(&$this, 'settingsPage'));
|
157 |
+
}
|
158 |
+
|
159 |
+
|
160 |
+
protected function addSettingsSubMenuPageToSettingsMenu() {
|
161 |
+
$this->requireExtraPluginFiles();
|
162 |
+
$displayName = $this->getPluginDisplayName();
|
163 |
+
add_options_page($displayName,
|
164 |
+
$displayName,
|
165 |
+
'manage_options',
|
166 |
+
$this->getSettingsSlug(),
|
167 |
+
array(&$this, 'settingsPage'));
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* @param $name string name of a database table
|
172 |
+
* @return string input prefixed with the WordPress DB table prefix
|
173 |
+
* plus the prefix for this plugin (lower-cased) to avoid table name collisions.
|
174 |
+
* The plugin prefix is lower-cases as a best practice that all DB table names are lower case to
|
175 |
+
* avoid issues on some platforms
|
176 |
+
*/
|
177 |
+
protected function prefixTableName($name) {
|
178 |
+
global $wpdb;
|
179 |
+
return $wpdb->prefix . strtolower($this->prefix($name));
|
180 |
+
}
|
181 |
+
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Convenience function for creating AJAX URLs.
|
185 |
+
*
|
186 |
+
* @param $actionName string the name of the ajax action registered in a call like
|
187 |
+
* add_action('wp_ajax_actionName', array(&$this, 'functionName'));
|
188 |
+
* and/or
|
189 |
+
* add_action('wp_ajax_nopriv_actionName', array(&$this, 'functionName'));
|
190 |
+
*
|
191 |
+
* If have an additional parameters to add to the Ajax call, e.g. an "id" parameter,
|
192 |
+
* you could call this function and append to the returned string like:
|
193 |
+
* $url = $this->getAjaxUrl('myaction&id=') . urlencode($id);
|
194 |
+
* or more complex:
|
195 |
+
* $url = sprintf($this->getAjaxUrl('myaction&id=%s&var2=%s&var3=%s'), urlencode($id), urlencode($var2), urlencode($var3));
|
196 |
+
*
|
197 |
+
* @return string URL that can be used in a web page to make an Ajax call to $this->functionName
|
198 |
+
*/
|
199 |
+
public function getAjaxUrl($actionName) {
|
200 |
+
return admin_url('admin-ajax.php') . '?action=' . $actionName;
|
201 |
+
}
|
202 |
+
|
203 |
+
public function registerPluginActionLinks( $actions, $plugin_file ) {
|
204 |
+
if ($this->getMainPluginFileName() == basename($plugin_file)) {
|
205 |
+
$settings = array('settings' => '<a href="admin.php?page=wpml_plugin_settings">' . __('Settings', 'General') . '</a>');
|
206 |
+
$actions = array_merge($settings, $actions);
|
207 |
+
}
|
208 |
+
return $actions;
|
209 |
+
}
|
210 |
+
|
211 |
+
}
|
WPML_LogRotation.php → src/WPML_LogRotation.php
RENAMED
@@ -1,131 +1,131 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace No3x\WPML;
|
4 |
-
|
5 |
-
// Exit if accessed directly.
|
6 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Log rotation for database.
|
10 |
-
* @author No3x
|
11 |
-
* @since 1.4
|
12 |
-
*/
|
13 |
-
class WPML_LogRotation {
|
14 |
-
|
15 |
-
const WPML_LOGROTATION_SCHEDULE_HOOK = 'wpml_log_rotation';
|
16 |
-
const WPML_LOGROTATION_SCHEDULE_ACTION = 'LogRotationSchedule';
|
17 |
-
private $plugin_meta;
|
18 |
-
|
19 |
-
function __construct( $plugin_meta ) {
|
20 |
-
$this->plugin_meta = $plugin_meta;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Add actions and filters for this module.
|
25 |
-
* @since 1.6.0
|
26 |
-
*/
|
27 |
-
public function addActionsAndFilters() {
|
28 |
-
add_action( 'plugins_loaded', array( $this, 'init') );
|
29 |
-
add_action( self::WPML_LOGROTATION_SCHEDULE_HOOK , array( __CLASS__, self::WPML_LOGROTATION_SCHEDULE_ACTION) );
|
30 |
-
register_deactivation_hook( plugin_dir_path( __FILE__ ) . $this->plugin_meta['main_file'], array( $this, 'unschedule' ) );
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Init this module.
|
35 |
-
* @since 1.6.0
|
36 |
-
*/
|
37 |
-
public function init() {
|
38 |
-
global $wpml_settings;
|
39 |
-
|
40 |
-
// if plugin is installed the first time settings are not initialized properly so quit early.
|
41 |
-
if( !isset($wpml_settings) || !array_key_exists('log-rotation-limit-amout', $wpml_settings) ) {
|
42 |
-
return;
|
43 |
-
}
|
44 |
-
|
45 |
-
if ( $wpml_settings['log-rotation-limit-amout'] == true || $wpml_settings['log-rotation-delete-time'] == true ) {
|
46 |
-
$this->schedule();
|
47 |
-
} else {
|
48 |
-
$this->unschedule();
|
49 |
-
}
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Schedules an event.
|
54 |
-
* @since 1.4
|
55 |
-
*/
|
56 |
-
function schedule() {
|
57 |
-
if ( ! wp_next_scheduled( self::WPML_LOGROTATION_SCHEDULE_HOOK ) ) {
|
58 |
-
wp_schedule_event( time(), 'hourly', self::WPML_LOGROTATION_SCHEDULE_HOOK );
|
59 |
-
}
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Unschedules an event.
|
64 |
-
* @since 1.4
|
65 |
-
*/
|
66 |
-
function unschedule() {
|
67 |
-
wp_clear_scheduled_hook( self::WPML_LOGROTATION_SCHEDULE_HOOK );
|
68 |
-
}
|
69 |
-
|
70 |
-
/**
|
71 |
-
* The LogRotation supports the limitation of stored mails by amount.
|
72 |
-
* @since 1.6.0
|
73 |
-
*/
|
74 |
-
static function limitNumberOfMailsByAmount() {
|
75 |
-
global $wpml_settings, $wpdb;
|
76 |
-
|
77 |
-
if(!isset($wpml_settings)) {
|
78 |
-
return;
|
79 |
-
}
|
80 |
-
|
81 |
-
$tableName = WPML_Plugin::getTablename( 'mails' );
|
82 |
-
|
83 |
-
if ( $wpml_settings['log-rotation-limit-amout'] == true) {
|
84 |
-
$keep = $wpml_settings['log-rotation-limit-amout-keep'];
|
85 |
-
if ( $keep > 0 ) {
|
86 |
-
$wpdb->query(
|
87 |
-
"DELETE p
|
88 |
-
FROM
|
89 |
-
$tableName AS p
|
90 |
-
JOIN
|
91 |
-
( SELECT mail_id
|
92 |
-
FROM $tableName
|
93 |
-
ORDER BY mail_id DESC
|
94 |
-
LIMIT 1 OFFSET $keep
|
95 |
-
) AS lim
|
96 |
-
ON p.mail_id <= lim.mail_id;"
|
97 |
-
);
|
98 |
-
}
|
99 |
-
}
|
100 |
-
}
|
101 |
-
|
102 |
-
/**
|
103 |
-
* The LogRotation supports the limitation of stored mails by date.
|
104 |
-
* @since 1.6.0
|
105 |
-
*/
|
106 |
-
static function limitNumberOfMailsByTime() {
|
107 |
-
global $wpml_settings, $wpdb;
|
108 |
-
|
109 |
-
if(!isset($wpml_settings)) {
|
110 |
-
return;
|
111 |
-
}
|
112 |
-
|
113 |
-
$tableName = WPML_Plugin::getTablename( 'mails' );
|
114 |
-
|
115 |
-
if ( $wpml_settings['log-rotation-delete-time'] == true) {
|
116 |
-
$days = $wpml_settings['log-rotation-delete-time-days'];
|
117 |
-
if ( $days > 0 ) {
|
118 |
-
$wpdb->query( "DELETE FROM `$tableName` WHERE DATEDIFF( NOW(), `timestamp` ) >= $days" );
|
119 |
-
}
|
120 |
-
}
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Executes log rotation periodically.
|
125 |
-
* @since 1.4
|
126 |
-
*/
|
127 |
-
static function LogRotationSchedule() {
|
128 |
-
self::limitNumberOfMailsByAmount();
|
129 |
-
self::limitNumberOfMailsByTime();
|
130 |
-
}
|
131 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
// Exit if accessed directly.
|
6 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Log rotation for database.
|
10 |
+
* @author No3x
|
11 |
+
* @since 1.4
|
12 |
+
*/
|
13 |
+
class WPML_LogRotation {
|
14 |
+
|
15 |
+
const WPML_LOGROTATION_SCHEDULE_HOOK = 'wpml_log_rotation';
|
16 |
+
const WPML_LOGROTATION_SCHEDULE_ACTION = 'LogRotationSchedule';
|
17 |
+
private $plugin_meta;
|
18 |
+
|
19 |
+
function __construct( $plugin_meta ) {
|
20 |
+
$this->plugin_meta = $plugin_meta;
|
21 |
+
}
|
22 |
+
|
23 |
+
/**
|
24 |
+
* Add actions and filters for this module.
|
25 |
+
* @since 1.6.0
|
26 |
+
*/
|
27 |
+
public function addActionsAndFilters() {
|
28 |
+
add_action( 'plugins_loaded', array( $this, 'init') );
|
29 |
+
add_action( self::WPML_LOGROTATION_SCHEDULE_HOOK , array( __CLASS__, self::WPML_LOGROTATION_SCHEDULE_ACTION) );
|
30 |
+
register_deactivation_hook( plugin_dir_path( __FILE__ ) . $this->plugin_meta['main_file'], array( $this, 'unschedule' ) );
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Init this module.
|
35 |
+
* @since 1.6.0
|
36 |
+
*/
|
37 |
+
public function init() {
|
38 |
+
global $wpml_settings;
|
39 |
+
|
40 |
+
// if plugin is installed the first time settings are not initialized properly so quit early.
|
41 |
+
if( !isset($wpml_settings) || !array_key_exists('log-rotation-limit-amout', $wpml_settings) ) {
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
|
45 |
+
if ( $wpml_settings['log-rotation-limit-amout'] == true || $wpml_settings['log-rotation-delete-time'] == true ) {
|
46 |
+
$this->schedule();
|
47 |
+
} else {
|
48 |
+
$this->unschedule();
|
49 |
+
}
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Schedules an event.
|
54 |
+
* @since 1.4
|
55 |
+
*/
|
56 |
+
function schedule() {
|
57 |
+
if ( ! wp_next_scheduled( self::WPML_LOGROTATION_SCHEDULE_HOOK ) ) {
|
58 |
+
wp_schedule_event( time(), 'hourly', self::WPML_LOGROTATION_SCHEDULE_HOOK );
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Unschedules an event.
|
64 |
+
* @since 1.4
|
65 |
+
*/
|
66 |
+
function unschedule() {
|
67 |
+
wp_clear_scheduled_hook( self::WPML_LOGROTATION_SCHEDULE_HOOK );
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* The LogRotation supports the limitation of stored mails by amount.
|
72 |
+
* @since 1.6.0
|
73 |
+
*/
|
74 |
+
static function limitNumberOfMailsByAmount() {
|
75 |
+
global $wpml_settings, $wpdb;
|
76 |
+
|
77 |
+
if(!isset($wpml_settings)) {
|
78 |
+
return;
|
79 |
+
}
|
80 |
+
|
81 |
+
$tableName = WPML_Plugin::getTablename( 'mails' );
|
82 |
+
|
83 |
+
if ( $wpml_settings['log-rotation-limit-amout'] == true) {
|
84 |
+
$keep = $wpml_settings['log-rotation-limit-amout-keep'];
|
85 |
+
if ( $keep > 0 ) {
|
86 |
+
$wpdb->query(
|
87 |
+
"DELETE p
|
88 |
+
FROM
|
89 |
+
$tableName AS p
|
90 |
+
JOIN
|
91 |
+
( SELECT mail_id
|
92 |
+
FROM $tableName
|
93 |
+
ORDER BY mail_id DESC
|
94 |
+
LIMIT 1 OFFSET $keep
|
95 |
+
) AS lim
|
96 |
+
ON p.mail_id <= lim.mail_id;"
|
97 |
+
);
|
98 |
+
}
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* The LogRotation supports the limitation of stored mails by date.
|
104 |
+
* @since 1.6.0
|
105 |
+
*/
|
106 |
+
static function limitNumberOfMailsByTime() {
|
107 |
+
global $wpml_settings, $wpdb;
|
108 |
+
|
109 |
+
if(!isset($wpml_settings)) {
|
110 |
+
return;
|
111 |
+
}
|
112 |
+
|
113 |
+
$tableName = WPML_Plugin::getTablename( 'mails' );
|
114 |
+
|
115 |
+
if ( $wpml_settings['log-rotation-delete-time'] == true) {
|
116 |
+
$days = $wpml_settings['log-rotation-delete-time-days'];
|
117 |
+
if ( $days > 0 ) {
|
118 |
+
$wpdb->query( "DELETE FROM `$tableName` WHERE DATEDIFF( NOW(), `timestamp` ) >= $days" );
|
119 |
+
}
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Executes log rotation periodically.
|
125 |
+
* @since 1.4
|
126 |
+
*/
|
127 |
+
static function LogRotationSchedule() {
|
128 |
+
self::limitNumberOfMailsByAmount();
|
129 |
+
self::limitNumberOfMailsByTime();
|
130 |
+
}
|
131 |
+
}
|
src/WPML_MailExtractor.php
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
|
6 |
+
use No3x\WPML\Model\WPML_Mail as Mail;
|
7 |
+
|
8 |
+
class WPML_MailExtractor {
|
9 |
+
|
10 |
+
const ERROR_NO_FIELD = "The message is not valid because it contains no message or html field.";
|
11 |
+
|
12 |
+
public function __construct() {
|
13 |
+
}
|
14 |
+
|
15 |
+
public function extract($mailArray) {
|
16 |
+
return Mail::create([
|
17 |
+
'receiver' => $this->extractReceiver($mailArray['to']),
|
18 |
+
'subject' => $mailArray['subject'],
|
19 |
+
'message' => $this->extractMessage($mailArray),
|
20 |
+
'headers' => $this->extractHeader($mailArray),
|
21 |
+
'attachments' => $this->extractAttachments($mailArray),
|
22 |
+
]);
|
23 |
+
}
|
24 |
+
|
25 |
+
private function extractReceiver( $receiver ) {
|
26 |
+
return $this->convertMultipartsToString($receiver);
|
27 |
+
}
|
28 |
+
|
29 |
+
private function extractMessage( $mail ) {
|
30 |
+
if ( isset($mail['message']) ) {
|
31 |
+
// usually the message is stored in the message field
|
32 |
+
return $mail['message'];
|
33 |
+
} elseif ( isset($mail['html']) ) {
|
34 |
+
// for example Mandrill stores the message in the 'html' field (see gh-22)
|
35 |
+
return $mail['html'];
|
36 |
+
}
|
37 |
+
throw new \Exception(self::ERROR_NO_FIELD);
|
38 |
+
}
|
39 |
+
|
40 |
+
private function extractHeader( $mail ) {
|
41 |
+
$headers = isset($mail['headers']) ? $mail['headers'] : array();
|
42 |
+
return $this->joinMultiParts($headers);
|
43 |
+
}
|
44 |
+
|
45 |
+
private function extractAttachments( $mail ) {
|
46 |
+
$attachments = isset($mail['attachments']) ? $mail['attachments'] : array();
|
47 |
+
|
48 |
+
if(!is_array($attachments)) {
|
49 |
+
$attachments = $this->splitAtComma($attachments);
|
50 |
+
}
|
51 |
+
|
52 |
+
$attachment_urls = array();
|
53 |
+
$basename = 'uploads';
|
54 |
+
$basename_needle = '/'.$basename.'/';
|
55 |
+
foreach ($attachments as $attachment) {
|
56 |
+
$posAttachmentInUploads = strrpos($attachment, $basename_needle);
|
57 |
+
if( false !== $posAttachmentInUploads) {
|
58 |
+
$append_url = substr( $attachment, $posAttachmentInUploads + strlen($basename_needle) - 1 );
|
59 |
+
} else {
|
60 |
+
// not found, save the path unmodified
|
61 |
+
$append_url = $attachment;
|
62 |
+
}
|
63 |
+
$attachment_urls[] = $append_url;
|
64 |
+
}
|
65 |
+
|
66 |
+
$string = $this->joinArrayWithCommaAndNewLine($attachment_urls);
|
67 |
+
|
68 |
+
return $string;
|
69 |
+
}
|
70 |
+
|
71 |
+
private function convertMultipartsToString($multiparts) {
|
72 |
+
|
73 |
+
if(is_array($multiparts)) {
|
74 |
+
$multiPartArray = $multiparts;
|
75 |
+
} else {
|
76 |
+
$multiPartArray = $this->splitAtComma($multiparts);
|
77 |
+
}
|
78 |
+
|
79 |
+
$string = $this->joinArrayWithCommaAndNewLine($multiPartArray);
|
80 |
+
|
81 |
+
return $string;
|
82 |
+
}
|
83 |
+
|
84 |
+
private function splitAtComma($string) {
|
85 |
+
$parts = preg_split( "/(,|,\s)/", $string );
|
86 |
+
return $parts;
|
87 |
+
}
|
88 |
+
|
89 |
+
private function joinMultiParts($multiPart) {
|
90 |
+
return is_array($multiPart) ? $this->joinArrayWithCommaAndNewLine($multiPart) : $multiPart;
|
91 |
+
}
|
92 |
+
|
93 |
+
private function joinArrayWithCommaAndNewLine(array $array) {
|
94 |
+
return implode(',\n', $array);
|
95 |
+
}
|
96 |
+
}
|
src/WPML_MessageSanitizer.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
|
6 |
+
class WPML_MessageSanitizer {
|
7 |
+
|
8 |
+
const SAVED_COMMENT_HTMLEntity_OPEN = "savedcommenthtmldentittyopen";
|
9 |
+
const SAVED_COMMENT_HTMLEntity_CLOSE = "savedcommenthtmlentittclose";
|
10 |
+
const SAVED_COMMENT_HTMLCode_OPEN = "savedcommenthtmlcodeopen";
|
11 |
+
const SAVED_COMMENT_HTMLCode_CLOSE = "savedcommenthtmlcodeclose";
|
12 |
+
|
13 |
+
private $mapping;
|
14 |
+
private $buffer;
|
15 |
+
|
16 |
+
public function __construct() {
|
17 |
+
$this->mapping = [
|
18 |
+
"<!--" => '<' . self::SAVED_COMMENT_HTMLEntity_OPEN . '>',
|
19 |
+
"-->" => '<' . self::SAVED_COMMENT_HTMLEntity_CLOSE . '>',
|
20 |
+
"<!--" => '<' . self::SAVED_COMMENT_HTMLCode_OPEN . '>',
|
21 |
+
"-->" => '<' . self::SAVED_COMMENT_HTMLCode_CLOSE . '>',
|
22 |
+
];
|
23 |
+
}
|
24 |
+
|
25 |
+
public function sanitize($message) {
|
26 |
+
$this->buffer = $message;
|
27 |
+
|
28 |
+
$this->saveComments();
|
29 |
+
$this->stripEvilCode();
|
30 |
+
$this->recoverComments();
|
31 |
+
|
32 |
+
return $this->buffer;
|
33 |
+
}
|
34 |
+
|
35 |
+
private function saveComments() {
|
36 |
+
$this->swapCommentsInStringWithMapping($this->mapping);
|
37 |
+
}
|
38 |
+
|
39 |
+
private function recoverComments() {
|
40 |
+
$this->swapCommentsInStringWithMapping(array_flip($this->mapping));
|
41 |
+
}
|
42 |
+
|
43 |
+
private function swapCommentsInStringWithMapping($mapping) {
|
44 |
+
foreach ($mapping as $from => $to) {
|
45 |
+
$this->buffer = str_replace($from, $to , $this->buffer);
|
46 |
+
}
|
47 |
+
}
|
48 |
+
|
49 |
+
private function stripEvilCode() {
|
50 |
+
$allowed_tags = wp_kses_allowed_html( 'post' );
|
51 |
+
$allowed_tags['style'][''] = true;
|
52 |
+
$allowed_tags[self::SAVED_COMMENT_HTMLEntity_OPEN][''] = true;
|
53 |
+
$allowed_tags[self::SAVED_COMMENT_HTMLEntity_CLOSE][''] = true;
|
54 |
+
$allowed_tags[self::SAVED_COMMENT_HTMLCode_OPEN][''] = true;
|
55 |
+
$allowed_tags[self::SAVED_COMMENT_HTMLCode_CLOSE][''] = true;
|
56 |
+
|
57 |
+
$this->buffer = wp_kses( $this->buffer, $allowed_tags );
|
58 |
+
}
|
59 |
+
|
60 |
+
}
|
WPML_OptionsManager.php → src/WPML_OptionsManager.php
RENAMED
@@ -1,604 +1,604 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
-
|
5 |
-
This file is part of WordPress Plugin Template for WordPress.
|
6 |
-
|
7 |
-
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
-
it under the terms of the GNU General Public License as published by
|
9 |
-
the Free Software Foundation, either version 3 of the License, or
|
10 |
-
(at your option) any later version.
|
11 |
-
|
12 |
-
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
-
GNU General Public License for more details.
|
16 |
-
|
17 |
-
You should have received a copy of the GNU General Public License
|
18 |
-
along with Contact Form to Database Extension.
|
19 |
-
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
-
*/
|
21 |
-
|
22 |
-
namespace No3x\WPML;
|
23 |
-
|
24 |
-
// Exit if accessed directly.
|
25 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
-
|
27 |
-
class WPML_OptionsManager {
|
28 |
-
/**
|
29 |
-
* Is used to retrive a settings value
|
30 |
-
* Important: This implementation understands bool for $default. (unlikely in comparision to all other settings implementation)
|
31 |
-
* @since 1.4
|
32 |
-
* @param string $settingName The option name to return
|
33 |
-
* @param mixed $default (null) The value to return if option not set.
|
34 |
-
* @return ambigous <string, mixed> the options value or $default if not found.
|
35 |
-
*/
|
36 |
-
public function getSetting($settingName, $default = null) {
|
37 |
-
global $wpml_settings;
|
38 |
-
|
39 |
-
if ( array_key_exists($settingName, $wpml_settings)) {
|
40 |
-
$retVal = $wpml_settings[$settingName];
|
41 |
-
}
|
42 |
-
if (!isset($retVal) && $default !== null) {
|
43 |
-
$retVal = $default;
|
44 |
-
}
|
45 |
-
return $retVal;
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Returns the appropriate datetime format string.
|
50 |
-
* @since 1.5.0
|
51 |
-
* @return string datetime format string
|
52 |
-
*/
|
53 |
-
public function getDateTimeFormatString() {
|
54 |
-
// default database like format
|
55 |
-
$format = 'Y-m-d G:i:s';
|
56 |
-
$date_format = get_option( 'date_format' );
|
57 |
-
$time_format = get_option( 'time_format' );
|
58 |
-
// get option or change to user friendly format as the options maybe not set at all
|
59 |
-
$date_format = empty( $date_format ) ? 'F j, Y' : $date_format;
|
60 |
-
$time_format = empty( $time_format ) ? 'g:i a' : $time_format;
|
61 |
-
if ( $this->getSetting( 'datetimeformat-use-wordpress', false) == true )
|
62 |
-
// Overwrite with defined values or default
|
63 |
-
$format = $date_format . " " . $time_format;
|
64 |
-
return $format;
|
65 |
-
}
|
66 |
-
|
67 |
-
public function getOptionNamePrefix() {
|
68 |
-
return $this->getClassnameWithoutNamespace() . '_';
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Define your options meta data here as an array, where each element in the array
|
73 |
-
* @return array of key=>display-name and/or key=>array(display-name, choice1, choice2, ...)
|
74 |
-
* key: an option name for the key (this name will be given a prefix when stored in
|
75 |
-
* the database to ensure it does not conflict with other plugin options)
|
76 |
-
* value: can be one of two things:
|
77 |
-
* (1) string display name for displaying the name of the option to the user on a web page
|
78 |
-
* (2) array where the first element is a display name (as above) and the rest of
|
79 |
-
* the elements are choices of values that the user can select
|
80 |
-
* e.g.
|
81 |
-
* array(
|
82 |
-
* 'item' => 'Item:', // key => display-name
|
83 |
-
* 'rating' => array( // key => array ( display-name, choice1, choice2, ...)
|
84 |
-
* 'CanDoOperationX' => array('Can do Operation X', 'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber'),
|
85 |
-
* 'Rating:', 'Excellent', 'Good', 'Fair', 'Poor')
|
86 |
-
*/
|
87 |
-
public function getOptionMetaData() {
|
88 |
-
return array();
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* @return array of string name of options
|
93 |
-
*/
|
94 |
-
public function getOptionNames() {
|
95 |
-
return array_keys($this->getOptionMetaData());
|
96 |
-
}
|
97 |
-
|
98 |
-
/**
|
99 |
-
* Override this method to initialize options to default values and save to the database with add_option
|
100 |
-
* @return void
|
101 |
-
*/
|
102 |
-
protected function initOptions() {
|
103 |
-
}
|
104 |
-
|
105 |
-
/**
|
106 |
-
* Cleanup: remove all options from the DB
|
107 |
-
* @return void
|
108 |
-
*/
|
109 |
-
protected function deleteSavedOptions() {
|
110 |
-
$optionMetaData = $this->getOptionMetaData();
|
111 |
-
if (is_array($optionMetaData)) {
|
112 |
-
foreach ($optionMetaData as $aOptionKey => $aOptionMeta) {
|
113 |
-
$prefixedOptionName = $this->prefix($aOptionKey); // how it is stored in DB
|
114 |
-
delete_option($prefixedOptionName);
|
115 |
-
}
|
116 |
-
}
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Cleanup: remove version option
|
121 |
-
* @since 1.6.0
|
122 |
-
* @return void
|
123 |
-
*/
|
124 |
-
protected function deleteVersionOption() {
|
125 |
-
delete_option( $this->prefix( WPML_Plugin::optionVersion ) );
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* @return string display name of the plugin to show as a name/title in HTML.
|
130 |
-
* Just returns the class name. Override this method to return something more readable
|
131 |
-
*/
|
132 |
-
public function getPluginDisplayName() {
|
133 |
-
return get_class($this);
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* @return string slug of the plugin to use as identifier.
|
138 |
-
* Just returns the class name in lowercase.
|
139 |
-
*/
|
140 |
-
public function getPluginSlug() {
|
141 |
-
return strtolower( $this->getClassnameWithoutNamespace() );
|
142 |
-
}
|
143 |
-
|
144 |
-
/**
|
145 |
-
* Get the class name without the namespace
|
146 |
-
* @return string class name without the namespace.
|
147 |
-
* @link http://php.net/manual/de/function.get-class.php#114568
|
148 |
-
*/
|
149 |
-
private function getClassnameWithoutNamespace() {
|
150 |
-
$classname = get_class($this);
|
151 |
-
if ($pos = strrpos( $classname, '\\')) {
|
152 |
-
return substr($classname, $pos + 1);
|
153 |
-
}
|
154 |
-
return $classname;
|
155 |
-
}
|
156 |
-
|
157 |
-
/**
|
158 |
-
* Get the prefixed version input $name suitable for storing in WP options
|
159 |
-
* Idempotent: if $optionName is already prefixed, it is not prefixed again, it is returned without change
|
160 |
-
* @param $name string option name to prefix. Defined in settings.php and set as keys of $this->optionMetaData
|
161 |
-
* @return string
|
162 |
-
*/
|
163 |
-
public function prefix($name) {
|
164 |
-
$optionNamePrefix = $this->getOptionNamePrefix();
|
165 |
-
if (strpos($name, $optionNamePrefix) === 0) { // 0 but not false
|
166 |
-
return $name; // already prefixed
|
167 |
-
}
|
168 |
-
return $optionNamePrefix . $name;
|
169 |
-
}
|
170 |
-
|
171 |
-
/**
|
172 |
-
* Remove the prefix from the input $name.
|
173 |
-
* Idempotent: If no prefix found, just returns what was input.
|
174 |
-
* @param $name string
|
175 |
-
* @return string $optionName without the prefix.
|
176 |
-
*/
|
177 |
-
public function &unPrefix($name) {
|
178 |
-
$optionNamePrefix = $this->getOptionNamePrefix();
|
179 |
-
if (strpos($name, $optionNamePrefix) === 0) {
|
180 |
-
return substr($name, strlen($optionNamePrefix));
|
181 |
-
}
|
182 |
-
return $name;
|
183 |
-
}
|
184 |
-
|
185 |
-
/**
|
186 |
-
* A wrapper function delegating to WP get_option() but it prefixes the input $optionName
|
187 |
-
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
188 |
-
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
189 |
-
* @param $default string default value to return if the option is not set
|
190 |
-
* @return string the value from delegated call to get_option(), or optional default value
|
191 |
-
* if option is not set.
|
192 |
-
*/
|
193 |
-
public function getOption($optionName, $default = null) {
|
194 |
-
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
195 |
-
$retVal = get_option($prefixedOptionName);
|
196 |
-
if (!$retVal && $default) {
|
197 |
-
$retVal = $default;
|
198 |
-
}
|
199 |
-
return $retVal;
|
200 |
-
}
|
201 |
-
|
202 |
-
/**
|
203 |
-
* A wrapper function delegating to WP delete_option() but it prefixes the input $optionName
|
204 |
-
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
205 |
-
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
206 |
-
* @return bool from delegated call to delete_option()
|
207 |
-
*/
|
208 |
-
public function deleteOption($optionName) {
|
209 |
-
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
210 |
-
return delete_option($prefixedOptionName);
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* A wrapper function delegating to WP add_option() but it prefixes the input $optionName
|
215 |
-
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
216 |
-
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
217 |
-
* @param $value mixed the new value
|
218 |
-
* @return null from delegated call to delete_option()
|
219 |
-
*/
|
220 |
-
public function addOption($optionName, $value) {
|
221 |
-
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
222 |
-
return add_option($prefixedOptionName, $value);
|
223 |
-
}
|
224 |
-
|
225 |
-
/**
|
226 |
-
* A wrapper function delegating to WP add_option() but it prefixes the input $optionName
|
227 |
-
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
228 |
-
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
229 |
-
* @param $value mixed the new value
|
230 |
-
* @return null from delegated call to delete_option()
|
231 |
-
*/
|
232 |
-
public function updateOption($optionName, $value) {
|
233 |
-
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
234 |
-
return update_option($prefixedOptionName, $value);
|
235 |
-
}
|
236 |
-
|
237 |
-
/**
|
238 |
-
* A Role Option is an option defined in getOptionMetaData() as a choice of WP standard roles, e.g.
|
239 |
-
* 'CanDoOperationX' => array('Can do Operation X', 'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber')
|
240 |
-
* The idea is use an option to indicate what role level a user must minimally have in order to do some operation.
|
241 |
-
* So if a Role Option 'CanDoOperationX' is set to 'Editor' then users which role 'Editor' or above should be
|
242 |
-
* able to do Operation X.
|
243 |
-
* Also see: canUserDoRoleOption()
|
244 |
-
* @param $optionName
|
245 |
-
* @return string role name
|
246 |
-
*/
|
247 |
-
public function getRoleOption($optionName) {
|
248 |
-
$roleAllowed = $this->getOption($optionName);
|
249 |
-
if (!$roleAllowed || $roleAllowed == '') {
|
250 |
-
$roleAllowed = 'Administrator';
|
251 |
-
}
|
252 |
-
return $roleAllowed;
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* Given a WP role name (case insensitive), return a WP capability which only that role and roles above it have.
|
257 |
-
* http://codex.wordpress.org/Roles_and_Capabilities
|
258 |
-
* @param $roleName
|
259 |
-
* @return string a WP capability or '' if unknown input role
|
260 |
-
*/
|
261 |
-
protected function roleToCapability($roleName) {
|
262 |
-
switch ( ucfirst( $roleName ) ) {
|
263 |
-
case 'Super Admin':
|
264 |
-
return 'manage_options';
|
265 |
-
case 'Administrator':
|
266 |
-
return 'manage_options';
|
267 |
-
case 'Editor':
|
268 |
-
return 'publish_pages';
|
269 |
-
case 'Author':
|
270 |
-
return 'publish_posts';
|
271 |
-
case 'Contributor':
|
272 |
-
return 'edit_posts';
|
273 |
-
case 'Subscriber':
|
274 |
-
return 'read';
|
275 |
-
case 'Anyone':
|
276 |
-
return 'read';
|
277 |
-
}
|
278 |
-
return '';
|
279 |
-
}
|
280 |
-
|
281 |
-
/**
|
282 |
-
* @param $roleName string a standard WP role name like 'Administrator'
|
283 |
-
* @return bool
|
284 |
-
*/
|
285 |
-
public function isUserRoleEqualOrBetterThan($roleName) {
|
286 |
-
if ('Anyone' == $roleName) {
|
287 |
-
return true;
|
288 |
-
}
|
289 |
-
$capability = $this->roleToCapability($roleName);
|
290 |
-
return current_user_can($capability);
|
291 |
-
}
|
292 |
-
|
293 |
-
/**
|
294 |
-
* @param $optionName string name of a Role option (see comments in getRoleOption())
|
295 |
-
* @return bool indicates if the user has adequate permissions
|
296 |
-
*/
|
297 |
-
public function canUserDoRoleOption($optionName) {
|
298 |
-
$roleAllowed = $this->getRoleOption($optionName);
|
299 |
-
if ('Anyone' == $roleAllowed) {
|
300 |
-
return true;
|
301 |
-
}
|
302 |
-
return $this->isUserRoleEqualOrBetterThan($roleAllowed);
|
303 |
-
}
|
304 |
-
|
305 |
-
/**
|
306 |
-
* see: http://codex.wordpress.org/Creating_Options_Pages
|
307 |
-
* @return void
|
308 |
-
*/
|
309 |
-
public function createSettingsMenu() {
|
310 |
-
|
311 |
-
global $wp_version;
|
312 |
-
global $wp_logging_list_page;
|
313 |
-
|
314 |
-
$pluginIcon = '';
|
315 |
-
if ( $wp_version >= 3.8 ) $pluginIcon = 'dashicons-email-alt';
|
316 |
-
|
317 |
-
$pluginNameSlug = $this->getPluginSlug();
|
318 |
-
$capability = $this->getSetting( 'can-see-submission-data', 'manage_options' );
|
319 |
-
|
320 |
-
//create new top-level menu
|
321 |
-
$wp_logging_list_page = add_menu_page(__('WP Mail Log', 'wp-mail-logging'),
|
322 |
-
__('WP Mail Log', 'wp-mail-logging'),
|
323 |
-
$capability,
|
324 |
-
$pluginNameSlug . '_log',
|
325 |
-
array(&$this, 'LogMenu'),
|
326 |
-
$pluginIcon
|
327 |
-
);
|
328 |
-
|
329 |
-
// Add Action to load assets when page is loaded
|
330 |
-
add_action( 'load-' . $wp_logging_list_page, array( $this, 'load_assets' ) );
|
331 |
-
|
332 |
-
add_submenu_page($pluginNameSlug . '_log',
|
333 |
-
__('About', 'wp-mail-logging'),
|
334 |
-
__('About', 'wp-mail-logging'),
|
335 |
-
$capability,
|
336 |
-
$pluginNameSlug . '_about',
|
337 |
-
array(&$this, 'LogSubMenuAbout') );
|
338 |
-
|
339 |
-
add_action( 'contextual_help', array( &$this, 'create_settings_panel' ), 10, 3 );
|
340 |
-
}
|
341 |
-
|
342 |
-
public function LogSubMenuAbout() {
|
343 |
-
?>
|
344 |
-
<div class="wrap">
|
345 |
-
<h2><?php echo $this->getPluginDisplayName(); echo ' '; _e('About', 'wp-mail-logging'); ?></h2>
|
346 |
-
<h3>Why use?</h3>
|
347 |
-
<p>Sometimes you may ask yourself if a mail was actually sent by WordPress - with
|
348 |
-
<strong>With <?php echo $this->getPluginDisplayName(); ?>, you can:</strong></p>
|
349 |
-
<ul>
|
350 |
-
<li>View a complete list of sent mails.</li>
|
351 |
-
<li>Search for mails.</li>
|
352 |
-
<li>Count on regular updates, enhancements, and troubleshooting.</li>
|
353 |
-
<li>DevOP: IP of server sent the mail</li>
|
354 |
-
<li>Developer: Boost your development performance by keeping track of sent mails from your WordPress site.</li>
|
355 |
-
<li>Developer: Use Filters that are provided to extend the columns.</li>
|
356 |
-
</ul>
|
357 |
-
<h3>Contributors</h3>
|
358 |
-
<p>This plugin is open source and some people helped to make it better:</p>
|
359 |
-
<ul>
|
360 |
-
<li>tripflex</li>
|
361 |
-
<li><a href="http://www.grafixone.co.za" title="GrafixONE">André Groenewald</a> (Icon before version 1.8.0, icon after this version slightly modified)</li>
|
362 |
-
</ul>
|
363 |
-
<h3>Donate</h3>
|
364 |
-
<p>Please consider to make a donation if you like the plugin. I spent a lot of time for support, enhancements and updates in general.</p>
|
365 |
-
<a title="Donate" class="button button-primary" href="http://no3x.de/web/donate">Donate</a>
|
366 |
-
</div>
|
367 |
-
<?php
|
368 |
-
}
|
369 |
-
|
370 |
-
public function load_assets() {
|
371 |
-
|
372 |
-
global $wp_logging_list_page;
|
373 |
-
$screen = get_current_screen();
|
374 |
-
|
375 |
-
if ( $screen->id != $wp_logging_list_page )
|
376 |
-
return;
|
377 |
-
|
378 |
-
// Enqueue Styles and Scripts if we're on the list page
|
379 |
-
wp_enqueue_script( 'wp-logging-modal', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '
|
380 |
-
wp_localize_script( 'wp-logging-modal', 'wpml_modal', array('ajax_nonce' => wp_create_nonce( 'wpml-modal-show' ) ) );
|
381 |
-
wp_enqueue_style( 'wp-logging-modal', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '
|
382 |
-
wp_enqueue_style( 'wp-logging-icons', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '
|
383 |
-
wp_enqueue_script( 'icheck', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '
|
384 |
-
wp_enqueue_style( 'icheck-square', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '
|
385 |
-
}
|
386 |
-
|
387 |
-
/**
|
388 |
-
* Add settings Panel
|
389 |
-
*/
|
390 |
-
function create_settings_panel($contextual_help, $screen_id, $screen) {
|
391 |
-
|
392 |
-
global $hook_suffix;
|
393 |
-
|
394 |
-
// Just add if we are at the plugin page
|
395 |
-
if ( strpos($hook_suffix, $this->getPluginSlug() . '_log' ) == false )
|
396 |
-
return $contextual_help;
|
397 |
-
|
398 |
-
// The add_help_tab function for screen was introduced in WordPress 3.3.
|
399 |
-
if ( ! method_exists( $screen, 'add_help_tab' ) )
|
400 |
-
return $contextual_help;
|
401 |
-
|
402 |
-
|
403 |
-
// List screen properties
|
404 |
-
$left = '<div style="width:50%;float:left;">'
|
405 |
-
. '<h4>About this plugin</h4>'
|
406 |
-
. '<p>This plugin is open source.</p>'
|
407 |
-
. '</div>';
|
408 |
-
|
409 |
-
|
410 |
-
$right = '<div style="width:50%;float:right;">'
|
411 |
-
. '<h4>Donate</h4>'
|
412 |
-
. '<p>If you like the plugin please consider to make a donation. More information are provided on my <a href="http://no3x.de/web/donate">website</a>.</p>'
|
413 |
-
. '</div>';
|
414 |
-
|
415 |
-
$help_content = $left . $right;
|
416 |
-
|
417 |
-
/**
|
418 |
-
* Content specified inline
|
419 |
-
*/
|
420 |
-
$screen->add_help_tab(
|
421 |
-
array(
|
422 |
-
'title' => __('About Plugin', 'wp-mail-logging'),
|
423 |
-
'id' => 'about_tab',
|
424 |
-
'content' => '<p>' . __( "{$this->getPluginDisplayName()}, logs each email sent by WordPress.", 'wp-mail-logging') . '</p>' . $help_content,
|
425 |
-
'callback' => false
|
426 |
-
)
|
427 |
-
);
|
428 |
-
|
429 |
-
// Add help sidebar
|
430 |
-
$screen->set_help_sidebar(
|
431 |
-
'<p><strong>' . __('More information', 'wp-mail-logging') . '</strong></p>' .
|
432 |
-
'<p><a href = "http://wordpress.org/extend/plugins/wp-mail-logging/">' . __('Plugin Homepage/support', 'wp-mail-logging') . '</a></p>' .
|
433 |
-
'<p><a href = "http://no3x.de/">' . __("Plugin author's blog", 'wp-mail-logging') . '</a></p>'
|
434 |
-
);
|
435 |
-
|
436 |
-
// Add screen options
|
437 |
-
$screen->add_option(
|
438 |
-
'per_page',
|
439 |
-
array(
|
440 |
-
'label' => __('Entries per page', 'wp-mail-logging'),
|
441 |
-
'default' => 25,
|
442 |
-
'option' => 'per_page'
|
443 |
-
)
|
444 |
-
);
|
445 |
-
|
446 |
-
return $contextual_help;
|
447 |
-
}
|
448 |
-
|
449 |
-
/**
|
450 |
-
* Save Screen option
|
451 |
-
* @since 1.3
|
452 |
-
*/
|
453 |
-
function save_screen_options( $status, $option, $value ) {
|
454 |
-
if ( 'per_page' == $option ) return $value;
|
455 |
-
return $status;
|
456 |
-
}
|
457 |
-
|
458 |
-
public function LogMenu() {
|
459 |
-
global $wp_version, $wpml_settings;
|
460 |
-
|
461 |
-
if ( !current_user_can( $this->getSetting( 'can-see-submission-data', 'manage_options' ) ) ) {
|
462 |
-
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-mail-logging'));
|
463 |
-
}
|
464 |
-
|
465 |
-
if (!class_exists( 'Email_Log_List_Table' ) ) {
|
466 |
-
require_once ( plugin_dir_path( __FILE__ ) . 'WPML_Email_Log_List.php' );
|
467 |
-
}
|
468 |
-
|
469 |
-
?>
|
470 |
-
<div class="wrap">
|
471 |
-
<h2><?php echo $this->getPluginDisplayName(); echo ' '; _e('Log', 'wp-mail-logging'); ?></h2>
|
472 |
-
<script>
|
473 |
-
jQuery(document).ready(function($) {
|
474 |
-
$('#wp-mail-logging-modal-content-header-format-switch input').iCheck({
|
475 |
-
checkboxClass: 'icheckbox_square-blue',
|
476 |
-
radioClass: 'iradio_square-blue',
|
477 |
-
increaseArea: '20%' // optional
|
478 |
-
});
|
479 |
-
});
|
480 |
-
</script>
|
481 |
-
<div id="wp-mail-logging-modal-wrap">
|
482 |
-
<div id="wp-mail-logging-modal-backdrop"></div>
|
483 |
-
<div id="wp-mail-logging-modal-content-wrap">
|
484 |
-
<div id="wp-mail-logging-modal-content">
|
485 |
-
<div id="wp-mail-logging-modal-content-header">
|
486 |
-
<a id="wp-mail-logging-modal-content-header-close" class="wp-mail-logging-modal-close" href="#" title="Close">
|
487 |
-
<?php if ( $wp_version >= 3.8 ): ?>
|
488 |
-
<div class="dashicons dashicons-no"></div>
|
489 |
-
<?php else: ?>
|
490 |
-
<span class="wp-mail-logging-modal-content-header-compat-close">X</span>
|
491 |
-
<?php endif; ?>
|
492 |
-
</a>
|
493 |
-
<?php if ( $wp_version >= 3.8 ): ?>
|
494 |
-
<div id="wp-mail-logging-modal-content-header-icon" class="dashicons dashicons-email-alt"></div>
|
495 |
-
<?php endif; ?>
|
496 |
-
<div id="wp-mail-logging-modal-content-header-title">
|
497 |
-
<?php _e( 'Message', 'wp-mail-logging' ); ?>
|
498 |
-
</div>
|
499 |
-
<div id="wp-mail-logging-modal-content-header-format-switch">
|
500 |
-
<?php
|
501 |
-
$supported_formats = apply_filters( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, array('html') );
|
502 |
-
foreach( $supported_formats as $key => $format ) {
|
503 |
-
$checked = checked($format, $wpml_settings['preferred-mail-format'], false);
|
504 |
-
echo ' <input type="radio" name="format" ' . $checked . ' id="' . esc_attr( $format ) . '"> ' . esc_html( $format ) . '</input> ';
|
505 |
-
}
|
506 |
-
?>
|
507 |
-
</div>
|
508 |
-
</div>
|
509 |
-
<div id="wp-mail-logging-modal-content-body">
|
510 |
-
<div id="wp-mail-logging-modal-content-body-content">
|
511 |
-
|
512 |
-
</div>
|
513 |
-
</div>
|
514 |
-
<div id="wp-mail-logging-modal-content-footer">
|
515 |
-
<a class="wp-mail-logging-modal-close button button-primary" href="#"><?php _e( 'Close', 'wp-mail-logging' ); ?></a>
|
516 |
-
</div>
|
517 |
-
</div>
|
518 |
-
</div>
|
519 |
-
</div>
|
520 |
-
|
521 |
-
<form id="email-list" method="get">
|
522 |
-
<input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
|
523 |
-
<?php
|
524 |
-
wp_nonce_field( WPML_Email_Log_List::NONCE_LIST_TABLE, WPML_Email_Log_List::NONCE_LIST_TABLE . '_nonce' );
|
525 |
-
$search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : false;
|
526 |
-
/** @var WPML_Email_Log_List $emailLogList */
|
527 |
-
$emailLogList = WPML_Init::getInstance()->getService('emailLogList');
|
528 |
-
$emailLogList->prepare_items( $search );
|
529 |
-
$emailLogList->search_box( __( 'Search' ), 's' );
|
530 |
-
$emailLogList->display();
|
531 |
-
?>
|
532 |
-
</form>
|
533 |
-
</div>
|
534 |
-
<?php
|
535 |
-
}
|
536 |
-
|
537 |
-
/**
|
538 |
-
* Override this method and follow its format.
|
539 |
-
* The purpose of this method is to provide i18n display strings for the values of options.
|
540 |
-
* For example, you may create a options with values 'true' or 'false'.
|
541 |
-
* In the options page, this will show as a drop down list with these choices.
|
542 |
-
* But when the the language is not English, you would like to display different strings
|
543 |
-
* for 'true' and 'false' while still keeping the value of that option that is actually saved in
|
544 |
-
* the DB as 'true' or 'false'.
|
545 |
-
* To do this, follow the convention of defining option values in getOptionMetaData() as canonical names
|
546 |
-
* (what you want them to literally be, like 'true') and then add each one to the switch statement in this
|
547 |
-
* function, returning the "__()" i18n name of that string.
|
548 |
-
* @param $optionValue string
|
549 |
-
* @return string __($optionValue) if it is listed in this method, otherwise just returns $optionValue
|
550 |
-
*/
|
551 |
-
protected function getOptionValueI18nString($optionValue) {
|
552 |
-
switch ($optionValue) {
|
553 |
-
case 'true':
|
554 |
-
return __('true', 'wp-mail-logging');
|
555 |
-
case 'false':
|
556 |
-
return __('false', 'wp-mail-logging');
|
557 |
-
|
558 |
-
case 'Administrator':
|
559 |
-
return __('Administrator', 'wp-mail-logging');
|
560 |
-
case 'Editor':
|
561 |
-
return __('Editor', 'wp-mail-logging');
|
562 |
-
case 'Author':
|
563 |
-
return __('Author', 'wp-mail-logging');
|
564 |
-
case 'Contributor':
|
565 |
-
return __('Contributor', 'wp-mail-logging');
|
566 |
-
case 'Subscriber':
|
567 |
-
return __('Subscriber', 'wp-mail-logging');
|
568 |
-
case 'Anyone':
|
569 |
-
return __('Anyone', 'wp-mail-logging');
|
570 |
-
}
|
571 |
-
return $optionValue;
|
572 |
-
}
|
573 |
-
|
574 |
-
/**
|
575 |
-
* Query MySQL DB for its version
|
576 |
-
* @return string|false
|
577 |
-
*/
|
578 |
-
protected function getMySqlVersion() {
|
579 |
-
global $wpdb;
|
580 |
-
$rows = $wpdb->get_results('select version() as mysqlversion');
|
581 |
-
if (!empty($rows)) {
|
582 |
-
return $rows[0]->mysqlversion;
|
583 |
-
}
|
584 |
-
return false;
|
585 |
-
}
|
586 |
-
|
587 |
-
/**
|
588 |
-
* If you want to generate an email address like "no-reply@your-site.com" then
|
589 |
-
* you can use this to get the domain name part.
|
590 |
-
* E.g. 'no-reply@' . $this->getEmailDomain();
|
591 |
-
* This code was stolen from the wp_mail function, where it generates a default
|
592 |
-
* from "wordpress@your-site.com"
|
593 |
-
* @return string domain name
|
594 |
-
*/
|
595 |
-
public function getEmailDomain() {
|
596 |
-
// Get the site domain and get rid of www.
|
597 |
-
$sitename = strtolower($_SERVER['SERVER_NAME']);
|
598 |
-
if (substr($sitename, 0, 4) == 'www.') {
|
599 |
-
$sitename = substr($sitename, 4);
|
600 |
-
}
|
601 |
-
return $sitename;
|
602 |
-
}
|
603 |
-
}
|
604 |
-
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
"WordPress Plugin Template" Copyright (C) 2013 Michael Simpson (email : michael.d.simpson@gmail.com)
|
4 |
+
|
5 |
+
This file is part of WordPress Plugin Template for WordPress.
|
6 |
+
|
7 |
+
WordPress Plugin Template is free software: you can redistribute it and/or modify
|
8 |
+
it under the terms of the GNU General Public License as published by
|
9 |
+
the Free Software Foundation, either version 3 of the License, or
|
10 |
+
(at your option) any later version.
|
11 |
+
|
12 |
+
WordPress Plugin Template is distributed in the hope that it will be useful,
|
13 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15 |
+
GNU General Public License for more details.
|
16 |
+
|
17 |
+
You should have received a copy of the GNU General Public License
|
18 |
+
along with Contact Form to Database Extension.
|
19 |
+
If not, see http://www.gnu.org/licenses/gpl-3.0.html
|
20 |
+
*/
|
21 |
+
|
22 |
+
namespace No3x\WPML;
|
23 |
+
|
24 |
+
// Exit if accessed directly.
|
25 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
+
|
27 |
+
class WPML_OptionsManager {
|
28 |
+
/**
|
29 |
+
* Is used to retrive a settings value
|
30 |
+
* Important: This implementation understands bool for $default. (unlikely in comparision to all other settings implementation)
|
31 |
+
* @since 1.4
|
32 |
+
* @param string $settingName The option name to return
|
33 |
+
* @param mixed $default (null) The value to return if option not set.
|
34 |
+
* @return ambigous <string, mixed> the options value or $default if not found.
|
35 |
+
*/
|
36 |
+
public function getSetting($settingName, $default = null) {
|
37 |
+
global $wpml_settings;
|
38 |
+
|
39 |
+
if ( array_key_exists($settingName, $wpml_settings)) {
|
40 |
+
$retVal = $wpml_settings[$settingName];
|
41 |
+
}
|
42 |
+
if (!isset($retVal) && $default !== null) {
|
43 |
+
$retVal = $default;
|
44 |
+
}
|
45 |
+
return $retVal;
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Returns the appropriate datetime format string.
|
50 |
+
* @since 1.5.0
|
51 |
+
* @return string datetime format string
|
52 |
+
*/
|
53 |
+
public function getDateTimeFormatString() {
|
54 |
+
// default database like format
|
55 |
+
$format = 'Y-m-d G:i:s';
|
56 |
+
$date_format = get_option( 'date_format' );
|
57 |
+
$time_format = get_option( 'time_format' );
|
58 |
+
// get option or change to user friendly format as the options maybe not set at all
|
59 |
+
$date_format = empty( $date_format ) ? 'F j, Y' : $date_format;
|
60 |
+
$time_format = empty( $time_format ) ? 'g:i a' : $time_format;
|
61 |
+
if ( $this->getSetting( 'datetimeformat-use-wordpress', false) == true )
|
62 |
+
// Overwrite with defined values or default
|
63 |
+
$format = $date_format . " " . $time_format;
|
64 |
+
return $format;
|
65 |
+
}
|
66 |
+
|
67 |
+
public function getOptionNamePrefix() {
|
68 |
+
return $this->getClassnameWithoutNamespace() . '_';
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Define your options meta data here as an array, where each element in the array
|
73 |
+
* @return array of key=>display-name and/or key=>array(display-name, choice1, choice2, ...)
|
74 |
+
* key: an option name for the key (this name will be given a prefix when stored in
|
75 |
+
* the database to ensure it does not conflict with other plugin options)
|
76 |
+
* value: can be one of two things:
|
77 |
+
* (1) string display name for displaying the name of the option to the user on a web page
|
78 |
+
* (2) array where the first element is a display name (as above) and the rest of
|
79 |
+
* the elements are choices of values that the user can select
|
80 |
+
* e.g.
|
81 |
+
* array(
|
82 |
+
* 'item' => 'Item:', // key => display-name
|
83 |
+
* 'rating' => array( // key => array ( display-name, choice1, choice2, ...)
|
84 |
+
* 'CanDoOperationX' => array('Can do Operation X', 'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber'),
|
85 |
+
* 'Rating:', 'Excellent', 'Good', 'Fair', 'Poor')
|
86 |
+
*/
|
87 |
+
public function getOptionMetaData() {
|
88 |
+
return array();
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @return array of string name of options
|
93 |
+
*/
|
94 |
+
public function getOptionNames() {
|
95 |
+
return array_keys($this->getOptionMetaData());
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Override this method to initialize options to default values and save to the database with add_option
|
100 |
+
* @return void
|
101 |
+
*/
|
102 |
+
protected function initOptions() {
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Cleanup: remove all options from the DB
|
107 |
+
* @return void
|
108 |
+
*/
|
109 |
+
protected function deleteSavedOptions() {
|
110 |
+
$optionMetaData = $this->getOptionMetaData();
|
111 |
+
if (is_array($optionMetaData)) {
|
112 |
+
foreach ($optionMetaData as $aOptionKey => $aOptionMeta) {
|
113 |
+
$prefixedOptionName = $this->prefix($aOptionKey); // how it is stored in DB
|
114 |
+
delete_option($prefixedOptionName);
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Cleanup: remove version option
|
121 |
+
* @since 1.6.0
|
122 |
+
* @return void
|
123 |
+
*/
|
124 |
+
protected function deleteVersionOption() {
|
125 |
+
delete_option( $this->prefix( WPML_Plugin::optionVersion ) );
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* @return string display name of the plugin to show as a name/title in HTML.
|
130 |
+
* Just returns the class name. Override this method to return something more readable
|
131 |
+
*/
|
132 |
+
public function getPluginDisplayName() {
|
133 |
+
return get_class($this);
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* @return string slug of the plugin to use as identifier.
|
138 |
+
* Just returns the class name in lowercase.
|
139 |
+
*/
|
140 |
+
public function getPluginSlug() {
|
141 |
+
return strtolower( $this->getClassnameWithoutNamespace() );
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Get the class name without the namespace
|
146 |
+
* @return string class name without the namespace.
|
147 |
+
* @link http://php.net/manual/de/function.get-class.php#114568
|
148 |
+
*/
|
149 |
+
private function getClassnameWithoutNamespace() {
|
150 |
+
$classname = get_class($this);
|
151 |
+
if ($pos = strrpos( $classname, '\\')) {
|
152 |
+
return substr($classname, $pos + 1);
|
153 |
+
}
|
154 |
+
return $classname;
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Get the prefixed version input $name suitable for storing in WP options
|
159 |
+
* Idempotent: if $optionName is already prefixed, it is not prefixed again, it is returned without change
|
160 |
+
* @param $name string option name to prefix. Defined in settings.php and set as keys of $this->optionMetaData
|
161 |
+
* @return string
|
162 |
+
*/
|
163 |
+
public function prefix($name) {
|
164 |
+
$optionNamePrefix = $this->getOptionNamePrefix();
|
165 |
+
if (strpos($name, $optionNamePrefix) === 0) { // 0 but not false
|
166 |
+
return $name; // already prefixed
|
167 |
+
}
|
168 |
+
return $optionNamePrefix . $name;
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Remove the prefix from the input $name.
|
173 |
+
* Idempotent: If no prefix found, just returns what was input.
|
174 |
+
* @param $name string
|
175 |
+
* @return string $optionName without the prefix.
|
176 |
+
*/
|
177 |
+
public function &unPrefix($name) {
|
178 |
+
$optionNamePrefix = $this->getOptionNamePrefix();
|
179 |
+
if (strpos($name, $optionNamePrefix) === 0) {
|
180 |
+
return substr($name, strlen($optionNamePrefix));
|
181 |
+
}
|
182 |
+
return $name;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* A wrapper function delegating to WP get_option() but it prefixes the input $optionName
|
187 |
+
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
188 |
+
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
189 |
+
* @param $default string default value to return if the option is not set
|
190 |
+
* @return string the value from delegated call to get_option(), or optional default value
|
191 |
+
* if option is not set.
|
192 |
+
*/
|
193 |
+
public function getOption($optionName, $default = null) {
|
194 |
+
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
195 |
+
$retVal = get_option($prefixedOptionName);
|
196 |
+
if (!$retVal && $default) {
|
197 |
+
$retVal = $default;
|
198 |
+
}
|
199 |
+
return $retVal;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* A wrapper function delegating to WP delete_option() but it prefixes the input $optionName
|
204 |
+
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
205 |
+
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
206 |
+
* @return bool from delegated call to delete_option()
|
207 |
+
*/
|
208 |
+
public function deleteOption($optionName) {
|
209 |
+
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
210 |
+
return delete_option($prefixedOptionName);
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* A wrapper function delegating to WP add_option() but it prefixes the input $optionName
|
215 |
+
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
216 |
+
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
217 |
+
* @param $value mixed the new value
|
218 |
+
* @return null from delegated call to delete_option()
|
219 |
+
*/
|
220 |
+
public function addOption($optionName, $value) {
|
221 |
+
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
222 |
+
return add_option($prefixedOptionName, $value);
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* A wrapper function delegating to WP add_option() but it prefixes the input $optionName
|
227 |
+
* to enforce "scoping" the options in the WP options table thereby avoiding name conflicts
|
228 |
+
* @param $optionName string defined in settings.php and set as keys of $this->optionMetaData
|
229 |
+
* @param $value mixed the new value
|
230 |
+
* @return null from delegated call to delete_option()
|
231 |
+
*/
|
232 |
+
public function updateOption($optionName, $value) {
|
233 |
+
$prefixedOptionName = $this->prefix($optionName); // how it is stored in DB
|
234 |
+
return update_option($prefixedOptionName, $value);
|
235 |
+
}
|
236 |
+
|
237 |
+
/**
|
238 |
+
* A Role Option is an option defined in getOptionMetaData() as a choice of WP standard roles, e.g.
|
239 |
+
* 'CanDoOperationX' => array('Can do Operation X', 'Administrator', 'Editor', 'Author', 'Contributor', 'Subscriber')
|
240 |
+
* The idea is use an option to indicate what role level a user must minimally have in order to do some operation.
|
241 |
+
* So if a Role Option 'CanDoOperationX' is set to 'Editor' then users which role 'Editor' or above should be
|
242 |
+
* able to do Operation X.
|
243 |
+
* Also see: canUserDoRoleOption()
|
244 |
+
* @param $optionName
|
245 |
+
* @return string role name
|
246 |
+
*/
|
247 |
+
public function getRoleOption($optionName) {
|
248 |
+
$roleAllowed = $this->getOption($optionName);
|
249 |
+
if (!$roleAllowed || $roleAllowed == '') {
|
250 |
+
$roleAllowed = 'Administrator';
|
251 |
+
}
|
252 |
+
return $roleAllowed;
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Given a WP role name (case insensitive), return a WP capability which only that role and roles above it have.
|
257 |
+
* http://codex.wordpress.org/Roles_and_Capabilities
|
258 |
+
* @param $roleName
|
259 |
+
* @return string a WP capability or '' if unknown input role
|
260 |
+
*/
|
261 |
+
protected function roleToCapability($roleName) {
|
262 |
+
switch ( ucfirst( $roleName ) ) {
|
263 |
+
case 'Super Admin':
|
264 |
+
return 'manage_options';
|
265 |
+
case 'Administrator':
|
266 |
+
return 'manage_options';
|
267 |
+
case 'Editor':
|
268 |
+
return 'publish_pages';
|
269 |
+
case 'Author':
|
270 |
+
return 'publish_posts';
|
271 |
+
case 'Contributor':
|
272 |
+
return 'edit_posts';
|
273 |
+
case 'Subscriber':
|
274 |
+
return 'read';
|
275 |
+
case 'Anyone':
|
276 |
+
return 'read';
|
277 |
+
}
|
278 |
+
return '';
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* @param $roleName string a standard WP role name like 'Administrator'
|
283 |
+
* @return bool
|
284 |
+
*/
|
285 |
+
public function isUserRoleEqualOrBetterThan($roleName) {
|
286 |
+
if ('Anyone' == $roleName) {
|
287 |
+
return true;
|
288 |
+
}
|
289 |
+
$capability = $this->roleToCapability($roleName);
|
290 |
+
return current_user_can($capability);
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* @param $optionName string name of a Role option (see comments in getRoleOption())
|
295 |
+
* @return bool indicates if the user has adequate permissions
|
296 |
+
*/
|
297 |
+
public function canUserDoRoleOption($optionName) {
|
298 |
+
$roleAllowed = $this->getRoleOption($optionName);
|
299 |
+
if ('Anyone' == $roleAllowed) {
|
300 |
+
return true;
|
301 |
+
}
|
302 |
+
return $this->isUserRoleEqualOrBetterThan($roleAllowed);
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* see: http://codex.wordpress.org/Creating_Options_Pages
|
307 |
+
* @return void
|
308 |
+
*/
|
309 |
+
public function createSettingsMenu() {
|
310 |
+
|
311 |
+
global $wp_version;
|
312 |
+
global $wp_logging_list_page;
|
313 |
+
|
314 |
+
$pluginIcon = '';
|
315 |
+
if ( $wp_version >= 3.8 ) $pluginIcon = 'dashicons-email-alt';
|
316 |
+
|
317 |
+
$pluginNameSlug = $this->getPluginSlug();
|
318 |
+
$capability = $this->getSetting( 'can-see-submission-data', 'manage_options' );
|
319 |
+
|
320 |
+
//create new top-level menu
|
321 |
+
$wp_logging_list_page = add_menu_page(__('WP Mail Log', 'wp-mail-logging'),
|
322 |
+
__('WP Mail Log', 'wp-mail-logging'),
|
323 |
+
$capability,
|
324 |
+
$pluginNameSlug . '_log',
|
325 |
+
array(&$this, 'LogMenu'),
|
326 |
+
$pluginIcon
|
327 |
+
);
|
328 |
+
|
329 |
+
// Add Action to load assets when page is loaded
|
330 |
+
add_action( 'load-' . $wp_logging_list_page, array( $this, 'load_assets' ) );
|
331 |
+
|
332 |
+
add_submenu_page($pluginNameSlug . '_log',
|
333 |
+
__('About', 'wp-mail-logging'),
|
334 |
+
__('About', 'wp-mail-logging'),
|
335 |
+
$capability,
|
336 |
+
$pluginNameSlug . '_about',
|
337 |
+
array(&$this, 'LogSubMenuAbout') );
|
338 |
+
|
339 |
+
add_action( 'contextual_help', array( &$this, 'create_settings_panel' ), 10, 3 );
|
340 |
+
}
|
341 |
+
|
342 |
+
public function LogSubMenuAbout() {
|
343 |
+
?>
|
344 |
+
<div class="wrap">
|
345 |
+
<h2><?php echo $this->getPluginDisplayName(); echo ' '; _e('About', 'wp-mail-logging'); ?></h2>
|
346 |
+
<h3>Why use?</h3>
|
347 |
+
<p>Sometimes you may ask yourself if a mail was actually sent by WordPress - with
|
348 |
+
<strong>With <?php echo $this->getPluginDisplayName(); ?>, you can:</strong></p>
|
349 |
+
<ul>
|
350 |
+
<li>View a complete list of sent mails.</li>
|
351 |
+
<li>Search for mails.</li>
|
352 |
+
<li>Count on regular updates, enhancements, and troubleshooting.</li>
|
353 |
+
<li>DevOP: IP of server sent the mail</li>
|
354 |
+
<li>Developer: Boost your development performance by keeping track of sent mails from your WordPress site.</li>
|
355 |
+
<li>Developer: Use Filters that are provided to extend the columns.</li>
|
356 |
+
</ul>
|
357 |
+
<h3>Contributors</h3>
|
358 |
+
<p>This plugin is open source and some people helped to make it better:</p>
|
359 |
+
<ul>
|
360 |
+
<li>tripflex</li>
|
361 |
+
<li><a href="http://www.grafixone.co.za" title="GrafixONE">André Groenewald</a> (Icon before version 1.8.0, icon after this version slightly modified)</li>
|
362 |
+
</ul>
|
363 |
+
<h3>Donate</h3>
|
364 |
+
<p>Please consider to make a donation if you like the plugin. I spent a lot of time for support, enhancements and updates in general.</p>
|
365 |
+
<a title="Donate" class="button button-primary" href="http://no3x.de/web/donate">Donate</a>
|
366 |
+
</div>
|
367 |
+
<?php
|
368 |
+
}
|
369 |
+
|
370 |
+
public function load_assets() {
|
371 |
+
|
372 |
+
global $wp_logging_list_page;
|
373 |
+
$screen = get_current_screen();
|
374 |
+
|
375 |
+
if ( $screen->id != $wp_logging_list_page )
|
376 |
+
return;
|
377 |
+
|
378 |
+
// Enqueue Styles and Scripts if we're on the list page
|
379 |
+
wp_enqueue_script( 'wp-logging-modal', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '/../js/modal.js', array( 'jquery' ), '1.0.0', true );
|
380 |
+
wp_localize_script( 'wp-logging-modal', 'wpml_modal', array('ajax_nonce' => wp_create_nonce( 'wpml-modal-show' ) ) );
|
381 |
+
wp_enqueue_style( 'wp-logging-modal', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '/../css/modal.css', array(), '1.0.0' );
|
382 |
+
wp_enqueue_style( 'wp-logging-icons', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '/../lib/font-awesome/css/font-awesome.min.css', array(), '4.1.0' );
|
383 |
+
wp_enqueue_script( 'icheck', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '/../lib/icheck/icheck.min.js', array(), '1.0.2' );
|
384 |
+
wp_enqueue_style( 'icheck-square', untrailingslashit( plugin_dir_url( __FILE__ ) ) . '/../lib/icheck/square/blue.css', array(), '1.0.2' );
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Add settings Panel
|
389 |
+
*/
|
390 |
+
function create_settings_panel($contextual_help, $screen_id, $screen) {
|
391 |
+
|
392 |
+
global $hook_suffix;
|
393 |
+
|
394 |
+
// Just add if we are at the plugin page
|
395 |
+
if ( strpos($hook_suffix, $this->getPluginSlug() . '_log' ) == false )
|
396 |
+
return $contextual_help;
|
397 |
+
|
398 |
+
// The add_help_tab function for screen was introduced in WordPress 3.3.
|
399 |
+
if ( ! method_exists( $screen, 'add_help_tab' ) )
|
400 |
+
return $contextual_help;
|
401 |
+
|
402 |
+
|
403 |
+
// List screen properties
|
404 |
+
$left = '<div style="width:50%;float:left;">'
|
405 |
+
. '<h4>About this plugin</h4>'
|
406 |
+
. '<p>This plugin is open source.</p>'
|
407 |
+
. '</div>';
|
408 |
+
|
409 |
+
|
410 |
+
$right = '<div style="width:50%;float:right;">'
|
411 |
+
. '<h4>Donate</h4>'
|
412 |
+
. '<p>If you like the plugin please consider to make a donation. More information are provided on my <a href="http://no3x.de/web/donate">website</a>.</p>'
|
413 |
+
. '</div>';
|
414 |
+
|
415 |
+
$help_content = $left . $right;
|
416 |
+
|
417 |
+
/**
|
418 |
+
* Content specified inline
|
419 |
+
*/
|
420 |
+
$screen->add_help_tab(
|
421 |
+
array(
|
422 |
+
'title' => __('About Plugin', 'wp-mail-logging'),
|
423 |
+
'id' => 'about_tab',
|
424 |
+
'content' => '<p>' . __( "{$this->getPluginDisplayName()}, logs each email sent by WordPress.", 'wp-mail-logging') . '</p>' . $help_content,
|
425 |
+
'callback' => false
|
426 |
+
)
|
427 |
+
);
|
428 |
+
|
429 |
+
// Add help sidebar
|
430 |
+
$screen->set_help_sidebar(
|
431 |
+
'<p><strong>' . __('More information', 'wp-mail-logging') . '</strong></p>' .
|
432 |
+
'<p><a href = "http://wordpress.org/extend/plugins/wp-mail-logging/">' . __('Plugin Homepage/support', 'wp-mail-logging') . '</a></p>' .
|
433 |
+
'<p><a href = "http://no3x.de/">' . __("Plugin author's blog", 'wp-mail-logging') . '</a></p>'
|
434 |
+
);
|
435 |
+
|
436 |
+
// Add screen options
|
437 |
+
$screen->add_option(
|
438 |
+
'per_page',
|
439 |
+
array(
|
440 |
+
'label' => __('Entries per page', 'wp-mail-logging'),
|
441 |
+
'default' => 25,
|
442 |
+
'option' => 'per_page'
|
443 |
+
)
|
444 |
+
);
|
445 |
+
|
446 |
+
return $contextual_help;
|
447 |
+
}
|
448 |
+
|
449 |
+
/**
|
450 |
+
* Save Screen option
|
451 |
+
* @since 1.3
|
452 |
+
*/
|
453 |
+
function save_screen_options( $status, $option, $value ) {
|
454 |
+
if ( 'per_page' == $option ) return $value;
|
455 |
+
return $status;
|
456 |
+
}
|
457 |
+
|
458 |
+
public function LogMenu() {
|
459 |
+
global $wp_version, $wpml_settings;
|
460 |
+
|
461 |
+
if ( !current_user_can( $this->getSetting( 'can-see-submission-data', 'manage_options' ) ) ) {
|
462 |
+
wp_die(__('You do not have sufficient permissions to access this page.', 'wp-mail-logging'));
|
463 |
+
}
|
464 |
+
|
465 |
+
if (!class_exists( 'Email_Log_List_Table' ) ) {
|
466 |
+
require_once ( plugin_dir_path( __FILE__ ) . 'WPML_Email_Log_List.php' );
|
467 |
+
}
|
468 |
+
|
469 |
+
?>
|
470 |
+
<div class="wrap">
|
471 |
+
<h2><?php echo $this->getPluginDisplayName(); echo ' '; _e('Log', 'wp-mail-logging'); ?></h2>
|
472 |
+
<script>
|
473 |
+
jQuery(document).ready(function($) {
|
474 |
+
$('#wp-mail-logging-modal-content-header-format-switch input').iCheck({
|
475 |
+
checkboxClass: 'icheckbox_square-blue',
|
476 |
+
radioClass: 'iradio_square-blue',
|
477 |
+
increaseArea: '20%' // optional
|
478 |
+
});
|
479 |
+
});
|
480 |
+
</script>
|
481 |
+
<div id="wp-mail-logging-modal-wrap">
|
482 |
+
<div id="wp-mail-logging-modal-backdrop"></div>
|
483 |
+
<div id="wp-mail-logging-modal-content-wrap">
|
484 |
+
<div id="wp-mail-logging-modal-content">
|
485 |
+
<div id="wp-mail-logging-modal-content-header">
|
486 |
+
<a id="wp-mail-logging-modal-content-header-close" class="wp-mail-logging-modal-close" href="#" title="Close">
|
487 |
+
<?php if ( $wp_version >= 3.8 ): ?>
|
488 |
+
<div class="dashicons dashicons-no"></div>
|
489 |
+
<?php else: ?>
|
490 |
+
<span class="wp-mail-logging-modal-content-header-compat-close">X</span>
|
491 |
+
<?php endif; ?>
|
492 |
+
</a>
|
493 |
+
<?php if ( $wp_version >= 3.8 ): ?>
|
494 |
+
<div id="wp-mail-logging-modal-content-header-icon" class="dashicons dashicons-email-alt"></div>
|
495 |
+
<?php endif; ?>
|
496 |
+
<div id="wp-mail-logging-modal-content-header-title">
|
497 |
+
<?php _e( 'Message', 'wp-mail-logging' ); ?>
|
498 |
+
</div>
|
499 |
+
<div id="wp-mail-logging-modal-content-header-format-switch">
|
500 |
+
<?php
|
501 |
+
$supported_formats = apply_filters( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, array('html') );
|
502 |
+
foreach( $supported_formats as $key => $format ) {
|
503 |
+
$checked = checked($format, $wpml_settings['preferred-mail-format'], false);
|
504 |
+
echo ' <input type="radio" name="format" ' . $checked . ' id="' . esc_attr( $format ) . '"> ' . esc_html( $format ) . '</input> ';
|
505 |
+
}
|
506 |
+
?>
|
507 |
+
</div>
|
508 |
+
</div>
|
509 |
+
<div id="wp-mail-logging-modal-content-body">
|
510 |
+
<div id="wp-mail-logging-modal-content-body-content">
|
511 |
+
|
512 |
+
</div>
|
513 |
+
</div>
|
514 |
+
<div id="wp-mail-logging-modal-content-footer">
|
515 |
+
<a class="wp-mail-logging-modal-close button button-primary" href="#"><?php _e( 'Close', 'wp-mail-logging' ); ?></a>
|
516 |
+
</div>
|
517 |
+
</div>
|
518 |
+
</div>
|
519 |
+
</div>
|
520 |
+
|
521 |
+
<form id="email-list" method="get">
|
522 |
+
<input type="hidden" name="page" value="<?php echo esc_attr( $_REQUEST['page'] ); ?>" />
|
523 |
+
<?php
|
524 |
+
wp_nonce_field( WPML_Email_Log_List::NONCE_LIST_TABLE, WPML_Email_Log_List::NONCE_LIST_TABLE . '_nonce' );
|
525 |
+
$search = ( isset( $_REQUEST['s'] ) ) ? $_REQUEST['s'] : false;
|
526 |
+
/** @var WPML_Email_Log_List $emailLogList */
|
527 |
+
$emailLogList = WPML_Init::getInstance()->getService('emailLogList');
|
528 |
+
$emailLogList->prepare_items( $search );
|
529 |
+
$emailLogList->search_box( __( 'Search' ), 's' );
|
530 |
+
$emailLogList->display();
|
531 |
+
?>
|
532 |
+
</form>
|
533 |
+
</div>
|
534 |
+
<?php
|
535 |
+
}
|
536 |
+
|
537 |
+
/**
|
538 |
+
* Override this method and follow its format.
|
539 |
+
* The purpose of this method is to provide i18n display strings for the values of options.
|
540 |
+
* For example, you may create a options with values 'true' or 'false'.
|
541 |
+
* In the options page, this will show as a drop down list with these choices.
|
542 |
+
* But when the the language is not English, you would like to display different strings
|
543 |
+
* for 'true' and 'false' while still keeping the value of that option that is actually saved in
|
544 |
+
* the DB as 'true' or 'false'.
|
545 |
+
* To do this, follow the convention of defining option values in getOptionMetaData() as canonical names
|
546 |
+
* (what you want them to literally be, like 'true') and then add each one to the switch statement in this
|
547 |
+
* function, returning the "__()" i18n name of that string.
|
548 |
+
* @param $optionValue string
|
549 |
+
* @return string __($optionValue) if it is listed in this method, otherwise just returns $optionValue
|
550 |
+
*/
|
551 |
+
protected function getOptionValueI18nString($optionValue) {
|
552 |
+
switch ($optionValue) {
|
553 |
+
case 'true':
|
554 |
+
return __('true', 'wp-mail-logging');
|
555 |
+
case 'false':
|
556 |
+
return __('false', 'wp-mail-logging');
|
557 |
+
|
558 |
+
case 'Administrator':
|
559 |
+
return __('Administrator', 'wp-mail-logging');
|
560 |
+
case 'Editor':
|
561 |
+
return __('Editor', 'wp-mail-logging');
|
562 |
+
case 'Author':
|
563 |
+
return __('Author', 'wp-mail-logging');
|
564 |
+
case 'Contributor':
|
565 |
+
return __('Contributor', 'wp-mail-logging');
|
566 |
+
case 'Subscriber':
|
567 |
+
return __('Subscriber', 'wp-mail-logging');
|
568 |
+
case 'Anyone':
|
569 |
+
return __('Anyone', 'wp-mail-logging');
|
570 |
+
}
|
571 |
+
return $optionValue;
|
572 |
+
}
|
573 |
+
|
574 |
+
/**
|
575 |
+
* Query MySQL DB for its version
|
576 |
+
* @return string|false
|
577 |
+
*/
|
578 |
+
protected function getMySqlVersion() {
|
579 |
+
global $wpdb;
|
580 |
+
$rows = $wpdb->get_results('select version() as mysqlversion');
|
581 |
+
if (!empty($rows)) {
|
582 |
+
return $rows[0]->mysqlversion;
|
583 |
+
}
|
584 |
+
return false;
|
585 |
+
}
|
586 |
+
|
587 |
+
/**
|
588 |
+
* If you want to generate an email address like "no-reply@your-site.com" then
|
589 |
+
* you can use this to get the domain name part.
|
590 |
+
* E.g. 'no-reply@' . $this->getEmailDomain();
|
591 |
+
* This code was stolen from the wp_mail function, where it generates a default
|
592 |
+
* from "wordpress@your-site.com"
|
593 |
+
* @return string domain name
|
594 |
+
*/
|
595 |
+
public function getEmailDomain() {
|
596 |
+
// Get the site domain and get rid of www.
|
597 |
+
$sitename = strtolower($_SERVER['SERVER_NAME']);
|
598 |
+
if (substr($sitename, 0, 4) == 'www.') {
|
599 |
+
$sitename = substr($sitename, 4);
|
600 |
+
}
|
601 |
+
return $sitename;
|
602 |
+
}
|
603 |
+
}
|
604 |
+
|
WPML_Plugin.php → src/WPML_Plugin.php
RENAMED
@@ -11,6 +11,8 @@ class WPML_Plugin extends WPML_LifeCycle {
|
|
11 |
|
12 |
protected $emailLogList;
|
13 |
|
|
|
|
|
14 |
const HOOK_LOGGING_COLUMNS = 'wpml_hook_mail_columns';
|
15 |
const HOOK_LOGGING_COLUMNS_RENDER = 'wpml_hook_mail_columns_render';
|
16 |
const HOOK_LOGGING_SUPPORTED_FORMATS = 'wpml_hook_supported_formats';
|
@@ -55,7 +57,7 @@ class WPML_Plugin extends WPML_LifeCycle {
|
|
55 |
`attachments` VARCHAR(800) NOT NULL DEFAULT '0',
|
56 |
`error` VARCHAR(400) NULL DEFAULT '',
|
57 |
`plugin_version` VARCHAR(200) NOT NULL DEFAULT '0',
|
58 |
-
PRIMARY KEY (`mail_id`)
|
59 |
) DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE utf8_general_ci;");
|
60 |
}
|
61 |
|
@@ -68,6 +70,8 @@ class WPML_Plugin extends WPML_LifeCycle {
|
|
68 |
global $wpdb;
|
69 |
$tableName = WPML_Plugin::getTablename('mails');
|
70 |
$wpdb->query("DROP TABLE IF EXISTS `$tableName`");
|
|
|
|
|
71 |
}
|
72 |
|
73 |
/**
|
@@ -154,7 +158,7 @@ class WPML_Plugin extends WPML_LifeCycle {
|
|
154 |
// Add Actions & Filters
|
155 |
// http://plugin.michael-simpson.com/?page_id=37
|
156 |
add_filter( 'plugin_action_links', array( &$this, 'registerPluginActionLinks'), 10, 5 );
|
157 |
-
add_filter( 'wp_mail', array(
|
158 |
add_action( 'wp_mail_failed', array( &$this, 'log_email_failed' ) );
|
159 |
add_filter( 'set-screen-option', array( &$this, 'save_screen_options' ), 10, 3);
|
160 |
add_filter( 'wpml_get_plugin_version', array( &$this, 'getVersion' ) );
|
@@ -190,70 +194,28 @@ class WPML_Plugin extends WPML_LifeCycle {
|
|
190 |
$failed_mail->set_error($wperror->get_error_message())->save();
|
191 |
}
|
192 |
|
193 |
-
private function extractReceiver( $receiver ) {
|
194 |
-
return is_array( $receiver ) ? implode( ',\n', $receiver ) : $receiver;
|
195 |
-
}
|
196 |
-
|
197 |
-
private function extractHeader( $headers ) {
|
198 |
-
return is_array( $headers ) ? implode( ',\n', $headers ) : $headers;
|
199 |
-
}
|
200 |
-
|
201 |
-
private function extractAttachments( $mail ) {
|
202 |
-
$attachments = isset($mail['attachments']) ? $mail['attachments'] : array();
|
203 |
-
$attachments = is_array( $attachments ) ? $attachments : array( $attachments );
|
204 |
-
$attachment_urls = array();
|
205 |
-
$uploads = wp_upload_dir();
|
206 |
-
$basename = 'uploads';
|
207 |
-
$basename_needle = '/'.$basename.'/';
|
208 |
-
foreach ( $attachments as $attachment ) {
|
209 |
-
$append_url = substr( $attachment, strrpos( $attachment, $basename_needle ) + strlen($basename_needle) - 1 );
|
210 |
-
$attachment_urls[] = $append_url;
|
211 |
-
}
|
212 |
-
return implode( ',\n', $attachment_urls );
|
213 |
-
}
|
214 |
-
|
215 |
-
private function extractMessage( $mail ) {
|
216 |
-
if ( isset($mail['message']) ) {
|
217 |
-
// usually the message is stored in the message field
|
218 |
-
return $mail['message'];
|
219 |
-
} elseif ( isset($mail['html']) ) {
|
220 |
-
// for example Mandrill stores the message in the 'html' field (see gh-22)
|
221 |
-
return $mail['html'];
|
222 |
-
}
|
223 |
-
return "";
|
224 |
-
}
|
225 |
-
|
226 |
-
|
227 |
-
private function extractFields( $mail ) {
|
228 |
-
return array(
|
229 |
-
'receiver' => $this->extractReceiver( $mail['to'] ),
|
230 |
-
'subject' => $mail['subject'],
|
231 |
-
'message' => $this->extractMessage( $mail ),
|
232 |
-
'headers' => $this->extractHeader( $mail['headers'] ),
|
233 |
-
'attachments' => $this->extractAttachments( $mail ),
|
234 |
-
'plugin_version' => $this->getVersionSaved(),
|
235 |
-
'timestamp' => current_time( 'mysql' ),
|
236 |
-
'host' => isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : ''
|
237 |
-
);
|
238 |
-
}
|
239 |
-
|
240 |
-
|
241 |
/**
|
242 |
* Logs mail to database.
|
243 |
*
|
244 |
-
* @param array $
|
245 |
* @global $wpml_current_mail_id
|
246 |
* @since 1.0
|
247 |
* @return array $mailOriginal
|
248 |
*/
|
249 |
-
public function log_email( $
|
250 |
global $wpml_current_mail_id;
|
251 |
-
// make copy to avoid any changes on the original mail
|
252 |
-
$mail = $mailOriginal;
|
253 |
|
254 |
-
$
|
255 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
256 |
|
257 |
-
|
|
|
258 |
}
|
259 |
}
|
11 |
|
12 |
protected $emailLogList;
|
13 |
|
14 |
+
const HOOK_LOGGING_MAIL = 'log_email';
|
15 |
+
const HOOK_LOGGING_MAIL_PRIORITY = PHP_INT_MAX;
|
16 |
const HOOK_LOGGING_COLUMNS = 'wpml_hook_mail_columns';
|
17 |
const HOOK_LOGGING_COLUMNS_RENDER = 'wpml_hook_mail_columns_render';
|
18 |
const HOOK_LOGGING_SUPPORTED_FORMATS = 'wpml_hook_supported_formats';
|
57 |
`attachments` VARCHAR(800) NOT NULL DEFAULT '0',
|
58 |
`error` VARCHAR(400) NULL DEFAULT '',
|
59 |
`plugin_version` VARCHAR(200) NOT NULL DEFAULT '0',
|
60 |
+
PRIMARY KEY (`mail_id`)
|
61 |
) DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE utf8_general_ci;");
|
62 |
}
|
63 |
|
70 |
global $wpdb;
|
71 |
$tableName = WPML_Plugin::getTablename('mails');
|
72 |
$wpdb->query("DROP TABLE IF EXISTS `$tableName`");
|
73 |
+
// Remove the cache option indicating tables are installed
|
74 |
+
wp_cache_delete(parent::CACHE_INSTALLED_KEY, parent::CACHE_GROUP);
|
75 |
}
|
76 |
|
77 |
/**
|
158 |
// Add Actions & Filters
|
159 |
// http://plugin.michael-simpson.com/?page_id=37
|
160 |
add_filter( 'plugin_action_links', array( &$this, 'registerPluginActionLinks'), 10, 5 );
|
161 |
+
add_filter( 'wp_mail', array( $this, self::HOOK_LOGGING_MAIL ), self::HOOK_LOGGING_MAIL_PRIORITY );
|
162 |
add_action( 'wp_mail_failed', array( &$this, 'log_email_failed' ) );
|
163 |
add_filter( 'set-screen-option', array( &$this, 'save_screen_options' ), 10, 3);
|
164 |
add_filter( 'wpml_get_plugin_version', array( &$this, 'getVersion' ) );
|
194 |
$failed_mail->set_error($wperror->get_error_message())->save();
|
195 |
}
|
196 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
/**
|
198 |
* Logs mail to database.
|
199 |
*
|
200 |
+
* @param array $mailArray
|
201 |
* @global $wpml_current_mail_id
|
202 |
* @since 1.0
|
203 |
* @return array $mailOriginal
|
204 |
*/
|
205 |
+
public function log_email( $mailArray ) {
|
206 |
global $wpml_current_mail_id;
|
|
|
|
|
207 |
|
208 |
+
$mail = (new WPML_MailExtractor())->extract($mailArray);
|
209 |
+
$mail->set_plugin_version($this->getVersionSaved());
|
210 |
+
$mail->set_timestamp(current_time( 'mysql' ));
|
211 |
+
$mail->set_host( isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : '');
|
212 |
+
|
213 |
+
$wpml_current_mail_id = $mail->save();
|
214 |
+
|
215 |
+
return $mailArray;
|
216 |
+
}
|
217 |
|
218 |
+
public static function getClass() {
|
219 |
+
return __CLASS__;
|
220 |
}
|
221 |
}
|
src/WPML_PrivacyController.php
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
namespace No3x\WPML;
|
3 |
+
|
4 |
+
|
5 |
+
use No3x\WPML\Model\WPML_Mail;
|
6 |
+
|
7 |
+
class WPML_PrivacyController {
|
8 |
+
|
9 |
+
const WPML_PRIVACY_EXPORTER = "wp-mail-logging-exporter";
|
10 |
+
const WPML_PRIVACY_ERASER = "wp-mail-logging-eraser";
|
11 |
+
const PER_PAGE = 500;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* WPML_PrivacyController constructor.
|
15 |
+
*/
|
16 |
+
private $plugin_meta;
|
17 |
+
|
18 |
+
function __construct( $plugin_meta ) {
|
19 |
+
$this->plugin_meta = $plugin_meta;
|
20 |
+
}
|
21 |
+
|
22 |
+
public function addActionsAndFilters() {
|
23 |
+
add_filter( 'wp_privacy_personal_data_exporters', [$this, 'register_exporter'], 10);
|
24 |
+
add_filter( 'wp_privacy_personal_data_erasers', [$this, 'register_eraser'], 10);
|
25 |
+
add_action( 'admin_init', [$this, 'register_privacy_policy_content'] );
|
26 |
+
add_action( 'wp_privacy_personal_data_erased', [$this, 'suspendLogging'], 9 );
|
27 |
+
}
|
28 |
+
|
29 |
+
function suspendLogging() {
|
30 |
+
(new WPML_Hook_Remover())->remove_class_hook(
|
31 |
+
'wp_mail',
|
32 |
+
WPML_Plugin::getClass(),
|
33 |
+
WPML_Plugin::HOOK_LOGGING_MAIL,
|
34 |
+
WPML_Plugin::HOOK_LOGGING_MAIL_PRIORITY
|
35 |
+
);
|
36 |
+
}
|
37 |
+
|
38 |
+
function register_privacy_policy_content() {
|
39 |
+
if ( ! function_exists( 'wp_add_privacy_policy_content' ) ) {
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
|
43 |
+
$content = __( 'When you use this site several actions (e.g. commenting) trigger the dispatch of emails. They contain information about you associated with your email address. Which data are part of these emails depends on the action performed. These emails are stored and accessible to the site management as log.', 'wp-mail-logging' );
|
44 |
+
|
45 |
+
wp_add_privacy_policy_content(
|
46 |
+
$this->plugin_meta['display_name'],
|
47 |
+
wp_kses_post( wpautop( $content, false ) )
|
48 |
+
);
|
49 |
+
|
50 |
+
}
|
51 |
+
|
52 |
+
function register_exporter( $exporters ) {
|
53 |
+
$exporters[self::WPML_PRIVACY_EXPORTER] = array(
|
54 |
+
'exporter_friendly_name' => __( 'WP Mail Logging' ),
|
55 |
+
'callback' => [$this, 'export'],
|
56 |
+
);
|
57 |
+
return $exporters;
|
58 |
+
}
|
59 |
+
|
60 |
+
function register_eraser( $erasers ) {
|
61 |
+
$erasers[self::WPML_PRIVACY_ERASER] = array(
|
62 |
+
'eraser_friendly_name' => __( 'WP Mail Logging' ),
|
63 |
+
'callback' => [$this, 'erase'],
|
64 |
+
);
|
65 |
+
return $erasers;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* @param $email_address
|
70 |
+
* @param $current_page
|
71 |
+
* @return array|WPML_Mail[]
|
72 |
+
*/
|
73 |
+
private function queryMails($email_address, $current_page) {
|
74 |
+
$offset = ( $current_page - 1 ) * self::PER_PAGE;
|
75 |
+
return WPML_Mail::query()
|
76 |
+
->search( $email_address )
|
77 |
+
->limit( self::PER_PAGE )
|
78 |
+
->offset( $offset )
|
79 |
+
->find();
|
80 |
+
}
|
81 |
+
|
82 |
+
public function export($email_address, $page = 1) {
|
83 |
+
$mails = $this->queryMails($email_address, $page);
|
84 |
+
|
85 |
+
$export_items = [];
|
86 |
+
foreach ($mails as $mail) {
|
87 |
+
// Most item IDs should look like postType-postID
|
88 |
+
// If you don't have a post, comment or other ID to work with,
|
89 |
+
// use a unique value to avoid having this item's export
|
90 |
+
// combined in the final report with other items of the same id
|
91 |
+
$item_id = "mail-{$mail->get_mail_id()}";
|
92 |
+
|
93 |
+
// Core group IDs include 'comments', 'posts', etc.
|
94 |
+
// But you can add your own group IDs as needed
|
95 |
+
$group_id = 'mails';
|
96 |
+
|
97 |
+
// Optional group label. Core provides these for core groups.
|
98 |
+
// If you define your own group, the first exporter to
|
99 |
+
// include a label will be used as the group label in the
|
100 |
+
// final exported report
|
101 |
+
$group_label = __( 'Mails' );
|
102 |
+
|
103 |
+
// Plugins can add as many items in the item data array as they want
|
104 |
+
$mail_as_array = $mail->to_array();
|
105 |
+
$data = [];
|
106 |
+
foreach ($mail_as_array as $name => $value) {
|
107 |
+
$data[] = [
|
108 |
+
'name' => $name, //TODO: translate function
|
109 |
+
'value' => $value
|
110 |
+
];
|
111 |
+
}
|
112 |
+
|
113 |
+
$export_items[] = array(
|
114 |
+
'group_id' => $group_id,
|
115 |
+
'group_label' => $group_label,
|
116 |
+
'item_id' => $item_id,
|
117 |
+
'data' => $data,
|
118 |
+
);
|
119 |
+
}
|
120 |
+
|
121 |
+
return array(
|
122 |
+
'data' => $export_items,
|
123 |
+
'done' => $this->isDone($mails),
|
124 |
+
);
|
125 |
+
}
|
126 |
+
|
127 |
+
function erase( $email_address, $page = 1 ) {
|
128 |
+
$mails = $this->queryMails($email_address, $page);
|
129 |
+
|
130 |
+
$items_removed = false;
|
131 |
+
$items_retained = false;
|
132 |
+
$messages = [];
|
133 |
+
foreach ($mails as $mail) {
|
134 |
+
if($mail->delete()) {
|
135 |
+
$items_removed = true;
|
136 |
+
} else {
|
137 |
+
$messages[] = sprintf( __( 'A mail with the id %d was unable to be removed at this time.', 'wp-mail-logging'), $mail->get_mail_id());
|
138 |
+
$items_retained = true;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
return array( 'items_removed' => $items_removed,
|
143 |
+
'items_retained' => $items_retained, // always false in this example
|
144 |
+
'messages' => $messages, // no messages in this example
|
145 |
+
'done' => $this->isDone($mails),
|
146 |
+
);
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* True if we have more mails to work on still.
|
151 |
+
* @param $mails
|
152 |
+
* @return bool
|
153 |
+
*/
|
154 |
+
private function isDone($mails) {
|
155 |
+
return count($mails) < self::PER_PAGE;
|
156 |
+
}
|
157 |
+
}
|
WPML_Utils.php → src/WPML_Utils.php
RENAMED
@@ -1,118 +1,118 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace No3x\WPML;
|
4 |
-
|
5 |
-
// Exit if accessed directly.
|
6 |
-
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
-
|
8 |
-
/**
|
9 |
-
* Utils
|
10 |
-
* @author No3x
|
11 |
-
* @since 1.6.0
|
12 |
-
*/
|
13 |
-
class WPML_Utils {
|
14 |
-
/**
|
15 |
-
* Ensure value is subset of given set
|
16 |
-
* @since 1.6.0
|
17 |
-
* @param string $value expected value.
|
18 |
-
* @param array $allowed_values allowed values.
|
19 |
-
* @param string $default_value default value.
|
20 |
-
* @return mixed
|
21 |
-
*/
|
22 |
-
public static function sanitize_expected_value( $value, $allowed_values, $default_value = null ) {
|
23 |
-
$allowed_values = (is_array( $allowed_values ) ) ? $allowed_values : array( $allowed_values );
|
24 |
-
if ( $value && in_array( $value, $allowed_values ) ) {
|
25 |
-
return $value;
|
26 |
-
}
|
27 |
-
if ( null !== $default_value ) {
|
28 |
-
return $default_value;
|
29 |
-
}
|
30 |
-
return false;
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Multilevel array_search
|
35 |
-
* @since 1.3
|
36 |
-
* @param string $needle the searched value.
|
37 |
-
* @param array $haystack the array.
|
38 |
-
* @return mixed Returns the value if needle is found in the array, false otherwise.
|
39 |
-
* @see array_search()
|
40 |
-
*/
|
41 |
-
public static function recursive_array_search( $needle, $haystack ) {
|
42 |
-
foreach ( $haystack as $key => $value ) {
|
43 |
-
$current_key = $key;
|
44 |
-
if ( $needle === $value or ( is_array( $value ) && self::recursive_array_search( $needle, $value ) !== false ) ) {
|
45 |
-
return $current_key;
|
46 |
-
}
|
47 |
-
}
|
48 |
-
return false;
|
49 |
-
}
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Determines appropriate fa icon for a file
|
53 |
-
* @sine 1.3
|
54 |
-
* @param string $file_path path to file.
|
55 |
-
* @return string returns the most suitable icon or generic one if not possible.
|
56 |
-
*/
|
57 |
-
public static function determine_fa_icon( $file_path ) {
|
58 |
-
$default_icon = '<i class="fa fa-file-o"></i>';
|
59 |
-
$supported = array(
|
60 |
-
'archive' => array(
|
61 |
-
'application/zip',
|
62 |
-
'application/x-rar-compressed',
|
63 |
-
'application/x-rar',
|
64 |
-
'application/x-gzip',
|
65 |
-
'application/x-msdownload',
|
66 |
-
'application/x-msdownload',
|
67 |
-
'application/vnd.ms-cab-compressed',
|
68 |
-
),
|
69 |
-
'audio',
|
70 |
-
'code' => array(
|
71 |
-
'text/x-c',
|
72 |
-
'text/x-c++',
|
73 |
-
),
|
74 |
-
'excel' => array( 'application/vnd.ms-excel'
|
75 |
-
),
|
76 |
-
'image', 'text', 'movie', 'pdf', 'photo', 'picture',
|
77 |
-
'powerpoint' => array(
|
78 |
-
'application/vnd.ms-powerpoint'
|
79 |
-
), 'sound', 'video', 'word' => array(
|
80 |
-
'application/msword'
|
81 |
-
), 'zip'
|
82 |
-
);
|
83 |
-
|
84 |
-
if( !function_exists('mime_content_type') ) {
|
85 |
-
return $default_icon;
|
86 |
-
}
|
87 |
-
|
88 |
-
$mime = mime_content_type( $file_path );
|
89 |
-
$mime_parts = explode( '/', $mime );
|
90 |
-
$attribute = $mime_parts[0];
|
91 |
-
$type = $mime_parts[1];
|
92 |
-
|
93 |
-
$fa_icon = false;
|
94 |
-
if ( ($key = self::recursive_array_search( $mime, $supported ) ) !== false ) {
|
95 |
-
// Use specific icon for mime first.
|
96 |
-
$fa_icon = $key;
|
97 |
-
} elseif ( in_array( $attribute, $supported ) ) {
|
98 |
-
// Use generic file icon.
|
99 |
-
$fa_icon = $attribute;
|
100 |
-
}
|
101 |
-
|
102 |
-
if ( false === $fa_icon ) {
|
103 |
-
return $default_icon;
|
104 |
-
} else {
|
105 |
-
return '<i class="fa fa-file-' . $fa_icon . '-o"></i>';
|
106 |
-
}
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Find appropriate fa icon from file path
|
111 |
-
* @since 1.3
|
112 |
-
* @param string $file_path path to file.
|
113 |
-
* @return string
|
114 |
-
*/
|
115 |
-
public static function generate_attachment_icon( $file_path ) {
|
116 |
-
return self::determine_fa_icon( $file_path );
|
117 |
-
}
|
118 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML;
|
4 |
+
|
5 |
+
// Exit if accessed directly.
|
6 |
+
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Utils
|
10 |
+
* @author No3x
|
11 |
+
* @since 1.6.0
|
12 |
+
*/
|
13 |
+
class WPML_Utils {
|
14 |
+
/**
|
15 |
+
* Ensure value is subset of given set
|
16 |
+
* @since 1.6.0
|
17 |
+
* @param string $value expected value.
|
18 |
+
* @param array $allowed_values allowed values.
|
19 |
+
* @param string $default_value default value.
|
20 |
+
* @return mixed
|
21 |
+
*/
|
22 |
+
public static function sanitize_expected_value( $value, $allowed_values, $default_value = null ) {
|
23 |
+
$allowed_values = (is_array( $allowed_values ) ) ? $allowed_values : array( $allowed_values );
|
24 |
+
if ( $value && in_array( $value, $allowed_values ) ) {
|
25 |
+
return $value;
|
26 |
+
}
|
27 |
+
if ( null !== $default_value ) {
|
28 |
+
return $default_value;
|
29 |
+
}
|
30 |
+
return false;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Multilevel array_search
|
35 |
+
* @since 1.3
|
36 |
+
* @param string $needle the searched value.
|
37 |
+
* @param array $haystack the array.
|
38 |
+
* @return mixed Returns the value if needle is found in the array, false otherwise.
|
39 |
+
* @see array_search()
|
40 |
+
*/
|
41 |
+
public static function recursive_array_search( $needle, $haystack ) {
|
42 |
+
foreach ( $haystack as $key => $value ) {
|
43 |
+
$current_key = $key;
|
44 |
+
if ( $needle === $value or ( is_array( $value ) && self::recursive_array_search( $needle, $value ) !== false ) ) {
|
45 |
+
return $current_key;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
return false;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Determines appropriate fa icon for a file
|
53 |
+
* @sine 1.3
|
54 |
+
* @param string $file_path path to file.
|
55 |
+
* @return string returns the most suitable icon or generic one if not possible.
|
56 |
+
*/
|
57 |
+
public static function determine_fa_icon( $file_path ) {
|
58 |
+
$default_icon = '<i class="fa fa-file-o"></i>';
|
59 |
+
$supported = array(
|
60 |
+
'archive' => array(
|
61 |
+
'application/zip',
|
62 |
+
'application/x-rar-compressed',
|
63 |
+
'application/x-rar',
|
64 |
+
'application/x-gzip',
|
65 |
+
'application/x-msdownload',
|
66 |
+
'application/x-msdownload',
|
67 |
+
'application/vnd.ms-cab-compressed',
|
68 |
+
),
|
69 |
+
'audio',
|
70 |
+
'code' => array(
|
71 |
+
'text/x-c',
|
72 |
+
'text/x-c++',
|
73 |
+
),
|
74 |
+
'excel' => array( 'application/vnd.ms-excel'
|
75 |
+
),
|
76 |
+
'image', 'text', 'movie', 'pdf', 'photo', 'picture',
|
77 |
+
'powerpoint' => array(
|
78 |
+
'application/vnd.ms-powerpoint'
|
79 |
+
), 'sound', 'video', 'word' => array(
|
80 |
+
'application/msword'
|
81 |
+
), 'zip'
|
82 |
+
);
|
83 |
+
|
84 |
+
if( !function_exists('mime_content_type') ) {
|
85 |
+
return $default_icon;
|
86 |
+
}
|
87 |
+
|
88 |
+
$mime = mime_content_type( $file_path );
|
89 |
+
$mime_parts = explode( '/', $mime );
|
90 |
+
$attribute = $mime_parts[0];
|
91 |
+
$type = $mime_parts[1];
|
92 |
+
|
93 |
+
$fa_icon = false;
|
94 |
+
if ( ($key = self::recursive_array_search( $mime, $supported ) ) !== false ) {
|
95 |
+
// Use specific icon for mime first.
|
96 |
+
$fa_icon = $key;
|
97 |
+
} elseif ( in_array( $attribute, $supported ) ) {
|
98 |
+
// Use generic file icon.
|
99 |
+
$fa_icon = $attribute;
|
100 |
+
}
|
101 |
+
|
102 |
+
if ( false === $fa_icon ) {
|
103 |
+
return $default_icon;
|
104 |
+
} else {
|
105 |
+
return '<i class="fa fa-file-' . $fa_icon . '-o"></i>';
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Find appropriate fa icon from file path
|
111 |
+
* @since 1.3
|
112 |
+
* @param string $file_path path to file.
|
113 |
+
* @return string
|
114 |
+
*/
|
115 |
+
public static function generate_attachment_icon( $file_path ) {
|
116 |
+
return self::determine_fa_icon( $file_path );
|
117 |
+
}
|
118 |
+
}
|
{inc → src/inc}/class-wp-list-table.php
RENAMED
File without changes
|
{inc → src/inc}/redux/WPML_Redux_Framework_config.php
RENAMED
@@ -1,359 +1,359 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace No3x\WPML\Settings;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* ReduxFramework Sample Config File
|
7 |
-
* For full documentation, please visit: http://docs.reduxframework.com/
|
8 |
-
*/
|
9 |
-
|
10 |
-
if (!class_exists('WPML_Redux_Framework_config')) {
|
11 |
-
|
12 |
-
class WPML_Redux_Framework_config {
|
13 |
-
|
14 |
-
public $args = array();
|
15 |
-
public $sections = array();
|
16 |
-
public $theme;
|
17 |
-
public $ReduxFramework;
|
18 |
-
protected $plugin_meta = array();
|
19 |
-
|
20 |
-
public function __construct( $plugin_meta ) {
|
21 |
-
$this->plugin_meta = $plugin_meta;
|
22 |
-
|
23 |
-
if ( ! class_exists( 'ReduxFramework' ) ) {
|
24 |
-
return;
|
25 |
-
}
|
26 |
-
|
27 |
-
// This is needed. Bah WordPress bugs. ;)
|
28 |
-
if ( true == \Redux_Helpers::isTheme( __FILE__ ) ) {
|
29 |
-
$this->initSettings();
|
30 |
-
} else {
|
31 |
-
add_action( 'plugins_loaded', array( $this, 'initSettings' ), 10 );
|
32 |
-
}
|
33 |
-
|
34 |
-
}
|
35 |
-
|
36 |
-
public function initSettings() {
|
37 |
-
|
38 |
-
// Just for demo purposes. Not needed per say.
|
39 |
-
$this->theme = wp_get_theme();
|
40 |
-
|
41 |
-
// Set the default arguments
|
42 |
-
$this->setArguments();
|
43 |
-
|
44 |
-
// Set a few help tabs so you can see how it's done
|
45 |
-
// $this->setHelpTabs();
|
46 |
-
|
47 |
-
// Create the sections and fields
|
48 |
-
$this->setSections();
|
49 |
-
|
50 |
-
if ( ! isset( $this->args['opt_name'] ) ) { // No errors please
|
51 |
-
return;
|
52 |
-
}
|
53 |
-
|
54 |
-
// If Redux is running as a plugin, this will remove the demo notice and links
|
55 |
-
//add_action( 'redux/loaded', array( $this, 'remove_demo' ) );
|
56 |
-
|
57 |
-
// Function to test the compiler hook and demo CSS output.
|
58 |
-
// Above 10 is a priority, but 2 in necessary to include the dynamically generated CSS to be sent to the function.
|
59 |
-
//add_filter('redux/options/'.$this->args['opt_name'].'/compiler', array( $this, 'compiler_action' ), 10, 3);
|
60 |
-
|
61 |
-
// Change the arguments after they've been declared, but before the panel is created
|
62 |
-
//add_filter('redux/options/'.$this->args['opt_name'].'/args', array( $this, 'change_arguments' ) );
|
63 |
-
|
64 |
-
// Change the default value of a field after it's been set, but before it's been useds
|
65 |
-
//add_filter('redux/options/'.$this->args['opt_name'].'/defaults', array( $this,'change_defaults' ) );
|
66 |
-
|
67 |
-
// Dynamically add a section. Can be also used to modify sections/fields
|
68 |
-
//add_filter('redux/options/' . $this->args['opt_name'] . '/sections', array($this, 'dynamic_section'));
|
69 |
-
|
70 |
-
$this->ReduxFramework = new \ReduxFramework( $this->sections, $this->args );
|
71 |
-
}
|
72 |
-
|
73 |
-
// Remove the demo link and the notice of integrated demo from the redux-framework plugin
|
74 |
-
function remove_demo() {
|
75 |
-
|
76 |
-
// Used to hide the demo mode link from the plugin page. Only used when Redux is a plugin.
|
77 |
-
if ( class_exists( 'ReduxFrameworkPlugin' ) ) {
|
78 |
-
remove_filter( 'plugin_row_meta', array(
|
79 |
-
ReduxFrameworkPlugin::instance(),
|
80 |
-
'plugin_metalinks'
|
81 |
-
), null, 2 );
|
82 |
-
|
83 |
-
// Used to hide the activation notice informing users of the demo panel. Only used when Redux is a plugin.
|
84 |
-
remove_action( 'admin_notices', array( ReduxFrameworkPlugin::instance(), 'admin_notices' ) );
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
public function setSections() {
|
89 |
-
|
90 |
-
// ACTUAL DECLARATION OF SECTIONS
|
91 |
-
$this->sections[] = array(
|
92 |
-
'title' => __('General Settings', 'wp-mail-logging'),
|
93 |
-
'desc' => __('', 'wp-mail-logging'),
|
94 |
-
'icon' => 'el-icon-cogs',
|
95 |
-
// 'submenu' => false, // Setting submenu to false on a given section will hide it from the WordPress sidebar menu!
|
96 |
-
'fields' => array(
|
97 |
-
|
98 |
-
array(
|
99 |
-
'id' => 'delete-on-deactivation',
|
100 |
-
'type' => 'switch',
|
101 |
-
'title' => __('Cleanup', 'wp-mail-logging' ),
|
102 |
-
'subtitle' => __('Delete all data on deactivation? (emails and settings)?', 'wp-mail-logging'),
|
103 |
-
'default' => 0,
|
104 |
-
'on' => __(__('Enabled', 'wp-mail-logging' ), 'wp-mail-logging' ),
|
105 |
-
'off' => __(__('Disabled', 'wp-mail-logging' ), 'wp-mail-logging' ),
|
106 |
-
),
|
107 |
-
array(
|
108 |
-
'id' => 'can-see-submission-data',
|
109 |
-
'type' => 'select',
|
110 |
-
'data' => 'capabilities',
|
111 |
-
'default' => 'manage_options',
|
112 |
-
'title' => __('Can See Submission data', 'wp-mail-logging'),
|
113 |
-
'subtitle' => __('Select the minimum role.', 'wp-mail-logging'),
|
114 |
-
),
|
115 |
-
array(
|
116 |
-
'id' => 'datetimeformat-use-wordpress',
|
117 |
-
'type' => 'switch',
|
118 |
-
'title' => __('WordPress Date Time Format', 'wp-mail-logging' ),
|
119 |
-
'subtitle' => sprintf( __( "Use format from WordPress settings (%s)", 'wp-mail-logging' ), date_i18n( $this->wordpress_default_format(), current_time( 'timestamp' ) ) ),
|
120 |
-
'default' => 0,
|
121 |
-
'on' => __('Enabled', 'wp-mail-logging' ),
|
122 |
-
'off' => __('Disabled', 'wp-mail-logging' ),
|
123 |
-
),
|
124 |
-
array(
|
125 |
-
'id' => 'preferred-mail-format',
|
126 |
-
'type' => 'select',
|
127 |
-
'options' => array(
|
128 |
-
'html' => 'html',
|
129 |
-
'raw' => 'raw',
|
130 |
-
'json' => 'json'
|
131 |
-
),
|
132 |
-
'default' => 'html',
|
133 |
-
'title' => __('Default Format for Message', 'wp-mail-logging'),
|
134 |
-
'subtitle' => __('Select your preferred display format.', 'wp-mail-logging'),
|
135 |
-
),
|
136 |
-
array(
|
137 |
-
'id' => 'display-host',
|
138 |
-
'type' => 'switch',
|
139 |
-
'title' => __('Display Host', 'wp-mail-logging' ),
|
140 |
-
'subtitle' => __('Display host column in list.', 'wp-mail-logging'),
|
141 |
-
'hint' => array(
|
142 |
-
'title' => 'Host',
|
143 |
-
'content' => 'Display the IP of the host WordPress is running on. This is useful when running it on multiple servers at the same time.',
|
144 |
-
),
|
145 |
-
'default' => 0,
|
146 |
-
'on' => __('Enabled', 'wp-mail-logging' ),
|
147 |
-
'off' => __('Disabled', 'wp-mail-logging' ),
|
148 |
-
),
|
149 |
-
array(
|
150 |
-
'id' => 'section-log-rotation-start',
|
151 |
-
'type' => 'section',
|
152 |
-
'title' => __('Log Rotation', 'wp-mail-logging' ),
|
153 |
-
'subtitle' => __('Save space by deleting logs regularly.', 'wp-mail-logging'),
|
154 |
-
'indent' => true, // Indent all options below until the next 'section' option is set.
|
155 |
-
),
|
156 |
-
array(
|
157 |
-
'id' => 'log-rotation-limit-amout',
|
158 |
-
'type' => 'switch',
|
159 |
-
'title' => __('Cleanup by Amount', 'wp-mail-logging' ),
|
160 |
-
'subtitle' => __('Setup a automated cleanup routine!', 'wp-mail-logging'),
|
161 |
-
'default' => 0,
|
162 |
-
'on' => __('Enabled', 'wp-mail-logging' ),
|
163 |
-
'off' => __('Disabled', 'wp-mail-logging' ),
|
164 |
-
),
|
165 |
-
array(
|
166 |
-
'id' => 'log-rotation-limit-amout-keep',
|
167 |
-
'type' => 'slider',
|
168 |
-
'required' => array('log-rotation-limit-amout', '=', '1'),
|
169 |
-
'title' => __('Amount', 'wp-mail-logging' ),
|
170 |
-
'subtitle' => __('When should mails are deleted?', 'wp-mail-logging'),
|
171 |
-
'desc' => __('Cleanup when the stored mails exceed...', 'wp-mail-logging'),
|
172 |
-
'default' => 75,
|
173 |
-
'min' => 25,
|
174 |
-
'step' => 50,
|
175 |
-
'max' => 3000,
|
176 |
-
'display_value' => 'text'
|
177 |
-
),
|
178 |
-
array(
|
179 |
-
'id' => 'log-rotation-delete-time',
|
180 |
-
'type' => 'switch',
|
181 |
-
'title' => __('Cleanup by Time', 'wp-mail-logging' ),
|
182 |
-
'subtitle' => __('Setup a automated cleanup routine!', 'wp-mail-logging'),
|
183 |
-
'default' => 0,
|
184 |
-
'on' => __('Enabled', 'wp-mail-logging' ),
|
185 |
-
'off' => __('Disabled', 'wp-mail-logging' ),
|
186 |
-
),
|
187 |
-
array(
|
188 |
-
'id' => 'log-rotation-delete-time-days',
|
189 |
-
'type' => 'slider',
|
190 |
-
'required' => array('log-rotation-delete-time', '=', '1'),
|
191 |
-
'title' => __('Time', 'wp-mail-logging' ),
|
192 |
-
'subtitle' => __('When should mails are deleted?', 'wp-mail-logging'),
|
193 |
-
'desc' => __('Delete mails older than days...', 'wp-mail-logging'),
|
194 |
-
'default' => 30,
|
195 |
-
'min' => 1,
|
196 |
-
'step' => 7,
|
197 |
-
'max' => 400,
|
198 |
-
'display_value' => 'text'
|
199 |
-
),
|
200 |
-
array(
|
201 |
-
'id' => 'section-log-rotation-end',
|
202 |
-
'type' => 'section',
|
203 |
-
'indent' => false // Indent all options below until the next 'section' option is set.
|
204 |
-
),
|
205 |
-
),
|
206 |
-
);
|
207 |
-
}
|
208 |
-
|
209 |
-
public function wordpress_default_format()
|
210 |
-
{
|
211 |
-
$date_format = get_option( 'date_format' );
|
212 |
-
$time_format = get_option( 'time_format' );
|
213 |
-
$date_format = empty( $date_format ) ? 'F j, Y' : $date_format;
|
214 |
-
$time_format = empty( $time_format ) ? 'g:i a' : $time_format;
|
215 |
-
return "{$date_format} {$time_format}";
|
216 |
-
}
|
217 |
-
|
218 |
-
/**
|
219 |
-
* All the possible arguments for Redux.
|
220 |
-
* For full documentation on arguments, please refer to: https://github.com/ReduxFramework/ReduxFramework/wiki/Arguments
|
221 |
-
* */
|
222 |
-
public function setArguments() {
|
223 |
-
|
224 |
-
$theme = wp_get_theme(); // For use with some settings. Not necessary.
|
225 |
-
|
226 |
-
$this->args = array(
|
227 |
-
// TYPICAL -> Change these values as you need/desire
|
228 |
-
'opt_name' => 'wpml_settings',
|
229 |
-
// This is where your data is stored in the database and also becomes your global variable name.
|
230 |
-
'display_name' => 'WP Mail Logging Settings',
|
231 |
-
// Name that appears at the top of your panel
|
232 |
-
'display_version' => $this->plugin_meta['version_installed'],
|
233 |
-
// Version that appears at the top of your panel
|
234 |
-
'menu_type' => 'submenu',
|
235 |
-
//Specify if the admin menu should appear or not. Options: menu or submenu (Under appearance only)
|
236 |
-
'allow_sub_menu' => true,
|
237 |
-
// Show the sections below the admin menu item or not
|
238 |
-
'menu_title' => 'Settings',
|
239 |
-
'page_title' => $this->plugin_meta['display_name'],
|
240 |
-
// You will need to generate a Google API key to use this feature.
|
241 |
-
// Please visit: https://developers.google.com/fonts/docs/developer_api#Auth
|
242 |
-
'google_api_key' => '',
|
243 |
-
// Set it you want google fonts to update weekly. A google_api_key value is required.
|
244 |
-
'google_update_weekly' => false,
|
245 |
-
// Must be defined to add google fonts to the typography module
|
246 |
-
'async_typography' => true,
|
247 |
-
// Use a asynchronous font on the front end or font string
|
248 |
-
//'disable_google_fonts_link' => true, // Disable this in case you want to create your own google fonts loader
|
249 |
-
'admin_bar' => false,
|
250 |
-
// Show the panel pages on the admin bar
|
251 |
-
'admin_bar_icon' => 'dashicons-portfolio',
|
252 |
-
// Choose an icon for the admin bar menu
|
253 |
-
'admin_bar_priority' => 50,
|
254 |
-
// Choose an priority for the admin bar menu
|
255 |
-
'global_variable' => '',
|
256 |
-
// Set a different name for your global variable other than the opt_name
|
257 |
-
'dev_mode' => false,
|
258 |
-
// Show the time the page took to load, etc
|
259 |
-
'update_notice' => true,
|
260 |
-
// If dev_mode is enabled, will notify developer of updated versions available in the GitHub Repo
|
261 |
-
'customizer' => false,
|
262 |
-
// Enable basic customizer support
|
263 |
-
//'open_expanded' => true, // Allow you to start the panel in an expanded way initially.
|
264 |
-
//'disable_save_warn' => true, // Disable the save warning when a user changes a field
|
265 |
-
|
266 |
-
// OPTIONAL -> Give you extra features
|
267 |
-
'page_priority' => null,
|
268 |
-
// Order where the menu appears in the admin area. If there is any conflict, something will not show. Warning.
|
269 |
-
'page_parent' => 'wpml_plugin_log',
|
270 |
-
// For a full list of options, visit: http://codex.wordpress.org/Function_Reference/add_submenu_page#Parameters
|
271 |
-
'page_permissions' => 'manage_options',
|
272 |
-
// Permissions needed to access the options panel.
|
273 |
-
'menu_icon' => '',
|
274 |
-
// Specify a custom URL to an icon
|
275 |
-
'last_tab' => '',
|
276 |
-
// Force your panel to always open to a specific tab (by id)
|
277 |
-
'page_icon' => 'icon-themes',
|
278 |
-
// Icon displayed in the admin panel next to your menu_title
|
279 |
-
'page_slug' => 'wpml_plugin_settings',
|
280 |
-
// Page slug used to denote the panel
|
281 |
-
'save_defaults' => true,
|
282 |
-
// On load save the defaults to DB before user clicks save or not
|
283 |
-
'default_show' => false,
|
284 |
-
// If true, shows the default value next to each field that is not the default value.
|
285 |
-
'default_mark' => '*',
|
286 |
-
// What to print by the field's title if the value shown is default. Suggested: *
|
287 |
-
'show_import_export' => true,
|
288 |
-
// Shows the Import/Export panel when not used as a field.
|
289 |
-
|
290 |
-
// CAREFUL -> These options are for advanced use only
|
291 |
-
'transient_time' => 60 * MINUTE_IN_SECONDS,
|
292 |
-
'output' => true,
|
293 |
-
// Global shut-off for dynamic CSS output by the framework. Will also disable google fonts output
|
294 |
-
'output_tag' => true,
|
295 |
-
// Allows dynamic CSS to be generated for customizer and google fonts, but stops the dynamic CSS from going to the head
|
296 |
-
// 'footer_credit' => '', // Disable the footer credit of Redux. Please leave if you can help it.
|
297 |
-
|
298 |
-
// FUTURE -> Not in use yet, but reserved or partially implemented. Use at your own risk.
|
299 |
-
'database' => '',
|
300 |
-
// possible: options, theme_mods, theme_mods_expanded, transient. Not fully functional, warning!
|
301 |
-
'system_info' => false,
|
302 |
-
// REMOVE
|
303 |
-
|
304 |
-
// HINTS
|
305 |
-
'hints' => array(
|
306 |
-
'icon' => 'el el-question-sign',
|
307 |
-
'icon_position' => 'right',
|
308 |
-
'icon_color' => 'lightgray',
|
309 |
-
'icon_size' => 'normal',
|
310 |
-
'tip_style' => array(
|
311 |
-
'color' => 'light',
|
312 |
-
'shadow' => true,
|
313 |
-
'rounded' => false,
|
314 |
-
'style' => 'bootstrap',
|
315 |
-
),
|
316 |
-
'tip_position' => array(
|
317 |
-
'my' => 'top left',
|
318 |
-
'at' => 'bottom right',
|
319 |
-
),
|
320 |
-
'tip_effect' => array(
|
321 |
-
'show' => array(
|
322 |
-
'effect' => 'slide',
|
323 |
-
'duration' => '500',
|
324 |
-
'event' => 'mouseover',
|
325 |
-
),
|
326 |
-
'hide' => array(
|
327 |
-
'effect' => 'slide',
|
328 |
-
'duration' => '500',
|
329 |
-
'event' => 'click mouseleave',
|
330 |
-
),
|
331 |
-
),
|
332 |
-
)
|
333 |
-
);
|
334 |
-
|
335 |
-
// SOCIAL ICONS -> Setup custom links in the footer for quick links in your panel footer icons.
|
336 |
-
$this->args['share_icons'][] = array(
|
337 |
-
'url' => 'https://github.com/No3x/wp-mail-logging',
|
338 |
-
'title' => 'Visit us on GitHub',
|
339 |
-
'icon' => 'el-icon-github'
|
340 |
-
//'img' => '', // You can use icon OR img. IMG needs to be a full URL.
|
341 |
-
);
|
342 |
-
$this->args['share_icons'][] = array(
|
343 |
-
'url' => $this->plugin_meta['wp_uri'],
|
344 |
-
'title' => 'Visit us on WordPress',
|
345 |
-
'icon' => 'el-icon-wordpress'
|
346 |
-
);
|
347 |
-
|
348 |
-
// Add content before the form.
|
349 |
-
// $this->args['intro_text'] = __( '<p>This text is displayed above the options panel. It isn\'t required, but more info is always better! The intro_text field accepts all HTML.</p>', 'redux-framework-demo' );
|
350 |
-
|
351 |
-
// Add content after the form.
|
352 |
-
// $this->args['footer_text'] = __( '<p>This text is displayed below the options panel. It isn\'t required, but more info is always better! The footer_text field accepts all HTML.</p>', 'redux-framework-demo' );
|
353 |
-
}
|
354 |
-
}
|
355 |
-
|
356 |
-
global $reduxConfig;
|
357 |
-
} else {
|
358 |
-
echo "The class named Redux_Framework_sample_config has already been called. <strong>Developers, you need to prefix this class with your company name or you'll run into problems!</strong>";
|
359 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace No3x\WPML\Settings;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* ReduxFramework Sample Config File
|
7 |
+
* For full documentation, please visit: http://docs.reduxframework.com/
|
8 |
+
*/
|
9 |
+
|
10 |
+
if (!class_exists('WPML_Redux_Framework_config')) {
|
11 |
+
|
12 |
+
class WPML_Redux_Framework_config {
|
13 |
+
|
14 |
+
public $args = array();
|
15 |
+
public $sections = array();
|
16 |
+
public $theme;
|
17 |
+
public $ReduxFramework;
|
18 |
+
protected $plugin_meta = array();
|
19 |
+
|
20 |
+
public function __construct( $plugin_meta ) {
|
21 |
+
$this->plugin_meta = $plugin_meta;
|
22 |
+
|
23 |
+
if ( ! class_exists( 'ReduxFramework' ) ) {
|
24 |
+
return;
|
25 |
+
}
|
26 |
+
|
27 |
+
// This is needed. Bah WordPress bugs. ;)
|
28 |
+
if ( true == \Redux_Helpers::isTheme( __FILE__ ) ) {
|
29 |
+
$this->initSettings();
|
30 |
+
} else {
|
31 |
+
add_action( 'plugins_loaded', array( $this, 'initSettings' ), 10 );
|
32 |
+
}
|
33 |
+
|
34 |
+
}
|
35 |
+
|
36 |
+
public function initSettings() {
|
37 |
+
|
38 |
+
// Just for demo purposes. Not needed per say.
|
39 |
+
$this->theme = wp_get_theme();
|
40 |
+
|
41 |
+
// Set the default arguments
|
42 |
+
$this->setArguments();
|
43 |
+
|
44 |
+
// Set a few help tabs so you can see how it's done
|
45 |
+
// $this->setHelpTabs();
|
46 |
+
|
47 |
+
// Create the sections and fields
|
48 |
+
$this->setSections();
|
49 |
+
|
50 |
+
if ( ! isset( $this->args['opt_name'] ) ) { // No errors please
|
51 |
+
return;
|
52 |
+
}
|
53 |
+
|
54 |
+
// If Redux is running as a plugin, this will remove the demo notice and links
|
55 |
+
//add_action( 'redux/loaded', array( $this, 'remove_demo' ) );
|
56 |
+
|
57 |
+
// Function to test the compiler hook and demo CSS output.
|
58 |
+
// Above 10 is a priority, but 2 in necessary to include the dynamically generated CSS to be sent to the function.
|
59 |
+
//add_filter('redux/options/'.$this->args['opt_name'].'/compiler', array( $this, 'compiler_action' ), 10, 3);
|
60 |
+
|
61 |
+
// Change the arguments after they've been declared, but before the panel is created
|
62 |
+
//add_filter('redux/options/'.$this->args['opt_name'].'/args', array( $this, 'change_arguments' ) );
|
63 |
+
|
64 |
+
// Change the default value of a field after it's been set, but before it's been useds
|
65 |
+
//add_filter('redux/options/'.$this->args['opt_name'].'/defaults', array( $this,'change_defaults' ) );
|
66 |
+
|
67 |
+
// Dynamically add a section. Can be also used to modify sections/fields
|
68 |
+
//add_filter('redux/options/' . $this->args['opt_name'] . '/sections', array($this, 'dynamic_section'));
|
69 |
+
|
70 |
+
$this->ReduxFramework = new \ReduxFramework( $this->sections, $this->args );
|
71 |
+
}
|
72 |
+
|
73 |
+
// Remove the demo link and the notice of integrated demo from the redux-framework plugin
|
74 |
+
function remove_demo() {
|
75 |
+
|
76 |
+
// Used to hide the demo mode link from the plugin page. Only used when Redux is a plugin.
|
77 |
+
if ( class_exists( 'ReduxFrameworkPlugin' ) ) {
|
78 |
+
remove_filter( 'plugin_row_meta', array(
|
79 |
+
ReduxFrameworkPlugin::instance(),
|
80 |
+
'plugin_metalinks'
|
81 |
+
), null, 2 );
|
82 |
+
|
83 |
+
// Used to hide the activation notice informing users of the demo panel. Only used when Redux is a plugin.
|
84 |
+
remove_action( 'admin_notices', array( ReduxFrameworkPlugin::instance(), 'admin_notices' ) );
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
public function setSections() {
|
89 |
+
|
90 |
+
// ACTUAL DECLARATION OF SECTIONS
|
91 |
+
$this->sections[] = array(
|
92 |
+
'title' => __('General Settings', 'wp-mail-logging'),
|
93 |
+
'desc' => __('', 'wp-mail-logging'),
|
94 |
+
'icon' => 'el-icon-cogs',
|
95 |
+
// 'submenu' => false, // Setting submenu to false on a given section will hide it from the WordPress sidebar menu!
|
96 |
+
'fields' => array(
|
97 |
+
|
98 |
+
array(
|
99 |
+
'id' => 'delete-on-deactivation',
|
100 |
+
'type' => 'switch',
|
101 |
+
'title' => __('Cleanup', 'wp-mail-logging' ),
|
102 |
+
'subtitle' => __('Delete all data on deactivation? (emails and settings)?', 'wp-mail-logging'),
|
103 |
+
'default' => 0,
|
104 |
+
'on' => __(__('Enabled', 'wp-mail-logging' ), 'wp-mail-logging' ),
|
105 |
+
'off' => __(__('Disabled', 'wp-mail-logging' ), 'wp-mail-logging' ),
|
106 |
+
),
|
107 |
+
array(
|
108 |
+
'id' => 'can-see-submission-data',
|
109 |
+
'type' => 'select',
|
110 |
+
'data' => 'capabilities',
|
111 |
+
'default' => 'manage_options',
|
112 |
+
'title' => __('Can See Submission data', 'wp-mail-logging'),
|
113 |
+
'subtitle' => __('Select the minimum role.', 'wp-mail-logging'),
|
114 |
+
),
|
115 |
+
array(
|
116 |
+
'id' => 'datetimeformat-use-wordpress',
|
117 |
+
'type' => 'switch',
|
118 |
+
'title' => __('WordPress Date Time Format', 'wp-mail-logging' ),
|
119 |
+
'subtitle' => sprintf( __( "Use format from WordPress settings (%s)", 'wp-mail-logging' ), date_i18n( $this->wordpress_default_format(), current_time( 'timestamp' ) ) ),
|
120 |
+
'default' => 0,
|
121 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
122 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
123 |
+
),
|
124 |
+
array(
|
125 |
+
'id' => 'preferred-mail-format',
|
126 |
+
'type' => 'select',
|
127 |
+
'options' => array(
|
128 |
+
'html' => 'html',
|
129 |
+
'raw' => 'raw',
|
130 |
+
'json' => 'json'
|
131 |
+
),
|
132 |
+
'default' => 'html',
|
133 |
+
'title' => __('Default Format for Message', 'wp-mail-logging'),
|
134 |
+
'subtitle' => __('Select your preferred display format.', 'wp-mail-logging'),
|
135 |
+
),
|
136 |
+
array(
|
137 |
+
'id' => 'display-host',
|
138 |
+
'type' => 'switch',
|
139 |
+
'title' => __('Display Host', 'wp-mail-logging' ),
|
140 |
+
'subtitle' => __('Display host column in list.', 'wp-mail-logging'),
|
141 |
+
'hint' => array(
|
142 |
+
'title' => 'Host',
|
143 |
+
'content' => 'Display the IP of the host WordPress is running on. This is useful when running it on multiple servers at the same time.',
|
144 |
+
),
|
145 |
+
'default' => 0,
|
146 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
147 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
148 |
+
),
|
149 |
+
array(
|
150 |
+
'id' => 'section-log-rotation-start',
|
151 |
+
'type' => 'section',
|
152 |
+
'title' => __('Log Rotation', 'wp-mail-logging' ),
|
153 |
+
'subtitle' => __('Save space by deleting logs regularly.', 'wp-mail-logging'),
|
154 |
+
'indent' => true, // Indent all options below until the next 'section' option is set.
|
155 |
+
),
|
156 |
+
array(
|
157 |
+
'id' => 'log-rotation-limit-amout',
|
158 |
+
'type' => 'switch',
|
159 |
+
'title' => __('Cleanup by Amount', 'wp-mail-logging' ),
|
160 |
+
'subtitle' => __('Setup a automated cleanup routine!', 'wp-mail-logging'),
|
161 |
+
'default' => 0,
|
162 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
163 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
164 |
+
),
|
165 |
+
array(
|
166 |
+
'id' => 'log-rotation-limit-amout-keep',
|
167 |
+
'type' => 'slider',
|
168 |
+
'required' => array('log-rotation-limit-amout', '=', '1'),
|
169 |
+
'title' => __('Amount', 'wp-mail-logging' ),
|
170 |
+
'subtitle' => __('When should mails are deleted?', 'wp-mail-logging'),
|
171 |
+
'desc' => __('Cleanup when the stored mails exceed...', 'wp-mail-logging'),
|
172 |
+
'default' => 75,
|
173 |
+
'min' => 25,
|
174 |
+
'step' => 50,
|
175 |
+
'max' => 3000,
|
176 |
+
'display_value' => 'text'
|
177 |
+
),
|
178 |
+
array(
|
179 |
+
'id' => 'log-rotation-delete-time',
|
180 |
+
'type' => 'switch',
|
181 |
+
'title' => __('Cleanup by Time', 'wp-mail-logging' ),
|
182 |
+
'subtitle' => __('Setup a automated cleanup routine!', 'wp-mail-logging'),
|
183 |
+
'default' => 0,
|
184 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
185 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
186 |
+
),
|
187 |
+
array(
|
188 |
+
'id' => 'log-rotation-delete-time-days',
|
189 |
+
'type' => 'slider',
|
190 |
+
'required' => array('log-rotation-delete-time', '=', '1'),
|
191 |
+
'title' => __('Time', 'wp-mail-logging' ),
|
192 |
+
'subtitle' => __('When should mails are deleted?', 'wp-mail-logging'),
|
193 |
+
'desc' => __('Delete mails older than days...', 'wp-mail-logging'),
|
194 |
+
'default' => 30,
|
195 |
+
'min' => 1,
|
196 |
+
'step' => 7,
|
197 |
+
'max' => 400,
|
198 |
+
'display_value' => 'text'
|
199 |
+
),
|
200 |
+
array(
|
201 |
+
'id' => 'section-log-rotation-end',
|
202 |
+
'type' => 'section',
|
203 |
+
'indent' => false // Indent all options below until the next 'section' option is set.
|
204 |
+
),
|
205 |
+
),
|
206 |
+
);
|
207 |
+
}
|
208 |
+
|
209 |
+
public function wordpress_default_format()
|
210 |
+
{
|
211 |
+
$date_format = get_option( 'date_format' );
|
212 |
+
$time_format = get_option( 'time_format' );
|
213 |
+
$date_format = empty( $date_format ) ? 'F j, Y' : $date_format;
|
214 |
+
$time_format = empty( $time_format ) ? 'g:i a' : $time_format;
|
215 |
+
return "{$date_format} {$time_format}";
|
216 |
+
}
|
217 |
+
|
218 |
+
/**
|
219 |
+
* All the possible arguments for Redux.
|
220 |
+
* For full documentation on arguments, please refer to: https://github.com/ReduxFramework/ReduxFramework/wiki/Arguments
|
221 |
+
* */
|
222 |
+
public function setArguments() {
|
223 |
+
|
224 |
+
$theme = wp_get_theme(); // For use with some settings. Not necessary.
|
225 |
+
|
226 |
+
$this->args = array(
|
227 |
+
// TYPICAL -> Change these values as you need/desire
|
228 |
+
'opt_name' => 'wpml_settings',
|
229 |
+
// This is where your data is stored in the database and also becomes your global variable name.
|
230 |
+
'display_name' => 'WP Mail Logging Settings',
|
231 |
+
// Name that appears at the top of your panel
|
232 |
+
'display_version' => $this->plugin_meta['version_installed'],
|
233 |
+
// Version that appears at the top of your panel
|
234 |
+
'menu_type' => 'submenu',
|
235 |
+
//Specify if the admin menu should appear or not. Options: menu or submenu (Under appearance only)
|
236 |
+
'allow_sub_menu' => true,
|
237 |
+
// Show the sections below the admin menu item or not
|
238 |
+
'menu_title' => 'Settings',
|
239 |
+
'page_title' => $this->plugin_meta['display_name'],
|
240 |
+
// You will need to generate a Google API key to use this feature.
|
241 |
+
// Please visit: https://developers.google.com/fonts/docs/developer_api#Auth
|
242 |
+
'google_api_key' => '',
|
243 |
+
// Set it you want google fonts to update weekly. A google_api_key value is required.
|
244 |
+
'google_update_weekly' => false,
|
245 |
+
// Must be defined to add google fonts to the typography module
|
246 |
+
'async_typography' => true,
|
247 |
+
// Use a asynchronous font on the front end or font string
|
248 |
+
//'disable_google_fonts_link' => true, // Disable this in case you want to create your own google fonts loader
|
249 |
+
'admin_bar' => false,
|
250 |
+
// Show the panel pages on the admin bar
|
251 |
+
'admin_bar_icon' => 'dashicons-portfolio',
|
252 |
+
// Choose an icon for the admin bar menu
|
253 |
+
'admin_bar_priority' => 50,
|
254 |
+
// Choose an priority for the admin bar menu
|
255 |
+
'global_variable' => '',
|
256 |
+
// Set a different name for your global variable other than the opt_name
|
257 |
+
'dev_mode' => false,
|
258 |
+
// Show the time the page took to load, etc
|
259 |
+
'update_notice' => true,
|
260 |
+
// If dev_mode is enabled, will notify developer of updated versions available in the GitHub Repo
|
261 |
+
'customizer' => false,
|
262 |
+
// Enable basic customizer support
|
263 |
+
//'open_expanded' => true, // Allow you to start the panel in an expanded way initially.
|
264 |
+
//'disable_save_warn' => true, // Disable the save warning when a user changes a field
|
265 |
+
|
266 |
+
// OPTIONAL -> Give you extra features
|
267 |
+
'page_priority' => null,
|
268 |
+
// Order where the menu appears in the admin area. If there is any conflict, something will not show. Warning.
|
269 |
+
'page_parent' => 'wpml_plugin_log',
|
270 |
+
// For a full list of options, visit: http://codex.wordpress.org/Function_Reference/add_submenu_page#Parameters
|
271 |
+
'page_permissions' => 'manage_options',
|
272 |
+
// Permissions needed to access the options panel.
|
273 |
+
'menu_icon' => '',
|
274 |
+
// Specify a custom URL to an icon
|
275 |
+
'last_tab' => '',
|
276 |
+
// Force your panel to always open to a specific tab (by id)
|
277 |
+
'page_icon' => 'icon-themes',
|
278 |
+
// Icon displayed in the admin panel next to your menu_title
|
279 |
+
'page_slug' => 'wpml_plugin_settings',
|
280 |
+
// Page slug used to denote the panel
|
281 |
+
'save_defaults' => true,
|
282 |
+
// On load save the defaults to DB before user clicks save or not
|
283 |
+
'default_show' => false,
|
284 |
+
// If true, shows the default value next to each field that is not the default value.
|
285 |
+
'default_mark' => '*',
|
286 |
+
// What to print by the field's title if the value shown is default. Suggested: *
|
287 |
+
'show_import_export' => true,
|
288 |
+
// Shows the Import/Export panel when not used as a field.
|
289 |
+
|
290 |
+
// CAREFUL -> These options are for advanced use only
|
291 |
+
'transient_time' => 60 * MINUTE_IN_SECONDS,
|
292 |
+
'output' => true,
|
293 |
+
// Global shut-off for dynamic CSS output by the framework. Will also disable google fonts output
|
294 |
+
'output_tag' => true,
|
295 |
+
// Allows dynamic CSS to be generated for customizer and google fonts, but stops the dynamic CSS from going to the head
|
296 |
+
// 'footer_credit' => '', // Disable the footer credit of Redux. Please leave if you can help it.
|
297 |
+
|
298 |
+
// FUTURE -> Not in use yet, but reserved or partially implemented. Use at your own risk.
|
299 |
+
'database' => '',
|
300 |
+
// possible: options, theme_mods, theme_mods_expanded, transient. Not fully functional, warning!
|
301 |
+
'system_info' => false,
|
302 |
+
// REMOVE
|
303 |
+
|
304 |
+
// HINTS
|
305 |
+
'hints' => array(
|
306 |
+
'icon' => 'el el-question-sign',
|
307 |
+
'icon_position' => 'right',
|
308 |
+
'icon_color' => 'lightgray',
|
309 |
+
'icon_size' => 'normal',
|
310 |
+
'tip_style' => array(
|
311 |
+
'color' => 'light',
|
312 |
+
'shadow' => true,
|
313 |
+
'rounded' => false,
|
314 |
+
'style' => 'bootstrap',
|
315 |
+
),
|
316 |
+
'tip_position' => array(
|
317 |
+
'my' => 'top left',
|
318 |
+
'at' => 'bottom right',
|
319 |
+
),
|
320 |
+
'tip_effect' => array(
|
321 |
+
'show' => array(
|
322 |
+
'effect' => 'slide',
|
323 |
+
'duration' => '500',
|
324 |
+
'event' => 'mouseover',
|
325 |
+
),
|
326 |
+
'hide' => array(
|
327 |
+
'effect' => 'slide',
|
328 |
+
'duration' => '500',
|
329 |
+
'event' => 'click mouseleave',
|
330 |
+
),
|
331 |
+
),
|
332 |
+
)
|
333 |
+
);
|
334 |
+
|
335 |
+
// SOCIAL ICONS -> Setup custom links in the footer for quick links in your panel footer icons.
|
336 |
+
$this->args['share_icons'][] = array(
|
337 |
+
'url' => 'https://github.com/No3x/wp-mail-logging',
|
338 |
+
'title' => 'Visit us on GitHub',
|
339 |
+
'icon' => 'el-icon-github'
|
340 |
+
//'img' => '', // You can use icon OR img. IMG needs to be a full URL.
|
341 |
+
);
|
342 |
+
$this->args['share_icons'][] = array(
|
343 |
+
'url' => $this->plugin_meta['wp_uri'],
|
344 |
+
'title' => 'Visit us on WordPress',
|
345 |
+
'icon' => 'el-icon-wordpress'
|
346 |
+
);
|
347 |
+
|
348 |
+
// Add content before the form.
|
349 |
+
// $this->args['intro_text'] = __( '<p>This text is displayed above the options panel. It isn\'t required, but more info is always better! The intro_text field accepts all HTML.</p>', 'redux-framework-demo' );
|
350 |
+
|
351 |
+
// Add content after the form.
|
352 |
+
// $this->args['footer_text'] = __( '<p>This text is displayed below the options panel. It isn\'t required, but more info is always better! The footer_text field accepts all HTML.</p>', 'redux-framework-demo' );
|
353 |
+
}
|
354 |
+
}
|
355 |
+
|
356 |
+
global $reduxConfig;
|
357 |
+
} else {
|
358 |
+
echo "The class named Redux_Framework_sample_config has already been called. <strong>Developers, you need to prefix this class with your company name or you'll run into problems!</strong>";
|
359 |
+
}
|
{inc → src/inc}/redux/admin-init.php
RENAMED
@@ -1,8 +1,8 @@
|
|
1 |
<?php
|
2 |
|
3 |
// Load the embedded Redux Framework
|
4 |
-
if ( file_exists( dirname( __FILE__ ).'
|
5 |
-
require_once dirname(__FILE__).'
|
6 |
}
|
7 |
// Load the theme/plugin options
|
8 |
if ( file_exists( dirname( __FILE__ ) . '/options-init.php' ) ) {
|
1 |
<?php
|
2 |
|
3 |
// Load the embedded Redux Framework
|
4 |
+
if ( file_exists( dirname( __FILE__ ).'/../../../lib/vendor/redux-framework/framework.php' ) ) {
|
5 |
+
require_once dirname(__FILE__) . '/../../../lib/vendor/redux-framework/framework.php';
|
6 |
}
|
7 |
// Load the theme/plugin options
|
8 |
if ( file_exists( dirname( __FILE__ ) . '/options-init.php' ) ) {
|
wp-mail-logging.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP Mail Logging
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/wp-mail-logging/
|
5 |
Support URI: https://github.com/No3x/wp-mail-logging/issues
|
6 |
-
Version: 1.8.
|
7 |
Author: Christian Zöller
|
8 |
Author URI: http://no3x.de/
|
9 |
Description: Logs each email sent by WordPress.
|
@@ -95,10 +95,9 @@ if (WPML_PhpVersionCheck()) {
|
|
95 |
$loader->register();
|
96 |
|
97 |
// Add our namespace and the folder it maps to
|
98 |
-
require_once __DIR__ . '/inc/redux/admin-init.php';
|
99 |
-
$loader->addNamespace('No3x\\WPML\\', __DIR__ );
|
100 |
-
$loader->addNamespace('No3x\\WPML\\
|
101 |
-
$loader->addNamespace('No3x\\WPML\\Settings\\', __DIR__ . '/inc/redux');
|
102 |
$loader->addNamespace('No3x\\WPML\\ORM\\', __DIR__ . '/lib/vendor/brandonwamboldt/wp-orm/src');
|
103 |
$loader->addNamespace('No3x\\WPML\\Pimple\\', __DIR__ . '/lib/vendor/pimple/pimple/src');
|
104 |
if( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
|
3 |
Plugin Name: WP Mail Logging
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/wp-mail-logging/
|
5 |
Support URI: https://github.com/No3x/wp-mail-logging/issues
|
6 |
+
Version: 1.8.5
|
7 |
Author: Christian Zöller
|
8 |
Author URI: http://no3x.de/
|
9 |
Description: Logs each email sent by WordPress.
|
95 |
$loader->register();
|
96 |
|
97 |
// Add our namespace and the folder it maps to
|
98 |
+
require_once __DIR__ . '/src/inc/redux/admin-init.php';
|
99 |
+
$loader->addNamespace('No3x\\WPML\\', __DIR__ . '/src' );
|
100 |
+
$loader->addNamespace('No3x\\WPML\\Settings\\', __DIR__ . '/src/inc/redux');
|
|
|
101 |
$loader->addNamespace('No3x\\WPML\\ORM\\', __DIR__ . '/lib/vendor/brandonwamboldt/wp-orm/src');
|
102 |
$loader->addNamespace('No3x\\WPML\\Pimple\\', __DIR__ . '/lib/vendor/pimple/pimple/src');
|
103 |
if( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
|