Export WordPress data to XML/CSV - Version 0.9.0

Version Description

Download this release

Release Info

Developer soflyy
Plugin Icon 128x128 Export WordPress data to XML/CSV
Version 0.9.0
Comparing to
See all releases

Version 0.9.0

Files changed (104) hide show
  1. actions/admin_init.php +5 -0
  2. actions/admin_menu.php +20 -0
  3. actions/admin_notices.php +30 -0
  4. actions/plugins_loaded.php +9 -0
  5. actions/wp.php +7 -0
  6. actions/wp_ajax_export.php +403 -0
  7. actions/wp_loaded.php +6 -0
  8. actions/wp_session_garbage_collection.php +65 -0
  9. banner-772x250.png +0 -0
  10. classes/arrayaccess.php +141 -0
  11. classes/config.php +91 -0
  12. classes/download.php +39 -0
  13. classes/helper.php +139 -0
  14. classes/input.php +72 -0
  15. classes/session.php +371 -0
  16. config/options.php +11 -0
  17. controllers/admin/export.php +161 -0
  18. controllers/admin/help.php +12 -0
  19. controllers/admin/settings.php +30 -0
  20. controllers/controller.php +102 -0
  21. controllers/controller/admin.php +104 -0
  22. helpers/backward.php +40 -0
  23. helpers/pmxe_functions.php +80 -0
  24. helpers/str_getcsv.php +18 -0
  25. helpers/wp_redirect_or_javascript.php +17 -0
  26. models/export/list.php +8 -0
  27. models/export/record.php +36 -0
  28. models/model.php +198 -0
  29. models/model/list.php +149 -0
  30. models/model/record.php +176 -0
  31. plugin.php +498 -0
  32. readme.txt +41 -0
  33. schema.php +27 -0
  34. screenshot-1.png +0 -0
  35. screenshot-2.png +0 -0
  36. static/css/admin-ie.css +13 -0
  37. static/css/admin-wp-3.8.css +0 -0
  38. static/css/admin.css +1332 -0
  39. static/img/add-ons/acf-thumb.jpg +0 -0
  40. static/img/add-ons/woo-commerce-thumb.jpg +0 -0
  41. static/img/date-picker.gif +0 -0
  42. static/img/down.gif +0 -0
  43. static/img/drag.png +0 -0
  44. static/img/help.png +0 -0
  45. static/img/ico-add-new.png +0 -0
  46. static/img/ico-remove.png +0 -0
  47. static/img/loading.png +0 -0
  48. static/img/progress_animated.gif +0 -0
  49. static/img/screen-options-right-up.gif +0 -0
  50. static/img/screen-options-right.gif +0 -0
  51. static/img/stars.png +0 -0
  52. static/img/xmlicon.png +0 -0
  53. static/js/admin.js +143 -0
  54. static/js/jquery/css/redmond/images/animated-overlay.gif +0 -0
  55. static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  56. static/js/jquery/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100_1.png +0 -0
  57. static/js/jquery/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png +0 -0
  58. static/js/jquery/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  59. static/js/jquery/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
  60. static/js/jquery/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  61. static/js/jquery/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  62. static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
  63. static/js/jquery/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  64. static/js/jquery/css/redmond/images/ui-icons_217bc0_256x240.png +0 -0
  65. static/js/jquery/css/redmond/images/ui-icons_2e83ff_256x240.png +0 -0
  66. static/js/jquery/css/redmond/images/ui-icons_469bdd_256x240.png +0 -0
  67. static/js/jquery/css/redmond/images/ui-icons_6da8d5_256x240.png +0 -0
  68. static/js/jquery/css/redmond/images/ui-icons_cd0a0a_256x240.png +0 -0
  69. static/js/jquery/css/redmond/images/ui-icons_d8e7f3_256x240.png +0 -0
  70. static/js/jquery/css/redmond/images/ui-icons_f9bd01_256x240.png +0 -0
  71. static/js/jquery/css/redmond/jquery-ui.css +1177 -0
  72. static/js/jquery/css/select2/select2-bootstrap.css +87 -0
  73. static/js/jquery/css/select2/select2-spinner.gif +0 -0
  74. static/js/jquery/css/select2/select2.css +617 -0
  75. static/js/jquery/css/select2/select2.png +0 -0
  76. static/js/jquery/css/smoothness/images/tipsy.gif +0 -0
  77. static/js/jquery/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  78. static/js/jquery/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  79. static/js/jquery/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  80. static/js/jquery/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  81. static/js/jquery/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  82. static/js/jquery/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  83. static/js/jquery/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  84. static/js/jquery/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  85. static/js/jquery/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  86. static/js/jquery/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  87. static/js/jquery/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  88. static/js/jquery/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  89. static/js/jquery/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  90. static/js/jquery/css/smoothness/jquery-ui.css +405 -0
  91. static/js/jquery/css/smoothness/jquery.tipsy.css +11 -0
  92. static/js/jquery/jquery.mjs.nestedSortable.js +426 -0
  93. static/js/jquery/jquery.tipsy.js +198 -0
  94. static/js/jquery/moment.js +6 -0
  95. static/js/jquery/select2.min.js +22 -0
  96. static/js/jquery/ui.autocomplete.js +606 -0
  97. static/js/jquery/ui.datepicker.js +1636 -0
  98. static/js/pmxe.js +14 -0
  99. views/admin/export/element.php +183 -0
  100. views/admin/export/index.php +61 -0
  101. views/admin/export/process.php +58 -0
  102. views/admin/help/index.php +13 -0
  103. views/admin/settings/index.php +25 -0
  104. views/controller/error.php +3 -0
actions/admin_init.php ADDED
@@ -0,0 +1,5 @@
1
+ <?php
2
+
3
+ function pmxe_admin_init(){
4
+ wp_enqueue_script('pmxe-script', PMXE_ROOT_URL . '/static/js/pmxe.js', array('jquery'), PMXE_VERSION);
5
+ }
actions/admin_menu.php ADDED
@@ -0,0 +1,20 @@
1
+ <?php
2
+ /**
3
+ * Register plugin specific admin menu
4
+ */
5
+
6
+ function pmxe_admin_menu() {
7
+ global $menu, $submenu;
8
+
9
+ if (current_user_can('manage_options')) { // admin management options
10
+
11
+ add_menu_page(__('WP All Export', 'pmxe_plugin'), __('All Export', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-home', array(PMXE_Plugin::getInstance(), 'adminDispatcher'), PMXE_Plugin::ROOT_URL . '/static/img/xmlicon.png');
12
+ // workaround to rename 1st option to `Home`
13
+ $submenu['pmxe-admin-home'] = array();
14
+ add_submenu_page('pmxe-admin-home', __('Export to XML', 'pmxe_plugin') . ' &lsaquo; ' . __('WP All Export', 'pmxe_plugin'), __('New Export', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-export', array(PMXE_Plugin::getInstance(), 'adminDispatcher'));
15
+ add_submenu_page('pmxe-admin-home', __('Settings', 'pmxe_plugin') . ' &lsaquo; ' . __('WP All Export', 'pmxe_plugin'), __('Settings', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-settings', array(PMXE_Plugin::getInstance(), 'adminDispatcher'));
16
+ add_submenu_page('pmxe-admin-home', __('Support', 'pmxe_plugin') . ' &lsaquo; ' . __('WP All Export', 'pmxe_plugin'), __('Support', 'pmxe_plugin'), 'manage_options', 'pmxe-admin-help', array(PMXE_Plugin::getInstance(), 'adminDispatcher'));
17
+
18
+ }
19
+ }
20
+
actions/admin_notices.php ADDED
@@ -0,0 +1,30 @@
1
+ <?php
2
+
3
+ function pmxe_admin_notices() {
4
+
5
+ // notify user if history folder is not writable
6
+ $uploads = wp_upload_dir();
7
+
8
+ // notify user
9
+ if (!PMXE_Plugin::getInstance()->getOption('dismiss') and strpos($_SERVER['REQUEST_URI'], 'pmxe-admin') !== false) {
10
+ ?>
11
+ <div class="updated"><p>
12
+ <?php printf(
13
+ __('Welcome to WP All Export. We hope you like it. Please send all support requests and feedback to <a href="mailto:support@soflyy.com">support@soflyy.com</a>.<br/><br/><a href="javascript:void(0);" id="dismiss">dismiss</a>', 'pmxe_plugin')
14
+ ) ?>
15
+ </p></div>
16
+ <?php
17
+ }
18
+
19
+ $input = new PMXE_Input();
20
+ $messages = $input->get('pmxe_nt', array());
21
+ if ($messages) {
22
+ is_array($messages) or $messages = array($messages);
23
+ foreach ($messages as $type => $m) {
24
+ in_array((string)$type, array('updated', 'error')) or $type = 'updated';
25
+ ?>
26
+ <div class="<?php echo $type ?>"><p><?php echo $m ?></p></div>
27
+ <?php
28
+ }
29
+ }
30
+ }
actions/plugins_loaded.php ADDED
@@ -0,0 +1,9 @@
1
+ <?php
2
+
3
+ function pmxe_plugins_loaded() {
4
+
5
+ PMXE_Plugin::$session = PMXE_Session::get_instance();
6
+ do_action( 'pmxe_session_start' );
7
+
8
+ return PMXE_Plugin::$session->session_started();
9
+ }
actions/wp.php ADDED
@@ -0,0 +1,7 @@
1
+ <?php
2
+
3
+ function pmxe_wp() {
4
+ if ( ! wp_next_scheduled( 'wp_session_garbage_collection' ) ) {
5
+ wp_schedule_event( time(), 'twicedaily', 'wp_session_garbage_collection' );
6
+ }
7
+ }
actions/wp_ajax_export.php ADDED
@@ -0,0 +1,403 @@
1
+ <?php
2
+
3
+ function pmxe_wp_ajax_export(){
4
+
5
+ $wp_uploads = wp_upload_dir();
6
+
7
+ $default = PMXE_Plugin::get_default_import_options();
8
+ $exportOptions = (isset(PMXE_Plugin::$session->data['pmxe_export']) ? PMXE_Plugin::$session->data['pmxe_export'] : array()) + $default;
9
+
10
+ wp_reset_postdata();
11
+
12
+ $exportQuery = new WP_Query( array( 'post_type' => $exportOptions['cpt'], 'orderby' => 'title', 'order' => 'ASC', 'posts_per_page' => -1 ));
13
+
14
+ ob_start();
15
+
16
+ switch ($exportOptions['export_to']) {
17
+ case 'xml':
18
+ echo '<?xml version="1.0" encoding="UTF-8"?>';
19
+
20
+ ?>
21
+ <data>
22
+ <?php
23
+ // The Loop
24
+ while ( $exportQuery->have_posts() ) :
25
+
26
+ $exportQuery->the_post();
27
+
28
+ $record = get_post( get_the_ID() );
29
+
30
+ ?>
31
+ <post>
32
+ <post_type><?php echo get_post_type(); ?></post_type>
33
+ <?php if ($exportOptions['is_export_title']): ?><title><?php the_title(); ?></title><?php endif; ?>
34
+
35
+ <?php if ($exportOptions['is_export_content']): ?>
36
+ <content><?php echo '<![CDATA['; the_content(); echo ']]>'; ?></content>
37
+ <?php endif; ?>
38
+
39
+ <?php if ($exportOptions['is_export_custom_fields']): ?>
40
+ <custom_fields>
41
+ <?php foreach (get_post_custom($record->ID) as $cur_meta_key => $cur_meta_val): ?>
42
+ <?php if ( $exportOptions['export_custom_fields_logic'] == 'full_export' or ($exportOptions['export_custom_fields_logic'] == 'only' and in_array($cur_meta_key, $exportOptions['custom_fields_list']))): ?>
43
+ <<?php echo $cur_meta_key; ?>><?php echo '<![CDATA[' . ((!empty($cur_meta_val) and is_array($cur_meta_val) and count($cur_meta_val) == 1) ? $cur_meta_val[0] : serialize($cur_meta_val)) . ']]>'; ?></<?php echo $cur_meta_key;?>>
44
+ <?php endif; ?>
45
+ <?php endforeach; ?>
46
+ </custom_fields>
47
+ <?php endif; ?>
48
+
49
+ <?php if ($exportOptions['is_export_categories']): ?>
50
+ <taxonomies>
51
+ <?php
52
+
53
+ global $wp_taxonomies;
54
+
55
+ foreach ($wp_taxonomies as $key => $obj) {
56
+
57
+ if ($exportOptions['export_categories_logic'] == 'full_export' or ($exportOptions['export_categories_logic'] == 'only' and in_array($obj->name, $exportOptions['taxonomies_list'])))
58
+ {
59
+ $txes_list = get_the_terms($record->ID, $obj->name);
60
+
61
+ if ( ! is_wp_error($txes_list)) {
62
+ $txes_new = array();
63
+ if (!empty($txes_list)):
64
+ foreach ($txes_list as $t) {
65
+ $txes_new[] = $t->slug;
66
+ }
67
+ ?>
68
+ <<?php echo $obj->name; ?>><?php echo implode(', ', $txes_new); ?></<?php echo $obj->name; ?>>
69
+ <?php
70
+ endif;
71
+ }
72
+ }
73
+ }
74
+ ?>
75
+ </taxonomies>
76
+ <?php endif; ?>
77
+
78
+ <?php if ($exportOptions['is_export_images'] and ! empty($exportOptions['export_images_logic'])): ?>
79
+
80
+ <media_gallery>
81
+ <?php
82
+
83
+ $attachment_imgs = get_posts( array(
84
+ 'post_type' => 'attachment',
85
+ 'posts_per_page' => -1,
86
+ 'post_parent' => $record->ID,
87
+ ) );
88
+
89
+ if ( ! empty($attachment_imgs)):
90
+
91
+ foreach ($attachment_imgs as $attach) {
92
+ if ( wp_attachment_is_image( $attach->ID ) ){
93
+ ?>
94
+ <image>
95
+ <?php if (in_array('urls', $exportOptions['export_images_logic'])): ?><url><?php echo wp_get_attachment_url( $attach->ID ); ?></url><?php endif;?>
96
+
97
+ <?php if (in_array('meta_data', $exportOptions['export_images_logic'])): ?>
98
+ <title><?php echo esc_html($attach->post_title); ?></title>
99
+ <caption><?php echo esc_html($attach->post_excerpt); ?></caption>
100
+ <description><?php echo $attach->post_content;?></description>
101
+ <alt><?php echo get_post_meta($record->ID, '_wp_attachment_image_alt'); ?></alt>
102
+ <?php endif; ?>
103
+ </image>
104
+ <?php
105
+ }
106
+ }
107
+
108
+ endif;
109
+
110
+ ?>
111
+ </media_gallery>
112
+
113
+ <?php endif; ?>
114
+
115
+ <?php if ($exportOptions['is_export_other']): ?>
116
+
117
+ <other_stuff>
118
+
119
+ <?php if ($exportOptions['is_export_dates']): ?><date><?php echo get_post_time('U', true); ?></date><?php endif; ?>
120
+ <?php if ($exportOptions['is_export_parent']): ?><parent><?php echo $record->post_parent; ?></parent><?php endif; ?>
121
+ <?php if ($exportOptions['is_export_template']): ?><template><?php echo get_post_meta($record->ID, '_wp_page_template', true); ?></template><?php endif; ?>
122
+ <?php if ($exportOptions['is_export_menu_order']): ?><menu_order><?php echo $record->menu_order; ?></menu_order><?php endif; ?>
123
+ <?php if ($exportOptions['is_export_status']): ?><status><?php echo $record->post_status; ?></status><?php endif; ?>
124
+ <?php if ($exportOptions['is_export_format']): ?><format><?php echo get_post_format($record->ID); ?></format><?php endif; ?>
125
+ <?php if ($exportOptions['is_export_author']): ?><author><?php echo $record->post_author; ?></author><?php endif; ?>
126
+ <?php if ($exportOptions['is_export_slug']): ?><slug><?php echo $record->guid; ?></slug><?php endif; ?>
127
+ <?php if ($exportOptions['is_export_excerpt']): ?><excerpt><?php echo $record->post_excerpt; ?></excerpt><?php endif; ?>
128
+ <?php if ($exportOptions['is_export_attachments']): ?>
129
+ <attachments>
130
+ <?php
131
+
132
+ $attachment_imgs = get_posts( array(
133
+ 'post_type' => 'attachment',
134
+ 'posts_per_page' => -1,
135
+ 'post_parent' => $record->ID,
136
+ ) );
137
+
138
+ if ( ! empty($attachment_imgs)):
139
+
140
+ foreach ($attachment_imgs as $attach) {
141
+ if ( ! wp_attachment_is_image( $attach->ID ) ){
142
+ ?>
143
+ <attach>
144
+ <url><?php echo wp_get_attachment_url( $attach->ID ); ?></url>
145
+ </attach>
146
+ <?php
147
+ }
148
+ }
149
+
150
+ endif;
151
+
152
+ ?>
153
+ </attachments>
154
+ <?php endif; ?>
155
+
156
+ </other_stuff>
157
+
158
+ <?php endif; ?>
159
+
160
+ </post>
161
+
162
+ <?php
163
+ endwhile;
164
+ ?>
165
+
166
+ </data>
167
+ <?php
168
+
169
+ break;
170
+ case 'csv':
171
+
172
+ // Prepare headers
173
+
174
+ $headers = array();
175
+
176
+ $stream = fopen("php://output", 'w');
177
+
178
+ $max_attach_count = 0;
179
+ $max_images_count = 0;
180
+
181
+ $cf = array();
182
+ $taxes = array();
183
+
184
+ $articles = array();
185
+
186
+ while ( $exportQuery->have_posts() ) :
187
+
188
+ $attach_count = 0;
189
+ $images_count = 0;
190
+
191
+ $exportQuery->the_post();
192
+
193
+ $record = get_post( get_the_ID() );
194
+
195
+ $article = array();
196
+
197
+ $article['post_type'] = $record->post_type;
198
+
199
+ if ($exportOptions['is_export_title']) $article['title'] = get_the_title();
200
+ if ($exportOptions['is_export_content']) $article['content'] = get_the_content();
201
+
202
+ if ($exportOptions['is_export_other']):
203
+ if ($exportOptions['is_export_dates']) $article['date'] = get_post_time('U', true);
204
+ if ($exportOptions['is_export_parent']) $article['parent'] = $record->post_parent;
205
+ if ($exportOptions['is_export_template']) $article['template'] = get_post_meta($record->ID, '_wp_page_template', true);
206
+ if ($exportOptions['is_export_menu_order']) $article['menu_order'] = $record->menu_order;
207
+ if ($exportOptions['is_export_status']) $article['status'] = $record->post_status;
208
+ if ($exportOptions['is_export_format']) $article['format'] = get_post_format($record->ID);
209
+ if ($exportOptions['is_export_author']) $article['author'] = $record->post_author;
210
+ if ($exportOptions['is_export_slug']) $article['slug'] = $record->guid;
211
+ if ($exportOptions['is_export_excerpt']) $article['excerpt'] = $record->post_excerpt;
212
+ if ($exportOptions['is_export_attachments']):
213
+ $attachment_imgs = get_posts( array(
214
+ 'post_type' => 'attachment',
215
+ 'posts_per_page' => -1,
216
+ 'post_parent' => $record->ID,
217
+ ) );
218
+
219
+ if ( ! empty($attachment_imgs)):
220
+
221
+ foreach ($attachment_imgs as $key => $attach) {
222
+ if ( ! wp_attachment_is_image( $attach->ID ) ){
223
+ $article['attach_' . ($key + 1)] = wp_get_attachment_url( $attach->ID );
224
+ $attach_count++;
225
+ }
226
+ }
227
+
228
+ if ($attach_count > $max_attach_count) $max_attach_count = $attach_count;
229
+
230
+ endif;
231
+ endif;
232
+ endif;
233
+
234
+ if ($exportOptions['is_export_custom_fields']):
235
+
236
+ foreach (get_post_custom($record->ID) as $cur_meta_key => $cur_meta_val):
237
+ if ( $exportOptions['export_custom_fields_logic'] == 'full_export' or ($exportOptions['export_custom_fields_logic'] == 'only' and in_array($cur_meta_key, $exportOptions['custom_fields_list']))):
238
+ $article['CF_' . $cur_meta_key] = ((!empty($cur_meta_val) and is_array($cur_meta_val) and count($cur_meta_val) == 1) ? $cur_meta_val[0] : serialize($cur_meta_val));
239
+
240
+ if (!in_array('CF_' . $cur_meta_key, $cf)) $cf[] = 'CF_' . $cur_meta_key;
241
+
242
+ endif;
243
+ endforeach;
244
+
245
+ endif;
246
+
247
+ if ($exportOptions['is_export_categories']):
248
+
249
+ global $wp_taxonomies;
250
+
251
+ foreach ($wp_taxonomies as $key => $obj) {
252
+
253
+ if ($exportOptions['export_categories_logic'] == 'full_export' or ($exportOptions['export_categories_logic'] == 'only' and in_array($obj->name, $exportOptions['taxonomies_list'])))
254
+ {
255
+ $txes_list = get_the_terms($record->ID, $obj->name);
256
+
257
+ if ( ! is_wp_error($txes_list)) {
258
+ $txes_new = array();
259
+ if (!empty($txes_list)):
260
+ foreach ($txes_list as $t) {
261
+ $txes_new[] = $t->slug;
262
+ }
263
+ $article['TX_' . $obj->name] = implode('|', $txes_new);
264
+
265
+ if (!in_array('TX_' . $obj->name, $taxes)) $taxes[] = 'TX_' . $obj->name;
266
+
267
+ endif;
268
+ }
269
+ }
270
+ }
271
+
272
+ endif;
273
+
274
+ if ($exportOptions['is_export_images'] and ! empty($exportOptions['export_images_logic'])):
275
+
276
+ $attachment_imgs = get_posts( array(
277
+ 'post_type' => 'attachment',
278
+ 'posts_per_page' => -1,
279
+ 'post_parent' => $record->ID,
280
+ ) );
281
+
282
+ if ( ! empty($attachment_imgs)):
283
+
284
+ foreach ($attachment_imgs as $key => $attach) {
285
+ if ( wp_attachment_is_image( $attach->ID ) ){
286
+ if (in_array('urls', $exportOptions['export_images_logic'])) $article['image_url_' . ($key + 1)] = wp_get_attachment_url( $attach->ID );
287
+
288
+ if (in_array('meta_data', $exportOptions['export_images_logic'])):
289
+ $article['image_title_' . ($key + 1)] = $attach->post_title;
290
+ $article['image_caption_' . ($key + 1)] = $attach->post_excerpt;
291
+ $article['image_description_' . ($key + 1)] = $attach->post_content;
292
+ $article['image_alt_' . ($key + 1)] = get_post_meta($record->ID, '_wp_attachment_image_alt');
293
+ endif;
294
+
295
+ $images_count++;
296
+ }
297
+ }
298
+
299
+ if ($max_images_count > $images_count) $max_images_count = $images_count;
300
+
301
+ endif;
302
+
303
+ endif;
304
+
305
+ $articles[] = $article;
306
+
307
+ //fputcsv($stream, $article);
308
+
309
+ endwhile;
310
+
311
+ $headers[] = 'post_type';
312
+
313
+ if ($exportOptions['is_export_title']) $headers[] = 'title';
314
+ if ($exportOptions['is_export_content']) $headers[] = 'content';
315
+
316
+ if ($exportOptions['is_export_other']):
317
+ if ($exportOptions['is_export_dates']) $headers[] = 'date';
318
+ if ($exportOptions['is_export_parent']) $headers[] = 'parent';
319
+ if ($exportOptions['is_export_template']) $headers[] = 'template';
320
+ if ($exportOptions['is_export_menu_order']) $headers[] = 'menu_order';
321
+ if ($exportOptions['is_export_status']) $headers[] = 'status';
322
+ if ($exportOptions['is_export_format']) $headers[] = 'format';
323
+ if ($exportOptions['is_export_author']) $headers[] = 'author';
324
+ if ($exportOptions['is_export_slug']) $headers[] = 'slug';
325
+ if ($exportOptions['is_export_excerpt']) $headers[] = 'excerpt';
326
+
327
+ for ($i = 0; $i < $max_attach_count; $i++){
328
+ $headers[] = 'attach_' . ($i + 1);
329
+ }
330
+
331
+ endif;
332
+
333
+ if (!empty($cf)){
334
+ foreach ($cf as $cf_key) {
335
+ $headers[] = $cf_key;
336
+ }
337
+ }
338
+
339
+ if (!empty($taxes)){
340
+ foreach ($taxes as $tx) {
341
+ $headers[] = $tx;
342
+ }
343
+ }
344
+
345
+ for ($i = 0; $i < $max_images_count; $i++){
346
+
347
+ if (in_array('urls', $exportOptions['export_images_logic'])) $headers[] = 'image_url_' . ($i + 1);
348
+
349
+ if (in_array('meta_data', $exportOptions['export_images_logic'])):
350
+ $headers[] = 'image_title_' . ($i + 1);
351
+ $headers[] = 'image_caption_' . ($i + 1);
352
+ $headers[] = 'image_description_' . ($i + 1);
353
+ $headers[] = 'image_alt_' . ($i + 1);
354
+ endif;
355
+
356
+ }
357
+
358
+ fputcsv($stream, $headers);
359
+
360
+ foreach ($articles as $article) {
361
+ $line = array();
362
+ foreach ($headers as $header) {
363
+ $line[$header] = (!empty($article[$header])) ? $article[$header] : '';
364
+ }
365
+ fputcsv($stream, $line);
366
+ }
367
+
368
+ break;
369
+
370
+ default:
371
+ # code...
372
+ break;
373
+ }
374
+
375
+ wp_reset_postdata();
376
+
377
+ $export_file = $wp_uploads['path'] . '/' . time() . '.' . $exportOptions['export_to'];
378
+
379
+ if (@file_exists($export_file)) @unlink($export_file);
380
+
381
+ file_put_contents($export_file, ob_get_clean());
382
+
383
+ if ( file_exists($export_file)){
384
+ $wp_filetype = wp_check_filetype(basename($export_file), null );
385
+ $attachment_data = array(
386
+ 'guid' => $wp_uploads['baseurl'] . '/' . _wp_relative_upload_path( $export_file ),
387
+ 'post_mime_type' => $wp_filetype['type'],
388
+ 'post_title' => preg_replace('/\.[^.]+#x2F;', '', basename($export_file)),
389
+ 'post_content' => '',
390
+ 'post_status' => 'inherit'
391
+ );
392
+ $attach_id = wp_insert_attachment( $attachment_data, $export_file );
393
+ }
394
+
395
+ PMXE_Plugin::$session['pmxe_export']['export_file'] = $export_file;
396
+
397
+ pmxe_session_commit();
398
+
399
+ exit(json_encode(array('file' => $export_file))); die;
400
+
401
+ }
402
+
403
+ ?>
actions/wp_loaded.php ADDED
@@ -0,0 +1,6 @@
1
+ <?php
2
+
3
+ function pmxe_wp_loaded() {
4
+
5
+
6
+ }
actions/wp_session_garbage_collection.php ADDED
@@ -0,0 +1,65 @@
1
+ <?php
2
+
3
+ function pmxe_wp_session_garbage_collection() {
4
+ global $wpdb;
5
+
6
+ if ( defined( 'WP_SETUP_CONFIG' ) ) {
7
+ return;
8
+ }
9
+
10
+ $session_mode = PMXE_Plugin::getInstance()->getOption('session_mode');
11
+
12
+ if ( ! defined( 'WP_INSTALLING' ) ) {
13
+ if ($session_mode == 'database'){
14
+ $expiration_keys = $wpdb->get_results( "SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE '_pmxe_session_expires_%'" );
15
+
16
+ $now = time();
17
+ $expired_sessions = array();
18
+
19
+ foreach( $expiration_keys as $expiration ) {
20
+ // If the session has expired
21
+ if ( $now > intval( $expiration->option_value ) ) {
22
+ // Get the session ID by parsing the option_name
23
+ $session_id = str_replace("_PMXE_session_expires_", "", $expiration->option_name);
24
+
25
+ $expired_sessions[] = $expiration->option_name;
26
+ $expired_sessions[] = "_PMXE_session_$session_id";
27
+ }
28
+ }
29
+
30
+ // Delete all expired sessions in a single query
31
+ if ( ! empty( $expired_sessions ) ) {
32
+ $option_names = implode( "','", $expired_sessions );
33
+ $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name IN ('$option_names')" );
34
+ }
35
+ }
36
+ elseif ($session_mode == 'files'){
37
+ $session_files = scandir( PMXE_ROOT_DIR . '/sessions');
38
+
39
+ if (!empty($session_files)){
40
+ $now = time();
41
+ $expired_sessions = array();
42
+ foreach ($session_files as $key => $file) {
43
+ if ( strpos($file, "_pmxe_session_expires_") !== false){
44
+ $expiration_value = @file_get_contents( PMXE_ROOT_DIR . "/sessions/" . $file );
45
+
46
+ if ($now > intval($expiration_value)){
47
+ $session_id = str_replace("_pmxe_session_expires_", "", $file);
48
+ $expired_sessions[] = $file;
49
+ $expired_sessions[] = "_pmxe_session_$session_id";
50
+ }
51
+ }
52
+ }
53
+ // Delete all expired sessions in a single query
54
+ if ( ! empty( $expired_sessions ) ) {
55
+ foreach ($expired_sessions as $key => $file) {
56
+ @unlink( PMXE_ROOT_DIR . "/sessions/" . $file );
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ // Allow other plugins to hook in to the garbage collection process.
64
+ do_action( 'PMXE_session_cleanup' );
65
+ }
banner-772x250.png ADDED
Binary file
classes/arrayaccess.php ADDED
@@ -0,0 +1,141 @@
1
+ <?php
2
+ /**
3
+ * Multidimensional ArrayAccess
4
+ *
5
+ * Allows ArrayAccess-like functionality with multidimensional arrays. Fully supports
6
+ * both sets and unsets.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Session
10
+ * @since 3.7.0
11
+ */
12
+
13
+ /**
14
+ * Recursive array class to allow multidimensional array access.
15
+ *
16
+ * @package WordPress
17
+ * @since 3.7.0
18
+ */
19
+ class PMXE_ArrayAccess implements ArrayAccess {
20
+ /**
21
+ * Internal data collection.
22
+ *
23
+ * @var array
24
+ */
25
+ public $container = array();
26
+
27
+ /**
28
+ * Flag whether or not the internal collection has been changed.
29
+ *
30
+ * @var bool
31
+ */
32
+ protected $dirty = false;
33
+
34
+ /**
35
+ * Default object constructor.
36
+ *
37
+ * @param array $data
38
+ */
39
+ protected function __construct( $data = array() ) {
40
+ foreach ( $data as $key => $value ) {
41
+ $this[ $key ] = $value;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Allow deep copies of objects
47
+ */
48
+ public function __clone() {
49
+ foreach ( $this->container as $key => $value ) {
50
+ if ( $value instanceof self ) {
51
+ $this[ $key ] = clone $value;
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Output the data container as a multidimensional array.
58
+ *
59
+ * @return array
60
+ */
61
+ public function toArray() {
62
+ $data = $this->container;
63
+ if (!empty($data)){
64
+ foreach ( $data as $key => $value ) {
65
+ if ( $value instanceof self ) {
66
+ $data[ $key ] = $value->toArray();
67
+ }
68
+ }
69
+ }
70
+ return $data;
71
+ }
72
+
73
+ /*****************************************************************/
74
+ /* ArrayAccess Implementation */
75
+ /*****************************************************************/
76
+
77
+ /**
78
+ * Whether a offset exists
79
+ *
80
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
81
+ *
82
+ * @param mixed $offset An offset to check for.
83
+ *
84
+ * @return boolean true on success or false on failure.
85
+ */
86
+ public function offsetExists( $offset ) {
87
+ return isset( $this->container[ $offset ]) ;
88
+ }
89
+
90
+ /**
91
+ * Offset to retrieve
92
+ *
93
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
94
+ *
95
+ * @param mixed $offset The offset to retrieve.
96
+ *
97
+ * @return mixed Can return all value types.
98
+ */
99
+ public function offsetGet( $offset ) {
100
+ return isset( $this->container[ $offset ] ) ? $this->container[ $offset ] : null;
101
+ }
102
+
103
+ /**
104
+ * Offset to set
105
+ *
106
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
107
+ *
108
+ * @param mixed $offset The offset to assign the value to.
109
+ * @param mixed $value The value to set.
110
+ *
111
+ * @return void
112
+ */
113
+ public function offsetSet( $offset, $data ) {
114
+ if ( is_array( $data ) ) {
115
+ $data = new self( $data );
116
+ }
117
+ if ( $offset === null ) { // don't forget this!
118
+ $this->container[] = $data;
119
+ } else {
120
+ $this->container[ $offset ] = $data;
121
+ }
122
+
123
+ $this->dirty = true;
124
+ }
125
+
126
+ /**
127
+ * Offset to unset
128
+ *
129
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
130
+ *
131
+ * @param mixed $offset The offset to unset.
132
+ *
133
+ * @return void
134
+ */
135
+ public function offsetUnset( $offset ) {
136
+ unset( $this->container[ $offset ] );
137
+
138
+ $this->dirty = true;
139
+ }
140
+ }
141
+ ?>
classes/config.php ADDED
@@ -0,0 +1,91 @@
1
+ <?php
2
+ /**
3
+ * Class to load config files
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Config implements IteratorAggregate {
8
+ /**
9
+ * Config variables stored
10
+ * @var array
11
+ */
12
+ protected $config = array();
13
+ /**
14
+ * List of loaded files in order to avoid loading same file several times
15
+ * @var array
16
+ */
17
+ protected $loaded = array();
18
+
19
+ /**
20
+ * Static method to create config instance from file on disc
21
+ * @param string $filePath
22
+ * @param string[optional] $section
23
+ * @return PMXE_Config
24
+ */
25
+ public static function createFromFile($filePath, $section = NULL) {
26
+ $config = new self();
27
+ return $config->loadFromFile($filePath, $section);
28
+ }
29
+
30
+ /**
31
+ * Load config file
32
+ * @param string $filePath
33
+ * @param string[optional] $section
34
+ * @return PMXE_Config
35
+ */
36
+ public function loadFromFile($filePath, $section = NULL) {
37
+ if ( ! is_null($section)) {
38
+ $this->config[$section] = self::createFromFile($filePath);
39
+ } else {
40
+ $filePath = realpath($filePath);
41
+ if ($filePath and ! in_array($filePath, $this->loaded)) {
42
+ require $filePath;
43
+
44
+ $sandbox = create_function('', "require '$filePath'; if(array_keys(get_defined_vars()) != array('config')) return array(); return \$config;");
45
+ $config = $sandbox();
46
+ $this->loaded[] = $filePath;
47
+ $this->config = array_merge($this->config, $config);
48
+ }
49
+ }
50
+ return $this;
51
+ }
52
+ /**
53
+ * Return value of setting with specified name
54
+ * @param string $field Setting name
55
+ * @param string[optional] $section Section name to look setting in
56
+ * @return mixed
57
+ */
58
+ public function get($field, $section = NULL) {
59
+ return ! is_null($section) ? $this->config[$section]->get($field) : $this->config[$field];
60
+ }
61
+
62
+ /**
63
+ * Magic method for checking whether some config option are set
64
+ * @param string $field
65
+ * @return bool
66
+ */
67
+ public function __isset($field) {
68
+ return isset($this->config[$field]);
69
+ }
70
+ /**
71
+ * Magic method to implement object-like access to config parameters
72
+ * @param string $field
73
+ * @return mixed
74
+ */
75
+ public function __get($field) {
76
+ return $this->config[$field];
77
+ }
78
+
79
+ /**
80
+ * Return all config options as array
81
+ * @return array
82
+ */
83
+ public function toArray($section = NULL) {
84
+ return ! is_null($section) ? $this->config[$section]->toArray() : $this->config;
85
+ }
86
+
87
+ public function getIterator() {
88
+ return new ArrayIterator($this->config);
89
+ }
90
+
91
+ }
classes/download.php ADDED
@@ -0,0 +1,39 @@
1
+ <?php
2
+
3
+ class PMXE_Download
4
+ {
5
+
6
+ static public function zip($file_name)
7
+ {
8
+
9
+ header('Content-type: application/zip');
10
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
11
+ readfile($file_name);
12
+ die;
13
+ }
14
+
15
+ static public function xls($file_name)
16
+ {
17
+ header("Content-Type: application/vnd.ms-excel; charset=UTF-8");
18
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
19
+ readfile($file_name);
20
+ die;
21
+ }
22
+
23
+ static public function csv($file_name)
24
+ {
25
+ header("Content-Type: text/plain; charset=UTF-8");
26
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
27
+ readfile($file_name);
28
+ die;
29
+ }
30
+
31
+ static public function xml($file_name)
32
+ {
33
+ header("Content-Type: application/xhtml+xml; charset=UTF-8");
34
+ header("Content-Disposition: attachment; filename=\"".basename($file_name)."\"");
35
+ readfile($file_name);
36
+ die;
37
+ }
38
+
39
+ }
classes/helper.php ADDED
@@ -0,0 +1,139 @@
1
+ <?php
2
+ /**
3
+ * Helper class which defnes a namespace for some commonly used functions
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Helper {
8
+ const GLOB_MARK = 1;
9
+ const GLOB_NOSORT = 2;
10
+ const GLOB_ONLYDIR = 4;
11
+
12
+ const GLOB_NODIR = 256;
13
+ const GLOB_PATH = 512;
14
+ const GLOB_NODOTS = 1024;
15
+ const GLOB_RECURSE = 2048;
16
+
17
+ /**
18
+ * A safe empowered glob().
19
+ *
20
+ * Function glob() is prohibited on some server (probably in safe mode)
21
+ * (Message "Warning: glob() has been disabled for security reasons in
22
+ * (script) on line (line)") for security reasons as stated on:
23
+ * http://seclists.org/fulldisclosure/2005/Sep/0001.html
24
+ *
25
+ * safe_glob() intends to replace glob() using readdir() & fnmatch() instead.
26
+ * Supported flags: self::GLOB_MARK, self::GLOB_NOSORT, self::GLOB_ONLYDIR
27
+ * Additional flags: self::GLOB_NODIR, self::GLOB_PATH, self::GLOB_NODOTS, self::GLOB_RECURSE
28
+ * (not original glob() flags)
29
+ * @author BigueNique AT yahoo DOT ca
30
+ * @updates
31
+ * - 080324 Added support for additional flags: self::GLOB_NODIR, self::GLOB_PATH,
32
+ * self::GLOB_NODOTS, self::GLOB_RECURSE
33
+ * - 100607 Recurse is_dir check fixed by Pavel Kulbakin <p.kulbakin@gmail.com>
34
+ */
35
+ public static function safe_glob($pattern, $flags=0) {
36
+ $split = explode('/', str_replace('\\', '/', $pattern));
37
+ $mask = array_pop($split);
38
+ $path = implode('/', $split);
39
+
40
+ if (($dir = @opendir($path . '/')) !== false or ($dir = @opendir($path)) !== false) {
41
+ $glob = array();
42
+ while(($file = readdir($dir)) !== false) {
43
+ // Recurse subdirectories (self::GLOB_RECURSE)
44
+ if (($flags & self::GLOB_RECURSE) && is_dir($path . '/' . $file) && ( ! in_array($file, array('.', '..')))) {
45
+ $glob = array_merge($glob, self::array_prepend(self::safe_glob($path . '/' . $file . '/' . $mask, $flags), ($flags & self::GLOB_PATH ? '' : $file . '/')));
46
+ }
47
+ // Match file mask
48
+ if (self::fnmatch($mask, $file, FNM_CASEFOLD)) {
49
+ if ((( ! ($flags & self::GLOB_ONLYDIR)) || is_dir("$path/$file"))
50
+ && (( ! ($flags & self::GLOB_NODIR)) || ( ! is_dir($path . '/' . $file)))
51
+ && (( ! ($flags & self::GLOB_NODOTS)) || ( ! in_array($file, array('.', '..'))))
52
+ ) {
53
+ $glob[] = ($flags & self::GLOB_PATH ? $path . '/' : '') . $file . ($flags & self::GLOB_MARK ? '/' : '');
54
+ }
55
+ }
56
+ }
57
+ closedir($dir);
58
+ if ( ! ($flags & self::GLOB_NOSORT)) sort($glob);
59
+ return $glob;
60
+ } else {
61
+ return (strpos($pattern, "*") === false) ? array($pattern) : false;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Prepends $string to each element of $array
67
+ * If $deep is true, will indeed also apply to sub-arrays
68
+ * @author BigueNique AT yahoo DOT ca
69
+ * @since 080324
70
+ */
71
+ public static function array_prepend($array, $string, $deep=false) {
72
+ if(empty($array)||empty($string)) {
73
+ return $array;
74
+ }
75
+ foreach ($array as $key => $element) {
76
+ if (is_array($element)) {
77
+ if ($deep) {
78
+ $array[$key] = self::array_prepend($element,$string,$deep);
79
+ } else {
80
+ trigger_error(__METHOD__ . ': array element', E_USER_WARNING);
81
+ }
82
+ } else {
83
+ $array[$key] = $string.$element;
84
+ }
85
+ }
86
+ return $array;
87
+
88
+ }
89
+
90
+ const FNM_PATHNAME = 1;
91
+ const FNM_NOESCAPE = 2;
92
+ const FNM_PERIOD = 4;
93
+ const FNM_CASEFOLD = 16;
94
+
95
+ /**
96
+ * non-POSIX complient remplacement for the fnmatch
97
+ */
98
+ public static function fnmatch($pattern, $string, $flags = 0) {
99
+
100
+ $modifiers = null;
101
+ $transforms = array(
102
+ '\*' => '.*',
103
+ '\?' => '.',
104
+ '\[\!' => '[^',
105
+ '\[' => '[',
106
+ '\]' => ']',
107
+ '\.' => '\.',
108
+ '\\' => '\\\\',
109
+ '\-' => '-',
110
+ );
111
+
112
+ // Forward slash in string must be in pattern:
113
+ if ($flags & FNM_PATHNAME) {
114
+ $transforms['\*'] = '[^/]*';
115
+ }
116
+
117
+ // Back slash should not be escaped:
118
+ if ($flags & FNM_NOESCAPE) {
119
+ unset($transforms['\\']);
120
+ }
121
+
122
+ // Perform case insensitive match:
123
+ if ($flags & FNM_CASEFOLD) {
124
+ $modifiers .= 'i';
125
+ }
126
+
127
+ // Period at start must be the same as pattern:
128
+ if ($flags & FNM_PERIOD) {
129
+ if (strpos($string, '.') === 0 && strpos($pattern, '.') !== 0) return false;
130
+ }
131
+
132
+ $pattern = '#^'
133
+ .strtr(preg_quote($pattern, '#'), $transforms)
134
+ .'$#'
135
+ .$modifiers;
136
+
137
+ return (boolean)preg_match($pattern, $string);
138
+ }
139
+ }
classes/input.php ADDED
@@ -0,0 +1,72 @@
1
+ <?php
2
+ class PMXE_Input {
3
+ protected $filters = array('stripslashes');
4
+
5
+ public function read($inputArray, $paramName, $default = NULL) {
6
+ if (is_array($paramName) and ! is_null($default)) {
7
+ throw new Exception('Either array of parameter names with default values as the only argument or param name and default value as seperate arguments are expected.');
8
+ }
9
+ if (is_array($paramName)) {
10
+ foreach ($paramName as $param => $def) {
11
+ if (isset($inputArray[$param])) {
12
+ $paramName[$param] = $this->applyFilters($inputArray[$param]);
13
+ }
14
+ }
15
+ return $paramName;
16
+ } else {
17
+ return isset($inputArray[$paramName]) ? $this->applyFilters($inputArray[$paramName]) : $default;
18
+ }
19
+ }
20
+
21
+ public function get($paramName, $default = NULL) {
22
+ return $this->read($_GET, $paramName, $default);
23
+ }
24
+
25
+ public function post($paramName, $default = NULL) {
26
+ return $this->read($_POST, $paramName, $default);
27
+ }
28
+
29
+ public function cookie($paramName, $default = NULL) {
30
+ return $this->read($_COOKIE, $paramName, $default);
31
+ }
32
+
33
+ public function request($paramName, $default = NULL) {
34
+ return $this->read($_GET + $_POST + $_COOKIE, $paramName, $default);
35
+ }
36
+
37
+ public function getpost($paramName, $default = NULL) {
38
+ return $this->read($_GET + $_POST, $paramName, $default);
39
+ }
40
+
41
+ public function server($paramName, $default = NULL) {
42
+ return $this->read($_SERVER, $paramName, $default);
43
+ }
44
+
45
+ public function addFilter($callback) {
46
+ if ( ! is_callable($callback)) {
47
+ throw new Exception(get_class($this) . '::' . __METHOD__ . ' parameter must be a proper callback function reference.');
48
+ }
49
+ if ( ! in_array($callback, $this->filters)) {
50
+ $this->filters[] = $callback;
51
+ }
52
+ return $this;
53
+ }
54
+
55
+ public function removeFilter($callback) {
56
+ $this->filters = array_diff($this->filters, array($callback));
57
+ return $this;
58
+ }
59
+
60
+ protected function applyFilters($val) {
61
+ if (is_array($val)) {
62
+ foreach ($val as $k => $v) {
63
+ $val[$k] = $this->applyFilters($v);
64
+ }
65
+ } else {
66
+ foreach ($this->filters as $filter) {
67
+ $val = call_user_func($filter, $val);
68
+ }
69
+ }
70
+ return $val;
71
+ }
72
+ }
classes/session.php ADDED
@@ -0,0 +1,371 @@
1
+ <?php
2
+ /**
3
+ * WordPress session managment.
4
+ *
5
+ * Standardizes WordPress session data using database-backed options for storage.
6
+ * for storing user session information.
7
+ *
8
+ * @package WordPress
9
+ * @subpackage Session
10
+ * @since 3.7.0
11
+ */
12
+
13
+ /**
14
+ * WordPress Session class for managing user session data.
15
+ *
16
+ * @package WordPress
17
+ * @since 3.7.0
18
+ */
19
+ final class PMXE_Session extends PMXE_ArrayAccess implements Iterator, Countable {
20
+ /**
21
+ * ID of the current session.
22
+ *
23
+ * @var string
24
+ */
25
+ protected $session_id;
26
+
27
+ /**
28
+ * Unix timestamp when session expires.
29
+ *
30
+ * @var int
31
+ */
32
+ protected $expires;
33
+
34
+ /**
35
+ * Unix timestamp indicating when the expiration time needs to be reset.
36
+ *
37
+ * @var int
38
+ */
39
+ protected $exp_variant;
40
+
41
+ /**
42
+ * Singleton instance.
43
+ *
44
+ * @var bool|WP_Session
45
+ */
46
+ private static $instance = false;
47
+
48
+ public $data = array();
49
+
50
+ public $session_mode = '';
51
+ /**
52
+ * Retrieve the current session instance.
53
+ *
54
+ * @param bool $session_id Session ID from which to populate data.
55
+ *
56
+ * @return bool|WP_Session
57
+ */
58
+ public static function get_instance() {
59
+ if ( ! self::$instance ) {
60
+ self::$instance = new self();
61
+ }
62
+
63
+ return self::$instance;
64
+ }
65
+
66
+ /**
67
+ * Default constructor.
68
+ * Will rebuild the session collection from the given session ID if it exists. Otherwise, will
69
+ * create a new session with that ID.
70
+ *
71
+ * @param $session_id
72
+ * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
73
+ */
74
+ protected function __construct() {
75
+
76
+ $this->session_mode = PMXE_Plugin::getInstance()->getOption('session_mode');
77
+
78
+ if ($this->session_mode != 'default'){
79
+
80
+ if ( isset( $_COOKIE[PMXE_SESSION_COOKIE] ) ) {
81
+
82
+ $cookie = stripslashes( $_COOKIE[PMXE_SESSION_COOKIE] );
83
+ $cookie_crumbs = explode( '||', $cookie );
84
+
85
+ $this->session_id = (!empty($cookie_crumbs[0])) ? $cookie_crumbs[0] : $this->generate_id();
86
+ $this->expires = $cookie_crumbs[1];
87
+ $this->exp_variant = $cookie_crumbs[2];
88
+
89
+ // Update the session expiration if we're past the variant time
90
+ if ( time() > $this->exp_variant ) {
91
+ $this->set_expiration();
92
+ if ($this->session_mode == 'database'){
93
+ update_option( "_pmxi_session_expires_{$this->session_id}", $this->expires );
94
+ }
95
+ elseif ($this->session_mode == 'files'){
96
+ @file_put_contents(PMXE_ROOT_DIR . "/sessions/_pmxe_session_expires_{$this->session_id}.txt", $this->expires);
97
+ }
98
+ }
99
+
100
+ } else {
101
+ $this->session_id = $this->generate_id();
102
+ $this->set_expiration();
103
+ }
104
+ }
105
+ else{
106
+ try{
107
+ $path = @session_save_path();
108
+ if ( ! @is_dir($path) or ! @is_writable($path)){
109
+ @ini_set("session.save_handler", "files");
110
+ @session_save_path(sys_get_temp_dir());
111
+ }
112
+ } catch (XmlImportException $e) {
113
+
114
+ }
115
+
116
+ // enable sessions
117
+ if ( ! session_id()) @session_start();
118
+ }
119
+
120
+ $this->read_data();
121
+
122
+ $this->set_cookie();
123
+ }
124
+
125
+ /**
126
+ * Set both the expiration time and the expiration variant.
127
+ *
128
+ * If the current time is below the variant, we don't update the session's expiration time. If it's
129
+ * greater than the variant, then we update the expiration time in the database. This prevents
130
+ * writing to the database on every page load for active sessions and only updates the expiration
131
+ * time if we're nearing when the session actually expires.
132
+ *
133
+ * By default, the expiration time is set to 30 minutes.
134
+ * By default, the expiration variant is set to 24 minutes.
135
+ *
136
+ * As a result, the session expiration time - at a maximum - will only be written to the database once
137
+ * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by
138
+ * the browser, and the old session will be queued for deletion by the garbage collector.
139
+ *
140
+ * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data.
141
+ * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions.
142
+ */
143
+ protected function set_expiration() {
144
+ $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 );
145
+ $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 );
146
+ }
147
+
148
+ /**
149
+ * Set the session cookie
150
+ */
151
+ protected function set_cookie() {
152
+ @setcookie( PMXE_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN );
153
+ }
154
+
155
+ /**
156
+ * Generate a cryptographically strong unique ID for the session token.
157
+ *
158
+ * @return string
159
+ */
160
+ protected function generate_id() {
161
+ require_once( ABSPATH . 'wp-includes/class-phpass.php');
162
+ $hasher = new PasswordHash( 8, false );
163
+
164
+ return md5( $hasher->get_random_bytes( 32 ) );
165
+ }
166
+
167
+ /**
168
+ * Read data from a transient for the current session.
169
+ *
170
+ * Automatically resets the expiration time for the session transient to some time in the future.
171
+ *
172
+ * @return array
173
+ */
174
+ protected function read_data() {
175
+ if ($this->session_mode == 'database'){
176
+ $this->container = get_option( "_pmxe_session_{$this->session_id}", array() );
177
+ }
178
+ elseif ($this->session_mode == 'files'){
179
+ $container = @file_get_contents(PMXE_ROOT_DIR . "/sessions/_pmxe_session_{$this->session_id}.txt");
180
+ $this->container = unserialize( (!empty($container)) ? $container : '' );
181
+ }
182
+ else{
183
+ $this['pmxe_export'] = ( ! empty($_SESSION['pmxe_export']) ) ? $_SESSION['pmxe_export'] : array();
184
+ }
185
+
186
+ $this->data = $this->toArray();
187
+
188
+ return $this->container;
189
+ }
190
+
191
+ /**
192
+ * Write the data from the current session to the data storage system.
193
+ */
194
+ public function write_data() {
195
+
196
+ $option_key = "_pmxe_session_{$this->session_id}";
197
+
198
+ $this->data = $this->toArray();
199
+
200
+ // Only write the collection to the DB if it's changed.
201
+ if ($this->session_mode == "database"){
202
+ if ( false === get_option( $option_key ) ) {
203
+ add_option( "_pmxe_session_{$this->session_id}", $this->container, '', 'no' );
204
+ add_option( "_pmxe_session_expires_{$this->session_id}", $this->expires, '', 'no' );
205
+ } else {
206
+ delete_option("_pmxe_session_{$this->session_id}");
207
+ add_option( "_pmxe_session_{$this->session_id}", $this->container, '', 'no' );
208
+ }
209
+ }
210
+ elseif ($this->session_mode == 'files'){
211
+ if ( @file_exists( PMXE_ROOT_DIR . "/sessions/" . $option_key . ".txt") ){
212
+ @file_put_contents( PMXE_ROOT_DIR . "/sessions/" . $option_key . ".txt", (string) serialize($this->container) );
213
+ }
214
+ else{
215
+ @file_put_contents( PMXE_ROOT_DIR . "/sessions/" . $option_key . ".txt", (string) serialize($this->container) );
216
+ @file_put_contents( PMXE_ROOT_DIR . "/sessions/_pmxe_session_expires_{$this->session_id}.txt", $this->expires );
217
+ }
218
+ }
219
+ else{
220
+ $session = $this->toArray(); $_SESSION['pmxe_export'] = (!empty($session['pmxe_export'])) ? $session['pmxe_export'] : array();
221
+ }
222
+
223
+ }
224
+
225
+ /**
226
+ * Output the current container contents as a JSON-encoded string.
227
+ *
228
+ * @return string
229
+ */
230
+ public function json_out() {
231
+ return json_encode( $this->container );
232
+ }
233
+
234
+ /**
235
+ * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents.
236
+ *
237
+ * @param string $data
238
+ *
239
+ * @return bool
240
+ */
241
+ public function json_in( $data ) {
242
+ $array = json_decode( $data );
243
+
244
+ if ( is_array( $array ) ) {
245
+ $this->container = $array;
246
+ return true;
247
+ }
248
+
249
+ return false;
250
+ }
251
+
252
+ /**
253
+ * Regenerate the current session's ID.
254
+ *
255
+ * @param bool $delete_old Flag whether or not to delete the old session data from the server.
256
+ */
257
+ public function regenerate_id( $delete_old = false ) {
258
+ if ( $delete_old ) {
259
+ if ($this->session_mode == "database"){
260
+ delete_option( "_pmxe_session_{$this->session_id}" );
261
+ }
262
+ elseif ($this->session_mode == 'files'){
263
+ @unlink( PMXE_ROOT_DIR . "/sessions/_pmxe_session_{$this->session_id}.txt");
264
+ }
265
+ }
266
+
267
+ $this->session_id = $this->generate_id();
268
+
269
+ $this->set_cookie();
270
+ }
271
+
272
+ /**
273
+ * Check if a session has been initialized.
274
+ *
275
+ * @return bool
276
+ */
277
+ public function session_started() {
278
+ return !!self::$instance;
279
+ }
280
+
281
+ /**
282
+ * Return the read-only cache expiration value.
283
+ *
284
+ * @return int
285
+ */
286
+ public function cache_expiration() {
287
+ return $this->expires;
288
+ }
289
+
290
+ /**
291
+ * Flushes all session variables.
292
+ */
293
+ public function reset() {
294
+ $this->container = array();
295
+ if ($this->session_mode == "default") unset($_SESSION['pmxe_export']);
296
+ }
297
+
298
+ /*****************************************************************/
299
+ /* Iterator Implementation */
300
+ /*****************************************************************/
301
+
302
+ /**
303
+ * Current position of the array.
304
+ *
305
+ * @link http://php.net/manual/en/iterator.current.php
306
+ *
307
+ * @return mixed
308
+ */
309
+ public function current() {
310
+ return current( $this->container );
311
+ }
312
+
313
+ /**
314
+ * Key of the current element.
315
+ *
316
+ * @link http://php.net/manual/en/iterator.key.php
317
+ *
318
+ * @return mixed
319
+ */
320
+ public function key() {
321
+ return key( $this->container );
322
+ }
323
+
324
+ /**
325
+ * Move the internal point of the container array to the next item
326
+ *
327
+ * @link http://php.net/manual/en/iterator.next.php
328
+ *
329
+ * @return void
330
+ */
331
+ public function next() {
332
+ next( $this->container );
333
+ }
334
+
335
+ /**
336
+ * Rewind the internal point of the container array.
337
+ *
338
+ * @link http://php.net/manual/en/iterator.rewind.php
339
+ *
340
+ * @return void
341
+ */
342
+ public function rewind() {
343
+ reset( $this->container );
344
+ }
345
+
346
+ /**
347
+ * Is the current key valid?
348
+ *
349
+ * @link http://php.net/manual/en/iterator.rewind.php
350
+ *
351
+ * @return bool
352
+ */
353
+ public function valid() {
354
+ return $this->offsetExists( $this->key() );
355
+ }
356
+
357
+ /*****************************************************************/
358
+ /* Countable Implementation */
359
+ /*****************************************************************/
360
+
361
+ /**
362
+ * Get the count of elements in the container array.
363
+ *
364
+ * @link http://php.net/manual/en/countable.count.php
365
+ *
366
+ * @return int
367
+ */
368
+ public function count() {
369
+ return count( $this->container );
370
+ }
371
+ }
config/options.php ADDED
@@ -0,0 +1,11 @@
1
+ <?php
2
+ /**
3
+ * List of plugin optins, contains only default values, actual values are stored in database
4
+ * and can be changed by corresponding wordpress function calls
5
+ */
6
+ $config = array(
7
+ "dismiss" => 0,
8
+ "dismiss_manage_top" => 0,
9
+ "dismiss_manage_bottom" => 0,
10
+ "session_mode" => 'default',
11
+ );
controllers/admin/export.php ADDED
@@ -0,0 +1,161 @@
1
+ <?php
2
+ /**
3
+ * Import configuration wizard
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+
8
+ class PMXE_Admin_Export extends PMXE_Controller_Admin {
9
+ protected $isWizard = true; // indicates whether controller is in wizard mode (otherwize it called to be deligated an edit action)
10
+
11
+ protected function init() {
12
+
13
+ parent::init();
14
+
15
+ $action = PMXE_Plugin::getInstance()->getAdminCurrentScreen()->action;
16
+ $this->_step_ready($action);
17
+
18
+ }
19
+
20
+ public function set($var, $val)
21
+ {
22
+ $this->{$var} = $val;
23
+ }
24
+ public function get($var)
25
+ {
26
+ return $this->{$var};
27
+ }
28
+
29
+ /**
30
+ * Checks whether corresponding step of wizard is complete
31
+ * @param string $action
32
+ */
33
+ protected function _step_ready($action) {
34
+
35
+ // step #1: xml selction - has no prerequisites
36
+ if ('index' == $action) return true;
37
+
38
+ if ('element' == $action) return true;
39
+
40
+ if (empty(PMXE_Plugin::$session->data['pmxe_export'])){
41
+ wp_redirect_or_javascript($this->baseUrl); die();
42
+ }
43
+
44
+ if ('process' == $action) return true;
45
+
46
+ }
47
+
48
+ /**
49
+ * Step #1: Choose CPT
50
+ */
51
+ public function index() {
52
+
53
+ $wp_uploads = wp_upload_dir();
54
+
55
+ $this->data['post'] = $post = $this->input->post(array(
56
+ 'cpt' => array(),
57
+ 'export_to' => 'xml'
58
+ ));
59
+
60
+ // Delete history
61
+ foreach (PMXE_Helper::safe_glob(PMXE_ROOT_DIR . '/history/*', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
62
+ @file_exists($filePath) and @unlink($filePath);
63
+ }
64
+
65
+ if ($this->input->post('is_submitted')){
66
+
67
+ pmxe_session_unset();
68
+
69
+ PMXE_Plugin::$session['pmxe_export'] = array(
70
+ 'cpt' => ( ! is_array($post['cpt']) ) ? array($post['cpt']) : $post['cpt']
71
+ );
72
+
73
+ }
74
+
75
+ if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
76
+
77
+ check_admin_referer('choose-cpt', '_wpnonce_choose-cpt');
78
+
79
+ pmxe_session_commit();
80
+
81
+ wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
82
+ }
83
+
84
+ $this->render();
85
+ }
86
+
87
+ /**
88
+ * Step #2: Choose data to export
89
+ */
90
+ public function element()
91
+ {
92
+
93
+ $default = PMXE_Plugin::get_default_import_options();
94
+ $DefaultOptions = (isset(PMXE_Plugin::$session->data['pmxe_export']) ? PMXE_Plugin::$session->data['pmxe_export'] : array()) + $default;
95
+ $post = $this->input->post($DefaultOptions);
96
+
97
+ $this->data['post'] =& $post;
98
+
99
+ $this->data['meta_keys'] = $keys = new PMXE_Model_List();
100
+ $keys->setTable(PMXE_Plugin::getInstance()->getWPPrefix() . 'postmeta');
101
+ $keys->setColumns('meta_id', 'meta_key')->getBy(NULL, "meta_id", NULL, NULL, "meta_key");
102
+
103
+ if ($this->input->post('is_submitted')) {
104
+
105
+ check_admin_referer('element', '_wpnonce_element');
106
+
107
+ if ( ! $this->errors->get_error_codes()) {
108
+
109
+ PMXE_Plugin::$session['pmxe_export']['export_to'] = preg_match('%\W(xml)$%i', trim($post['export_to'])) ? 'xml' : 'csv';
110
+
111
+ pmxe_session_commit();
112
+
113
+ wp_redirect(add_query_arg('action', 'process', $this->baseUrl)); die();
114
+
115
+ }
116
+
117
+ }
118
+
119
+ $this->render();
120
+
121
+ }
122
+
123
+ /**
124
+ * Step #3: Export
125
+ */
126
+ public function process()
127
+ {
128
+
129
+ @set_time_limit(0);
130
+ $this->render();
131
+
132
+ }
133
+
134
+ /**
135
+ * Step #4: Download
136
+ */
137
+ public function download(){
138
+
139
+ $attch_url = PMXE_Plugin::$session->data['pmxe_export']['export_file'];
140
+
141
+ $export_type = PMXE_Plugin::$session->data['pmxe_export']['export_to'];
142
+
143
+ // clear import session
144
+ pmxe_session_unset(); // clear session data (prevent from reimporting the same data on page refresh)
145
+
146
+ switch ($export_type) {
147
+ case 'xml':
148
+ PMXE_download::xml($attch_url);
149
+ break;
150
+ case 'csv':
151
+ PMXE_download::csv($attch_url);
152
+ break;
153
+
154
+ default:
155
+ # code...
156
+ break;
157
+ }
158
+
159
+ }
160
+
161
+ }
controllers/admin/help.php ADDED
@@ -0,0 +1,12 @@
1
+ <?php
2
+ /**
3
+ * Admin Help page
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Admin_Help extends PMXE_Controller_Admin {
8
+
9
+ public function index() {
10
+ $this->render();
11
+ }
12
+ }
controllers/admin/settings.php ADDED
@@ -0,0 +1,30 @@
1
+ <?php
2
+ /**
3
+ * Admin Statistics page
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ class PMXE_Admin_Settings extends PMXE_Controller_Admin {
8
+
9
+ public function index() {
10
+
11
+ $this->data['post'] = $post = $this->input->post(PMXI_Plugin::getInstance()->getOption());
12
+
13
+ $this->render();
14
+
15
+ }
16
+
17
+ public function dismiss(){
18
+
19
+ PMXE_Plugin::getInstance()->updateOption("dismiss", 1);
20
+
21
+ exit('OK');
22
+ }
23
+
24
+ public function download(){
25
+
26
+ PMXE_download::csv(PMXE_Plugin::ROOT_DIR.'/logs/'.$_GET['file'].'.txt');
27
+
28
+ }
29
+
30
+ }
controllers/controller.php ADDED
@@ -0,0 +1,102 @@
1
+ <?php
2
+ /**
3
+ * Common logic for all shortcodes plugin implements
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ abstract class PMXE_Controller {
8
+ /**
9
+ * Input class instance to retrieve parameters submitted during page request
10
+ * @var PMXE_Input
11
+ */
12
+ protected $input;
13
+ /**
14
+ * Error messages
15
+ * @var WP_Error
16
+ */
17
+ protected $errors;
18
+ /**
19
+ * Associative array of data which will be automatically available as variables when template is rendered
20
+ * @var array
21
+ */
22
+ public $data = array();
23
+ /**
24
+ * Constructor
25
+ */
26
+ public function __construct() {
27
+ $this->input = new PMXE_Input();
28
+ $this->input->addFilter('trim');
29
+
30
+ $this->errors = new WP_Error();
31
+
32
+ $this->init();
33
+ }
34
+
35
+ /**
36
+ * Method to put controller initialization logic to
37
+ */
38
+ protected function init() {}
39
+
40
+ /**
41
+ * Checks wether protocol is HTTPS and redirects user to secure connection if not
42
+ */
43
+ protected function force_ssl() {
44
+ if (force_ssl_admin() && ! is_ssl()) {
45
+ if ( 0 === strpos($_SERVER['REQUEST_URI'], 'http') ) {
46
+ wp_redirect(preg_replace('|^http://|', 'https://', $_SERVER['REQUEST_URI'])); die();
47
+ } else {
48
+ wp_redirect('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']); die();
49
+ }
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Method returning resolved template content
55
+ *
56
+ * @param string[optional] $viewPath Template path to render
57
+ */
58
+ protected function render($viewPath = null) {
59
+ // assume template file name depending on calling function
60
+ if (is_null($viewPath)) {
61
+ $trace = debug_backtrace();
62
+ $viewPath = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXE_Plugin::PREFIX, '%') . '%', '', strtolower($trace[1]['class']))) . '/' . $trace[1]['function'];
63
+ }
64
+ // append file extension if not specified
65
+ if ( ! preg_match('%\.php$%', $viewPath)) {
66
+ $viewPath .= '.php';
67
+ }
68
+ $filePath = PMXE_Plugin::ROOT_DIR . '/views/' . $viewPath;
69
+ if (is_file($filePath)) {
70
+ extract($this->data);
71
+ include $filePath;
72
+ } else {
73
+ throw new Exception("Requested template file $filePath is not found.");
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Display list of errors
79
+ *
80
+ * @param string|array|WP_Error[optional] $msgs
81
+ */
82
+ protected function error($msgs = NULL) {
83
+ if (is_null($msgs)) {
84
+ $msgs = $this->errors;
85
+ }
86
+ if (is_wp_error($msgs)) {
87
+ $msgs = $msgs->get_error_messages();
88
+ }
89
+ if ( ! is_array($msgs)) {
90
+ $msgs = array($msgs);
91
+ }
92
+ $this->data['errors'] = $msgs;
93
+
94
+ $viewPathRel = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXE_Plugin::PREFIX, '%') . '%', '', strtolower(get_class($this)))) . '/error.php';
95
+ if (is_file(PMXE_Plugin::ROOT_DIR . '/views/' . $viewPathRel)) { // if calling controller class has specific error view
96
+ $this->render($viewPathRel);
97
+ } else { // render default error view
98
+ $this->render('controller/error.php');
99
+ }
100
+ }
101
+
102
+ }
controllers/controller/admin.php ADDED
@@ -0,0 +1,104 @@
1
+ <?php
2
+ /**
3
+ * Introduce special type for controllers which render pages inside admin area
4
+ *
5
+ * @author Pavel Kulbakin <p.kulbakin@gmail.com>
6
+ */
7
+ abstract class PMXE_Controller_Admin extends PMXE_Controller {
8
+ /**
9
+ * Admin page base url (request url without all get parameters but `page`)
10
+ * @var string
11
+ */
12
+ public $baseUrl;
13
+ /**
14
+ * Parameters which is left when baseUrl is detected
15
+ * @var array
16
+ */
17
+ public $baseUrlParamNames = array('page', 'pagenum', 'order', 'order_by', 'type', 's', 'f');
18
+ /**
19
+ * Whether controller is rendered inside wordpress page
20
+ * @var bool
21
+ */
22
+ public $isInline = false;
23
+ /**
24
+ * Constructor
25
+ */
26
+ public function __construct() {
27
+
28
+ $remove = array_diff(array_keys($_GET), $this->baseUrlParamNames);
29
+ if ($remove) {
30
+ $this->baseUrl = remove_query_arg($remove);
31
+ } else {
32
+ $this->baseUrl = $_SERVER['REQUEST_URI'];
33
+ }
34
+ parent::__construct();
35
+
36
+ // add special filter for url fields
37
+ $this->input->addFilter(create_function('$str', 'return "http://" == $str || "ftp://" == $str ? "" : $str;'));
38
+
39
+ // enqueue required sripts and styles
40
+ global $wp_styles;
41
+ if ( ! is_a($wp_styles, 'WP_Styles'))
42
+ $wp_styles = new WP_Styles();
43
+
44
+ wp_enqueue_style('jquery-ui', PMXE_ROOT_URL . '/static/js/jquery/css/redmond/jquery-ui.css');
45
+ wp_enqueue_style('jquery-tipsy', PMXE_ROOT_URL . '/static/js/jquery/css/smoothness/jquery.tipsy.css');
46
+ wp_enqueue_style('pmxe-admin-style', PMXE_ROOT_URL . '/static/css/admin.css');
47
+ wp_enqueue_style('pmxe-admin-style-ie', PMXE_ROOT_URL . '/static/css/admin-ie.css');
48
+ wp_enqueue_style('jquery-select2', PMXE_ROOT_URL . '/static/js/jquery/css/select2/select2.css');
49
+ wp_enqueue_style('jquery-select2', PMXE_ROOT_URL . '/static/js/jquery/css/select2/select2-bootstrap.css');
50
+ $wp_styles->add_data('pmxe-admin-style-ie', 'conditional', 'lte IE 7');
51
+ wp_enqueue_style('wp-pointer');
52
+
53
+ if ( version_compare(get_bloginfo('version'), '3.8-RC1') >= 0 ){
54
+ wp_enqueue_style('pmxe-admin-style-wp-3.8', PMXE_ROOT_URL . '/static/css/admin-wp-3.8.css');
55
+ }
56
+
57
+ $scheme_color = get_user_option('admin_color') and is_file(PMXE_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css') or $scheme_color = 'fresh';
58
+ if (is_file(PMXE_Plugin::ROOT_DIR . '/static/css/admin-colors-' . $scheme_color . '.css')) {
59
+ wp_enqueue_style('pmxe-admin-style-color', PMXE_ROOT_URL . '/static/css/admin-colors-' . $scheme_color . '.css');
60
+ }
61
+
62
+ wp_enqueue_script('jquery-ui-datepicker', PMXE_ROOT_URL . '/static/js/jquery/ui.datepicker.js', 'jquery-ui-core');
63
+ wp_enqueue_script('jquery-ui-autocomplete', PMXE_ROOT_URL . '/static/js/jquery/ui.autocomplete.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'));
64
+ wp_enqueue_script('jquery-tipsy', PMXE_ROOT_URL . '/static/js/jquery/jquery.tipsy.js', 'jquery');
65
+ wp_enqueue_script('jquery-nestable', PMXE_ROOT_URL . '/static/js/jquery/jquery.mjs.nestedSortable.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-tabs', 'jquery-ui-progressbar'));
66
+ wp_enqueue_script('jquery-moment', PMXE_ROOT_URL . '/static/js/jquery/moment.js', 'jquery');
67
+ wp_enqueue_script('jquery-select2', PMXE_ROOT_URL . '/static/js/jquery/select2.min.js', 'jquery');
68
+ wp_enqueue_script('wp-pointer');
69
+
70
+ /* load plupload scripts */
71
+ wp_enqueue_script('pmxe-admin-script', PMXE_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
72
+
73
+ }
74
+
75
+ /**
76
+ * @see Controller::render()
77
+ */
78
+ protected function render($viewPath = NULL)
79
+ {
80
+ // assume template file name depending on calling function
81
+ if (is_null($viewPath)) {
82
+ $trace = debug_backtrace();
83
+ $viewPath = str_replace('_', '/', preg_replace('%^' . preg_quote(PMXE_Plugin::PREFIX, '%') . '%', '', strtolower($trace[1]['class']))) . '/' . $trace[1]['function'];
84
+ }
85
+
86
+ // render contextual help automatically
87
+ $viewHelpPath = $viewPath;
88
+ // append file extension if not specified
89
+ if ( ! preg_match('%\.php$%', $viewHelpPath)) {
90
+ $viewHelpPath .= '.php';
91
+ }
92
+ $viewHelpPath = preg_replace('%\.php$%', '-help.php', $viewHelpPath);
93
+ $fileHelpPath = PMXE_Plugin::ROOT_DIR . '/views/' . $viewHelpPath;
94
+
95
+ if (is_file($fileHelpPath)) { // there is help file defined
96
+ ob_start();
97
+ include $fileHelpPath;
98
+ add_contextual_help(PMXE_Plugin::getInstance()->getAdminCurrentScreen()->id, ob_get_clean());
99
+ }
100
+
101
+ parent::render($viewPath);
102
+ }
103
+
104
+ }
helpers/backward.php ADDED
@@ -0,0 +1,40 @@