Version Description
- New: Error status from mail implementation is logged
- New: Resend mail
- New: Added translation files
- New: Added translation for de_DE and zh_CN
- Fix: raw mode of message renders attachments as text
- Fix: fallback to raw mode for json mode if mail is containing html
- Tweak: Pretty print json
=
Download this release
Release Info
Developer | No3x |
Plugin | WP Mail Logging |
Version | 1.8.0 |
Comparing to | |
See all releases |
Code changes from version 1.7.0 to 1.8.0
- WPML_API_Example.php +65 -65
- WPML_DI_Container.php +12 -12
- WPML_Email_Log_List.php +471 -428
- WPML_Init.php +121 -121
- WPML_InstallIndicator.php +142 -157
- WPML_LifeCycle.php +181 -184
- WPML_LogRotation.php +108 -97
- WPML_OptionsManager.php +575 -575
- WPML_Plugin.php +257 -216
- WPML_ShortCodeLoader.php +35 -35
- WPML_ShortCodeScriptLoader.php +26 -26
- WPML_Utils.php +94 -94
- css/modal.css +16 -7
- css/modal.less +12 -2
- inc/class-wp-list-table.php +974 -974
- inc/redux/WPML_Redux_Framework_config.php +479 -479
- inc/redux/admin-init.php +2 -2
- languages/wp-mail-logging-de_DE.mo +0 -0
- languages/wp-mail-logging-de_DE.po +375 -0
- languages/wp-mail-logging-zh_CN.mo +0 -0
- languages/wp-mail-logging-zh_CN.po +371 -0
- languages/wp-mail-logging.pot +371 -0
- model/WPML_Mail.php +6 -1
- readme.txt +29 -11
- wp-mail-logging.php +34 -38
WPML_API_Example.php
CHANGED
@@ -13,73 +13,73 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
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 |
-
|
21 |
-
|
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 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
//,array('test2' => __( 'test2', 'wpml' ) ) // ...
|
40 |
-
);
|
41 |
-
}
|
42 |
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
return '';
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
CHANGED
@@ -10,15 +10,15 @@ use No3x\WPML\Pimple\Container;
|
|
10 |
|
11 |
class WPML_DI_Container extends Container {
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
}
|
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_Log_List.php
CHANGED
@@ -3,6 +3,7 @@
|
|
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;
|
@@ -11,7 +12,7 @@ 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 |
-
|
15 |
}
|
16 |
|
17 |
/**
|
@@ -21,61 +22,62 @@ if ( ! class_exists( 'WP_List_Table' ) ) {
|
|
21 |
*/
|
22 |
class WPML_Email_Log_List extends \WP_List_Table {
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
|
|
79 |
|
80 |
/* @var $instance WPML_Plugin */
|
81 |
$instance = WPML_Init::getInstance()->getService( 'plugin' );
|
@@ -85,382 +87,423 @@ class WPML_Email_Log_List extends \WP_List_Table {
|
|
85 |
$posAfterTimestamp = array_search('timestamp', array_keys($columns) ) + 1;
|
86 |
$columns = array_merge(
|
87 |
array_slice( $columns, 0, $posAfterTimestamp),
|
88 |
-
[ 'host' => __( 'Host', '
|
89 |
array_slice( $columns, $posAfterTimestamp )
|
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 |
-
|
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 |
-
|
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 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
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 |
-
|
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 |
-
|
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 |
/* @var $instance WPML_Email_Log_List */
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
}
|
466 |
}
|
3 |
namespace No3x\WPML;
|
4 |
|
5 |
use No3x\WPML\Model\WPML_Mail as Mail;
|
6 |
+
use No3x\WPML\Model\WPML_Mail;
|
7 |
|
8 |
// Exit if accessed directly.
|
9 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
12 |
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
|
13 |
|
14 |
if ( ! class_exists( 'WP_List_Table' ) ) {
|
15 |
+
require_once( plugin_dir_path( __FILE__ ) . 'inc/class-wp-list-table.php' );
|
16 |
}
|
17 |
|
18 |
/**
|
22 |
*/
|
23 |
class WPML_Email_Log_List extends \WP_List_Table {
|
24 |
|
25 |
+
const NONCE_LIST_TABLE = 'wpml-list_table';
|
26 |
+
private $supported_formats = array();
|
27 |
+
/**
|
28 |
+
* Initializes the List Table
|
29 |
+
* @since 1.0
|
30 |
+
*/
|
31 |
+
function __construct( $supported_formats = array() ) {
|
32 |
+
$this->supported_formats = $supported_formats;
|
33 |
+
}
|
34 |
+
|
35 |
+
function addActionsAndFilters() {
|
36 |
+
add_action( 'admin_init', array( $this, 'init') );
|
37 |
+
add_filter( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, function() {
|
38 |
+
return $this->supported_formats;
|
39 |
+
} );
|
40 |
+
add_action( 'wp_ajax_wpml_email_get', __CLASS__ . '::ajax_wpml_email_get' );
|
41 |
+
}
|
42 |
+
|
43 |
+
function init() {
|
44 |
+
global $status, $page, $hook_suffix;
|
45 |
+
|
46 |
+
parent::__construct( array(
|
47 |
+
'singular' => 'email', // singular name of the listed records
|
48 |
+
'plural' => 'emails', // plural name of the listed records
|
49 |
+
'ajax' => false, // does this table support ajax?
|
50 |
+
) );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Is displayed if no item is available to render
|
55 |
+
* @since 1.0
|
56 |
+
* @see WP_List_Table::no_items()
|
57 |
+
*/
|
58 |
+
function no_items() {
|
59 |
+
_e( 'No email found.', 'wp-mail-logging' );
|
60 |
+
return;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Defines the available columns.
|
65 |
+
* @since 1.0
|
66 |
+
* @see WP_List_Table::get_columns()
|
67 |
+
*/
|
68 |
+
function get_columns() {
|
69 |
+
$columns = array(
|
70 |
+
'cb' => '<input type="checkbox" />',
|
71 |
+
'mail_id' => __( 'ID', 'wp-mail-logging' ),
|
72 |
+
'timestamp' => __( 'Time', 'wp-mail-logging' ),
|
73 |
+
'receiver' => __( 'Receiver', 'wp-mail-logging' ),
|
74 |
+
'subject' => __( 'Subject', 'wp-mail-logging' ),
|
75 |
+
'message' => __( 'Message', 'wp-mail-logging' ),
|
76 |
+
'headers' => __( 'Headers', 'wp-mail-logging' ),
|
77 |
+
'attachments' => __( 'Attachments', 'wp-mail-logging' ),
|
78 |
+
'error' => __( 'Error', 'wp-mail-logging' ),
|
79 |
+
'plugin_version' => __( 'Plugin Version', 'wp-mail-logging' ),
|
80 |
+
);
|
81 |
|
82 |
/* @var $instance WPML_Plugin */
|
83 |
$instance = WPML_Init::getInstance()->getService( 'plugin' );
|
87 |
$posAfterTimestamp = array_search('timestamp', array_keys($columns) ) + 1;
|
88 |
$columns = array_merge(
|
89 |
array_slice( $columns, 0, $posAfterTimestamp),
|
90 |
+
[ 'host' => __( 'Host', 'wp-mail-logging' ) ],
|
91 |
array_slice( $columns, $posAfterTimestamp )
|
92 |
);
|
93 |
}
|
94 |
|
95 |
+
// Give a plugin the chance to edit the columns.
|
96 |
+
$columns = apply_filters( WPML_Plugin::HOOK_LOGGING_COLUMNS, $columns );
|
97 |
+
|
98 |
+
$reserved = array( '_title', 'comment', 'media', 'name', 'title', 'username', 'blogname' );
|
99 |
+
|
100 |
+
// Show message for reserved column names.
|
101 |
+
foreach ( $reserved as $reserved_key ) {
|
102 |
+
if ( array_key_exists( $reserved_key, $columns ) ) {
|
103 |
+
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!";
|
104 |
+
break;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
return $columns;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Define which columns are hidden
|
112 |
+
* @since 1.0
|
113 |
+
* @return array
|
114 |
+
*/
|
115 |
+
function get_hidden_columns() {
|
116 |
+
return array(
|
117 |
+
'plugin_version',
|
118 |
+
'mail_id',
|
119 |
+
);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Sanitize orderby parameter.
|
124 |
+
* @s
|
125 |
+
* @return string sanitized orderby parameter
|
126 |
+
*/
|
127 |
+
private function sanitize_orderby() {
|
128 |
+
return WPML_Utils::sanitize_expected_value( ( !empty( $_GET['orderby'] ) ) ? $_GET['orderby'] : null, $this->get_sortable_columns(), 'mail_id');
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Sanitize order parameter.
|
133 |
+
* @return string sanitized order parameter
|
134 |
+
*/
|
135 |
+
private function sanitize_order() {
|
136 |
+
return WPML_Utils::sanitize_expected_value( ( !empty( $_GET['order'] ) ) ? $_GET['order'] : null, array('desc', 'asc'), 'desc');
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Prepares the items for rendering
|
141 |
+
* @since 1.0
|
142 |
+
* @param string|boolean $search string you want to search for. Default false.
|
143 |
+
* @see WP_List_Table::prepare_items()
|
144 |
+
*/
|
145 |
+
function prepare_items( $search = false ) {
|
146 |
+
$orderby = $this->sanitize_orderby();
|
147 |
+
$order = $this->sanitize_order();
|
148 |
+
|
149 |
+
$columns = $this->get_columns();
|
150 |
+
$hidden = $this->get_hidden_columns();
|
151 |
+
$sortable = $this->get_sortable_columns();
|
152 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
153 |
+
|
154 |
+
$this->process_bulk_action();
|
155 |
+
|
156 |
+
$per_page = $this->get_items_per_page( 'per_page', 25 );
|
157 |
+
$current_page = $this->get_pagenum();
|
158 |
+
$offset = ( $current_page - 1 ) * $per_page;
|
159 |
+
|
160 |
+
$total_items = Mail::query()
|
161 |
+
->search( $search )
|
162 |
+
->find( true );
|
163 |
+
|
164 |
+
$mails = Mail::query()
|
165 |
+
->search( $search )
|
166 |
+
->sort_by( $orderby )
|
167 |
+
->order( $order )
|
168 |
+
->limit( $per_page )
|
169 |
+
->offset( $offset )
|
170 |
+
->find();
|
171 |
+
|
172 |
+
foreach ( $mails as $mail ) {
|
173 |
+
/* @var $mail Mail */
|
174 |
+
$this->items[] = $mail->to_array();
|
175 |
+
}
|
176 |
+
|
177 |
+
$this->set_pagination_args( array(
|
178 |
+
'total_items' => $total_items, // The total number of items.
|
179 |
+
'per_page' => $per_page, // Number of items per page.
|
180 |
+
) );
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Renders the cell.
|
185 |
+
* 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)
|
186 |
+
* @since 1.0
|
187 |
+
* @param array $item The current item.
|
188 |
+
* @param string $column_name The current column name.
|
189 |
+
* @return string The cell content
|
190 |
+
*/
|
191 |
+
function column_default( $item, $column_name ) {
|
192 |
+
switch ( $column_name ) {
|
193 |
+
case 'mail_id':
|
194 |
+
case 'timestamp':
|
195 |
+
case 'host':
|
196 |
+
case 'subject':
|
197 |
+
case 'message':
|
198 |
+
case 'headers':
|
199 |
+
case 'attachments':
|
200 |
+
case 'error':
|
201 |
+
case 'plugin_version':
|
202 |
+
case 'receiver':
|
203 |
+
return $item[ $column_name ];
|
204 |
+
default:
|
205 |
+
// 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).
|
206 |
+
return ( is_array( $res = apply_filters( WPML_Plugin::HOOK_LOGGING_COLUMNS_RENDER, $item, $column_name ) ) ) ? '' : $res;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Sanitize message to remove unsafe html.
|
212 |
+
* @since 1.5.1
|
213 |
+
* @param string $message unsafe message.
|
214 |
+
* @return string safe message.
|
215 |
+
*/
|
216 |
+
function sanitize_message( $message ) {
|
217 |
+
$allowed_tags = wp_kses_allowed_html( 'post' );
|
218 |
+
$allowed_tags['a']['data-message'] = true;
|
219 |
+
$allowed_tags['style'][''] = true;
|
220 |
+
return wp_kses( $message, $allowed_tags );
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Renders the message column.
|
225 |
+
* @since 1.3
|
226 |
+
* @param array $item The current item.
|
227 |
+
* @return string
|
228 |
+
*/
|
229 |
+
function column_message( $item ) {
|
230 |
+
if ( empty( $item['message'] ) ) {
|
231 |
+
return '';
|
232 |
+
}
|
233 |
+
$content = $item['mail_id'];
|
234 |
+
$message = '<a class="wp-mail-logging-view-message button button-secondary" href="#" data-mail-id="' . esc_attr( $content ) . '">View</a>';
|
235 |
+
return $message;
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Renders the timestamp column.
|
240 |
+
* @since 1.5.0
|
241 |
+
* @param array $item The current item.
|
242 |
+
* @return string
|
243 |
+
*/
|
244 |
+
function column_timestamp( $item ) {
|
245 |
+
return date_i18n( apply_filters( 'wpml_get_date_time_format', '' ), strtotime( $item['timestamp'] ) );
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Renders the attachment column in compbat mode for mails prior 1.6.0.
|
250 |
+
* @since 1.6.0
|
251 |
+
* @param array $item The current item.
|
252 |
+
* @return string The attachment column.
|
253 |
+
*/
|
254 |
+
function column_attachments_compat_152( $item ) {
|
255 |
+
$attachment_append = '';
|
256 |
+
$attachments = explode( ',\n', $item['attachments'] );
|
257 |
+
$attachments = is_array( $attachments ) ? $attachments : array( $attachments );
|
258 |
+
foreach ( $attachments as $attachment ) {
|
259 |
+
// $attachment can be an empty string ''.
|
260 |
+
if ( ! empty( $attachment ) ) {
|
261 |
+
$filename = basename( $attachment );
|
262 |
+
$attachment_path = WP_CONTENT_DIR . $attachment;
|
263 |
+
$attachment_url = WP_CONTENT_URL . $attachment;
|
264 |
+
if ( is_file( $attachment_path ) ) {
|
265 |
+
$attachment_append .= '<a href="' . $attachment_url . '" title="' . $filename . '">' . WPML_Utils::generate_attachment_icon( $attachment_path ) . '</a> ';
|
266 |
+
} else {
|
267 |
+
$message = sprintf( __( 'Attachment %s is not present', 'wp-mail-logging' ), $filename );
|
268 |
+
$attachment_append .= '<i class="fa fa-times" title="' . $message . '"></i>';
|
269 |
+
}
|
270 |
+
}
|
271 |
+
}
|
272 |
+
return $attachment_append;
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Renders the attachment column.
|
277 |
+
* @since 1.3
|
278 |
+
* @param array $item The current item.
|
279 |
+
* @return string The attachment column.
|
280 |
+
*/
|
281 |
+
function column_attachments( $item ) {
|
282 |
+
|
283 |
+
if ( version_compare( trim( $item ['plugin_version'] ), '1.6.0', '<' ) ) {
|
284 |
+
return $this->column_attachments_compat_152( $item );
|
285 |
+
}
|
286 |
+
|
287 |
+
$attachment_append = '';
|
288 |
+
$attachments = explode( ',\n', $item['attachments'] );
|
289 |
+
$attachments = is_array( $attachments ) ? $attachments : array( $attachments );
|
290 |
+
foreach ( $attachments as $attachment ) {
|
291 |
+
// $attachment can be an empty string ''.
|
292 |
+
if ( ! empty( $attachment ) ) {
|
293 |
+
$filename = basename( $attachment );
|
294 |
+
$basename = '/uploads';
|
295 |
+
$attachment_path = WP_CONTENT_DIR . $basename . $attachment;
|
296 |
+
$attachment_url = WP_CONTENT_URL . $basename . $attachment;
|
297 |
+
|
298 |
+
if ( is_file( $attachment_path ) ) {
|
299 |
+
$attachment_append .= '<a href="' . $attachment_url . '" title="' . $filename . '">' . WPML_Utils::generate_attachment_icon( $attachment_path ) . '</a> ';
|
300 |
+
} else {
|
301 |
+
$message = sprintf( __( 'Attachment %s is not present', 'wp-mail-logging' ), $filename );
|
302 |
+
$attachment_append .= '<i class="fa fa-times" title="' . $message . '"></i>';
|
303 |
+
}
|
304 |
+
}
|
305 |
+
}
|
306 |
+
return $attachment_append;
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Renders the error column.
|
311 |
+
* @since 1.8.0
|
312 |
+
* @param $item
|
313 |
+
* @return string
|
314 |
+
*/
|
315 |
+
function column_error($item ) {
|
316 |
+
$error = $item['error'];
|
317 |
+
if( empty($error)) return "";
|
318 |
+
$errorMessage = is_array($error) ? join(',', $error) : $error;
|
319 |
+
return "<i class='fa fa-exclamation-circle' title='{$errorMessage}' aria-hidden='true'></i>";
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Renders all components of the mail.
|
324 |
+
* @since 1.3
|
325 |
+
* @param array $item The current item.
|
326 |
+
* @return string The mail as html
|
327 |
+
*/
|
328 |
+
function render_mail( $item ) {
|
329 |
+
$mailAppend = '';
|
330 |
+
foreach ( $item as $key => $value ) {
|
331 |
+
if ( array_key_exists( $key, $this->get_columns() ) && ! in_array( $key, $this->get_hidden_columns() ) ) {
|
332 |
+
$display = $this->get_columns();
|
333 |
+
$column_name = $key;
|
334 |
+
$title = "<span class=\"title\">{$display[$key]}: </span>";
|
335 |
+
$content = '';
|
336 |
+
if ( 'message' !== $column_name && method_exists( $this, 'column_' . $column_name ) ) {
|
337 |
+
if( 'error' === $column_name || 'attachments' === $column_name ) {
|
338 |
+
// don't render with icons and stuff, just plain
|
339 |
+
$content .= is_array($item[$column_name]) ? join("\n", $item[$column_name]) : $item[$column_name];
|
340 |
+
} else {
|
341 |
+
$content .= call_user_func( array( $this, 'column_' . $column_name ), $item );
|
342 |
+
}
|
343 |
+
} else {
|
344 |
+
$content .= $this->column_default( $item, $column_name );
|
345 |
+
}
|
346 |
+
$mailAppend .= $title . htmlentities( $content );
|
347 |
+
}
|
348 |
+
}
|
349 |
+
|
350 |
+
return $mailAppend;
|
351 |
+
}
|
352 |
+
|
353 |
+
/**
|
354 |
+
* Renders all components of the mail.
|
355 |
+
* @since 1.6.0
|
356 |
+
* @param array $item The current item.
|
357 |
+
* @return string The mail as html
|
358 |
+
*/
|
359 |
+
function render_mail_html( $item ) {
|
360 |
+
$mailAppend = '';
|
361 |
+
foreach ( $item as $key => $value ) {
|
362 |
+
if ( array_key_exists( $key, $this->get_columns() ) && ! in_array( $key, $this->get_hidden_columns() ) ) {
|
363 |
+
$display = $this->get_columns();
|
364 |
+
$column_name = $key;
|
365 |
+
$mailAppend .= "<span class=\"title\">{$display[$key]}: </span>";
|
366 |
+
if ( 'message' !== $column_name && method_exists( $this, 'column_' . $column_name ) ) {
|
367 |
+
$mailAppend .= call_user_func( array( $this, 'column_' . $column_name ), $item );
|
368 |
+
} else {
|
369 |
+
$mailAppend .= $this->column_default( $item, $column_name );
|
370 |
+
}
|
371 |
+
}
|
372 |
+
}
|
373 |
+
return $mailAppend;
|
374 |
+
}
|
375 |
+
/**
|
376 |
+
* Defines available bulk actions.
|
377 |
+
* @since 1.0
|
378 |
+
* @see WP_List_Table::get_bulk_actions()
|
379 |
+
*/
|
380 |
+
function get_bulk_actions() {
|
381 |
+
$actions = array(
|
382 |
+
'delete' => 'Delete',
|
383 |
+
'resend' => 'Resend'
|
384 |
+
);
|
385 |
+
return $actions;
|
386 |
+
}
|
387 |
+
|
388 |
+
/**
|
389 |
+
* Processes bulk actions.
|
390 |
+
* @since 1.0
|
391 |
+
*/
|
392 |
+
function process_bulk_action() {
|
393 |
+
if ( false === $this->current_action() ) {
|
394 |
+
return;
|
395 |
+
}
|
396 |
+
|
397 |
+
if ( check_admin_referer( WPML_Email_Log_List::NONCE_LIST_TABLE, WPML_Email_Log_List::NONCE_LIST_TABLE . '_nonce' ) ) {
|
398 |
+
$name = $this->_args['singular'];
|
399 |
+
|
400 |
+
// Detect when a bulk action is being triggered.
|
401 |
+
if ( 'delete' === $this->current_action() ) {
|
402 |
+
foreach ( $_REQUEST[$name] as $item_id ) {
|
403 |
+
$mail = Mail::find_one( $item_id );
|
404 |
+
if ( false !== $mail ) {
|
405 |
+
$mail->delete();
|
406 |
+
}
|
407 |
+
}
|
408 |
+
} else if ( 'resend' == $this->current_action() ) {
|
409 |
+
foreach ( $_REQUEST[$name] as $item_id ) {
|
410 |
+
$mail = Mail::find_one( $item_id );
|
411 |
+
if ( false !== $mail ) {
|
412 |
+
$this->resend_email( $mail );
|
413 |
+
}
|
414 |
+
}
|
415 |
+
}
|
416 |
+
}
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Send logged email via wp_mail
|
421 |
+
* @param WPML_Mail $mail the email object to resend
|
422 |
+
* @since 1.8.0
|
423 |
+
*/
|
424 |
+
function resend_email( $mail ) {
|
425 |
+
wp_mail( $mail->get_receiver(), $mail->get_subject(), $mail->get_message(), $mail->get_headers(), $mail->get_attachments() ) ;
|
426 |
+
}
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Render the cb column
|
430 |
+
* @since 1.0
|
431 |
+
* @param array $item The current item.
|
432 |
+
* @return string the rendered cb cell content
|
433 |
+
*/
|
434 |
+
function column_cb($item) {
|
435 |
+
$name = $this->_args['singular'];
|
436 |
+
return sprintf(
|
437 |
+
'<input type="checkbox" name="%1$s[]" value="%2$s" />', $name, $item['mail_id']
|
438 |
+
);
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Define the sortable columns
|
443 |
+
* @since 1.0
|
444 |
+
* @return array
|
445 |
+
*/
|
446 |
+
function get_sortable_columns() {
|
447 |
+
return array(
|
448 |
+
// Description: column_name => array( 'display_name', true[asc] | false[desc] ).
|
449 |
+
'mail_id' => array( 'mail_id', false ),
|
450 |
+
'timestamp' => array( 'timestamp', true ),
|
451 |
+
'host' => array( 'host', true ),
|
452 |
+
'receiver' => array( 'receiver', true ),
|
453 |
+
'subject' => array( 'subject', true ),
|
454 |
+
'message' => array( 'message', true ),
|
455 |
+
'headers' => array( 'headers', true ),
|
456 |
+
'attachments' => array( 'attachments', true ),
|
457 |
+
'plugin_version'=> array( 'plugin_version', true ),
|
458 |
+
);
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Ajax function to retrieve rendered mail in certain format.
|
463 |
+
* @since 1.6.0
|
464 |
+
*/
|
465 |
+
public static function ajax_wpml_email_get() {
|
466 |
+
$formats = is_array( $additional = apply_filters( WPML_Plugin::HOOK_LOGGING_SUPPORTED_FORMATS, array() ) ) ? $additional : array();
|
467 |
+
|
468 |
+
check_ajax_referer( 'wpml-modal-show', 'ajax_nonce', true );
|
469 |
+
|
470 |
+
if( ! isset( $_POST['id'] ) )
|
471 |
+
wp_die( "huh?" );
|
472 |
+
$id = intval( $_POST['id'] );
|
473 |
+
|
474 |
+
$format_requested = isset( $_POST['format'] ) ? $_POST['format'] : 'html';
|
475 |
+
if ( ! in_array( $format_requested, $formats ) ) {
|
476 |
+
echo "Unsupported Format. Using html as fallback.";
|
477 |
+
$format_requested = WPML_Utils::sanitize_expected_value($format_requested, $formats, 'html');
|
478 |
+
}
|
479 |
+
$mail = Mail::find_one( $id );
|
480 |
/* @var $instance WPML_Email_Log_List */
|
481 |
+
$instance = WPML_Init::getInstance()->getService( 'emailLogList' );
|
482 |
+
$mailAppend = '';
|
483 |
+
switch( $format_requested ) {
|
484 |
+
case 'html': {
|
485 |
+
$mailAppend .= $instance->render_mail_html( $mail->to_array() );
|
486 |
+
break;
|
487 |
+
}
|
488 |
+
case 'raw': {
|
489 |
+
$mailAppend .= $instance->render_mail( $mail->to_array() );
|
490 |
+
break;
|
491 |
+
}
|
492 |
+
case 'json': {
|
493 |
+
if( stristr( str_replace(' ', '', $mail->get_headers()), "Content-Type:text/html")) {
|
494 |
+
// Fallback to raw in case it is a html mail
|
495 |
+
$mailAppend .= sprintf("<span class='info'>%s</span>", __("Fallback to raw format because html is not convertible to json.", 'wp-mail-logging' ) );
|
496 |
+
$mailAppend .= $instance->render_mail( $mail->to_array() );
|
497 |
+
} else {
|
498 |
+
$mailAppend .= "<pre>" . json_encode( $mail->to_array(), JSON_PRETTY_PRINT ) . "</pre>";
|
499 |
+
}
|
500 |
+
break;
|
501 |
+
}
|
502 |
+
default:
|
503 |
+
$mailAppend .= apply_filters( WPML_Plugin::HOOK_LOGGING_FORMAT_CONTENT . "_{$format_requested}", $mail->to_array() );
|
504 |
+
break;
|
505 |
+
}
|
506 |
+
echo $mailAppend;
|
507 |
+
wp_die(); // this is required to terminate immediately and return a proper response
|
508 |
}
|
509 |
}
|
WPML_Init.php
CHANGED
@@ -28,125 +28,125 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
28 |
|
29 |
class WPML_Init {
|
30 |
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
}
|
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'] );
|
100 |
+
};
|
101 |
+
$this->container['redux'] = function ($c) {
|
102 |
+
return new WPML_Redux_Framework_config( $c['plugin-meta'] );
|
103 |
+
};
|
104 |
+
$this->container['logRotation'] = function ($c) {
|
105 |
+
return new WPML_LogRotation( $c['plugin-meta'] );
|
106 |
+
};
|
107 |
+
$this->container['api'] = function ($c) {
|
108 |
+
// Uncomment for an API Example
|
109 |
+
// return new WPML_API_Example();
|
110 |
+
};
|
111 |
+
$this->container->addActionsAndFilters();
|
112 |
+
|
113 |
+
add_filter( 'wpml_get_di_container', function() {
|
114 |
+
return $this->container;
|
115 |
+
} );
|
116 |
+
|
117 |
+
add_filter( 'wpml_get_di_service', function( $service ) {
|
118 |
+
return $this->getService( $service );
|
119 |
+
} );
|
120 |
+
|
121 |
+
/*
|
122 |
+
* Install the plugin
|
123 |
+
* NOTE: this file gets run each time you *activate* the plugin.
|
124 |
+
* So in WP when you "install" the plugin, all that does it dump its files in the plugin-templates directory
|
125 |
+
* but it does not call any of its code.
|
126 |
+
* So here, the plugin tracks whether or not it has run its install operation, and we ensure it is run only once
|
127 |
+
* on the first activation
|
128 |
+
*/
|
129 |
+
if ( ! $this->container['plugin']->isInstalled() ) {
|
130 |
+
$this->container['plugin']->install();
|
131 |
+
} else {
|
132 |
+
// Perform any version-upgrade activities prior to activation (e.g. database changes).
|
133 |
+
$this->container['plugin']->upgrade();
|
134 |
+
}
|
135 |
+
|
136 |
+
if ( ! $file ) {
|
137 |
+
$file = __FILE__;
|
138 |
+
}
|
139 |
+
// Register the Plugin Activation Hook.
|
140 |
+
register_activation_hook( $file, array( &$this->container['plugin'], 'activate' ) );
|
141 |
+
|
142 |
+
// Register the Plugin Deactivation Hook.
|
143 |
+
register_deactivation_hook( $file, array( &$this->container['plugin'], 'deactivate' ) );
|
144 |
+
}
|
145 |
+
|
146 |
+
public function getService( $key ) {
|
147 |
+
if( in_array( $key, $this->container->keys() ) ) {
|
148 |
+
return $this->container[ $key ];
|
149 |
+
}
|
150 |
+
throw new \Exception("Service '{$key}' is not registered");
|
151 |
+
}
|
152 |
}
|
WPML_InstallIndicator.php
CHANGED
@@ -26,161 +26,146 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
26 |
|
27 |
class WPML_InstallIndicator extends WPML_OptionsManager {
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
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 |
-
* @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 |
}
|
26 |
|
27 |
class WPML_InstallIndicator extends WPML_OptionsManager {
|
28 |
|
29 |
+
const optionInstalled = '_installed';
|
30 |
+
const optionVersion = '_version';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Checks if the plugin is installed.
|
34 |
+
* @return bool indicating if the plugin is installed already
|
35 |
+
*/
|
36 |
+
public function isInstalled() {
|
37 |
+
global $wpdb;
|
38 |
+
$mails = $this->getTablename('mails');
|
39 |
+
$query = $wpdb->query("SHOW TABLES LIKE \"$mails\"");
|
40 |
+
return (bool) $query;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Set a version string in the options. This is useful if you install upgrade and
|
45 |
+
* need to check if an older version was installed to see if you need to do certain
|
46 |
+
* upgrade housekeeping (e.g. changes to DB schema).
|
47 |
+
* @return null
|
48 |
+
*/
|
49 |
+
protected function getVersionSaved() {
|
50 |
+
return $this->getOption( self::optionVersion );
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Set a version string in the options.
|
55 |
+
* need to check if
|
56 |
+
* @param string $version string best practice: use a dot-delimited string like '1.2.3' so version strings can be easily
|
57 |
+
* compared using version_compare (http://php.net/manual/en/function.version-compare.php)
|
58 |
+
* @return null
|
59 |
+
*/
|
60 |
+
protected function setVersionSaved( $version ) {
|
61 |
+
return $this->updateOption( self::optionVersion, $version );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @return string name of the main plugin file that has the header section with
|
66 |
+
* "Plugin Name", "Version", "Description", "Text Domain", etc.
|
67 |
+
*/
|
68 |
+
protected function getMainPluginFileName() {
|
69 |
+
return basename( dirname( __FILE__ ) ) . 'php';
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Get a value for input key in the header section of main plugin file.
|
74 |
+
* E.g. "Plugin Name", "Version", "Description", "Text Domain", etc.
|
75 |
+
* @param $key string plugin header key
|
76 |
+
* @return string if found, otherwise null
|
77 |
+
*/
|
78 |
+
public function getPluginHeaderValue($key) {
|
79 |
+
// Read the string from the comment header of the main plugin file.
|
80 |
+
$data = file_get_contents( $this->getPluginDir() . DIRECTORY_SEPARATOR . $this->getMainPluginFileName() );
|
81 |
+
$match = array();
|
82 |
+
preg_match( '/' . $key . ':\s*(.*)/', $data, $match );
|
83 |
+
if ( count( $match ) >= 1 ) {
|
84 |
+
return $match[1];
|
85 |
+
}
|
86 |
+
return null;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* If your subclass of this class lives in a different directory,
|
91 |
+
* override this method with the exact same code. Since __FILE__ will
|
92 |
+
* be different, you will then get the right dir returned.
|
93 |
+
* @return string
|
94 |
+
*/
|
95 |
+
protected function getPluginDir() {
|
96 |
+
return dirname( __FILE__ );
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Version of this code.
|
101 |
+
* Best practice: define version strings to be easily compared using version_compare()
|
102 |
+
* (http://php.net/manual/en/function.version-compare.php)
|
103 |
+
* NOTE: You should manually make this match the SVN tag for your main plugin file 'Version' release and 'Stable tag' in readme.txt
|
104 |
+
* @return string
|
105 |
+
*/
|
106 |
+
public function getVersion() {
|
107 |
+
return $this->getPluginHeaderValue( 'Version' );
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Useful when checking for upgrades, can tell if the currently installed version is earlier than the
|
112 |
+
* newly installed code. This case indicates that an upgrade has been installed and this is the first time it
|
113 |
+
* has been activated, so any upgrade actions should be taken.
|
114 |
+
* @return bool true if the version saved in the options is earlier than the version declared in getVersion().
|
115 |
+
* true indicates that new code is installed and this is the first time it is activated, so upgrade actions
|
116 |
+
* should be taken. Assumes that version string comparable by version_compare, examples: '1', '1.1', '1.1.1', '2.0', etc.
|
117 |
+
*/
|
118 |
+
public function isInstalledCodeAnUpgrade() {
|
119 |
+
return $this->isSavedVersionLessThan( $this->getVersion() );
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Used to see if the installed code is an earlier version than the input version
|
124 |
+
* @param string $aVersion version string.
|
125 |
+
* @return bool true if the saved version is earlier (by natural order) than the input version
|
126 |
+
*/
|
127 |
+
public function isSavedVersionLessThan( $aVersion ) {
|
128 |
+
return $this->isVersionLessThan( $this->getVersionSaved(), $aVersion );
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Used to see if the installed code is the same or earlier than the input version.
|
133 |
+
* Useful when checking for an upgrade. If you haven't specified the number of the newer version yet,
|
134 |
+
* but the last version (installed) was 2.3 (for example) you could check if
|
135 |
+
* For example, $this->isSavedVersionLessThanEqual('2.3') == true indicates that the saved version is not upgraded
|
136 |
+
* past 2.3 yet and therefore you would perform some appropriate upgrade action.
|
137 |
+
* @param string $aVersion version string.
|
138 |
+
* @return bool true if the saved version is earlier (by natural order) than the input version
|
139 |
+
*/
|
140 |
+
public function isSavedVersionLessThanEqual( $aVersion ) {
|
141 |
+
return $this->isVersionLessThanEqual( $this->getVersionSaved(), $aVersion );
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* @param string $version1 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
146 |
+
* @param string $version2 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
147 |
+
* @return bool true if version_compare of $versions1 and $version2 shows $version1 as the same or earlier
|
148 |
+
*/
|
149 |
+
public function isVersionLessThanEqual( $version1, $version2 ) {
|
150 |
+
return ( version_compare( $version1, $version2 ) <= 0 );
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @param string $version1 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
155 |
+
* @param string $version2 version string such as '1', '1.1', '1.1.1', '2.0', etc.
|
156 |
+
* @return bool true if version_compare of $versions1 and $version2 shows $version1 as earlier
|
157 |
+
*/
|
158 |
+
public function isVersionLessThan( $version1, $version2 ) {
|
159 |
+
return ( version_compare( $version1, $version2 ) < 0 );
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Record the installed version to options.
|
164 |
+
* This helps track was version is installed so when an upgrade is installed, it should call this when finished
|
165 |
+
* upgrading to record the new current version
|
166 |
+
* @return void
|
167 |
+
*/
|
168 |
+
protected function saveInstalledVersion() {
|
169 |
+
$this->setVersionSaved( $this->getVersion() );
|
170 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
}
|
WPML_LifeCycle.php
CHANGED
@@ -26,189 +26,186 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
26 |
|
27 |
class WPML_LifeCycle extends WPML_InstallIndicator {
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
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 |
-
|
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 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
}
|
211 |
-
return $actions;
|
212 |
-
}
|
213 |
|
214 |
}
|
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
CHANGED
@@ -2,8 +2,6 @@
|
|
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 |
|
@@ -14,71 +12,79 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
14 |
*/
|
15 |
class WPML_LogRotation {
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
FROM
|
83 |
$tableName AS p
|
84 |
JOIN
|
@@ -88,33 +94,38 @@ class WPML_LogRotation {
|
|
88 |
LIMIT 1 OFFSET $keep
|
89 |
) AS lim
|
90 |
ON p.mail_id <= lim.mail_id;"
|
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 |
-
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
namespace No3x\WPML;
|
4 |
|
|
|
|
|
5 |
// Exit if accessed directly.
|
6 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
7 |
|
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
|
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 |
+
}
|
WPML_OptionsManager.php
CHANGED
@@ -25,580 +25,580 @@ namespace No3x\WPML;
|
|
25 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
26 |
|
27 |
class WPML_OptionsManager {
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
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 |
-
|
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 |
-
|
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 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
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 |
-
|
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 |
-
|
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 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
}
|
604 |
|
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
CHANGED
@@ -1,216 +1,257 @@
|
|
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 |
-
class WPML_Plugin extends WPML_LifeCycle {
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
`mail_id` INT NOT NULL AUTO_INCREMENT,
|
49 |
-
`timestamp` TIMESTAMP NOT NULL,
|
50 |
-
`host` VARCHAR(200) NOT NULL DEFAULT '0',
|
51 |
-
`receiver` VARCHAR(200) NOT NULL DEFAULT '0',
|
52 |
-
`subject` VARCHAR(200) NOT NULL DEFAULT '0',
|
53 |
-
`message` TEXT NULL,
|
54 |
-
`headers` TEXT NULL,
|
55 |
-
`attachments` VARCHAR(800) NOT NULL DEFAULT '0',
|
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 |
-
if ($this->isVersionLessThan($savedVersion, '1.
|
107 |
-
$wpdb->query("ALTER TABLE `$tableName`
|
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 |
-
|
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 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
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';
|
17 |
+
const HOOK_LOGGING_FORMAT_CONTENT = 'wpml_hook_format_content';
|
18 |
+
|
19 |
+
public static function getTablename( $name ) {
|
20 |
+
global $wpdb;
|
21 |
+
return $wpdb->prefix . 'wpml_' . $name;
|
22 |
+
}
|
23 |
+
|
24 |
+
public function getPluginDisplayName() {
|
25 |
+
return 'WP Mail Logging';
|
26 |
+
}
|
27 |
+
|
28 |
+
public function getMainPluginFileName() {
|
29 |
+
return 'wp-mail-logging.php';
|
30 |
+
}
|
31 |
+
|
32 |
+
public function getVersionSaved() {
|
33 |
+
return parent::getVersionSaved();
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* See: http://plugin.michael-simpson.com/?page_id=101
|
38 |
+
* Called by install() to create any database tables if needed.
|
39 |
+
* Best Practice:
|
40 |
+
* (1) Prefix all table names with $wpdb->prefix
|
41 |
+
* (2) make table names lower case only
|
42 |
+
* @return void
|
43 |
+
*/
|
44 |
+
protected function installDatabaseTables() {
|
45 |
+
global $wpdb;
|
46 |
+
$tableName = WPML_Plugin::getTablename('mails');
|
47 |
+
$wpdb->query("CREATE TABLE IF NOT EXISTS `$tableName` (
|
48 |
+
`mail_id` INT NOT NULL AUTO_INCREMENT,
|
49 |
+
`timestamp` TIMESTAMP NOT NULL,
|
50 |
+
`host` VARCHAR(200) NOT NULL DEFAULT '0',
|
51 |
+
`receiver` VARCHAR(200) NOT NULL DEFAULT '0',
|
52 |
+
`subject` VARCHAR(200) NOT NULL DEFAULT '0',
|
53 |
+
`message` TEXT NULL,
|
54 |
+
`headers` TEXT NULL,
|
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 |
+
|
62 |
+
/**
|
63 |
+
* See: http://plugin.michael-simpson.com/?page_id=101
|
64 |
+
* Drop plugin-created tables on uninstall.
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
protected function unInstallDatabaseTables() {
|
68 |
+
global $wpdb;
|
69 |
+
$tableName = WPML_Plugin::getTablename('mails');
|
70 |
+
$wpdb->query("DROP TABLE IF EXISTS `$tableName`");
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Perform actions when upgrading from version X to version Y
|
75 |
+
* See: http://plugin.michael-simpson.com/?page_id=35
|
76 |
+
* @return void
|
77 |
+
*/
|
78 |
+
public function upgrade() {
|
79 |
+
global $wpdb;
|
80 |
+
|
81 |
+
$savedVersion = $this->getVersionSaved();
|
82 |
+
if(! $this->isInstalled() || empty( $savedVersion ) ) {
|
83 |
+
// The plugin must be installed before any upgrades
|
84 |
+
return;
|
85 |
+
}
|
86 |
+
|
87 |
+
$upgradeOk = true;
|
88 |
+
$savedVersion = $this->getVersionSaved();
|
89 |
+
$codeVersion = $this->getVersion();
|
90 |
+
$tableName = $this->getTablename('mails');
|
91 |
+
|
92 |
+
/* check for downgrade or beta
|
93 |
+
if( $this->isVersionLessThan($codeVersion, $savedVersion)
|
94 |
+
|| false !== strpos($savedVersion, 'beta') ) {
|
95 |
+
$upgradeOk = false;
|
96 |
+
// This is only be the case if the user had a beta version installed
|
97 |
+
if ( is_admin() ) {
|
98 |
+
wp_die( "[{$this->getPluginDisplayName()}] You have installed version {$savedVersion} but try to install {$codeVersion}! This would require a database downgrade which is not supported! You need to install {$savedVersion} again, enable \"Cleanup\" in the settings and disable the plugin.");
|
99 |
+
}
|
100 |
+
}*/
|
101 |
+
|
102 |
+
if ($this->isVersionLessThan($savedVersion, '2.0')) {
|
103 |
+
if ($this->isVersionLessThan($savedVersion, '1.2')) {
|
104 |
+
$wpdb->query("ALTER TABLE `$tableName` CHANGE COLUMN `to` `receiver` VARCHAR(200)");
|
105 |
+
}
|
106 |
+
if ($this->isVersionLessThan($savedVersion, '1.3')) {
|
107 |
+
$wpdb->query("ALTER TABLE `$tableName` MODIFY COLUMN `attachments` VARCHAR(800) NOT NULL DEFAULT '0'");
|
108 |
+
}
|
109 |
+
if ($this->isVersionLessThan($savedVersion, '1.4')) {
|
110 |
+
$wpdb->query("ALTER TABLE `$tableName` CHARACTER SET utf8 COLLATE utf8_general_ci;");
|
111 |
+
}
|
112 |
+
if ($this->isVersionLessThan($savedVersion, '1.7')) {
|
113 |
+
$wpdb->query("ALTER TABLE `$tableName` ADD COLUMN `host` VARCHAR(200) NOT NULL DEFAULT '0' AFTER `timestamp`;");
|
114 |
+
}
|
115 |
+
if ($this->isVersionLessThan($savedVersion, '1.8')) {
|
116 |
+
// Due to upgrade bug upgrades from 1.6.2 to 1.7.0 failed. Redo the schema change if required
|
117 |
+
$results = $wpdb->get_results( $wpdb->prepare( "SHOW COLUMNS FROM `$tableName` LIKE %s", 'host' ) );
|
118 |
+
$column_exists = ( count( $results ) > 0 ) ? true : false;
|
119 |
+
|
120 |
+
if ( false === $column_exists && is_array( $results ) ) {
|
121 |
+
$wpdb->query("ALTER TABLE `$tableName` ADD COLUMN `host` VARCHAR(200) NOT NULL DEFAULT '0' AFTER `timestamp`;");
|
122 |
+
}
|
123 |
+
|
124 |
+
$wpdb->query("ALTER TABLE `$tableName` ADD COLUMN `error` VARCHAR(400) NULL DEFAULT '' AFTER `attachments`;");
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
if ( !empty( $wpdb->last_error ) ) {
|
129 |
+
$upgradeOk = false;
|
130 |
+
if ( is_admin() ) {
|
131 |
+
echo "There was at least one error while upgrading the database schema. Please report the following error: {$wpdb->last_error}";
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
// Post-upgrade, set the current version in the options
|
136 |
+
if ($upgradeOk && $savedVersion != $codeVersion) {
|
137 |
+
$this->saveInstalledVersion();
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
public function addActionsAndFilters() {
|
142 |
+
// Add options administration page
|
143 |
+
// http://plugin.michael-simpson.com/?page_id=47
|
144 |
+
add_action( 'admin_menu', array(&$this, 'createSettingsMenu'), 9 );
|
145 |
+
|
146 |
+
// Example adding a script & style just for the options administration page
|
147 |
+
// http://plugin.michael-simpson.com/?page_id=47
|
148 |
+
// if (strpos($_SERVER['REQUEST_URI'], $this->getSettingsSlug()) !== false) {
|
149 |
+
// wp_enqueue_script('my-script', plugins_url('/js/my-script.js', __FILE__));
|
150 |
+
// wp_enqueue_style('my-style', plugins_url('/css/my-style.css', __FILE__));
|
151 |
+
// }
|
152 |
+
|
153 |
+
|
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( &$this, 'log_email' ), PHP_INT_MAX );
|
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' ) );
|
161 |
+
add_filter( 'wpml_get_plugin_name', array( &$this, 'getPluginDisplayName' ) );
|
162 |
+
add_filter( 'wpml_get_date_time_format', array( &$this, 'getDateTimeFormatString' ) );
|
163 |
+
// Adding scripts & styles to all pages
|
164 |
+
// Examples:
|
165 |
+
// wp_enqueue_script('jquery');
|
166 |
+
// wp_enqueue_style('my-style', plugins_url('/css/my-style.css', __FILE__));
|
167 |
+
// wp_enqueue_script('my-script', plugins_url('/js/my-script.js', __FILE__));
|
168 |
+
|
169 |
+
|
170 |
+
// Register short codes
|
171 |
+
// http://plugin.michael-simpson.com/?page_id=39
|
172 |
+
|
173 |
+
|
174 |
+
// Register AJAX hooks
|
175 |
+
// http://plugin.michael-simpson.com/?page_id=41
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Action to log errors for mails failed to send.
|
180 |
+
*
|
181 |
+
* @since 1.8.0
|
182 |
+
* @global $wpml_current_mail_id
|
183 |
+
* @param \WP_Error $wperror
|
184 |
+
*/
|
185 |
+
public function log_email_failed( $wperror ) {
|
186 |
+
global $wpml_current_mail_id;
|
187 |
+
if(!isset($wpml_current_mail_id)) return;
|
188 |
+
$failed_mail = Mail::find_one($wpml_current_mail_id);
|
189 |
+
$failed_mail->set_error($wperror->get_error_message())->save();
|
190 |
+
}
|
191 |
+
|
192 |
+
private function extractReceiver( $receiver ) {
|
193 |
+
return is_array( $receiver ) ? implode( ',\n', $receiver ) : $receiver;
|
194 |
+
}
|
195 |
+
|
196 |
+
private function extractHeader( $headers ) {
|
197 |
+
return is_array( $headers ) ? implode( ',\n', $headers ) : $headers;
|
198 |
+
}
|
199 |
+
|
200 |
+
private function extractAttachments( $attachments ) {
|
201 |
+
$attachments = is_array( $attachments ) ? $attachments : array( $attachments );
|
202 |
+
$attachment_urls = array();
|
203 |
+
$uploads = wp_upload_dir();
|
204 |
+
$basename = 'uploads';
|
205 |
+
$basename_needle = '/'.$basename.'/';
|
206 |
+
foreach ( $attachments as $attachment ) {
|
207 |
+
$append_url = substr( $attachment, strrpos( $attachment, $basename_needle ) + strlen($basename_needle) - 1 );
|
208 |
+
$attachment_urls[] = $append_url;
|
209 |
+
}
|
210 |
+
return implode( ',\n', $attachment_urls );
|
211 |
+
}
|
212 |
+
|
213 |
+
private function extractMessage( $mail ) {
|
214 |
+
if ( isset($mail['message']) ) {
|
215 |
+
// usually the message is stored in the message field
|
216 |
+
return $mail['message'];
|
217 |
+
} elseif ( isset($mail['html']) ) {
|
218 |
+
// for example Mandrill stores the message in the 'html' field (see gh-22)
|
219 |
+
return $mail['html'];
|
220 |
+
}
|
221 |
+
return "";
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
private function extractFields( $mail ) {
|
226 |
+
return array(
|
227 |
+
'receiver' => $this->extractReceiver( $mail['to'] ),
|
228 |
+
'subject' => $mail['subject'],
|
229 |
+
'message' => $this->extractMessage( $mail ),
|
230 |
+
'headers' => $this->extractHeader( $mail['headers'] ),
|
231 |
+
'attachments' => $this->extractAttachments( $mail['attachments'] ),
|
232 |
+
'plugin_version' => $this->getVersionSaved(),
|
233 |
+
'timestamp' => current_time( 'mysql' ),
|
234 |
+
'host' => isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : ''
|
235 |
+
);
|
236 |
+
}
|
237 |
+
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Logs mail to database.
|
241 |
+
*
|
242 |
+
* @param array $mailOriginal
|
243 |
+
* @global $wpml_current_mail_id
|
244 |
+
* @since 1.0
|
245 |
+
* @return array $mailOriginal
|
246 |
+
*/
|
247 |
+
public function log_email( $mailOriginal ) {
|
248 |
+
global $wpml_current_mail_id;
|
249 |
+
// make copy to avoid any changes on the original mail
|
250 |
+
$mail = $mailOriginal;
|
251 |
+
|
252 |
+
$fields = $this->extractFields( $mail );
|
253 |
+
$wpml_current_mail_id = Mail::create($fields)->save();
|
254 |
+
|
255 |
+
return $mailOriginal;
|
256 |
+
}
|
257 |
+
}
|
WPML_ShortCodeLoader.php
CHANGED
@@ -26,42 +26,42 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
26 |
|
27 |
abstract class WPML_ShortCodeLoader {
|
28 |
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
}
|
26 |
|
27 |
abstract class WPML_ShortCodeLoader {
|
28 |
|
29 |
+
/**
|
30 |
+
* @param $shortcodeName mixed either string name of the shortcode
|
31 |
+
* (as it would appear in a post, e.g. [shortcodeName])
|
32 |
+
* or an array of such names in case you want to have more than one name
|
33 |
+
* for the same shortcode
|
34 |
+
* @return void
|
35 |
+
*/
|
36 |
+
public function register($shortcodeName) {
|
37 |
+
$this->registerShortcodeToFunction($shortcodeName, 'handleShortcode');
|
38 |
+
}
|
39 |
|
40 |
+
/**
|
41 |
+
* @param $shortcodeName mixed either string name of the shortcode
|
42 |
+
* (as it would appear in a post, e.g. [shortcodeName])
|
43 |
+
* or an array of such names in case you want to have more than one name
|
44 |
+
* for the same shortcode
|
45 |
+
* @param $functionName string name of public function in this class to call as the
|
46 |
+
* shortcode handler
|
47 |
+
* @return void
|
48 |
+
*/
|
49 |
+
protected function registerShortcodeToFunction($shortcodeName, $functionName) {
|
50 |
+
if (is_array($shortcodeName)) {
|
51 |
+
foreach ($shortcodeName as $aName) {
|
52 |
+
add_shortcode($aName, array($this, $functionName));
|
53 |
+
}
|
54 |
+
}
|
55 |
+
else {
|
56 |
+
add_shortcode($shortcodeName, array($this, $functionName));
|
57 |
+
}
|
58 |
+
}
|
59 |
|
60 |
+
/**
|
61 |
+
* @abstract Override this function and add actual shortcode handling here
|
62 |
+
* @param $atts shortcode inputs
|
63 |
+
* @return string shortcode content
|
64 |
+
*/
|
65 |
+
public abstract function handleShortcode($atts);
|
66 |
|
67 |
}
|
WPML_ShortCodeScriptLoader.php
CHANGED
@@ -33,37 +33,37 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
33 |
*/
|
34 |
abstract class WPML_ShortCodeScriptLoader extends WPML_ShortCodeLoader {
|
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 |
}
|
33 |
*/
|
34 |
abstract class WPML_ShortCodeScriptLoader extends WPML_ShortCodeLoader {
|
35 |
|
36 |
+
var $doAddScript;
|
37 |
|
38 |
+
public function register($shortcodeName) {
|
39 |
+
$this->registerShortcodeToFunction($shortcodeName, 'handleShortcodeWrapper');
|
40 |
|
41 |
+
// It will be too late to enqueue the script in the header,
|
42 |
+
// but can add them to the footer
|
43 |
+
add_action('wp_footer', array($this, 'addScriptWrapper'));
|
44 |
+
}
|
45 |
|
46 |
+
public function handleShortcodeWrapper($atts) {
|
47 |
+
// Flag that we need to add the script
|
48 |
+
$this->doAddScript = true;
|
49 |
+
return $this->handleShortcode($atts);
|
50 |
+
}
|
51 |
|
52 |
|
53 |
+
public function addScriptWrapper() {
|
54 |
+
// Only add the script if the shortcode was actually called
|
55 |
+
if ($this->doAddScript) {
|
56 |
+
$this->addScript();
|
57 |
+
}
|
58 |
+
}
|
59 |
|
60 |
+
/**
|
61 |
+
* @abstract override this function with calls to insert scripts needed by your shortcode in the footer
|
62 |
+
* Example:
|
63 |
+
* wp_register_script('my-script', plugins_url('js/my-script.js', __FILE__), array('jquery'), '1.0', true);
|
64 |
+
* wp_print_scripts('my-script');
|
65 |
+
* @return void
|
66 |
+
*/
|
67 |
+
public abstract function addScript();
|
68 |
|
69 |
}
|
WPML_Utils.php
CHANGED
@@ -11,108 +11,108 @@ if ( ! defined( 'ABSPATH' ) ) exit;
|
|
11 |
* @since 1.6.0
|
12 |
*/
|
13 |
class WPML_Utils {
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
$default_icon = '<i class="fa fa-file-o"></i>';
|
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 |
if( !function_exists('mime_content_type') ) {
|
85 |
return $default_icon;
|
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 |
}
|
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 |
}
|
css/modal.css
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
display: none;
|
3 |
}
|
4 |
#wp-mail-logging-modal-backdrop {
|
5 |
-
background: none repeat scroll 0 0 #
|
6 |
bottom: 0;
|
7 |
left: 0;
|
8 |
min-height: 360px;
|
@@ -13,7 +13,7 @@
|
|
13 |
z-index: 159900;
|
14 |
}
|
15 |
#wp-mail-logging-modal-content {
|
16 |
-
background: none repeat scroll 0 0 #
|
17 |
bottom: 0;
|
18 |
left: 0;
|
19 |
margin: auto;
|
@@ -33,8 +33,8 @@
|
|
33 |
z-index: 300010;
|
34 |
}
|
35 |
#wp-mail-logging-modal-content-header {
|
36 |
-
background-color: #
|
37 |
-
border-bottom: 1px solid #
|
38 |
left: 0;
|
39 |
padding: 15px 10px 15px 10px;
|
40 |
position: absolute;
|
@@ -47,7 +47,7 @@
|
|
47 |
position: absolute;
|
48 |
right: 10px;
|
49 |
text-decoration: none;
|
50 |
-
top:
|
51 |
width: 30px;
|
52 |
z-index: 1000;
|
53 |
}
|
@@ -79,13 +79,22 @@
|
|
79 |
position: relative;
|
80 |
padding: 15px;
|
81 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
#wp-mail-logging-modal-content-body .title {
|
83 |
font-weight: bold;
|
84 |
display: block;
|
85 |
}
|
86 |
#wp-mail-logging-modal-content-footer {
|
87 |
-
background-color: #
|
88 |
-
border-top: 1px solid #
|
89 |
bottom: 0;
|
90 |
left: 0;
|
91 |
padding: 15px 10px 15px 10px;
|
2 |
display: none;
|
3 |
}
|
4 |
#wp-mail-logging-modal-backdrop {
|
5 |
+
background: none repeat scroll 0 0 #000;
|
6 |
bottom: 0;
|
7 |
left: 0;
|
8 |
min-height: 360px;
|
13 |
z-index: 159900;
|
14 |
}
|
15 |
#wp-mail-logging-modal-content {
|
16 |
+
background: none repeat scroll 0 0 #fff;
|
17 |
bottom: 0;
|
18 |
left: 0;
|
19 |
margin: auto;
|
33 |
z-index: 300010;
|
34 |
}
|
35 |
#wp-mail-logging-modal-content-header {
|
36 |
+
background-color: #eee;
|
37 |
+
border-bottom: 1px solid #ccc;
|
38 |
left: 0;
|
39 |
padding: 15px 10px 15px 10px;
|
40 |
position: absolute;
|
47 |
position: absolute;
|
48 |
right: 10px;
|
49 |
text-decoration: none;
|
50 |
+
top: 35%;
|
51 |
width: 30px;
|
52 |
z-index: 1000;
|
53 |
}
|
79 |
position: relative;
|
80 |
padding: 15px;
|
81 |
}
|
82 |
+
#wp-mail-logging-modal-content-body .info {
|
83 |
+
border-left: 4px solid #ffba00;
|
84 |
+
display: block;
|
85 |
+
background: #FFF9E9;
|
86 |
+
-webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
87 |
+
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1);
|
88 |
+
margin: 5px 5px 2px;
|
89 |
+
padding: 1px 12px;
|
90 |
+
}
|
91 |
#wp-mail-logging-modal-content-body .title {
|
92 |
font-weight: bold;
|
93 |
display: block;
|
94 |
}
|
95 |
#wp-mail-logging-modal-content-footer {
|
96 |
+
background-color: #eee;
|
97 |
+
border-top: 1px solid #ccc;
|
98 |
bottom: 0;
|
99 |
left: 0;
|
100 |
padding: 15px 10px 15px 10px;
|
css/modal.less
CHANGED
@@ -73,7 +73,7 @@
|
|
73 |
position: absolute;
|
74 |
right: 10px;
|
75 |
text-decoration: none;
|
76 |
-
top:
|
77 |
width: 30px;
|
78 |
z-index: 1000;
|
79 |
}
|
@@ -110,7 +110,17 @@
|
|
110 |
position: relative;
|
111 |
padding: @body-content-padding;
|
112 |
}
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
& .title {
|
115 |
font-weight: bold;
|
116 |
display: block;
|
73 |
position: absolute;
|
74 |
right: 10px;
|
75 |
text-decoration: none;
|
76 |
+
top: 35%;
|
77 |
width: 30px;
|
78 |
z-index: 1000;
|
79 |
}
|
110 |
position: relative;
|
111 |
padding: @body-content-padding;
|
112 |
}
|
113 |
+
|
114 |
+
& .info {
|
115 |
+
border-left: 4px solid #ffba00;
|
116 |
+
display: block;
|
117 |
+
background: #FFF9E9;
|
118 |
+
-webkit-box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
|
119 |
+
box-shadow: 0 1px 1px 0 rgba( 0, 0, 0, 0.1 );
|
120 |
+
margin: 5px 5px 2px;
|
121 |
+
padding: 1px 12px;
|
122 |
+
}
|
123 |
+
|
124 |
& .title {
|
125 |
font-weight: bold;
|
126 |
display: block;
|
inc/class-wp-list-table.php
CHANGED
@@ -1,974 +1,974 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Base class for displaying a list of items in an ajaxified HTML table.
|
4 |
-
*
|
5 |
-
* @package WordPress
|
6 |
-
* @subpackage List_Table
|
7 |
-
* @since 3.1.0
|
8 |
-
*/
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Base class for displaying a list of items in an ajaxified HTML table.
|
12 |
-
*
|
13 |
-
* @package WordPress
|
14 |
-
* @subpackage List_Table
|
15 |
-
* @since 3.1.0
|
16 |
-
* @access private
|
17 |
-
*/
|
18 |
-
class WP_List_Table {
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
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 |
-
|
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 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
?>
|
218 |
-
<p class="search-box">
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
</p>
|
223 |
-
<?php
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
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 |
-
|
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 |
-
|
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 |
-
SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
|
386 |
-
FROM $wpdb->posts
|
387 |
-
WHERE post_type = %s
|
388 |
-
ORDER BY post_date DESC
|
389 |
-
", $post_type ) );
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
?>
|
408 |
-
|
409 |
-
|
410 |
-
<?php
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
?>
|
426 |
-
|
427 |
-
<?php
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
?>
|
443 |
-
|
444 |
-
|
445 |
-
<?php
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
<?php
|
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 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
|
770 |
-
|
771 |
-
|
772 |
-
|
773 |
-
|
774 |
-
|
775 |
-
?>
|
776 |
-
<table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
</table>
|
793 |
-
<?php
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
?>
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
<?php
|
825 |
-
|
826 |
-
|
827 |
-
?>
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
<?php
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
|
946 |
-
|
947 |
-
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Base class for displaying a list of items in an ajaxified HTML table.
|
4 |
+
*
|
5 |
+
* @package WordPress
|
6 |
+
* @subpackage List_Table
|
7 |
+
* @since 3.1.0
|
8 |
+
*/
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Base class for displaying a list of items in an ajaxified HTML table.
|
12 |
+
*
|
13 |
+
* @package WordPress
|
14 |
+
* @subpackage List_Table
|
15 |
+
* @since 3.1.0
|
16 |
+
* @access private
|
17 |
+
*/
|
18 |
+
class WP_List_Table {
|
19 |
+
|
20 |
+
/**
|
21 |
+
* The current list of items
|
22 |
+
*
|
23 |
+
* @since 3.1.0
|
24 |
+
* @var array
|
25 |
+
* @access protected
|
26 |
+
*/
|
27 |
+
var $items;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Various information about the current table
|
31 |
+
*
|
32 |
+
* @since 3.1.0
|
33 |
+
* @var array
|
34 |
+
* @access private
|
35 |
+
*/
|
36 |
+
var $_args;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Various information needed for displaying the pagination
|
40 |
+
*
|
41 |
+
* @since 3.1.0
|
42 |
+
* @var array
|
43 |
+
* @access private
|
44 |
+
*/
|
45 |
+
var $_pagination_args = array();
|
46 |
+
|
47 |
+
/**
|
48 |
+
* The current screen
|
49 |
+
*
|
50 |
+
* @since 3.1.0
|
51 |
+
* @var object
|
52 |
+
* @access protected
|
53 |
+
*/
|
54 |
+
var $screen;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Cached bulk actions
|
58 |
+
*
|
59 |
+
* @since 3.1.0
|
60 |
+
* @var array
|
61 |
+
* @access private
|
62 |
+
*/
|
63 |
+
var $_actions;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Cached pagination output
|
67 |
+
*
|
68 |
+
* @since 3.1.0
|
69 |
+
* @var string
|
70 |
+
* @access private
|
71 |
+
*/
|
72 |
+
var $_pagination;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Constructor. The child class should call this constructor from its own constructor
|
76 |
+
*
|
77 |
+
* @param array $args An associative array with information about the current table
|
78 |
+
* @access protected
|
79 |
+
*/
|
80 |
+
function __construct( $args = array() ) {
|
81 |
+
$args = wp_parse_args( $args, array(
|
82 |
+
'plural' => '',
|
83 |
+
'singular' => '',
|
84 |
+
'ajax' => false,
|
85 |
+
'screen' => null,
|
86 |
+
) );
|
87 |
+
|
88 |
+
$this->screen = convert_to_screen( $args['screen'] );
|
89 |
+
|
90 |
+
add_filter( "manage_{$this->screen->id}_columns", array( $this, 'get_columns' ), 0 );
|
91 |
+
|
92 |
+
if ( !$args['plural'] )
|
93 |
+
$args['plural'] = $this->screen->base;
|
94 |
+
|
95 |
+
$args['plural'] = sanitize_key( $args['plural'] );
|
96 |
+
$args['singular'] = sanitize_key( $args['singular'] );
|
97 |
+
|
98 |
+
$this->_args = $args;
|
99 |
+
|
100 |
+
if ( $args['ajax'] ) {
|
101 |
+
// wp_enqueue_script( 'list-table' );
|
102 |
+
add_action( 'admin_footer', array( $this, '_js_vars' ) );
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Checks the current user's permissions
|
108 |
+
* @uses wp_die()
|
109 |
+
*
|
110 |
+
* @since 3.1.0
|
111 |
+
* @access public
|
112 |
+
* @abstract
|
113 |
+
*/
|
114 |
+
function ajax_user_can() {
|
115 |
+
die( 'function WP_List_Table::ajax_user_can() must be over-ridden in a sub-class.' );
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Prepares the list of items for displaying.
|
120 |
+
* @uses WP_List_Table::set_pagination_args()
|
121 |
+
*
|
122 |
+
* @since 3.1.0
|
123 |
+
* @access public
|
124 |
+
* @abstract
|
125 |
+
*/
|
126 |
+
function prepare_items() {
|
127 |
+
die( 'function WP_List_Table::prepare_items() must be over-ridden in a sub-class.' );
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* An internal method that sets all the necessary pagination arguments
|
132 |
+
*
|
133 |
+
* @param array $args An associative array with information about the pagination
|
134 |
+
* @access protected
|
135 |
+
*/
|
136 |
+
function set_pagination_args( $args ) {
|
137 |
+
$args = wp_parse_args( $args, array(
|
138 |
+
'total_items' => 0,
|
139 |
+
'total_pages' => 0,
|
140 |
+
'per_page' => 0,
|
141 |
+
) );
|
142 |
+
|
143 |
+
if ( !$args['total_pages'] && $args['per_page'] > 0 )
|
144 |
+
$args['total_pages'] = ceil( $args['total_items'] / $args['per_page'] );
|
145 |
+
|
146 |
+
// redirect if page number is invalid and headers are not already sent
|
147 |
+
if ( ! headers_sent() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) && $args['total_pages'] > 0 && $this->get_pagenum() > $args['total_pages'] ) {
|
148 |
+
wp_redirect( add_query_arg( 'paged', $args['total_pages'] ) );
|
149 |
+
exit;
|
150 |
+
}
|
151 |
+
|
152 |
+
$this->_pagination_args = $args;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Access the pagination args
|
157 |
+
*
|
158 |
+
* @since 3.1.0
|
159 |
+
* @access public
|
160 |
+
*
|
161 |
+
* @param string $key
|
162 |
+
* @return array
|
163 |
+
*/
|
164 |
+
function get_pagination_arg( $key ) {
|
165 |
+
if ( 'page' == $key )
|
166 |
+
return $this->get_pagenum();
|
167 |
+
|
168 |
+
if ( isset( $this->_pagination_args[$key] ) )
|
169 |
+
return $this->_pagination_args[$key];
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Whether the table has items to display or not
|
174 |
+
*
|
175 |
+
* @since 3.1.0
|
176 |
+
* @access public
|
177 |
+
*
|
178 |
+
* @return bool
|
179 |
+
*/
|
180 |
+
function has_items() {
|
181 |
+
return !empty( $this->items );
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Message to be displayed when there are no items
|
186 |
+
*
|
187 |
+
* @since 3.1.0
|
188 |
+
* @access public
|
189 |
+
*/
|
190 |
+
function no_items() {
|
191 |
+
_e( 'No items found.' );
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Display the search box.
|
196 |
+
*
|
197 |
+
* @since 3.1.0
|
198 |
+
* @access public
|
199 |
+
*
|
200 |
+
* @param string $text The search button text
|
201 |
+
* @param string $input_id The search input id
|
202 |
+
*/
|
203 |
+
function search_box( $text, $input_id ) {
|
204 |
+
if ( empty( $_REQUEST['s'] ) && !$this->has_items() )
|
205 |
+
return;
|
206 |
+
|
207 |
+
$input_id = $input_id . '-search-input';
|
208 |
+
|
209 |
+
if ( ! empty( $_REQUEST['orderby'] ) )
|
210 |
+
echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
|
211 |
+
if ( ! empty( $_REQUEST['order'] ) )
|
212 |
+
echo '<input type="hidden" name="order" value="' . esc_attr( $_REQUEST['order'] ) . '" />';
|
213 |
+
if ( ! empty( $_REQUEST['post_mime_type'] ) )
|
214 |
+
echo '<input type="hidden" name="post_mime_type" value="' . esc_attr( $_REQUEST['post_mime_type'] ) . '" />';
|
215 |
+
if ( ! empty( $_REQUEST['detached'] ) )
|
216 |
+
echo '<input type="hidden" name="detached" value="' . esc_attr( $_REQUEST['detached'] ) . '" />';
|
217 |
+
?>
|
218 |
+
<p class="search-box">
|
219 |
+
<label class="screen-reader-text" for="<?php echo $input_id ?>"><?php echo $text; ?>:</label>
|
220 |
+
<input type="search" id="<?php echo $input_id ?>" name="s" value="<?php _admin_search_query(); ?>" />
|
221 |
+
<?php submit_button( $text, 'button', false, false, array('id' => 'search-submit') ); ?>
|
222 |
+
</p>
|
223 |
+
<?php
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Get an associative array ( id => link ) with the list
|
228 |
+
* of views available on this table.
|
229 |
+
*
|
230 |
+
* @since 3.1.0
|
231 |
+
* @access protected
|
232 |
+
*
|
233 |
+
* @return array
|
234 |
+
*/
|
235 |
+
function get_views() {
|
236 |
+
return array();
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Display the list of views available on this table.
|
241 |
+
*
|
242 |
+
* @since 3.1.0
|
243 |
+
* @access public
|
244 |
+
*/
|
245 |
+
function views() {
|
246 |
+
$views = $this->get_views();
|
247 |
+
/**
|
248 |
+
* Filter the list of available list table views.
|
249 |
+
*
|
250 |
+
* The dynamic portion of the hook name, $this->screen->id, refers
|
251 |
+
* to the ID of the current screen, usually a string.
|
252 |
+
*
|
253 |
+
* @since 3.5.0
|
254 |
+
*
|
255 |
+
* @param array $views An array of available list table views.
|
256 |
+
*/
|
257 |
+
$views = apply_filters( "views_{$this->screen->id}", $views );
|
258 |
+
|
259 |
+
if ( empty( $views ) )
|
260 |
+
return;
|
261 |
+
|
262 |
+
echo "<ul class='subsubsub'>\n";
|
263 |
+
foreach ( $views as $class => $view ) {
|
264 |
+
$views[ $class ] = "\t<li class='$class'>$view";
|
265 |
+
}
|
266 |
+
echo implode( " |</li>\n", $views ) . "</li>\n";
|
267 |
+
echo "</ul>";
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Get an associative array ( option_name => option_title ) with the list
|
272 |
+
* of bulk actions available on this table.
|
273 |
+
*
|
274 |
+
* @since 3.1.0
|
275 |
+
* @access protected
|
276 |
+
*
|
277 |
+
* @return array
|
278 |
+
*/
|
279 |
+
function get_bulk_actions() {
|
280 |
+
return array();
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Display the bulk actions dropdown.
|
285 |
+
*
|
286 |
+
* @since 3.1.0
|
287 |
+
* @access public
|
288 |
+
*/
|
289 |
+
function bulk_actions() {
|
290 |
+
if ( is_null( $this->_actions ) ) {
|
291 |
+
$no_new_actions = $this->_actions = $this->get_bulk_actions();
|
292 |
+
/**
|
293 |
+
* Filter the list table Bulk Actions drop-down.
|
294 |
+
*
|
295 |
+
* The dynamic portion of the hook name, $this->screen->id, refers
|
296 |
+
* to the ID of the current screen, usually a string.
|
297 |
+
*
|
298 |
+
* This filter can currently only be used to remove bulk actions.
|
299 |
+
*
|
300 |
+
* @since 3.5.0
|
301 |
+
*
|
302 |
+
* @param array $actions An array of the available bulk actions.
|
303 |
+
*/
|
304 |
+
$this->_actions = apply_filters( "bulk_actions-{$this->screen->id}", $this->_actions );
|
305 |
+
$this->_actions = array_intersect_assoc( $this->_actions, $no_new_actions );
|
306 |
+
$two = '';
|
307 |
+
} else {
|
308 |
+
$two = '2';
|
309 |
+
}
|
310 |
+
|
311 |
+
if ( empty( $this->_actions ) )
|
312 |
+
return;
|
313 |
+
|
314 |
+
echo "<select name='action$two'>\n";
|
315 |
+
echo "<option value='-1' selected='selected'>" . __( 'Bulk Actions' ) . "</option>\n";
|
316 |
+
|
317 |
+
foreach ( $this->_actions as $name => $title ) {
|
318 |
+
$class = 'edit' == $name ? ' class="hide-if-no-js"' : '';
|
319 |
+
|
320 |
+
echo "\t<option value='$name'$class>$title</option>\n";
|
321 |
+
}
|
322 |
+
|
323 |
+
echo "</select>\n";
|
324 |
+
|
325 |
+
submit_button( __( 'Apply' ), 'action', false, false, array( 'id' => "doaction$two" ) );
|
326 |
+
echo "\n";
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Get the current action selected from the bulk actions dropdown.
|
331 |
+
*
|
332 |
+
* @since 3.1.0
|
333 |
+
* @access public
|
334 |
+
*
|
335 |
+
* @return string|bool The action name or False if no action was selected
|
336 |
+
*/
|
337 |
+
function current_action() {
|
338 |
+
if ( isset( $_REQUEST['action'] ) && -1 != $_REQUEST['action'] )
|
339 |
+
return $_REQUEST['action'];
|
340 |
+
|
341 |
+
if ( isset( $_REQUEST['action2'] ) && -1 != $_REQUEST['action2'] )
|
342 |
+
return $_REQUEST['action2'];
|
343 |
+
|
344 |
+
return false;
|
345 |
+
}
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Generate row actions div
|
349 |
+
*
|
350 |
+
* @since 3.1.0
|
351 |
+
* @access protected
|
352 |
+
*
|
353 |
+
* @param array $actions The list of actions
|
354 |
+
* @param bool $always_visible Whether the actions should be always visible
|
355 |
+
* @return string
|
356 |
+
*/
|
357 |
+
function row_actions( $actions, $always_visible = false ) {
|
358 |
+
$action_count = count( $actions );
|
359 |
+
$i = 0;
|
360 |
+
|
361 |
+
if ( !$action_count )
|
362 |
+
return '';
|
363 |
+
|
364 |
+
$out = '<div class="' . ( $always_visible ? 'row-actions visible' : 'row-actions' ) . '">';
|
365 |
+
foreach ( $actions as $action => $link ) {
|
366 |
+
++$i;
|
367 |
+
( $i == $action_count ) ? $sep = '' : $sep = ' | ';
|
368 |
+
$out .= "<span class='$action'>$link$sep</span>";
|
369 |
+
}
|
370 |
+
$out .= '</div>';
|
371 |
+
|
372 |
+
return $out;
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Display a monthly dropdown for filtering items
|
377 |
+
*
|
378 |
+
* @since 3.1.0
|
379 |
+
* @access protected
|
380 |
+
*/
|
381 |
+
function months_dropdown( $post_type ) {
|
382 |
+
global $wpdb, $wp_locale;
|
383 |
+
|
384 |
+
$months = $wpdb->get_results( $wpdb->prepare( "
|
385 |
+
SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
|
386 |
+
FROM $wpdb->posts
|
387 |
+
WHERE post_type = %s
|
388 |
+
ORDER BY post_date DESC
|
389 |
+
", $post_type ) );
|
390 |
+
|
391 |
+
/**
|
392 |
+
* Filter the 'Months' drop-down results.
|
393 |
+
*
|
394 |
+
* @since 3.7.0
|
395 |
+
*
|
396 |
+
* @param object $months The months drop-down query results.
|
397 |
+
* @param string $post_type The post type.
|
398 |
+
*/
|
399 |
+
$months = apply_filters( 'months_dropdown_results', $months, $post_type );
|
400 |
+
|
401 |
+
$month_count = count( $months );
|
402 |
+
|
403 |
+
if ( !$month_count || ( 1 == $month_count && 0 == $months[0]->month ) )
|
404 |
+
return;
|
405 |
+
|
406 |
+
$m = isset( $_GET['m'] ) ? (int) $_GET['m'] : 0;
|
407 |
+
?>
|
408 |
+
<select name='m'>
|
409 |
+
<option<?php selected( $m, 0 ); ?> value='0'><?php _e( 'Show all dates' ); ?></option>
|
410 |
+
<?php
|
411 |
+
foreach ( $months as $arc_row ) {
|
412 |
+
if ( 0 == $arc_row->year )
|
413 |
+
continue;
|
414 |
+
|
415 |
+
$month = zeroise( $arc_row->month, 2 );
|
416 |
+
$year = $arc_row->year;
|
417 |
+
|
418 |
+
printf( "<option %s value='%s'>%s</option>\n",
|
419 |
+
selected( $m, $year . $month, false ),
|
420 |
+
esc_attr( $arc_row->year . $month ),
|
421 |
+
/* translators: 1: month name, 2: 4-digit year */
|
422 |
+
sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
|
423 |
+
);
|
424 |
+
}
|
425 |
+
?>
|
426 |
+
</select>
|
427 |
+
<?php
|
428 |
+
}
|
429 |
+
|
430 |
+
/**
|
431 |
+
* Display a view switcher
|
432 |
+
*
|
433 |
+
* @since 3.1.0
|
434 |
+
* @access protected
|
435 |
+
*/
|
436 |
+
function view_switcher( $current_mode ) {
|
437 |
+
$modes = array(
|
438 |
+
'list' => __( 'List View' ),
|
439 |
+
'excerpt' => __( 'Excerpt View' )
|
440 |
+
);
|
441 |
+
|
442 |
+
?>
|
443 |
+
<input type="hidden" name="mode" value="<?php echo esc_attr( $current_mode ); ?>" />
|
444 |
+
<div class="view-switch">
|
445 |
+
<?php
|
446 |
+
foreach ( $modes as $mode => $title ) {
|
447 |
+
$class = ( $current_mode == $mode ) ? 'class="current"' : '';
|
448 |
+
echo "<a href='" . esc_url( add_query_arg( 'mode', $mode, $_SERVER['REQUEST_URI'] ) ) . "' $class><img id='view-switch-$mode' src='" . esc_url( includes_url( 'images/blank.gif' ) ) . "' width='20' height='20' title='$title' alt='$title' /></a>\n";
|
449 |
+
}
|
450 |
+
?>
|
451 |
+
</div>
|
452 |
+
<?php
|
453 |
+
}
|
454 |
+
|
455 |
+
/**
|
456 |
+
* Display a comment count bubble
|
457 |
+
*
|
458 |
+
* @since 3.1.0
|
459 |
+
* @access protected
|
460 |
+
*
|
461 |
+
* @param int $post_id
|
462 |
+
* @param int $pending_comments
|
463 |
+
*/
|
464 |
+
function comments_bubble( $post_id, $pending_comments ) {
|
465 |
+
$pending_phrase = sprintf( __( '%s pending' ), number_format( $pending_comments ) );
|
466 |
+
|
467 |
+
if ( $pending_comments )
|
468 |
+
echo '<strong>';
|
469 |
+
|
470 |
+
echo "<a href='" . esc_url( add_query_arg( 'p', $post_id, admin_url( 'edit-comments.php' ) ) ) . "' title='" . esc_attr( $pending_phrase ) . "' class='post-com-count'><span class='comment-count'>" . number_format_i18n( get_comments_number() ) . "</span></a>";
|
471 |
+
|
472 |
+
if ( $pending_comments )
|
473 |
+
echo '</strong>';
|
474 |
+
}
|
475 |
+
|
476 |
+
/**
|
477 |
+
* Get the current page number
|
478 |
+
*
|
479 |
+
* @since 3.1.0
|
480 |
+
* @access protected
|
481 |
+
*
|
482 |
+
* @return int
|
483 |
+
*/
|
484 |
+
function get_pagenum() {
|
485 |
+
$pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0;
|
486 |
+
|
487 |
+
if( isset( $this->_pagination_args['total_pages'] ) && $pagenum > $this->_pagination_args['total_pages'] )
|
488 |
+
$pagenum = $this->_pagination_args['total_pages'];
|
489 |
+
|
490 |
+
return max( 1, $pagenum );
|
491 |
+
}
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Get number of items to display on a single page
|
495 |
+
*
|
496 |
+
* @since 3.1.0
|
497 |
+
* @access protected
|
498 |
+
*
|
499 |
+
* @return int
|
500 |
+
*/
|
501 |
+
function get_items_per_page( $option, $default = 20 ) {
|
502 |
+
$per_page = (int) get_user_option( $option );
|
503 |
+
if ( empty( $per_page ) || $per_page < 1 )
|
504 |
+
$per_page = $default;
|
505 |
+
|
506 |
+
/**
|
507 |
+
* Filter the number of items to be displayed on each page of the list table.
|
508 |
+
*
|
509 |
+
* The dynamic hook name, $option, refers to the per page option depending
|
510 |
+
* on the type of list table in use. Possible values may include:
|
511 |
+
* 'edit_comments_per_page', 'sites_network_per_page', 'site_themes_network_per_page',
|
512 |
+
* 'themes_netework_per_page', 'users_network_per_page', 'edit_{$post_type}', etc.
|
513 |
+
*
|
514 |
+
* @since 2.9.0
|
515 |
+
*
|
516 |
+
* @param int $per_page Number of items to be displayed. Default 20.
|
517 |
+
*/
|
518 |
+
return (int) apply_filters( $option, $per_page );
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Display the pagination.
|
523 |
+
*
|
524 |
+
* @since 3.1.0
|
525 |
+
* @access protected
|
526 |
+
*/
|
527 |
+
function pagination( $which ) {
|
528 |
+
if ( empty( $this->_pagination_args ) )
|
529 |
+
return;
|
530 |
+
|
531 |
+
extract( $this->_pagination_args, EXTR_SKIP );
|
532 |
+
|
533 |
+
$output = '<span class="displaying-num">' . sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) ) . '</span>';
|
534 |
+
|
535 |
+
$current = $this->get_pagenum();
|
536 |
+
|
537 |
+
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
|
538 |
+
|
539 |
+
$current_url = remove_query_arg( array( 'hotkeys_highlight_last', 'hotkeys_highlight_first' ), $current_url );
|
540 |
+
|
541 |
+
$page_links = array();
|
542 |
+
|
543 |
+
$disable_first = $disable_last = '';
|
544 |
+
if ( $current == 1 )
|
545 |
+
$disable_first = ' disabled';
|
546 |
+
if ( $current == $total_pages )
|
547 |
+
$disable_last = ' disabled';
|
548 |
+
|
549 |
+
$page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
|
550 |
+
'first-page' . $disable_first,
|
551 |
+
esc_attr__( 'Go to the first page' ),
|
552 |
+
esc_url( remove_query_arg( 'paged', $current_url ) ),
|
553 |
+
'«'
|
554 |
+
);
|
555 |
+
|
556 |
+
$page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
|
557 |
+
'prev-page' . $disable_first,
|
558 |
+
esc_attr__( 'Go to the previous page' ),
|
559 |
+
esc_url( add_query_arg( 'paged', max( 1, $current-1 ), $current_url ) ),
|
560 |
+
'‹'
|
561 |
+
);
|
562 |
+
|
563 |
+
if ( 'bottom' == $which )
|
564 |
+
$html_current_page = $current;
|
565 |
+
else
|
566 |
+
$html_current_page = sprintf( "<input class='current-page' title='%s' type='text' name='paged' value='%s' size='%d' />",
|
567 |
+
esc_attr__( 'Current page' ),
|
568 |
+
$current,
|
569 |
+
strlen( $total_pages )
|
570 |
+
);
|
571 |
+
|
572 |
+
$html_total_pages = sprintf( "<span class='total-pages'>%s</span>", number_format_i18n( $total_pages ) );
|
573 |
+
$page_links[] = '<span class="paging-input">' . sprintf( _x( '%1$s of %2$s', 'paging' ), $html_current_page, $html_total_pages ) . '</span>';
|
574 |
+
|
575 |
+
$page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
|
576 |
+
'next-page' . $disable_last,
|
577 |
+
esc_attr__( 'Go to the next page' ),
|
578 |
+
esc_url( add_query_arg( 'paged', min( $total_pages, $current+1 ), $current_url ) ),
|
579 |
+
'›'
|
580 |
+
);
|
581 |
+
|
582 |
+
$page_links[] = sprintf( "<a class='%s' title='%s' href='%s'>%s</a>",
|
583 |
+
'last-page' . $disable_last,
|
584 |
+
esc_attr__( 'Go to the last page' ),
|
585 |
+
esc_url( add_query_arg( 'paged', $total_pages, $current_url ) ),
|
586 |
+
'»'
|
587 |
+
);
|
588 |
+
|
589 |
+
$pagination_links_class = 'pagination-links';
|
590 |
+
if ( ! empty( $infinite_scroll ) )
|
591 |
+
$pagination_links_class = ' hide-if-js';
|
592 |
+
$output .= "\n<span class='$pagination_links_class'>" . join( "\n", $page_links ) . '</span>';
|
593 |
+
|
594 |
+
if ( $total_pages )
|
595 |
+
$page_class = $total_pages < 2 ? ' one-page' : '';
|
596 |
+
else
|
597 |
+
$page_class = ' no-pages';
|
598 |
+
|
599 |
+
$this->_pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
|
600 |
+
|
601 |
+
echo $this->_pagination;
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* Get a list of columns. The format is:
|
606 |
+
* 'internal-name' => 'Title'
|
607 |
+
*
|
608 |
+
* @since 3.1.0
|
609 |
+
* @access protected
|
610 |
+
* @abstract
|
611 |
+
*
|
612 |
+
* @return array
|
613 |
+
*/
|
614 |
+
function get_columns() {
|
615 |
+
die( 'function WP_List_Table::get_columns() must be over-ridden in a sub-class.' );
|
616 |
+
}
|
617 |
+
|
618 |
+
/**
|
619 |
+
* Get a list of sortable columns. The format is:
|
620 |
+
* 'internal-name' => 'orderby'
|
621 |
+
* or
|
622 |
+
* 'internal-name' => array( 'orderby', true )
|
623 |
+
*
|
624 |
+
* The second format will make the initial sorting order be descending
|
625 |
+
*
|
626 |
+
* @since 3.1.0
|
627 |
+
* @access protected
|
628 |
+
*
|
629 |
+
* @return array
|
630 |
+
*/
|
631 |
+
function get_sortable_columns() {
|
632 |
+
return array();
|
633 |
+
}
|
634 |
+
|
635 |
+
/**
|
636 |
+
* Get a list of all, hidden and sortable columns, with filter applied
|
637 |
+
*
|
638 |
+
* @since 3.1.0
|
639 |
+
* @access protected
|
640 |
+
*
|
641 |
+
* @return array
|
642 |
+
*/
|
643 |
+
function get_column_info() {
|
644 |
+
if ( isset( $this->_column_headers ) )
|
645 |
+
return $this->_column_headers;
|
646 |
+
|
647 |
+
$columns = get_column_headers( $this->screen );
|
648 |
+
$hidden = get_hidden_columns( $this->screen );
|
649 |
+
|
650 |
+
$sortable_columns = $this->get_sortable_columns();
|
651 |
+
/**
|
652 |
+
* Filter the list table sortable columns for a specific screen.
|
653 |
+
*
|
654 |
+
* The dynamic portion of the hook name, $this->screen->id, refers
|
655 |
+
* to the ID of the current screen, usually a string.
|
656 |
+
*
|
657 |
+
* @since 3.5.0
|
658 |
+
*
|
659 |
+
* @param array $sortable_columns An array of sortable columns.
|
660 |
+
*/
|
661 |
+
$_sortable = apply_filters( "manage_{$this->screen->id}_sortable_columns", $sortable_columns );
|
662 |
+
|
663 |
+
$sortable = array();
|
664 |
+
foreach ( $_sortable as $id => $data ) {
|
665 |
+
if ( empty( $data ) )
|
666 |
+
continue;
|
667 |
+
|
668 |
+
$data = (array) $data;
|
669 |
+
if ( !isset( $data[1] ) )
|
670 |
+
$data[1] = false;
|
671 |
+
|
672 |
+
$sortable[$id] = $data;
|
673 |
+
}
|
674 |
+
|
675 |
+
$this->_column_headers = array( $columns, $hidden, $sortable );
|
676 |
+
|
677 |
+
return $this->_column_headers;
|
678 |
+
}
|
679 |
+
|
680 |
+
/**
|
681 |
+
* Return number of visible columns
|
682 |
+
*
|
683 |
+
* @since 3.1.0
|
684 |
+
* @access public
|
685 |
+
*
|
686 |
+
* @return int
|
687 |
+
*/
|
688 |
+
function get_column_count() {
|
689 |
+
list ( $columns, $hidden ) = $this->get_column_info();
|
690 |
+
$hidden = array_intersect( array_keys( $columns ), array_filter( $hidden ) );
|
691 |
+
return count( $columns ) - count( $hidden );
|
692 |
+
}
|
693 |
+
|
694 |
+
/**
|
695 |
+
* Print column headers, accounting for hidden and sortable columns.
|
696 |
+
*
|
697 |
+
* @since 3.1.0
|
698 |
+
* @access protected
|
699 |
+
*
|
700 |
+
* @param bool $with_id Whether to set the id attribute or not
|
701 |
+
*/
|
702 |
+
function print_column_headers( $with_id = true ) {
|
703 |
+
list( $columns, $hidden, $sortable ) = $this->get_column_info();
|
704 |
+
|
705 |
+
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
|
706 |
+
$current_url = remove_query_arg( 'paged', $current_url );
|
707 |
+
|
708 |
+
if ( isset( $_GET['orderby'] ) )
|
709 |
+
$current_orderby = $_GET['orderby'];
|
710 |
+
else
|
711 |
+
$current_orderby = '';
|
712 |
+
|
713 |
+
if ( isset( $_GET['order'] ) && 'desc' == $_GET['order'] )
|
714 |
+
$current_order = 'desc';
|
715 |
+
else
|
716 |
+
$current_order = 'asc';
|
717 |
+
|
718 |
+
if ( ! empty( $columns['cb'] ) ) {
|
719 |
+
static $cb_counter = 1;
|
720 |
+
$columns['cb'] = '<label class="screen-reader-text" for="cb-select-all-' . $cb_counter . '">' . __( 'Select All' ) . '</label>'
|
721 |
+
. '<input id="cb-select-all-' . $cb_counter . '" type="checkbox" />';
|
722 |
+
$cb_counter++;
|
723 |
+
}
|
724 |
+
|
725 |
+
foreach ( $columns as $column_key => $column_display_name ) {
|
726 |
+
$class = array( 'manage-column', "column-$column_key" );
|
727 |
+
|
728 |
+
$style = '';
|
729 |
+
if ( in_array( $column_key, $hidden ) )
|
730 |
+
$style = 'display:none;';
|
731 |
+
|
732 |
+
$style = ' style="' . $style . '"';
|
733 |
+
|
734 |
+
if ( 'cb' == $column_key )
|
735 |
+
$class[] = 'check-column';
|
736 |
+
elseif ( in_array( $column_key, array( 'posts', 'comments', 'links' ) ) )
|
737 |
+
$class[] = 'num';
|
738 |
+
|
739 |
+
if ( isset( $sortable[$column_key] ) ) {
|
740 |
+
list( $orderby, $desc_first ) = $sortable[$column_key];
|
741 |
+
|
742 |
+
if ( $current_orderby == $orderby ) {
|
743 |
+
$order = 'asc' == $current_order ? 'desc' : 'asc';
|
744 |
+
$class[] = 'sorted';
|
745 |
+
$class[] = $current_order;
|
746 |
+
} else {
|
747 |
+
$order = $desc_first ? 'desc' : 'asc';
|
748 |
+
$class[] = 'sortable';
|
749 |
+
$class[] = $desc_first ? 'asc' : 'desc';
|
750 |
+
}
|
751 |
+
|
752 |
+
$column_display_name = '<a href="' . esc_url( add_query_arg( compact( 'orderby', 'order' ), $current_url ) ) . '"><span>' . $column_display_name . '</span><span class="sorting-indicator"></span></a>';
|
753 |
+
}
|
754 |
+
|
755 |
+
$id = $with_id ? "id='$column_key'" : '';
|
756 |
+
|
757 |
+
if ( !empty( $class ) )
|
758 |
+
$class = "class='" . join( ' ', $class ) . "'";
|
759 |
+
|
760 |
+
echo "<th scope='col' $id $class $style>$column_display_name</th>";
|
761 |
+
}
|
762 |
+
}
|
763 |
+
|
764 |
+
/**
|
765 |
+
* Display the table
|
766 |
+
*
|
767 |
+
* @since 3.1.0
|
768 |
+
* @access public
|
769 |
+
*/
|
770 |
+
function display() {
|
771 |
+
extract( $this->_args );
|
772 |
+
|
773 |
+
$this->display_tablenav( 'top' );
|
774 |
+
|
775 |
+
?>
|
776 |
+
<table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>" cellspacing="0">
|
777 |
+
<thead>
|
778 |
+
<tr>
|
779 |
+
<?php $this->print_column_headers(); ?>
|
780 |
+
</tr>
|
781 |
+
</thead>
|
782 |
+
|
783 |
+
<tfoot>
|
784 |
+
<tr>
|
785 |
+
<?php $this->print_column_headers( false ); ?>
|
786 |
+
</tr>
|
787 |
+
</tfoot>
|
788 |
+
|
789 |
+
<tbody id="the-list"<?php if ( $singular ) echo " data-wp-lists='list:$singular'"; ?>>
|
790 |
+
<?php $this->display_rows_or_placeholder(); ?>
|
791 |
+
</tbody>
|
792 |
+
</table>
|
793 |
+
<?php
|
794 |
+
$this->display_tablenav( 'bottom' );
|
795 |
+
}
|
796 |
+
|
797 |
+
/**
|
798 |
+
* Get a list of CSS classes for the <table> tag
|
799 |
+
*
|
800 |
+
* @since 3.1.0
|
801 |
+
* @access protected
|
802 |
+
*
|
803 |
+
* @return array
|
804 |
+
*/
|
805 |
+
function get_table_classes() {
|
806 |
+
return array( 'widefat', 'fixed', $this->_args['plural'] );
|
807 |
+
}
|
808 |
+
|
809 |
+
/**
|
810 |
+
* Generate the table navigation above or below the table
|
811 |
+
*
|
812 |
+
* @since 3.1.0
|
813 |
+
* @access protected
|
814 |
+
*/
|
815 |
+
function display_tablenav( $which ) {
|
816 |
+
if ( 'top' == $which )
|
817 |
+
wp_nonce_field( 'bulk-' . $this->_args['plural'] );
|
818 |
+
?>
|
819 |
+
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
820 |
+
|
821 |
+
<div class="alignleft actions bulkactions">
|
822 |
+
<?php $this->bulk_actions(); ?>
|
823 |
+
</div>
|
824 |
+
<?php
|
825 |
+
$this->extra_tablenav( $which );
|
826 |
+
$this->pagination( $which );
|
827 |
+
?>
|
828 |
+
|
829 |
+
<br class="clear" />
|
830 |
+
</div>
|
831 |
+
<?php
|
832 |
+
}
|
833 |
+
|
834 |
+
/**
|
835 |
+
* Extra controls to be displayed between bulk actions and pagination
|
836 |
+
*
|
837 |
+
* @since 3.1.0
|
838 |
+
* @access protected
|
839 |
+
*/
|
840 |
+
function extra_tablenav( $which ) {}
|
841 |
+
|
842 |
+
/**
|
843 |
+
* Generate the <tbody> part of the table
|
844 |
+
*
|
845 |
+
* @since 3.1.0
|
846 |
+
* @access protected
|
847 |
+
*/
|
848 |
+
function display_rows_or_placeholder() {
|
849 |
+
if ( $this->has_items() ) {
|
850 |
+
$this->display_rows();
|
851 |
+
} else {
|
852 |
+
list( $columns, $hidden ) = $this->get_column_info();
|
853 |
+
echo '<tr class="no-items"><td class="colspanchange" colspan="' . $this->get_column_count() . '">';
|
854 |
+
$this->no_items();
|
855 |
+
echo '</td></tr>';
|
856 |
+
}
|
857 |
+
}
|
858 |
+
|
859 |
+
/**
|
860 |
+
* Generate the table rows
|
861 |
+
*
|
862 |
+
* @since 3.1.0
|
863 |
+
* @access protected
|
864 |
+
*/
|
865 |
+
function display_rows() {
|
866 |
+
foreach ( $this->items as $item )
|
867 |
+
$this->single_row( $item );
|
868 |
+
}
|
869 |
+
|
870 |
+
/**
|
871 |
+
* Generates content for a single row of the table
|
872 |
+
*
|
873 |
+
* @since 3.1.0
|
874 |
+
* @access protected
|
875 |
+
*
|
876 |
+
* @param object $item The current item
|
877 |
+
*/
|
878 |
+
function single_row( $item ) {
|
879 |
+
static $row_class = '';
|
880 |
+
$row_class = ( $row_class == '' ? ' class="alternate"' : '' );
|
881 |
+
|
882 |
+
echo '<tr' . $row_class . '>';
|
883 |
+
$this->single_row_columns( $item );
|
884 |
+
echo '</tr>';
|
885 |
+
}
|
886 |
+
|
887 |
+
/**
|
888 |
+
* Generates the columns for a single row of the table
|
889 |
+
*
|
890 |
+
* @since 3.1.0
|
891 |
+
* @access protected
|
892 |
+
*
|
893 |
+
* @param object $item The current item
|
894 |
+
*/
|
895 |
+
function single_row_columns( $item ) {
|
896 |
+
list( $columns, $hidden ) = $this->get_column_info();
|
897 |
+
|
898 |
+
foreach ( $columns as $column_name => $column_display_name ) {
|
899 |
+
$class = "class='$column_name column-$column_name'";
|
900 |
+
|
901 |
+
$style = '';
|
902 |
+
if ( in_array( $column_name, $hidden ) )
|
903 |
+
$style = ' style="display:none;"';
|
904 |
+
|
905 |
+
$attributes = "$class$style";
|
906 |
+
|
907 |
+
if ( 'cb' == $column_name ) {
|
908 |
+
echo '<th scope="row" class="check-column">';
|
909 |
+
echo $this->column_cb( $item );
|
910 |
+
echo '</th>';
|
911 |
+
}
|
912 |
+
elseif ( method_exists( $this, 'column_' . $column_name ) ) {
|
913 |
+
echo "<td $attributes>";
|
914 |
+
echo call_user_func( array( $this, 'column_' . $column_name ), $item );
|
915 |
+
echo "</td>";
|
916 |
+
}
|
917 |
+
else {
|
918 |
+
echo "<td $attributes>";
|
919 |
+
echo $this->column_default( $item, $column_name );
|
920 |
+
echo "</td>";
|
921 |
+
}
|
922 |
+
}
|
923 |
+
}
|
924 |
+
|
925 |
+
/**
|
926 |
+
* Handle an incoming ajax request (called from admin-ajax.php)
|
927 |
+
*
|
928 |
+
* @since 3.1.0
|
929 |
+
* @access public
|
930 |
+
*/
|
931 |
+
function ajax_response() {
|
932 |
+
$this->prepare_items();
|
933 |
+
|
934 |
+
extract( $this->_args );
|
935 |
+
extract( $this->_pagination_args, EXTR_SKIP );
|
936 |
+
|
937 |
+
ob_start();
|
938 |
+
if ( ! empty( $_REQUEST['no_placeholder'] ) )
|
939 |
+
$this->display_rows();
|
940 |
+
else
|
941 |
+
$this->display_rows_or_placeholder();
|
942 |
+
|
943 |
+
$rows = ob_get_clean();
|
944 |
+
|
945 |
+
$response = array( 'rows' => $rows );
|
946 |
+
|
947 |
+
if ( isset( $total_items ) )
|
948 |
+
$response['total_items_i18n'] = sprintf( _n( '1 item', '%s items', $total_items ), number_format_i18n( $total_items ) );
|
949 |
+
|
950 |
+
if ( isset( $total_pages ) ) {
|
951 |
+
$response['total_pages'] = $total_pages;
|
952 |
+
$response['total_pages_i18n'] = number_format_i18n( $total_pages );
|
953 |
+
}
|
954 |
+
|
955 |
+
die( json_encode( $response ) );
|
956 |
+
}
|
957 |
+
|
958 |
+
/**
|
959 |
+
* Send required variables to JavaScript land
|
960 |
+
*
|
961 |
+
* @access private
|
962 |
+
*/
|
963 |
+
function _js_vars() {
|
964 |
+
$args = array(
|
965 |
+
'class' => get_class( $this ),
|
966 |
+
'screen' => array(
|
967 |
+
'id' => $this->screen->id,
|
968 |
+
'base' => $this->screen->base,
|
969 |
+
)
|
970 |
+
);
|
971 |
+
|
972 |
+
printf( "<script type='text/javascript'>list_args = %s;</script>\n", json_encode( $args ) );
|
973 |
+
}
|
974 |
+
}
|
inc/redux/WPML_Redux_Framework_config.php
CHANGED
@@ -2,247 +2,247 @@
|
|
2 |
|
3 |
namespace No3x\WPML\Settings;
|
4 |
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
|
10 |
if (!class_exists('WPML_Redux_Framework_config')) {
|
11 |
|
12 |
class WPML_Redux_Framework_config {
|
13 |
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
public function __construct( $plugin_meta ) {
|
21 |
-
$this->plugin_meta = $plugin_meta;
|
22 |
|
23 |
-
|
24 |
-
|
25 |
-
}
|
26 |
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
} else {
|
31 |
-
add_action( 'plugins_loaded', array( $this, 'initSettings' ), 10 );
|
32 |
-
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
-
|
37 |
|
38 |
-
|
39 |
-
$this->theme = wp_get_theme();
|
40 |
|
41 |
-
|
42 |
-
|
43 |
|
44 |
-
|
45 |
-
|
46 |
|
47 |
-
|
48 |
-
|
49 |
|
50 |
-
|
51 |
-
|
52 |
-
}
|
53 |
|
54 |
-
|
55 |
-
|
|
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
//add_filter('redux/options/'.$this->args['opt_name'].'/compiler', array( $this, 'compiler_action' ), 10, 3);
|
60 |
|
61 |
-
|
62 |
-
|
|
|
63 |
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
|
69 |
|
70 |
-
|
71 |
-
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
* It only runs if a field set with compiler=>true is changed.
|
76 |
-
* */
|
77 |
-
function compiler_action( $options, $css, $changed_values ) {
|
78 |
-
echo '<h1>The compiler hook has run!</h1>';
|
79 |
-
echo "<pre>";
|
80 |
-
print_r( $changed_values ); // Values that have changed since the last save
|
81 |
-
echo "</pre>";
|
82 |
-
//print_r($options); //Option values
|
83 |
-
//print_r($css); // Compiler selector CSS values compiler => array( CSS SELECTORS )
|
84 |
-
|
85 |
-
/*
|
86 |
-
// Demo of how to use the dynamic CSS and write your own static CSS file
|
87 |
-
$filename = dirname(__FILE__) . '/style' . '.css';
|
88 |
-
global $wp_filesystem;
|
89 |
-
if( empty( $wp_filesystem ) ) {
|
90 |
-
require_once( ABSPATH .'/wp-admin/includes/file.php' );
|
91 |
-
WP_Filesystem();
|
92 |
-
}
|
93 |
-
|
94 |
-
if( $wp_filesystem ) {
|
95 |
-
$wp_filesystem->put_contents(
|
96 |
-
$filename,
|
97 |
-
$css,
|
98 |
-
FS_CHMOD_FILE // predefined mode settings for WP files
|
99 |
-
);
|
100 |
-
}
|
101 |
-
*/
|
102 |
-
}
|
103 |
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
'icon' => 'el-icon-paper-clip',
|
116 |
-
// Leave this as a blank section, no options just some intro text set above.
|
117 |
-
'fields' => array()
|
118 |
-
);
|
119 |
-
|
120 |
-
return $sections;
|
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 |
-
|
172 |
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
}
|
181 |
}
|
182 |
-
|
183 |
endif;
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
<img class="hide-if-customize" src="<?php echo esc_url( $screenshot ); ?>"
|
207 |
-
alt="<?php esc_attr_e( 'Current theme preview', 'redux-framework-demo' ); ?>"/>
|
208 |
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
209 |
|
210 |
-
<h4><?php echo $this->theme->display( 'Name' ); ?></h4>
|
211 |
-
|
212 |
-
<div>
|
213 |
-
<ul class="theme-info">
|
214 |
-
<li><?php printf( __( 'By %s', 'redux-framework-demo' ), $this->theme->display( 'Author' ) ); ?></li>
|
215 |
-
<li><?php printf( __( 'Version %s', 'redux-framework-demo' ), $this->theme->display( 'Version' ) ); ?></li>
|
216 |
-
<li><?php echo '<strong>' . __( 'Tags', 'redux-framework-demo' ) . ':</strong> '; ?><?php printf( $this->theme->display( 'Tags' ) ); ?></li>
|
217 |
-
</ul>
|
218 |
-
<p class="theme-description"><?php echo $this->theme->display( 'Description' ); ?></p>
|
219 |
-
<?php
|
220 |
-
if ( $this->theme->parent() ) {
|
221 |
-
printf( ' <p class="howto">' . __( 'This <a href="%1$s">child theme</a> requires its parent theme, %2$s.', 'redux-framework-demo' ) . '</p>', __( 'http://codex.wordpress.org/Child_Themes', 'redux-framework-demo' ), $this->theme->parent()->display( 'Name' ) );
|
222 |
-
}
|
223 |
-
?>
|
224 |
-
|
225 |
-
</div>
|
226 |
</div>
|
|
|
227 |
|
228 |
-
|
229 |
-
|
230 |
|
231 |
-
|
232 |
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
|
237 |
-
|
238 |
|
239 |
-
|
240 |
-
|
241 |
|
242 |
// ACTUAL DECLARATION OF SECTIONS
|
243 |
$this->sections[] = array(
|
244 |
-
'title' => __('General Settings', '
|
245 |
-
'desc' => __('', '
|
246 |
'icon' => 'el-icon-cogs',
|
247 |
// 'submenu' => false, // Setting submenu to false on a given section will hide it from the WordPress sidebar menu!
|
248 |
'fields' => array(
|
@@ -250,354 +250,300 @@ if (!class_exists('WPML_Redux_Framework_config')) {
|
|
250 |
array(
|
251 |
'id' => 'delete-on-deactivation',
|
252 |
'type' => 'switch',
|
253 |
-
'title' => __('Cleanup', '
|
254 |
-
'subtitle' => __('Delete all data on deactivation? (emails and settings)?', '
|
255 |
'default' => 0,
|
256 |
-
'on' => 'Enabled',
|
257 |
-
'off' => 'Disabled',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
),
|
259 |
-
array(
|
260 |
-
'id' => 'can-see-submission-data',
|
261 |
-
'type' => 'select',
|
262 |
-
'data' => 'capabilities',
|
263 |
-
'default' => 'manage_options',
|
264 |
-
'title' => __('Can See Submission data', 'wpml'),
|
265 |
-
'subtitle' => __('Select the minimum role.', 'wpml'),
|
266 |
-
),
|
267 |
array(
|
268 |
'id' => 'datetimeformat-use-wordpress',
|
269 |
'type' => 'switch',
|
270 |
-
'title' => __('WordPress Date Time Format', '
|
271 |
-
'subtitle' => __(
|
272 |
'default' => 0,
|
273 |
-
'on' => 'Enabled',
|
274 |
-
'off' => 'Disabled',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
),
|
276 |
-
array(
|
277 |
-
'id' => 'preferred-mail-format',
|
278 |
-
'type' => 'select',
|
279 |
-
'options' => array(
|
280 |
-
'html' => 'html',
|
281 |
-
'raw' => 'raw',
|
282 |
-
'json' => 'json'
|
283 |
-
),
|
284 |
-
'default' => 'html',
|
285 |
-
'title' => __('Default Format for Message', 'wpml'),
|
286 |
-
'subtitle' => __('Select your preferred display format.', 'wpml'),
|
287 |
-
),
|
288 |
array(
|
289 |
'id' => 'display-host',
|
290 |
'type' => 'switch',
|
291 |
-
'title' => __('Display Host', '
|
292 |
-
'subtitle' => __('Display host column in list.', '
|
293 |
'hint' => array(
|
294 |
'title' => 'Host',
|
295 |
'content' => 'Display the IP of the host WordPress is running on. This is useful when running it on multiple servers at the same time.',
|
296 |
),
|
297 |
'default' => 0,
|
298 |
-
'on' => 'Enabled',
|
299 |
-
'off' => 'Disabled',
|
300 |
),
|
301 |
-
|
302 |
'id' => 'section-log-rotation-start',
|
303 |
'type' => 'section',
|
304 |
-
'title' => __('Log Rotation', '
|
305 |
-
'subtitle' => __('Save space by deleting logs regularly.', '
|
306 |
'indent' => true, // Indent all options below until the next 'section' option is set.
|
307 |
-
|
308 |
-
|
309 |
'id' => 'log-rotation-limit-amout',
|
310 |
'type' => 'switch',
|
311 |
-
'title' => __('Cleanup by Amount', '
|
312 |
-
'subtitle' => __('Setup a automated cleanup routine!', '
|
313 |
'default' => 0,
|
314 |
-
'on' => 'Enabled',
|
315 |
-
'off' => 'Disabled',
|
316 |
-
|
317 |
-
|
318 |
'id' => 'log-rotation-limit-amout-keep',
|
319 |
'type' => 'slider',
|
320 |
'required' => array('log-rotation-limit-amout', '=', '1'),
|
321 |
-
'title' => __('Amount', '
|
322 |
-
'subtitle' => __('When should mails are deleted?', '
|
323 |
-
'desc' => __('Cleanup when the stored mails exceed...', '
|
324 |
'default' => 75,
|
325 |
'min' => 25,
|
326 |
'step' => 50,
|
327 |
'max' => 3000,
|
328 |
'display_value' => 'text'
|
329 |
-
|
330 |
-
|
331 |
'id' => 'log-rotation-delete-time',
|
332 |
'type' => 'switch',
|
333 |
-
'title' => __('Cleanup by Time', '
|
334 |
-
'subtitle' => __('Setup a automated cleanup routine!', '
|
335 |
'default' => 0,
|
336 |
-
'on' => 'Enabled',
|
337 |
-
'off' => 'Disabled',
|
338 |
-
|
339 |
-
|
340 |
'id' => 'log-rotation-delete-time-days',
|
341 |
'type' => 'slider',
|
342 |
'required' => array('log-rotation-delete-time', '=', '1'),
|
343 |
-
'title' => __('Time', '
|
344 |
-
'subtitle' => __('When should mails are deleted?', '
|
345 |
-
'desc' => __('Delete mails older than days...', '
|
346 |
'default' => 30,
|
347 |
'min' => 1,
|
348 |
'step' => 7,
|
349 |
'max' => 400,
|
350 |
'display_value' => 'text'
|
351 |
-
|
352 |
-
|
353 |
'id' => 'section-log-rotation-end',
|
354 |
'type' => 'section',
|
355 |
'indent' => false // Indent all options below until the next 'section' option is set.
|
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 |
-
'event' => 'mouseover',
|
496 |
-
),
|
497 |
-
'hide' => array(
|
498 |
-
'effect' => 'slide',
|
499 |
-
'duration' => '500',
|
500 |
-
'event' => 'click mouseleave',
|
501 |
-
),
|
502 |
),
|
503 |
-
)
|
504 |
-
)
|
505 |
-
|
506 |
-
// ADMIN BAR LINKS -> Setup custom links in the admin bar menu as external items.
|
507 |
-
$this->args['admin_bar_links'][] = array(
|
508 |
-
'id' => 'redux-docs',
|
509 |
-
'href' => 'http://docs.reduxframework.com/',
|
510 |
-
'title' => __( 'Documentation', 'redux-framework-demo' ),
|
511 |
-
);
|
512 |
-
|
513 |
-
$this->args['admin_bar_links'][] = array(
|
514 |
-
//'id' => 'redux-support',
|
515 |
-
'href' => 'https://github.com/ReduxFramework/redux-framework/issues',
|
516 |
-
'title' => __( 'Support', 'redux-framework-demo' ),
|
517 |
-
);
|
518 |
-
|
519 |
-
$this->args['admin_bar_links'][] = array(
|
520 |
-
'id' => 'redux-extensions',
|
521 |
-
'href' => 'reduxframework.com/extensions',
|
522 |
-
'title' => __( 'Extensions', 'redux-framework-demo' ),
|
523 |
-
);
|
524 |
-
|
525 |
-
// SOCIAL ICONS -> Setup custom links in the footer for quick links in your panel footer icons.
|
526 |
-
$this->args['share_icons'][] = array(
|
527 |
-
'url' => 'https://github.com/No3x/wp-mail-logging',
|
528 |
-
'title' => 'Visit us on GitHub',
|
529 |
-
'icon' => 'el-icon-github'
|
530 |
-
//'img' => '', // You can use icon OR img. IMG needs to be a full URL.
|
531 |
-
);
|
532 |
-
$this->args['share_icons'][] = array(
|
533 |
-
'url' => $this->plugin_meta['wp_uri'],
|
534 |
-
'title' => 'Visit us on WordPress',
|
535 |
-
'icon' => 'el-icon-wordpress'
|
536 |
-
);
|
537 |
-
|
538 |
-
|
539 |
-
// Add content before the form.
|
540 |
-
// $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' );
|
541 |
-
|
542 |
-
// Add content after the form.
|
543 |
-
// $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' );
|
544 |
-
}
|
545 |
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
if(something) {
|
554 |
-
$value = $value;
|
555 |
-
} elseif(something else) {
|
556 |
-
$error = true;
|
557 |
-
$value = $existing_value;
|
558 |
-
|
559 |
-
}
|
560 |
-
*/
|
561 |
-
|
562 |
-
$return['value'] = $value;
|
563 |
-
$field['msg'] = 'your custom error message';
|
564 |
-
if ( $error == true ) {
|
565 |
-
$return['error'] = $field;
|
566 |
-
}
|
567 |
-
|
568 |
-
return $return;
|
569 |
-
}
|
570 |
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
|
577 |
-
|
|
|
|
|
|
|
|
|
578 |
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
584 |
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
echo '<br/>';
|
592 |
-
print_r( $value );
|
593 |
}
|
594 |
-
endif;
|
595 |
|
596 |
-
|
597 |
-
* Custom function for the callback validation referenced above
|
598 |
-
* */
|
599 |
-
if ( ! function_exists( 'redux_validate_callback_function' ) ):
|
600 |
-
function redux_validate_callback_function( $field, $value, $existing_value ) {
|
601 |
$error = true;
|
602 |
$value = 'just testing';
|
603 |
|
@@ -609,7 +555,7 @@ if (!class_exists('WPML_Redux_Framework_config')) {
|
|
609 |
} elseif(something else) {
|
610 |
$error = true;
|
611 |
$value = $existing_value;
|
612 |
-
|
613 |
}
|
614 |
*/
|
615 |
|
@@ -621,4 +567,58 @@ if (!class_exists('WPML_Redux_Framework_config')) {
|
|
621 |
|
622 |
return $return;
|
623 |
}
|
624 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
+
/**
|
74 |
+
* This is a test function that will let you see when the compiler hook occurs.
|
75 |
+
* It only runs if a field set with compiler=>true is changed.
|
76 |
+
* */
|
77 |
+
function compiler_action( $options, $css, $changed_values ) {
|
78 |
+
echo '<h1>The compiler hook has run!</h1>';
|
79 |
+
echo "<pre>";
|
80 |
+
print_r( $changed_values ); // Values that have changed since the last save
|
81 |
+
echo "</pre>";
|
82 |
+
//print_r($options); //Option values
|
83 |
+
//print_r($css); // Compiler selector CSS values compiler => array( CSS SELECTORS )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
+
/*
|
86 |
+
// Demo of how to use the dynamic CSS and write your own static CSS file
|
87 |
+
$filename = dirname(__FILE__) . '/style' . '.css';
|
88 |
+
global $wp_filesystem;
|
89 |
+
if( empty( $wp_filesystem ) ) {
|
90 |
+
require_once( ABSPATH .'/wp-admin/includes/file.php' );
|
91 |
+
WP_Filesystem();
|
92 |
+
}
|
93 |
|
94 |
+
if( $wp_filesystem ) {
|
95 |
+
$wp_filesystem->put_contents(
|
96 |
+
$filename,
|
97 |
+
$css,
|
98 |
+
FS_CHMOD_FILE // predefined mode settings for WP files
|
99 |
+
);
|
100 |
+
}
|
101 |
+
*/
|
102 |
+
}
|
103 |
|
104 |
+
/**
|
105 |
+
* Custom function for filtering the sections array. Good for child themes to override or add to the sections.
|
106 |
+
* Simply include this function in the child themes functions.php file.
|
107 |
+
* NOTE: the defined constants for URLs, and directories will NOT be available at this point in a child theme,
|
108 |
+
* so you must use get_template_directory_uri() if you want to use any of the built in icons
|
109 |
+
* */
|
110 |
+
function dynamic_section( $sections ) {
|
111 |
+
//$sections = array();
|
112 |
+
$sections[] = array(
|
113 |
+
'title' => 'Section via hook',
|
114 |
+
'desc' => '<p class="description">This is a section created by adding a filter to the sections array. Can be used by child themes to add/remove sections from the options.</p>',
|
115 |
+
'icon' => 'el-icon-paper-clip',
|
116 |
+
// Leave this as a blank section, no options just some intro text set above.
|
117 |
+
'fields' => array()
|
118 |
+
);
|
119 |
|
120 |
+
return $sections;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Filter hook for filtering the args. Good for child themes to override or add to the args array. Can also be used in other functions.
|
125 |
+
* */
|
126 |
+
function change_arguments( $args ) {
|
127 |
+
//$args['dev_mode'] = true;
|
128 |
+
|
129 |
+
return $args;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Filter hook for filtering the default value of any given field. Very useful in development mode.
|
134 |
+
* */
|
135 |
+
function change_defaults( $defaults ) {
|
136 |
+
$defaults['str_replace'] = 'Testing filter hook!';
|
137 |
|
138 |
+
return $defaults;
|
139 |
+
}
|
140 |
+
|
141 |
+
// Remove the demo link and the notice of integrated demo from the redux-framework plugin
|
142 |
+
function remove_demo() {
|
143 |
|
144 |
+
// Used to hide the demo mode link from the plugin page. Only used when Redux is a plugin.
|
145 |
+
if ( class_exists( 'ReduxFrameworkPlugin' ) ) {
|
146 |
+
remove_filter( 'plugin_row_meta', array(
|
147 |
+
ReduxFrameworkPlugin::instance(),
|
148 |
+
'plugin_metalinks'
|
149 |
+
), null, 2 );
|
150 |
|
151 |
+
// Used to hide the activation notice informing users of the demo panel. Only used when Redux is a plugin.
|
152 |
+
remove_action( 'admin_notices', array( ReduxFrameworkPlugin::instance(), 'admin_notices' ) );
|
|
|
153 |
}
|
154 |
+
}
|
155 |
|
156 |
+
public function setSections() {
|
157 |
|
158 |
+
/**
|
159 |
+
* Used within different fields. Simply examples. Search for ACTUAL DECLARATION for field examples
|
160 |
+
* */
|
161 |
+
// Background Patterns Reader
|
162 |
+
$sample_patterns_path = \ReduxFramework::$_dir . '../sample/patterns/';
|
163 |
+
$sample_patterns_url = \ReduxFramework::$_url . '../sample/patterns/';
|
164 |
+
$sample_patterns = array();
|
165 |
|
166 |
+
if ( is_dir( $sample_patterns_path ) ) :
|
167 |
|
168 |
+
if ( $sample_patterns_dir = opendir( $sample_patterns_path ) ) :
|
169 |
+
$sample_patterns = array();
|
170 |
|
171 |
+
while ( ( $sample_patterns_file = readdir( $sample_patterns_dir ) ) !== false ) {
|
172 |
|
173 |
+
if ( stristr( $sample_patterns_file, '.png' ) !== false || stristr( $sample_patterns_file, '.jpg' ) !== false ) {
|
174 |
+
$name = explode( '.', $sample_patterns_file );
|
175 |
+
$name = str_replace( '.' . end( $name ), '', $sample_patterns_file );
|
176 |
+
$sample_patterns[] = array(
|
177 |
+
'alt' => $name,
|
178 |
+
'img' => $sample_patterns_url . $sample_patterns_file
|
179 |
+
);
|
|
|
180 |
}
|
181 |
+
}
|
182 |
endif;
|
183 |
+
endif;
|
184 |
+
|
185 |
+
ob_start();
|
186 |
+
|
187 |
+
$ct = wp_get_theme();
|
188 |
+
$this->theme = $ct;
|
189 |
+
$item_name = $this->theme->get( 'Name' );
|
190 |
+
$tags = $this->theme->Tags;
|
191 |
+
$screenshot = $this->theme->get_screenshot();
|
192 |
+
$class = $screenshot ? 'has-screenshot' : '';
|
193 |
+
|
194 |
+
$customize_title = sprintf( __( 'Customize “%s”', 'redux-framework-demo' ), $this->theme->display( 'Name' ) );
|
195 |
+
|
196 |
+
?>
|
197 |
+
<div id="current-theme" class="<?php echo esc_attr( $class ); ?>">
|
198 |
+
<?php if ( $screenshot ) : ?>
|
199 |
+
<?php if ( current_user_can( 'edit_theme_options' ) ) : ?>
|
200 |
+
<a href="<?php echo wp_customize_url(); ?>" class="load-customize hide-if-no-customize"
|
201 |
+
title="<?php echo esc_attr( $customize_title ); ?>">
|
202 |
+
<img src="<?php echo esc_url( $screenshot ); ?>"
|
203 |
+
alt="<?php esc_attr_e( 'Current theme preview', 'redux-framework-demo' ); ?>"/>
|
204 |
+
</a>
|
|
|
|
|
205 |
<?php endif; ?>
|
206 |
+
<img class="hide-if-customize" src="<?php echo esc_url( $screenshot ); ?>"
|
207 |
+
alt="<?php esc_attr_e( 'Current theme preview', 'redux-framework-demo' ); ?>"/>
|
208 |
+
<?php endif; ?>
|
209 |
+
|
210 |
+
<h4><?php echo $this->theme->display( 'Name' ); ?></h4>
|
211 |
+
|
212 |
+
<div>
|
213 |
+
<ul class="theme-info">
|
214 |
+
<li><?php printf( __( 'By %s', 'redux-framework-demo' ), $this->theme->display( 'Author' ) ); ?></li>
|
215 |
+
<li><?php printf( __( 'Version %s', 'redux-framework-demo' ), $this->theme->display( 'Version' ) ); ?></li>
|
216 |
+
<li><?php echo '<strong>' . __( 'Tags', 'redux-framework-demo' ) . ':</strong> '; ?><?php printf( $this->theme->display( 'Tags' ) ); ?></li>
|
217 |
+
</ul>
|
218 |
+
<p class="theme-description"><?php echo $this->theme->display( 'Description' ); ?></p>
|
219 |
+
<?php
|
220 |
+
if ( $this->theme->parent() ) {
|
221 |
+
printf( ' <p class="howto">' . __( 'This <a href="%1$s">child theme</a> requires its parent theme, %2$s.', 'redux-framework-demo' ) . '</p>', __( 'http://codex.wordpress.org/Child_Themes', 'redux-framework-demo' ), $this->theme->parent()->display( 'Name' ) );
|
222 |
+
}
|
223 |
+
?>
|
224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
</div>
|
226 |
+
</div>
|
227 |
|
228 |
+
<?php
|
229 |
+
$item_info = ob_get_contents();
|
230 |
|
231 |
+
ob_end_clean();
|
232 |
|
233 |
+
$sampleHTML = '';
|
234 |
+
if ( file_exists( dirname( __FILE__ ) . '/info-html.html' ) ) {
|
235 |
+
Redux_Functions::initWpFilesystem();
|
236 |
|
237 |
+
global $wp_filesystem;
|
238 |
|
239 |
+
$sampleHTML = $wp_filesystem->get_contents( dirname( __FILE__ ) . '/info-html.html' );
|
240 |
+
}
|
241 |
|
242 |
// ACTUAL DECLARATION OF SECTIONS
|
243 |
$this->sections[] = array(
|
244 |
+
'title' => __('General Settings', 'wp-mail-logging'),
|
245 |
+
'desc' => __('', 'wp-mail-logging'),
|
246 |
'icon' => 'el-icon-cogs',
|
247 |
// 'submenu' => false, // Setting submenu to false on a given section will hide it from the WordPress sidebar menu!
|
248 |
'fields' => array(
|
250 |
array(
|
251 |
'id' => 'delete-on-deactivation',
|
252 |
'type' => 'switch',
|
253 |
+
'title' => __('Cleanup', 'wp-mail-logging' ),
|
254 |
+
'subtitle' => __('Delete all data on deactivation? (emails and settings)?', 'wp-mail-logging'),
|
255 |
'default' => 0,
|
256 |
+
'on' => __(__('Enabled', 'wp-mail-logging' ), 'wp-mail-logging' ),
|
257 |
+
'off' => __(__('Disabled', 'wp-mail-logging' ), 'wp-mail-logging' ),
|
258 |
+
),
|
259 |
+
array(
|
260 |
+
'id' => 'can-see-submission-data',
|
261 |
+
'type' => 'select',
|
262 |
+
'data' => 'capabilities',
|
263 |
+
'default' => 'manage_options',
|
264 |
+
'title' => __('Can See Submission data', 'wp-mail-logging'),
|
265 |
+
'subtitle' => __('Select the minimum role.', 'wp-mail-logging'),
|
266 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
array(
|
268 |
'id' => 'datetimeformat-use-wordpress',
|
269 |
'type' => 'switch',
|
270 |
+
'title' => __('WordPress Date Time Format', 'wp-mail-logging' ),
|
271 |
+
'subtitle' => sprintf( __( "Use format from WordPress settings (%s)", 'wp-mail-logging' ), date_i18n( $this->wordpress_default_format(), current_time( 'timestamp' ) ) ),
|
272 |
'default' => 0,
|
273 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
274 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
275 |
+
),
|
276 |
+
array(
|
277 |
+
'id' => 'preferred-mail-format',
|
278 |
+
'type' => 'select',
|
279 |
+
'options' => array(
|
280 |
+
'html' => 'html',
|
281 |
+
'raw' => 'raw',
|
282 |
+
'json' => 'json'
|
283 |
+
),
|
284 |
+
'default' => 'html',
|
285 |
+
'title' => __('Default Format for Message', 'wp-mail-logging'),
|
286 |
+
'subtitle' => __('Select your preferred display format.', 'wp-mail-logging'),
|
287 |
),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
array(
|
289 |
'id' => 'display-host',
|
290 |
'type' => 'switch',
|
291 |
+
'title' => __('Display Host', 'wp-mail-logging' ),
|
292 |
+
'subtitle' => __('Display host column in list.', 'wp-mail-logging'),
|
293 |
'hint' => array(
|
294 |
'title' => 'Host',
|
295 |
'content' => 'Display the IP of the host WordPress is running on. This is useful when running it on multiple servers at the same time.',
|
296 |
),
|
297 |
'default' => 0,
|
298 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
299 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
300 |
),
|
301 |
+
array(
|
302 |
'id' => 'section-log-rotation-start',
|
303 |
'type' => 'section',
|
304 |
+
'title' => __('Log Rotation', 'wp-mail-logging' ),
|
305 |
+
'subtitle' => __('Save space by deleting logs regularly.', 'wp-mail-logging'),
|
306 |
'indent' => true, // Indent all options below until the next 'section' option is set.
|
307 |
+
),
|
308 |
+
array(
|
309 |
'id' => 'log-rotation-limit-amout',
|
310 |
'type' => 'switch',
|
311 |
+
'title' => __('Cleanup by Amount', 'wp-mail-logging' ),
|
312 |
+
'subtitle' => __('Setup a automated cleanup routine!', 'wp-mail-logging'),
|
313 |
'default' => 0,
|
314 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
315 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
316 |
+
),
|
317 |
+
array(
|
318 |
'id' => 'log-rotation-limit-amout-keep',
|
319 |
'type' => 'slider',
|
320 |
'required' => array('log-rotation-limit-amout', '=', '1'),
|
321 |
+
'title' => __('Amount', 'wp-mail-logging' ),
|
322 |
+
'subtitle' => __('When should mails are deleted?', 'wp-mail-logging'),
|
323 |
+
'desc' => __('Cleanup when the stored mails exceed...', 'wp-mail-logging'),
|
324 |
'default' => 75,
|
325 |
'min' => 25,
|
326 |
'step' => 50,
|
327 |
'max' => 3000,
|
328 |
'display_value' => 'text'
|
329 |
+
),
|
330 |
+
array(
|
331 |
'id' => 'log-rotation-delete-time',
|
332 |
'type' => 'switch',
|
333 |
+
'title' => __('Cleanup by Time', 'wp-mail-logging' ),
|
334 |
+
'subtitle' => __('Setup a automated cleanup routine!', 'wp-mail-logging'),
|
335 |
'default' => 0,
|
336 |
+
'on' => __('Enabled', 'wp-mail-logging' ),
|
337 |
+
'off' => __('Disabled', 'wp-mail-logging' ),
|
338 |
+
),
|
339 |
+
array(
|
340 |
'id' => 'log-rotation-delete-time-days',
|
341 |
'type' => 'slider',
|
342 |
'required' => array('log-rotation-delete-time', '=', '1'),
|
343 |
+
'title' => __('Time', 'wp-mail-logging' ),
|
344 |
+
'subtitle' => __('When should mails are deleted?', 'wp-mail-logging'),
|
345 |
+
'desc' => __('Delete mails older than days...', 'wp-mail-logging'),
|
346 |
'default' => 30,
|
347 |
'min' => 1,
|
348 |
'step' => 7,
|
349 |
'max' => 400,
|
350 |
'display_value' => 'text'
|
351 |
+
),
|
352 |
+
array(
|
353 |
'id' => 'section-log-rotation-end',
|
354 |
'type' => 'section',
|
355 |
'indent' => false // Indent all options below until the next 'section' option is set.
|
356 |
+
),
|
357 |
),
|
358 |
);
|
359 |
}
|
360 |
|
361 |
+
public function wordpress_default_format()
|
362 |
+
{
|
363 |
+
$date_format = get_option( 'date_format' );
|
364 |
+
$time_format = get_option( 'time_format' );
|
365 |
+
$date_format = empty( $date_format ) ? 'F j, Y' : $date_format;
|
366 |
+
$time_format = empty( $time_format ) ? 'g:i a' : $time_format;
|
367 |
+
return "{$date_format} {$time_format}";
|
368 |
+
}
|
369 |
|
370 |
+
public function setHelpTabs() {
|
371 |
|
372 |
+
// Custom page help tabs, displayed using the help API. Tabs are shown in order of definition.
|
373 |
+
$this->args['help_tabs'][] = array(
|
374 |
+
'id' => 'redux-help-tab-1',
|
375 |
+
'title' => 'Theme Information 1',
|
376 |
+
'content' => '<p>This is the tab content, HTML is allowed.</p>'
|
377 |
+
);
|
378 |
|
379 |
+
$this->args['help_tabs'][] = array(
|
380 |
+
'id' => 'redux-help-tab-2',
|
381 |
+
'title' => 'Theme Information 2', 'redux-framework-demo',
|
382 |
+
'content' => '<p>This is the tab content, HTML is allowed.</p>'
|
383 |
+
);
|
384 |
|
385 |
+
// Set the help sidebar
|
386 |
+
$this->args['help_sidebar'] = '<p>This is the sidebar content, HTML is allowed.</p>';
|
387 |
+
}
|
388 |
|
389 |
+
/**
|
390 |
+
* All the possible arguments for Redux.
|
391 |
+
* For full documentation on arguments, please refer to: https://github.com/ReduxFramework/ReduxFramework/wiki/Arguments
|
392 |
+
* */
|
393 |
+
public function setArguments() {
|
394 |
+
|
395 |
+
$theme = wp_get_theme(); // For use with some settings. Not necessary.
|
396 |
+
|
397 |
+
$this->args = array(
|
398 |
+
// TYPICAL -> Change these values as you need/desire
|
399 |
+
'opt_name' => 'wpml_settings',
|
400 |
+
// This is where your data is stored in the database and also becomes your global variable name.
|
401 |
+
'display_name' => 'WP Mail Logging Settings',
|
402 |
+
// Name that appears at the top of your panel
|
403 |
+
'display_version' => $this->plugin_meta['version_installed'],
|
404 |
+
// Version that appears at the top of your panel
|
405 |
+
'menu_type' => 'submenu',
|
406 |
+
//Specify if the admin menu should appear or not. Options: menu or submenu (Under appearance only)
|
407 |
+
'allow_sub_menu' => true,
|
408 |
+
// Show the sections below the admin menu item or not
|
409 |
+
'menu_title' => 'Settings',
|
410 |
+
'page_title' => $this->plugin_meta['display_name'],
|
411 |
+
// You will need to generate a Google API key to use this feature.
|
412 |
+
// Please visit: https://developers.google.com/fonts/docs/developer_api#Auth
|
413 |
+
'google_api_key' => '',
|
414 |
+
// Set it you want google fonts to update weekly. A google_api_key value is required.
|
415 |
+
'google_update_weekly' => false,
|
416 |
+
// Must be defined to add google fonts to the typography module
|
417 |
+
'async_typography' => true,
|
418 |
+
// Use a asynchronous font on the front end or font string
|
419 |
+
//'disable_google_fonts_link' => true, // Disable this in case you want to create your own google fonts loader
|
420 |
+
'admin_bar' => false,
|
421 |
+
// Show the panel pages on the admin bar
|
422 |
+
'admin_bar_icon' => 'dashicons-portfolio',
|
423 |
+
// Choose an icon for the admin bar menu
|
424 |
+
'admin_bar_priority' => 50,
|
425 |
+
// Choose an priority for the admin bar menu
|
426 |
+
'global_variable' => '',
|
427 |
+
// Set a different name for your global variable other than the opt_name
|
428 |
+
'dev_mode' => false,
|
429 |
+
// Show the time the page took to load, etc
|
430 |
+
'update_notice' => true,
|
431 |
+
// If dev_mode is enabled, will notify developer of updated versions available in the GitHub Repo
|
432 |
+
'customizer' => false,
|
433 |
+
// Enable basic customizer support
|
434 |
+
//'open_expanded' => true, // Allow you to start the panel in an expanded way initially.
|
435 |
+
//'disable_save_warn' => true, // Disable the save warning when a user changes a field
|
436 |
+
|
437 |
+
// OPTIONAL -> Give you extra features
|
438 |
+
'page_priority' => null,
|
439 |
+
// Order where the menu appears in the admin area. If there is any conflict, something will not show. Warning.
|
440 |
+
'page_parent' => 'wpml_plugin_log',
|
441 |
+
// For a full list of options, visit: http://codex.wordpress.org/Function_Reference/add_submenu_page#Parameters
|
442 |
+
'page_permissions' => 'manage_options',
|
443 |
+
// Permissions needed to access the options panel.
|
444 |
+
'menu_icon' => '',
|
445 |
+
// Specify a custom URL to an icon
|
446 |
+
'last_tab' => '',
|
447 |
+
// Force your panel to always open to a specific tab (by id)
|
448 |
+
'page_icon' => 'icon-themes',
|
449 |
+
// Icon displayed in the admin panel next to your menu_title
|
450 |
+
'page_slug' => 'wpml_plugin_settings',
|
451 |
+
// Page slug used to denote the panel
|
452 |
+
'save_defaults' => true,
|
453 |
+
// On load save the defaults to DB before user clicks save or not
|
454 |
+
'default_show' => false,
|
455 |
+
// If true, shows the default value next to each field that is not the default value.
|
456 |
+
'default_mark' => '*',
|
457 |
+
// What to print by the field's title if the value shown is default. Suggested: *
|
458 |
+
'show_import_export' => true,
|
459 |
+
// Shows the Import/Export panel when not used as a field.
|
460 |
+
|
461 |
+
// CAREFUL -> These options are for advanced use only
|
462 |
+
'transient_time' => 60 * MINUTE_IN_SECONDS,
|
463 |
+
'output' => true,
|
464 |
+
// Global shut-off for dynamic CSS output by the framework. Will also disable google fonts output
|
465 |
+
'output_tag' => true,
|
466 |
+
// Allows dynamic CSS to be generated for customizer and google fonts, but stops the dynamic CSS from going to the head
|
467 |
+
// 'footer_credit' => '', // Disable the footer credit of Redux. Please leave if you can help it.
|
468 |
+
|
469 |
+
// FUTURE -> Not in use yet, but reserved or partially implemented. Use at your own risk.
|
470 |
+
'database' => '',
|
471 |
+
// possible: options, theme_mods, theme_mods_expanded, transient. Not fully functional, warning!
|
472 |
+
'system_info' => false,
|
473 |
+
// REMOVE
|
474 |
+
|
475 |
+
// HINTS
|
476 |
+
'hints' => array(
|
477 |
+
'icon' => 'el el-question-sign',
|
478 |
+
'icon_position' => 'right',
|
479 |
+
'icon_color' => 'lightgray',
|
480 |
+
'icon_size' => 'normal',
|
481 |
+
'tip_style' => array(
|
482 |
+
'color' => 'light',
|
483 |
+
'shadow' => true,
|
484 |
+
'rounded' => false,
|
485 |
+
'style' => 'bootstrap',
|
486 |
+
),
|
487 |
+
'tip_position' => array(
|
488 |
+
'my' => 'top left',
|
489 |
+
'at' => 'bottom right',
|
490 |
+
),
|
491 |
+
'tip_effect' => array(
|
492 |
+
'show' => array(
|
493 |
+
'effect' => 'slide',
|
494 |
+
'duration' => '500',
|
495 |
+
'event' => 'mouseover',
|
496 |
),
|
497 |
+
'hide' => array(
|
498 |
+
'effect' => 'slide',
|
499 |
+
'duration' => '500',
|
500 |
+
'event' => 'click mouseleave',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
501 |
),
|
502 |
+
),
|
503 |
+
)
|
504 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
|
506 |
+
// ADMIN BAR LINKS -> Setup custom links in the admin bar menu as external items.
|
507 |
+
$this->args['admin_bar_links'][] = array(
|
508 |
+
'id' => 'redux-docs',
|
509 |
+
'href' => 'http://docs.reduxframework.com/',
|
510 |
+
'title' => __( 'Documentation', 'redux-framework-demo' ),
|
511 |
+
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
|
513 |
+
$this->args['admin_bar_links'][] = array(
|
514 |
+
//'id' => 'redux-support',
|
515 |
+
'href' => 'https://github.com/ReduxFramework/redux-framework/issues',
|
516 |
+
'title' => __( 'Support', 'redux-framework-demo' ),
|
517 |
+
);
|
518 |
|
519 |
+
$this->args['admin_bar_links'][] = array(
|
520 |
+
'id' => 'redux-extensions',
|
521 |
+
'href' => 'reduxframework.com/extensions',
|
522 |
+
'title' => __( 'Extensions', 'redux-framework-demo' ),
|
523 |
+
);
|
524 |
|
525 |
+
// SOCIAL ICONS -> Setup custom links in the footer for quick links in your panel footer icons.
|
526 |
+
$this->args['share_icons'][] = array(
|
527 |
+
'url' => 'https://github.com/No3x/wp-mail-logging',
|
528 |
+
'title' => 'Visit us on GitHub',
|
529 |
+
'icon' => 'el-icon-github'
|
530 |
+
//'img' => '', // You can use icon OR img. IMG needs to be a full URL.
|
531 |
+
);
|
532 |
+
$this->args['share_icons'][] = array(
|
533 |
+
'url' => $this->plugin_meta['wp_uri'],
|
534 |
+
'title' => 'Visit us on WordPress',
|
535 |
+
'icon' => 'el-icon-wordpress'
|
536 |
+
);
|
537 |
|
538 |
+
|
539 |
+
// Add content before the form.
|
540 |
+
// $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' );
|
541 |
+
|
542 |
+
// Add content after the form.
|
543 |
+
// $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' );
|
|
|
|
|
544 |
}
|
|
|
545 |
|
546 |
+
public function validate_callback_function( $field, $value, $existing_value ) {
|
|
|
|
|
|
|
|
|
547 |
$error = true;
|
548 |
$value = 'just testing';
|
549 |
|
555 |
} elseif(something else) {
|
556 |
$error = true;
|
557 |
$value = $existing_value;
|
558 |
+
|
559 |
}
|
560 |
*/
|
561 |
|
567 |
|
568 |
return $return;
|
569 |
}
|
570 |
+
|
571 |
+
public function class_field_callback( $field, $value ) {
|
572 |
+
print_r( $field );
|
573 |
+
echo '<br/>CLASS CALLBACK';
|
574 |
+
print_r( $value );
|
575 |
+
}
|
576 |
+
|
577 |
+
}
|
578 |
+
|
579 |
+
global $reduxConfig;
|
580 |
+
//$reduxConfig = new WPML_Redux_Framework_config();
|
581 |
+
} else {
|
582 |
+
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>";
|
583 |
+
}
|
584 |
+
|
585 |
+
/**
|
586 |
+
* Custom function for the callback referenced above
|
587 |
+
*/
|
588 |
+
if ( ! function_exists( 'redux_my_custom_field' ) ):
|
589 |
+
function redux_my_custom_field( $field, $value ) {
|
590 |
+
print_r( $field );
|
591 |
+
echo '<br/>';
|
592 |
+
print_r( $value );
|
593 |
+
}
|
594 |
+
endif;
|
595 |
+
|
596 |
+
/**
|
597 |
+
* Custom function for the callback validation referenced above
|
598 |
+
* */
|
599 |
+
if ( ! function_exists( 'redux_validate_callback_function' ) ):
|
600 |
+
function redux_validate_callback_function( $field, $value, $existing_value ) {
|
601 |
+
$error = true;
|
602 |
+
$value = 'just testing';
|
603 |
+
|
604 |
+
/*
|
605 |
+
do your validation
|
606 |
+
|
607 |
+
if(something) {
|
608 |
+
$value = $value;
|
609 |
+
} elseif(something else) {
|
610 |
+
$error = true;
|
611 |
+
$value = $existing_value;
|
612 |
+
|
613 |
+
}
|
614 |
+
*/
|
615 |
+
|
616 |
+
$return['value'] = $value;
|
617 |
+
$field['msg'] = 'your custom error message';
|
618 |
+
if ( $error == true ) {
|
619 |
+
$return['error'] = $field;
|
620 |
+
}
|
621 |
+
|
622 |
+
return $return;
|
623 |
+
}
|
624 |
+
endif;
|
inc/redux/admin-init.php
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
|
3 |
// Load the embedded Redux Framework
|
4 |
if ( file_exists( dirname( __FILE__ ).'/../../lib/vendor/redux-framework/framework.php' ) ) {
|
5 |
-
|
6 |
}
|
7 |
// Load the theme/plugin options
|
8 |
if ( file_exists( dirname( __FILE__ ) . '/options-init.php' ) ) {
|
9 |
-
|
10 |
}
|
11 |
|
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' ) ) {
|
9 |
+
require_once dirname( __FILE__ ) . '/options-init.php';
|
10 |
}
|
11 |
|
languages/wp-mail-logging-de_DE.mo
ADDED
Binary file
|
languages/wp-mail-logging-de_DE.po
ADDED
@@ -0,0 +1,375 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2016 Christian Zöller
|
2 |
+
# This file is distributed under the GPLv3.
|
3 |
+
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-01-03 19:59+0100\n"
|
8 |
+
"PO-Revision-Date: 2017-01-03 20:08+0100\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 1.8.6\n"
|
16 |
+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
17 |
+
|
18 |
+
#: WPML_Email_Log_List.php:59
|
19 |
+
msgid "No email found."
|
20 |
+
msgstr "Keine E-Mail gefunden."
|
21 |
+
|
22 |
+
#: WPML_Email_Log_List.php:71
|
23 |
+
msgid "ID"
|
24 |
+
msgstr "ID"
|
25 |
+
|
26 |
+
#: WPML_Email_Log_List.php:72 inc/redux/WPML_Redux_Framework_config.php:343
|
27 |
+
msgid "Time"
|
28 |
+
msgstr "Zeit"
|
29 |
+
|
30 |
+
#: WPML_Email_Log_List.php:73
|
31 |
+
msgid "Receiver"
|
32 |
+
msgstr "Empfänger"
|
33 |
+
|
34 |
+
#: WPML_Email_Log_List.php:74
|
35 |
+
msgid "Subject"
|
36 |
+
msgstr "Betreff"
|
37 |
+
|
38 |
+
#: WPML_Email_Log_List.php:75 WPML_OptionsManager.php:497
|
39 |
+
msgid "Message"
|
40 |
+
msgstr "Nachricht"
|
41 |
+
|
42 |
+
#: WPML_Email_Log_List.php:76
|
43 |
+
msgid "Headers"
|
44 |
+
msgstr "Header"
|
45 |
+
|
46 |
+
#: WPML_Email_Log_List.php:77
|
47 |
+
msgid "Attachments"
|
48 |
+
msgstr "Anhänge"
|
49 |
+
|
50 |
+
#: WPML_Email_Log_List.php:78
|
51 |
+
msgid "Error"
|
52 |
+
msgstr "Fehler"
|
53 |
+
|
54 |
+
#: WPML_Email_Log_List.php:79
|
55 |
+
msgid "Plugin Version"
|
56 |
+
msgstr "Plugin Version"
|
57 |
+
|
58 |
+
#: WPML_Email_Log_List.php:90
|
59 |
+
msgid "Host"
|
60 |
+
msgstr "Host"
|
61 |
+
|
62 |
+
#: WPML_Email_Log_List.php:267 WPML_Email_Log_List.php:301
|
63 |
+
msgid "Attachment %s is not present"
|
64 |
+
msgstr "Anhang %s ist nicht vorhanden"
|
65 |
+
|
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 |
+
"dargestellt werden kann."
|
71 |
+
|
72 |
+
#: WPML_LifeCycle.php:205
|
73 |
+
msgid "Settings"
|
74 |
+
msgstr "Einstellungen"
|
75 |
+
|
76 |
+
#: WPML_OptionsManager.php:321 WPML_OptionsManager.php:322
|
77 |
+
msgid "WP Mail Log"
|
78 |
+
msgstr ""
|
79 |
+
|
80 |
+
#: WPML_OptionsManager.php:333 WPML_OptionsManager.php:334
|
81 |
+
#: WPML_OptionsManager.php:345
|
82 |
+
msgid "About"
|
83 |
+
msgstr "Über"
|
84 |
+
|
85 |
+
#: WPML_OptionsManager.php:422
|
86 |
+
msgid "About Plugin"
|
87 |
+
msgstr "Über das Plugin"
|
88 |
+
|
89 |
+
#: WPML_OptionsManager.php:431
|
90 |
+
msgid "More information"
|
91 |
+
msgstr "Mehr Informationen"
|
92 |
+
|
93 |
+
#: WPML_OptionsManager.php:432
|
94 |
+
msgid "Plugin Homepage/support"
|
95 |
+
msgstr ""
|
96 |
+
|
97 |
+
#: WPML_OptionsManager.php:433
|
98 |
+
msgid "Plugin author's blog"
|
99 |
+
msgstr ""
|
100 |
+
|
101 |
+
#: WPML_OptionsManager.php:440
|
102 |
+
msgid "Entries per page"
|
103 |
+
msgstr "Einträge pro Seite"
|
104 |
+
|
105 |
+
#: WPML_OptionsManager.php:462
|
106 |
+
msgid "You do not have sufficient permissions to access this page."
|
107 |
+
msgstr "Sie haben keine ausreichende Berechtigung um diese Seite zu öffnen."
|
108 |
+
|
109 |
+
#: WPML_OptionsManager.php:471
|
110 |
+
msgid "Log"
|
111 |
+
msgstr "Log"
|
112 |
+
|
113 |
+
#: WPML_OptionsManager.php:515
|
114 |
+
msgid "Close"
|
115 |
+
msgstr "Schließen"
|
116 |
+
|
117 |
+
#: WPML_OptionsManager.php:529
|
118 |
+
msgid "Search"
|
119 |
+
msgstr "Suchen"
|
120 |
+
|
121 |
+
#: WPML_OptionsManager.php:554
|
122 |
+
msgid "true"
|
123 |
+
msgstr ""
|
124 |
+
|
125 |
+
#: WPML_OptionsManager.php:556
|
126 |
+
msgid "false"
|
127 |
+
msgstr ""
|
128 |
+
|
129 |
+
#: WPML_OptionsManager.php:559
|
130 |
+
msgid "Administrator"
|
131 |
+
msgstr ""
|
132 |
+
|
133 |
+
#: WPML_OptionsManager.php:561
|
134 |
+
msgid "Editor"
|
135 |
+
msgstr ""
|
136 |
+
|
137 |
+
#: WPML_OptionsManager.php:563
|
138 |
+
msgid "Author"
|
139 |
+
msgstr ""
|
140 |
+
|
141 |
+
#: WPML_OptionsManager.php:565
|
142 |
+
msgid "Contributor"
|
143 |
+
msgstr ""
|
144 |
+
|
145 |
+
#: WPML_OptionsManager.php:567
|
146 |
+
msgid "Subscriber"
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: WPML_OptionsManager.php:569
|
150 |
+
msgid "Anyone"
|
151 |
+
msgstr ""
|
152 |
+
|
153 |
+
#: inc/class-wp-list-table.php:191
|
154 |
+
msgid "No items found."
|
155 |
+
msgstr "Keine Einträge gefunden."
|
156 |
+
|
157 |
+
#: inc/class-wp-list-table.php:315
|
158 |
+
msgid "Bulk Actions"
|
159 |
+
msgstr ""
|
160 |
+
|
161 |
+
#: inc/class-wp-list-table.php:325
|
162 |
+
msgid "Apply"
|
163 |
+
msgstr "Anwenden"
|
164 |
+
|
165 |
+
#: inc/class-wp-list-table.php:409
|
166 |
+
msgid "Show all dates"
|
167 |
+
msgstr ""
|
168 |
+
|
169 |
+
#. translators: 1: month name, 2: 4-digit year
|
170 |
+
#: inc/class-wp-list-table.php:422
|
171 |
+
msgid "%1$s %2$d"
|
172 |
+
msgstr ""
|
173 |
+
|
174 |
+
#: inc/class-wp-list-table.php:438
|
175 |
+
msgid "List View"
|
176 |
+
msgstr ""
|
177 |
+
|
178 |
+
#: inc/class-wp-list-table.php:439
|
179 |
+
msgid "Excerpt View"
|
180 |
+
msgstr ""
|
181 |
+
|
182 |
+
#: inc/class-wp-list-table.php:465
|
183 |
+
msgid "%s pending"
|
184 |
+
msgstr ""
|
185 |
+
|
186 |
+
#: inc/class-wp-list-table.php:533 inc/class-wp-list-table.php:948
|
187 |
+
msgid "1 item"
|
188 |
+
msgid_plural "%s items"
|
189 |
+
msgstr[0] ""
|
190 |
+
msgstr[1] ""
|
191 |
+
|
192 |
+
#: inc/class-wp-list-table.php:551
|
193 |
+
msgid "Go to the first page"
|
194 |
+
msgstr ""
|
195 |
+
|
196 |
+
#: inc/class-wp-list-table.php:558
|
197 |
+
msgid "Go to the previous page"
|
198 |
+
msgstr ""
|
199 |
+
|
200 |
+
#: inc/class-wp-list-table.php:567
|
201 |
+
msgid "Current page"
|
202 |
+
msgstr ""
|
203 |
+
|
204 |
+
#: inc/class-wp-list-table.php:577
|
205 |
+
msgid "Go to the next page"
|
206 |
+
msgstr ""
|
207 |
+
|
208 |
+
#: inc/class-wp-list-table.php:584
|
209 |
+
msgid "Go to the last page"
|
210 |
+
msgstr ""
|
211 |
+
|
212 |
+
#: inc/class-wp-list-table.php:720
|
213 |
+
msgid "Select All"
|
214 |
+
msgstr ""
|
215 |
+
|
216 |
+
#: inc/redux/WPML_Redux_Framework_config.php:194
|
217 |
+
msgid "Customize “%s”"
|
218 |
+
msgstr ""
|
219 |
+
|
220 |
+
#: inc/redux/WPML_Redux_Framework_config.php:203
|
221 |
+
#: inc/redux/WPML_Redux_Framework_config.php:207
|
222 |
+
msgid "Current theme preview"
|
223 |
+
msgstr ""
|
224 |
+
|
225 |
+
#: inc/redux/WPML_Redux_Framework_config.php:214
|
226 |
+
msgid "By %s"
|
227 |
+
msgstr ""
|
228 |
+
|
229 |
+
#: inc/redux/WPML_Redux_Framework_config.php:215
|
230 |
+
msgid "Version %s"
|
231 |
+
msgstr ""
|
232 |
+
|
233 |
+
#: inc/redux/WPML_Redux_Framework_config.php:216
|
234 |
+
msgid "Tags"
|
235 |
+
msgstr ""
|
236 |
+
|
237 |
+
#: inc/redux/WPML_Redux_Framework_config.php:221
|
238 |
+
msgid "This <a href=\"%1$s\">child theme</a> requires its parent theme, %2$s."
|
239 |
+
msgstr ""
|
240 |
+
|
241 |
+
#: inc/redux/WPML_Redux_Framework_config.php:221
|
242 |
+
msgid "http://codex.wordpress.org/Child_Themes"
|
243 |
+
msgstr ""
|
244 |
+
|
245 |
+
#: inc/redux/WPML_Redux_Framework_config.php:244
|
246 |
+
msgid "General Settings"
|
247 |
+
msgstr ""
|
248 |
+
|
249 |
+
#: inc/redux/WPML_Redux_Framework_config.php:253
|
250 |
+
msgid "Cleanup"
|
251 |
+
msgstr "Aufräumen"
|
252 |
+
|
253 |
+
#: inc/redux/WPML_Redux_Framework_config.php:254
|
254 |
+
msgid "Delete all data on deactivation? (emails and settings)?"
|
255 |
+
msgstr "Alle Daten bei Deaktivierung löschen? (E-Mails und Einstellungen)"
|
256 |
+
|
257 |
+
#: inc/redux/WPML_Redux_Framework_config.php:264
|
258 |
+
msgid "Can See Submission data"
|
259 |
+
msgstr "Daten sichtbar für"
|
260 |
+
|
261 |
+
#: inc/redux/WPML_Redux_Framework_config.php:265
|
262 |
+
msgid "Select the minimum role."
|
263 |
+
msgstr "Wähle die Mindestberechtigung"
|
264 |
+
|
265 |
+
#: inc/redux/WPML_Redux_Framework_config.php:270
|
266 |
+
msgid "WordPress Date Time Format"
|
267 |
+
msgstr "WordPress Zeitstempel Format"
|
268 |
+
|
269 |
+
#: inc/redux/WPML_Redux_Framework_config.php:271
|
270 |
+
msgid "Use format from WordPress settings (%s)"
|
271 |
+
msgstr "Benutze das WordPress Datumsformat aus den Einstellungen (%s)"
|
272 |
+
|
273 |
+
#: inc/redux/WPML_Redux_Framework_config.php:273
|
274 |
+
#: inc/redux/WPML_Redux_Framework_config.php:298
|
275 |
+
#: inc/redux/WPML_Redux_Framework_config.php:314
|
276 |
+
#: inc/redux/WPML_Redux_Framework_config.php:336
|
277 |
+
msgid "Enabled"
|
278 |
+
msgstr "Ein"
|
279 |
+
|
280 |
+
#: inc/redux/WPML_Redux_Framework_config.php:274
|
281 |
+
#: inc/redux/WPML_Redux_Framework_config.php:299
|
282 |
+
#: inc/redux/WPML_Redux_Framework_config.php:315
|
283 |
+
#: inc/redux/WPML_Redux_Framework_config.php:337
|
284 |
+
msgid "Disabled"
|
285 |
+
msgstr "Aus"
|
286 |
+
|
287 |
+
#: inc/redux/WPML_Redux_Framework_config.php:285
|
288 |
+
msgid "Default Format for Message"
|
289 |
+
msgstr "Standardformat für Nachrichten"
|
290 |
+
|
291 |
+
#: inc/redux/WPML_Redux_Framework_config.php:286
|
292 |
+
msgid "Select your preferred display format."
|
293 |
+
msgstr "Bevorzugtes Standardformat"
|
294 |
+
|
295 |
+
#: inc/redux/WPML_Redux_Framework_config.php:291
|
296 |
+
msgid "Display Host"
|
297 |
+
msgstr "Zeige Host"
|
298 |
+
|
299 |
+
#: inc/redux/WPML_Redux_Framework_config.php:292
|
300 |
+
msgid "Display host column in list."
|
301 |
+
msgstr "Zeige Host Spalte in Liste"
|
302 |
+
|
303 |
+
#: inc/redux/WPML_Redux_Framework_config.php:304
|
304 |
+
msgid "Log Rotation"
|
305 |
+
msgstr ""
|
306 |
+
|
307 |
+
#: inc/redux/WPML_Redux_Framework_config.php:305
|
308 |
+
msgid "Save space by deleting logs regularly."
|
309 |
+
msgstr "Platz sparen durch regelmäßiges Löschen des Logs."
|
310 |
+
|
311 |
+
#: inc/redux/WPML_Redux_Framework_config.php:311
|
312 |
+
msgid "Cleanup by Amount"
|
313 |
+
msgstr "Löschen nach Anzahl"
|
314 |
+
|
315 |
+
#: inc/redux/WPML_Redux_Framework_config.php:312
|
316 |
+
#: inc/redux/WPML_Redux_Framework_config.php:334
|
317 |
+
msgid "Setup a automated cleanup routine!"
|
318 |
+
msgstr "Erstelle eine automatische Aufräumroutine!"
|
319 |
+
|
320 |
+
#: inc/redux/WPML_Redux_Framework_config.php:321
|
321 |
+
msgid "Amount"
|
322 |
+
msgstr "Anzahl"
|
323 |
+
|
324 |
+
#: inc/redux/WPML_Redux_Framework_config.php:322
|
325 |
+
#: inc/redux/WPML_Redux_Framework_config.php:344
|
326 |
+
msgid "When should mails are deleted?"
|
327 |
+
msgstr "Wann sollen Mails gelöscht werden?"
|
328 |
+
|
329 |
+
#: inc/redux/WPML_Redux_Framework_config.php:323
|
330 |
+
msgid "Cleanup when the stored mails exceed..."
|
331 |
+
msgstr "Lösche wenn die Mails den Betrag übersteigen..."
|
332 |
+
|
333 |
+
#: inc/redux/WPML_Redux_Framework_config.php:333
|
334 |
+
msgid "Cleanup by Time"
|
335 |
+
msgstr "Löschen nach Zeit"
|
336 |
+
|
337 |
+
#: inc/redux/WPML_Redux_Framework_config.php:345
|
338 |
+
msgid "Delete mails older than days..."
|
339 |
+
msgstr "Lösche Mails älter als ... Tage"
|
340 |
+
|
341 |
+
#: inc/redux/WPML_Redux_Framework_config.php:510
|
342 |
+
msgid "Documentation"
|
343 |
+
msgstr "Dokumentation"
|
344 |
+
|
345 |
+
#: inc/redux/WPML_Redux_Framework_config.php:516
|
346 |
+
msgid "Support"
|
347 |
+
msgstr "Hilfe"
|
348 |
+
|
349 |
+
#: inc/redux/WPML_Redux_Framework_config.php:522
|
350 |
+
msgid "Extensions"
|
351 |
+
msgstr "Erweiterungen"
|
352 |
+
|
353 |
+
#: wp-mail-logging.php:48
|
354 |
+
msgid ""
|
355 |
+
"Error: plugin \"WP Mail Logging\" requires a newer version of PHP to be "
|
356 |
+
"running."
|
357 |
+
msgstr ""
|
358 |
+
"Fehler: Das Plugin \"WP Mail Logging\" benötigt eine neuere PHP Version."
|
359 |
+
|
360 |
+
#: wp-mail-logging.php:49
|
361 |
+
msgid "Minimal version of PHP required: "
|
362 |
+
msgstr "Mindestanforderung PHP Version:"
|
363 |
+
|
364 |
+
#: wp-mail-logging.php:50
|
365 |
+
msgid "Your server's PHP version: "
|
366 |
+
msgstr "Die PHP Version des Servers:"
|
367 |
+
|
368 |
+
#. Description of the plugin/theme
|
369 |
+
msgid "Logs each email sent by WordPress."
|
370 |
+
msgstr ""
|
371 |
+
|
372 |
+
#: inc/class-wp-list-table.php:573
|
373 |
+
msgctxt "paging"
|
374 |
+
msgid "%1$s of %2$s"
|
375 |
+
msgstr "%1$s von %2$s"
|
languages/wp-mail-logging-zh_CN.mo
ADDED
Binary file
|
languages/wp-mail-logging-zh_CN.po
ADDED
@@ -0,0 +1,371 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2017 Christian Zöller
|
2 |
+
# This file is distributed under the GPLv3.
|
3 |
+
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-02-12 02:34+0800\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: 2017-02-15 09:29+0800\n"
|
12 |
+
"Language-Team: \n"
|
13 |
+
"X-Generator: Poedit 1.8.1\n"
|
14 |
+
"Plural-Forms: nplurals=1; plural=0;\n"
|
15 |
+
"Language: zh_CN\n"
|
16 |
+
"Last-Translator: \n"
|
17 |
+
|
18 |
+
#: WPML_Email_Log_List.php:59
|
19 |
+
msgid "No email found."
|
20 |
+
msgstr "未找到电子邮件。"
|
21 |
+
|
22 |
+
#: WPML_Email_Log_List.php:71
|
23 |
+
msgid "ID"
|
24 |
+
msgstr "ID"
|
25 |
+
|
26 |
+
#: WPML_Email_Log_List.php:72 inc/redux/WPML_Redux_Framework_config.php:343
|
27 |
+
msgid "Time"
|
28 |
+
msgstr "时间"
|
29 |
+
|
30 |
+
#: WPML_Email_Log_List.php:73
|
31 |
+
msgid "Receiver"
|
32 |
+
msgstr "收件人"
|
33 |
+
|
34 |
+
#: WPML_Email_Log_List.php:74
|
35 |
+
msgid "Subject"
|
36 |
+
msgstr "主题"
|
37 |
+
|
38 |
+
#: WPML_Email_Log_List.php:75 WPML_OptionsManager.php:497
|
39 |
+
msgid "Message"
|
40 |
+
msgstr "消息"
|
41 |
+
|
42 |
+
#: WPML_Email_Log_List.php:76
|
43 |
+
msgid "Headers"
|
44 |
+
msgstr "邮件头"
|
45 |
+
|
46 |
+
#: WPML_Email_Log_List.php:77
|
47 |
+
msgid "Attachments"
|
48 |
+
msgstr "附件"
|
49 |
+
|
50 |
+
#: WPML_Email_Log_List.php:78
|
51 |
+
msgid "Error"
|
52 |
+
msgstr "错误"
|
53 |
+
|
54 |
+
#: WPML_Email_Log_List.php:79
|
55 |
+
msgid "Plugin Version"
|
56 |
+
msgstr "插件版本"
|
57 |
+
|
58 |
+
#: WPML_Email_Log_List.php:90
|
59 |
+
msgid "Host"
|
60 |
+
msgstr "主机名"
|
61 |
+
|
62 |
+
#: WPML_Email_Log_List.php:267 WPML_Email_Log_List.php:301
|
63 |
+
msgid "Attachment %s is not present"
|
64 |
+
msgstr "附件 %s 不存在"
|
65 |
+
|
66 |
+
#: WPML_Email_Log_List.php:495
|
67 |
+
msgid "Fallback to raw format because html is not convertible to json."
|
68 |
+
msgstr "回退到原始格式,因为 html 不是转换为 json。"
|
69 |
+
|
70 |
+
#: WPML_LifeCycle.php:205
|
71 |
+
msgid "Settings"
|
72 |
+
msgstr "设置"
|
73 |
+
|
74 |
+
#: WPML_OptionsManager.php:321 WPML_OptionsManager.php:322
|
75 |
+
msgid "WP Mail Log"
|
76 |
+
msgstr "WP Mail Log"
|
77 |
+
|
78 |
+
#: WPML_OptionsManager.php:333 WPML_OptionsManager.php:334
|
79 |
+
#: WPML_OptionsManager.php:345
|
80 |
+
msgid "About"
|
81 |
+
msgstr "关于"
|
82 |
+
|
83 |
+
#: WPML_OptionsManager.php:422
|
84 |
+
msgid "About Plugin"
|
85 |
+
msgstr "关于插件"
|
86 |
+
|
87 |
+
#: WPML_OptionsManager.php:431
|
88 |
+
msgid "More information"
|
89 |
+
msgstr "更多信息"
|
90 |
+
|
91 |
+
#: WPML_OptionsManager.php:432
|
92 |
+
msgid "Plugin Homepage/support"
|
93 |
+
msgstr "插件主页/支持"
|
94 |
+
|
95 |
+
#: WPML_OptionsManager.php:433
|
96 |
+
msgid "Plugin author's blog"
|
97 |
+
msgstr "插件作者的博客"
|
98 |
+
|
99 |
+
#: WPML_OptionsManager.php:440
|
100 |
+
msgid "Entries per page"
|
101 |
+
msgstr "每页的项目数:"
|
102 |
+
|
103 |
+
#: WPML_OptionsManager.php:462
|
104 |
+
msgid "You do not have sufficient permissions to access this page."
|
105 |
+
msgstr "您没有足够的权限来访问该页面。"
|
106 |
+
|
107 |
+
#: WPML_OptionsManager.php:471
|
108 |
+
msgid "Log"
|
109 |
+
msgstr "日志"
|
110 |
+
|
111 |
+
#: WPML_OptionsManager.php:515
|
112 |
+
msgid "Close"
|
113 |
+
msgstr "关闭"
|
114 |
+
|
115 |
+
#: WPML_OptionsManager.php:529
|
116 |
+
msgid "Search"
|
117 |
+
msgstr "搜索"
|
118 |
+
|
119 |
+
#: WPML_OptionsManager.php:554
|
120 |
+
msgid "true"
|
121 |
+
msgstr "true"
|
122 |
+
|
123 |
+
#: WPML_OptionsManager.php:556
|
124 |
+
msgid "false"
|
125 |
+
msgstr "false"
|
126 |
+
|
127 |
+
#: WPML_OptionsManager.php:559
|
128 |
+
msgid "Administrator"
|
129 |
+
msgstr "管理员"
|
130 |
+
|
131 |
+
#: WPML_OptionsManager.php:561
|
132 |
+
msgid "Editor"
|
133 |
+
msgstr "编辑"
|
134 |
+
|
135 |
+
#: WPML_OptionsManager.php:563
|
136 |
+
msgid "Author"
|
137 |
+
msgstr "作者"
|
138 |
+
|
139 |
+
#: WPML_OptionsManager.php:565
|
140 |
+
msgid "Contributor"
|
141 |
+
msgstr "贡献者"
|
142 |
+
|
143 |
+
#: WPML_OptionsManager.php:567
|
144 |
+
msgid "Subscriber"
|
145 |
+
msgstr "订阅者"
|
146 |
+
|
147 |
+
#: WPML_OptionsManager.php:569
|
148 |
+
msgid "Anyone"
|
149 |
+
msgstr "任何人"
|
150 |
+
|
151 |
+
#: inc/class-wp-list-table.php:191
|
152 |
+
msgid "No items found."
|
153 |
+
msgstr "没有找到项目。"
|
154 |
+
|
155 |
+
#: inc/class-wp-list-table.php:315
|
156 |
+
msgid "Bulk Actions"
|
157 |
+
msgstr "批量操作"
|
158 |
+
|
159 |
+
#: inc/class-wp-list-table.php:325
|
160 |
+
msgid "Apply"
|
161 |
+
msgstr "应用"
|
162 |
+
|
163 |
+
#: inc/class-wp-list-table.php:409
|
164 |
+
msgid "Show all dates"
|
165 |
+
msgstr "显示所有日期"
|
166 |
+
|
167 |
+
#. translators: 1: month name, 2: 4-digit year
|
168 |
+
#: inc/class-wp-list-table.php:422
|
169 |
+
msgid "%1$s %2$d"
|
170 |
+
msgstr "%1$s %2$d"
|
171 |
+
|
172 |
+
#: inc/class-wp-list-table.php:438
|
173 |
+
msgid "List View"
|
174 |
+
msgstr "列表视图"
|
175 |
+
|
176 |
+
#: inc/class-wp-list-table.php:439
|
177 |
+
msgid "Excerpt View"
|
178 |
+
msgstr "摘要"
|
179 |
+
|
180 |
+
#: inc/class-wp-list-table.php:465
|
181 |
+
msgid "%s pending"
|
182 |
+
msgstr "%s 待处理"
|
183 |
+
|
184 |
+
#: inc/class-wp-list-table.php:533 inc/class-wp-list-table.php:948
|
185 |
+
msgid "1 item"
|
186 |
+
msgid_plural "%s items"
|
187 |
+
msgstr[0] "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:194
|
214 |
+
msgid "Customize “%s”"
|
215 |
+
msgstr "自定义 “%s”"
|
216 |
+
|
217 |
+
#: inc/redux/WPML_Redux_Framework_config.php:203
|
218 |
+
#: inc/redux/WPML_Redux_Framework_config.php:207
|
219 |
+
msgid "Current theme preview"
|
220 |
+
msgstr "预览当前主题"
|
221 |
+
|
222 |
+
#: inc/redux/WPML_Redux_Framework_config.php:214
|
223 |
+
msgid "By %s"
|
224 |
+
msgstr "由 %s"
|
225 |
+
|
226 |
+
#: inc/redux/WPML_Redux_Framework_config.php:215
|
227 |
+
msgid "Version %s"
|
228 |
+
msgstr "版本 %s"
|
229 |
+
|
230 |
+
#: inc/redux/WPML_Redux_Framework_config.php:216
|
231 |
+
msgid "Tags"
|
232 |
+
msgstr "标签"
|
233 |
+
|
234 |
+
#: inc/redux/WPML_Redux_Framework_config.php:221
|
235 |
+
msgid "This <a href=\"%1$s\">child theme</a> requires its parent theme, %2$s."
|
236 |
+
msgstr "此<a href=\"%1$s\">子主题</a>需要其父主题 %2$s。"
|
237 |
+
|
238 |
+
#: inc/redux/WPML_Redux_Framework_config.php:221
|
239 |
+
msgid "http://codex.wordpress.org/Child_Themes"
|
240 |
+
msgstr "http://codex.wordpress.org/Child_Themes"
|
241 |
+
|
242 |
+
#: inc/redux/WPML_Redux_Framework_config.php:244
|
243 |
+
msgid "General Settings"
|
244 |
+
msgstr "常规设置"
|
245 |
+
|
246 |
+
#: inc/redux/WPML_Redux_Framework_config.php:253
|
247 |
+
msgid "Cleanup"
|
248 |
+
msgstr "清理"
|
249 |
+
|
250 |
+
#: inc/redux/WPML_Redux_Framework_config.php:254
|
251 |
+
msgid "Delete all data on deactivation? (emails and settings)?"
|
252 |
+
msgstr "删除所有停用的数据吗?(电子邮件和设置)?"
|
253 |
+
|
254 |
+
#: inc/redux/WPML_Redux_Framework_config.php:264
|
255 |
+
msgid "Can See Submission data"
|
256 |
+
msgstr "可以看到提交数据"
|
257 |
+
|
258 |
+
#: inc/redux/WPML_Redux_Framework_config.php:265
|
259 |
+
msgid "Select the minimum role."
|
260 |
+
msgstr "选择的最小的角色。"
|
261 |
+
|
262 |
+
#: inc/redux/WPML_Redux_Framework_config.php:270
|
263 |
+
msgid "WordPress Date Time Format"
|
264 |
+
msgstr "WordPress 的日期时间格式"
|
265 |
+
|
266 |
+
#: inc/redux/WPML_Redux_Framework_config.php:271
|
267 |
+
msgid "Use format from WordPress settings (%s)"
|
268 |
+
msgstr "从 WordPress 使用格式设置 (%s)"
|
269 |
+
|
270 |
+
#: inc/redux/WPML_Redux_Framework_config.php:273
|
271 |
+
#: inc/redux/WPML_Redux_Framework_config.php:298
|
272 |
+
#: inc/redux/WPML_Redux_Framework_config.php:314
|
273 |
+
#: inc/redux/WPML_Redux_Framework_config.php:336
|
274 |
+
msgid "Enabled"
|
275 |
+
msgstr "启用"
|
276 |
+
|
277 |
+
#: inc/redux/WPML_Redux_Framework_config.php:274
|
278 |
+
#: inc/redux/WPML_Redux_Framework_config.php:299
|
279 |
+
#: inc/redux/WPML_Redux_Framework_config.php:315
|
280 |
+
#: inc/redux/WPML_Redux_Framework_config.php:337
|
281 |
+
msgid "Disabled"
|
282 |
+
msgstr "禁用"
|
283 |
+
|
284 |
+
#: inc/redux/WPML_Redux_Framework_config.php:285
|
285 |
+
msgid "Default Format for Message"
|
286 |
+
msgstr "消息的默认格式"
|
287 |
+
|
288 |
+
#: inc/redux/WPML_Redux_Framework_config.php:286
|
289 |
+
msgid "Select your preferred display format."
|
290 |
+
msgstr "选择您喜欢的显示格式。"
|
291 |
+
|
292 |
+
#: inc/redux/WPML_Redux_Framework_config.php:291
|
293 |
+
msgid "Display Host"
|
294 |
+
msgstr "显示主机"
|
295 |
+
|
296 |
+
#: inc/redux/WPML_Redux_Framework_config.php:292
|
297 |
+
msgid "Display host column in list."
|
298 |
+
msgstr "在列表中显示主机。"
|
299 |
+
|
300 |
+
#: inc/redux/WPML_Redux_Framework_config.php:304
|
301 |
+
msgid "Log Rotation"
|
302 |
+
msgstr "日志轮转"
|
303 |
+
|
304 |
+
#: inc/redux/WPML_Redux_Framework_config.php:305
|
305 |
+
msgid "Save space by deleting logs regularly."
|
306 |
+
msgstr "定期删除日志以节省空间。"
|
307 |
+
|
308 |
+
#: inc/redux/WPML_Redux_Framework_config.php:311
|
309 |
+
msgid "Cleanup by Amount"
|
310 |
+
msgstr "按数量清理"
|
311 |
+
|
312 |
+
#: inc/redux/WPML_Redux_Framework_config.php:312
|
313 |
+
#: inc/redux/WPML_Redux_Framework_config.php:334
|
314 |
+
msgid "Setup a automated cleanup routine!"
|
315 |
+
msgstr "设置自动清理"
|
316 |
+
|
317 |
+
#: inc/redux/WPML_Redux_Framework_config.php:321
|
318 |
+
msgid "Amount"
|
319 |
+
msgstr "数量"
|
320 |
+
|
321 |
+
#: inc/redux/WPML_Redux_Framework_config.php:322
|
322 |
+
#: inc/redux/WPML_Redux_Framework_config.php:344
|
323 |
+
msgid "When should mails are deleted?"
|
324 |
+
msgstr "邮件何时被删除?"
|
325 |
+
|
326 |
+
#: inc/redux/WPML_Redux_Framework_config.php:323
|
327 |
+
msgid "Cleanup when the stored mails exceed..."
|
328 |
+
msgstr "当存储的邮件超过上述数量时开始清理邮件..."
|
329 |
+
|
330 |
+
#: inc/redux/WPML_Redux_Framework_config.php:333
|
331 |
+
msgid "Cleanup by Time"
|
332 |
+
msgstr "按时间清理"
|
333 |
+
|
334 |
+
#: inc/redux/WPML_Redux_Framework_config.php:345
|
335 |
+
msgid "Delete mails older than days..."
|
336 |
+
msgstr "删除超过上述天数的邮件..."
|
337 |
+
|
338 |
+
#: inc/redux/WPML_Redux_Framework_config.php:510
|
339 |
+
msgid "Documentation"
|
340 |
+
msgstr "文档"
|
341 |
+
|
342 |
+
#: inc/redux/WPML_Redux_Framework_config.php:516
|
343 |
+
msgid "Support"
|
344 |
+
msgstr "支持"
|
345 |
+
|
346 |
+
#: inc/redux/WPML_Redux_Framework_config.php:522
|
347 |
+
msgid "Extensions"
|
348 |
+
msgstr "扩展"
|
349 |
+
|
350 |
+
#: wp-mail-logging.php:48
|
351 |
+
msgid ""
|
352 |
+
"Error: plugin \"WP Mail Logging\" requires a newer version of PHP to be "
|
353 |
+
"running."
|
354 |
+
msgstr "错误:插件“WP Mail Logging”需要运行较新版本的PHP。"
|
355 |
+
|
356 |
+
#: wp-mail-logging.php:49
|
357 |
+
msgid "Minimal version of PHP required: "
|
358 |
+
msgstr "PHP的最低版本要求:"
|
359 |
+
|
360 |
+
#: wp-mail-logging.php:50
|
361 |
+
msgid "Your server's PHP version: "
|
362 |
+
msgstr "您的服务器的PHP版本:"
|
363 |
+
|
364 |
+
#. Description of the plugin/theme
|
365 |
+
msgid "Logs each email sent by WordPress."
|
366 |
+
msgstr "记录WordPress发送的每封电子邮件。"
|
367 |
+
|
368 |
+
#: inc/class-wp-list-table.php:573
|
369 |
+
msgctxt "paging"
|
370 |
+
msgid "%1$s of %2$s"
|
371 |
+
msgstr "%1$s of %2$s"
|
languages/wp-mail-logging.pot
ADDED
@@ -0,0 +1,371 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (C) 2017 Christian Zöller
|
2 |
+
# This file is distributed under the GPLv3.
|
3 |
+
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-01-03 18:59:13+00:00\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: 2017-MO-DA HO:MI+ZONE\n"
|
12 |
+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13 |
+
"Language-Team: LANGUAGE <LL@li.org>\n"
|
14 |
+
"X-Generator: grunt-wp-i18n 0.5.4\n"
|
15 |
+
"Language: en_GB\n"
|
16 |
+
|
17 |
+
#: WPML_Email_Log_List.php:59
|
18 |
+
msgid "No email found."
|
19 |
+
msgstr ""
|
20 |
+
|
21 |
+
#: WPML_Email_Log_List.php:71
|
22 |
+
msgid "ID"
|
23 |
+
msgstr ""
|
24 |
+
|
25 |
+
#: WPML_Email_Log_List.php:72 inc/redux/WPML_Redux_Framework_config.php:343
|
26 |
+
msgid "Time"
|
27 |
+
msgstr ""
|
28 |
+
|
29 |
+
#: WPML_Email_Log_List.php:73
|
30 |
+
msgid "Receiver"
|
31 |
+
msgstr ""
|
32 |
+
|
33 |
+
#: WPML_Email_Log_List.php:74
|
34 |
+
msgid "Subject"
|
35 |
+
msgstr ""
|
36 |
+
|
37 |
+
#: WPML_Email_Log_List.php:75 WPML_OptionsManager.php:497
|
38 |
+
msgid "Message"
|
39 |
+
msgstr ""
|
40 |
+
|
41 |
+
#: WPML_Email_Log_List.php:76
|
42 |
+
msgid "Headers"
|
43 |
+
msgstr ""
|
44 |
+
|
45 |
+
#: WPML_Email_Log_List.php:77
|
46 |
+
msgid "Attachments"
|
47 |
+
msgstr ""
|
48 |
+
|
49 |
+
#: WPML_Email_Log_List.php:78
|
50 |
+
msgid "Error"
|
51 |
+
msgstr ""
|
52 |
+
|
53 |
+
#: WPML_Email_Log_List.php:79
|
54 |
+
msgid "Plugin Version"
|
55 |
+
msgstr ""
|
56 |
+
|
57 |
+
#: WPML_Email_Log_List.php:90
|
58 |
+
msgid "Host"
|
59 |
+
msgstr ""
|
60 |
+
|
61 |
+
#: WPML_Email_Log_List.php:267 WPML_Email_Log_List.php:301
|
62 |
+
msgid "Attachment %s is not present"
|
63 |
+
msgstr ""
|
64 |
+
|
65 |
+
#: WPML_Email_Log_List.php:495
|
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 |
+
#: inc/class-wp-list-table.php:191
|
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:194
|
214 |
+
msgid "Customize “%s”"
|
215 |
+
msgstr ""
|
216 |
+
|
217 |
+
#: inc/redux/WPML_Redux_Framework_config.php:203
|
218 |
+
#: inc/redux/WPML_Redux_Framework_config.php:207
|
219 |
+
msgid "Current theme preview"
|
220 |
+
msgstr ""
|
221 |
+
|
222 |
+
#: inc/redux/WPML_Redux_Framework_config.php:214
|
223 |
+
msgid "By %s"
|
224 |
+
msgstr ""
|
225 |
+
|
226 |
+
#: inc/redux/WPML_Redux_Framework_config.php:215
|
227 |
+
msgid "Version %s"
|
228 |
+
msgstr ""
|
229 |
+
|
230 |
+
#: inc/redux/WPML_Redux_Framework_config.php:216
|
231 |
+
msgid "Tags"
|
232 |
+
msgstr ""
|
233 |
+
|
234 |
+
#: inc/redux/WPML_Redux_Framework_config.php:221
|
235 |
+
msgid "This <a href=\"%1$s\">child theme</a> requires its parent theme, %2$s."
|
236 |
+
msgstr ""
|
237 |
+
|
238 |
+
#: inc/redux/WPML_Redux_Framework_config.php:221
|
239 |
+
msgid "http://codex.wordpress.org/Child_Themes"
|
240 |
+
msgstr ""
|
241 |
+
|
242 |
+
#: inc/redux/WPML_Redux_Framework_config.php:244
|
243 |
+
msgid "General Settings"
|
244 |
+
msgstr ""
|
245 |
+
|
246 |
+
#: inc/redux/WPML_Redux_Framework_config.php:253
|
247 |
+
msgid "Cleanup"
|
248 |
+
msgstr ""
|
249 |
+
|
250 |
+
#: inc/redux/WPML_Redux_Framework_config.php:254
|
251 |
+
msgid "Delete all data on deactivation? (emails and settings)?"
|
252 |
+
msgstr ""
|
253 |
+
|
254 |
+
#: inc/redux/WPML_Redux_Framework_config.php:264
|
255 |
+
msgid "Can See Submission data"
|
256 |
+
msgstr ""
|
257 |
+
|
258 |
+
#: inc/redux/WPML_Redux_Framework_config.php:265
|
259 |
+
msgid "Select the minimum role."
|
260 |
+
msgstr ""
|
261 |
+
|
262 |
+
#: inc/redux/WPML_Redux_Framework_config.php:270
|
263 |
+
msgid "WordPress Date Time Format"
|
264 |
+
msgstr ""
|
265 |
+
|
266 |
+
#: inc/redux/WPML_Redux_Framework_config.php:271
|
267 |
+
msgid "Use format from WordPress settings (%s)"
|
268 |
+
msgstr ""
|
269 |
+
|
270 |
+
#: inc/redux/WPML_Redux_Framework_config.php:273
|
271 |
+
#: inc/redux/WPML_Redux_Framework_config.php:298
|
272 |
+
#: inc/redux/WPML_Redux_Framework_config.php:314
|
273 |
+
#: inc/redux/WPML_Redux_Framework_config.php:336
|
274 |
+
msgid "Enabled"
|
275 |
+
msgstr ""
|
276 |
+
|
277 |
+
#: inc/redux/WPML_Redux_Framework_config.php:274
|
278 |
+
#: inc/redux/WPML_Redux_Framework_config.php:299
|
279 |
+
#: inc/redux/WPML_Redux_Framework_config.php:315
|
280 |
+
#: inc/redux/WPML_Redux_Framework_config.php:337
|
281 |
+
msgid "Disabled"
|
282 |
+
msgstr ""
|
283 |
+
|
284 |
+
#: inc/redux/WPML_Redux_Framework_config.php:285
|
285 |
+
msgid "Default Format for Message"
|
286 |
+
msgstr ""
|
287 |
+
|
288 |
+
#: inc/redux/WPML_Redux_Framework_config.php:286
|
289 |
+
msgid "Select your preferred display format."
|
290 |
+
msgstr ""
|
291 |
+
|
292 |
+
#: inc/redux/WPML_Redux_Framework_config.php:291
|
293 |
+
msgid "Display Host"
|
294 |
+
msgstr ""
|
295 |
+
|
296 |
+
#: inc/redux/WPML_Redux_Framework_config.php:292
|
297 |
+
msgid "Display host column in list."
|
298 |
+
msgstr ""
|
299 |
+
|
300 |
+
#: inc/redux/WPML_Redux_Framework_config.php:304
|
301 |
+
msgid "Log Rotation"
|
302 |
+
msgstr ""
|
303 |
+
|
304 |
+
#: inc/redux/WPML_Redux_Framework_config.php:305
|
305 |
+
msgid "Save space by deleting logs regularly."
|
306 |
+
msgstr ""
|
307 |
+
|
308 |
+
#: inc/redux/WPML_Redux_Framework_config.php:311
|
309 |
+
msgid "Cleanup by Amount"
|
310 |
+
msgstr ""
|
311 |
+
|
312 |
+
#: inc/redux/WPML_Redux_Framework_config.php:312
|
313 |
+
#: inc/redux/WPML_Redux_Framework_config.php:334
|
314 |
+
msgid "Setup a automated cleanup routine!"
|
315 |
+
msgstr ""
|
316 |
+
|
317 |
+
#: inc/redux/WPML_Redux_Framework_config.php:321
|
318 |
+
msgid "Amount"
|
319 |
+
msgstr ""
|
320 |
+
|
321 |
+
#: inc/redux/WPML_Redux_Framework_config.php:322
|
322 |
+
#: inc/redux/WPML_Redux_Framework_config.php:344
|
323 |
+
msgid "When should mails are deleted?"
|
324 |
+
msgstr ""
|
325 |
+
|
326 |
+
#: inc/redux/WPML_Redux_Framework_config.php:323
|
327 |
+
msgid "Cleanup when the stored mails exceed..."
|
328 |
+
msgstr ""
|
329 |
+
|
330 |
+
#: inc/redux/WPML_Redux_Framework_config.php:333
|
331 |
+
msgid "Cleanup by Time"
|
332 |
+
msgstr ""
|
333 |
+
|
334 |
+
#: inc/redux/WPML_Redux_Framework_config.php:345
|
335 |
+
msgid "Delete mails older than days..."
|
336 |
+
msgstr ""
|
337 |
+
|
338 |
+
#: inc/redux/WPML_Redux_Framework_config.php:510
|
339 |
+
msgid "Documentation"
|
340 |
+
msgstr ""
|
341 |
+
|
342 |
+
#: inc/redux/WPML_Redux_Framework_config.php:516
|
343 |
+
msgid "Support"
|
344 |
+
msgstr ""
|
345 |
+
|
346 |
+
#: inc/redux/WPML_Redux_Framework_config.php:522
|
347 |
+
msgid "Extensions"
|
348 |
+
msgstr ""
|
349 |
+
|
350 |
+
#: wp-mail-logging.php:48
|
351 |
+
msgid ""
|
352 |
+
"Error: plugin \"WP Mail Logging\" requires a newer version of PHP to be "
|
353 |
+
"running."
|
354 |
+
msgstr ""
|
355 |
+
|
356 |
+
#: wp-mail-logging.php:49
|
357 |
+
msgid "Minimal version of PHP required: "
|
358 |
+
msgstr ""
|
359 |
+
|
360 |
+
#: wp-mail-logging.php:50
|
361 |
+
msgid "Your server's PHP version: "
|
362 |
+
msgstr ""
|
363 |
+
|
364 |
+
#. Description of the plugin/theme
|
365 |
+
msgid "Logs each email sent by WordPress."
|
366 |
+
msgstr ""
|
367 |
+
|
368 |
+
#: inc/class-wp-list-table.php:573
|
369 |
+
msgctxt "paging"
|
370 |
+
msgid "%1$s of %2$s"
|
371 |
+
msgstr ""
|
model/WPML_Mail.php
CHANGED
@@ -10,7 +10,7 @@ if(!defined( 'ABSPATH' )) exit;
|
|
10 |
|
11 |
/**
|
12 |
* WPML Mail model.
|
13 |
-
* @
|
14 |
* @author No3x
|
15 |
*/
|
16 |
class WPML_Mail extends BaseModel
|
@@ -55,6 +55,11 @@ class WPML_Mail extends BaseModel
|
|
55 |
*/
|
56 |
protected $attachments;
|
57 |
|
|
|
|
|
|
|
|
|
|
|
58 |
/**
|
59 |
* @var string
|
60 |
*/
|
10 |
|
11 |
/**
|
12 |
* WPML Mail model.
|
13 |
+
* @since 1.6.0
|
14 |
* @author No3x
|
15 |
*/
|
16 |
class WPML_Mail extends BaseModel
|
55 |
*/
|
56 |
protected $attachments;
|
57 |
|
58 |
+
/**
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
protected $error;
|
62 |
+
|
63 |
/**
|
64 |
* @var string
|
65 |
*/
|
readme.txt
CHANGED
@@ -5,8 +5,8 @@ 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 |
-
Stable tag: 1.
|
10 |
|
11 |
Logs each email sent by WordPress.
|
12 |
|
@@ -17,6 +17,7 @@ Logs each email sent by WordPress. This can be useful if you don't want to lose
|
|
17 |
Features of the plugin include:
|
18 |
|
19 |
* Complete list of sent mails - view and search through the mails.
|
|
|
20 |
* Zero-configuration - just install and enjoy.
|
21 |
* Log rotation - decide which emails you want to keep.
|
22 |
* DevOP: IP of server sent the mail
|
@@ -33,11 +34,15 @@ Features of the plugin include:
|
|
33 |
|
34 |
== Installation ==
|
35 |
Just install and activate wp-mail-logging. The plugin will do the work for you! You can list all logged mails on the plugin site.
|
36 |
-
|
|
|
|
|
37 |
|
38 |
== Frequently Asked Questions ==
|
39 |
-
= How do I know the
|
40 |
-
|
|
|
|
|
41 |
|
42 |
== Screenshots ==
|
43 |
1. The List
|
@@ -45,13 +50,26 @@ The logged email has been sent by WordPress but please note this does NOT mean i
|
|
45 |
3. The Settings
|
46 |
|
47 |
== Upgrade Notice ==
|
48 |
-
= 1.
|
49 |
-
- New:
|
50 |
-
-
|
51 |
-
-
|
|
|
|
|
|
|
|
|
52 |
|
53 |
== Changelog ==
|
54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
= 1.7.0, November 6, 2016 =
|
56 |
- New: logging host IP
|
57 |
- Fix: passing search term for pagination
|
@@ -99,7 +117,7 @@ The logged email has been sent by WordPress but please note this does NOT mean i
|
|
99 |
|
100 |
= 1.3, August 24, 2014 =
|
101 |
- New: clean mail listing including:
|
102 |
-
Modal window for mail details.
|
103 |
Attachment support with appropriate icon for mime type.
|
104 |
- Tweak: Performance improvement
|
105 |
- Fix: screen option for mails per page
|
@@ -110,7 +128,7 @@ The logged email has been sent by WordPress but please note this does NOT mean i
|
|
110 |
- Fix: deletion of mails regardless of options (on update to 1.2 your mails will be deleted hopefully this happens for the last time)
|
111 |
|
112 |
= 1.1 =
|
113 |
-
- Tweak: Modified readme.
|
114 |
|
115 |
= 1.0 =
|
116 |
- Initial Revision
|
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.7.2
|
9 |
+
Stable tag: 1.8.0
|
10 |
|
11 |
Logs each email sent by WordPress.
|
12 |
|
17 |
Features of the plugin include:
|
18 |
|
19 |
* Complete list of sent mails - view and search through the mails.
|
20 |
+
* Error status from mail implementation is logged
|
21 |
* Zero-configuration - just install and enjoy.
|
22 |
* Log rotation - decide which emails you want to keep.
|
23 |
* DevOP: IP of server sent the mail
|
34 |
|
35 |
== Installation ==
|
36 |
Just install and activate wp-mail-logging. The plugin will do the work for you! You can list all logged mails on the plugin site.
|
37 |
+
I recommend the following plugins if you want to send mails via SMTP because they are technically well integrated into WordPress and provide error messages on failure.:
|
38 |
+
- [WP Mail SMTP](https://de.wordpress.org/plugins/wp-mail-smtp/)
|
39 |
+
- [SMTP Mailer](https://de.wordpress.org/plugins/smtp-mailer/)
|
40 |
|
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 wail 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 ==
|
48 |
1. The List
|
50 |
3. The Settings
|
51 |
|
52 |
== Upgrade Notice ==
|
53 |
+
= 1.8.0 =
|
54 |
+
- New: Error status from mail implementation is logged
|
55 |
+
- New: Resend mail
|
56 |
+
- New: Added translation files
|
57 |
+
- New: Added translation for de_DE and zh_CN
|
58 |
+
- Fix: raw mode of message renders attachments as text
|
59 |
+
- Fix: fallback to raw mode for json mode if mail is containing html
|
60 |
+
- Tweak: Pretty print json
|
61 |
|
62 |
== Changelog ==
|
63 |
|
64 |
+
= 1.8.0, February 15, 2017 =
|
65 |
+
- New: Error status from mail implementation is logged
|
66 |
+
- New: Resend mail
|
67 |
+
- New: Added translation files
|
68 |
+
- New: Added translation for de_DE and zh_CN
|
69 |
+
- Fix: raw mode of message renders attachments as text
|
70 |
+
- Fix: fallback to raw mode for json mode if mail is containing html
|
71 |
+
- Tweak: Pretty print json
|
72 |
+
|
73 |
= 1.7.0, November 6, 2016 =
|
74 |
- New: logging host IP
|
75 |
- Fix: passing search term for pagination
|
117 |
|
118 |
= 1.3, August 24, 2014 =
|
119 |
- New: clean mail listing including:
|
120 |
+
Modal window for mail details.
|
121 |
Attachment support with appropriate icon for mime type.
|
122 |
- Tweak: Performance improvement
|
123 |
- Fix: screen option for mails per page
|
128 |
- Fix: deletion of mails regardless of options (on update to 1.2 your mails will be deleted hopefully this happens for the last time)
|
129 |
|
130 |
= 1.1 =
|
131 |
+
- Tweak: Modified readme.
|
132 |
|
133 |
= 1.0 =
|
134 |
- Initial Revision
|
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.
|
7 |
Author: Christian Zöller
|
8 |
Author URI: http://no3x.de/
|
9 |
Description: Logs each email sent by WordPress.
|
@@ -33,12 +33,10 @@
|
|
33 |
|
34 |
namespace No3x\WPML;
|
35 |
|
36 |
-
use No3x\WPML\WPML_Init;
|
37 |
-
|
38 |
// Exit if accessed directly.
|
39 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
40 |
|
41 |
-
|
42 |
|
43 |
/**
|
44 |
* Check the PHP version and give a useful error message if the user's version is less than the required version
|
@@ -46,22 +44,20 @@ $WPML_minimalRequiredPhpVersion = '5.4';
|
|
46 |
* an error message on the Admin page
|
47 |
*/
|
48 |
function WPML_noticePhpVersionWrong() {
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
'</div>';
|
55 |
}
|
56 |
|
57 |
|
58 |
function WPML_PhpVersionCheck() {
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
return true;
|
65 |
}
|
66 |
|
67 |
|
@@ -73,8 +69,8 @@ function WPML_PhpVersionCheck() {
|
|
73 |
* @return void
|
74 |
*/
|
75 |
function WPML_i18n_init() {
|
76 |
-
|
77 |
-
|
78 |
}
|
79 |
|
80 |
|
@@ -89,24 +85,24 @@ WPML_i18n_init();
|
|
89 |
// Next, run the version check.
|
90 |
// If it is successful, continue with initialization for this plugin
|
91 |
if (WPML_PhpVersionCheck()) {
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
}
|
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.0
|
7 |
Author: Christian Zöller
|
8 |
Author URI: http://no3x.de/
|
9 |
Description: Logs each email sent by WordPress.
|
33 |
|
34 |
namespace No3x\WPML;
|
35 |
|
|
|
|
|
36 |
// Exit if accessed directly.
|
37 |
if ( ! defined( 'ABSPATH' ) ) exit;
|
38 |
|
39 |
+
define('WPML_PHP_MIN_VERSION', '5.4');
|
40 |
|
41 |
/**
|
42 |
* Check the PHP version and give a useful error message if the user's version is less than the required version
|
44 |
* an error message on the Admin page
|
45 |
*/
|
46 |
function WPML_noticePhpVersionWrong() {
|
47 |
+
echo '<div class="error">' .
|
48 |
+
__( 'Error: plugin "WP Mail Logging" requires a newer version of PHP to be running.', 'wp-mail-logging' ).
|
49 |
+
'<br/>' . __( 'Minimal version of PHP required: ', 'wp-mail-logging' ) . '<strong>' . WPML_PHP_MIN_VERSION . '</strong>' .
|
50 |
+
'<br/>' . __( 'Your server\'s PHP version: ', 'wp-mail-logging' ) . '<strong>' . phpversion() . '</strong>' .
|
51 |
+
'</div>';
|
|
|
52 |
}
|
53 |
|
54 |
|
55 |
function WPML_PhpVersionCheck() {
|
56 |
+
if ( version_compare( phpversion(), WPML_PHP_MIN_VERSION ) < 0 ) {
|
57 |
+
add_action( 'admin_notices', __NAMESPACE__ . '\WPML_noticePhpVersionWrong' );
|
58 |
+
return false;
|
59 |
+
}
|
60 |
+
return true;
|
|
|
61 |
}
|
62 |
|
63 |
|
69 |
* @return void
|
70 |
*/
|
71 |
function WPML_i18n_init() {
|
72 |
+
$pluginDir = dirname(plugin_basename(__FILE__));
|
73 |
+
load_plugin_textdomain('wp-mail-logging', false, $pluginDir . '/languages/');
|
74 |
}
|
75 |
|
76 |
|
85 |
// Next, run the version check.
|
86 |
// If it is successful, continue with initialization for this plugin
|
87 |
if (WPML_PhpVersionCheck()) {
|
88 |
+
// Only init and run the init function if we know PHP version can parse it
|
89 |
+
require __DIR__ . '/autoload.php';
|
90 |
+
|
91 |
+
// Create a new instance of the autoloader
|
92 |
+
$loader = new \WPML_Psr4AutoloaderClass();
|
93 |
+
|
94 |
+
// Register this instance
|
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\\Model\\', __DIR__ . '/model' );
|
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' ) ) {
|
105 |
+
require_once __DIR__ . '/vendor/autoload.php';
|
106 |
+
}
|
107 |
+
WPML_Init::getInstance()->init( __FILE__ );
|
108 |
}
|