Version Description
- Free edition of 3.0 pro release with added support for the WooCommerce add-on
Download this release
Release Info
Developer | soflyy |
Plugin | Import any XML or CSV File to WordPress |
Version | 3.0.2 |
Comparing to | |
See all releases |
Code changes from version 3.0.1 to 3.0.2
- actions/admin_menu.php +21 -21
- actions/admin_notices.php +40 -40
- actions/wp_loaded.php +6 -6
- classes/chunk.php +436 -423
- classes/download.php +38 -38
- config/options.php +23 -22
- controllers/admin/import.php +1682 -1593
- controllers/admin/manage.php +417 -416
- controllers/admin/settings.php +207 -207
- helpers/get_file_curl.php +101 -89
- helpers/import_custom_meta_box.php +28 -28
- helpers/pmxi_functions.php +384 -237
- libraries/XmlImportConfig.php +87 -87
- libraries/XmlImportCsvParse.php +1258 -1254
- libraries/XmlImportException.php +9 -9
- libraries/XmlImportParser.php +115 -115
- libraries/XmlImportReaderInterface.php +21 -21
- libraries/XmlImportStringReader.php +66 -66
- libraries/XmlImportTemplate.php +77 -77
- libraries/XmlImportTemplateCodeGenerator.php +382 -382
- libraries/XmlImportTemplateParser.php +398 -398
- libraries/XmlImportTemplateScanner.php +403 -403
- libraries/XmlImportToken.php +171 -171
- models/import/record.php +1293 -922
- models/model/record.php +175 -175
- plugin.php +624 -606
- readme.txt +17 -6
- schema.php +11 -9
- static/css/admin.css +996 -982
- static/js/admin.js +561 -550
- static/js/pmxi.js +32 -32
- views/admin/import/element_after.php +60 -60
- views/admin/import/index.php +128 -128
- views/admin/import/options.php +194 -197
- views/admin/import/options/_author_template.php +19 -19
- views/admin/import/options/_buttons_template.php +65 -60
- views/admin/import/options/_categories_template.php +66 -66
- views/admin/import/options/_custom_fields_template.php +53 -53
- views/admin/import/options/_featured_template.php +37 -36
- views/admin/import/options/_main_options_template.php +55 -55
- views/admin/import/options/_reimport_template.php +131 -131
- views/admin/import/options/_scheduling_template.php +38 -38
- views/admin/import/options/_taxonomies_template.php +70 -70
- views/admin/import/process.php +111 -111
- views/admin/import/tag.php +20 -20
- views/admin/import/template.php +97 -97
- views/admin/manage/index.php +248 -248
- views/admin/settings/index.php +71 -66
actions/admin_menu.php
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Register plugin specific admin menu
|
4 |
-
*/
|
5 |
-
|
6 |
-
function pmxi_admin_menu() {
|
7 |
-
global $menu, $submenu;
|
8 |
-
|
9 |
-
if (current_user_can('manage_options')) { // admin management options
|
10 |
-
|
11 |
-
add_menu_page(__('WP All Import', 'pmxi_plugin'), __('All Import', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-home', array(PMXI_Plugin::getInstance(), 'adminDispatcher'), PMXI_Plugin::ROOT_URL . '/static/img/xmlicon.png');
|
12 |
-
// workaround to rename 1st option to `Home`
|
13 |
-
$submenu['pmxi-admin-home'] = array();
|
14 |
-
add_submenu_page('pmxi-admin-home', __('Import XML', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('New Import', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-import', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
15 |
-
add_submenu_page('pmxi-admin-home', __('Manage Previous Imports', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Manage Imports', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-manage', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
16 |
-
add_submenu_page('pmxi-admin-home', __('Settings', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Settings', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-settings', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
17 |
-
add_submenu_page('pmxi-admin-home', __('Support', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Support', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-help', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
18 |
-
|
19 |
-
}
|
20 |
-
}
|
21 |
-
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Register plugin specific admin menu
|
4 |
+
*/
|
5 |
+
|
6 |
+
function pmxi_admin_menu() {
|
7 |
+
global $menu, $submenu;
|
8 |
+
|
9 |
+
if (current_user_can('manage_options')) { // admin management options
|
10 |
+
|
11 |
+
add_menu_page(__('WP All Import', 'pmxi_plugin'), __('All Import', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-home', array(PMXI_Plugin::getInstance(), 'adminDispatcher'), PMXI_Plugin::ROOT_URL . '/static/img/xmlicon.png');
|
12 |
+
// workaround to rename 1st option to `Home`
|
13 |
+
$submenu['pmxi-admin-home'] = array();
|
14 |
+
add_submenu_page('pmxi-admin-home', __('Import XML', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('New Import', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-import', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
15 |
+
add_submenu_page('pmxi-admin-home', __('Manage Previous Imports', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Manage Imports', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-manage', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
16 |
+
add_submenu_page('pmxi-admin-home', __('Settings', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Settings', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-settings', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
17 |
+
add_submenu_page('pmxi-admin-home', __('Support', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Support', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-help', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
18 |
+
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
actions/admin_notices.php
CHANGED
@@ -1,41 +1,41 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
function pmxi_admin_notices() {
|
4 |
-
// notify user if history folder is not writable
|
5 |
-
$uploads = wp_upload_dir();
|
6 |
-
|
7 |
-
if ( ! @is_dir($uploads['basedir'] . '/wpallimport_history') or ! @is_writable($uploads['basedir'] . '/wpallimport_history')) {
|
8 |
-
?>
|
9 |
-
<div class="error"><p>
|
10 |
-
<?php printf(
|
11 |
-
__('<b>%s Plugin</b>: History folder %s must be writable for the plugin to function properly. Please deactivate the plugin, set proper permissions to the folder and activate the plugin again.', 'pmxi_plugin'),
|
12 |
-
PMXI_Plugin::getInstance()->getName(),
|
13 |
-
$uploads['basedir'] . '/wpallimport_history'
|
14 |
-
) ?>
|
15 |
-
</p></div>
|
16 |
-
<?php
|
17 |
-
}
|
18 |
-
|
19 |
-
// notify user
|
20 |
-
if (!PMXI_Plugin::getInstance()->getOption('dismiss') and strpos($_SERVER['REQUEST_URI'], '
|
21 |
-
?>
|
22 |
-
<div class="updated"><p>
|
23 |
-
<?php printf(
|
24 |
-
__('Welcome to WP All Import. 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>', 'pmxi_plugin')
|
25 |
-
) ?>
|
26 |
-
</p></div>
|
27 |
-
<?php
|
28 |
-
}
|
29 |
-
|
30 |
-
$input = new PMXI_Input();
|
31 |
-
$messages = $input->get('pmxi_nt', array());
|
32 |
-
if ($messages) {
|
33 |
-
is_array($messages) or $messages = array($messages);
|
34 |
-
foreach ($messages as $type => $m) {
|
35 |
-
in_array((string)$type, array('updated', 'error')) or $type = 'updated';
|
36 |
-
?>
|
37 |
-
<div class="<?php echo $type ?>"><p><?php echo $m ?></p></div>
|
38 |
-
<?php
|
39 |
-
}
|
40 |
-
}
|
41 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
function pmxi_admin_notices() {
|
4 |
+
// notify user if history folder is not writable
|
5 |
+
$uploads = wp_upload_dir();
|
6 |
+
|
7 |
+
if ( ! @is_dir($uploads['basedir'] . '/wpallimport_history') or ! @is_writable($uploads['basedir'] . '/wpallimport_history')) {
|
8 |
+
?>
|
9 |
+
<div class="error"><p>
|
10 |
+
<?php printf(
|
11 |
+
__('<b>%s Plugin</b>: History folder %s must be writable for the plugin to function properly. Please deactivate the plugin, set proper permissions to the folder and activate the plugin again.', 'pmxi_plugin'),
|
12 |
+
PMXI_Plugin::getInstance()->getName(),
|
13 |
+
$uploads['basedir'] . '/wpallimport_history'
|
14 |
+
) ?>
|
15 |
+
</p></div>
|
16 |
+
<?php
|
17 |
+
}
|
18 |
+
|
19 |
+
// notify user
|
20 |
+
if (!PMXI_Plugin::getInstance()->getOption('dismiss') and strpos($_SERVER['REQUEST_URI'], 'pmxi-admin') !== false) {
|
21 |
+
?>
|
22 |
+
<div class="updated"><p>
|
23 |
+
<?php printf(
|
24 |
+
__('Welcome to WP All Import. 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>', 'pmxi_plugin')
|
25 |
+
) ?>
|
26 |
+
</p></div>
|
27 |
+
<?php
|
28 |
+
}
|
29 |
+
|
30 |
+
$input = new PMXI_Input();
|
31 |
+
$messages = $input->get('pmxi_nt', array());
|
32 |
+
if ($messages) {
|
33 |
+
is_array($messages) or $messages = array($messages);
|
34 |
+
foreach ($messages as $type => $m) {
|
35 |
+
in_array((string)$type, array('updated', 'error')) or $type = 'updated';
|
36 |
+
?>
|
37 |
+
<div class="<?php echo $type ?>"><p><?php echo $m ?></p></div>
|
38 |
+
<?php
|
39 |
+
}
|
40 |
+
}
|
41 |
}
|
actions/wp_loaded.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
function pmxi_wp_loaded() {
|
4 |
-
|
5 |
-
wp_enqueue_script('pmxi-script', PMXI_ROOT_URL . '/static/js/pmxi.js', array('jquery'));
|
6 |
-
|
7 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
function pmxi_wp_loaded() {
|
4 |
+
|
5 |
+
wp_enqueue_script('pmxi-script', PMXI_ROOT_URL . '/static/js/pmxi.js', array('jquery'));
|
6 |
+
|
7 |
}
|
classes/chunk.php
CHANGED
@@ -1,423 +1,436 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Chunk
|
4 |
-
*
|
5 |
-
* Reads a large file in as chunks for easier parsing.
|
6 |
-
*
|
7 |
-
* The chunks returned are whole <$this->options['element']/>s found within file.
|
8 |
-
*
|
9 |
-
* Each call to read() returns the whole element including start and end tags.
|
10 |
-
*
|
11 |
-
* Tested with a 1.8MB file, extracted 500 elements in 0.11s
|
12 |
-
* (with no work done, just extracting the elements)
|
13 |
-
*
|
14 |
-
* Usage:
|
15 |
-
* <code>
|
16 |
-
* // initialize the object
|
17 |
-
* $file = new Chunk('chunk-test.xml', array('element' => 'Chunk'));
|
18 |
-
*
|
19 |
-
* // loop through the file until all lines are read
|
20 |
-
* while ($xml = $file->read()) {
|
21 |
-
* // do whatever you want with the string
|
22 |
-
* $o = simplexml_load_string($xml);
|
23 |
-
* }
|
24 |
-
* </code>
|
25 |
-
*
|
26 |
-
* @package default
|
27 |
-
* @author Dom Hastings
|
28 |
-
*/
|
29 |
-
class PMXI_Chunk {
|
30 |
-
/**
|
31 |
-
* options
|
32 |
-
*
|
33 |
-
* @var array Contains all major options
|
34 |
-
* @access public
|
35 |
-
*/
|
36 |
-
public $options = array(
|
37 |
-
'path' => './', // string The path to check for $file in
|
38 |
-
'element' => '', // string The XML element to return
|
39 |
-
'chunkSize' => 1024, // integer The amount of bytes to retrieve in each chunk
|
40 |
-
'type' => 'upload'
|
41 |
-
);
|
42 |
-
|
43 |
-
/**
|
44 |
-
* file
|
45 |
-
*
|
46 |
-
* @var string The filename being read
|
47 |
-
* @access public
|
48 |
-
*/
|
49 |
-
public $file = '';
|
50 |
-
/**
|
51 |
-
* pointer
|
52 |
-
*
|
53 |
-
* @var integer The current position the file is being read from
|
54 |
-
* @access public
|
55 |
-
*/
|
56 |
-
public $pointer = 0;
|
57 |
-
|
58 |
-
public $cloud = array();
|
59 |
-
|
60 |
-
public $is_validate = true;
|
61 |
-
|
62 |
-
public $open_counter = 0;
|
63 |
-
|
64 |
-
public $encoding = "";
|
65 |
-
|
66 |
-
public $return_with_encoding = true;
|
67 |
-
|
68 |
-
/**
|
69 |
-
* handle
|
70 |
-
*
|
71 |
-
* @var resource The fopen() resource
|
72 |
-
* @access private
|
73 |
-
*/
|
74 |
-
private $handle = null;
|
75 |
-
/**
|
76 |
-
* reading
|
77 |
-
*
|
78 |
-
* @var boolean Whether the script is currently reading the file
|
79 |
-
* @access private
|
80 |
-
*/
|
81 |
-
private $reading = false;
|
82 |
-
/**
|
83 |
-
* readBuffer
|
84 |
-
*
|
85 |
-
* @var string Used to make sure start tags aren't missed
|
86 |
-
* @access private
|
87 |
-
*/
|
88 |
-
private $readBuffer = '';
|
89 |
-
|
90 |
-
/**
|
91 |
-
* __construct
|
92 |
-
*
|
93 |
-
* Builds the Chunk object
|
94 |
-
*
|
95 |
-
* @param string $file The filename to work with
|
96 |
-
* @param array $options The options with which to parse the file
|
97 |
-
* @author Dom Hastings
|
98 |
-
* @access public
|
99 |
-
*/
|
100 |
-
public function __construct($file, $options = array(), $pointer = 0, $return_with_encoding = true) {
|
101 |
-
// merge the options together
|
102 |
-
$this->options = array_merge($this->options, (is_array($options) ? $options : array()));
|
103 |
-
$this->return_with_encoding = $return_with_encoding;
|
104 |
-
// check that the path ends with a /
|
105 |
-
if (substr($this->options['path'], -1) != '/') {
|
106 |
-
$this->options['path'] .= '/';
|
107 |
-
}
|
108 |
-
|
109 |
-
// normalize the filename
|
110 |
-
$file_base = basename($file);
|
111 |
-
|
112 |
-
// make sure chunkSize is an int
|
113 |
-
$this->options['chunkSize'] = intval($this->options['chunkSize']);
|
114 |
-
|
115 |
-
// check it's valid
|
116 |
-
if ($this->options['chunkSize'] < 64) {
|
117 |
-
$this->options['chunkSize'] = 1024;
|
118 |
-
}
|
119 |
-
|
120 |
-
$this->options['chunkSize'] *= PMXI_Plugin::getInstance()->getOption('chunk_size');
|
121 |
-
|
122 |
-
$this->pointer = $pointer;
|
123 |
-
|
124 |
-
// set the filename
|
125 |
-
$this->file = $file;
|
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 |
-
// add the length of the close string itself
|
365 |
-
if ( ! $withoutcloseelement)
|
366 |
-
$checkClose += strlen($close);
|
367 |
-
else
|
368 |
-
$checkClose += strlen(
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
if
|
373 |
-
|
374 |
-
if
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Chunk
|
4 |
+
*
|
5 |
+
* Reads a large file in as chunks for easier parsing.
|
6 |
+
*
|
7 |
+
* The chunks returned are whole <$this->options['element']/>s found within file.
|
8 |
+
*
|
9 |
+
* Each call to read() returns the whole element including start and end tags.
|
10 |
+
*
|
11 |
+
* Tested with a 1.8MB file, extracted 500 elements in 0.11s
|
12 |
+
* (with no work done, just extracting the elements)
|
13 |
+
*
|
14 |
+
* Usage:
|
15 |
+
* <code>
|
16 |
+
* // initialize the object
|
17 |
+
* $file = new Chunk('chunk-test.xml', array('element' => 'Chunk'));
|
18 |
+
*
|
19 |
+
* // loop through the file until all lines are read
|
20 |
+
* while ($xml = $file->read()) {
|
21 |
+
* // do whatever you want with the string
|
22 |
+
* $o = simplexml_load_string($xml);
|
23 |
+
* }
|
24 |
+
* </code>
|
25 |
+
*
|
26 |
+
* @package default
|
27 |
+
* @author Dom Hastings
|
28 |
+
*/
|
29 |
+
class PMXI_Chunk {
|
30 |
+
/**
|
31 |
+
* options
|
32 |
+
*
|
33 |
+
* @var array Contains all major options
|
34 |
+
* @access public
|
35 |
+
*/
|
36 |
+
public $options = array(
|
37 |
+
'path' => './', // string The path to check for $file in
|
38 |
+
'element' => '', // string The XML element to return
|
39 |
+
'chunkSize' => 1024, // integer The amount of bytes to retrieve in each chunk
|
40 |
+
'type' => 'upload'
|
41 |
+
);
|
42 |
+
|
43 |
+
/**
|
44 |
+
* file
|
45 |
+
*
|
46 |
+
* @var string The filename being read
|
47 |
+
* @access public
|
48 |
+
*/
|
49 |
+
public $file = '';
|
50 |
+
/**
|
51 |
+
* pointer
|
52 |
+
*
|
53 |
+
* @var integer The current position the file is being read from
|
54 |
+
* @access public
|
55 |
+
*/
|
56 |
+
public $pointer = 0;
|
57 |
+
|
58 |
+
public $cloud = array();
|
59 |
+
|
60 |
+
public $is_validate = true;
|
61 |
+
|
62 |
+
public $open_counter = 0;
|
63 |
+
|
64 |
+
public $encoding = "";
|
65 |
+
|
66 |
+
public $return_with_encoding = true;
|
67 |
+
|
68 |
+
/**
|
69 |
+
* handle
|
70 |
+
*
|
71 |
+
* @var resource The fopen() resource
|
72 |
+
* @access private
|
73 |
+
*/
|
74 |
+
private $handle = null;
|
75 |
+
/**
|
76 |
+
* reading
|
77 |
+
*
|
78 |
+
* @var boolean Whether the script is currently reading the file
|
79 |
+
* @access private
|
80 |
+
*/
|
81 |
+
private $reading = false;
|
82 |
+
/**
|
83 |
+
* readBuffer
|
84 |
+
*
|
85 |
+
* @var string Used to make sure start tags aren't missed
|
86 |
+
* @access private
|
87 |
+
*/
|
88 |
+
private $readBuffer = '';
|
89 |
+
|
90 |
+
/**
|
91 |
+
* __construct
|
92 |
+
*
|
93 |
+
* Builds the Chunk object
|
94 |
+
*
|
95 |
+
* @param string $file The filename to work with
|
96 |
+
* @param array $options The options with which to parse the file
|
97 |
+
* @author Dom Hastings
|
98 |
+
* @access public
|
99 |
+
*/
|
100 |
+
public function __construct($file, $options = array(), $pointer = 0, $return_with_encoding = true) {
|
101 |
+
// merge the options together
|
102 |
+
$this->options = array_merge($this->options, (is_array($options) ? $options : array()));
|
103 |
+
$this->return_with_encoding = $return_with_encoding;
|
104 |
+
// check that the path ends with a /
|
105 |
+
if (substr($this->options['path'], -1) != '/') {
|
106 |
+
$this->options['path'] .= '/';
|
107 |
+
}
|
108 |
+
|
109 |
+
// normalize the filename
|
110 |
+
$file_base = basename($file);
|
111 |
+
|
112 |
+
// make sure chunkSize is an int
|
113 |
+
$this->options['chunkSize'] = intval($this->options['chunkSize']);
|
114 |
+
|
115 |
+
// check it's valid
|
116 |
+
if ($this->options['chunkSize'] < 64) {
|
117 |
+
$this->options['chunkSize'] = 1024;
|
118 |
+
}
|
119 |
+
|
120 |
+
$this->options['chunkSize'] *= PMXI_Plugin::getInstance()->getOption('chunk_size');
|
121 |
+
|
122 |
+
$this->pointer = $pointer;
|
123 |
+
|
124 |
+
// set the filename
|
125 |
+
$this->file = $file;
|
126 |
+
|
127 |
+
// open the file
|
128 |
+
$this->handle = @fopen($this->file, 'rb');
|
129 |
+
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* __destruct
|
134 |
+
*
|
135 |
+
* Cleans up
|
136 |
+
*
|
137 |
+
* @return void
|
138 |
+
* @author Dom Hastings
|
139 |
+
* @access public
|
140 |
+
*/
|
141 |
+
public function __destruct() {
|
142 |
+
// close the file resource
|
143 |
+
if ($this->handle) @fclose($this->handle);
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* read
|
148 |
+
*
|
149 |
+
* Reads the first available occurence of the XML element $this->options['element']
|
150 |
+
*
|
151 |
+
* @return string The XML string from $this->file
|
152 |
+
* @author Dom Hastings
|
153 |
+
* @access public
|
154 |
+
*/
|
155 |
+
public function read() {
|
156 |
+
// check we have an element specified
|
157 |
+
if (!empty($this->options['element'])) {
|
158 |
+
// trim it
|
159 |
+
$element = trim($this->options['element']);
|
160 |
+
|
161 |
+
} else {
|
162 |
+
$element = '';
|
163 |
+
}
|
164 |
+
|
165 |
+
// initialize the buffer
|
166 |
+
$buffer = false;
|
167 |
+
|
168 |
+
// if the element is empty, then start auto detect root element tag name
|
169 |
+
if (empty($element)) {
|
170 |
+
// let the script know we're reading
|
171 |
+
$this->reading = true;
|
172 |
+
$founded_tags = array();
|
173 |
+
// read in the whole doc, cos we don't know what's wanted
|
174 |
+
while ($this->reading and (count($founded_tags) < 500)) {
|
175 |
+
$c = @fread($this->handle, $this->options['chunkSize']);
|
176 |
+
|
177 |
+
$c = $this->removeColonsFromRSS($c);
|
178 |
+
|
179 |
+
if ($this->is_validate) {
|
180 |
+
if (stripos($c, "xmlns") !== false){
|
181 |
+
$this->is_validate = false;
|
182 |
+
}
|
183 |
+
}
|
184 |
+
|
185 |
+
if ( preg_match_all("/<\\w+\\s*[^<|^\n]*\\s*\/?>/i", $c, $matches, PREG_PATTERN_ORDER) ){
|
186 |
+
foreach ($matches[0] as $tag) {
|
187 |
+
$tag = explode(" ", trim(str_replace(array('<','>','/'), '', $tag)));
|
188 |
+
array_push($founded_tags, $tag[0]);
|
189 |
+
}
|
190 |
+
}
|
191 |
+
$this->reading = (!@feof($this->handle));
|
192 |
+
}
|
193 |
+
|
194 |
+
// we must be looking for a specific element
|
195 |
+
}
|
196 |
+
|
197 |
+
if (empty($this->encoding)) {
|
198 |
+
fseek($this->handle, 0);
|
199 |
+
$this->reading = true;
|
200 |
+
// read in the whole doc, cos we don't know what's wanted
|
201 |
+
while ($this->reading) {
|
202 |
+
$c = @fread($this->handle, $this->options['chunkSize']);
|
203 |
+
$enc = preg_match("/<\?xml.*\?>/i", $c, $enc_matches);
|
204 |
+
if ($enc)
|
205 |
+
$this->encoding = $enc_matches[0];
|
206 |
+
$this->reading = false;
|
207 |
+
}
|
208 |
+
}
|
209 |
+
|
210 |
+
if (empty($this->encoding)) $this->encoding = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
211 |
+
|
212 |
+
if (empty($element) and !empty($founded_tags)) {
|
213 |
+
|
214 |
+
$element_counts = array_count_values($founded_tags);
|
215 |
+
|
216 |
+
if (!empty($element_counts)){
|
217 |
+
|
218 |
+
//$this->cloud = array_slice($element_counts, 0, 2);
|
219 |
+
|
220 |
+
foreach ($element_counts as $tag => $count) {
|
221 |
+
if (strpos($tag, ":") === false){
|
222 |
+
if ($count > 1 and empty($this->options['element'])) {
|
223 |
+
$this->options['element'] = $element = $tag;
|
224 |
+
}
|
225 |
+
else{
|
226 |
+
$this->cloud[$tag] = $count;
|
227 |
+
}
|
228 |
+
}
|
229 |
+
}
|
230 |
+
}
|
231 |
+
|
232 |
+
}
|
233 |
+
|
234 |
+
// return it all if element doesn't founded
|
235 |
+
if (empty($element)){
|
236 |
+
if (!empty($element_counts)){
|
237 |
+
$this->options['element'] = $element = array_shift(array_keys($element_counts));
|
238 |
+
}
|
239 |
+
else return false;
|
240 |
+
}
|
241 |
+
|
242 |
+
// we must be looking for a specific element
|
243 |
+
|
244 |
+
// initialize the buffer
|
245 |
+
$buffer = false;
|
246 |
+
|
247 |
+
// set up the strings to find
|
248 |
+
$open = '<'.$element;
|
249 |
+
$close = '</'.$element.'>';
|
250 |
+
|
251 |
+
// let the script know we're reading
|
252 |
+
$this->reading = true;
|
253 |
+
|
254 |
+
// reset the global buffer
|
255 |
+
$this->readBuffer = '';
|
256 |
+
|
257 |
+
// this is used to ensure all data is read, and to make sure we don't send the start data again by mistake
|
258 |
+
$store = false;
|
259 |
+
|
260 |
+
$checkOpen = false;
|
261 |
+
|
262 |
+
// seek to the position we need in the file
|
263 |
+
fseek($this->handle, $this->pointer);
|
264 |
+
|
265 |
+
// start reading
|
266 |
+
while ($this->reading && !@feof($this->handle)) {
|
267 |
+
|
268 |
+
// store the chunk in a temporary variable
|
269 |
+
$tmp = @fread($this->handle, $this->options['chunkSize']);
|
270 |
+
|
271 |
+
$tmp = $this->removeColonsFromRSS($tmp);
|
272 |
+
|
273 |
+
// update the global buffer
|
274 |
+
$this->readBuffer .= $tmp;
|
275 |
+
|
276 |
+
if ($checkOpen === false){
|
277 |
+
|
278 |
+
$checkOpen = preg_match_all("/".$open."[ |>]{1}/i", $tmp, $checkOpenmatches, PREG_OFFSET_CAPTURE);
|
279 |
+
|
280 |
+
if (!empty($checkOpenmatches[0])){
|
281 |
+
|
282 |
+
$checkOpen = $checkOpenmatches[0][0][1];
|
283 |
+
|
284 |
+
}
|
285 |
+
else $checkOpen = false;
|
286 |
+
|
287 |
+
// check for the open string
|
288 |
+
/*$checkOpen = stripos($tmp, $open." ");
|
289 |
+
if ($checkOpen === false) stripos($tmp, $open.">"); */
|
290 |
+
|
291 |
+
// if it wasn't in the new buffer
|
292 |
+
if ($checkOpen === false && !($store)) {
|
293 |
+
// check the full buffer (in case it was only half in this buffer)
|
294 |
+
|
295 |
+
$checkOpen = preg_match_all("/".$open."[ |>]{1}/i", $this->readBuffer, $checkOpenmatches, PREG_OFFSET_CAPTURE);
|
296 |
+
|
297 |
+
if (!empty($checkOpenmatches[0])){
|
298 |
+
|
299 |
+
$checkOpen = $checkOpenmatches[0][0][1];
|
300 |
+
|
301 |
+
}
|
302 |
+
else $checkOpen = false;
|
303 |
+
|
304 |
+
/*$checkOpen = strpos($this->readBuffer, $open." ");
|
305 |
+
if ($checkOpen === false) $checkOpen = strpos($this->readBuffer, $open.">");*/
|
306 |
+
|
307 |
+
// if it was in there
|
308 |
+
if ($checkOpen !== false) {
|
309 |
+
// set it to the remainder
|
310 |
+
$checkOpen = $checkOpen % $this->options['chunkSize'];
|
311 |
+
}
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
// check for the close string
|
316 |
+
$checkClose = preg_match_all("/<\/".$element.">/i", $tmp, $closematches, PREG_OFFSET_CAPTURE);
|
317 |
+
$withoutcloseelement = false;
|
318 |
+
|
319 |
+
if (!$checkClose){
|
320 |
+
$checkClose = (preg_match("%<".$element."\s{1,}[^<]*\/>%i", $tmp, $matches)) ? strpos($tmp, $matches[0]) : false;
|
321 |
+
|
322 |
+
if ($checkClose !== false)
|
323 |
+
$withoutcloseelement = true;
|
324 |
+
else{
|
325 |
+
$checkClose = (preg_match_all("%<".$element."\s{1,}[^<]*\/>%i", $this->readBuffer, $matches)) ? strpos($this->readBuffer, $matches[0][count($matches[0]) - 1]) : false;
|
326 |
+
if ($checkClose !== false) {
|
327 |
+
$withoutcloseelement = true;
|
328 |
+
$matches[0] = $matches[0][count($matches[0]) - 1];
|
329 |
+
}
|
330 |
+
}
|
331 |
+
}
|
332 |
+
else{
|
333 |
+
|
334 |
+
$close_finded = false;
|
335 |
+
$length = $closematches[0][0][1] - $checkOpen;
|
336 |
+
|
337 |
+
$checkDuplicateOpen = preg_match_all("/".$open."[ |>]{1}/i", substr($this->readBuffer, $checkOpen, $length), $matches, PREG_OFFSET_CAPTURE);
|
338 |
+
|
339 |
+
while (!$close_finded){
|
340 |
+
if ($checkDuplicateOpen > 1 and !empty($closematches[0][$checkDuplicateOpen - 1])){
|
341 |
+
$secondcheckDuplicateOpen = preg_match_all("/".$open."[ |>]{1}/i", substr($this->readBuffer, $checkOpen, $closematches[0][$checkDuplicateOpen - 1][1] - $checkOpen), $matches, PREG_OFFSET_CAPTURE);
|
342 |
+
if ($secondcheckDuplicateOpen == $checkDuplicateOpen){
|
343 |
+
$checkClose = $closematches[0][$checkDuplicateOpen - 1][1];
|
344 |
+
$close_finded = true;
|
345 |
+
}
|
346 |
+
else{
|
347 |
+
$checkClose = false;
|
348 |
+
$checkDuplicateOpen = $secondcheckDuplicateOpen;
|
349 |
+
}
|
350 |
+
}
|
351 |
+
elseif ($checkDuplicateOpen > 1){
|
352 |
+
$checkClose = false;
|
353 |
+
$close_finded = true;
|
354 |
+
$store = true;
|
355 |
+
}
|
356 |
+
else{
|
357 |
+
$checkClose = $closematches[0][0][1];
|
358 |
+
$close_finded = true;
|
359 |
+
}
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
if ($checkClose !== false) {
|
364 |
+
// add the length of the close string itself
|
365 |
+
if ( ! $withoutcloseelement)
|
366 |
+
$checkClose += strlen($close);
|
367 |
+
else
|
368 |
+
$checkClose += strlen($matches[0]); // "/>" symbols
|
369 |
+
|
370 |
+
}
|
371 |
+
|
372 |
+
// if we've found the opening string and we're not already reading another element
|
373 |
+
if ($checkOpen !== false && !($store)) {
|
374 |
+
// if we're found the end element too
|
375 |
+
if ($checkClose !== false) {
|
376 |
+
// append the string only between the start and end element
|
377 |
+
$buffer .= substr($tmp, $checkOpen, ($checkClose - $checkOpen));
|
378 |
+
|
379 |
+
// update the pointer
|
380 |
+
$this->pointer += $checkClose;
|
381 |
+
|
382 |
+
// let the script know we're done
|
383 |
+
$this->reading = false;
|
384 |
+
|
385 |
+
} else {
|
386 |
+
// append the data we know to be part of this element
|
387 |
+
$buffer .= substr($tmp, $checkOpen);
|
388 |
+
|
389 |
+
// update the pointer
|
390 |
+
$this->pointer += $this->options['chunkSize'];
|
391 |
+
|
392 |
+
// let the script know we're gonna be storing all the data until we find the close element
|
393 |
+
$store = true;
|
394 |
+
|
395 |
+
}
|
396 |
+
|
397 |
+
// if we've found the closing element
|
398 |
+
} elseif ($checkClose !== false) {
|
399 |
+
// update the buffer with the data upto and including the close tag
|
400 |
+
$buffer .= substr($tmp, 0, $checkClose);
|
401 |
+
|
402 |
+
// update the pointer
|
403 |
+
$this->pointer += $checkClose;
|
404 |
+
|
405 |
+
// let the script know we're done
|
406 |
+
$this->reading = false;
|
407 |
+
|
408 |
+
// if we've found the closing element, but half in the previous chunk
|
409 |
+
} elseif ($store) {
|
410 |
+
// update the buffer
|
411 |
+
$buffer .= $tmp;
|
412 |
+
|
413 |
+
// and the pointer
|
414 |
+
$this->pointer += $this->options['chunkSize'];
|
415 |
+
}
|
416 |
+
|
417 |
+
}
|
418 |
+
|
419 |
+
// return the element (or the whole file if we're not looking for elements)
|
420 |
+
return $buffer;
|
421 |
+
}
|
422 |
+
|
423 |
+
function removeColonsFromRSS($feed) {
|
424 |
+
// pull out colons from start tags
|
425 |
+
// (<\w+):(\w+>)
|
426 |
+
$pattern = '/(<\w+):(\w+[ |>]{1})/i';
|
427 |
+
$replacement = '$1_$2';
|
428 |
+
$feed = preg_replace($pattern, $replacement, $feed);
|
429 |
+
// pull out colons from end tags
|
430 |
+
// (<\/\w+):(\w+>)
|
431 |
+
$pattern = '/(<\/\w+):(\w+>)/i';
|
432 |
+
$replacement = '$1_$2';
|
433 |
+
$feed = preg_replace($pattern, $replacement, $feed);
|
434 |
+
return $feed;
|
435 |
+
}
|
436 |
+
}
|
classes/download.php
CHANGED
@@ -1,39 +1,39 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class PMXI_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 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PMXI_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 |
}
|
config/options.php
CHANGED
@@ -1,22 +1,23 @@
|
|
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 |
-
"info_api_url" => "http://www.wpallimport.com/adminpanel/update/info.php",
|
8 |
-
"history_file_count" => 10000,
|
9 |
-
"history_file_age" => 365,
|
10 |
-
"highlight_limit" => 10000,
|
11 |
-
"upload_max_filesize" => 2048,
|
12 |
-
"post_max_size" => 2048,
|
13 |
-
"max_input_time" => -1,
|
14 |
-
"max_execution_time" => -1,
|
15 |
-
"dismiss" => 0,
|
16 |
-
"dismiss_manage_top" => 0,
|
17 |
-
"dismiss_manage_bottom" => 0,
|
18 |
-
"html_entities" => 0,
|
19 |
-
"utf8_decode" => 0,
|
20 |
-
"cron_job_key" => url_title(rand_char(12)),
|
21 |
-
"chunk_size" => 64
|
22 |
-
|
|
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 |
+
"info_api_url" => "http://www.wpallimport.com/adminpanel/update/info.php",
|
8 |
+
"history_file_count" => 10000,
|
9 |
+
"history_file_age" => 365,
|
10 |
+
"highlight_limit" => 10000,
|
11 |
+
"upload_max_filesize" => 2048,
|
12 |
+
"post_max_size" => 2048,
|
13 |
+
"max_input_time" => -1,
|
14 |
+
"max_execution_time" => -1,
|
15 |
+
"dismiss" => 0,
|
16 |
+
"dismiss_manage_top" => 0,
|
17 |
+
"dismiss_manage_bottom" => 0,
|
18 |
+
"html_entities" => 0,
|
19 |
+
"utf8_decode" => 0,
|
20 |
+
"cron_job_key" => url_title(rand_char(12)),
|
21 |
+
"chunk_size" => 64,
|
22 |
+
"pingbacks" => 1
|
23 |
+
);
|
controllers/admin/import.php
CHANGED
@@ -1,1593 +1,1682 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Import configuration wizard
|
4 |
-
*
|
5 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
-
*/
|
7 |
-
|
8 |
-
class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
9 |
-
protected $isWizard = true; // indicates whether controller is in wizard mode (otherwize it called to be deligated an edit action)
|
10 |
-
protected $isTemplateEdit = false; // indicates whether controlled is deligated by manage imports controller
|
11 |
-
|
12 |
-
protected function init() {
|
13 |
-
parent::init();
|
14 |
-
|
15 |
-
try{
|
16 |
-
$path = session_save_path();
|
17 |
-
if ( ! @is_dir($path) or ! @is_writable($path)){
|
18 |
-
@ini_set("session.save_handler", "files");
|
19 |
-
session_save_path(sys_get_temp_dir());
|
20 |
-
}
|
21 |
-
} catch (XmlImportException $e) {
|
22 |
-
$this->errors->add('form-validation', __('Can not create session.', 'pmxi_plugin'));
|
23 |
-
}
|
24 |
-
|
25 |
-
// enable sessions
|
26 |
-
if ( ! session_id()) session_start();
|
27 |
-
|
28 |
-
if ('PMXI_Admin_Manage' == PMXI_Plugin::getInstance()->getAdminCurrentScreen()->base) { // prereqisites are not checked when flow control is deligated
|
29 |
-
$id = $this->input->get('id');
|
30 |
-
$this->data['import'] = $import = new PMXI_Import_Record();
|
31 |
-
if ( ! $id or $import->getById($id)->isEmpty()) { // specified import is not found
|
32 |
-
wp_redirect(add_query_arg('page', 'pmxi-admin-manage', admin_url('admin.php'))); die();
|
33 |
-
}
|
34 |
-
$this->isWizard = false;
|
35 |
-
|
36 |
-
} else {
|
37 |
-
$action = PMXI_Plugin::getInstance()->getAdminCurrentScreen()->action;
|
38 |
-
$this->_step_ready($action);
|
39 |
-
$this->isInline = 'process' == $action;
|
40 |
-
}
|
41 |
-
|
42 |
-
XmlImportConfig::getInstance()->setCacheDirectory(sys_get_temp_dir());
|
43 |
-
|
44 |
-
// preserve id parameter as part of baseUrl
|
45 |
-
$id = $this->input->get('id') and $this->baseUrl = add_query_arg('id', $id, $this->baseUrl);
|
46 |
-
}
|
47 |
-
|
48 |
-
public function set($var, $val)
|
49 |
-
{
|
50 |
-
$this->{$var} = $val;
|
51 |
-
}
|
52 |
-
public function get($var)
|
53 |
-
{
|
54 |
-
return $this->{$var};
|
55 |
-
}
|
56 |
-
|
57 |
-
/**
|
58 |
-
* Checks whether corresponding step of wizard is complete
|
59 |
-
* @param string $action
|
60 |
-
*/
|
61 |
-
protected function _step_ready($action) {
|
62 |
-
// step #1: xml selction - has no prerequisites
|
63 |
-
if ('index' == $action) return true;
|
64 |
-
|
65 |
-
// step #2: element selection
|
66 |
-
$this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
|
67 |
-
$this->data['update_previous'] = $update_previous = new PMXI_Import_Record();
|
68 |
-
$old = libxml_use_internal_errors(true);
|
69 |
-
|
70 |
-
if (empty($_SESSION['pmxi_import'])
|
71 |
-
or ! $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']))// FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
72 |
-
//or empty($_SESSION['pmxi_import']['source'])
|
73 |
-
or ! empty($_SESSION['pmxi_import']['update_previous']) and $update_previous->getById($_SESSION['pmxi_import']['update_previous'])->isEmpty()
|
74 |
-
) {
|
75 |
-
$this->errors->add('form-validation', __('Can not create DOM object for provided feed.', 'pmxi_plugin'));
|
76 |
-
wp_redirect_or_javascript($this->baseUrl); die();
|
77 |
-
}
|
78 |
-
libxml_use_internal_errors($old);
|
79 |
-
if ('element' == $action) return true;
|
80 |
-
if ('evaluate' == $action) return true;
|
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 |
-
$this->data['
|
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 |
-
$this->data['
|
418 |
-
$this->
|
419 |
-
|
420 |
-
$
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
$
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
$this->errors->add('form-validation', __('
|
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 |
-
libxml_use_internal_errors(
|
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 |
-
libxml_use_internal_errors(
|
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 |
-
$this->errors->add('form-validation', __('
|
599 |
-
}
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
$this->data['
|
614 |
-
|
615 |
-
$
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
$this->
|
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 |
-
if (
|
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 |
-
if ($
|
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 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
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 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
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 |
-
if (
|
955 |
-
$
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
$
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
'
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
'
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
//
|
1111 |
-
|
1112 |
-
|
1113 |
-
$
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
'
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
$
|
1274 |
-
|
1275 |
-
|
1276 |
-
$_SESSION['pmxi_import']['
|
1277 |
-
|
1278 |
-
$
|
1279 |
-
|
1280 |
-
$loop
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
1501 |
-
|
1502 |
-
|
1503 |
-
|
1504 |
-
echo '<
|
1505 |
-
|
1506 |
-
|
1507 |
-
|
1508 |
-
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
|
1517 |
-
|
1518 |
-
|
1519 |
-
|
1520 |
-
|
1521 |
-
|
1522 |
-
|
1523 |
-
|
1524 |
-
|
1525 |
-
|
1526 |
-
}
|
1527 |
-
|
1528 |
-
|
1529 |
-
|
1530 |
-
|
1531 |
-
|
1532 |
-
|
1533 |
-
|
1534 |
-
|
1535 |
-
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
}
|
1543 |
-
}
|
1544 |
-
protected function
|
1545 |
-
{
|
1546 |
-
|
1547 |
-
|
1548 |
-
|
1549 |
-
|
1550 |
-
|
1551 |
-
|
1552 |
-
|
1553 |
-
|
1554 |
-
|
1555 |
-
|
1556 |
-
|
1557 |
-
|
1558 |
-
|
1559 |
-
|
1560 |
-
$
|
1561 |
-
|
1562 |
-
|
1563 |
-
|
1564 |
-
|
1565 |
-
|
1566 |
-
|
1567 |
-
|
1568 |
-
|
1569 |
-
|
1570 |
-
|
1571 |
-
|
1572 |
-
|
1573 |
-
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
1588 |
-
|
1589 |
-
|
1590 |
-
|
1591 |
-
|
1592 |
-
|
1593 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Import configuration wizard
|
4 |
+
*
|
5 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
+
*/
|
7 |
+
|
8 |
+
class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
9 |
+
protected $isWizard = true; // indicates whether controller is in wizard mode (otherwize it called to be deligated an edit action)
|
10 |
+
protected $isTemplateEdit = false; // indicates whether controlled is deligated by manage imports controller
|
11 |
+
|
12 |
+
protected function init() {
|
13 |
+
parent::init();
|
14 |
+
|
15 |
+
try{
|
16 |
+
$path = session_save_path();
|
17 |
+
if ( ! @is_dir($path) or ! @is_writable($path)){
|
18 |
+
@ini_set("session.save_handler", "files");
|
19 |
+
session_save_path(sys_get_temp_dir());
|
20 |
+
}
|
21 |
+
} catch (XmlImportException $e) {
|
22 |
+
$this->errors->add('form-validation', __('Can not create session.', 'pmxi_plugin'));
|
23 |
+
}
|
24 |
+
|
25 |
+
// enable sessions
|
26 |
+
if ( ! session_id()) session_start();
|
27 |
+
|
28 |
+
if ('PMXI_Admin_Manage' == PMXI_Plugin::getInstance()->getAdminCurrentScreen()->base) { // prereqisites are not checked when flow control is deligated
|
29 |
+
$id = $this->input->get('id');
|
30 |
+
$this->data['import'] = $import = new PMXI_Import_Record();
|
31 |
+
if ( ! $id or $import->getById($id)->isEmpty()) { // specified import is not found
|
32 |
+
wp_redirect(add_query_arg('page', 'pmxi-admin-manage', admin_url('admin.php'))); die();
|
33 |
+
}
|
34 |
+
$this->isWizard = false;
|
35 |
+
|
36 |
+
} else {
|
37 |
+
$action = PMXI_Plugin::getInstance()->getAdminCurrentScreen()->action;
|
38 |
+
$this->_step_ready($action);
|
39 |
+
$this->isInline = 'process' == $action;
|
40 |
+
}
|
41 |
+
|
42 |
+
XmlImportConfig::getInstance()->setCacheDirectory(sys_get_temp_dir());
|
43 |
+
|
44 |
+
// preserve id parameter as part of baseUrl
|
45 |
+
$id = $this->input->get('id') and $this->baseUrl = add_query_arg('id', $id, $this->baseUrl);
|
46 |
+
}
|
47 |
+
|
48 |
+
public function set($var, $val)
|
49 |
+
{
|
50 |
+
$this->{$var} = $val;
|
51 |
+
}
|
52 |
+
public function get($var)
|
53 |
+
{
|
54 |
+
return $this->{$var};
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Checks whether corresponding step of wizard is complete
|
59 |
+
* @param string $action
|
60 |
+
*/
|
61 |
+
protected function _step_ready($action) {
|
62 |
+
// step #1: xml selction - has no prerequisites
|
63 |
+
if ('index' == $action) return true;
|
64 |
+
|
65 |
+
// step #2: element selection
|
66 |
+
$this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
|
67 |
+
$this->data['update_previous'] = $update_previous = new PMXI_Import_Record();
|
68 |
+
$old = libxml_use_internal_errors(true);
|
69 |
+
|
70 |
+
if (empty($_SESSION['pmxi_import'])
|
71 |
+
or ! $dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']))// FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
72 |
+
//or empty($_SESSION['pmxi_import']['source'])
|
73 |
+
or ! empty($_SESSION['pmxi_import']['update_previous']) and $update_previous->getById($_SESSION['pmxi_import']['update_previous'])->isEmpty()
|
74 |
+
) {
|
75 |
+
$this->errors->add('form-validation', __('Can not create DOM object for provided feed.', 'pmxi_plugin'));
|
76 |
+
wp_redirect_or_javascript($this->baseUrl); die();
|
77 |
+
}
|
78 |
+
libxml_use_internal_errors($old);
|
79 |
+
if ('element' == $action) return true;
|
80 |
+
if ('evaluate' == $action) return true;
|
81 |
+
if ('evaluate_variations' == $action) return true;
|
82 |
+
|
83 |
+
// step #3: template
|
84 |
+
$xpath = new DOMXPath($dom);
|
85 |
+
|
86 |
+
if (empty($_SESSION['pmxi_import']['xpath']) or ! ($this->data['elements'] = $elements = $xpath->query($_SESSION['pmxi_import']['xpath'])) or ! $elements->length) {
|
87 |
+
$this->errors->add('form-validation', __('No matching elements found.', 'pmxi_plugin'));
|
88 |
+
wp_redirect_or_javascript(add_query_arg('action', 'element', $this->baseUrl)); die();
|
89 |
+
}
|
90 |
+
if ('template' == $action or 'preview' == $action or 'tag' == $action) return true;
|
91 |
+
|
92 |
+
// step #4: options
|
93 |
+
if (empty($_SESSION['pmxi_import']['template']) or empty($_SESSION['pmxi_import']['template']['title']) or empty($_SESSION['pmxi_import']['template']['title'])) {
|
94 |
+
wp_redirect_or_javascript(add_query_arg('action', 'template', $this->baseUrl)); die();
|
95 |
+
}
|
96 |
+
if ('options' == $action) return true;
|
97 |
+
|
98 |
+
if (empty($_SESSION['pmxi_import']['options'])) {
|
99 |
+
wp_redirect(add_query_arg('action', 'options', $this->baseUrl)); die();
|
100 |
+
}
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Step #1: Choose File
|
105 |
+
*/
|
106 |
+
public function index() {
|
107 |
+
|
108 |
+
$this->data['reimported_import'] = $import = new PMXI_Import_Record();
|
109 |
+
$this->data['id'] = $id = $this->input->get('id');
|
110 |
+
if ($id and $import->getById($id)->isEmpty()) { // update requested but corresponding import is not found
|
111 |
+
wp_redirect(remove_query_arg('id', $this->baseUrl)); die();
|
112 |
+
}
|
113 |
+
|
114 |
+
$this->data['post'] = $post = $this->input->post(array(
|
115 |
+
'type' => 'upload',
|
116 |
+
'url' => 'http://',
|
117 |
+
'ftp' => array('url' => 'ftp://'),
|
118 |
+
'file' => '',
|
119 |
+
'reimport' => '',
|
120 |
+
'is_update_previous' => $id ? 1 : 0,
|
121 |
+
'update_previous' => $id,
|
122 |
+
'xpath' => '/',
|
123 |
+
'large_file' => '',
|
124 |
+
'filepath' => '',
|
125 |
+
'root_element' => ''
|
126 |
+
));
|
127 |
+
|
128 |
+
if ($this->input->post('is_submitted_continue')) {
|
129 |
+
if ( ! empty($_SESSION['pmxi_import']['xml'])) {
|
130 |
+
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
131 |
+
}
|
132 |
+
} elseif ('upload' == $this->input->post('type')) {
|
133 |
+
|
134 |
+
$uploads = wp_upload_dir();
|
135 |
+
|
136 |
+
if (empty($post['filepath'])) {
|
137 |
+
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
138 |
+
} elseif (!is_file($post['filepath'])) {
|
139 |
+
$this->errors->add('form-validation', __('Uploaded file is empty', 'pmxi_plugin'));
|
140 |
+
} elseif ( ! preg_match('%\W(xml|gzip|zip|csv|gz)$%i', trim(basename($post['filepath'])))) {
|
141 |
+
$this->errors->add('form-validation', __('Uploaded file must be XML, CSV or ZIP, GZIP', 'pmxi_plugin'));
|
142 |
+
} elseif (preg_match('%\W(zip)$%i', trim(basename($post['filepath'])))) {
|
143 |
+
|
144 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
|
145 |
+
|
146 |
+
$archive = new PclZip($post['filepath']);
|
147 |
+
if (($v_result_list = $archive->extract(PCLZIP_OPT_PATH, $uploads['path'], PCLZIP_OPT_REPLACE_NEWER)) == 0) {
|
148 |
+
$this->errors->add('form-validation', 'Failed to open uploaded ZIP archive : '.$archive->errorInfo(true));
|
149 |
+
}
|
150 |
+
else {
|
151 |
+
|
152 |
+
$filePath = '';
|
153 |
+
|
154 |
+
if (!empty($v_result_list)){
|
155 |
+
foreach ($v_result_list as $unzipped_file) {
|
156 |
+
if ($unzipped_file['status'] == 'ok') $filePath = $unzipped_file['filename'];
|
157 |
+
}
|
158 |
+
}
|
159 |
+
if($uploads['error']){
|
160 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
161 |
+
}
|
162 |
+
|
163 |
+
if(empty($filePath)){
|
164 |
+
$zip = zip_open(trim($post['filepath']));
|
165 |
+
if (is_resource($zip)) {
|
166 |
+
while ($zip_entry = zip_read($zip)) {
|
167 |
+
$filePath = zip_entry_name($zip_entry);
|
168 |
+
$fp = fopen($uploads['path']."/".$filePath, "w");
|
169 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
170 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
171 |
+
fwrite($fp,"$buf");
|
172 |
+
zip_entry_close($zip_entry);
|
173 |
+
fclose($fp);
|
174 |
+
}
|
175 |
+
break;
|
176 |
+
}
|
177 |
+
zip_close($zip);
|
178 |
+
|
179 |
+
} else {
|
180 |
+
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive. Can\'t extract files.', 'pmxi_plugin'));
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
// Detect if file is very large
|
185 |
+
$post['large_file'] = (filesize($filePath) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
186 |
+
$source = array(
|
187 |
+
'name' => basename($post['filepath']),
|
188 |
+
'type' => 'upload',
|
189 |
+
'path' => $post['filepath'],
|
190 |
+
);
|
191 |
+
|
192 |
+
if (preg_match('%\W(csv)$%i', trim($filePath))){ // If CSV file found in archieve
|
193 |
+
|
194 |
+
if($uploads['error']){
|
195 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
196 |
+
}
|
197 |
+
if (empty($post['large_file'])) {
|
198 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath);
|
199 |
+
}
|
200 |
+
else{
|
201 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
202 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
203 |
+
$filePath = $csv->xml_path;
|
204 |
+
$post['root_element'] = 'node';
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
} elseif ( preg_match('%\W(csv)$%i', trim($post['filepath']))) { // If CSV file uploaded
|
210 |
+
|
211 |
+
// Detect if file is very large
|
212 |
+
$post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
213 |
+
|
214 |
+
if($uploads['error']){
|
215 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
216 |
+
}
|
217 |
+
$filePath = $post['filepath'];
|
218 |
+
$source = array(
|
219 |
+
'name' => basename($post['filepath']),
|
220 |
+
'type' => 'upload',
|
221 |
+
'path' => $filePath,
|
222 |
+
);
|
223 |
+
if (empty($post['large_file'])) {
|
224 |
+
$filePath = PMXI_Plugin::csv_to_xml($post['filepath']);
|
225 |
+
} else{
|
226 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
227 |
+
$csv = new PMXI_CsvParser($post['filepath'], true);
|
228 |
+
$filePath = $csv->xml_path;
|
229 |
+
$post['root_element'] = 'node';
|
230 |
+
}
|
231 |
+
} elseif(preg_match('%\W(gz)$%i', trim($post['filepath']))){ // If gz file uploaded
|
232 |
+
$fileInfo = pmxi_gzfile_get_contents($post['filepath']);
|
233 |
+
$filePath = $fileInfo['localPath'];
|
234 |
+
|
235 |
+
// Detect if file is very large
|
236 |
+
$post['large_file'] = (filesize($filePath) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
237 |
+
|
238 |
+
$source = array(
|
239 |
+
'name' => basename($post['filepath']),
|
240 |
+
'type' => 'upload',
|
241 |
+
'path' => $post['filepath'],
|
242 |
+
);
|
243 |
+
|
244 |
+
// detect CSV or XML
|
245 |
+
if ( $fileInfo['type'] == 'csv') { // it is CSV file
|
246 |
+
if (empty($post['large_file'])) {
|
247 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath); // convert CSV to XML
|
248 |
+
}
|
249 |
+
else{
|
250 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
251 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
252 |
+
$filePath = $csv->xml_path;
|
253 |
+
$post['root_element'] = 'node';
|
254 |
+
}
|
255 |
+
}
|
256 |
+
} else { // If XML file uploaded
|
257 |
+
|
258 |
+
// Detect if file is very large
|
259 |
+
$post['large_file'] = (filesize($post['filepath']) > PMXI_Plugin::LARGE_SIZE) ? 'on' : false;
|
260 |
+
|
261 |
+
$filePath = $post['filepath'];
|
262 |
+
$source = array(
|
263 |
+
'name' => basename($post['filepath']),
|
264 |
+
'type' => 'upload',
|
265 |
+
'path' => $filePath,
|
266 |
+
);
|
267 |
+
}
|
268 |
+
}
|
269 |
+
elseif ($this->input->post('is_submitted')){
|
270 |
+
|
271 |
+
$this->errors->add('form-validation', __('Upgrade to the paid edition of WP All Import to use this feature.', 'pmxi_plugin'));
|
272 |
+
}
|
273 |
+
|
274 |
+
if ($post['is_update_previous'] and empty($post['update_previous'])) {
|
275 |
+
$this->errors->add('form-validation', __('Previous import for update must be selected to proceed with a new one', 'pmxi_plugin'));
|
276 |
+
}
|
277 |
+
|
278 |
+
if ($this->input->post('is_submitted') and ! $this->errors->get_error_codes()) {
|
279 |
+
|
280 |
+
check_admin_referer('choose-file', '_wpnonce_choose-file');
|
281 |
+
|
282 |
+
$elements_cloud = array();
|
283 |
+
|
284 |
+
$is_validate = true;
|
285 |
+
|
286 |
+
if (empty($xml)){
|
287 |
+
|
288 |
+
$wp_uploads = wp_upload_dir();
|
289 |
+
|
290 |
+
if (!empty($post['large_file'])){
|
291 |
+
|
292 |
+
set_time_limit(0);
|
293 |
+
|
294 |
+
$chunks = 0;
|
295 |
+
|
296 |
+
$chunk_path = '';
|
297 |
+
|
298 |
+
$local_paths = !empty($local_paths) ? $local_paths : array($filePath);
|
299 |
+
|
300 |
+
foreach ($local_paths as $key => $path) {
|
301 |
+
|
302 |
+
$file = new PMXI_Chunk($path, array('element' => $post['root_element'], 'path' => $wp_uploads['path']));
|
303 |
+
|
304 |
+
while ($chunk_xml = $file->read()) {
|
305 |
+
|
306 |
+
if (!empty($chunk_xml))
|
307 |
+
{
|
308 |
+
PMXI_Import_Record::preprocessXml($chunk_xml);
|
309 |
+
if ( !empty($chunk_xml) ){ // save first chunk to the file
|
310 |
+
$chunk_path = $wp_uploads['path'] .'/'. wp_unique_filename($wp_uploads['path'], "chunk_".basename($path));
|
311 |
+
file_put_contents($chunk_path, $file->encoding . "\n" . $chunk_xml);
|
312 |
+
chmod($chunk_path, 0755);
|
313 |
+
$is_validate = $file->is_validate;
|
314 |
+
$chunks++;
|
315 |
+
break;
|
316 |
+
}
|
317 |
+
}
|
318 |
+
}
|
319 |
+
if ( ! $key ){
|
320 |
+
|
321 |
+
if ( ! empty($file->options['element'])) {
|
322 |
+
|
323 |
+
$post['root_element'] = $file->options['element'];
|
324 |
+
|
325 |
+
$xpath = "/".$post['root_element'];
|
326 |
+
|
327 |
+
$elements_cloud = $file->cloud;
|
328 |
+
|
329 |
+
if (empty($chunks)) { $this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin')); }
|
330 |
+
|
331 |
+
$filePath && $xml = @file_get_contents($chunk_path);
|
332 |
+
}
|
333 |
+
else $this->errors->add('form-validation', __('Unable to find root element for this feed. Please open the feed in your browser or a text editor and ensure it is a valid feed.', 'pmxi_plugin'));
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
} else {
|
338 |
+
|
339 |
+
ob_start();
|
340 |
+
$filePath && @readgzfile($filePath);
|
341 |
+
$xml = ob_get_clean();
|
342 |
+
|
343 |
+
if (empty($xml)){
|
344 |
+
$xml = @file_get_contents($filePath);
|
345 |
+
if (empty($xml)) get_file_curl($filePath, $wp_uploads['path'] .'/'. basename($filePath));
|
346 |
+
if (empty($xml)) $xml = @file_get_contents($wp_uploads['path'] .'/'. basename($filePath));
|
347 |
+
}
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
if ((!$is_validate or PMXI_Import_Record::validateXml($xml, $this->errors)) and (empty($post['large_file']) or (!empty($post['large_file']) and !empty($chunks)))) {
|
352 |
+
// xml is valid
|
353 |
+
if (!empty($post['large_file'])){
|
354 |
+
$source['large_import'] = 'Yes';
|
355 |
+
$source['root_element'] = $post['root_element'];
|
356 |
+
}
|
357 |
+
else {
|
358 |
+
$source['large_import'] = 'No';
|
359 |
+
$source['root_element'] = '';
|
360 |
+
}
|
361 |
+
|
362 |
+
$source['first_import'] = date("Y-m-d H:i:s");
|
363 |
+
|
364 |
+
$_SESSION['pmxi_import'] = array(
|
365 |
+
'xml' => $xml,
|
366 |
+
'filePath' => $filePath,
|
367 |
+
'xpath' => (!empty($xpath)) ? $xpath : '',
|
368 |
+
'source' => $source,
|
369 |
+
'large_file' => (!empty($post['large_file'])) ? true : false,
|
370 |
+
'chunk_number' => 1,
|
371 |
+
'log' => '',
|
372 |
+
'current_post_ids' => '',
|
373 |
+
'processing' => 0,
|
374 |
+
'queue_chunk_number' => 0,
|
375 |
+
'count' => (isset($chunks)) ? $chunks : 0,
|
376 |
+
'created_records' => 0,
|
377 |
+
'updated_records' => 0,
|
378 |
+
'skipped_records' => 0,
|
379 |
+
'warnings' => 0,
|
380 |
+
'errors' => 0,
|
381 |
+
'start_time' => 0,
|
382 |
+
'local_paths' => (!empty($local_paths)) ? $local_paths : array(), // ftp import local copies of remote files
|
383 |
+
'action' => 'import',
|
384 |
+
'elements_cloud' => (!empty($elements_cloud)) ? $elements_cloud : array()
|
385 |
+
);
|
386 |
+
|
387 |
+
unset($xml);
|
388 |
+
$update_previous = new PMXI_Import_Record();
|
389 |
+
if ($post['is_update_previous'] and ! $update_previous->getById($post['update_previous'])->isEmpty()) {
|
390 |
+
$_SESSION['pmxi_import'] += array(
|
391 |
+
'update_previous' => $update_previous->id,
|
392 |
+
'xpath' => $update_previous->xpath,
|
393 |
+
'template' => $update_previous->template,
|
394 |
+
'options' => $update_previous->options,
|
395 |
+
);
|
396 |
+
} else {
|
397 |
+
$_SESSION['pmxi_import']['update_previous'] = '';
|
398 |
+
}
|
399 |
+
|
400 |
+
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
401 |
+
|
402 |
+
}
|
403 |
+
else {
|
404 |
+
$this->errors->add('form-validation', __('Please confirm you are importing a valid feed.<br/> Often, feed providers distribute feeds with invalid data, improperly wrapped HTML, line breaks where they should not be, faulty character encodings, syntax errors in the XML, and other issues.<br/><br/>WP All Import has checks in place to automatically fix some of the most common problems, but we can’t catch every single one.<br/><br/>It is also possible that there is a bug in WP All Import, and the problem is not with the feed.<br/><br/>If you need assistance, please contact support – <a href="mailto:support@soflyy.com">support@soflyy.com</a> – with your XML/CSV file. We will identify the problem and release a bug fix if necessary.', 'pmxi_plugin'));
|
405 |
+
}
|
406 |
+
}
|
407 |
+
|
408 |
+
$this->render();
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Step #2: Choose elements
|
413 |
+
*/
|
414 |
+
public function element()
|
415 |
+
{
|
416 |
+
|
417 |
+
$xpath = new DOMXPath($this->data['dom']);
|
418 |
+
$post = $this->input->post(array('xpath' => ''));
|
419 |
+
$this->data['post'] =& $post;
|
420 |
+
$this->data['elements_cloud'] = $_SESSION['pmxi_import']['elements_cloud'];
|
421 |
+
|
422 |
+
$wp_uploads = wp_upload_dir();
|
423 |
+
|
424 |
+
if ($this->input->post('is_submitted')) {
|
425 |
+
check_admin_referer('choose-elements', '_wpnonce_choose-elements');
|
426 |
+
if ('' == $post['xpath']) {
|
427 |
+
$this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
|
428 |
+
} else {
|
429 |
+
$node_list = @ $xpath->query($post['xpath']); // make sure only element selection is allowed; prevent parsing warning to be displayed
|
430 |
+
|
431 |
+
if (FALSE === $node_list) {
|
432 |
+
$this->errors->add('form-validation', __('Invalid XPath expression', 'pmxi_plugin'));
|
433 |
+
} elseif ( ! $node_list->length) {
|
434 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
435 |
+
} else {
|
436 |
+
foreach ($node_list as $el) {
|
437 |
+
if ( ! $el instanceof DOMElement) {
|
438 |
+
$this->errors->add('form-validation', __('XPath must match only elements', 'pmxi_plugin'));
|
439 |
+
break;
|
440 |
+
};
|
441 |
+
}
|
442 |
+
}
|
443 |
+
}
|
444 |
+
|
445 |
+
if ( ! $this->errors->get_error_codes()) {
|
446 |
+
|
447 |
+
$_SESSION['pmxi_import']['xpath'] = $post['xpath'];
|
448 |
+
// counting element selected by xPath
|
449 |
+
if ($_SESSION['pmxi_import']['large_file']){
|
450 |
+
|
451 |
+
$_SESSION['pmxi_import']['count'] = 0;
|
452 |
+
|
453 |
+
$this->data['node_list_count'] = 0;
|
454 |
+
|
455 |
+
// loop through the file until all lines are read
|
456 |
+
$first_loop = true;
|
457 |
+
|
458 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
459 |
+
|
460 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path'], 'type' => $this->input->post('type')));
|
461 |
+
|
462 |
+
while ($xml = $file->read()) {
|
463 |
+
|
464 |
+
if (!empty($xml))
|
465 |
+
{
|
466 |
+
$xml = $file->encoding . "\n" . $xml;
|
467 |
+
PMXI_Import_Record::preprocessXml($xml);
|
468 |
+
|
469 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
470 |
+
$old = libxml_use_internal_errors(true);
|
471 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
472 |
+
libxml_use_internal_errors($old);
|
473 |
+
$xpath = new DOMXPath($dom);
|
474 |
+
if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
|
475 |
+
$_SESSION['pmxi_import']['count']++;
|
476 |
+
$this->data['node_list_count']++;
|
477 |
+
if ($first_loop){
|
478 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
479 |
+
$first_loop = false;
|
480 |
+
}
|
481 |
+
}
|
482 |
+
unset($dom, $xpath, $elements);
|
483 |
+
|
484 |
+
}
|
485 |
+
}
|
486 |
+
}
|
487 |
+
|
488 |
+
if ( ! $this->data['node_list_count']) {
|
489 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
490 |
+
}
|
491 |
+
}
|
492 |
+
wp_redirect(add_query_arg('action', 'template', $this->baseUrl)); die();
|
493 |
+
}
|
494 |
+
} else {
|
495 |
+
|
496 |
+
if (isset($_SESSION['pmxi_import']['xpath']) and $_SESSION['pmxi_import']['large_file']) {
|
497 |
+
$post['xpath'] = $_SESSION['pmxi_import']['xpath'];
|
498 |
+
$this->data['elements'] = $elements = $xpath->query($post['xpath']);
|
499 |
+
if ( ! $elements->length and ! empty($_SESSION['pmxi_import']['update_previous'])) {
|
500 |
+
$_GET['pmxi_nt'] = __('<b>Warning</b>: No matching elements found for XPath expression from the import being updated. It probably means that new XML file has different format. Though you can update XPath, procceed only if you sure about update operation being valid.', 'pmxi_plugin');
|
501 |
+
}
|
502 |
+
} else {
|
503 |
+
// suggest 1st repeating element as default selection
|
504 |
+
$post['xpath'] = $this->xml_find_repeating($this->data['dom']->documentElement);
|
505 |
+
if (!empty($post['xpath'])){
|
506 |
+
$this->data['elements'] = $elements = $xpath->query($post['xpath']);
|
507 |
+
}
|
508 |
+
}
|
509 |
+
|
510 |
+
}
|
511 |
+
|
512 |
+
// workaround to prevent rendered XML representation to eat memory since it has to be stored in momory when output is bufferred
|
513 |
+
$this->render();
|
514 |
+
add_action('pmxi_action_after', array($this, 'element_after'));
|
515 |
+
}
|
516 |
+
public function element_after()
|
517 |
+
{
|
518 |
+
$this->render();
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Helper to evaluate xpath and return matching elements as direct paths for javascript side to highlight them
|
523 |
+
*/
|
524 |
+
public function evaluate()
|
525 |
+
{
|
526 |
+
if ( ! PMXI_Plugin::getInstance()->getAdminCurrentScreen()->is_ajax) { // call is only valid when send with ajax
|
527 |
+
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
528 |
+
}
|
529 |
+
|
530 |
+
$xpath = new DOMXPath($this->data['dom']);
|
531 |
+
$post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => $_SESSION['pmxi_import']['source']['root_element']));
|
532 |
+
$wp_uploads = wp_upload_dir();
|
533 |
+
|
534 |
+
if ('' == $post['xpath']) {
|
535 |
+
$this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
|
536 |
+
} else {
|
537 |
+
// counting selected elements
|
538 |
+
if ($_SESSION['pmxi_import']['large_file']){ // in large mode
|
539 |
+
|
540 |
+
if ($post['show_element'] == 1) {
|
541 |
+
$_SESSION['pmxi_import']['count'] = $this->data['node_list_count'] = 0;
|
542 |
+
}
|
543 |
+
else
|
544 |
+
$this->data['node_list_count'] = $_SESSION['pmxi_import']['count'];
|
545 |
+
|
546 |
+
|
547 |
+
$xpath_elements = explode('[', $post['xpath']);
|
548 |
+
$xpath_parts = explode('/', $xpath_elements[0]);
|
549 |
+
|
550 |
+
$_SESSION['pmxi_import']['source']['root_element'] = $xpath_parts[count($xpath_parts) - 1];
|
551 |
+
|
552 |
+
$loop = 1;
|
553 |
+
|
554 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
555 |
+
|
556 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
|
557 |
+
// loop through the file until all lines are read
|
558 |
+
while ($xml = $file->read()) {
|
559 |
+
|
560 |
+
if (!empty($xml))
|
561 |
+
{
|
562 |
+
$xml = $file->encoding . "\n" . $xml;
|
563 |
+
PMXI_Import_Record::preprocessXml($xml);
|
564 |
+
|
565 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
566 |
+
$old = libxml_use_internal_errors(true);
|
567 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
568 |
+
libxml_use_internal_errors($old);
|
569 |
+
$xpath = new DOMXPath($dom);
|
570 |
+
if (($this->data['elements'] = $elements = @$xpath->query($post['xpath'])) and $elements->length){
|
571 |
+
|
572 |
+
if ($post['show_element'] == 1){
|
573 |
+
$_SESSION['pmxi_import']['count']++;
|
574 |
+
$this->data['node_list_count']++;
|
575 |
+
}
|
576 |
+
|
577 |
+
if ($loop == $post['show_element'] ){
|
578 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
579 |
+
$this->data['dom'] = $dom;
|
580 |
+
if ($post['show_element'] > 1)
|
581 |
+
break;
|
582 |
+
}
|
583 |
+
else unset($dom, $xpath, $elements);
|
584 |
+
$loop++;
|
585 |
+
}
|
586 |
+
}
|
587 |
+
}
|
588 |
+
unset($file);
|
589 |
+
}
|
590 |
+
if ( ! $this->data['node_list_count']) {
|
591 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
592 |
+
}
|
593 |
+
}
|
594 |
+
else{ // in default mode
|
595 |
+
$this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
|
596 |
+
$this->data['node_list_count'] = $elements->length;
|
597 |
+
if (FALSE === $elements) {
|
598 |
+
$this->errors->add('form-validation', __('Invalid XPath expression', 'pmxi_plugin'));
|
599 |
+
} elseif ( ! $elements->length) {
|
600 |
+
$this->errors->add('form-validation', __('No matching elements found for XPath expression specified', 'pmxi_plugin'));
|
601 |
+
} else {
|
602 |
+
foreach ($elements as $el) {
|
603 |
+
if ( ! $el instanceof DOMElement) {
|
604 |
+
$this->errors->add('form-validation', __('XPath must match only elements', 'pmxi_plugin'));
|
605 |
+
break;
|
606 |
+
};
|
607 |
+
}
|
608 |
+
}
|
609 |
+
}
|
610 |
+
}
|
611 |
+
if ( ! $this->errors->get_error_codes()) {
|
612 |
+
|
613 |
+
//$this->shrink_xml_element($this->data['dom']->documentElement);
|
614 |
+
$xpath = new DOMXPath($this->data['dom']);
|
615 |
+
$this->data['elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
|
616 |
+
|
617 |
+
$paths = array(); $this->data['paths'] =& $paths;
|
618 |
+
if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
|
619 |
+
foreach ($elements as $el) {
|
620 |
+
if ( ! $el instanceof DOMElement) continue;
|
621 |
+
|
622 |
+
$p = $this->get_xml_path($el, $xpath) and $paths[] = $p;
|
623 |
+
}
|
624 |
+
}
|
625 |
+
$this->render();
|
626 |
+
} else {
|
627 |
+
$this->error();
|
628 |
+
}
|
629 |
+
}
|
630 |
+
|
631 |
+
/**
|
632 |
+
* Helper to evaluate xpath and return matching elements as direct paths for javascript side to highlight them
|
633 |
+
*/
|
634 |
+
public function evaluate_variations()
|
635 |
+
{
|
636 |
+
if ( ! PMXI_Plugin::getInstance()->getAdminCurrentScreen()->is_ajax) { // call is only valid when send with ajax
|
637 |
+
wp_redirect(add_query_arg('action', 'element', $this->baseUrl)); die();
|
638 |
+
}
|
639 |
+
|
640 |
+
$xpath = new DOMXPath($this->data['dom']);
|
641 |
+
$post = $this->input->post(array('xpath' => '', 'show_element' => 1, 'root_element' => $_SESSION['pmxi_import']['source']['root_element'], 'tagno' => 0));
|
642 |
+
$wp_uploads = wp_upload_dir();
|
643 |
+
|
644 |
+
$this->data['tagno'] = max(intval($this->input->getpost('tagno', 1)), 0);
|
645 |
+
|
646 |
+
if ('' == $post['xpath']) {
|
647 |
+
$this->errors->add('form-validation', __('No elements selected', 'pmxi_plugin'));
|
648 |
+
} else {
|
649 |
+
$post['xpath'] = '/' . $_SESSION['pmxi_import']['source']['root_element'] . '/'. ltrim(trim(str_replace("[*]","",$post['xpath']),'{}'), '/');
|
650 |
+
|
651 |
+
// in default mode
|
652 |
+
$this->data['variation_elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
|
653 |
+
$this->data['variation_list_count'] = $elements->length;
|
654 |
+
if (FALSE === $elements) {
|
655 |
+
$this->errors->add('form-validation', __('Invalid XPath expression', 'pmxi_plugin'));
|
656 |
+
} elseif ( ! $elements->length) {
|
657 |
+
$this->errors->add('form-validation', __('No matching variations found for XPath specified', 'pmxi_plugin'));
|
658 |
+
} else {
|
659 |
+
foreach ($elements as $el) {
|
660 |
+
if ( ! $el instanceof DOMElement) {
|
661 |
+
$this->errors->add('form-validation', __('XPath must match only elements', 'pmxi_plugin'));
|
662 |
+
break;
|
663 |
+
};
|
664 |
+
}
|
665 |
+
}
|
666 |
+
}
|
667 |
+
if ( ! $this->errors->get_error_codes()) {
|
668 |
+
|
669 |
+
$xpath = new DOMXPath($this->data['dom']);
|
670 |
+
$this->data['variation_elements'] = $elements = @ $xpath->query($post['xpath']); // prevent parsing warning to be displayed
|
671 |
+
$paths = array(); $this->data['paths'] =& $paths;
|
672 |
+
if (PMXI_Plugin::getInstance()->getOption('highlight_limit') and $elements->length <= PMXI_Plugin::getInstance()->getOption('highlight_limit')) {
|
673 |
+
foreach ($elements as $el) {
|
674 |
+
if ( ! $el instanceof DOMElement) continue;
|
675 |
+
|
676 |
+
$p = $this->get_xml_path($el, $xpath) and $paths[] = $p;
|
677 |
+
}
|
678 |
+
}
|
679 |
+
|
680 |
+
$this->render();
|
681 |
+
} else {
|
682 |
+
$this->error();
|
683 |
+
}
|
684 |
+
}
|
685 |
+
|
686 |
+
/**
|
687 |
+
* Step #3: Choose template
|
688 |
+
*/
|
689 |
+
public function template()
|
690 |
+
{
|
691 |
+
|
692 |
+
$template = new PMXI_Template_Record();
|
693 |
+
$default = array(
|
694 |
+
'title' => '',
|
695 |
+
'content' => '',
|
696 |
+
'name' => '',
|
697 |
+
'is_keep_linebreaks' => 0,
|
698 |
+
'is_leave_html' => 0,
|
699 |
+
'fix_characters' => 0
|
700 |
+
);
|
701 |
+
if ($this->isWizard) {
|
702 |
+
$this->data['post'] = $post = $this->input->post(
|
703 |
+
(isset($_SESSION['pmxi_import']['template']) ? $_SESSION['pmxi_import']['template'] : array())
|
704 |
+
+ $default
|
705 |
+
);
|
706 |
+
} else {
|
707 |
+
$this->data['post'] = $post = $this->input->post(
|
708 |
+
$this->data['import']->template
|
709 |
+
+ $default
|
710 |
+
);
|
711 |
+
}
|
712 |
+
|
713 |
+
if (($load_template = $this->input->post('load_template'))) { // init form with template selected
|
714 |
+
if ( ! $template->getById($load_template)->isEmpty()) {
|
715 |
+
$this->data['post'] = array(
|
716 |
+
'title' => $template->title,
|
717 |
+
'content' => $template->content,
|
718 |
+
'is_keep_linebreaks' => $template->is_keep_linebreaks,
|
719 |
+
'is_leave_html' => $template->is_leave_html,
|
720 |
+
'fix_characters' => $template->fix_characters,
|
721 |
+
'name' => '', // template is always empty
|
722 |
+
);
|
723 |
+
$_SESSION['pmxi_import']['is_loaded_template'] = $load_template;
|
724 |
+
}
|
725 |
+
|
726 |
+
} elseif ($this->input->post('is_submitted')) { // save template submission
|
727 |
+
check_admin_referer('template', '_wpnonce_template');
|
728 |
+
|
729 |
+
if (empty($post['title'])) {
|
730 |
+
$this->errors->add('form-validation', __('Post title is empty', 'pmxi_plugin'));
|
731 |
+
} else {
|
732 |
+
$this->_validate_template($post['title'], 'Post title');
|
733 |
+
}
|
734 |
+
|
735 |
+
if (empty($post['content'])) {
|
736 |
+
$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
|
737 |
+
} else {
|
738 |
+
$this->_validate_template($post['content'], 'Post content');
|
739 |
+
}
|
740 |
+
|
741 |
+
if ( ! $this->errors->get_error_codes()) {
|
742 |
+
if ( ! empty($post['name'])) { // save template in database
|
743 |
+
$template->getByName($post['name'])->set($post)->save();
|
744 |
+
$_SESSION['pmxi_import']['saved_template'] = $template->id;
|
745 |
+
}
|
746 |
+
if ($this->isWizard) {
|
747 |
+
$_SESSION['pmxi_import']['template'] = $post;
|
748 |
+
wp_redirect(add_query_arg('action', 'options', $this->baseUrl)); die();
|
749 |
+
} else {
|
750 |
+
$this->data['import']->set('template', $post)->save();
|
751 |
+
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Template updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
|
752 |
+
}
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
if (user_can_richedit()) {
|
757 |
+
wp_enqueue_script('editor');
|
758 |
+
}
|
759 |
+
wp_enqueue_script('word-count');
|
760 |
+
add_thickbox();
|
761 |
+
wp_enqueue_script('media-upload');
|
762 |
+
add_action('admin_print_footer_scripts', 'wp_tiny_mce', 25);
|
763 |
+
wp_enqueue_script('quicktags');
|
764 |
+
$this->render();
|
765 |
+
}
|
766 |
+
|
767 |
+
protected function _validate_template($text, $field_title)
|
768 |
+
{
|
769 |
+
try {
|
770 |
+
$scanner = new XmlImportTemplateScanner();
|
771 |
+
$tokens = $scanner->scan(new XmlImportStringReader($text));
|
772 |
+
$parser = new XmlImportTemplateParser($tokens);
|
773 |
+
$tree = $parser->parse();
|
774 |
+
} catch (XmlImportException $e) {
|
775 |
+
$this->errors->add('form-validation', sprintf(__('%s template is invalid: %s', 'pmxi_plugin'), $field_title, $e->getMessage()));
|
776 |
+
}
|
777 |
+
}
|
778 |
+
|
779 |
+
/**
|
780 |
+
* Preview selected xml tag (called with ajax from `template` step)
|
781 |
+
*/
|
782 |
+
public function tag()
|
783 |
+
{
|
784 |
+
|
785 |
+
$wp_uploads = wp_upload_dir();
|
786 |
+
|
787 |
+
if (empty($this->data['elements']->length))
|
788 |
+
{
|
789 |
+
$update_previous = new PMXI_Import_Record();
|
790 |
+
if ($update_previous->getById($this->input->get('id'))) {
|
791 |
+
$_SESSION['pmxi_import'] = array(
|
792 |
+
'update_previous' => $update_previous->id,
|
793 |
+
'xpath' => $update_previous->xpath,
|
794 |
+
'template' => $update_previous->template,
|
795 |
+
'options' => $update_previous->options,
|
796 |
+
);
|
797 |
+
$history = new PMXI_File_List();
|
798 |
+
$history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $update_previous->id), 'id DESC');
|
799 |
+
if ($history->count()){
|
800 |
+
$history_file = new PMXI_File_Record();
|
801 |
+
$history_file->getBy('id', $history[0]['id']);
|
802 |
+
|
803 |
+
if ($update_previous->large_import == 'Yes'){
|
804 |
+
$_SESSION['pmxi_import']['filePath'] = $history_file->path;
|
805 |
+
if (!@file_exists($_SESSION['pmxi_import']['filePath'])) $_SESSION['pmxi_import']['filePath'] = $wp_uploads['basedir'] . '/wpallimport_history/' . $history_file->id;
|
806 |
+
$_SESSION['pmxi_import']['source']['root_element'] = $update_previous->root_element;
|
807 |
+
$_SESSION['pmxi_import']['large_file'] = true;
|
808 |
+
$_SESSION['pmxi_import']['count'] = $update_previous->count;
|
809 |
+
}
|
810 |
+
else{
|
811 |
+
$_SESSION['pmxi_import']['xml'] = @file_get_contents($history_file->path);
|
812 |
+
$this->data['dom'] = $dom = new DOMDocument('1.0', 'UTF-8');
|
813 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $_SESSION['pmxi_import']['xml']));
|
814 |
+
$xpath = new DOMXPath($dom);
|
815 |
+
|
816 |
+
$this->data['elements'] = $elements = $xpath->query($update_previous->xpath);
|
817 |
+
if ( !$elements->length ) $this->data['elements'] = $elements = $xpath->query('.');
|
818 |
+
}
|
819 |
+
}
|
820 |
+
|
821 |
+
} else {
|
822 |
+
$_SESSION['pmxi_import']['update_previous'] = '';
|
823 |
+
}
|
824 |
+
}
|
825 |
+
|
826 |
+
$this->data['tagno'] = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! $_SESSION['pmxi_import']['large_file'] ) ? $this->data['elements']->length : $_SESSION['pmxi_import']['count']);
|
827 |
+
|
828 |
+
if ($_SESSION['pmxi_import']['large_file'] and $this->data['tagno']){
|
829 |
+
$loop = 1;
|
830 |
+
$_SESSION['pmxi_import']['local_paths'] = (!empty($_SESSION['pmxi_import']['local_paths'])) ? $_SESSION['pmxi_import']['local_paths'] : array($_SESSION['pmxi_import']['filePath']);
|
831 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
832 |
+
if (file_exists($path)){
|
833 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element']));
|
834 |
+
// loop through the file until all lines are read
|
835 |
+
while ($xml = $file->read()) {
|
836 |
+
if (!empty($xml))
|
837 |
+
{
|
838 |
+
$xml = $file->encoding . "\n" . $xml;
|
839 |
+
PMXI_Import_Record::preprocessXml($xml);
|
840 |
+
|
841 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
842 |
+
$old = libxml_use_internal_errors(true);
|
843 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
844 |
+
libxml_use_internal_errors($old);
|
845 |
+
$xpath = new DOMXPath($dom);
|
846 |
+
if (($this->data['elements'] = $elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
847 |
+
if ($loop == $this->data['tagno']){
|
848 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
849 |
+
break;
|
850 |
+
} else unset($dom, $xpath, $elements);
|
851 |
+
$loop++;
|
852 |
+
}
|
853 |
+
}
|
854 |
+
}
|
855 |
+
unset($file);
|
856 |
+
}
|
857 |
+
}
|
858 |
+
}
|
859 |
+
|
860 |
+
$this->render();
|
861 |
+
}
|
862 |
+
|
863 |
+
/**
|
864 |
+
* Preview future post based on current template and tag (called with ajax from `template` step)
|
865 |
+
*/
|
866 |
+
public function preview()
|
867 |
+
{
|
868 |
+
$post = $this->input->post(array(
|
869 |
+
'title' => '',
|
870 |
+
'content' => '',
|
871 |
+
'is_keep_linebreaks' => 0,
|
872 |
+
'is_leave_html' => 0,
|
873 |
+
'fix_characters' => 0
|
874 |
+
));
|
875 |
+
$wp_uploads = wp_upload_dir();
|
876 |
+
|
877 |
+
$tagno = min(max(intval($this->input->getpost('tagno', 1)), 1), ( ! $_SESSION['pmxi_import']['large_file']) ? $this->data['elements']->length : $_SESSION['pmxi_import']['count']);
|
878 |
+
if ($_SESSION['pmxi_import']['large_file']){
|
879 |
+
$loop = 1;
|
880 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
881 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
|
882 |
+
// loop through the file until all lines are read
|
883 |
+
while ($xml = $file->read()) {
|
884 |
+
if (!empty($xml))
|
885 |
+
{
|
886 |
+
$xml = $file->encoding . "\n" . $xml;
|
887 |
+
PMXI_Import_Record::preprocessXml($xml);
|
888 |
+
|
889 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
890 |
+
$old = libxml_use_internal_errors(true);
|
891 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
892 |
+
libxml_use_internal_errors($old);
|
893 |
+
$xpath = new DOMXPath($dom);
|
894 |
+
if (($this->data['elements'] = $elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
895 |
+
if ( $loop == $tagno ) {
|
896 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
897 |
+
break;
|
898 |
+
}
|
899 |
+
unset($dom, $xpath, $elements);
|
900 |
+
$loop++;
|
901 |
+
}
|
902 |
+
}
|
903 |
+
}
|
904 |
+
unset($file);
|
905 |
+
}
|
906 |
+
$tagno = 1;
|
907 |
+
}
|
908 |
+
$xpath = "(" . $_SESSION['pmxi_import']['xpath'] . ")[$tagno]";
|
909 |
+
// validate
|
910 |
+
try {
|
911 |
+
if (empty($post['title'])) {
|
912 |
+
$this->errors->add('form-validation', __('Post title is empty', 'pmxi_plugin'));
|
913 |
+
} else {
|
914 |
+
list($this->data['title']) = XmlImportParser::factory($_SESSION['pmxi_import']['xml'], $xpath, $post['title'], $file)->parse(); unlink($file);
|
915 |
+
if ( ! isset($this->data['title']) or '' == strval(trim(strip_tags($this->data['title'], '<img><input><textarea><iframe><object><embed>')))) {
|
916 |
+
$this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post title is empty', 'pmxi_plugin'));
|
917 |
+
}
|
918 |
+
else $this->data['title'] = ($post['fix_characters']) ? utf8_encode(html_entity_decode($this->data['title'])) : (($post['is_leave_html']) ? html_entity_decode($this->data['title']) : $this->data['title']);
|
919 |
+
}
|
920 |
+
} catch (XmlImportException $e) {
|
921 |
+
$this->errors->add('form-validation', sprintf(__('Error parsing title: %s', 'pmxi_plugin'), $e->getMessage()));
|
922 |
+
}
|
923 |
+
try {
|
924 |
+
if (empty($post['content'])) {
|
925 |
+
$this->errors->add('form-validation', __('Post content is empty', 'pmxi_plugin'));
|
926 |
+
} else {
|
927 |
+
list($this->data['content']) = XmlImportParser::factory($post['is_keep_linebreaks'] ? $_SESSION['pmxi_import']['xml'] : preg_replace('%\r\n?|\n%', ' ', $_SESSION['pmxi_import']['xml']), $xpath, $post['content'], $file)->parse(); unlink($file);
|
928 |
+
if ( ! isset($this->data['content']) or '' == strval(trim(strip_tags($this->data['content'], '<img><input><textarea><iframe><object><embed>')))) {
|
929 |
+
$this->errors->add('xml-parsing', __('<strong>Warning</strong>: resulting post content is empty', 'pmxi_plugin'));
|
930 |
+
}
|
931 |
+
else $this->data['content'] = ($post['fix_characters']) ? utf8_encode(html_entity_decode($this->data['content'])) : (($post['is_leave_html']) ? html_entity_decode($this->data['content']) : $this->data['content']);
|
932 |
+
}
|
933 |
+
} catch (XmlImportException $e) {
|
934 |
+
$this->errors->add('form-validation', sprintf(__('Error parsing content: %s', 'pmxi_plugin'), $e->getMessage()));
|
935 |
+
}
|
936 |
+
|
937 |
+
$this->render();
|
938 |
+
}
|
939 |
+
|
940 |
+
/**
|
941 |
+
* Step #4: Options
|
942 |
+
*/
|
943 |
+
public function options()
|
944 |
+
{
|
945 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
946 |
+
|
947 |
+
$default = PMXI_Plugin::get_default_import_options();
|
948 |
+
|
949 |
+
if ($this->isWizard) {
|
950 |
+
$this->data['source_type'] = $_SESSION['pmxi_import']['source']['type'];
|
951 |
+
$default['unique_key'] = $_SESSION['pmxi_import']['template']['title'];
|
952 |
+
|
953 |
+
// auto searching ID element
|
954 |
+
if (!empty($this->data['dom'])){
|
955 |
+
$this->find_unique_key($this->data['dom']->documentElement);
|
956 |
+
if (!empty($this->_unique_key)){
|
957 |
+
$id_finded = false;
|
958 |
+
foreach ($this->_unique_key as $key) {
|
959 |
+
if (stripos($key, 'id') !== false) {
|
960 |
+
$default['unique_key'] .= ' - {'.$key.'[1]}';
|
961 |
+
$id_finded = true;
|
962 |
+
break;
|
963 |
+
}
|
964 |
+
}
|
965 |
+
if (!$id_finded){
|
966 |
+
foreach ($this->_unique_key as $key) {
|
967 |
+
if (stripos($key, 'url') !== false) {
|
968 |
+
$default['unique_key'] .= ' - {'.$key.'[1]}';
|
969 |
+
$id_finded = true;
|
970 |
+
break;
|
971 |
+
}
|
972 |
+
}
|
973 |
+
}
|
974 |
+
}
|
975 |
+
}
|
976 |
+
|
977 |
+
if ( class_exists('PMWI_Plugin') )
|
978 |
+
$post = $this->input->post(
|
979 |
+
(isset($_SESSION['pmxi_import']['options']) ? $_SESSION['pmxi_import']['options'] : array())
|
980 |
+
+ $default
|
981 |
+
+ PMWI_Plugin::get_default_import_options()
|
982 |
+
);
|
983 |
+
else
|
984 |
+
$post = $this->input->post(
|
985 |
+
(isset($_SESSION['pmxi_import']['options']) ? $_SESSION['pmxi_import']['options'] : array())
|
986 |
+
+ $default
|
987 |
+
);
|
988 |
+
|
989 |
+
$scheduled = $this->input->post(array(
|
990 |
+
'is_scheduled' => ! empty($_SESSION['pmxi_import']['scheduled']),
|
991 |
+
'scheduled_period' => ! empty($_SESSION['pmxi_import']['scheduled']) ? $_SESSION['pmxi_import']['scheduled'] : '0 0 * * *', // daily by default
|
992 |
+
));
|
993 |
+
|
994 |
+
} else {
|
995 |
+
$this->data['source_type'] = $this->data['import']->type;
|
996 |
+
if ( class_exists('PMWI_Plugin') )
|
997 |
+
$post = $this->input->post(
|
998 |
+
$this->data['import']->options
|
999 |
+
+ $default
|
1000 |
+
+ PMWI_Plugin::get_default_import_options()
|
1001 |
+
);
|
1002 |
+
else
|
1003 |
+
$post = $this->input->post(
|
1004 |
+
$this->data['import']->options
|
1005 |
+
+ $default
|
1006 |
+
);
|
1007 |
+
$scheduled = $this->input->post(array(
|
1008 |
+
'is_scheduled' => ! empty($this->data['import']->scheduled),
|
1009 |
+
'scheduled_period' => ! empty($this->data['import']->scheduled) ? $this->data['import']->scheduled : '0 0 * * *', // daily by default
|
1010 |
+
));
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
$this->data['post'] =& $post;
|
1014 |
+
$this->data['scheduled'] =& $scheduled;
|
1015 |
+
$this->data['is_loaded_template'] = $_SESSION['pmxi_import']['is_loaded_template'];
|
1016 |
+
|
1017 |
+
// Get All meta keys in the system
|
1018 |
+
$this->data['meta_keys'] = $keys = new PMXI_Model_List();
|
1019 |
+
$keys->setTable(PMXI_Plugin::getInstance()->getWPPrefix() . 'postmeta');
|
1020 |
+
$keys->setColumns('meta_id', 'meta_key')->getBy(NULL, "meta_id", NULL, NULL, "meta_key");
|
1021 |
+
|
1022 |
+
$load_template = $this->input->post('load_template');
|
1023 |
+
if ($load_template) { // init form with template selected
|
1024 |
+
$_SESSION['pmxi_import']['is_loaded_template'] = $load_template;
|
1025 |
+
$template = new PMXI_Template_Record();
|
1026 |
+
if ( ! $template->getById($load_template)->isEmpty()) {
|
1027 |
+
$post = (!empty($template->options) ? $template->options : array()) + $default;
|
1028 |
+
$scheduled = array(
|
1029 |
+
'is_scheduled' => ! empty($template->scheduled),
|
1030 |
+
'scheduled_period' => ! empty($template->scheduled) ? $template->scheduled : '0 0 * * *', // daily by default
|
1031 |
+
);
|
1032 |
+
}
|
1033 |
+
} elseif ($load_template == -1){
|
1034 |
+
$_SESSION['pmxi_import']['is_loaded_template'] = 0;
|
1035 |
+
|
1036 |
+
$post = $default;
|
1037 |
+
$scheduled = $this->input->post(array(
|
1038 |
+
'is_scheduled' => ! empty($post['scheduled']),
|
1039 |
+
'scheduled_period' => ! empty($post['scheduled']) ? $post['scheduled_period'] : '0 0 * * *', // daily by default
|
1040 |
+
));
|
1041 |
+
|
1042 |
+
} elseif ($this->input->post('is_submitted')) {
|
1043 |
+
check_admin_referer('options', '_wpnonce_options');
|
1044 |
+
|
1045 |
+
if ( $post['type'] == "post" and $post['custom_type'] == "product" and class_exists('PMWI_Plugin')){
|
1046 |
+
// remove entires where both custom_name and custom_value are empty
|
1047 |
+
$not_empty = array_flip(array_values(array_merge(array_keys(array_filter($post['attribute_name'], 'strlen')), array_keys(array_filter($post['attribute_value'], 'strlen')))));
|
1048 |
+
|
1049 |
+
$post['attribute_name'] = array_intersect_key($post['attribute_name'], $not_empty);
|
1050 |
+
$post['attribute_value'] = array_intersect_key($post['attribute_value'], $not_empty);
|
1051 |
+
|
1052 |
+
// validate
|
1053 |
+
if (array_keys(array_filter($post['attribute_name'], 'strlen')) != array_keys(array_filter($post['attribute_value'], 'strlen'))) {
|
1054 |
+
$this->errors->add('form-validation', __('Both name and value must be set for all woocommerce attributes', 'pmxi_plugin'));
|
1055 |
+
} else {
|
1056 |
+
foreach ($post['attribute_name'] as $attribute_name) {
|
1057 |
+
$this->_validate_template($attribute_name, __('Attribute Field Name', 'pmxi_plugin'));
|
1058 |
+
}
|
1059 |
+
foreach ($post['attribute_value'] as $custom_value) {
|
1060 |
+
$this->_validate_template($custom_value, __('Attribute Field Value', 'pmxi_plugin'));
|
1061 |
+
}
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
if ('page' == $post['type'] and ! preg_match('%^(-?\d+)?$%', $post['order'])) {
|
1067 |
+
$this->errors->add('form-validation', __('Order must be an integer number', 'pmxi_plugin'));
|
1068 |
+
}
|
1069 |
+
if ('post' == $post['type']) {
|
1070 |
+
/*'' == $post['categories'] or $this->_validate_template($post['categories'], __('Categories', 'pmxi_plugin'));*/
|
1071 |
+
'' == $post['tags'] or $this->_validate_template($post['tags'], __('Tags', 'pmxi_plugin'));
|
1072 |
+
}
|
1073 |
+
if ('specific' == $post['date_type']) {
|
1074 |
+
'' == $post['date'] or $this->_validate_template($post['date'], __('Date', 'pmxi_plugin'));
|
1075 |
+
} else {
|
1076 |
+
'' == $post['date_start'] or $this->_validate_template($post['date_start'], __('Start Date', 'pmxi_plugin'));
|
1077 |
+
'' == $post['date_end'] or $this->_validate_template($post['date_end'], __('Start Date', 'pmxi_plugin'));
|
1078 |
+
}
|
1079 |
+
if ('' == $post['tags_delim']) {
|
1080 |
+
$this->errors->add('form-validation', __('Tag list delimiter must cannot be empty', 'pmxi_plugin'));
|
1081 |
+
}
|
1082 |
+
if ($post['is_import_specified']) {
|
1083 |
+
if (empty($post['import_specified'])) {
|
1084 |
+
$this->errors->add('form-validation', __('Records to import must be specified or uncheck `Import only specified records` option to process all records', 'pmxi_plugin'));
|
1085 |
+
} else {
|
1086 |
+
$chanks = preg_split('% *, *%', $post['import_specified']);
|
1087 |
+
foreach ($chanks as $chank) {
|
1088 |
+
if ( ! preg_match('%^([1-9]\d*)( *- *([1-9]\d*))?$%', $chank, $mtch)) {
|
1089 |
+
$this->errors->add('form-validation', __('Wrong format of `Import only specified records` value', 'pmxi_plugin'));
|
1090 |
+
break;
|
1091 |
+
} elseif ($this->isWizard and empty($_SESSION['pmxi_import']['large_file']) and (intval($mtch[1]) > $this->data['elements']->length or isset($mtch[3]) and intval($mtch[3]) > $this->data['elements']->length)) {
|
1092 |
+
$this->errors->add('form-validation', __('One of the numbers in `Import only specified records` value exceeds record quantity in XML file', 'pmxi_plugin'));
|
1093 |
+
break;
|
1094 |
+
}
|
1095 |
+
}
|
1096 |
+
}
|
1097 |
+
}
|
1098 |
+
if ('' == $post['unique_key']) {
|
1099 |
+
$this->errors->add('form-validation', __('Expression for `Post Unique Key` must be set, use the same expression as specified for post title if you are not sure what to put there', 'pmxi_plugin'));
|
1100 |
+
} else {
|
1101 |
+
$this->_validate_template($post['unique_key'], __('Post Unique Key', 'pmxi_plugin'));
|
1102 |
+
}
|
1103 |
+
if ( $post['is_duplicates'] and 'custom field' == $post['duplicate_indicator']){
|
1104 |
+
if ('' == $post['custom_duplicate_name'])
|
1105 |
+
$this->errors->add('form-validation', __('Custom field name must be specified.', 'pmxi_plugin'));
|
1106 |
+
if ('' == $post['custom_duplicate_value'])
|
1107 |
+
$this->errors->add('form-validation', __('Custom field value must be specified.', 'pmxi_plugin'));
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
if ( ! $this->errors->get_error_codes()) { // no validation errors found
|
1111 |
+
// assign some defaults
|
1112 |
+
'' !== $post['date'] or $post['date'] = 'now';
|
1113 |
+
'' !== $post['date_start'] or $post['date_start'] = 'now';
|
1114 |
+
'' !== $post['date_end'] or $post['date_end'] = 'now';
|
1115 |
+
|
1116 |
+
if ($this->isWizard) {
|
1117 |
+
$_SESSION['pmxi_import']['options'] = $post;
|
1118 |
+
$_SESSION['pmxi_import']['scheduled'] = $scheduled['is_scheduled'] ? $scheduled['scheduled_period'] : '';
|
1119 |
+
|
1120 |
+
if ( $this->input->post('name')) { // save template in database
|
1121 |
+
$template = new PMXI_Template_Record();
|
1122 |
+
|
1123 |
+
$template->getByName($this->input->post('name'))->set(array(
|
1124 |
+
'name' => $this->input->post('name'),
|
1125 |
+
'options' => $post,
|
1126 |
+
'scheduled' => (($scheduled['is_scheduled']) ? $scheduled['scheduled_period'] : '')
|
1127 |
+
))->save();
|
1128 |
+
}
|
1129 |
+
|
1130 |
+
if ( ! $this->input->post('save_only')) {
|
1131 |
+
wp_redirect(add_query_arg('action', 'process', $this->baseUrl)); die();
|
1132 |
+
} else {
|
1133 |
+
$import = $this->data['update_previous'];
|
1134 |
+
$is_update = ! $import->isEmpty();
|
1135 |
+
$import->set(
|
1136 |
+
$_SESSION['pmxi_import']['source']
|
1137 |
+
+ array(
|
1138 |
+
'xpath' => $_SESSION['pmxi_import']['xpath'],
|
1139 |
+
'template' => $_SESSION['pmxi_import']['template'],
|
1140 |
+
'options' => $_SESSION['pmxi_import']['options'],
|
1141 |
+
'scheduled' => $_SESSION['pmxi_import']['scheduled'],
|
1142 |
+
'count' => $_SESSION['pmxi_import']['count'],
|
1143 |
+
'friendly_name' => $this->data['post']['friendly_name'],
|
1144 |
+
)
|
1145 |
+
)->save();
|
1146 |
+
|
1147 |
+
$history_file = new PMXI_File_Record();
|
1148 |
+
$history_file->set(array(
|
1149 |
+
'name' => $import->name,
|
1150 |
+
'import_id' => $import->id,
|
1151 |
+
'path' => $_SESSION['pmxi_import']['filePath'],
|
1152 |
+
'contents' => $_SESSION['pmxi_import']['xml'],
|
1153 |
+
'registered_on' => date('Y-m-d H:i:s'),
|
1154 |
+
))->save();
|
1155 |
+
unset($_SESSION['pmxi_import']); // clear session data
|
1156 |
+
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode($is_update ? __('Import updated', 'pmxi_plugin') : __('Import created', 'pmxi_plugin'))), admin_url('admin.php'))); die();
|
1157 |
+
}
|
1158 |
+
} else {
|
1159 |
+
|
1160 |
+
$this->data['import']->set('options', $post)->set( array( 'scheduled' => $scheduled['is_scheduled'] ? $scheduled['scheduled_period'] : '', 'friendly_name' => $this->data['post']['friendly_name'] ) )->save();
|
1161 |
+
|
1162 |
+
wp_redirect(add_query_arg(array('page' => 'pmxi-admin-manage', 'pmlc_nt' => urlencode(__('Options updated', 'pmxi_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))); die();
|
1163 |
+
}
|
1164 |
+
}
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
if ( $post['type'] == "product" and class_exists('PMWI_Plugin'))
|
1168 |
+
{
|
1169 |
+
! empty($post['attribute_name']) or $post['attribute_name'] = array('') and $post['attribute_value'] = array('');
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
$this->render();
|
1173 |
+
}
|
1174 |
+
|
1175 |
+
/**
|
1176 |
+
* Import processing step (status console)
|
1177 |
+
*/
|
1178 |
+
public function process($save_history = true)
|
1179 |
+
{
|
1180 |
+
$wp_uploads = wp_upload_dir();
|
1181 |
+
|
1182 |
+
set_time_limit(0);
|
1183 |
+
|
1184 |
+
$import = $this->data['update_previous'];
|
1185 |
+
$import->set(
|
1186 |
+
(empty($_SESSION['pmxi_import']['source']) ? array() : $_SESSION['pmxi_import']['source'])
|
1187 |
+
+ array(
|
1188 |
+
'xpath' => $_SESSION['pmxi_import']['xpath'],
|
1189 |
+
'template' => $_SESSION['pmxi_import']['template'],
|
1190 |
+
'options' => $_SESSION['pmxi_import']['options'],
|
1191 |
+
'scheduled' => $_SESSION['pmxi_import']['scheduled'],
|
1192 |
+
'count' => $_SESSION['pmxi_import']['count'],
|
1193 |
+
'friendly_name' => $_SESSION['pmxi_import']['options']['friendly_name'],
|
1194 |
+
)
|
1195 |
+
);
|
1196 |
+
|
1197 |
+
if ( ! PMXI_Plugin::is_ajax()) {
|
1198 |
+
|
1199 |
+
// Save import history
|
1200 |
+
if ( $_SESSION['pmxi_import']['chunk_number'] === 1 ){
|
1201 |
+
// store import info in database
|
1202 |
+
$import->set(array(
|
1203 |
+
'imported' => 0,
|
1204 |
+
'created' => 0,
|
1205 |
+
'updated' => 0,
|
1206 |
+
'skipped' => 0
|
1207 |
+
))->save();
|
1208 |
+
|
1209 |
+
do_action( 'pmxi_before_xml_import', $import->id );
|
1210 |
+
|
1211 |
+
if ($_SESSION['pmxi_import']['large_file']) $_SESSION['pmxi_import']['update_previous'] = $import->id;
|
1212 |
+
|
1213 |
+
// unlick previous files
|
1214 |
+
$history = new PMXI_File_List();
|
1215 |
+
$history->setColumns('id', 'name', 'registered_on', 'path')->getBy(array('import_id' => $import->id), 'id DESC');
|
1216 |
+
if ($history->count()){
|
1217 |
+
foreach ($history as $file){
|
1218 |
+
if (@file_exists($file['path']) and $file['path'] != $_SESSION['pmxi_import']['filePath']) @unlink($file['path']);
|
1219 |
+
$history_file = new PMXI_File_Record();
|
1220 |
+
$history_file->getBy('id', $file['id']);
|
1221 |
+
if ( ! $history_file->isEmpty()) $history_file->delete();
|
1222 |
+
}
|
1223 |
+
}
|
1224 |
+
|
1225 |
+
if ($save_history){
|
1226 |
+
$history_file = new PMXI_File_Record();
|
1227 |
+
$history_file->set(array(
|
1228 |
+
'name' => $import->name,
|
1229 |
+
'import_id' => $import->id,
|
1230 |
+
'path' => $_SESSION['pmxi_import']['filePath'],
|
1231 |
+
'contents' => $_SESSION['pmxi_import']['xml'],
|
1232 |
+
'registered_on' => date('Y-m-d H:i:s'),
|
1233 |
+
))->save();
|
1234 |
+
}
|
1235 |
+
}
|
1236 |
+
|
1237 |
+
$this->render();
|
1238 |
+
wp_ob_end_flush_all(); flush();
|
1239 |
+
}
|
1240 |
+
|
1241 |
+
// create chunks
|
1242 |
+
if ($_SESSION['pmxi_import']['large_file'] and $_SESSION['pmxi_import']['chunk_number'] === 1 and $_SESSION['pmxi_import']['options']['create_chunks'] and ! PMXI_Plugin::is_ajax()){
|
1243 |
+
|
1244 |
+
$_SESSION['pmxi_import']['chunks_files'] = array();
|
1245 |
+
|
1246 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
1247 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']));
|
1248 |
+
$new_chunk = true;
|
1249 |
+
$loop = 0;
|
1250 |
+
$o = false;
|
1251 |
+
|
1252 |
+
// loop through the file until all lines are read
|
1253 |
+
while ($xml = $file->read()) {
|
1254 |
+
|
1255 |
+
if (!empty($xml))
|
1256 |
+
{
|
1257 |
+
|
1258 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1259 |
+
|
1260 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
1261 |
+
$old = libxml_use_internal_errors(true);
|
1262 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
1263 |
+
libxml_use_internal_errors($old);
|
1264 |
+
$xpath = new DOMXPath($dom);
|
1265 |
+
if (($elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
1266 |
+
|
1267 |
+
if ($new_chunk){
|
1268 |
+
$tmpname = $wp_uploads['path'] .'/'. wp_unique_filename($wp_uploads['path'], basename($path));
|
1269 |
+
$c = fopen($tmpname, 'w');
|
1270 |
+
fwrite($c, $file->encoding . "\n" . "<".$_SESSION['pmxi_import']['source']['root_element'] ."s>\n");
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
fwrite($c, $xml . "\n");
|
1274 |
+
|
1275 |
+
if ($loop == $_SESSION['pmxi_import']['options']['records_per_request'] - 1) {
|
1276 |
+
fwrite($c, "</".$_SESSION['pmxi_import']['source']['root_element'] . "s>");
|
1277 |
+
fclose($c);
|
1278 |
+
$_SESSION['pmxi_import']['chunks_files'][] = $tmpname;
|
1279 |
+
|
1280 |
+
$loop = 0;
|
1281 |
+
$new_chunk = true;
|
1282 |
+
}
|
1283 |
+
else {
|
1284 |
+
$loop++;
|
1285 |
+
$new_chunk = false;
|
1286 |
+
}
|
1287 |
+
}
|
1288 |
+
}
|
1289 |
+
}
|
1290 |
+
if ($loop){
|
1291 |
+
fwrite($c, "</".$_SESSION['pmxi_import']['source']['root_element'] . "s>");
|
1292 |
+
fclose($c);
|
1293 |
+
$_SESSION['pmxi_import']['chunks_files'][] = $tmpname;
|
1294 |
+
}
|
1295 |
+
}
|
1296 |
+
$_SESSION['pmxi_import']['local_paths'] = $_SESSION['pmxi_import']['chunks_files'];
|
1297 |
+
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
$logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; if ( "" != strip_tags(pmxi_strip_tags_content($m))) { $_SESSION[\'pmxi_import\'][\'log\'] .= "<p>".strip_tags(pmxi_strip_tags_content($m))."</p>"; flush(); }');
|
1301 |
+
|
1302 |
+
$_SESSION['pmxi_import']['start_time'] = (empty($_SESSION['pmxi_import']['start_time'])) ? time() : $_SESSION['pmxi_import']['start_time'];
|
1303 |
+
|
1304 |
+
in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, __('Reading files for import...', 'pmxi_plugin'));
|
1305 |
+
in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, sprintf(_n('%s file found', '%s files found', count($_SESSION['pmxi_import']['local_paths']), 'pmxi_plugin'), count($_SESSION['pmxi_import']['local_paths'])));
|
1306 |
+
in_array($import->type, array('ftp')) and !PMXI_Plugin::is_ajax() and $logger and call_user_func($logger, sprintf(__('Importing %s (%s of %s)', 'pmxi_plugin'), $_SESSION['pmxi_import']['local_paths'][0], 1, count($_SESSION['pmxi_import']['local_paths'])));
|
1307 |
+
|
1308 |
+
if (empty($_SESSION['pmxi_import']['large_file'])){
|
1309 |
+
$import->process($_SESSION['pmxi_import']['xml'], $logger, false);
|
1310 |
+
}
|
1311 |
+
elseif (PMXI_Plugin::is_ajax()) {
|
1312 |
+
|
1313 |
+
$_SESSION['pmxi_import']['current_post_ids'] = (empty($_SESSION['pmxi_import']['current_post_ids'])) ? array() : $_SESSION['pmxi_import']['current_post_ids'];
|
1314 |
+
|
1315 |
+
$_SESSION['pmxi_import']['pointer'] = (empty($_SESSION['pmxi_import']['pointer'])) ? 0 : $_SESSION['pmxi_import']['pointer'];
|
1316 |
+
|
1317 |
+
$loop = 0;
|
1318 |
+
|
1319 |
+
foreach ($_SESSION['pmxi_import']['local_paths'] as $key => $path) {
|
1320 |
+
|
1321 |
+
if ($_SESSION['pmxi_import']['options']['create_chunks'] and $_SESSION['pmxi_import']['action'] != 'continue'){
|
1322 |
+
|
1323 |
+
if ($_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] == $_SESSION['pmxi_import']['count']) break;
|
1324 |
+
|
1325 |
+
ob_start();
|
1326 |
+
|
1327 |
+
$xml = file_get_contents($path);
|
1328 |
+
|
1329 |
+
if (!empty($xml))
|
1330 |
+
{
|
1331 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1332 |
+
|
1333 |
+
$import->set(array('xpath' => '/' . $_SESSION['pmxi_import']['source']['root_element'] . 's' . $_SESSION['pmxi_import']['xpath']))->save();
|
1334 |
+
$import->process($xml, $logger, $_SESSION['pmxi_import']['chunk_number']);
|
1335 |
+
$import->set(array('xpath' => $_SESSION['pmxi_import']['xpath']))->save();
|
1336 |
+
|
1337 |
+
array_shift($_SESSION['pmxi_import']['local_paths']);
|
1338 |
+
if (!empty($_SESSION['pmxi_import']['chunks_files'])) {
|
1339 |
+
$imported_file = array_shift($_SESSION['pmxi_import']['chunks_files']);
|
1340 |
+
@unlink($imported_file);
|
1341 |
+
}
|
1342 |
+
}
|
1343 |
+
|
1344 |
+
exit(ob_get_clean());
|
1345 |
+
}
|
1346 |
+
else{
|
1347 |
+
|
1348 |
+
$file = new PMXI_Chunk($path, array('element' => $_SESSION['pmxi_import']['source']['root_element'], 'path' => $wp_uploads['path']), $_SESSION['pmxi_import']['pointer']);
|
1349 |
+
|
1350 |
+
// loop through the file until all lines are read
|
1351 |
+
while ($xml = $file->read()) {
|
1352 |
+
|
1353 |
+
if (!empty($xml))
|
1354 |
+
{
|
1355 |
+
$xml = $file->encoding . "\n" . $xml;
|
1356 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1357 |
+
|
1358 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
1359 |
+
$old = libxml_use_internal_errors(true);
|
1360 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
1361 |
+
libxml_use_internal_errors($old);
|
1362 |
+
$xpath = new DOMXPath($dom);
|
1363 |
+
if (($this->data['elements'] = $elements = @$xpath->query($_SESSION['pmxi_import']['xpath'])) and $elements->length){
|
1364 |
+
$_SESSION['pmxi_import']['pointer'] = $file->pointer;
|
1365 |
+
$_SESSION['pmxi_import']['xml'] = $xml;
|
1366 |
+
if ( ! $loop ) ob_start();
|
1367 |
+
$import->process($_SESSION['pmxi_import']['xml'], $logger, $_SESSION['pmxi_import']['chunk_number']);
|
1368 |
+
if ( $loop == $_SESSION['pmxi_import']['options']['records_per_request'] - 1 ) exit(ob_get_clean());
|
1369 |
+
$loop++;
|
1370 |
+
}
|
1371 |
+
}
|
1372 |
+
|
1373 |
+
if (($_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] == $_SESSION['pmxi_import']['count']) and !in_array($import->type, array('ftp'))){
|
1374 |
+
$_SESSION['pmxi_import']['pointer'] = 0;
|
1375 |
+
array_shift($_SESSION['pmxi_import']['local_paths']);
|
1376 |
+
exit(ob_get_clean());
|
1377 |
+
}
|
1378 |
+
}
|
1379 |
+
|
1380 |
+
if (in_array($import->type, array('ftp'))) {
|
1381 |
+
$_SESSION['pmxi_import']['pointer'] = 0;
|
1382 |
+
array_shift($_SESSION['pmxi_import']['local_paths']);
|
1383 |
+
if (!empty($_SESSION['pmxi_import']['local_paths'])) {
|
1384 |
+
$logger and call_user_func($logger, sprintf(__('Importing %s', 'pmxi_plugin'), $_SESSION['pmxi_import']['local_paths'][0]));
|
1385 |
+
}
|
1386 |
+
exit(ob_get_clean());
|
1387 |
+
}
|
1388 |
+
}
|
1389 |
+
}
|
1390 |
+
}
|
1391 |
+
|
1392 |
+
if (! $_SESSION['pmxi_import']['large_file'] or PMXI_Plugin::is_ajax()){
|
1393 |
+
|
1394 |
+
// Save import process log
|
1395 |
+
$log_file = $wp_uploads['basedir'] . '/wpallimport_logs/' . $import->id . '.html';
|
1396 |
+
if (file_exists($log_file)) unlink($log_file);
|
1397 |
+
@file_put_contents($log_file, $_SESSION['pmxi_import']['log']);
|
1398 |
+
|
1399 |
+
if (!empty($_SESSION['pmxi_import'])) do_action( 'pmxi_after_xml_import', $import->id );
|
1400 |
+
|
1401 |
+
// clear import session
|
1402 |
+
unset($_SESSION['pmxi_import']); // clear session data (prevent from reimporting the same data on page refresh)
|
1403 |
+
|
1404 |
+
// [indicate in header process is complete]
|
1405 |
+
$msg = addcslashes(__('Complete', 'pmxi_plugin'), "'\n\r");
|
1406 |
+
|
1407 |
+
delete_option('category_children');
|
1408 |
+
|
1409 |
+
ob_start();
|
1410 |
+
|
1411 |
+
echo '<a id="download_pmxi_log" class="update" href="'.esc_url(add_query_arg(array('id' => $import->id, 'action' => 'log', 'page' => 'pmxi-admin-manage'), $this->baseUrl)).'">Download log</a>';
|
1412 |
+
echo <<<COMPLETE
|
1413 |
+
<script type="text/javascript">
|
1414 |
+
//<![CDATA[
|
1415 |
+
(function($){
|
1416 |
+
var percents = $('.import_percent:last').html();
|
1417 |
+
if (percents != null && percents != ''){
|
1418 |
+
$('#center_progress').html($('.import_process_bar:last').html());
|
1419 |
+
$('#right_progress').html(percents + '%');
|
1420 |
+
$('#progressbar div').css({'width': ((parseInt(percents) > 100) ? 100 : percents) + '%'});
|
1421 |
+
}
|
1422 |
+
$('#status').html('$msg');
|
1423 |
+
window.onbeforeunload = false;
|
1424 |
+
})(jQuery);
|
1425 |
+
//]]>
|
1426 |
+
</script>
|
1427 |
+
COMPLETE;
|
1428 |
+
// [/indicate in header process is complete]
|
1429 |
+
|
1430 |
+
echo ob_get_clean();
|
1431 |
+
|
1432 |
+
die;
|
1433 |
+
|
1434 |
+
}
|
1435 |
+
}
|
1436 |
+
|
1437 |
+
protected $_sibling_limit = 20;
|
1438 |
+
protected function get_xml_path(DOMElement $el, DOMXPath $xpath)
|
1439 |
+
{
|
1440 |
+
for($p = '', $doc = $el; $doc and ! $doc instanceof DOMDocument; $doc = $doc->parentNode) {
|
1441 |
+
if (($ind = $xpath->query('preceding-sibling::' . $doc->nodeName, $doc)->length)) {
|
1442 |
+
$p = '[' . ++$ind . ']' . $p;
|
1443 |
+
} elseif ( ! $doc->parentNode instanceof DOMDocument) {
|
1444 |
+
$p = '[' . ($ind = 1) . ']' . $p;
|
1445 |
+
}
|
1446 |
+
$p = '/' . $doc->nodeName . $p;
|
1447 |
+
}
|
1448 |
+
return $p;
|
1449 |
+
}
|
1450 |
+
|
1451 |
+
protected function shrink_xml_element(DOMElement $el)
|
1452 |
+
{
|
1453 |
+
$prev = null; $sub_ind = null;
|
1454 |
+
for ($i = 0; $i < $el->childNodes->length; $i++) {
|
1455 |
+
$child = $el->childNodes->item($i);
|
1456 |
+
if ($child instanceof DOMText) {
|
1457 |
+
if ('' == trim($child->wholeText)) {
|
1458 |
+
$el->removeChild($child);
|
1459 |
+
$i--;
|
1460 |
+
continue;
|
1461 |
+
}
|
1462 |
+
}
|
1463 |
+
if ($child instanceof DOMComment) {
|
1464 |
+
continue;
|
1465 |
+
}
|
1466 |
+
if ($prev instanceof $child and $prev->nodeName == $child->nodeName) {
|
1467 |
+
$sub_ind++;
|
1468 |
+
} else {
|
1469 |
+
if ($sub_ind > $this->_sibling_limit) {
|
1470 |
+
$el->insertBefore(new DOMComment('[pmxi_more:' . ($sub_ind - $this->_sibling_limit) . ']'), $child);
|
1471 |
+
$i++;
|
1472 |
+
}
|
1473 |
+
$sub_ind = 1;
|
1474 |
+
$prev = null;
|
1475 |
+
}
|
1476 |
+
if ($child instanceof DOMElement) {
|
1477 |
+
$prev = $child;
|
1478 |
+
if ($sub_ind <= $this->_sibling_limit) {
|
1479 |
+
$this->shrink_xml_element($child);
|
1480 |
+
} else {
|
1481 |
+
$el->removeChild($child);
|
1482 |
+
$i--;
|
1483 |
+
}
|
1484 |
+
}
|
1485 |
+
}
|
1486 |
+
if ($sub_ind > $this->_sibling_limit) {
|
1487 |
+
$el->appendChild(new DOMComment('[pmxi_more:' . ($sub_ind - $this->_sibling_limit) . ']'));
|
1488 |
+
}
|
1489 |
+
return $el;
|
1490 |
+
}
|
1491 |
+
protected function render_xml_element(DOMElement $el, $shorten = false, $path = '/', $ind = 1, $lvl = 0)
|
1492 |
+
{
|
1493 |
+
$path .= $el->nodeName;
|
1494 |
+
if ( ! $el->parentNode instanceof DOMDocument and $ind > 0) {
|
1495 |
+
$path .= "[$ind]";
|
1496 |
+
}
|
1497 |
+
|
1498 |
+
echo '<div class="xml-element lvl-' . $lvl . ' lvl-mod4-' . ($lvl % 4) . '" title="' . $path . '">';
|
1499 |
+
if ($el->hasChildNodes()) {
|
1500 |
+
$is_render_collapsed = $ind > 1;
|
1501 |
+
if ($el->childNodes->length > 1 or ! $el->childNodes->item(0) instanceof DOMText or strlen(trim($el->childNodes->item(0)->wholeText)) > 40) {
|
1502 |
+
echo '<div class="xml-expander">' . ($is_render_collapsed ? '+' : '-') . '</div>';
|
1503 |
+
}
|
1504 |
+
echo '<div class="xml-tag opening"><<span class="xml-tag-name">' . $el->nodeName . '</span>'; $this->render_xml_attributes($el, $path . '/'); echo '></div>';
|
1505 |
+
if (1 == $el->childNodes->length and $el->childNodes->item(0) instanceof DOMText) {
|
1506 |
+
$this->render_xml_text(trim($el->childNodes->item(0)->wholeText), $shorten, $is_render_collapsed);
|
1507 |
+
} else {
|
1508 |
+
echo '<div class="xml-content' . ($is_render_collapsed ? ' collapsed' : '') . '">';
|
1509 |
+
$indexes = array();
|
1510 |
+
foreach ($el->childNodes as $child) {
|
1511 |
+
if ($child instanceof DOMElement) {
|
1512 |
+
empty($indexes[$child->nodeName]) and $indexes[$child->nodeName] = 0; $indexes[$child->nodeName]++;
|
1513 |
+
$this->render_xml_element($child, $shorten, $path . '/', $indexes[$child->nodeName], $lvl + 1);
|
1514 |
+
} elseif ($child instanceof DOMText) {
|
1515 |
+
$this->render_xml_text(trim($child->wholeText), $shorten);
|
1516 |
+
} elseif ($child instanceof DOMComment) {
|
1517 |
+
if (preg_match('%\[pmxi_more:(\d+)\]%', $child->nodeValue, $mtch)) {
|
1518 |
+
$no = intval($mtch[1]);
|
1519 |
+
echo '<div class="xml-more">[ ⇓ ' . sprintf(__('<strong>%s</strong> %s more', 'pmxi_plugin'), $no, _n('element', 'elements', $no, 'pmxi_plugin')) . ' ⇓ ]</div>';
|
1520 |
+
}
|
1521 |
+
}
|
1522 |
+
}
|
1523 |
+
echo '</div>';
|
1524 |
+
}
|
1525 |
+
echo '<div class="xml-tag closing"></<span class="xml-tag-name">' . $el->nodeName . '</span>></div>';
|
1526 |
+
} else {
|
1527 |
+
echo '<div class="xml-tag opening empty"><<span class="xml-tag-name">' . $el->nodeName . '</span>'; $this->render_xml_attributes($el); echo '/></div>';
|
1528 |
+
}
|
1529 |
+
echo '</div>';
|
1530 |
+
}
|
1531 |
+
protected $_unique_key = array();
|
1532 |
+
protected function find_unique_key(DOMElement $el){
|
1533 |
+
if ($el->hasChildNodes()) {
|
1534 |
+
if ($el->childNodes->length) {
|
1535 |
+
foreach ($el->childNodes as $child) {
|
1536 |
+
if ($child instanceof DOMElement) {
|
1537 |
+
if (!in_array($child->nodeName, $this->_unique_key)) $this->_unique_key[] = $child->nodeName;
|
1538 |
+
$this->find_unique_key($child);
|
1539 |
+
}
|
1540 |
+
}
|
1541 |
+
}
|
1542 |
+
}
|
1543 |
+
}
|
1544 |
+
protected function render_xml_text($text, $shorten = false, $is_render_collapsed = false)
|
1545 |
+
{
|
1546 |
+
if (empty($text)) {
|
1547 |
+
return; // do not display empty text nodes
|
1548 |
+
}
|
1549 |
+
if (preg_match('%\[more:(\d+)\]%', $text, $mtch)) {
|
1550 |
+
$no = intval($mtch[1]);
|
1551 |
+
echo '<div class="xml-more">[ ⇓ ' . sprintf(__('<strong>%s</strong> %s more', 'pmxi_plugin'), $no, _n('element', 'elements', $no, 'pmxi_plugin')) . ' ⇓ ]</div>';
|
1552 |
+
return;
|
1553 |
+
}
|
1554 |
+
$more = '';
|
1555 |
+
if ($shorten and preg_match('%^(.*?\s+){20}(?=\S)%', $text, $mtch)) {
|
1556 |
+
$text = $mtch[0];
|
1557 |
+
$more = '<span class="xml-more">[' . __('more', 'pmxi_plugin') . ']</span>';
|
1558 |
+
}
|
1559 |
+
$is_short = strlen($text) <= 40;
|
1560 |
+
$text = esc_html($text);
|
1561 |
+
$text = preg_replace('%(?<!\s)\b(?!\s|\W[\w\s])|\w{20}%', '$0​', $text); // put explicit breaks for xml content to wrap
|
1562 |
+
echo '<div class="xml-content textonly' . ($is_short ? ' short' : '') . ($is_render_collapsed ? ' collapsed' : '') . '">' . $text . $more . '</div>';
|
1563 |
+
}
|
1564 |
+
protected function render_xml_attributes(DOMElement $el, $path = '/')
|
1565 |
+
{
|
1566 |
+
foreach ($el->attributes as $attr) {
|
1567 |
+
echo ' <span class="xml-attr" title="' . $path . '@' . $attr->nodeName . '"><span class="xml-attr-name">' . $attr->nodeName . '</span>=<span class="xml-attr-value">"' . esc_attr($attr->value) . '"</span></span>';
|
1568 |
+
}
|
1569 |
+
}
|
1570 |
+
|
1571 |
+
protected function render_xml_element_table(DOMElement $el, $shorten = false, $path = '/', $ind = 0, $lvl = 0)
|
1572 |
+
{
|
1573 |
+
$path .= $el->nodeName;
|
1574 |
+
if ($ind > 0) {
|
1575 |
+
$path .= "[$ind]";
|
1576 |
+
}
|
1577 |
+
|
1578 |
+
$is_render_collapsed = $ind > 1;
|
1579 |
+
echo '<tr class="xml-element lvl-' . $lvl . ($is_render_collapsed ? ' collapsed' : '') . '" title="' . $path . '">';
|
1580 |
+
echo '<td style="padding-left:' . ($lvl + 1) * 15 . 'px">';
|
1581 |
+
$is_inline = true;
|
1582 |
+
if ( ! (0 == $el->attributes->length and 1 == $el->childNodes->length and $el->childNodes->item(0) instanceof DOMText and strlen($el->childNodes->item(0)->wholeText) <= 40)) {
|
1583 |
+
$is_inline = false;
|
1584 |
+
echo '<div class="xml-expander">' . ($is_render_collapsed ? '+' : '-') . '</div>';
|
1585 |
+
}
|
1586 |
+
echo '<div class="xml-tag opening"><span class="xml-tag-name">' . $el->nodeName . '</span></div>';
|
1587 |
+
echo '</td>';
|
1588 |
+
echo '<td>';
|
1589 |
+
$is_inline and $this->render_xml_text_table(trim($el->childNodes->item(0)->wholeText), $shorten, NULL, NULL, $is_inline = true);
|
1590 |
+
echo '</td>';
|
1591 |
+
echo '</tr>';
|
1592 |
+
if ( ! $is_inline) {
|
1593 |
+
echo '<tr class="xml-content' . ($is_render_collapsed ? ' collapsed' : '') . '">';
|
1594 |
+
echo '<td colspan="2">';
|
1595 |
+
echo '<table>';
|
1596 |
+
$this->render_xml_attributes_table($el, $path . '/', $lvl + 1);
|
1597 |
+
$indexes = array();
|
1598 |
+
foreach ($el->childNodes as $child) {
|
1599 |
+
if ($child instanceof DOMElement) {
|
1600 |
+
empty($indexes[$child->nodeName]) and $indexes[$child->nodeName] = 1;
|
1601 |
+
$this->render_xml_element_table($child, $shorten, $path . '/', $indexes[$child->nodeName]++, $lvl + 1);
|
1602 |
+
} elseif ($child instanceof DOMText) {
|
1603 |
+
$this->render_xml_text_table(trim($child->wholeText), $shorten, $path . '/', $lvl + 1);
|
1604 |
+
}
|
1605 |
+
}
|
1606 |
+
echo '</table>';
|
1607 |
+
echo '</td>';
|
1608 |
+
echo '</tr>';
|
1609 |
+
}
|
1610 |
+
}
|
1611 |
+
protected function render_xml_text_table($text, $shorten = false, $path = '/', $lvl = 0, $is_inline = false)
|
1612 |
+
{
|
1613 |
+
if (empty($text)) {
|
1614 |
+
return; // do not display empty text nodes
|
1615 |
+
}
|
1616 |
+
$more = '';
|
1617 |
+
if ($shorten and preg_match('%^(.*?\s+){20}(?=\S)%', $text, $mtch)) {
|
1618 |
+
$text = $mtch[0];
|
1619 |
+
$more = '<span class="xml-more">[' . __('more', 'pmxi_plugin') . ']</span>';
|
1620 |
+
}
|
1621 |
+
$is_short = strlen($text) <= 40;
|
1622 |
+
$text = esc_html($text);
|
1623 |
+
$text = preg_replace('%(?<!\s)\b(?!\s|\W[\w\s])|\w{20}%', '$0​', $text); // put explicit breaks for xml content to wrap
|
1624 |
+
if ($is_inline) {
|
1625 |
+
echo $text . $more;
|
1626 |
+
} else {
|
1627 |
+
echo '<tr class="xml-content-tr textonly lvl-' . $lvl . ($is_short ? ' short' : '') . '" title="' . $path . 'text()">';
|
1628 |
+
echo '<td style="padding-left:' . ($lvl + 1) * 15 . 'px"><span class="xml-attr-name">text</span></td>';
|
1629 |
+
echo '<td>' . $text . $more . '</td>';
|
1630 |
+
echo '</tr>';
|
1631 |
+
}
|
1632 |
+
}
|
1633 |
+
protected function render_xml_attributes_table(DOMElement $el, $path = '/', $lvl = 0)
|
1634 |
+
{
|
1635 |
+
foreach ($el->attributes as $attr) {
|
1636 |
+
echo '<tr class="xml-attr lvl-' . $lvl . '" title="' . $path . '@' . $attr->nodeName . '">';
|
1637 |
+
echo '<td style="padding-left:' . ($lvl + 1) * 15 . 'px"><span class="xml-attr-name">@' . $attr->nodeName . '</span></td>';
|
1638 |
+
echo '<td><span class="xml-attr-value">' . esc_attr($attr->value) . '</span></td>';
|
1639 |
+
echo '</tr>';
|
1640 |
+
}
|
1641 |
+
}
|
1642 |
+
|
1643 |
+
protected function xml_find_repeating(DOMElement $el, $path = '/')
|
1644 |
+
{
|
1645 |
+
$path .= $el->nodeName;
|
1646 |
+
if ( ! $el->parentNode instanceof DOMDocument) {
|
1647 |
+
$path .= '[1]';
|
1648 |
+
}
|
1649 |
+
$children = array();
|
1650 |
+
foreach ($el->childNodes as $child) {
|
1651 |
+
if ($child instanceof DOMElement) {
|
1652 |
+
if ( ! empty($children[$child->nodeName])) {
|
1653 |
+
return $path . '/' . $child->nodeName;
|
1654 |
+
} else {
|
1655 |
+
$children[$child->nodeName] = true;
|
1656 |
+
}
|
1657 |
+
}
|
1658 |
+
}
|
1659 |
+
// reaching this point means we didn't find anything among current element children, so recursively ask children to find something in them
|
1660 |
+
foreach ($el->childNodes as $child) {
|
1661 |
+
if ($child instanceof DOMElement) {
|
1662 |
+
$result = $this->xml_find_repeating($child, $path . '/');
|
1663 |
+
if ($result) {
|
1664 |
+
return $result;
|
1665 |
+
}
|
1666 |
+
}
|
1667 |
+
}
|
1668 |
+
// reaching this point means we didn't find anything, so return element itself if the function was called for it
|
1669 |
+
if ('/' . $el->nodeName == $path) {
|
1670 |
+
return $path;
|
1671 |
+
}
|
1672 |
+
|
1673 |
+
return NULL;
|
1674 |
+
}
|
1675 |
+
|
1676 |
+
protected function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from) {
|
1677 |
+
$toDom = dom_import_simplexml($to);
|
1678 |
+
$fromDom = dom_import_simplexml($from);
|
1679 |
+
$toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
|
1680 |
+
}
|
1681 |
+
|
1682 |
+
}
|
controllers/admin/manage.php
CHANGED
@@ -1,417 +1,418 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Manage Imports
|
4 |
-
*
|
5 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
-
*/
|
7 |
-
class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
8 |
-
|
9 |
-
public function init() {
|
10 |
-
parent::init();
|
11 |
-
|
12 |
-
if ('update' == PMXI_Plugin::getInstance()->getAdminCurrentScreen()->action) {
|
13 |
-
$this->isInline = true;
|
14 |
-
if ( ! session_id()) session_start(); // prevent session initialization throw a notification in inline mode of delegated plugin
|
15 |
-
}
|
16 |
-
}
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Previous Imports list
|
20 |
-
*/
|
21 |
-
public function index() {
|
22 |
-
|
23 |
-
$get = $this->input->get(array(
|
24 |
-
's' => '',
|
25 |
-
'order_by' => 'registered_on',
|
26 |
-
'order' => 'DESC',
|
27 |
-
'pagenum' => 1,
|
28 |
-
'perPage' => 10,
|
29 |
-
));
|
30 |
-
$get['pagenum'] = absint($get['pagenum']);
|
31 |
-
extract($get);
|
32 |
-
$this->data += $get;
|
33 |
-
|
34 |
-
$list = new PMXI_Import_List();
|
35 |
-
$post = new PMXI_Post_Record();
|
36 |
-
$by = NULL;
|
37 |
-
if ('' != $s) {
|
38 |
-
$like = '%' . preg_replace('%\s+%', '%', preg_replace('/[%?]/', '\\\\$0', $s)) . '%';
|
39 |
-
$by[] = array(array('name LIKE' => $like, 'type LIKE' => $like, 'path LIKE' => $like), 'OR');
|
40 |
-
}
|
41 |
-
|
42 |
-
$this->data['list'] = $list->join($post->getTable(), $list->getTable() . '.id = ' . $post->getTable() . '.import_id', 'LEFT')
|
43 |
-
->setColumns(
|
44 |
-
$list->getTable() . '.*',
|
45 |
-
'COUNT(' . $post->getTable() . '.post_id' . ') AS post_count'
|
46 |
-
)
|
47 |
-
->getBy($by, "$order_by $order", $pagenum, $perPage, $list->getTable() . '.id');
|
48 |
-
|
49 |
-
$this->data['page_links'] = paginate_links(array(
|
50 |
-
'base' => add_query_arg('pagenum', '%#%', $this->baseUrl),
|
51 |
-
'format' => '',
|
52 |
-
'prev_text' => __('«', 'pmxi_plugin'),
|
53 |
-
'next_text' => __('»', 'pmxi_plugin'),
|
54 |
-
'total' => ceil($list->total() / $perPage),
|
55 |
-
'current' => $pagenum,
|
56 |
-
));
|
57 |
-
|
58 |
-
unset($_SESSION['pmxi_import']);
|
59 |
-
|
60 |
-
$this->render();
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Edit Template
|
65 |
-
*/
|
66 |
-
public function edit() {
|
67 |
-
// deligate operation to other controller
|
68 |
-
$controller = new PMXI_Admin_Import();
|
69 |
-
$controller->set('isTemplateEdit', true);
|
70 |
-
$controller->template();
|
71 |
-
}
|
72 |
-
|
73 |
-
/**
|
74 |
-
* Edit Options
|
75 |
-
*/
|
76 |
-
public function options() {
|
77 |
-
// deligate operation to other controller
|
78 |
-
$controller = new PMXI_Admin_Import();
|
79 |
-
$controller->set('isTemplateEdit', true);
|
80 |
-
$controller->options();
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* Reimport
|
85 |
-
*/
|
86 |
-
public function update() {
|
87 |
-
$id = $this->input->get('id');
|
88 |
-
$action_type = $this->input->get('type');
|
89 |
-
$pointer = 0;
|
90 |
-
|
91 |
-
$this->data['item'] = $item = new PMXI_Import_Record();
|
92 |
-
if ( ! $id or $item->getById($id)->isEmpty()) {
|
93 |
-
wp_redirect($this->baseUrl); die();
|
94 |
-
}
|
95 |
-
|
96 |
-
unset($_SESSION['pmxi_import']);
|
97 |
-
|
98 |
-
if ($this->input->post('is_confirmed')) {
|
99 |
-
|
100 |
-
check_admin_referer('update-import', '_wpnonce_update-import');
|
101 |
-
|
102 |
-
$uploads = wp_upload_dir();
|
103 |
-
|
104 |
-
if ($item->large_import == 'No' or ($item->large_import == 'Yes' and empty($_SESSION['pmxi_import']['chunk_number']))) {
|
105 |
-
|
106 |
-
if ( in_array($item->type, array('upload')) ) { // if import type NOT URL
|
107 |
-
|
108 |
-
if (preg_match('%\W(zip)$%i', trim(basename($item->path)))) {
|
109 |
-
|
110 |
-
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
|
111 |
-
|
112 |
-
$archive = new PclZip(trim($item->path));
|
113 |
-
if (($v_result_list = $archive->extract(PCLZIP_OPT_PATH, $uploads['path'], PCLZIP_OPT_REPLACE_NEWER)) == 0) {
|
114 |
-
$this->errors->add('form-validation', 'Failed to open uploaded ZIP archive : '.$archive->errorInfo(true));
|
115 |
-
}
|
116 |
-
else {
|
117 |
-
|
118 |
-
$filePath = '';
|
119 |
-
|
120 |
-
if (!empty($v_result_list)){
|
121 |
-
foreach ($v_result_list as $unzipped_file) {
|
122 |
-
if ($unzipped_file['status'] == 'ok') $filePath = $unzipped_file['filename'];
|
123 |
-
}
|
124 |
-
}
|
125 |
-
if($uploads['error']){
|
126 |
-
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
127 |
-
}
|
128 |
-
|
129 |
-
if(empty($filePath)){
|
130 |
-
$zip = zip_open(trim($item->path));
|
131 |
-
if (is_resource($zip)) {
|
132 |
-
while ($zip_entry = zip_read($zip)) {
|
133 |
-
$filePath = zip_entry_name($zip_entry);
|
134 |
-
$fp = fopen($uploads['path']."/".$filePath, "w");
|
135 |
-
if (zip_entry_open($zip, $zip_entry, "r")) {
|
136 |
-
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
137 |
-
fwrite($fp,"$buf");
|
138 |
-
zip_entry_close($zip_entry);
|
139 |
-
fclose($fp);
|
140 |
-
}
|
141 |
-
break;
|
142 |
-
}
|
143 |
-
zip_close($zip);
|
144 |
-
|
145 |
-
} else {
|
146 |
-
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive. Can\'t extract files.', 'pmxi_plugin'));
|
147 |
-
}
|
148 |
-
}
|
149 |
-
|
150 |
-
if (preg_match('%\W(csv)$%i', trim($filePath))){ // If CSV file found in archieve
|
151 |
-
|
152 |
-
if($uploads['error']){
|
153 |
-
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
154 |
-
}
|
155 |
-
if (empty($item->large_import) or $item->large_import == 'No') {
|
156 |
-
$filePath = PMXI_Plugin::csv_to_xml($filePath);
|
157 |
-
}
|
158 |
-
else{
|
159 |
-
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
160 |
-
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
161 |
-
$filePath = $csv->xml_path;
|
162 |
-
}
|
163 |
-
}
|
164 |
-
}
|
165 |
-
|
166 |
-
} elseif ( preg_match('%\W(csv)$%i', trim($item->path))) { // If CSV file uploaded
|
167 |
-
if($uploads['error']){
|
168 |
-
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
169 |
-
}
|
170 |
-
$filePath = $post['filepath'];
|
171 |
-
if (empty($item->large_import) or $item->large_import == 'No') {
|
172 |
-
$filePath = PMXI_Plugin::csv_to_xml($item->path);
|
173 |
-
} else{
|
174 |
-
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
175 |
-
$csv = new PMXI_CsvParser($item->path, true);
|
176 |
-
$filePath = $csv->xml_path;
|
177 |
-
}
|
178 |
-
} elseif(preg_match('%\W(gz)$%i', trim($item->path))){ // If gz file uploaded
|
179 |
-
$fileInfo = pmxi_gzfile_get_contents($item->path);
|
180 |
-
$filePath = $fileInfo['localPath'];
|
181 |
-
// detect CSV or XML
|
182 |
-
if ( $fileInfo['type'] == 'csv') { // it is CSV file
|
183 |
-
if (empty($item->large_import) or $item->large_import == 'No') {
|
184 |
-
$filePath = PMXI_Plugin::csv_to_xml($filePath); // convert CSV to XML
|
185 |
-
}
|
186 |
-
else{
|
187 |
-
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
188 |
-
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
189 |
-
$filePath = $csv->xml_path;
|
190 |
-
}
|
191 |
-
}
|
192 |
-
} else { // If XML file uploaded
|
193 |
-
|
194 |
-
$filePath = $item->path;
|
195 |
-
|
196 |
-
}
|
197 |
-
|
198 |
-
}
|
199 |
-
|
200 |
-
if (empty($xml)){
|
201 |
-
|
202 |
-
if ($item->large_import == 'Yes'){
|
203 |
-
|
204 |
-
set_time_limit(0);
|
205 |
-
|
206 |
-
$chunks = 0;
|
207 |
-
|
208 |
-
$chunk_path = '';
|
209 |
-
|
210 |
-
$local_paths = !empty($local_paths) ? $local_paths : array($filePath);
|
211 |
-
|
212 |
-
$chunk_founded = false;
|
213 |
-
|
214 |
-
foreach ($local_paths as $key => $path) {
|
215 |
-
|
216 |
-
$file = new PMXI_Chunk($path, array('element' => $item->root_element, 'path' => $uploads['path']));
|
217 |
-
|
218 |
-
while ($xml = $file->read()) {
|
219 |
-
|
220 |
-
if (!empty($xml))
|
221 |
-
{
|
222 |
-
if (!empty($action_type) and $action_type == 'continue'){
|
223 |
-
if ( !$chunk_founded) {
|
224 |
-
$xml = $file->encoding . "\n" . $xml;
|
225 |
-
PMXI_Import_Record::preprocessXml($xml);
|
226 |
-
|
227 |
-
$dom = new DOMDocument('1.0', 'UTF-8');
|
228 |
-
$old = libxml_use_internal_errors(true);
|
229 |
-
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
230 |
-
libxml_use_internal_errors($old);
|
231 |
-
$xpath = new DOMXPath($dom);
|
232 |
-
if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) {
|
233 |
-
$chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
|
234 |
-
file_put_contents($chunk_path, $xml);
|
235 |
-
chmod($chunk_path, 0755);
|
236 |
-
$chunk_founded = true;
|
237 |
-
}
|
238 |
-
unset($dom, $xpath, $elements);
|
239 |
-
}
|
240 |
-
$chunks++;
|
241 |
-
if ($chunks == $item->imported){
|
242 |
-
$pointer = $file->pointer;
|
243 |
-
$chunks = $item->count;
|
244 |
-
break;
|
245 |
-
}
|
246 |
-
}
|
247 |
-
else{
|
248 |
-
$xml = $file->encoding . "\n" . $xml;
|
249 |
-
PMXI_Import_Record::preprocessXml($xml);
|
250 |
-
|
251 |
-
$dom = new DOMDocument('1.0', 'UTF-8');
|
252 |
-
$old = libxml_use_internal_errors(true);
|
253 |
-
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
254 |
-
libxml_use_internal_errors($old);
|
255 |
-
$xpath = new DOMXPath($dom);
|
256 |
-
if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) {
|
257 |
-
if ( !$chunks) {
|
258 |
-
$chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
|
259 |
-
file_put_contents($chunk_path, $xml);
|
260 |
-
chmod($chunk_path, 0755);
|
261 |
-
}
|
262 |
-
$chunks++;
|
263 |
-
}
|
264 |
-
unset($dom, $xpath, $elements);
|
265 |
-
}
|
266 |
-
}
|
267 |
-
}
|
268 |
-
unset($file);
|
269 |
-
|
270 |
-
!$key and $filePath = $path;
|
271 |
-
}
|
272 |
-
|
273 |
-
if (empty($chunks))
|
274 |
-
$this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin'));
|
275 |
-
else
|
276 |
-
$xml = @file_get_contents($chunk_path);
|
277 |
-
|
278 |
-
} else {
|
279 |
-
|
280 |
-
ob_start();
|
281 |
-
$filePath && @readgzfile($filePath);
|
282 |
-
$xml = ob_get_clean();
|
283 |
-
|
284 |
-
if (empty($xml)){
|
285 |
-
$xml = @file_get_contents($filePath);
|
286 |
-
if (empty($xml)) get_file_curl($filePath, $uploads['path'] .'/'. basename($filePath));
|
287 |
-
if (empty($xml)) $xml = @file_get_contents($uploads['path'] .'/'. basename($filePath));
|
288 |
-
}
|
289 |
-
}
|
290 |
-
}
|
291 |
-
}
|
292 |
-
|
293 |
-
if (!empty($_SESSION['pmxi_import']['xml'])) $xml = $_SESSION['pmxi_import']['xml'];
|
294 |
-
|
295 |
-
if ($item->large_import == 'Yes' or PMXI_Import_Record::validateXml($xml, $this->errors)) { // xml is valid
|
296 |
-
|
297 |
-
if ( ! PMXI_Plugin::is_ajax() and empty($_SESSION['pmxi_import']['chunk_number'])){
|
298 |
-
|
299 |
-
$item->set(array(
|
300 |
-
'processing' => 0,
|
301 |
-
'queue_chunk_number' => 0,
|
302 |
-
'current_post_ids' => ''
|
303 |
-
))->save();
|
304 |
-
|
305 |
-
if (empty($action_type)){
|
306 |
-
$item->set(array(
|
307 |
-
'imported' => 0,
|
308 |
-
'created' => 0,
|
309 |
-
'updated' => 0,
|
310 |
-
'skipped' => 0
|
311 |
-
))->save();
|
312 |
-
}
|
313 |
-
|
314 |
-
// compose data to look like result of wizard steps
|
315 |
-
$_SESSION['pmxi_import'] = array(
|
316 |
-
'xml' => (isset($xml)) ? $xml : '',
|
317 |
-
'filePath' => $filePath,
|
318 |
-
'source' => array(
|
319 |
-
'name' => $item->name,
|
320 |
-
'type' => $item->type,
|
321 |
-
'path' => $item->path,
|
322 |
-
'root_element' => $item->root_element,
|
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 |
-
$controller
|
349 |
-
$controller->
|
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 |
-
$this->data['
|
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 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Manage Imports
|
4 |
+
*
|
5 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
+
*/
|
7 |
+
class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
8 |
+
|
9 |
+
public function init() {
|
10 |
+
parent::init();
|
11 |
+
|
12 |
+
if ('update' == PMXI_Plugin::getInstance()->getAdminCurrentScreen()->action) {
|
13 |
+
$this->isInline = true;
|
14 |
+
if ( ! session_id()) session_start(); // prevent session initialization throw a notification in inline mode of delegated plugin
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Previous Imports list
|
20 |
+
*/
|
21 |
+
public function index() {
|
22 |
+
|
23 |
+
$get = $this->input->get(array(
|
24 |
+
's' => '',
|
25 |
+
'order_by' => 'registered_on',
|
26 |
+
'order' => 'DESC',
|
27 |
+
'pagenum' => 1,
|
28 |
+
'perPage' => 10,
|
29 |
+
));
|
30 |
+
$get['pagenum'] = absint($get['pagenum']);
|
31 |
+
extract($get);
|
32 |
+
$this->data += $get;
|
33 |
+
|
34 |
+
$list = new PMXI_Import_List();
|
35 |
+
$post = new PMXI_Post_Record();
|
36 |
+
$by = NULL;
|
37 |
+
if ('' != $s) {
|
38 |
+
$like = '%' . preg_replace('%\s+%', '%', preg_replace('/[%?]/', '\\\\$0', $s)) . '%';
|
39 |
+
$by[] = array(array('name LIKE' => $like, 'type LIKE' => $like, 'path LIKE' => $like), 'OR');
|
40 |
+
}
|
41 |
+
|
42 |
+
$this->data['list'] = $list->join($post->getTable(), $list->getTable() . '.id = ' . $post->getTable() . '.import_id', 'LEFT')
|
43 |
+
->setColumns(
|
44 |
+
$list->getTable() . '.*',
|
45 |
+
'COUNT(' . $post->getTable() . '.post_id' . ') AS post_count'
|
46 |
+
)
|
47 |
+
->getBy($by, "$order_by $order", $pagenum, $perPage, $list->getTable() . '.id');
|
48 |
+
|
49 |
+
$this->data['page_links'] = paginate_links(array(
|
50 |
+
'base' => add_query_arg('pagenum', '%#%', $this->baseUrl),
|
51 |
+
'format' => '',
|
52 |
+
'prev_text' => __('«', 'pmxi_plugin'),
|
53 |
+
'next_text' => __('»', 'pmxi_plugin'),
|
54 |
+
'total' => ceil($list->total() / $perPage),
|
55 |
+
'current' => $pagenum,
|
56 |
+
));
|
57 |
+
|
58 |
+
unset($_SESSION['pmxi_import']);
|
59 |
+
|
60 |
+
$this->render();
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Edit Template
|
65 |
+
*/
|
66 |
+
public function edit() {
|
67 |
+
// deligate operation to other controller
|
68 |
+
$controller = new PMXI_Admin_Import();
|
69 |
+
$controller->set('isTemplateEdit', true);
|
70 |
+
$controller->template();
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Edit Options
|
75 |
+
*/
|
76 |
+
public function options() {
|
77 |
+
// deligate operation to other controller
|
78 |
+
$controller = new PMXI_Admin_Import();
|
79 |
+
$controller->set('isTemplateEdit', true);
|
80 |
+
$controller->options();
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Reimport
|
85 |
+
*/
|
86 |
+
public function update() {
|
87 |
+
$id = $this->input->get('id');
|
88 |
+
$action_type = $this->input->get('type');
|
89 |
+
$pointer = 0;
|
90 |
+
|
91 |
+
$this->data['item'] = $item = new PMXI_Import_Record();
|
92 |
+
if ( ! $id or $item->getById($id)->isEmpty()) {
|
93 |
+
wp_redirect($this->baseUrl); die();
|
94 |
+
}
|
95 |
+
|
96 |
+
unset($_SESSION['pmxi_import']);
|
97 |
+
|
98 |
+
if ($this->input->post('is_confirmed')) {
|
99 |
+
|
100 |
+
check_admin_referer('update-import', '_wpnonce_update-import');
|
101 |
+
|
102 |
+
$uploads = wp_upload_dir();
|
103 |
+
|
104 |
+
if ($item->large_import == 'No' or ($item->large_import == 'Yes' and empty($_SESSION['pmxi_import']['chunk_number']))) {
|
105 |
+
|
106 |
+
if ( in_array($item->type, array('upload')) ) { // if import type NOT URL
|
107 |
+
|
108 |
+
if (preg_match('%\W(zip)$%i', trim(basename($item->path)))) {
|
109 |
+
|
110 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/pclzip.lib.php');
|
111 |
+
|
112 |
+
$archive = new PclZip(trim($item->path));
|
113 |
+
if (($v_result_list = $archive->extract(PCLZIP_OPT_PATH, $uploads['path'], PCLZIP_OPT_REPLACE_NEWER)) == 0) {
|
114 |
+
$this->errors->add('form-validation', 'Failed to open uploaded ZIP archive : '.$archive->errorInfo(true));
|
115 |
+
}
|
116 |
+
else {
|
117 |
+
|
118 |
+
$filePath = '';
|
119 |
+
|
120 |
+
if (!empty($v_result_list)){
|
121 |
+
foreach ($v_result_list as $unzipped_file) {
|
122 |
+
if ($unzipped_file['status'] == 'ok') $filePath = $unzipped_file['filename'];
|
123 |
+
}
|
124 |
+
}
|
125 |
+
if($uploads['error']){
|
126 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
127 |
+
}
|
128 |
+
|
129 |
+
if(empty($filePath)){
|
130 |
+
$zip = zip_open(trim($item->path));
|
131 |
+
if (is_resource($zip)) {
|
132 |
+
while ($zip_entry = zip_read($zip)) {
|
133 |
+
$filePath = zip_entry_name($zip_entry);
|
134 |
+
$fp = fopen($uploads['path']."/".$filePath, "w");
|
135 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
136 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
137 |
+
fwrite($fp,"$buf");
|
138 |
+
zip_entry_close($zip_entry);
|
139 |
+
fclose($fp);
|
140 |
+
}
|
141 |
+
break;
|
142 |
+
}
|
143 |
+
zip_close($zip);
|
144 |
+
|
145 |
+
} else {
|
146 |
+
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive. Can\'t extract files.', 'pmxi_plugin'));
|
147 |
+
}
|
148 |
+
}
|
149 |
+
|
150 |
+
if (preg_match('%\W(csv)$%i', trim($filePath))){ // If CSV file found in archieve
|
151 |
+
|
152 |
+
if($uploads['error']){
|
153 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
154 |
+
}
|
155 |
+
if (empty($item->large_import) or $item->large_import == 'No') {
|
156 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath);
|
157 |
+
}
|
158 |
+
else{
|
159 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
160 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
161 |
+
$filePath = $csv->xml_path;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
} elseif ( preg_match('%\W(csv)$%i', trim($item->path))) { // If CSV file uploaded
|
167 |
+
if($uploads['error']){
|
168 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
169 |
+
}
|
170 |
+
$filePath = $post['filepath'];
|
171 |
+
if (empty($item->large_import) or $item->large_import == 'No') {
|
172 |
+
$filePath = PMXI_Plugin::csv_to_xml($item->path);
|
173 |
+
} else{
|
174 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
175 |
+
$csv = new PMXI_CsvParser($item->path, true);
|
176 |
+
$filePath = $csv->xml_path;
|
177 |
+
}
|
178 |
+
} elseif(preg_match('%\W(gz)$%i', trim($item->path))){ // If gz file uploaded
|
179 |
+
$fileInfo = pmxi_gzfile_get_contents($item->path);
|
180 |
+
$filePath = $fileInfo['localPath'];
|
181 |
+
// detect CSV or XML
|
182 |
+
if ( $fileInfo['type'] == 'csv') { // it is CSV file
|
183 |
+
if (empty($item->large_import) or $item->large_import == 'No') {
|
184 |
+
$filePath = PMXI_Plugin::csv_to_xml($filePath); // convert CSV to XML
|
185 |
+
}
|
186 |
+
else{
|
187 |
+
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
188 |
+
$csv = new PMXI_CsvParser($filePath, true); // create chunks
|
189 |
+
$filePath = $csv->xml_path;
|
190 |
+
}
|
191 |
+
}
|
192 |
+
} else { // If XML file uploaded
|
193 |
+
|
194 |
+
$filePath = $item->path;
|
195 |
+
|
196 |
+
}
|
197 |
+
|
198 |
+
}
|
199 |
+
|
200 |
+
if (empty($xml)){
|
201 |
+
|
202 |
+
if ($item->large_import == 'Yes'){
|
203 |
+
|
204 |
+
set_time_limit(0);
|
205 |
+
|
206 |
+
$chunks = 0;
|
207 |
+
|
208 |
+
$chunk_path = '';
|
209 |
+
|
210 |
+
$local_paths = !empty($local_paths) ? $local_paths : array($filePath);
|
211 |
+
|
212 |
+
$chunk_founded = false;
|
213 |
+
|
214 |
+
foreach ($local_paths as $key => $path) {
|
215 |
+
|
216 |
+
$file = new PMXI_Chunk($path, array('element' => $item->root_element, 'path' => $uploads['path']));
|
217 |
+
|
218 |
+
while ($xml = $file->read()) {
|
219 |
+
|
220 |
+
if (!empty($xml))
|
221 |
+
{
|
222 |
+
if (!empty($action_type) and $action_type == 'continue'){
|
223 |
+
if ( !$chunk_founded) {
|
224 |
+
$xml = $file->encoding . "\n" . $xml;
|
225 |
+
PMXI_Import_Record::preprocessXml($xml);
|
226 |
+
|
227 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
228 |
+
$old = libxml_use_internal_errors(true);
|
229 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
230 |
+
libxml_use_internal_errors($old);
|
231 |
+
$xpath = new DOMXPath($dom);
|
232 |
+
if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) {
|
233 |
+
$chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
|
234 |
+
file_put_contents($chunk_path, $xml);
|
235 |
+
chmod($chunk_path, 0755);
|
236 |
+
$chunk_founded = true;
|
237 |
+
}
|
238 |
+
unset($dom, $xpath, $elements);
|
239 |
+
}
|
240 |
+
$chunks++;
|
241 |
+
if ($chunks == $item->imported){
|
242 |
+
$pointer = $file->pointer;
|
243 |
+
$chunks = $item->count;
|
244 |
+
break;
|
245 |
+
}
|
246 |
+
}
|
247 |
+
else{
|
248 |
+
$xml = $file->encoding . "\n" . $xml;
|
249 |
+
PMXI_Import_Record::preprocessXml($xml);
|
250 |
+
|
251 |
+
$dom = new DOMDocument('1.0', 'UTF-8');
|
252 |
+
$old = libxml_use_internal_errors(true);
|
253 |
+
$dom->loadXML(preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml)); // FIX: libxml xpath doesn't handle default namespace properly, so remove it upon XML load
|
254 |
+
libxml_use_internal_errors($old);
|
255 |
+
$xpath = new DOMXPath($dom);
|
256 |
+
if (($elements = @$xpath->query($item->xpath)) and !empty($elements) and !empty($elements->length)) {
|
257 |
+
if ( !$chunks) {
|
258 |
+
$chunk_path = $uploads['path'] .'/'. wp_unique_filename($uploads['path'], "chunk_".basename($path));
|
259 |
+
file_put_contents($chunk_path, $xml);
|
260 |
+
chmod($chunk_path, 0755);
|
261 |
+
}
|
262 |
+
$chunks++;
|
263 |
+
}
|
264 |
+
unset($dom, $xpath, $elements);
|
265 |
+
}
|
266 |
+
}
|
267 |
+
}
|
268 |
+
unset($file);
|
269 |
+
|
270 |
+
!$key and $filePath = $path;
|
271 |
+
}
|
272 |
+
|
273 |
+
if (empty($chunks))
|
274 |
+
$this->errors->add('form-validation', __('No matching elements found for Root element and XPath expression specified', 'pmxi_plugin'));
|
275 |
+
else
|
276 |
+
$xml = @file_get_contents($chunk_path);
|
277 |
+
|
278 |
+
} else {
|
279 |
+
|
280 |
+
ob_start();
|
281 |
+
$filePath && @readgzfile($filePath);
|
282 |
+
$xml = ob_get_clean();
|
283 |
+
|
284 |
+
if (empty($xml)){
|
285 |
+
$xml = @file_get_contents($filePath);
|
286 |
+
if (empty($xml)) get_file_curl($filePath, $uploads['path'] .'/'. basename($filePath));
|
287 |
+
if (empty($xml)) $xml = @file_get_contents($uploads['path'] .'/'. basename($filePath));
|
288 |
+
}
|
289 |
+
}
|
290 |
+
}
|
291 |
+
}
|
292 |
+
|
293 |
+
if (!empty($_SESSION['pmxi_import']['xml'])) $xml = $_SESSION['pmxi_import']['xml'];
|
294 |
+
|
295 |
+
if ($item->large_import == 'Yes' or PMXI_Import_Record::validateXml($xml, $this->errors)) { // xml is valid
|
296 |
+
|
297 |
+
if ( ! PMXI_Plugin::is_ajax() and empty($_SESSION['pmxi_import']['chunk_number'])){
|
298 |
+
|
299 |
+
$item->set(array(
|
300 |
+
'processing' => 0,
|
301 |
+
'queue_chunk_number' => 0,
|
302 |
+
'current_post_ids' => ''
|
303 |
+
))->save();
|
304 |
+
|
305 |
+
if (empty($action_type)){
|
306 |
+
$item->set(array(
|
307 |
+
'imported' => 0,
|
308 |
+
'created' => 0,
|
309 |
+
'updated' => 0,
|
310 |
+
'skipped' => 0
|
311 |
+
))->save();
|
312 |
+
}
|
313 |
+
|
314 |
+
// compose data to look like result of wizard steps
|
315 |
+
$_SESSION['pmxi_import'] = array(
|
316 |
+
'xml' => (isset($xml)) ? $xml : '',
|
317 |
+
'filePath' => $filePath,
|
318 |
+
'source' => array(
|
319 |
+
'name' => $item->name,
|
320 |
+
'type' => $item->type,
|
321 |
+
'path' => $item->path,
|
322 |
+
'root_element' => $item->root_element,
|
323 |
+
),
|
324 |
+
'feed_type' => $item->feed_type,
|
325 |
+
'update_previous' => $item->id,
|
326 |
+
'xpath' => $item->xpath,
|
327 |
+
'template' => $item->template,
|
328 |
+
'options' => $item->options,
|
329 |
+
'scheduled' => $item->scheduled,
|
330 |
+
'current_post_ids' => '',
|
331 |
+
'large_file' => ($item->large_import == 'Yes') ? true : false,
|
332 |
+
'chunk_number' => (!empty($action_type) and $action_type == 'continue') ? $item->imported : 1,
|
333 |
+
'pointer' => $pointer,
|
334 |
+
'log' => '',
|
335 |
+
'created_records' => (!empty($action_type) and $action_type == 'continue') ? $item->created : 0,
|
336 |
+
'updated_records' => (!empty($action_type) and $action_type == 'continue') ? $item->updated : 0,
|
337 |
+
'skipped_records' => (!empty($action_type) and $action_type == 'continue') ? $item->skipped : 0,
|
338 |
+
'warnings' => 0,
|
339 |
+
'errors' => 0,
|
340 |
+
'start_time' => 0,
|
341 |
+
'count' => (isset($chunks)) ? $chunks : 0,
|
342 |
+
'local_paths' => (!empty($local_paths)) ? $local_paths : array(), // ftp import local copies of remote files
|
343 |
+
'action' => (!empty($action_type) and $action_type == 'continue') ? 'continue' : 'update',
|
344 |
+
);
|
345 |
+
}
|
346 |
+
|
347 |
+
// deligate operation to other controller
|
348 |
+
$controller = new PMXI_Admin_Import();
|
349 |
+
$controller->data['update_previous'] = $item;
|
350 |
+
$controller->process();
|
351 |
+
return;
|
352 |
+
}
|
353 |
+
}
|
354 |
+
$this->render();
|
355 |
+
}
|
356 |
+
|
357 |
+
/**
|
358 |
+
* Delete an import
|
359 |
+
*/
|
360 |
+
public function delete() {
|
361 |
+
$id = $this->input->get('id');
|
362 |
+
$this->data['item'] = $item = new PMXI_Import_Record();
|
363 |
+
if ( ! $id or $item->getById($id)->isEmpty()) {
|
364 |
+
wp_redirect($this->baseUrl); die();
|
365 |
+
}
|
366 |
+
|
367 |
+
if ($this->input->post('is_confirmed')) {
|
368 |
+
check_admin_referer('delete-import', '_wpnonce_delete-import');
|
369 |
+
|
370 |
+
$item->delete( ! $this->input->post('is_delete_posts'));
|
371 |
+
wp_redirect(add_query_arg('pmxi_nt', urlencode(__('Import deleted', 'pmxi_plugin')), $this->baseUrl)); die();
|
372 |
+
}
|
373 |
+
|
374 |
+
$this->render();
|
375 |
+
}
|
376 |
+
|
377 |
+
/**
|
378 |
+
* Bulk actions
|
379 |
+
*/
|
380 |
+
public function bulk() {
|
381 |
+
check_admin_referer('bulk-imports', '_wpnonce_bulk-imports');
|
382 |
+
if ($this->input->post('doaction2')) {
|
383 |
+
$this->data['action'] = $action = $this->input->post('bulk-action2');
|
384 |
+
} else {
|
385 |
+
$this->data['action'] = $action = $this->input->post('bulk-action');
|
386 |
+
}
|
387 |
+
$this->data['ids'] = $ids = $this->input->post('items');
|
388 |
+
$this->data['items'] = $items = new PMXI_Import_List();
|
389 |
+
if (empty($action) or ! in_array($action, array('delete')) or empty($ids) or $items->getBy('id', $ids)->isEmpty()) {
|
390 |
+
wp_redirect($this->baseUrl); die();
|
391 |
+
}
|
392 |
+
|
393 |
+
if ($this->input->post('is_confirmed')) {
|
394 |
+
$is_delete_posts = $this->input->post('is_delete_posts');
|
395 |
+
foreach($items->convertRecords() as $item) {
|
396 |
+
$item->delete( ! $is_delete_posts);
|
397 |
+
}
|
398 |
+
|
399 |
+
wp_redirect(add_query_arg('pmxi_nt', urlencode(sprintf(__('<strong>%d</strong> %s deleted', 'pmxi_plugin'), $items->count(), _n('import', 'imports', $items->count(), 'pmxi_plugin'))), $this->baseUrl)); die();
|
400 |
+
}
|
401 |
+
|
402 |
+
$this->render();
|
403 |
+
}
|
404 |
+
|
405 |
+
/*
|
406 |
+
* Download import log file
|
407 |
+
*
|
408 |
+
*/
|
409 |
+
public function log(){
|
410 |
+
|
411 |
+
$id = $this->input->get('id');
|
412 |
+
|
413 |
+
$wp_uploads = wp_upload_dir();
|
414 |
+
|
415 |
+
PMXI_download::csv($wp_uploads['basedir'] . '/wpallimport_logs/' .$id.'.html');
|
416 |
+
|
417 |
+
}
|
418 |
}
|
controllers/admin/settings.php
CHANGED
@@ -1,208 +1,208 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Admin Statistics page
|
4 |
-
*
|
5 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
-
*/
|
7 |
-
class PMXI_Admin_Settings extends PMXI_Controller_Admin {
|
8 |
-
|
9 |
-
public function index() {
|
10 |
-
$this->data['post'] = $post = $this->input->post(PMXI_Plugin::getInstance()->getOption());
|
11 |
-
|
12 |
-
if ($this->input->post('is_settings_submitted')) { // save settings form
|
13 |
-
check_admin_referer('edit-settings', '_wpnonce_edit-settings');
|
14 |
-
|
15 |
-
if ( ! preg_match('%^\d+$%', $post['history_file_count'])) {
|
16 |
-
$this->errors->add('form-validation', __('History File Count must be a non-negative integer', 'pmxi_plugin'));
|
17 |
-
}
|
18 |
-
if ( ! preg_match('%^\d+$%', $post['history_file_age'])) {
|
19 |
-
$this->errors->add('form-validation', __('History Age must be a non-negative integer', 'pmxi_plugin'));
|
20 |
-
}
|
21 |
-
if (empty($post['html_entities'])) $post['html_entities'] = 0;
|
22 |
-
if (empty($post['utf8_decode'])) $post['utf8_decode'] = 0;
|
23 |
-
|
24 |
-
if ( ! $this->errors->get_error_codes()) { // no validation errors detected
|
25 |
-
|
26 |
-
PMXI_Plugin::getInstance()->updateOption($post);
|
27 |
-
$files = new PMXI_File_List(); $files->sweepHistory(); // adjust file history to new settings specified
|
28 |
-
|
29 |
-
wp_redirect(add_query_arg('pmxi_nt', urlencode(__('Settings saved', 'pmxi_plugin')), $this->baseUrl)); die();
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
if ($this->input->post('is_templates_submitted')) { // delete templates form
|
34 |
-
$templates_ids = $this->input->post('templates', array());
|
35 |
-
if (empty($templates_ids)) {
|
36 |
-
$this->errors->add('form-validation', __('Templates must be selected', 'pmxi_plugin'));
|
37 |
-
}
|
38 |
-
if ( ! $this->errors->get_error_codes()) { // no validation errors detected
|
39 |
-
$template = new PMXI_Template_Record();
|
40 |
-
foreach ($templates_ids as $template_id) {
|
41 |
-
$template->clear()->set('id', $template_id)->delete();
|
42 |
-
}
|
43 |
-
wp_redirect(add_query_arg('pmxi_nt', urlencode(sprintf(_n('%d template deleted', '%d templates deleted', count($templates_ids), 'pmxi_plugin'), count($templates_ids))), $this->baseUrl)); die();
|
44 |
-
}
|
45 |
-
}
|
46 |
-
|
47 |
-
$this->render();
|
48 |
-
}
|
49 |
-
|
50 |
-
public function dismiss(){
|
51 |
-
|
52 |
-
PMXI_Plugin::getInstance()->updateOption("dismiss", 1);
|
53 |
-
|
54 |
-
exit('OK');
|
55 |
-
}
|
56 |
-
|
57 |
-
public function dismiss_manage_top(){
|
58 |
-
|
59 |
-
PMXI_Plugin::getInstance()->updateOption("dismiss_manage_top", 1);
|
60 |
-
|
61 |
-
exit('OK');
|
62 |
-
}
|
63 |
-
|
64 |
-
public function dismiss_manage_bottom(){
|
65 |
-
|
66 |
-
PMXI_Plugin::getInstance()->updateOption("dismiss_manage_bottom", 1);
|
67 |
-
|
68 |
-
exit('OK');
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* upload.php
|
73 |
-
*
|
74 |
-
* Copyright 2009, Moxiecode Systems AB
|
75 |
-
* Released under GPL License.
|
76 |
-
*
|
77 |
-
* License: http://www.plupload.com/license
|
78 |
-
* Contributing: http://www.plupload.com/contributing
|
79 |
-
*/
|
80 |
-
public function upload(){
|
81 |
-
|
82 |
-
// HTTP headers for no cache etc
|
83 |
-
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
84 |
-
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
85 |
-
header("Cache-Control: no-store, no-cache, must-revalidate");
|
86 |
-
header("Cache-Control: post-check=0, pre-check=0", false);
|
87 |
-
header("Pragma: no-cache");
|
88 |
-
|
89 |
-
// Settings
|
90 |
-
//$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
91 |
-
$uploads = wp_upload_dir();
|
92 |
-
|
93 |
-
$targetDir = $uploads['path'];
|
94 |
-
|
95 |
-
$cleanupTargetDir = true; // Remove old files
|
96 |
-
$maxFileAge = 5 * 3600; // Temp file age in seconds
|
97 |
-
|
98 |
-
// 5 minutes execution time
|
99 |
-
@set_time_limit(5 * 60);
|
100 |
-
|
101 |
-
// Uncomment this one to fake upload time
|
102 |
-
// usleep(5000);
|
103 |
-
|
104 |
-
// Get parameters
|
105 |
-
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
|
106 |
-
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
|
107 |
-
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
|
108 |
-
|
109 |
-
// Clean the fileName for security reasons
|
110 |
-
$fileName = preg_replace('/[^\w\._]+/', '_', $fileName);
|
111 |
-
|
112 |
-
// Make sure the fileName is unique but only if chunking is disabled
|
113 |
-
if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
|
114 |
-
$ext = strrpos($fileName, '.');
|
115 |
-
$fileName_a = substr($fileName, 0, $ext);
|
116 |
-
$fileName_b = substr($fileName, $ext);
|
117 |
-
|
118 |
-
$count = 1;
|
119 |
-
while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
|
120 |
-
$count++;
|
121 |
-
|
122 |
-
$fileName = $fileName_a . '_' . $count . $fileName_b;
|
123 |
-
}
|
124 |
-
|
125 |
-
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
|
126 |
-
|
127 |
-
// Create target dir
|
128 |
-
if (!file_exists($targetDir))
|
129 |
-
@mkdir($targetDir);
|
130 |
-
|
131 |
-
// Remove old temp files
|
132 |
-
if ($cleanupTargetDir && is_dir($targetDir) && ($dir = opendir($targetDir))) {
|
133 |
-
while (($file = readdir($dir)) !== false) {
|
134 |
-
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
|
135 |
-
|
136 |
-
// Remove temp file if it is older than the max age and is not the current file
|
137 |
-
if (preg_match('/\.part$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge) && ($tmpfilePath != "{$filePath}.part")) {
|
138 |
-
@unlink($tmpfilePath);
|
139 |
-
}
|
140 |
-
}
|
141 |
-
|
142 |
-
closedir($dir);
|
143 |
-
} else
|
144 |
-
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => "Failed to open temp directory."), "id" => "id")));
|
145 |
-
|
146 |
-
|
147 |
-
// Look for the content type header
|
148 |
-
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
|
149 |
-
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
|
150 |
-
|
151 |
-
if (isset($_SERVER["CONTENT_TYPE"]))
|
152 |
-
$contentType = $_SERVER["CONTENT_TYPE"];
|
153 |
-
|
154 |
-
// Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
|
155 |
-
if (strpos($contentType, "multipart") !== false) {
|
156 |
-
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
|
157 |
-
// Open temp file
|
158 |
-
$out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
|
159 |
-
if ($out) {
|
160 |
-
// Read binary input stream and append it to temp file
|
161 |
-
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
162 |
-
|
163 |
-
if ($in) {
|
164 |
-
while ($buff = fread($in, 4096))
|
165 |
-
fwrite($out, $buff);
|
166 |
-
} else
|
167 |
-
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => "Failed to open input stream."), "id" => "id")));
|
168 |
-
fclose($in);
|
169 |
-
fclose($out);
|
170 |
-
@unlink($_FILES['file']['tmp_name']);
|
171 |
-
} else
|
172 |
-
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
|
173 |
-
} else
|
174 |
-
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 103, "message" => "Failed to move uploaded file."), "id" => "id")));
|
175 |
-
} else {
|
176 |
-
// Open temp file
|
177 |
-
$out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
|
178 |
-
if ($out) {
|
179 |
-
// Read binary input stream and append it to temp file
|
180 |
-
$in = fopen("php://input", "rb");
|
181 |
-
|
182 |
-
if ($in) {
|
183 |
-
while ($buff = fread($in, 4096))
|
184 |
-
fwrite($out, $buff);
|
185 |
-
} else
|
186 |
-
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => "Failed to open input stream."), "id" => "id")));
|
187 |
-
|
188 |
-
fclose($in);
|
189 |
-
fclose($out);
|
190 |
-
} else
|
191 |
-
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => "Failed to open output stream."), "id" => "id")));
|
192 |
-
}
|
193 |
-
|
194 |
-
// Check if file has been uploaded
|
195 |
-
if (!$chunks || $chunk == $chunks - 1) {
|
196 |
-
// Strip the temp .part suffix off
|
197 |
-
rename("{$filePath}.part", $filePath); chmod($filePath, 0755);
|
198 |
-
}
|
199 |
-
|
200 |
-
// Return JSON-RPC response
|
201 |
-
exit(json_encode(array("jsonrpc" => "2.0", "result" => null, "id" => "id", "name" => $filePath)));
|
202 |
-
|
203 |
-
}
|
204 |
-
|
205 |
-
public function download(){
|
206 |
-
PMXI_download::csv(PMXI_Plugin::ROOT_DIR.'/logs/'.$_GET['file'].'.txt');
|
207 |
-
}
|
208 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Admin Statistics page
|
4 |
+
*
|
5 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
+
*/
|
7 |
+
class PMXI_Admin_Settings extends PMXI_Controller_Admin {
|
8 |
+
|
9 |
+
public function index() {
|
10 |
+
$this->data['post'] = $post = $this->input->post(PMXI_Plugin::getInstance()->getOption());
|
11 |
+
|
12 |
+
if ($this->input->post('is_settings_submitted')) { // save settings form
|
13 |
+
check_admin_referer('edit-settings', '_wpnonce_edit-settings');
|
14 |
+
|
15 |
+
if ( ! preg_match('%^\d+$%', $post['history_file_count'])) {
|
16 |
+
$this->errors->add('form-validation', __('History File Count must be a non-negative integer', 'pmxi_plugin'));
|
17 |
+
}
|
18 |
+
if ( ! preg_match('%^\d+$%', $post['history_file_age'])) {
|
19 |
+
$this->errors->add('form-validation', __('History Age must be a non-negative integer', 'pmxi_plugin'));
|
20 |
+
}
|
21 |
+
if (empty($post['html_entities'])) $post['html_entities'] = 0;
|
22 |
+
if (empty($post['utf8_decode'])) $post['utf8_decode'] = 0;
|
23 |
+
|
24 |
+
if ( ! $this->errors->get_error_codes()) { // no validation errors detected
|
25 |
+
|
26 |
+
PMXI_Plugin::getInstance()->updateOption($post);
|
27 |
+
$files = new PMXI_File_List(); $files->sweepHistory(); // adjust file history to new settings specified
|
28 |
+
|
29 |
+
wp_redirect(add_query_arg('pmxi_nt', urlencode(__('Settings saved', 'pmxi_plugin')), $this->baseUrl)); die();
|
30 |
+
}
|
31 |
+
}
|
32 |
+
|
33 |
+
if ($this->input->post('is_templates_submitted')) { // delete templates form
|
34 |
+
$templates_ids = $this->input->post('templates', array());
|
35 |
+
if (empty($templates_ids)) {
|
36 |
+
$this->errors->add('form-validation', __('Templates must be selected', 'pmxi_plugin'));
|
37 |
+
}
|
38 |
+
if ( ! $this->errors->get_error_codes()) { // no validation errors detected
|
39 |
+
$template = new PMXI_Template_Record();
|
40 |
+
foreach ($templates_ids as $template_id) {
|
41 |
+
$template->clear()->set('id', $template_id)->delete();
|
42 |
+
}
|
43 |
+
wp_redirect(add_query_arg('pmxi_nt', urlencode(sprintf(_n('%d template deleted', '%d templates deleted', count($templates_ids), 'pmxi_plugin'), count($templates_ids))), $this->baseUrl)); die();
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
$this->render();
|
48 |
+
}
|
49 |
+
|
50 |
+
public function dismiss(){
|
51 |
+
|
52 |
+
PMXI_Plugin::getInstance()->updateOption("dismiss", 1);
|
53 |
+
|
54 |
+
exit('OK');
|
55 |
+
}
|
56 |
+
|
57 |
+
public function dismiss_manage_top(){
|
58 |
+
|
59 |
+
PMXI_Plugin::getInstance()->updateOption("dismiss_manage_top", 1);
|
60 |
+
|
61 |
+
exit('OK');
|
62 |
+
}
|
63 |
+
|
64 |
+
public function dismiss_manage_bottom(){
|
65 |
+
|
66 |
+
PMXI_Plugin::getInstance()->updateOption("dismiss_manage_bottom", 1);
|
67 |
+
|
68 |
+
exit('OK');
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* upload.php
|
73 |
+
*
|
74 |
+
* Copyright 2009, Moxiecode Systems AB
|
75 |
+
* Released under GPL License.
|
76 |
+
*
|
77 |
+
* License: http://www.plupload.com/license
|
78 |
+
* Contributing: http://www.plupload.com/contributing
|
79 |
+
*/
|
80 |
+
public function upload(){
|
81 |
+
|
82 |
+
// HTTP headers for no cache etc
|
83 |
+
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
|
84 |
+
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
85 |
+
header("Cache-Control: no-store, no-cache, must-revalidate");
|
86 |
+
header("Cache-Control: post-check=0, pre-check=0", false);
|
87 |
+
header("Pragma: no-cache");
|
88 |
+
|
89 |
+
// Settings
|
90 |
+
//$targetDir = ini_get("upload_tmp_dir") . DIRECTORY_SEPARATOR . "plupload";
|
91 |
+
$uploads = wp_upload_dir();
|
92 |
+
|
93 |
+
$targetDir = $uploads['path'];
|
94 |
+
|
95 |
+
$cleanupTargetDir = true; // Remove old files
|
96 |
+
$maxFileAge = 5 * 3600; // Temp file age in seconds
|
97 |
+
|
98 |
+
// 5 minutes execution time
|
99 |
+
@set_time_limit(5 * 60);
|
100 |
+
|
101 |
+
// Uncomment this one to fake upload time
|
102 |
+
// usleep(5000);
|
103 |
+
|
104 |
+
// Get parameters
|
105 |
+
$chunk = isset($_REQUEST["chunk"]) ? intval($_REQUEST["chunk"]) : 0;
|
106 |
+
$chunks = isset($_REQUEST["chunks"]) ? intval($_REQUEST["chunks"]) : 0;
|
107 |
+
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
|
108 |
+
|
109 |
+
// Clean the fileName for security reasons
|
110 |
+
$fileName = preg_replace('/[^\w\._]+/', '_', $fileName);
|
111 |
+
|
112 |
+
// Make sure the fileName is unique but only if chunking is disabled
|
113 |
+
if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
|
114 |
+
$ext = strrpos($fileName, '.');
|
115 |
+
$fileName_a = substr($fileName, 0, $ext);
|
116 |
+
$fileName_b = substr($fileName, $ext);
|
117 |
+
|
118 |
+
$count = 1;
|
119 |
+
while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
|
120 |
+
$count++;
|
121 |
+
|
122 |
+
$fileName = $fileName_a . '_' . $count . $fileName_b;
|
123 |
+
}
|
124 |
+
|
125 |
+
$filePath = $targetDir . DIRECTORY_SEPARATOR . $fileName;
|
126 |
+
|
127 |
+
// Create target dir
|
128 |
+
if (!file_exists($targetDir))
|
129 |
+
@mkdir($targetDir);
|
130 |
+
|
131 |
+
// Remove old temp files
|
132 |
+
if ($cleanupTargetDir && is_dir($targetDir) && ($dir = opendir($targetDir))) {
|
133 |
+
while (($file = readdir($dir)) !== false) {
|
134 |
+
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
|
135 |
+
|
136 |
+
// Remove temp file if it is older than the max age and is not the current file
|
137 |
+
if (preg_match('/\.part$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge) && ($tmpfilePath != "{$filePath}.part")) {
|
138 |
+
@unlink($tmpfilePath);
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
closedir($dir);
|
143 |
+
} else
|
144 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 100, "message" => "Failed to open temp directory."), "id" => "id")));
|
145 |
+
|
146 |
+
|
147 |
+
// Look for the content type header
|
148 |
+
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
|
149 |
+
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
|
150 |
+
|
151 |
+
if (isset($_SERVER["CONTENT_TYPE"]))
|
152 |
+
$contentType = $_SERVER["CONTENT_TYPE"];
|
153 |
+
|
154 |
+
// Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
|
155 |
+
if (strpos($contentType, "multipart") !== false) {
|
156 |
+
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
|
157 |
+
// Open temp file
|
158 |
+
$out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
|
159 |
+
if ($out) {
|
160 |
+
// Read binary input stream and append it to temp file
|
161 |
+
$in = fopen($_FILES['file']['tmp_name'], "rb");
|
162 |
+
|
163 |
+
if ($in) {
|
164 |
+
while ($buff = fread($in, 4096))
|
165 |
+
fwrite($out, $buff);
|
166 |
+
} else
|
167 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => "Failed to open input stream."), "id" => "id")));
|
168 |
+
fclose($in);
|
169 |
+
fclose($out);
|
170 |
+
@unlink($_FILES['file']['tmp_name']);
|
171 |
+
} else
|
172 |
+
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
|
173 |
+
} else
|
174 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 103, "message" => "Failed to move uploaded file."), "id" => "id")));
|
175 |
+
} else {
|
176 |
+
// Open temp file
|
177 |
+
$out = fopen("{$filePath}.part", $chunk == 0 ? "wb" : "ab");
|
178 |
+
if ($out) {
|
179 |
+
// Read binary input stream and append it to temp file
|
180 |
+
$in = fopen("php://input", "rb");
|
181 |
+
|
182 |
+
if ($in) {
|
183 |
+
while ($buff = fread($in, 4096))
|
184 |
+
fwrite($out, $buff);
|
185 |
+
} else
|
186 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 101, "message" => "Failed to open input stream."), "id" => "id")));
|
187 |
+
|
188 |
+
fclose($in);
|
189 |
+
fclose($out);
|
190 |
+
} else
|
191 |
+
exit(json_encode(array("jsonrpc" => "2.0", "error" => array("code" => 102, "message" => "Failed to open output stream."), "id" => "id")));
|
192 |
+
}
|
193 |
+
|
194 |
+
// Check if file has been uploaded
|
195 |
+
if (!$chunks || $chunk == $chunks - 1) {
|
196 |
+
// Strip the temp .part suffix off
|
197 |
+
rename("{$filePath}.part", $filePath); chmod($filePath, 0755);
|
198 |
+
}
|
199 |
+
|
200 |
+
// Return JSON-RPC response
|
201 |
+
exit(json_encode(array("jsonrpc" => "2.0", "result" => null, "id" => "id", "name" => $filePath)));
|
202 |
+
|
203 |
+
}
|
204 |
+
|
205 |
+
public function download(){
|
206 |
+
PMXI_download::csv(PMXI_Plugin::ROOT_DIR.'/logs/'.$_GET['file'].'.txt');
|
207 |
+
}
|
208 |
}
|
helpers/get_file_curl.php
CHANGED
@@ -1,90 +1,102 @@
|
|
1 |
-
<?php
|
2 |
-
if ( ! function_exists('get_file_curl')):
|
3 |
-
|
4 |
-
function get_file_curl($url, $fullpath, $to_variable = false) {
|
5 |
-
|
6 |
-
$
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
}
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
endif;
|
1 |
+
<?php
|
2 |
+
if ( ! function_exists('get_file_curl')):
|
3 |
+
|
4 |
+
function get_file_curl($url, $fullpath, $to_variable = false) {
|
5 |
+
|
6 |
+
$rawdata = wp_remote_retrieve_body( wp_remote_get($url) );
|
7 |
+
|
8 |
+
if (empty($rawdata)){
|
9 |
+
$ch = curl_init($url);
|
10 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
11 |
+
$rawdata = curl_exec_follow($ch);
|
12 |
+
|
13 |
+
$result = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
14 |
+
|
15 |
+
curl_close ($ch);
|
16 |
+
|
17 |
+
if (!@file_put_contents($fullpath, $rawdata)){
|
18 |
+
$fp = fopen($fullpath,'w');
|
19 |
+
fwrite($fp, $rawdata);
|
20 |
+
fclose($fp);
|
21 |
+
}
|
22 |
+
|
23 |
+
return ($result == 200) ? (($to_variable) ? $rawdata : true) : false;
|
24 |
+
}
|
25 |
+
|
26 |
+
if (!@file_put_contents($fullpath, $rawdata)){
|
27 |
+
$fp = fopen($fullpath,'w');
|
28 |
+
fwrite($fp, $rawdata);
|
29 |
+
fclose($fp);
|
30 |
+
}
|
31 |
+
|
32 |
+
return ($to_variable) ? $rawdata : true;
|
33 |
+
}
|
34 |
+
|
35 |
+
endif;
|
36 |
+
|
37 |
+
if (!function_exists('curl_exec_follow')):
|
38 |
+
function curl_exec_follow($ch, &$maxredirect = null) {
|
39 |
+
|
40 |
+
$mr = $maxredirect === null ? 5 : intval($maxredirect);
|
41 |
+
|
42 |
+
if (ini_get('open_basedir') == '' && ini_get('safe_mode' == 'Off')) {
|
43 |
+
|
44 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $mr > 0);
|
45 |
+
curl_setopt($ch, CURLOPT_MAXREDIRS, $mr);
|
46 |
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
47 |
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
48 |
+
|
49 |
+
} else {
|
50 |
+
|
51 |
+
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
|
52 |
+
|
53 |
+
if ($mr > 0)
|
54 |
+
{
|
55 |
+
$original_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
|
56 |
+
$newurl = $original_url;
|
57 |
+
|
58 |
+
$rch = curl_copy_handle($ch);
|
59 |
+
|
60 |
+
curl_setopt($rch, CURLOPT_HEADER, true);
|
61 |
+
curl_setopt($rch, CURLOPT_NOBODY, true);
|
62 |
+
curl_setopt($rch, CURLOPT_FORBID_REUSE, false);
|
63 |
+
do
|
64 |
+
{
|
65 |
+
curl_setopt($rch, CURLOPT_URL, $newurl);
|
66 |
+
$header = curl_exec($rch);
|
67 |
+
if (curl_errno($rch)) {
|
68 |
+
$code = 0;
|
69 |
+
} else {
|
70 |
+
$code = curl_getinfo($rch, CURLINFO_HTTP_CODE);
|
71 |
+
if ($code == 301 || $code == 302) {
|
72 |
+
preg_match('/Location:(.*?)\n/', $header, $matches);
|
73 |
+
$newurl = trim(array_pop($matches));
|
74 |
+
|
75 |
+
// if no scheme is present then the new url is a
|
76 |
+
// relative path and thus needs some extra care
|
77 |
+
if(!preg_match("/^https?:/i", $newurl)){
|
78 |
+
$newurl = $original_url . $newurl;
|
79 |
+
}
|
80 |
+
} else {
|
81 |
+
$code = 0;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
} while ($code && --$mr);
|
85 |
+
|
86 |
+
curl_close($rch);
|
87 |
+
|
88 |
+
if (!$mr)
|
89 |
+
{
|
90 |
+
if ($maxredirect === null)
|
91 |
+
trigger_error('Too many redirects.', E_USER_WARNING);
|
92 |
+
else
|
93 |
+
$maxredirect = 0;
|
94 |
+
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
curl_setopt($ch, CURLOPT_URL, $newurl);
|
98 |
+
}
|
99 |
+
}
|
100 |
+
return curl_exec($ch);
|
101 |
+
}
|
102 |
endif;
|
helpers/import_custom_meta_box.php
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
<?php
|
2 |
-
if (!function_exists('import_custom_meta_box')){
|
3 |
-
function import_custom_meta_box($edit_post) {
|
4 |
-
?>
|
5 |
-
<div id="postcustomstuff">
|
6 |
-
<table id="list-table">
|
7 |
-
<tbody class="list:meta" id="the-list">
|
8 |
-
<?php if (!empty($_SESSION['pmxi_import']['options']['custom_name'])): foreach ($_SESSION['pmxi_import']['options']['custom_name'] as $i => $name): ?>
|
9 |
-
<tr>
|
10 |
-
<td class="left">
|
11 |
-
<label class="screen-reader-text">Key</label>
|
12 |
-
<input type="text" value="<?php echo esc_attr($name) ?>" name="custom_name[]" size="20">
|
13 |
-
<div class="submit"><input type="submit" class="delete deletemeta" value="Delete"></div>
|
14 |
-
</td>
|
15 |
-
<td>
|
16 |
-
<label class="screen-reader-text">Value</label>
|
17 |
-
<textarea name="custom_value[]" rows="2" cols="30" class="widefat"><?php echo esc_html($_SESSION['pmxi_import']['options']['custom_value'][$i]) ?></textarea>
|
18 |
-
</td>
|
19 |
-
</tr>
|
20 |
-
<?php endforeach; endif; ?>
|
21 |
-
</tbody>
|
22 |
-
</table>
|
23 |
-
<?php meta_form(); ?>
|
24 |
-
</div>
|
25 |
-
<p><?php _e('Custom fields can be used to add extra metadata to a post that you can <a href="http://codex.wordpress.org/Using_Custom_Fields" target="_blank">use in your theme</a>.'); ?></p>
|
26 |
-
<?php
|
27 |
-
}
|
28 |
-
}
|
29 |
?>
|
1 |
+
<?php
|
2 |
+
if (!function_exists('import_custom_meta_box')){
|
3 |
+
function import_custom_meta_box($edit_post) {
|
4 |
+
?>
|
5 |
+
<div id="postcustomstuff">
|
6 |
+
<table id="list-table">
|
7 |
+
<tbody class="list:meta" id="the-list">
|
8 |
+
<?php if (!empty($_SESSION['pmxi_import']['options']['custom_name'])): foreach ($_SESSION['pmxi_import']['options']['custom_name'] as $i => $name): ?>
|
9 |
+
<tr>
|
10 |
+
<td class="left">
|
11 |
+
<label class="screen-reader-text">Key</label>
|
12 |
+
<input type="text" value="<?php echo esc_attr($name) ?>" name="custom_name[]" size="20">
|
13 |
+
<div class="submit"><input type="submit" class="delete deletemeta" value="Delete"></div>
|
14 |
+
</td>
|
15 |
+
<td>
|
16 |
+
<label class="screen-reader-text">Value</label>
|
17 |
+
<textarea name="custom_value[]" rows="2" cols="30" class="widefat"><?php echo esc_html($_SESSION['pmxi_import']['options']['custom_value'][$i]) ?></textarea>
|
18 |
+
</td>
|
19 |
+
</tr>
|
20 |
+
<?php endforeach; endif; ?>
|
21 |
+
</tbody>
|
22 |
+
</table>
|
23 |
+
<?php meta_form(); ?>
|
24 |
+
</div>
|
25 |
+
<p><?php _e('Custom fields can be used to add extra metadata to a post that you can <a href="http://codex.wordpress.org/Using_Custom_Fields" target="_blank">use in your theme</a>.'); ?></p>
|
26 |
+
<?php
|
27 |
+
}
|
28 |
+
}
|
29 |
?>
|
helpers/pmxi_functions.php
CHANGED
@@ -1,237 +1,384 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* IF statement
|
4 |
-
*
|
5 |
-
* @access public
|
6 |
-
* @param string
|
7 |
-
* @param string
|
8 |
-
* @param string
|
9 |
-
* @param string
|
10 |
-
* @param string
|
11 |
-
* @return string
|
12 |
-
*/
|
13 |
-
if (!function_exists('pmxi_if')){
|
14 |
-
function pmxi_if($left_condition, $operand = '', $right_condition = '', $then, $else = ''){
|
15 |
-
$str = trim(implode(' ', array($left_condition, html_entity_decode($operand), $right_condition)));
|
16 |
-
return (eval ("return ($str);")) ? $then : $else;
|
17 |
-
}
|
18 |
-
}
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
*
|
29 |
-
*
|
30 |
-
*
|
31 |
-
*
|
32 |
-
* @
|
33 |
-
* @param string
|
34 |
-
* @param string
|
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 |
-
* @param string
|
66 |
-
* @param string
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* IF statement
|
4 |
+
*
|
5 |
+
* @access public
|
6 |
+
* @param string
|
7 |
+
* @param string
|
8 |
+
* @param string
|
9 |
+
* @param string
|
10 |
+
* @param string
|
11 |
+
* @return string
|
12 |
+
*/
|
13 |
+
if (!function_exists('pmxi_if')){
|
14 |
+
function pmxi_if($left_condition, $operand = '', $right_condition = '', $then, $else = ''){
|
15 |
+
$str = trim(implode(' ', array($left_condition, html_entity_decode($operand), $right_condition)));
|
16 |
+
return (eval ("return ($str);")) ? $then : $else;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
|
20 |
+
if (!function_exists('is_empty')){
|
21 |
+
function is_empty($var)
|
22 |
+
{
|
23 |
+
return empty($var);
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Word Limiter
|
29 |
+
*
|
30 |
+
* Limits a string to X number of words.
|
31 |
+
*
|
32 |
+
* @access public
|
33 |
+
* @param string
|
34 |
+
* @param string
|
35 |
+
* @param string the end character. Usually an ellipsis
|
36 |
+
* @return string
|
37 |
+
*/
|
38 |
+
if ( ! function_exists('pmxi_word_limiter'))
|
39 |
+
{
|
40 |
+
function pmxi_word_limiter($str, $limit = 100, $end_char = '…')
|
41 |
+
{
|
42 |
+
if (trim($str) == '')
|
43 |
+
{
|
44 |
+
return $str;
|
45 |
+
}
|
46 |
+
|
47 |
+
preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
|
48 |
+
|
49 |
+
if (strlen($str) == strlen($matches[0]))
|
50 |
+
{
|
51 |
+
$end_char = '';
|
52 |
+
}
|
53 |
+
|
54 |
+
return rtrim($matches[0]).$end_char;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Character Limiter
|
60 |
+
*
|
61 |
+
* Limits the string based on the character count. Preserves complete words
|
62 |
+
* so the character count may not be exactly as specified.
|
63 |
+
*
|
64 |
+
* @access public
|
65 |
+
* @param string
|
66 |
+
* @param string
|
67 |
+
* @param string the end character. Usually an ellipsis
|
68 |
+
* @return string
|
69 |
+
*/
|
70 |
+
if ( ! function_exists('pmxi_character_limiter'))
|
71 |
+
{
|
72 |
+
function pmxi_character_limiter($str, $n = 500, $end_char = '…')
|
73 |
+
{
|
74 |
+
if (strlen($str) < $n)
|
75 |
+
{
|
76 |
+
return $str;
|
77 |
+
}
|
78 |
+
|
79 |
+
$str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str));
|
80 |
+
|
81 |
+
if (strlen($str) <= $n)
|
82 |
+
{
|
83 |
+
return $str;
|
84 |
+
}
|
85 |
+
|
86 |
+
$out = "";
|
87 |
+
foreach (explode(' ', trim($str)) as $val)
|
88 |
+
{
|
89 |
+
$out .= $val.' ';
|
90 |
+
|
91 |
+
if (strlen($out) >= $n)
|
92 |
+
{
|
93 |
+
$out = trim($out);
|
94 |
+
return (strlen($out) == strlen($str)) ? $out : $out.$end_char;
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
if ( ! function_exists('url_title')){
|
101 |
+
|
102 |
+
function url_title($str, $separator = 'dash', $lowercase = FALSE)
|
103 |
+
{
|
104 |
+
if ($separator == 'dash')
|
105 |
+
{
|
106 |
+
$search = '_';
|
107 |
+
$replace = '-';
|
108 |
+
}
|
109 |
+
else
|
110 |
+
{
|
111 |
+
$search = '-';
|
112 |
+
$replace = '_';
|
113 |
+
}
|
114 |
+
|
115 |
+
$trans = array(
|
116 |
+
'&\#\d+?;' => '',
|
117 |
+
'&\S+?;' => '',
|
118 |
+
'\s+' => $replace,
|
119 |
+
'[^a-z0-9\-\._]' => '',
|
120 |
+
$replace.'+' => $replace,
|
121 |
+
$replace.'$' => $replace,
|
122 |
+
'^'.$replace => $replace,
|
123 |
+
'\.+$' => ''
|
124 |
+
);
|
125 |
+
|
126 |
+
$str = strip_tags($str);
|
127 |
+
|
128 |
+
foreach ($trans as $key => $val)
|
129 |
+
{
|
130 |
+
$str = preg_replace("#".$key."#i", $val, $str);
|
131 |
+
}
|
132 |
+
|
133 |
+
if ($lowercase === TRUE)
|
134 |
+
{
|
135 |
+
$str = strtolower($str);
|
136 |
+
}
|
137 |
+
|
138 |
+
return trim(stripslashes($str));
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
if ( ! function_exists('rand_char')){
|
143 |
+
|
144 |
+
function rand_char($length) {
|
145 |
+
$random = '';
|
146 |
+
for ($i = 0; $i < $length; $i++) {
|
147 |
+
$random .= chr(mt_rand(33, 126));
|
148 |
+
}
|
149 |
+
return $random;
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
if ( ! function_exists('pmxi_get_remote_file_name')){
|
154 |
+
|
155 |
+
function pmxi_get_remote_file_name($filePath){
|
156 |
+
$type = (preg_match('%\W(csv|txt|dat|psv)$%i', basename($filePath))) ? 'csv' : false;
|
157 |
+
if (!$type) $type = (preg_match('%\W(xml)$%i', basename($filePath))) ? 'xml' : false;
|
158 |
+
if (!$type) $type = (preg_match('%\W(zip)$%i', basename($filePath))) ? 'zip' : false;
|
159 |
+
if (!$type) $type = (preg_match('%\W(gz)$%i', basename($filePath))) ? 'gz' : false;
|
160 |
+
|
161 |
+
if (!$type){
|
162 |
+
$response = wp_remote_get($filePath);
|
163 |
+
$headers = wp_remote_retrieve_headers( $response );
|
164 |
+
|
165 |
+
if (preg_match("/filename=\".*\"/i", $headers['content-disposition'], $matches)){
|
166 |
+
$remote_file_name = str_replace(array('filename=','"'), '', $matches[0]);
|
167 |
+
if (!empty($remote_file_name)){
|
168 |
+
$type = (preg_match('%\W(csv)$%i', basename($remote_file_name))) ? 'csv' : false;
|
169 |
+
if (!$type) $type = (preg_match('%\W(xml)$%i', basename($remote_file_name))) ? 'xml' : false;
|
170 |
+
if (!$type) $type = (preg_match('%\W(zip)$%i', basename($remote_file_name))) ? 'zip' : false;
|
171 |
+
if (!$type) $type = (preg_match('%\W(gz)$%i', basename($remote_file_name))) ? 'gz' : false;
|
172 |
+
};
|
173 |
+
};
|
174 |
+
}
|
175 |
+
|
176 |
+
return ($type) ? $type : '';
|
177 |
+
}
|
178 |
+
}
|
179 |
+
|
180 |
+
if ( ! function_exists('pmxi_get_remote_image_ext')){
|
181 |
+
|
182 |
+
function pmxi_get_remote_image_ext($filePath){
|
183 |
+
$ext = pmxi_getExtension($filePath);
|
184 |
+
|
185 |
+
if ("" != $ext) return $ext;
|
186 |
+
$response = wp_remote_get($filePath);
|
187 |
+
$headers = wp_remote_retrieve_headers( $response );
|
188 |
+
$content_type = explode('/',$headers['content-type']);
|
189 |
+
|
190 |
+
return (!empty($content_type[1])) ? $content_type[1] : '';
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
if ( ! function_exists('pmxi_getExtension')){
|
195 |
+
function pmxi_getExtension($str)
|
196 |
+
{
|
197 |
+
$i = strrpos($str,".");
|
198 |
+
if (!$i) return "";
|
199 |
+
$l = strlen($str) - $i;
|
200 |
+
$ext = substr($str,$i+1,$l);
|
201 |
+
return ($l <= 4) ? $ext : "";
|
202 |
+
}
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Reading large files from remote server
|
207 |
+
* @ $filePath - file URL
|
208 |
+
* return local path of copied file
|
209 |
+
*/
|
210 |
+
if ( ! function_exists('pmxi_copy_url_file')){
|
211 |
+
|
212 |
+
function pmxi_copy_url_file($filePath, $detect = false){
|
213 |
+
/*$ctx = stream_context_create();
|
214 |
+
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));*/
|
215 |
+
|
216 |
+
$type = (preg_match('%\W(csv|txt|dat|psv)$%i', basename($filePath))) ? 'csv' : false;
|
217 |
+
if (!$type) $type = (preg_match('%\W(xml)$%i', basename($filePath))) ? 'xml' : false;
|
218 |
+
|
219 |
+
$uploads = wp_upload_dir();
|
220 |
+
$tmpname = wp_unique_filename($uploads['path'], basename($filePath));
|
221 |
+
$localPath = $uploads['path'] .'/'. $tmpname;
|
222 |
+
|
223 |
+
$file = @fopen($filePath, "rb");
|
224 |
+
|
225 |
+
if (is_resource($file)){
|
226 |
+
$fp = @fopen($localPath, 'w');
|
227 |
+
$first_chunk = true;
|
228 |
+
while (!feof($file)) {
|
229 |
+
$chunk = @fread($file, 1024);
|
230 |
+
if (!$type and $first_chunk and strpos($chunk, "<") !== false) $type = 'xml'; elseif (!$type and $first_chunk) $type = 'csv'; // if it's a 1st chunk, then chunk <? symbols to detect XML file
|
231 |
+
$first_chunk = false;
|
232 |
+
@fwrite($fp, $chunk);
|
233 |
+
}
|
234 |
+
@fclose($file);
|
235 |
+
@fclose($fp);
|
236 |
+
}
|
237 |
+
|
238 |
+
if (!file_exists($localPath)) {
|
239 |
+
|
240 |
+
get_file_curl($filePath, $localPath);
|
241 |
+
|
242 |
+
if (!$type){
|
243 |
+
$file = @fopen($localPath, "rb");
|
244 |
+
while (!feof($file)) {
|
245 |
+
$chunk = @fread($file, 1024);
|
246 |
+
if (strpos($chunk, "<?") !== false) $type = 'xml'; else $type = 'csv'; // if it's a 1st chunk, then chunk <? symbols to detect XML file
|
247 |
+
break;
|
248 |
+
}
|
249 |
+
@fclose($file);
|
250 |
+
}
|
251 |
+
|
252 |
+
}
|
253 |
+
|
254 |
+
return ($detect) ? array('type' => $type, 'localPath' => $localPath) : $localPath;
|
255 |
+
}
|
256 |
+
}
|
257 |
+
|
258 |
+
if ( ! function_exists('pmxi_gzfile_get_contents')){
|
259 |
+
function pmxi_gzfile_get_contents($filename, $use_include_path = 0) {
|
260 |
+
|
261 |
+
$type = 'csv';
|
262 |
+
$uploads = wp_upload_dir();
|
263 |
+
$tmpname = wp_unique_filename($uploads['path'], basename($filename));
|
264 |
+
$fp = @fopen($uploads['path'] .'/'. $tmpname, 'w');
|
265 |
+
|
266 |
+
$file = @gzopen($filename, 'rb', $use_include_path);
|
267 |
+
if ($file) {
|
268 |
+
$first_chunk = true;
|
269 |
+
while (!gzeof($file)) {
|
270 |
+
$chunk = gzread($file, 1024);
|
271 |
+
if ($first_chunk and strpos($chunk, "<?") !== false) { $type = 'xml'; $first_chunk = false; } // if it's a 1st chunk, then chunk <? symbols to detect XML file
|
272 |
+
@fwrite($fp, $chunk);
|
273 |
+
}
|
274 |
+
gzclose($file);
|
275 |
+
}
|
276 |
+
@fclose($fp);
|
277 |
+
$localPath = $uploads['path'] .'/'. $tmpname;
|
278 |
+
return array('type' => $type, 'localPath' => $localPath);
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
if ( ! function_exists('stream_notification_callback')){
|
283 |
+
|
284 |
+
function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
|
285 |
+
static $filesize = null;
|
286 |
+
|
287 |
+
$logger = create_function('$m', 'echo "$m\\n"; flush();');
|
288 |
+
|
289 |
+
$msg = '';
|
290 |
+
switch($notification_code) {
|
291 |
+
case STREAM_NOTIFY_RESOLVE:
|
292 |
+
case STREAM_NOTIFY_AUTH_REQUIRED:
|
293 |
+
case STREAM_NOTIFY_COMPLETED:
|
294 |
+
case STREAM_NOTIFY_FAILURE:
|
295 |
+
case STREAM_NOTIFY_AUTH_RESULT:
|
296 |
+
/* Ignore */
|
297 |
+
break;
|
298 |
+
|
299 |
+
case STREAM_NOTIFY_REDIRECTED:
|
300 |
+
//$msg = "Being redirected to: ". $message;
|
301 |
+
break;
|
302 |
+
|
303 |
+
case STREAM_NOTIFY_CONNECT:
|
304 |
+
//$msg = "Connected...";
|
305 |
+
break;
|
306 |
+
|
307 |
+
case STREAM_NOTIFY_FILE_SIZE_IS:
|
308 |
+
$filesize = $bytes_max;
|
309 |
+
//$msg = "Filesize: ". $filesize;
|
310 |
+
break;
|
311 |
+
|
312 |
+
case STREAM_NOTIFY_MIME_TYPE_IS:
|
313 |
+
//$msg = "Mime-type: ". $message;
|
314 |
+
break;
|
315 |
+
|
316 |
+
case STREAM_NOTIFY_PROGRESS:
|
317 |
+
if ($bytes_transferred > 0) {
|
318 |
+
/*$m = "<script type='text/javascript'>";
|
319 |
+
if (!isset($filesize)) {
|
320 |
+
$m .= "document.getElementById('url_progressbar').innerHTML('Unknown filesize.. ".($bytes_transferred/1024)."d kb done..');";
|
321 |
+
} else {
|
322 |
+
$length = (int)(($bytes_transferred/$filesize)*100);
|
323 |
+
$m .= "document.getElementById('url_upload_value').style.width = ".$length."%";
|
324 |
+
$m .= "document.getElementById('url_progressbar').innerHTML('".$length."% (".($bytes_transferred/1024)."/".($filesize/1024)." kb)');";
|
325 |
+
}
|
326 |
+
$m .= "</script>";*/
|
327 |
+
|
328 |
+
//$logger and call_user_func($logger, sprintf(__('%s', 'pmxi_plugin'), ($bytes_transferred/1024)));
|
329 |
+
|
330 |
+
/*echo(str_repeat(' ', 256));
|
331 |
+
if (@ob_get_contents()) {
|
332 |
+
@ob_end_flush();
|
333 |
+
}
|
334 |
+
flush();*/
|
335 |
+
}
|
336 |
+
break;
|
337 |
+
}
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
if ( ! function_exists('pmxi_strip_tags_content')){
|
342 |
+
|
343 |
+
function pmxi_strip_tags_content($text, $tags = '', $invert = FALSE) {
|
344 |
+
|
345 |
+
preg_match_all('/<(.+?)[\s]*\/?[\s]*>/si', trim($tags), $tags);
|
346 |
+
$tags = array_unique($tags[1]);
|
347 |
+
|
348 |
+
if(is_array($tags) AND count($tags) > 0) {
|
349 |
+
if($invert == FALSE) {
|
350 |
+
return preg_replace('@<(?!(?:'. implode('|', $tags) .')\b)(\w+)\b.*?>.*?</\1>@si', '', $text);
|
351 |
+
}
|
352 |
+
else {
|
353 |
+
return preg_replace('@<('. implode('|', $tags) .')\b.*?>.*?</\1>@si', '', $text);
|
354 |
+
}
|
355 |
+
}
|
356 |
+
elseif($invert == FALSE) {
|
357 |
+
return preg_replace('@<(\w+)\b.*?>.*?</\1>@si', '', $text);
|
358 |
+
}
|
359 |
+
return $text;
|
360 |
+
}
|
361 |
+
}
|
362 |
+
|
363 |
+
/*
|
364 |
+
* $value = {property/type[1]}
|
365 |
+
* Would return Rent if $value is 1, $Buy if $value is 2, Unavailable if $value is 3.
|
366 |
+
*/
|
367 |
+
if ( ! function_exists('wpai_util_map')){
|
368 |
+
|
369 |
+
function wpai_util_map($orig, $change, $value) {
|
370 |
+
|
371 |
+
$orig_array = explode(',', $orig);
|
372 |
+
|
373 |
+
if ( empty($orig_array) ) return "";
|
374 |
+
|
375 |
+
$change_array = explode(',', $change);
|
376 |
+
|
377 |
+
if ( empty($change_array) or count($orig_array) != count($change_array)) return "";
|
378 |
+
|
379 |
+
return str_replace($orig_array, $change_array, $value);
|
380 |
+
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
+
|
libraries/XmlImportConfig.php
CHANGED
@@ -1,88 +1,88 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
5 |
-
* @package General
|
6 |
-
*/
|
7 |
-
|
8 |
-
/**
|
9 |
-
* This class is used for different XmlImport settings
|
10 |
-
*/
|
11 |
-
if (!class_exists('XmlImportConfig'))
|
12 |
-
{
|
13 |
-
final class XmlImportConfig
|
14 |
-
{
|
15 |
-
/**
|
16 |
-
* Singleton instance
|
17 |
-
* @var XmlImportConfig
|
18 |
-
*/
|
19 |
-
private static $instance = null;
|
20 |
-
/**
|
21 |
-
* Path to cache directory
|
22 |
-
* @var string
|
23 |
-
*/
|
24 |
-
private $cache_dir;
|
25 |
-
/**
|
26 |
-
* String to use when concatenating result of xpath corresponding to multiple elements
|
27 |
-
* @var string
|
28 |
-
*/
|
29 |
-
private $multi_glue;
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Initial settings
|
33 |
-
*/
|
34 |
-
private function init()
|
35 |
-
{
|
36 |
-
$this->setCacheDirectory(dirname(__FILE__) . '/cache');
|
37 |
-
$this->setMultiGlue(', ');
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Gets instance of a singleton class
|
42 |
-
* @return XmlImportConfig
|
43 |
-
*/
|
44 |
-
public static function getInstance()
|
45 |
-
{
|
46 |
-
//if (is_null(self::$instance)) {
|
47 |
-
self::$instance = new self;
|
48 |
-
self::$instance->init();
|
49 |
-
//}
|
50 |
-
return self::$instance;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Returns path to cache directory
|
55 |
-
* @return string
|
56 |
-
*/
|
57 |
-
public function getCacheDirectory()
|
58 |
-
{
|
59 |
-
return $this->cache_dir;
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Sets path to cache directory
|
64 |
-
* @param string $cacheDirectoryPath
|
65 |
-
*/
|
66 |
-
public function setCacheDirectory($cacheDirectoryPath)
|
67 |
-
{
|
68 |
-
$this->cache_dir = $cacheDirectoryPath;
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Returns string glue to use when concatenating multiple elements
|
73 |
-
* @return string
|
74 |
-
*/
|
75 |
-
public function getMultiGlue()
|
76 |
-
{
|
77 |
-
return $this->multi_glue;
|
78 |
-
}
|
79 |
-
/**
|
80 |
-
* Sets string glue to use when concatenating multiple element
|
81 |
-
* @param unknown_type $glue
|
82 |
-
*/
|
83 |
-
public function setMultiGlue($glue)
|
84 |
-
{
|
85 |
-
$this->multi_glue = $glue;
|
86 |
-
}
|
87 |
-
}
|
88 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
5 |
+
* @package General
|
6 |
+
*/
|
7 |
+
|
8 |
+
/**
|
9 |
+
* This class is used for different XmlImport settings
|
10 |
+
*/
|
11 |
+
if (!class_exists('XmlImportConfig'))
|
12 |
+
{
|
13 |
+
final class XmlImportConfig
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* Singleton instance
|
17 |
+
* @var XmlImportConfig
|
18 |
+
*/
|
19 |
+
private static $instance = null;
|
20 |
+
/**
|
21 |
+
* Path to cache directory
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
private $cache_dir;
|
25 |
+
/**
|
26 |
+
* String to use when concatenating result of xpath corresponding to multiple elements
|
27 |
+
* @var string
|
28 |
+
*/
|
29 |
+
private $multi_glue;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Initial settings
|
33 |
+
*/
|
34 |
+
private function init()
|
35 |
+
{
|
36 |
+
$this->setCacheDirectory(dirname(__FILE__) . '/cache');
|
37 |
+
$this->setMultiGlue(', ');
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Gets instance of a singleton class
|
42 |
+
* @return XmlImportConfig
|
43 |
+
*/
|
44 |
+
public static function getInstance()
|
45 |
+
{
|
46 |
+
//if (is_null(self::$instance)) {
|
47 |
+
self::$instance = new self;
|
48 |
+
self::$instance->init();
|
49 |
+
//}
|
50 |
+
return self::$instance;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Returns path to cache directory
|
55 |
+
* @return string
|
56 |
+
*/
|
57 |
+
public function getCacheDirectory()
|
58 |
+
{
|
59 |
+
return $this->cache_dir;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Sets path to cache directory
|
64 |
+
* @param string $cacheDirectoryPath
|
65 |
+
*/
|
66 |
+
public function setCacheDirectory($cacheDirectoryPath)
|
67 |
+
{
|
68 |
+
$this->cache_dir = $cacheDirectoryPath;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Returns string glue to use when concatenating multiple elements
|
73 |
+
* @return string
|
74 |
+
*/
|
75 |
+
public function getMultiGlue()
|
76 |
+
{
|
77 |
+
return $this->multi_glue;
|
78 |
+
}
|
79 |
+
/**
|
80 |
+
* Sets string glue to use when concatenating multiple element
|
81 |
+
* @param unknown_type $glue
|
82 |
+
*/
|
83 |
+
public function setMultiGlue($glue)
|
84 |
+
{
|
85 |
+
$this->multi_glue = $glue;
|
86 |
+
}
|
87 |
+
}
|
88 |
}
|
libraries/XmlImportCsvParse.php
CHANGED
@@ -1,1254 +1,1258 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
4 |
-
|
5 |
-
/**
|
6 |
-
* contains a few csv file data access tools.
|
7 |
-
*
|
8 |
-
* PHP VERSION 5
|
9 |
-
*
|
10 |
-
* LICENSE: The MIT License
|
11 |
-
*
|
12 |
-
* Copyright (c) <2008> <Kazuyoshi Tlacaelel>
|
13 |
-
*
|
14 |
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 |
-
* of this software and associated documentation files (the "Software"), to deal
|
16 |
-
* in the Software without restriction, including without limitation the rights
|
17 |
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18 |
-
* copies of the Software, and to permit persons to whom the Software is
|
19 |
-
* furnished to do so, subject to the following conditions:
|
20 |
-
*
|
21 |
-
* The above copyright notice and this permission notice shall be included in
|
22 |
-
* all copies or substantial portions of the Software.
|
23 |
-
*
|
24 |
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
25 |
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
26 |
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
27 |
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
28 |
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
29 |
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
30 |
-
* THE SOFTWARE.
|
31 |
-
*
|
32 |
-
* @category File
|
33 |
-
* @package File_CSV_DataSource
|
34 |
-
* @author Kazuyoshi Tlacaelel <kazu.dev@gmail.com>
|
35 |
-
* @copyright 2008 Kazuyoshi Tlacaelel
|
36 |
-
* @license The MIT License
|
37 |
-
* @version SVN: $Id: DataSource.php 285574 2009-03-09 15:22:24Z ktlacaelel $
|
38 |
-
* @link http://code.google.com/p/php-csv-parser/
|
39 |
-
*/
|
40 |
-
|
41 |
-
/**
|
42 |
-
* csv data fetcher
|
43 |
-
*
|
44 |
-
* Sample snippets refer to this csv file for demonstration.
|
45 |
-
* <code>
|
46 |
-
* name,age,skill
|
47 |
-
* john,13,knows magic
|
48 |
-
* tanaka,8,makes sushi
|
49 |
-
* jose,5,dances salsa
|
50 |
-
* </code>
|
51 |
-
*
|
52 |
-
* @category File
|
53 |
-
* @package Csv_parse
|
54 |
-
* @author Kazuyoshi Tlacaelel <kazu.dev@gmail.com>
|
55 |
-
* @copyright 2008 Kazuyoshi Tlacaelel
|
56 |
-
* @license The MIT License
|
57 |
-
* @link http://code.google.com/p/php-csv-parser/
|
58 |
-
*/
|
59 |
-
class PMXI_CsvParser
|
60 |
-
{
|
61 |
-
public
|
62 |
-
|
63 |
-
/**
|
64 |
-
* csv parsing default-settings
|
65 |
-
*
|
66 |
-
* @var array
|
67 |
-
* @access public
|
68 |
-
*/
|
69 |
-
$settings = array(
|
70 |
-
'delimiter' => ',',
|
71 |
-
'eol' => '',
|
72 |
-
'length' => 999999,
|
73 |
-
'escape' => '"'
|
74 |
-
),
|
75 |
-
|
76 |
-
$tmp_files = array(),
|
77 |
-
|
78 |
-
$xpath = '',
|
79 |
-
|
80 |
-
$large_import = false,
|
81 |
-
|
82 |
-
$htmlentities = false,
|
83 |
-
|
84 |
-
$xml_path = '',
|
85 |
-
|
86 |
-
$iteration = 0;
|
87 |
-
|
88 |
-
protected
|
89 |
-
|
90 |
-
/**
|
91 |
-
* imported data from csv
|
92 |
-
*
|
93 |
-
* @var array
|
94 |
-
* @access protected
|
95 |
-
*/
|
96 |
-
$rows = array(),
|
97 |
-
|
98 |
-
/**
|
99 |
-
* csv file to parse
|
100 |
-
*
|
101 |
-
* @var string
|
102 |
-
* @access protected
|
103 |
-
*/
|
104 |
-
$_filename = '',
|
105 |
-
|
106 |
-
/**
|
107 |
-
* csv headers to parse
|
108 |
-
*
|
109 |
-
* @var array
|
110 |
-
* @access protected
|
111 |
-
*/
|
112 |
-
$headers = array();
|
113 |
-
|
114 |
-
/**
|
115 |
-
* data load initialize
|
116 |
-
*
|
117 |
-
* @param mixed $filename please look at the load() method
|
118 |
-
*
|
119 |
-
* @access public
|
120 |
-
* @see load()
|
121 |
-
* @return void
|
122 |
-
*/
|
123 |
-
public function __construct($filename = null, $large_import = false, $xpath = '')
|
124 |
-
{
|
125 |
-
|
126 |
-
$this->large_import = $large_import;
|
127 |
-
$this->xpath = (!empty($xpath) ? $xpath : ((!empty($_POST['xpath'])) ? $_POST['xpath'] : '/node'));
|
128 |
-
|
129 |
-
ini_set( "display_errors", 0);
|
130 |
-
ini_set('auto_detect_line_endings', true);
|
131 |
-
|
132 |
-
$file_params = self::analyse_file($filename, 1);
|
133 |
-
|
134 |
-
$this->set_settings(array('delimiter' => $file_params['delimiter']['value'], 'eol' => $file_params['line_ending']['value']));
|
135 |
-
|
136 |
-
unset($file_params);
|
137 |
-
|
138 |
-
$this->load($filename);
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* csv file loader
|
143 |
-
*
|
144 |
-
* indicates the object which file is to be loaded
|
145 |
-
*
|
146 |
-
*
|
147 |
-
* @param string $filename the csv filename to load
|
148 |
-
*
|
149 |
-
* @access public
|
150 |
-
* @return boolean true if file was loaded successfully
|
151 |
-
* @see isSymmetric(), getAsymmetricRows(), symmetrize()
|
152 |
-
*/
|
153 |
-
public function load($filename)
|
154 |
-
{
|
155 |
-
$this->_filename = $filename;
|
156 |
-
$this->flush();
|
157 |
-
return $this->parse();
|
158 |
-
}
|
159 |
-
|
160 |
-
/**
|
161 |
-
* settings alterator
|
162 |
-
*
|
163 |
-
* lets you define different settings for scanning
|
164 |
-
*
|
165 |
-
*
|
166 |
-
* @param mixed $array containing settings to use
|
167 |
-
*
|
168 |
-
* @access public
|
169 |
-
* @return boolean true if changes where applyed successfully
|
170 |
-
* @see $settings
|
171 |
-
*/
|
172 |
-
public function set_settings($array)
|
173 |
-
{
|
174 |
-
$this->settings = array_merge($this->settings, $array);
|
175 |
-
}
|
176 |
-
|
177 |
-
/**
|
178 |
-
* header fetcher
|
179 |
-
*
|
180 |
-
* gets csv headers into an array
|
181 |
-
*
|
182 |
-
* @access public
|
183 |
-
* @return array
|
184 |
-
*/
|
185 |
-
public function getHeaders()
|
186 |
-
{
|
187 |
-
return $this->headers;
|
188 |
-
}
|
189 |
-
|
190 |
-
/**
|
191 |
-
* header counter
|
192 |
-
*
|
193 |
-
* retrives the total number of loaded headers
|
194 |
-
*
|
195 |
-
* @access public
|
196 |
-
* @return integer gets the length of headers
|
197 |
-
*/
|
198 |
-
public function countHeaders()
|
199 |
-
{
|
200 |
-
return count($this->headers);
|
201 |
-
}
|
202 |
-
|
203 |
-
/**
|
204 |
-
* header and row relationship builder
|
205 |
-
*
|
206 |
-
* Attempts to create a relationship for every single cell that
|
207 |
-
* was captured and its corresponding header. The sample below shows
|
208 |
-
* how a connection/relationship is built.
|
209 |
-
*
|
210 |
-
* @param array $columns the columns to connect, if nothing
|
211 |
-
* is given all headers will be used to create a connection
|
212 |
-
*
|
213 |
-
* @access public
|
214 |
-
* @return array If the data is not symmetric an empty array
|
215 |
-
* will be returned instead
|
216 |
-
* @see isSymmetric(), getAsymmetricRows(), symmetrize(), getHeaders()
|
217 |
-
*/
|
218 |
-
public function connect($columns = array())
|
219 |
-
{
|
220 |
-
if (!$this->isSymmetric()) {
|
221 |
-
return array();
|
222 |
-
}
|
223 |
-
if (!is_array($columns)) {
|
224 |
-
return array();
|
225 |
-
}
|
226 |
-
if ($columns === array()) {
|
227 |
-
$columns = $this->headers;
|
228 |
-
}
|
229 |
-
|
230 |
-
$ret_arr = array();
|
231 |
-
|
232 |
-
foreach ($this->rows as $record) {
|
233 |
-
$item_array = array();
|
234 |
-
foreach ($record as $column => $value) {
|
235 |
-
$header = $this->headers[$column];
|
236 |
-
if (in_array($header, $columns)) {
|
237 |
-
$item_array[$header] = $value;
|
238 |
-
}
|
239 |
-
}
|
240 |
-
|
241 |
-
// do not append empty results
|
242 |
-
if ($item_array !== array()) {
|
243 |
-
array_push($ret_arr, $item_array);
|
244 |
-
}
|
245 |
-
}
|
246 |
-
|
247 |
-
return $ret_arr;
|
248 |
-
}
|
249 |
-
|
250 |
-
/**
|
251 |
-
* data length/symmetry checker
|
252 |
-
*
|
253 |
-
* tells if the headers and all of the contents length match.
|
254 |
-
* Note: there is a lot of methods that won't work if data is not
|
255 |
-
* symmetric this method is very important!
|
256 |
-
*
|
257 |
-
* @access public
|
258 |
-
* @return boolean
|
259 |
-
* @see symmetrize(), getAsymmetricRows(), isSymmetric()
|
260 |
-
*/
|
261 |
-
public function isSymmetric()
|
262 |
-
{
|
263 |
-
$hc = count($this->headers);
|
264 |
-
foreach ($this->rows as $row) {
|
265 |
-
if (count($row) != $hc) {
|
266 |
-
return false;
|
267 |
-
}
|
268 |
-
}
|
269 |
-
return true;
|
270 |
-
}
|
271 |
-
|
272 |
-
/**
|
273 |
-
* asymmetric data fetcher
|
274 |
-
*
|
275 |
-
* finds the rows that do not match the headers length
|
276 |
-
*
|
277 |
-
* lets assume that we add one more row to our csv file.
|
278 |
-
* that has only two values. Something like
|
279 |
-
*
|
280 |
-
* @access public
|
281 |
-
* @return array filled with rows that do not match headers
|
282 |
-
* @see getHeaders(), symmetrize(), isSymmetric(),
|
283 |
-
* getAsymmetricRows()
|
284 |
-
*/
|
285 |
-
public function getAsymmetricRows()
|
286 |
-
{
|
287 |
-
$ret_arr = array();
|
288 |
-
$hc = count($this->headers);
|
289 |
-
foreach ($this->rows as $row) {
|
290 |
-
if (count($row) != $hc) {
|
291 |
-
$ret_arr[] = $row;
|
292 |
-
}
|
293 |
-
}
|
294 |
-
return $ret_arr;
|
295 |
-
}
|
296 |
-
|
297 |
-
/**
|
298 |
-
* all rows length equalizer
|
299 |
-
*
|
300 |
-
* makes the length of all rows and headers the same. If no $value is given
|
301 |
-
* all unexistent cells will be filled with empty spaces
|
302 |
-
*
|
303 |
-
* @param mixed $value the value to fill the unexistent cells
|
304 |
-
*
|
305 |
-
* @access public
|
306 |
-
* @return array
|
307 |
-
* @see isSymmetric(), getAsymmetricRows(), symmetrize()
|
308 |
-
*/
|
309 |
-
public function symmetrize($value = '')
|
310 |
-
{
|
311 |
-
$max_length = 0;
|
312 |
-
$headers_length = count($this->headers);
|
313 |
-
|
314 |
-
foreach ($this->rows as $row) {
|
315 |
-
$row_length = count($row);
|
316 |
-
if ($max_length < $row_length) {
|
317 |
-
$max_length = $row_length;
|
318 |
-
}
|
319 |
-
}
|
320 |
-
|
321 |
-
if ($max_length < $headers_length) {
|
322 |
-
$max_length = $headers_length;
|
323 |
-
}
|
324 |
-
|
325 |
-
foreach ($this->rows as $key => $row) {
|
326 |
-
$this->rows[$key] = array_pad($row, $max_length, $value);
|
327 |
-
}
|
328 |
-
|
329 |
-
$this->headers = array_pad($this->headers, $max_length, $value);
|
330 |
-
}
|
331 |
-
|
332 |
-
/**
|
333 |
-
* grid walker
|
334 |
-
*
|
335 |
-
* travels through the whole dataset executing a callback per each
|
336 |
-
* cell
|
337 |
-
*
|
338 |
-
* Note: callback functions get the value of the cell as an
|
339 |
-
* argument, and whatever that callback returns will be used to
|
340 |
-
* replace the current value of that cell.
|
341 |
-
*
|
342 |
-
* @param string $callback the callback function to be called per
|
343 |
-
* each cell in the dataset.
|
344 |
-
*
|
345 |
-
* @access public
|
346 |
-
* @return void
|
347 |
-
* @see walkColumn(), walkRow(), fillColumn(), fillRow(), fillCell()
|
348 |
-
*/
|
349 |
-
public function walkGrid($callback)
|
350 |
-
{
|
351 |
-
foreach (array_keys($this->getRows()) as $key) {
|
352 |
-
if (!$this->walkRow($key, $callback)) {
|
353 |
-
return false;
|
354 |
-
}
|
355 |
-
}
|
356 |
-
return true;
|
357 |
-
}
|
358 |
-
|
359 |
-
/**
|
360 |
-
* column fetcher
|
361 |
-
*
|
362 |
-
* gets all the data for a specific column identified by $name
|
363 |
-
*
|
364 |
-
* Note $name is the same as the items returned by getHeaders()
|
365 |
-
*
|
366 |
-
* @param string $name the name of the column to fetch
|
367 |
-
*
|
368 |
-
* @access public
|
369 |
-
* @return array filled with values of a column
|
370 |
-
* @see getHeaders(), fillColumn(), appendColumn(), getCell(), getRows(),
|
371 |
-
* getRow(), hasColumn()
|
372 |
-
*/
|
373 |
-
public function getColumn($name)
|
374 |
-
{
|
375 |
-
if (!in_array($name, $this->headers)) {
|
376 |
-
return array();
|
377 |
-
}
|
378 |
-
$ret_arr = array();
|
379 |
-
$key = array_search($name, $this->headers, true);
|
380 |
-
foreach ($this->rows as $data) {
|
381 |
-
$ret_arr[] = $data[$key];
|
382 |
-
}
|
383 |
-
return $ret_arr;
|
384 |
-
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* column existance checker
|
388 |
-
*
|
389 |
-
* checks if a column exists, columns are identified by their
|
390 |
-
* header name.
|
391 |
-
*
|
392 |
-
* @param string $string an item returned by getHeaders()
|
393 |
-
*
|
394 |
-
* @access public
|
395 |
-
* @return boolean
|
396 |
-
* @see getHeaders()
|
397 |
-
*/
|
398 |
-
public function hasColumn($string)
|
399 |
-
{
|
400 |
-
return in_array($string, $this->headers);
|
401 |
-
}
|
402 |
-
|
403 |
-
/**
|
404 |
-
* column appender
|
405 |
-
*
|
406 |
-
* Appends a column and each or all values in it can be
|
407 |
-
*
|
408 |
-
* @param string $column an item returned by getHeaders()
|
409 |
-
* @param mixed $values same as fillColumn()
|
410 |
-
*
|
411 |
-
* @access public
|
412 |
-
* @return boolean
|
413 |
-
* @see getHeaders(), fillColumn(), fillCell(), createHeaders(),
|
414 |
-
* setHeaders()
|
415 |
-
*/
|
416 |
-
public function appendColumn($column, $values = null)
|
417 |
-
{
|
418 |
-
if ($this->hasColumn($column)) {
|
419 |
-
return false;
|
420 |
-
}
|
421 |
-
$this->headers[] = $column;
|
422 |
-
$length = $this->countHeaders();
|
423 |
-
$rows = array();
|
424 |
-
|
425 |
-
foreach ($this->rows as $row) {
|
426 |
-
$rows[] = array_pad($row, $length, '');
|
427 |
-
}
|
428 |
-
|
429 |
-
$this->rows = $rows;
|
430 |
-
|
431 |
-
if ($values === null) {
|
432 |
-
$values = '';
|
433 |
-
}
|
434 |
-
|
435 |
-
return $this->fillColumn($column, $values);
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* collumn data injector
|
440 |
-
*
|
441 |
-
* fills alll the data in the given column with $values
|
442 |
-
*
|
443 |
-
* @param mixed $column the column identified by a string
|
444 |
-
* @param mixed $values ither one of the following
|
445 |
-
* - (Number) will fill the whole column with the value of number
|
446 |
-
* - (String) will fill the whole column with the value of string
|
447 |
-
* - (Array) will fill the while column with the values of array
|
448 |
-
* the array gets ignored if it does not match the length of rows
|
449 |
-
*
|
450 |
-
* @access public
|
451 |
-
* @return void
|
452 |
-
*/
|
453 |
-
public function fillColumn($column, $values = null)
|
454 |
-
{
|
455 |
-
if (!$this->hasColumn($column)) {
|
456 |
-
return false;
|
457 |
-
}
|
458 |
-
|
459 |
-
if ($values === null) {
|
460 |
-
return false;
|
461 |
-
}
|
462 |
-
|
463 |
-
if (!$this->isSymmetric()) {
|
464 |
-
return false;
|
465 |
-
}
|
466 |
-
|
467 |
-
$y = array_search($column, $this->headers);
|
468 |
-
|
469 |
-
if (is_numeric($values) || is_string($values)) {
|
470 |
-
foreach (range(0, $this->countRows() -1) as $x) {
|
471 |
-
$this->fillCell($x, $y, $values);
|
472 |
-
}
|
473 |
-
return true;
|
474 |
-
}
|
475 |
-
|
476 |
-
if ($values === array()) {
|
477 |
-
return false;
|
478 |
-
}
|
479 |
-
|
480 |
-
$length = $this->countRows();
|
481 |
-
if (is_array($values) && $length == count($values)) {
|
482 |
-
for ($x = 0; $x < $length; $x++) {
|
483 |
-
$this->fillCell($x, $y, $values[$x]);
|
484 |
-
}
|
485 |
-
return true;
|
486 |
-
}
|
487 |
-
|
488 |
-
return false;
|
489 |
-
}
|
490 |
-
|
491 |
-
/**
|
492 |
-
* column remover
|
493 |
-
*
|
494 |
-
* Completly removes a whole column identified by $name
|
495 |
-
*
|
496 |
-
* @param string $name same as the ones returned by getHeaders();
|
497 |
-
*
|
498 |
-
* @access public
|
499 |
-
* @return boolean
|
500 |
-
* @see hasColumn(), getHeaders(), createHeaders(), setHeaders(),
|
501 |
-
* isSymmetric(), getAsymmetricRows()
|
502 |
-
*/
|
503 |
-
public function removeColumn($name)
|
504 |
-
{
|
505 |
-
if (!in_array($name, $this->headers)) {
|
506 |
-
return false;
|
507 |
-
}
|
508 |
-
|
509 |
-
if (!$this->isSymmetric()) {
|
510 |
-
return false;
|
511 |
-
}
|
512 |
-
|
513 |
-
$key = array_search($name, $this->headers);
|
514 |
-
unset($this->headers[$key]);
|
515 |
-
$this->resetKeys($this->headers);
|
516 |
-
|
517 |
-
foreach ($this->rows as $target => $row) {
|
518 |
-
unset($this->rows[$target][$key]);
|
519 |
-
$this->resetKeys($this->rows[$target]);
|
520 |
-
}
|
521 |
-
|
522 |
-
return $this->isSymmetric();
|
523 |
-
}
|
524 |
-
|
525 |
-
/**
|
526 |
-
* column walker
|
527 |
-
*
|
528 |
-
* goes through the whole column and executes a callback for each
|
529 |
-
* one of the cells in it.
|
530 |
-
*
|
531 |
-
* Note: callback functions get the value of the cell as an
|
532 |
-
* argument, and whatever that callback returns will be used to
|
533 |
-
* replace the current value of that cell.
|
534 |
-
*
|
535 |
-
* @param string $name the header name used to identify the column
|
536 |
-
* @param string $callback the callback function to be called per
|
537 |
-
* each cell value
|
538 |
-
*
|
539 |
-
* @access public
|
540 |
-
* @return boolean
|
541 |
-
* @see getHeaders(), fillColumn(), appendColumn()
|
542 |
-
*/
|
543 |
-
public function walkColumn($name, $callback)
|
544 |
-
{
|
545 |
-
if (!$this->isSymmetric()) {
|
546 |
-
return false;
|
547 |
-
}
|
548 |
-
|
549 |
-
if (!$this->hasColumn($name)) {
|
550 |
-
return false;
|
551 |
-
}
|
552 |
-
|
553 |
-
if (!function_exists($callback)) {
|
554 |
-
return false;
|
555 |
-
}
|
556 |
-
|
557 |
-
$column = $this->getColumn($name);
|
558 |
-
foreach ($column as $key => $cell) {
|
559 |
-
$column[$key] = $callback($cell);
|
560 |
-
}
|
561 |
-
return $this->fillColumn($name, $column);
|
562 |
-
}
|
563 |
-
|
564 |
-
/**
|
565 |
-
* cell fetcher
|
566 |
-
*
|
567 |
-
* gets the value of a specific cell by given coordinates
|
568 |
-
*
|
569 |
-
* @param integer $x the row to fetch
|
570 |
-
* @param integer $y the column to fetch
|
571 |
-
*
|
572 |
-
* @access public
|
573 |
-
* @return mixed|false the value of the cell or false if the cell does
|
574 |
-
* not exist
|
575 |
-
* @see getHeaders(), hasCell(), getRow(), getRows(), getColumn()
|
576 |
-
*/
|
577 |
-
public function getCell($x, $y)
|
578 |
-
{
|
579 |
-
if ($this->hasCell($x, $y)) {
|
580 |
-
$row = $this->getRow($x);
|
581 |
-
return $row[$y];
|
582 |
-
}
|
583 |
-
return false;
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
* cell value filler
|
588 |
-
*
|
589 |
-
* replaces the value of a specific cell
|
590 |
-
*
|
591 |
-
* @param integer $x the row to fetch
|
592 |
-
* @param integer $y the column to fetch
|
593 |
-
* @param mixed $value the value to fill the cell with
|
594 |
-
*
|
595 |
-
* @access public
|
596 |
-
* @return boolean
|
597 |
-
* @see hasCell(), getRow(), getRows(), getColumn()
|
598 |
-
*/
|
599 |
-
public function fillCell($x, $y, $value)
|
600 |
-
{
|
601 |
-
if (!$this->hasCell($x, $y)) {
|
602 |
-
return false;
|
603 |
-
}
|
604 |
-
$row = $this->getRow($x);
|
605 |
-
$row[$y] = $value;
|
606 |
-
$this->rows[$x] = $row;
|
607 |
-
return true;
|
608 |
-
}
|
609 |
-
|
610 |
-
/**
|
611 |
-
* checks if a coordinate is valid
|
612 |
-
*
|
613 |
-
* @param mixed $x the row to fetch
|
614 |
-
* @param mixed $y the column to fetch
|
615 |
-
*
|
616 |
-
* @access public
|
617 |
-
* @return void
|
618 |
-
*/
|
619 |
-
public function hasCell($x, $y)
|
620 |
-
{
|
621 |
-
$has_x = array_key_exists($x, $this->rows);
|
622 |
-
$has_y = array_key_exists($y, $this->headers);
|
623 |
-
return ($has_x && $has_y);
|
624 |
-
}
|
625 |
-
|
626 |
-
/**
|
627 |
-
* row fetcher
|
628 |
-
*
|
629 |
-
* Note: first row is zero
|
630 |
-
*
|
631 |
-
* @param integer $number the row number to fetch
|
632 |
-
*
|
633 |
-
* @access public
|
634 |
-
* @return array the row identified by number, if $number does
|
635 |
-
* not exist an empty array is returned instead
|
636 |
-
*/
|
637 |
-
public function getRow($number)
|
638 |
-
{
|
639 |
-
$raw = $this->rows;
|
640 |
-
if (array_key_exists($number, $raw)) {
|
641 |
-
return $raw[$number];
|
642 |
-
}
|
643 |
-
return array();
|
644 |
-
}
|
645 |
-
|
646 |
-
/**
|
647 |
-
* multiple row fetcher
|
648 |
-
*
|
649 |
-
* Extracts a rows in the following fashion
|
650 |
-
* - all rows if no $range argument is given
|
651 |
-
* - a range of rows identified by their key
|
652 |
-
* - if rows in range are not found nothing is retrived instead
|
653 |
-
* - if no rows were found an empty array is returned
|
654 |
-
*
|
655 |
-
* @param array $range a list of rows to retrive
|
656 |
-
*
|
657 |
-
* @access public
|
658 |
-
* @return array
|
659 |
-
*/
|
660 |
-
public function getRows($range = array())
|
661 |
-
{
|
662 |
-
if (is_array($range) && ($range === array())) {
|
663 |
-
return $this->rows;
|
664 |
-
}
|
665 |
-
|
666 |
-
if (!is_array($range)) {
|
667 |
-
return $this->rows;
|
668 |
-
}
|
669 |
-
|
670 |
-
$ret_arr = array();
|
671 |
-
foreach ($this->rows as $key => $row) {
|
672 |
-
if (in_array($key, $range)) {
|
673 |
-
$ret_arr[] = $row;
|
674 |
-
}
|
675 |
-
}
|
676 |
-
return $ret_arr;
|
677 |
-
}
|
678 |
-
|
679 |
-
/**
|
680 |
-
* row counter
|
681 |
-
*
|
682 |
-
* This function will exclude the headers
|
683 |
-
*
|
684 |
-
* @access public
|
685 |
-
* @return integer
|
686 |
-
*/
|
687 |
-
public function countRows()
|
688 |
-
{
|
689 |
-
return count($this->rows);
|
690 |
-
}
|
691 |
-
|
692 |
-
/**
|
693 |
-
* row appender
|
694 |
-
*
|
695 |
-
* Aggregates one more row to the currently loaded dataset
|
696 |
-
*
|
697 |
-
* @param array $values the values to be appended to the row
|
698 |
-
*
|
699 |
-
* @access public
|
700 |
-
* @return boolean
|
701 |
-
*/
|
702 |
-
public function appendRow($values)
|
703 |
-
{
|
704 |
-
$this->rows[] = array();
|
705 |
-
$this->symmetrize();
|
706 |
-
return $this->fillRow($this->countRows() - 1, $values);
|
707 |
-
}
|
708 |
-
|
709 |
-
/**
|
710 |
-
* fillRow
|
711 |
-
*
|
712 |
-
* Replaces the contents of cells in one given row with $values.
|
713 |
-
*
|
714 |
-
* @param integer $row the row to fill identified by its key
|
715 |
-
* @param mixed $values the value to use, if a string or number
|
716 |
-
* is given the whole row will be replaced with this value.
|
717 |
-
* if an array is given instead the values will be used to fill
|
718 |
-
* the row. Only when the currently loaded dataset is symmetric
|
719 |
-
*
|
720 |
-
* @access public
|
721 |
-
* @return boolean
|
722 |
-
* @see isSymmetric(), getAsymmetricRows(), symmetrize(), fillColumn(),
|
723 |
-
* fillCell(), appendRow()
|
724 |
-
*/
|
725 |
-
public function fillRow($row, $values)
|
726 |
-
{
|
727 |
-
if (!$this->hasRow($row)) {
|
728 |
-
return false;
|
729 |
-
}
|
730 |
-
|
731 |
-
if (is_string($values) || is_numeric($values)) {
|
732 |
-
foreach ($this->rows[$row] as $key => $cell) {
|
733 |
-
$this->rows[$row][$key] = $values;
|
734 |
-
}
|
735 |
-
return true;
|
736 |
-
}
|
737 |
-
|
738 |
-
$eql_to_headers = ($this->countHeaders() == count($values));
|
739 |
-
if (is_array($values) && $this->isSymmetric() && $eql_to_headers) {
|
740 |
-
$this->rows[$row] = $values;
|
741 |
-
return true;
|
742 |
-
}
|
743 |
-
|
744 |
-
return false;
|
745 |
-
}
|
746 |
-
|
747 |
-
/**
|
748 |
-
* row existance checker
|
749 |
-
*
|
750 |
-
* Scans currently loaded dataset and
|
751 |
-
* checks if a given row identified by $number exists
|
752 |
-
*
|
753 |
-
* @param mixed $number a numeric value that identifies the row
|
754 |
-
* you are trying to fetch.
|
755 |
-
*
|
756 |
-
* @access public
|
757 |
-
* @return boolean
|
758 |
-
* @see getRow(), getRows(), appendRow(), fillRow()
|
759 |
-
*/
|
760 |
-
public function hasRow($number)
|
761 |
-
{
|
762 |
-
return (in_array($number, array_keys($this->rows)));
|
763 |
-
}
|
764 |
-
|
765 |
-
/**
|
766 |
-
* row remover
|
767 |
-
*
|
768 |
-
* removes one row from the current data set.
|
769 |
-
*
|
770 |
-
*
|
771 |
-
* @param mixed $number the key that identifies that row
|
772 |
-
*
|
773 |
-
* @access public
|
774 |
-
* @return boolean
|
775 |
-
* @see hasColumn(), getHeaders(), createHeaders(), setHeaders(),
|
776 |
-
* isSymmetric(), getAsymmetricRows()
|
777 |
-
*/
|
778 |
-
public function removeRow($number)
|
779 |
-
{
|
780 |
-
$cnt = $this->countRows();
|
781 |
-
$row = $this->getRow($number);
|
782 |
-
if (is_array($row) && ($row != array())) {
|
783 |
-
unset($this->rows[$number]);
|
784 |
-
} else {
|
785 |
-
return false;
|
786 |
-
}
|
787 |
-
$this->resetKeys($this->rows);
|
788 |
-
return ($cnt == ($this->countRows() + 1));
|
789 |
-
}
|
790 |
-
|
791 |
-
/**
|
792 |
-
* row walker
|
793 |
-
*
|
794 |
-
* goes through one full row of data and executes a callback
|
795 |
-
* function per each cell in that row.
|
796 |
-
*
|
797 |
-
* Note: callback functions get the value of the cell as an
|
798 |
-
* argument, and whatever that callback returns will be used to
|
799 |
-
* replace the current value of that cell.
|
800 |
-
*
|
801 |
-
* @param string|integer $row anything that is numeric is a valid row
|
802 |
-
* identificator. As long as it is within the range of the currently
|
803 |
-
* loaded dataset
|
804 |
-
*
|
805 |
-
* @param string $callback the callback function to be executed
|
806 |
-
* per each cell in a row
|
807 |
-
*
|
808 |
-
* @access public
|
809 |
-
* @return boolean
|
810 |
-
* - false if callback does not exist
|
811 |
-
* - false if row does not exits
|
812 |
-
*/
|
813 |
-
public function walkRow($row, $callback)
|
814 |
-
{
|
815 |
-
if (!function_exists($callback)) {
|
816 |
-
return false;
|
817 |
-
}
|
818 |
-
if ($this->hasRow($row)) {
|
819 |
-
foreach ($this->getRow($row) as $key => $value) {
|
820 |
-
$this->rows[$row][$key] = $callback($value);
|
821 |
-
}
|
822 |
-
return true;
|
823 |
-
}
|
824 |
-
return false;
|
825 |
-
}
|
826 |
-
|
827 |
-
/**
|
828 |
-
* raw data as array
|
829 |
-
*
|
830 |
-
* Gets the data that was retrived from the csv file as an array
|
831 |
-
*
|
832 |
-
* Note: that changes and alterations made to rows, columns and
|
833 |
-
* values will also reflect on what this function retrives.
|
834 |
-
*
|
835 |
-
* @access public
|
836 |
-
* @return array
|
837 |
-
* @see connect(), getHeaders(), getRows(), isSymmetric(), getAsymmetricRows(),
|
838 |
-
* symmetrize()
|
839 |
-
*/
|
840 |
-
public function getRawArray()
|
841 |
-
{
|
842 |
-
$ret_arr = array();
|
843 |
-
|
844 |
-
foreach ($this->rows as $key => $row) {
|
845 |
-
$item = array();
|
846 |
-
foreach ($this->headers as $col => $value) {
|
847 |
-
$item[$value] = $this->fixEncoding($row[$col]);
|
848 |
-
}
|
849 |
-
array_push($ret_arr, $item);
|
850 |
-
unset($item);
|
851 |
-
}
|
852 |
-
return $ret_arr;
|
853 |
-
}
|
854 |
-
|
855 |
-
// Fixes the encoding to uf8
|
856 |
-
function fixEncoding($in_str)
|
857 |
-
{
|
858 |
-
if (function_exists('mb_detect_encoding') and function_exists('mb_check_encoding')){
|
859 |
-
$cur_encoding = mb_detect_encoding($in_str) ;
|
860 |
-
if($cur_encoding == "UTF-8" && mb_check_encoding($in_str,"UTF-8"))
|
861 |
-
return $in_str;
|
862 |
-
else
|
863 |
-
return utf8_encode($in_str);
|
864 |
-
}
|
865 |
-
|
866 |
-
return $in_str;
|
867 |
-
|
868 |
-
} // fixEncoding
|
869 |
-
|
870 |
-
/**
|
871 |
-
* header creator
|
872 |
-
*
|
873 |
-
* uses prefix and creates a header for each column suffixed by a
|
874 |
-
* numeric value
|
875 |
-
*
|
876 |
-
* @param string $prefix string to use as prefix for each
|
877 |
-
* independent header
|
878 |
-
*
|
879 |
-
* @access public
|
880 |
-
* @return boolean fails if data is not symmetric
|
881 |
-
* @see isSymmetric(), getAsymmetricRows()
|
882 |
-
*/
|
883 |
-
public function createHeaders($prefix)
|
884 |
-
{
|
885 |
-
if (!$this->isSymmetric()) {
|
886 |
-
return false;
|
887 |
-
}
|
888 |
-
|
889 |
-
$length = count($this->headers) + 1;
|
890 |
-
$this->moveHeadersToRows();
|
891 |
-
|
892 |
-
$ret_arr = array();
|
893 |
-
for ($i = 1; $i < $length; $i ++) {
|
894 |
-
$ret_arr[] = $prefix . "_$i";
|
895 |
-
}
|
896 |
-
$this->headers = $ret_arr;
|
897 |
-
return $this->isSymmetric();
|
898 |
-
}
|
899 |
-
|
900 |
-
/**
|
901 |
-
* header injector
|
902 |
-
*
|
903 |
-
* uses a $list of values which wil be used to replace current
|
904 |
-
* headers.
|
905 |
-
*
|
906 |
-
*
|
907 |
-
* @param array $list a collection of names to use as headers,
|
908 |
-
*
|
909 |
-
* @access public
|
910 |
-
* @return boolean fails if data is not symmetric
|
911 |
-
* @see isSymmetric(), getAsymmetricRows(), getHeaders(), createHeaders()
|
912 |
-
*/
|
913 |
-
public function setHeaders($list)
|
914 |
-
{
|
915 |
-
if (!$this->isSymmetric()) {
|
916 |
-
return false;
|
917 |
-
}
|
918 |
-
if (!is_array($list)) {
|
919 |
-
return false;
|
920 |
-
}
|
921 |
-
if (count($list) != count($this->headers)) {
|
922 |
-
return false;
|
923 |
-
}
|
924 |
-
$this->moveHeadersToRows();
|
925 |
-
$this->headers = $list;
|
926 |
-
return true;
|
927 |
-
}
|
928 |
-
|
929 |
-
/**
|
930 |
-
* csv parser
|
931 |
-
*
|
932 |
-
* reads csv data and transforms it into php-data
|
933 |
-
*
|
934 |
-
* @access protected
|
935 |
-
* @return boolean
|
936 |
-
*/
|
937 |
-
protected function parse()
|
938 |
-
{
|
939 |
-
if (!$this->validates()) {
|
940 |
-
return false;
|
941 |
-
}
|
942 |
-
|
943 |
-
$c = 0;
|
944 |
-
$d = $this->settings['delimiter'];
|
945 |
-
$e = $this->settings['escape'];
|
946 |
-
$l = $this->settings['length'];
|
947 |
-
|
948 |
-
$res = fopen($this->_filename, 'rb');
|
949 |
-
|
950 |
-
$wp_uploads = wp_upload_dir();
|
951 |
-
if ($this->large_import){
|
952 |
-
$tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($this->_filename)));
|
953 |
-
$this->xml_path = $wp_uploads['path'] .'/'. $tmpname;
|
954 |
-
$fp = fopen($this->xml_path, 'w');
|
955 |
-
fwrite($fp, "<?xml version=\"1.0\" encoding=\"utf-8\"?><data>");
|
956 |
-
}
|
957 |
-
$create_new_headers = false;
|
958 |
-
|
959 |
-
while ($keys = fgetcsv($res, $l, $d, $e)) {
|
960 |
-
|
961 |
-
if ($c == 0) {
|
962 |
-
|
963 |
-
foreach ($keys as $key => $value) {
|
964 |
-
if (!$create_new_headers and (preg_match('%\W(http:|https:|ftp:)$%i', $value) or is_numeric($value))) $create_new_headers = true;
|
965 |
-
$value = trim(strtolower(preg_replace('/^[0-9]{1}/','el_', preg_replace('/[^a-z0-9_]/i', '', $value))));
|
966 |
-
$keys[$key] = (!empty($value)) ? $value : 'undefined'.$key;
|
967 |
-
}
|
968 |
-
$this->headers = $keys;
|
969 |
-
if ($create_new_headers)
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
$
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
*
|
1024 |
-
*
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
*
|
1044 |
-
*
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
$
|
1075 |
-
$this->
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
*
|
1084 |
-
*
|
1085 |
-
*
|
1086 |
-
*
|
1087 |
-
*
|
1088 |
-
*
|
1089 |
-
*
|
1090 |
-
* @
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
$
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
*
|
1107 |
-
*
|
1108 |
-
*
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
$this->
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
$
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
$
|
1173 |
-
|
1174 |
-
//
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
$output['
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
*
|
1203 |
-
*
|
1204 |
-
*
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
4 |
+
|
5 |
+
/**
|
6 |
+
* contains a few csv file data access tools.
|
7 |
+
*
|
8 |
+
* PHP VERSION 5
|
9 |
+
*
|
10 |
+
* LICENSE: The MIT License
|
11 |
+
*
|
12 |
+
* Copyright (c) <2008> <Kazuyoshi Tlacaelel>
|
13 |
+
*
|
14 |
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 |
+
* of this software and associated documentation files (the "Software"), to deal
|
16 |
+
* in the Software without restriction, including without limitation the rights
|
17 |
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
18 |
+
* copies of the Software, and to permit persons to whom the Software is
|
19 |
+
* furnished to do so, subject to the following conditions:
|
20 |
+
*
|
21 |
+
* The above copyright notice and this permission notice shall be included in
|
22 |
+
* all copies or substantial portions of the Software.
|
23 |
+
*
|
24 |
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
25 |
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
26 |
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
27 |
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
28 |
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
29 |
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
30 |
+
* THE SOFTWARE.
|
31 |
+
*
|
32 |
+
* @category File
|
33 |
+
* @package File_CSV_DataSource
|
34 |
+
* @author Kazuyoshi Tlacaelel <kazu.dev@gmail.com>
|
35 |
+
* @copyright 2008 Kazuyoshi Tlacaelel
|
36 |
+
* @license The MIT License
|
37 |
+
* @version SVN: $Id: DataSource.php 285574 2009-03-09 15:22:24Z ktlacaelel $
|
38 |
+
* @link http://code.google.com/p/php-csv-parser/
|
39 |
+
*/
|
40 |
+
|
41 |
+
/**
|
42 |
+
* csv data fetcher
|
43 |
+
*
|
44 |
+
* Sample snippets refer to this csv file for demonstration.
|
45 |
+
* <code>
|
46 |
+
* name,age,skill
|
47 |
+
* john,13,knows magic
|
48 |
+
* tanaka,8,makes sushi
|
49 |
+
* jose,5,dances salsa
|
50 |
+
* </code>
|
51 |
+
*
|
52 |
+
* @category File
|
53 |
+
* @package Csv_parse
|
54 |
+
* @author Kazuyoshi Tlacaelel <kazu.dev@gmail.com>
|
55 |
+
* @copyright 2008 Kazuyoshi Tlacaelel
|
56 |
+
* @license The MIT License
|
57 |
+
* @link http://code.google.com/p/php-csv-parser/
|
58 |
+
*/
|
59 |
+
class PMXI_CsvParser
|
60 |
+
{
|
61 |
+
public
|
62 |
+
|
63 |
+
/**
|
64 |
+
* csv parsing default-settings
|
65 |
+
*
|
66 |
+
* @var array
|
67 |
+
* @access public
|
68 |
+
*/
|
69 |
+
$settings = array(
|
70 |
+
'delimiter' => ',',
|
71 |
+
'eol' => '',
|
72 |
+
'length' => 999999,
|
73 |
+
'escape' => '"'
|
74 |
+
),
|
75 |
+
|
76 |
+
$tmp_files = array(),
|
77 |
+
|
78 |
+
$xpath = '',
|
79 |
+
|
80 |
+
$large_import = false,
|
81 |
+
|
82 |
+
$htmlentities = false,
|
83 |
+
|
84 |
+
$xml_path = '',
|
85 |
+
|
86 |
+
$iteration = 0;
|
87 |
+
|
88 |
+
protected
|
89 |
+
|
90 |
+
/**
|
91 |
+
* imported data from csv
|
92 |
+
*
|
93 |
+
* @var array
|
94 |
+
* @access protected
|
95 |
+
*/
|
96 |
+
$rows = array(),
|
97 |
+
|
98 |
+
/**
|
99 |
+
* csv file to parse
|
100 |
+
*
|
101 |
+
* @var string
|
102 |
+
* @access protected
|
103 |
+
*/
|
104 |
+
$_filename = '',
|
105 |
+
|
106 |
+
/**
|
107 |
+
* csv headers to parse
|
108 |
+
*
|
109 |
+
* @var array
|
110 |
+
* @access protected
|
111 |
+
*/
|
112 |
+
$headers = array();
|
113 |
+
|
114 |
+
/**
|
115 |
+
* data load initialize
|
116 |
+
*
|
117 |
+
* @param mixed $filename please look at the load() method
|
118 |
+
*
|
119 |
+
* @access public
|
120 |
+
* @see load()
|
121 |
+
* @return void
|
122 |
+
*/
|
123 |
+
public function __construct($filename = null, $large_import = false, $xpath = '')
|
124 |
+
{
|
125 |
+
|
126 |
+
$this->large_import = $large_import;
|
127 |
+
$this->xpath = (!empty($xpath) ? $xpath : ((!empty($_POST['xpath'])) ? $_POST['xpath'] : '/node'));
|
128 |
+
|
129 |
+
ini_set( "display_errors", 0);
|
130 |
+
ini_set('auto_detect_line_endings', true);
|
131 |
+
|
132 |
+
$file_params = self::analyse_file($filename, 1);
|
133 |
+
|
134 |
+
$this->set_settings(array('delimiter' => $file_params['delimiter']['value'], 'eol' => $file_params['line_ending']['value']));
|
135 |
+
|
136 |
+
unset($file_params);
|
137 |
+
|
138 |
+
$this->load($filename);
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* csv file loader
|
143 |
+
*
|
144 |
+
* indicates the object which file is to be loaded
|
145 |
+
*
|
146 |
+
*
|
147 |
+
* @param string $filename the csv filename to load
|
148 |
+
*
|
149 |
+
* @access public
|
150 |
+
* @return boolean true if file was loaded successfully
|
151 |
+
* @see isSymmetric(), getAsymmetricRows(), symmetrize()
|
152 |
+
*/
|
153 |
+
public function load($filename)
|
154 |
+
{
|
155 |
+
$this->_filename = $filename;
|
156 |
+
$this->flush();
|
157 |
+
return $this->parse();
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* settings alterator
|
162 |
+
*
|
163 |
+
* lets you define different settings for scanning
|
164 |
+
*
|
165 |
+
*
|
166 |
+
* @param mixed $array containing settings to use
|
167 |
+
*
|
168 |
+
* @access public
|
169 |
+
* @return boolean true if changes where applyed successfully
|
170 |
+
* @see $settings
|
171 |
+
*/
|
172 |
+
public function set_settings($array)
|
173 |
+
{
|
174 |
+
$this->settings = array_merge($this->settings, $array);
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* header fetcher
|
179 |
+
*
|
180 |
+
* gets csv headers into an array
|
181 |
+
*
|
182 |
+
* @access public
|
183 |
+
* @return array
|
184 |
+
*/
|
185 |
+
public function getHeaders()
|
186 |
+
{
|
187 |
+
return $this->headers;
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* header counter
|
192 |
+
*
|
193 |
+
* retrives the total number of loaded headers
|
194 |
+
*
|
195 |
+
* @access public
|
196 |
+
* @return integer gets the length of headers
|
197 |
+
*/
|
198 |
+
public function countHeaders()
|
199 |
+
{
|
200 |
+
return count($this->headers);
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* header and row relationship builder
|
205 |
+
*
|
206 |
+
* Attempts to create a relationship for every single cell that
|
207 |
+
* was captured and its corresponding header. The sample below shows
|
208 |
+
* how a connection/relationship is built.
|
209 |
+
*
|
210 |
+
* @param array $columns the columns to connect, if nothing
|
211 |
+
* is given all headers will be used to create a connection
|
212 |
+
*
|
213 |
+
* @access public
|
214 |
+
* @return array If the data is not symmetric an empty array
|
215 |
+
* will be returned instead
|
216 |
+
* @see isSymmetric(), getAsymmetricRows(), symmetrize(), getHeaders()
|
217 |
+
*/
|
218 |
+
public function connect($columns = array())
|
219 |
+
{
|
220 |
+
if (!$this->isSymmetric()) {
|
221 |
+
return array();
|
222 |
+
}
|
223 |
+
if (!is_array($columns)) {
|
224 |
+
return array();
|
225 |
+
}
|
226 |
+
if ($columns === array()) {
|
227 |
+
$columns = $this->headers;
|
228 |
+
}
|
229 |
+
|
230 |
+
$ret_arr = array();
|
231 |
+
|
232 |
+
foreach ($this->rows as $record) {
|
233 |
+
$item_array = array();
|
234 |
+
foreach ($record as $column => $value) {
|
235 |
+
$header = $this->headers[$column];
|
236 |
+
if (in_array($header, $columns)) {
|
237 |
+
$item_array[$header] = $value;
|
238 |
+
}
|
239 |
+
}
|
240 |
+
|
241 |
+
// do not append empty results
|
242 |
+
if ($item_array !== array()) {
|
243 |
+
array_push($ret_arr, $item_array);
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
+
return $ret_arr;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* data length/symmetry checker
|
252 |
+
*
|
253 |
+
* tells if the headers and all of the contents length match.
|
254 |
+
* Note: there is a lot of methods that won't work if data is not
|
255 |
+
* symmetric this method is very important!
|
256 |
+
*
|
257 |
+
* @access public
|
258 |
+
* @return boolean
|
259 |
+
* @see symmetrize(), getAsymmetricRows(), isSymmetric()
|
260 |
+
*/
|
261 |
+
public function isSymmetric()
|
262 |
+
{
|
263 |
+
$hc = count($this->headers);
|
264 |
+
foreach ($this->rows as $row) {
|
265 |
+
if (count($row) != $hc) {
|
266 |
+
return false;
|
267 |
+
}
|
268 |
+
}
|
269 |
+
return true;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* asymmetric data fetcher
|
274 |
+
*
|
275 |
+
* finds the rows that do not match the headers length
|
276 |
+
*
|
277 |
+
* lets assume that we add one more row to our csv file.
|
278 |
+
* that has only two values. Something like
|
279 |
+
*
|
280 |
+
* @access public
|
281 |
+
* @return array filled with rows that do not match headers
|
282 |
+
* @see getHeaders(), symmetrize(), isSymmetric(),
|
283 |
+
* getAsymmetricRows()
|
284 |
+
*/
|
285 |
+
public function getAsymmetricRows()
|
286 |
+
{
|
287 |
+
$ret_arr = array();
|
288 |
+
$hc = count($this->headers);
|
289 |
+
foreach ($this->rows as $row) {
|
290 |
+
if (count($row) != $hc) {
|
291 |
+
$ret_arr[] = $row;
|
292 |
+
}
|
293 |
+
}
|
294 |
+
return $ret_arr;
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* all rows length equalizer
|
299 |
+
*
|
300 |
+
* makes the length of all rows and headers the same. If no $value is given
|
301 |
+
* all unexistent cells will be filled with empty spaces
|
302 |
+
*
|
303 |
+
* @param mixed $value the value to fill the unexistent cells
|
304 |
+
*
|
305 |
+
* @access public
|
306 |
+
* @return array
|
307 |
+
* @see isSymmetric(), getAsymmetricRows(), symmetrize()
|
308 |
+
*/
|
309 |
+
public function symmetrize($value = '')
|
310 |
+
{
|
311 |
+
$max_length = 0;
|
312 |
+
$headers_length = count($this->headers);
|
313 |
+
|
314 |
+
foreach ($this->rows as $row) {
|
315 |
+
$row_length = count($row);
|
316 |
+
if ($max_length < $row_length) {
|
317 |
+
$max_length = $row_length;
|
318 |
+
}
|
319 |
+
}
|
320 |
+
|
321 |
+
if ($max_length < $headers_length) {
|
322 |
+
$max_length = $headers_length;
|
323 |
+
}
|
324 |
+
|
325 |
+
foreach ($this->rows as $key => $row) {
|
326 |
+
$this->rows[$key] = array_pad($row, $max_length, $value);
|
327 |
+
}
|
328 |
+
|
329 |
+
$this->headers = array_pad($this->headers, $max_length, $value);
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* grid walker
|
334 |
+
*
|
335 |
+
* travels through the whole dataset executing a callback per each
|
336 |
+
* cell
|
337 |
+
*
|
338 |
+
* Note: callback functions get the value of the cell as an
|
339 |
+
* argument, and whatever that callback returns will be used to
|
340 |
+
* replace the current value of that cell.
|
341 |
+
*
|
342 |
+
* @param string $callback the callback function to be called per
|
343 |
+
* each cell in the dataset.
|
344 |
+
*
|
345 |
+
* @access public
|
346 |
+
* @return void
|
347 |
+
* @see walkColumn(), walkRow(), fillColumn(), fillRow(), fillCell()
|
348 |
+
*/
|
349 |
+
public function walkGrid($callback)
|
350 |
+
{
|
351 |
+
foreach (array_keys($this->getRows()) as $key) {
|
352 |
+
if (!$this->walkRow($key, $callback)) {
|
353 |
+
return false;
|
354 |
+
}
|
355 |
+
}
|
356 |
+
return true;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* column fetcher
|
361 |
+
*
|
362 |
+
* gets all the data for a specific column identified by $name
|
363 |
+
*
|
364 |
+
* Note $name is the same as the items returned by getHeaders()
|
365 |
+
*
|
366 |
+
* @param string $name the name of the column to fetch
|
367 |
+
*
|
368 |
+
* @access public
|
369 |
+
* @return array filled with values of a column
|
370 |
+
* @see getHeaders(), fillColumn(), appendColumn(), getCell(), getRows(),
|
371 |
+
* getRow(), hasColumn()
|
372 |
+
*/
|
373 |
+
public function getColumn($name)
|
374 |
+
{
|
375 |
+
if (!in_array($name, $this->headers)) {
|
376 |
+
return array();
|
377 |
+
}
|
378 |
+
$ret_arr = array();
|
379 |
+
$key = array_search($name, $this->headers, true);
|
380 |
+
foreach ($this->rows as $data) {
|
381 |
+
$ret_arr[] = $data[$key];
|
382 |
+
}
|
383 |
+
return $ret_arr;
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* column existance checker
|
388 |
+
*
|
389 |
+
* checks if a column exists, columns are identified by their
|
390 |
+
* header name.
|
391 |
+
*
|
392 |
+
* @param string $string an item returned by getHeaders()
|
393 |
+
*
|
394 |
+
* @access public
|
395 |
+
* @return boolean
|
396 |
+
* @see getHeaders()
|
397 |
+
*/
|
398 |
+
public function hasColumn($string)
|
399 |
+
{
|
400 |
+
return in_array($string, $this->headers);
|
401 |
+
}
|
402 |
+
|
403 |
+
/**
|
404 |
+
* column appender
|
405 |
+
*
|
406 |
+
* Appends a column and each or all values in it can be
|
407 |
+
*
|
408 |
+
* @param string $column an item returned by getHeaders()
|
409 |
+
* @param mixed $values same as fillColumn()
|
410 |
+
*
|
411 |
+
* @access public
|
412 |
+
* @return boolean
|
413 |
+
* @see getHeaders(), fillColumn(), fillCell(), createHeaders(),
|
414 |
+
* setHeaders()
|
415 |
+
*/
|
416 |
+
public function appendColumn($column, $values = null)
|
417 |
+
{
|
418 |
+
if ($this->hasColumn($column)) {
|
419 |
+
return false;
|
420 |
+
}
|
421 |
+
$this->headers[] = $column;
|
422 |
+
$length = $this->countHeaders();
|
423 |
+
$rows = array();
|
424 |
+
|
425 |
+
foreach ($this->rows as $row) {
|
426 |
+
$rows[] = array_pad($row, $length, '');
|
427 |
+
}
|
428 |
+
|
429 |
+
$this->rows = $rows;
|
430 |
+
|
431 |
+
if ($values === null) {
|
432 |
+
$values = '';
|
433 |
+
}
|
434 |
+
|
435 |
+
return $this->fillColumn($column, $values);
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* collumn data injector
|
440 |
+
*
|
441 |
+
* fills alll the data in the given column with $values
|
442 |
+
*
|
443 |
+
* @param mixed $column the column identified by a string
|
444 |
+
* @param mixed $values ither one of the following
|
445 |
+
* - (Number) will fill the whole column with the value of number
|
446 |
+
* - (String) will fill the whole column with the value of string
|
447 |
+
* - (Array) will fill the while column with the values of array
|
448 |
+
* the array gets ignored if it does not match the length of rows
|
449 |
+
*
|
450 |
+
* @access public
|
451 |
+
* @return void
|
452 |
+
*/
|
453 |
+
public function fillColumn($column, $values = null)
|
454 |
+
{
|
455 |
+
if (!$this->hasColumn($column)) {
|
456 |
+
return false;
|
457 |
+
}
|
458 |
+
|
459 |
+
if ($values === null) {
|
460 |
+
return false;
|
461 |
+
}
|
462 |
+
|
463 |
+
if (!$this->isSymmetric()) {
|
464 |
+
return false;
|
465 |
+
}
|
466 |
+
|
467 |
+
$y = array_search($column, $this->headers);
|
468 |
+
|
469 |
+
if (is_numeric($values) || is_string($values)) {
|
470 |
+
foreach (range(0, $this->countRows() -1) as $x) {
|
471 |
+
$this->fillCell($x, $y, $values);
|
472 |
+
}
|
473 |
+
return true;
|
474 |
+
}
|
475 |
+
|
476 |
+
if ($values === array()) {
|
477 |
+
return false;
|
478 |
+
}
|
479 |
+
|
480 |
+
$length = $this->countRows();
|
481 |
+
if (is_array($values) && $length == count($values)) {
|
482 |
+
for ($x = 0; $x < $length; $x++) {
|
483 |
+
$this->fillCell($x, $y, $values[$x]);
|
484 |
+
}
|
485 |
+
return true;
|
486 |
+
}
|
487 |
+
|
488 |
+
return false;
|
489 |
+
}
|
490 |
+
|
491 |
+
/**
|
492 |
+
* column remover
|
493 |
+
*
|
494 |
+
* Completly removes a whole column identified by $name
|
495 |
+
*
|
496 |
+
* @param string $name same as the ones returned by getHeaders();
|
497 |
+
*
|
498 |
+
* @access public
|
499 |
+
* @return boolean
|
500 |
+
* @see hasColumn(), getHeaders(), createHeaders(), setHeaders(),
|
501 |
+
* isSymmetric(), getAsymmetricRows()
|
502 |
+
*/
|
503 |
+
public function removeColumn($name)
|
504 |
+
{
|
505 |
+
if (!in_array($name, $this->headers)) {
|
506 |
+
return false;
|
507 |
+
}
|
508 |
+
|
509 |
+
if (!$this->isSymmetric()) {
|
510 |
+
return false;
|
511 |
+
}
|
512 |
+
|
513 |
+
$key = array_search($name, $this->headers);
|
514 |
+
unset($this->headers[$key]);
|
515 |
+
$this->resetKeys($this->headers);
|
516 |
+
|
517 |
+
foreach ($this->rows as $target => $row) {
|
518 |
+
unset($this->rows[$target][$key]);
|
519 |
+
$this->resetKeys($this->rows[$target]);
|
520 |
+
}
|
521 |
+
|
522 |
+
return $this->isSymmetric();
|
523 |
+
}
|
524 |
+
|
525 |
+
/**
|
526 |
+
* column walker
|
527 |
+
*
|
528 |
+
* goes through the whole column and executes a callback for each
|
529 |
+
* one of the cells in it.
|
530 |
+
*
|
531 |
+
* Note: callback functions get the value of the cell as an
|
532 |
+
* argument, and whatever that callback returns will be used to
|
533 |
+
* replace the current value of that cell.
|
534 |
+
*
|
535 |
+
* @param string $name the header name used to identify the column
|
536 |
+
* @param string $callback the callback function to be called per
|
537 |
+
* each cell value
|
538 |
+
*
|
539 |
+
* @access public
|
540 |
+
* @return boolean
|
541 |
+
* @see getHeaders(), fillColumn(), appendColumn()
|
542 |
+
*/
|
543 |
+
public function walkColumn($name, $callback)
|
544 |
+
{
|
545 |
+
if (!$this->isSymmetric()) {
|
546 |
+
return false;
|
547 |
+
}
|
548 |
+
|
549 |
+
if (!$this->hasColumn($name)) {
|
550 |
+
return false;
|
551 |
+
}
|
552 |
+
|
553 |
+
if (!function_exists($callback)) {
|
554 |
+
return false;
|
555 |
+
}
|
556 |
+
|
557 |
+
$column = $this->getColumn($name);
|
558 |
+
foreach ($column as $key => $cell) {
|
559 |
+
$column[$key] = $callback($cell);
|
560 |
+
}
|
561 |
+
return $this->fillColumn($name, $column);
|
562 |
+
}
|
563 |
+
|
564 |
+
/**
|
565 |
+
* cell fetcher
|
566 |
+
*
|
567 |
+
* gets the value of a specific cell by given coordinates
|
568 |
+
*
|
569 |
+
* @param integer $x the row to fetch
|
570 |
+
* @param integer $y the column to fetch
|
571 |
+
*
|
572 |
+
* @access public
|
573 |
+
* @return mixed|false the value of the cell or false if the cell does
|
574 |
+
* not exist
|
575 |
+
* @see getHeaders(), hasCell(), getRow(), getRows(), getColumn()
|
576 |
+
*/
|
577 |
+
public function getCell($x, $y)
|
578 |
+
{
|
579 |
+
if ($this->hasCell($x, $y)) {
|
580 |
+
$row = $this->getRow($x);
|
581 |
+
return $row[$y];
|
582 |
+
}
|
583 |
+
return false;
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
* cell value filler
|
588 |
+
*
|
589 |
+
* replaces the value of a specific cell
|
590 |
+
*
|
591 |
+
* @param integer $x the row to fetch
|
592 |
+
* @param integer $y the column to fetch
|
593 |
+
* @param mixed $value the value to fill the cell with
|
594 |
+
*
|
595 |
+
* @access public
|
596 |
+
* @return boolean
|
597 |
+
* @see hasCell(), getRow(), getRows(), getColumn()
|
598 |
+
*/
|
599 |
+
public function fillCell($x, $y, $value)
|
600 |
+
{
|
601 |
+
if (!$this->hasCell($x, $y)) {
|
602 |
+
return false;
|
603 |
+
}
|
604 |
+
$row = $this->getRow($x);
|
605 |
+
$row[$y] = $value;
|
606 |
+
$this->rows[$x] = $row;
|
607 |
+
return true;
|
608 |
+
}
|
609 |
+
|
610 |
+
/**
|
611 |
+
* checks if a coordinate is valid
|
612 |
+
*
|
613 |
+
* @param mixed $x the row to fetch
|
614 |
+
* @param mixed $y the column to fetch
|
615 |
+
*
|
616 |
+
* @access public
|
617 |
+
* @return void
|
618 |
+
*/
|
619 |
+
public function hasCell($x, $y)
|
620 |
+
{
|
621 |
+
$has_x = array_key_exists($x, $this->rows);
|
622 |
+
$has_y = array_key_exists($y, $this->headers);
|
623 |
+
return ($has_x && $has_y);
|
624 |
+
}
|
625 |
+
|
626 |
+
/**
|
627 |
+
* row fetcher
|
628 |
+
*
|
629 |
+
* Note: first row is zero
|
630 |
+
*
|
631 |
+
* @param integer $number the row number to fetch
|
632 |
+
*
|
633 |
+
* @access public
|
634 |
+
* @return array the row identified by number, if $number does
|
635 |
+
* not exist an empty array is returned instead
|
636 |
+
*/
|
637 |
+
public function getRow($number)
|
638 |
+
{
|
639 |
+
$raw = $this->rows;
|
640 |
+
if (array_key_exists($number, $raw)) {
|
641 |
+
return $raw[$number];
|
642 |
+
}
|
643 |
+
return array();
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* multiple row fetcher
|
648 |
+
*
|
649 |
+
* Extracts a rows in the following fashion
|
650 |
+
* - all rows if no $range argument is given
|
651 |
+
* - a range of rows identified by their key
|
652 |
+
* - if rows in range are not found nothing is retrived instead
|
653 |
+
* - if no rows were found an empty array is returned
|
654 |
+
*
|
655 |
+
* @param array $range a list of rows to retrive
|
656 |
+
*
|
657 |
+
* @access public
|
658 |
+
* @return array
|
659 |
+
*/
|
660 |
+
public function getRows($range = array())
|
661 |
+
{
|
662 |
+
if (is_array($range) && ($range === array())) {
|
663 |
+
return $this->rows;
|
664 |
+
}
|
665 |
+
|
666 |
+
if (!is_array($range)) {
|
667 |
+
return $this->rows;
|
668 |
+
}
|
669 |
+
|
670 |
+
$ret_arr = array();
|
671 |
+
foreach ($this->rows as $key => $row) {
|
672 |
+
if (in_array($key, $range)) {
|
673 |
+
$ret_arr[] = $row;
|
674 |
+
}
|
675 |
+
}
|
676 |
+
return $ret_arr;
|
677 |
+
}
|
678 |
+
|
679 |
+
/**
|
680 |
+
* row counter
|
681 |
+
*
|
682 |
+
* This function will exclude the headers
|
683 |
+
*
|
684 |
+
* @access public
|
685 |
+
* @return integer
|
686 |
+
*/
|
687 |
+
public function countRows()
|
688 |
+
{
|
689 |
+
return count($this->rows);
|
690 |
+
}
|
691 |
+
|
692 |
+
/**
|
693 |
+
* row appender
|
694 |
+
*
|
695 |
+
* Aggregates one more row to the currently loaded dataset
|
696 |
+
*
|
697 |
+
* @param array $values the values to be appended to the row
|
698 |
+
*
|
699 |
+
* @access public
|
700 |
+
* @return boolean
|
701 |
+
*/
|
702 |
+
public function appendRow($values)
|
703 |
+
{
|
704 |
+
$this->rows[] = array();
|
705 |
+
$this->symmetrize();
|
706 |
+
return $this->fillRow($this->countRows() - 1, $values);
|
707 |
+
}
|
708 |
+
|
709 |
+
/**
|
710 |
+
* fillRow
|
711 |
+
*
|
712 |
+
* Replaces the contents of cells in one given row with $values.
|
713 |
+
*
|
714 |
+
* @param integer $row the row to fill identified by its key
|
715 |
+
* @param mixed $values the value to use, if a string or number
|
716 |
+
* is given the whole row will be replaced with this value.
|
717 |
+
* if an array is given instead the values will be used to fill
|
718 |
+
* the row. Only when the currently loaded dataset is symmetric
|
719 |
+
*
|
720 |
+
* @access public
|
721 |
+
* @return boolean
|
722 |
+
* @see isSymmetric(), getAsymmetricRows(), symmetrize(), fillColumn(),
|
723 |
+
* fillCell(), appendRow()
|
724 |
+
*/
|
725 |
+
public function fillRow($row, $values)
|
726 |
+
{
|
727 |
+
if (!$this->hasRow($row)) {
|
728 |
+
return false;
|
729 |
+
}
|
730 |
+
|
731 |
+
if (is_string($values) || is_numeric($values)) {
|
732 |
+
foreach ($this->rows[$row] as $key => $cell) {
|
733 |
+
$this->rows[$row][$key] = $values;
|
734 |
+
}
|
735 |
+
return true;
|
736 |
+
}
|
737 |
+
|
738 |
+
$eql_to_headers = ($this->countHeaders() == count($values));
|
739 |
+
if (is_array($values) && $this->isSymmetric() && $eql_to_headers) {
|
740 |
+
$this->rows[$row] = $values;
|
741 |
+
return true;
|
742 |
+
}
|
743 |
+
|
744 |
+
return false;
|
745 |
+
}
|
746 |
+
|
747 |
+
/**
|
748 |
+
* row existance checker
|
749 |
+
*
|
750 |
+
* Scans currently loaded dataset and
|
751 |
+
* checks if a given row identified by $number exists
|
752 |
+
*
|
753 |
+
* @param mixed $number a numeric value that identifies the row
|
754 |
+
* you are trying to fetch.
|
755 |
+
*
|
756 |
+
* @access public
|
757 |
+
* @return boolean
|
758 |
+
* @see getRow(), getRows(), appendRow(), fillRow()
|
759 |
+
*/
|
760 |
+
public function hasRow($number)
|
761 |
+
{
|
762 |
+
return (in_array($number, array_keys($this->rows)));
|
763 |
+
}
|
764 |
+
|
765 |
+
/**
|
766 |
+
* row remover
|
767 |
+
*
|
768 |
+
* removes one row from the current data set.
|
769 |
+
*
|
770 |
+
*
|
771 |
+
* @param mixed $number the key that identifies that row
|
772 |
+
*
|
773 |
+
* @access public
|
774 |
+
* @return boolean
|
775 |
+
* @see hasColumn(), getHeaders(), createHeaders(), setHeaders(),
|
776 |
+
* isSymmetric(), getAsymmetricRows()
|
777 |
+
*/
|
778 |
+
public function removeRow($number)
|
779 |
+
{
|
780 |
+
$cnt = $this->countRows();
|
781 |
+
$row = $this->getRow($number);
|
782 |
+
if (is_array($row) && ($row != array())) {
|
783 |
+
unset($this->rows[$number]);
|
784 |
+
} else {
|
785 |
+
return false;
|
786 |
+
}
|
787 |
+
$this->resetKeys($this->rows);
|
788 |
+
return ($cnt == ($this->countRows() + 1));
|
789 |
+
}
|
790 |
+
|
791 |
+
/**
|
792 |
+
* row walker
|
793 |
+
*
|
794 |
+
* goes through one full row of data and executes a callback
|
795 |
+
* function per each cell in that row.
|
796 |
+
*
|
797 |
+
* Note: callback functions get the value of the cell as an
|
798 |
+
* argument, and whatever that callback returns will be used to
|
799 |
+
* replace the current value of that cell.
|
800 |
+
*
|
801 |
+
* @param string|integer $row anything that is numeric is a valid row
|
802 |
+
* identificator. As long as it is within the range of the currently
|
803 |
+
* loaded dataset
|
804 |
+
*
|
805 |
+
* @param string $callback the callback function to be executed
|
806 |
+
* per each cell in a row
|
807 |
+
*
|
808 |
+
* @access public
|
809 |
+
* @return boolean
|
810 |
+
* - false if callback does not exist
|
811 |
+
* - false if row does not exits
|
812 |
+
*/
|
813 |
+
public function walkRow($row, $callback)
|
814 |
+
{
|
815 |
+
if (!function_exists($callback)) {
|
816 |
+
return false;
|
817 |
+
}
|
818 |
+
if ($this->hasRow($row)) {
|
819 |
+
foreach ($this->getRow($row) as $key => $value) {
|
820 |
+
$this->rows[$row][$key] = $callback($value);
|
821 |
+
}
|
822 |
+
return true;
|
823 |
+
}
|
824 |
+
return false;
|
825 |
+
}
|
826 |
+
|
827 |
+
/**
|
828 |
+
* raw data as array
|
829 |
+
*
|
830 |
+
* Gets the data that was retrived from the csv file as an array
|
831 |
+
*
|
832 |
+
* Note: that changes and alterations made to rows, columns and
|
833 |
+
* values will also reflect on what this function retrives.
|
834 |
+
*
|
835 |
+
* @access public
|
836 |
+
* @return array
|
837 |
+
* @see connect(), getHeaders(), getRows(), isSymmetric(), getAsymmetricRows(),
|
838 |
+
* symmetrize()
|
839 |
+
*/
|
840 |
+
public function getRawArray()
|
841 |
+
{
|
842 |
+
$ret_arr = array();
|
843 |
+
|
844 |
+
foreach ($this->rows as $key => $row) {
|
845 |
+
$item = array();
|
846 |
+
foreach ($this->headers as $col => $value) {
|
847 |
+
$item[$value] = $this->fixEncoding($row[$col]);
|
848 |
+
}
|
849 |
+
array_push($ret_arr, $item);
|
850 |
+
unset($item);
|
851 |
+
}
|
852 |
+
return $ret_arr;
|
853 |
+
}
|
854 |
+
|
855 |
+
// Fixes the encoding to uf8
|
856 |
+
function fixEncoding($in_str)
|
857 |
+
{
|
858 |
+
if (function_exists('mb_detect_encoding') and function_exists('mb_check_encoding')){
|
859 |
+
$cur_encoding = mb_detect_encoding($in_str) ;
|
860 |
+
if($cur_encoding == "UTF-8" && mb_check_encoding($in_str,"UTF-8"))
|
861 |
+
return $in_str;
|
862 |
+
else
|
863 |
+
return utf8_encode($in_str);
|
864 |
+
}
|
865 |
+
|
866 |
+
return $in_str;
|
867 |
+
|
868 |
+
} // fixEncoding
|
869 |
+
|
870 |
+
/**
|
871 |
+
* header creator
|
872 |
+
*
|
873 |
+
* uses prefix and creates a header for each column suffixed by a
|
874 |
+
* numeric value
|
875 |
+
*
|
876 |
+
* @param string $prefix string to use as prefix for each
|
877 |
+
* independent header
|
878 |
+
*
|
879 |
+
* @access public
|
880 |
+
* @return boolean fails if data is not symmetric
|
881 |
+
* @see isSymmetric(), getAsymmetricRows()
|
882 |
+
*/
|
883 |
+
public function createHeaders($prefix)
|
884 |
+
{
|
885 |
+
if (!$this->isSymmetric()) {
|
886 |
+
return false;
|
887 |
+
}
|
888 |
+
|
889 |
+
$length = count($this->headers) + 1;
|
890 |
+
$this->moveHeadersToRows();
|
891 |
+
|
892 |
+
$ret_arr = array();
|
893 |
+
for ($i = 1; $i < $length; $i ++) {
|
894 |
+
$ret_arr[] = $prefix . "_$i";
|
895 |
+
}
|
896 |
+
$this->headers = $ret_arr;
|
897 |
+
return $this->isSymmetric();
|
898 |
+
}
|
899 |
+
|
900 |
+
/**
|
901 |
+
* header injector
|
902 |
+
*
|
903 |
+
* uses a $list of values which wil be used to replace current
|
904 |
+
* headers.
|
905 |
+
*
|
906 |
+
*
|
907 |
+
* @param array $list a collection of names to use as headers,
|
908 |
+
*
|
909 |
+
* @access public
|
910 |
+
* @return boolean fails if data is not symmetric
|
911 |
+
* @see isSymmetric(), getAsymmetricRows(), getHeaders(), createHeaders()
|
912 |
+
*/
|
913 |
+
public function setHeaders($list)
|
914 |
+
{
|
915 |
+
if (!$this->isSymmetric()) {
|
916 |
+
return false;
|
917 |
+
}
|
918 |
+
if (!is_array($list)) {
|
919 |
+
return false;
|
920 |
+
}
|
921 |
+
if (count($list) != count($this->headers)) {
|
922 |
+
return false;
|
923 |
+
}
|
924 |
+
$this->moveHeadersToRows();
|
925 |
+
$this->headers = $list;
|
926 |
+
return true;
|
927 |
+
}
|
928 |
+
|
929 |
+
/**
|
930 |
+
* csv parser
|
931 |
+
*
|
932 |
+
* reads csv data and transforms it into php-data
|
933 |
+
*
|
934 |
+
* @access protected
|
935 |
+
* @return boolean
|
936 |
+
*/
|
937 |
+
protected function parse()
|
938 |
+
{
|
939 |
+
if (!$this->validates()) {
|
940 |
+
return false;
|
941 |
+
}
|
942 |
+
|
943 |
+
$c = 0;
|
944 |
+
$d = $this->settings['delimiter'];
|
945 |
+
$e = $this->settings['escape'];
|
946 |
+
$l = $this->settings['length'];
|
947 |
+
|
948 |
+
$res = fopen($this->_filename, 'rb');
|
949 |
+
|
950 |
+
$wp_uploads = wp_upload_dir();
|
951 |
+
if ($this->large_import){
|
952 |
+
$tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($this->_filename)));
|
953 |
+
$this->xml_path = $wp_uploads['path'] .'/'. $tmpname;
|
954 |
+
$fp = fopen($this->xml_path, 'w');
|
955 |
+
fwrite($fp, "<?xml version=\"1.0\" encoding=\"utf-8\"?><data>");
|
956 |
+
}
|
957 |
+
$create_new_headers = false;
|
958 |
+
|
959 |
+
while ($keys = fgetcsv($res, $l, $d, $e)) {
|
960 |
+
|
961 |
+
if ($c == 0) {
|
962 |
+
$buf_keys = $keys;
|
963 |
+
foreach ($keys as $key => $value) {
|
964 |
+
if (!$create_new_headers and (preg_match('%\W(http:|https:|ftp:)$%i', $value) or is_numeric($value))) $create_new_headers = true;
|
965 |
+
$value = trim(strtolower(preg_replace('/^[0-9]{1}/','el_', preg_replace('/[^a-z0-9_]/i', '', $value))));
|
966 |
+
$keys[$key] = (!empty($value)) ? $value : 'undefined'.$key;
|
967 |
+
}
|
968 |
+
$this->headers = $keys;
|
969 |
+
if ($create_new_headers){
|
970 |
+
$this->createHeaders('column');
|
971 |
+
$keys = $buf_keys;
|
972 |
+
}
|
973 |
+
}
|
974 |
+
|
975 |
+
if ($c or $create_new_headers) {
|
976 |
+
if (!$this->large_import and empty($_POST['large_file'])) {
|
977 |
+
array_push($this->rows, $keys);
|
978 |
+
}
|
979 |
+
else if (!empty($keys)){
|
980 |
+
|
981 |
+
$chunk = array();
|
982 |
+
|
983 |
+
foreach ($this->headers as $key => $header) {
|
984 |
+
$chunk[$header] = $this->fixEncoding(htmlentities($keys[$key]));
|
985 |
+
}
|
986 |
+
|
987 |
+
if (!empty($chunk))
|
988 |
+
{
|
989 |
+
fwrite($fp, "<node>");
|
990 |
+
foreach ($chunk as $header => $value) fwrite($fp, "<".$header.">".$value."</".$header.">");
|
991 |
+
fwrite($fp, "</node>");
|
992 |
+
}
|
993 |
+
}
|
994 |
+
}
|
995 |
+
|
996 |
+
$c ++;
|
997 |
+
}
|
998 |
+
fwrite($fp, '</data>');
|
999 |
+
fclose($fp);
|
1000 |
+
fclose($res);
|
1001 |
+
$this->removeEmpty();
|
1002 |
+
|
1003 |
+
/*$errors = array();
|
1004 |
+
$xml = file_get_contents($this->xml_path);
|
1005 |
+
|
1006 |
+
PMXI_Import_Record::preprocessXml($xml);
|
1007 |
+
|
1008 |
+
if (PMXI_Import_Record::validateXml($xml, $errors)){
|
1009 |
+
return true;
|
1010 |
+
}
|
1011 |
+
else{
|
1012 |
+
$this->htmlentities = true;
|
1013 |
+
$this->rows = array();
|
1014 |
+
$this->iteration++;
|
1015 |
+
if ($this->iteration > 1) return true;
|
1016 |
+
return $this->parse();
|
1017 |
+
} */
|
1018 |
+
|
1019 |
+
return true;
|
1020 |
+
}
|
1021 |
+
|
1022 |
+
/**
|
1023 |
+
* empty row remover
|
1024 |
+
*
|
1025 |
+
* removes all records that have been defined but have no data.
|
1026 |
+
*
|
1027 |
+
* @access protected
|
1028 |
+
* @return array containing only the rows that have data
|
1029 |
+
*/
|
1030 |
+
protected function removeEmpty()
|
1031 |
+
{
|
1032 |
+
$ret_arr = array();
|
1033 |
+
foreach ($this->rows as $row) {
|
1034 |
+
$line = trim(join('', $row));
|
1035 |
+
if (!empty($line)) {
|
1036 |
+
$ret_arr[] = $row;
|
1037 |
+
}
|
1038 |
+
}
|
1039 |
+
$this->rows = $ret_arr;
|
1040 |
+
}
|
1041 |
+
|
1042 |
+
/**
|
1043 |
+
* csv file validator
|
1044 |
+
*
|
1045 |
+
* checks wheather if the given csv file is valid or not
|
1046 |
+
*
|
1047 |
+
* @access protected
|
1048 |
+
* @return boolean
|
1049 |
+
*/
|
1050 |
+
protected function validates()
|
1051 |
+
{
|
1052 |
+
// file existance
|
1053 |
+
if (!file_exists($this->_filename)) {
|
1054 |
+
return false;
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
// file readability
|
1058 |
+
if (!is_readable($this->_filename)) {
|
1059 |
+
return false;
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
return true;
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
/**
|
1066 |
+
* header relocator
|
1067 |
+
*
|
1068 |
+
* @access protected
|
1069 |
+
* @return void
|
1070 |
+
*/
|
1071 |
+
protected function moveHeadersToRows()
|
1072 |
+
{
|
1073 |
+
$arr = array();
|
1074 |
+
$arr[] = $this->headers;
|
1075 |
+
foreach ($this->rows as $row) {
|
1076 |
+
$arr[] = $row;
|
1077 |
+
}
|
1078 |
+
$this->rows = $arr;
|
1079 |
+
$this->headers = array();
|
1080 |
+
}
|
1081 |
+
|
1082 |
+
/**
|
1083 |
+
* array key reseter
|
1084 |
+
*
|
1085 |
+
* makes sure that an array's keys are setted in a correct numerical order
|
1086 |
+
*
|
1087 |
+
* Note: that this function does not return anything, all changes
|
1088 |
+
* are made to the original array as a reference
|
1089 |
+
*
|
1090 |
+
* @param array &$array any array, if keys are strings they will
|
1091 |
+
* be replaced with numeric values
|
1092 |
+
*
|
1093 |
+
* @access protected
|
1094 |
+
* @return void
|
1095 |
+
*/
|
1096 |
+
protected function resetKeys(&$array)
|
1097 |
+
{
|
1098 |
+
$arr = array();
|
1099 |
+
foreach ($array as $item) {
|
1100 |
+
$arr[] = $item;
|
1101 |
+
}
|
1102 |
+
$array = $arr;
|
1103 |
+
}
|
1104 |
+
|
1105 |
+
/**
|
1106 |
+
* object data flusher
|
1107 |
+
*
|
1108 |
+
* tells this object to forget all data loaded and start from
|
1109 |
+
* scratch
|
1110 |
+
*
|
1111 |
+
* @access protected
|
1112 |
+
* @return void
|
1113 |
+
*/
|
1114 |
+
protected function flush()
|
1115 |
+
{
|
1116 |
+
$this->rows = array();
|
1117 |
+
$this->headers = array();
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
public function toXml() {
|
1121 |
+
$this->symmetrize();
|
1122 |
+
return ArrayToXML::toXml($this->getRawArray());
|
1123 |
+
}
|
1124 |
+
|
1125 |
+
function analyse_file($file, $capture_limit_in_kb = 10) {
|
1126 |
+
// capture starting memory usage
|
1127 |
+
$output['peak_mem']['start'] = memory_get_peak_usage(true);
|
1128 |
+
|
1129 |
+
// log the limit how much of the file was sampled (in Kb)
|
1130 |
+
$output['read_kb'] = $capture_limit_in_kb;
|
1131 |
+
|
1132 |
+
// read in file
|
1133 |
+
$fh = fopen($file, 'r');
|
1134 |
+
$contents = fgets($fh);
|
1135 |
+
fclose($fh);
|
1136 |
+
|
1137 |
+
// specify allowed field delimiters
|
1138 |
+
$delimiters = array(
|
1139 |
+
'comma' => ',',
|
1140 |
+
'semicolon' => ';',
|
1141 |
+
'pipe' => '|',
|
1142 |
+
'tabulation' => "\t"
|
1143 |
+
);
|
1144 |
+
|
1145 |
+
// specify allowed line endings
|
1146 |
+
$line_endings = array(
|
1147 |
+
'rn' => "\r\n",
|
1148 |
+
'n' => "\n",
|
1149 |
+
'r' => "\r",
|
1150 |
+
'nr' => "\n\r"
|
1151 |
+
);
|
1152 |
+
|
1153 |
+
// loop and count each line ending instance
|
1154 |
+
foreach ($line_endings as $key => $value) {
|
1155 |
+
$line_result[$key] = substr_count($contents, $value);
|
1156 |
+
}
|
1157 |
+
|
1158 |
+
// sort by largest array value
|
1159 |
+
asort($line_result);
|
1160 |
+
|
1161 |
+
// log to output array
|
1162 |
+
$output['line_ending']['results'] = $line_result;
|
1163 |
+
$output['line_ending']['count'] = end($line_result);
|
1164 |
+
$output['line_ending']['key'] = key($line_result);
|
1165 |
+
$output['line_ending']['value'] = $line_endings[$output['line_ending']['key']];
|
1166 |
+
$lines = explode($output['line_ending']['value'], $contents);
|
1167 |
+
|
1168 |
+
// remove last line of array, as this maybe incomplete?
|
1169 |
+
array_pop($lines);
|
1170 |
+
|
1171 |
+
// create a string from the legal lines
|
1172 |
+
$complete_lines = implode(' ', $lines);
|
1173 |
+
|
1174 |
+
// log statistics to output array
|
1175 |
+
$output['lines']['count'] = count($lines);
|
1176 |
+
$output['lines']['length'] = strlen($complete_lines);
|
1177 |
+
|
1178 |
+
// loop and count each delimiter instance
|
1179 |
+
foreach ($delimiters as $delimiter_key => $delimiter) {
|
1180 |
+
$delimiter_result[$delimiter_key] = substr_count($complete_lines, $delimiter);
|
1181 |
+
}
|
1182 |
+
|
1183 |
+
// sort by largest array value
|
1184 |
+
asort($delimiter_result);
|
1185 |
+
|
1186 |
+
// log statistics to output array with largest counts as the value
|
1187 |
+
$output['delimiter']['results'] = $delimiter_result;
|
1188 |
+
$output['delimiter']['count'] = end($delimiter_result);
|
1189 |
+
$output['delimiter']['key'] = key($delimiter_result);
|
1190 |
+
$output['delimiter']['value'] = $delimiters[$output['delimiter']['key']];
|
1191 |
+
|
1192 |
+
// capture ending memory usage
|
1193 |
+
$output['peak_mem']['end'] = memory_get_peak_usage(true);
|
1194 |
+
return $output;
|
1195 |
+
}
|
1196 |
+
|
1197 |
+
}
|
1198 |
+
|
1199 |
+
class ArrayToXML
|
1200 |
+
{
|
1201 |
+
/**
|
1202 |
+
* The main function for converting to an XML document.
|
1203 |
+
* Pass in a multi dimensional array and this recrusively loops through and builds up an XML document.
|
1204 |
+
*
|
1205 |
+
* @param array $data
|
1206 |
+
* @param string $rootNodeName - what you want the root node to be - defaultsto data.
|
1207 |
+
* @param SimpleXMLElement $xml - should only be used recursively
|
1208 |
+
* @return string XML
|
1209 |
+
*/
|
1210 |
+
public static function toXml($data, $rootNodeName = 'data', $xml=null)
|
1211 |
+
{
|
1212 |
+
// turn off compatibility mode as simple xml throws a wobbly if you don't.
|
1213 |
+
if (ini_get('zend.ze1_compatibility_mode') == 1)
|
1214 |
+
{
|
1215 |
+
ini_set ('zend.ze1_compatibility_mode', 0);
|
1216 |
+
}
|
1217 |
+
|
1218 |
+
if ($xml == null)
|
1219 |
+
{
|
1220 |
+
$xml = simplexml_load_string('<?xml version="1.0" encoding="utf-8"?><'.$rootNodeName .'/>');
|
1221 |
+
}
|
1222 |
+
|
1223 |
+
// loop through the data passed in.
|
1224 |
+
foreach($data as $key => $value)
|
1225 |
+
{
|
1226 |
+
// no numeric keys in our xml please!
|
1227 |
+
if (is_numeric($key))
|
1228 |
+
{
|
1229 |
+
// make string key...
|
1230 |
+
$key = "node";
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
// replace anything not alpha numeric
|
1234 |
+
$key = preg_replace('/[^a-z0-9_]/i', '', $key);
|
1235 |
+
|
1236 |
+
// if there is another array found recrusively call this function
|
1237 |
+
if (is_array($value) or is_object($value))
|
1238 |
+
{
|
1239 |
+
$node = $xml->addChild($key);
|
1240 |
+
// recrusive call.
|
1241 |
+
ArrayToXML::toXml($value, $rootNodeName, $node);
|
1242 |
+
}
|
1243 |
+
else
|
1244 |
+
{
|
1245 |
+
// add single node.
|
1246 |
+
$value = htmlspecialchars($value);
|
1247 |
+
$xml->addChild($key,$value);
|
1248 |
+
}
|
1249 |
+
|
1250 |
+
}
|
1251 |
+
// pass back as string. or simple xml object if you want!
|
1252 |
+
return $xml->asXML();
|
1253 |
+
}
|
1254 |
+
|
1255 |
+
|
1256 |
+
}
|
1257 |
+
|
1258 |
+
?>
|
libraries/XmlImportException.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
/**
|
8 |
-
* XmlImport library exception
|
9 |
-
*/
|
10 |
class XmlImportException extends Exception {}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**
|
8 |
+
* XmlImport library exception
|
9 |
+
*/
|
10 |
class XmlImportException extends Exception {}
|
libraries/XmlImportParser.php
CHANGED
@@ -1,116 +1,116 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
5 |
-
* @package General
|
6 |
-
*/
|
7 |
-
|
8 |
-
require_once dirname(__FILE__) . '/XmlImportTemplate.php';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Is used to parse XML using specified template and root node
|
12 |
-
*/
|
13 |
-
class XmlImportParser {
|
14 |
-
/**
|
15 |
-
* SimpleXmlElement instance for the xml file
|
16 |
-
*
|
17 |
-
* @var SimpleXMLElement
|
18 |
-
*/
|
19 |
-
protected $xml;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* XPath expression for selecting the root node of the record
|
23 |
-
*
|
24 |
-
* @var string
|
25 |
-
*/
|
26 |
-
protected $rootNodeXPath;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Path to cached template
|
30 |
-
*
|
31 |
-
* @var string
|
32 |
-
*/
|
33 |
-
protected $cachedTemplate;
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Creates new parser instance
|
37 |
-
*
|
38 |
-
* @param string $xml
|
39 |
-
* @param string $rootNodeXPath XPath for the record root node
|
40 |
-
* @param string $cachedTemplate path to cached template
|
41 |
-
* @param bool $isURL whether xml is URL or path
|
42 |
-
*/
|
43 |
-
public function __construct($xml, $rootNodeXPath, $cachedTemplate, $isURL = false)
|
44 |
-
{
|
45 |
-
if ($isURL) {
|
46 |
-
$xml = file_get_contents($xml);
|
47 |
-
}
|
48 |
-
|
49 |
-
// FIX: remove default namespace because libxml xpath implementation doesn't handle it properly
|
50 |
-
$xml and $xml = preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml);
|
51 |
-
|
52 |
-
libxml_use_internal_errors(true);
|
53 |
-
try{
|
54 |
-
$this->xml = new SimpleXMLElement($xml);
|
55 |
-
} catch (Exception $e){
|
56 |
-
try{
|
57 |
-
$this->xml = new SimpleXMLElement(utf8_encode($xml));
|
58 |
-
} catch (Exception $e){
|
59 |
-
throw new XmlImportException($e->getMessage());
|
60 |
-
}
|
61 |
-
}
|
62 |
-
|
63 |
-
$this->rootNodeXPath = $rootNodeXPath;
|
64 |
-
$this->cachedTemplate = $cachedTemplate;
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Gets the parser results for all records or
|
69 |
-
* the part of them if $start and $count parameters are passed
|
70 |
-
*
|
71 |
-
* @param array[optional] $records Sequence numbers of records to import (first record corresponds to 1)
|
72 |
-
* @return array
|
73 |
-
*/
|
74 |
-
public function parse($records = array())
|
75 |
-
{
|
76 |
-
empty($records) or is_array($records) or $records = array($records);
|
77 |
-
|
78 |
-
$result = array();
|
79 |
-
|
80 |
-
$rootNodes = $this->xml->xpath($this->rootNodeXPath);
|
81 |
-
if ($rootNodes === false)
|
82 |
-
throw new XmlImportException('Invalid root node XPath \'' . $this->rootNodeXPath . '\' specified');
|
83 |
-
|
84 |
-
for ($i = 0; $i < count($rootNodes); $i++) {
|
85 |
-
if (empty($records) or in_array($i + 1, $records)) {
|
86 |
-
$rootNode = $rootNodes[$i];
|
87 |
-
$template = new XmlImportTemplate($rootNode, $this->cachedTemplate);
|
88 |
-
$result[] = $template->parse();
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
return $result;
|
93 |
-
}
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Creates new parser instance for text template specified
|
97 |
-
*
|
98 |
-
* @param string $xml
|
99 |
-
* @param string $rootNodeXPath XPath for the record root node
|
100 |
-
* @param string $template template
|
101 |
-
* @param string &$file path to the cached template
|
102 |
-
* @return XmlImportParser
|
103 |
-
*/
|
104 |
-
public static function factory($xml, $rootNodeXPath, $template, &$file = NULL)
|
105 |
-
{
|
106 |
-
|
107 |
-
$scanner = new XmlImportTemplateScanner();
|
108 |
-
$tokens = $scanner->scan(new XmlImportStringReader($template));
|
109 |
-
$t_parser = new XmlImportTemplateParser($tokens);
|
110 |
-
$tree = $t_parser->parse();
|
111 |
-
$codegenerator = new XmlImportTemplateCodeGenerator($tree);
|
112 |
-
$file = $codegenerator->generate();
|
113 |
-
|
114 |
-
return new self($xml, $rootNodeXPath, $file);
|
115 |
-
}
|
116 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
5 |
+
* @package General
|
6 |
+
*/
|
7 |
+
|
8 |
+
require_once dirname(__FILE__) . '/XmlImportTemplate.php';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Is used to parse XML using specified template and root node
|
12 |
+
*/
|
13 |
+
class XmlImportParser {
|
14 |
+
/**
|
15 |
+
* SimpleXmlElement instance for the xml file
|
16 |
+
*
|
17 |
+
* @var SimpleXMLElement
|
18 |
+
*/
|
19 |
+
protected $xml;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* XPath expression for selecting the root node of the record
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
protected $rootNodeXPath;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Path to cached template
|
30 |
+
*
|
31 |
+
* @var string
|
32 |
+
*/
|
33 |
+
protected $cachedTemplate;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Creates new parser instance
|
37 |
+
*
|
38 |
+
* @param string $xml
|
39 |
+
* @param string $rootNodeXPath XPath for the record root node
|
40 |
+
* @param string $cachedTemplate path to cached template
|
41 |
+
* @param bool $isURL whether xml is URL or path
|
42 |
+
*/
|
43 |
+
public function __construct($xml, $rootNodeXPath, $cachedTemplate, $isURL = false)
|
44 |
+
{
|
45 |
+
if ($isURL) {
|
46 |
+
$xml = file_get_contents($xml);
|
47 |
+
}
|
48 |
+
|
49 |
+
// FIX: remove default namespace because libxml xpath implementation doesn't handle it properly
|
50 |
+
$xml and $xml = preg_replace('%xmlns\s*=\s*([\'"]).*\1%sU', '', $xml);
|
51 |
+
|
52 |
+
libxml_use_internal_errors(true);
|
53 |
+
try{
|
54 |
+
$this->xml = new SimpleXMLElement($xml);
|
55 |
+
} catch (Exception $e){
|
56 |
+
try{
|
57 |
+
$this->xml = new SimpleXMLElement(utf8_encode($xml));
|
58 |
+
} catch (Exception $e){
|
59 |
+
throw new XmlImportException($e->getMessage());
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
$this->rootNodeXPath = $rootNodeXPath;
|
64 |
+
$this->cachedTemplate = $cachedTemplate;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Gets the parser results for all records or
|
69 |
+
* the part of them if $start and $count parameters are passed
|
70 |
+
*
|
71 |
+
* @param array[optional] $records Sequence numbers of records to import (first record corresponds to 1)
|
72 |
+
* @return array
|
73 |
+
*/
|
74 |
+
public function parse($records = array())
|
75 |
+
{
|
76 |
+
empty($records) or is_array($records) or $records = array($records);
|
77 |
+
|
78 |
+
$result = array();
|
79 |
+
|
80 |
+
$rootNodes = $this->xml->xpath($this->rootNodeXPath);
|
81 |
+
if ($rootNodes === false)
|
82 |
+
throw new XmlImportException('Invalid root node XPath \'' . $this->rootNodeXPath . '\' specified');
|
83 |
+
|
84 |
+
for ($i = 0; $i < count($rootNodes); $i++) {
|
85 |
+
if (empty($records) or in_array($i + 1, $records)) {
|
86 |
+
$rootNode = $rootNodes[$i];
|
87 |
+
$template = new XmlImportTemplate($rootNode, $this->cachedTemplate);
|
88 |
+
$result[] = $template->parse();
|
89 |
+
}
|
90 |
+
}
|
91 |
+
|
92 |
+
return $result;
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Creates new parser instance for text template specified
|
97 |
+
*
|
98 |
+
* @param string $xml
|
99 |
+
* @param string $rootNodeXPath XPath for the record root node
|
100 |
+
* @param string $template template
|
101 |
+
* @param string &$file path to the cached template
|
102 |
+
* @return XmlImportParser
|
103 |
+
*/
|
104 |
+
public static function factory($xml, $rootNodeXPath, $template, &$file = NULL)
|
105 |
+
{
|
106 |
+
|
107 |
+
$scanner = new XmlImportTemplateScanner();
|
108 |
+
$tokens = $scanner->scan(new XmlImportStringReader($template));
|
109 |
+
$t_parser = new XmlImportTemplateParser($tokens);
|
110 |
+
$tree = $t_parser->parse();
|
111 |
+
$codegenerator = new XmlImportTemplateCodeGenerator($tree);
|
112 |
+
$file = $codegenerator->generate();
|
113 |
+
|
114 |
+
return new self($xml, $rootNodeXPath, $file);
|
115 |
+
}
|
116 |
}
|
libraries/XmlImportReaderInterface.php
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Interface that allows to either peek or read symbol from class that implements it
|
9 |
-
*/
|
10 |
-
interface XmlImportReaderInterface
|
11 |
-
{
|
12 |
-
/**
|
13 |
-
* Peeks a symbol
|
14 |
-
*/
|
15 |
-
public function peek();
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Reads a symbol
|
19 |
-
*/
|
20 |
-
public function read();
|
21 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Interface that allows to either peek or read symbol from class that implements it
|
9 |
+
*/
|
10 |
+
interface XmlImportReaderInterface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Peeks a symbol
|
14 |
+
*/
|
15 |
+
public function peek();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Reads a symbol
|
19 |
+
*/
|
20 |
+
public function read();
|
21 |
+
}
|
libraries/XmlImportStringReader.php
CHANGED
@@ -1,67 +1,67 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
require_once dirname(__FILE__) . '/XmlImportReaderInterface.php';
|
8 |
-
|
9 |
-
/**
|
10 |
-
* Allows to either peek or read a character from a string buffer
|
11 |
-
*/
|
12 |
-
class XmlImportStringReader implements XmlImportReaderInterface
|
13 |
-
{
|
14 |
-
/**
|
15 |
-
* String buffer
|
16 |
-
*
|
17 |
-
* @var string
|
18 |
-
*/
|
19 |
-
private $buffer;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Current index
|
23 |
-
*
|
24 |
-
* @var int
|
25 |
-
*/
|
26 |
-
private $index = -1;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Creates new instance
|
30 |
-
*
|
31 |
-
* @param string $input
|
32 |
-
*/
|
33 |
-
public function __construct($input)
|
34 |
-
{
|
35 |
-
if (is_string($input))
|
36 |
-
$this->buffer = $input;
|
37 |
-
else
|
38 |
-
throw new InvalidArgumentException("String expected as argument.");
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Returns the next symbol from the buffer without changes to current index
|
43 |
-
* or false if buffer ends
|
44 |
-
*
|
45 |
-
* @return string
|
46 |
-
*/
|
47 |
-
public function peek()
|
48 |
-
{
|
49 |
-
if ($this->index + 1 >= strlen($this->buffer))
|
50 |
-
return false;
|
51 |
-
else
|
52 |
-
return $this->buffer[$this->index + 1];
|
53 |
-
}
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Returns the next symbol from the buffer or false if buffer is ended
|
57 |
-
*
|
58 |
-
* @return string
|
59 |
-
*/
|
60 |
-
public function read()
|
61 |
-
{
|
62 |
-
$result = $this->peek();
|
63 |
-
if ($this->index < strlen($this->buffer))
|
64 |
-
$this->index++;
|
65 |
-
return $result;
|
66 |
-
}
|
67 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
require_once dirname(__FILE__) . '/XmlImportReaderInterface.php';
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Allows to either peek or read a character from a string buffer
|
11 |
+
*/
|
12 |
+
class XmlImportStringReader implements XmlImportReaderInterface
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
* String buffer
|
16 |
+
*
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
private $buffer;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Current index
|
23 |
+
*
|
24 |
+
* @var int
|
25 |
+
*/
|
26 |
+
private $index = -1;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Creates new instance
|
30 |
+
*
|
31 |
+
* @param string $input
|
32 |
+
*/
|
33 |
+
public function __construct($input)
|
34 |
+
{
|
35 |
+
if (is_string($input))
|
36 |
+
$this->buffer = $input;
|
37 |
+
else
|
38 |
+
throw new InvalidArgumentException("String expected as argument.");
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Returns the next symbol from the buffer without changes to current index
|
43 |
+
* or false if buffer ends
|
44 |
+
*
|
45 |
+
* @return string
|
46 |
+
*/
|
47 |
+
public function peek()
|
48 |
+
{
|
49 |
+
if ($this->index + 1 >= strlen($this->buffer))
|
50 |
+
return false;
|
51 |
+
else
|
52 |
+
return $this->buffer[$this->index + 1];
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Returns the next symbol from the buffer or false if buffer is ended
|
57 |
+
*
|
58 |
+
* @return string
|
59 |
+
*/
|
60 |
+
public function read()
|
61 |
+
{
|
62 |
+
$result = $this->peek();
|
63 |
+
if ($this->index < strlen($this->buffer))
|
64 |
+
$this->index++;
|
65 |
+
return $result;
|
66 |
+
}
|
67 |
}
|
libraries/XmlImportTemplate.php
CHANGED
@@ -1,78 +1,78 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
5 |
-
* @package General
|
6 |
-
*/
|
7 |
-
|
8 |
-
require_once dirname(__FILE__) . '/XmlImportConfig.php';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Represents a template
|
12 |
-
*/
|
13 |
-
class XmlImportTemplate {
|
14 |
-
/**
|
15 |
-
* Root element of the record that is being parsed
|
16 |
-
*
|
17 |
-
* @var SimpleXMLElement
|
18 |
-
*/
|
19 |
-
protected $xml;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* file name of the cached template
|
23 |
-
*
|
24 |
-
* @var string
|
25 |
-
*/
|
26 |
-
protected $cachedTemplate;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Creates new instance
|
30 |
-
*
|
31 |
-
* @param SimpleXmlElement $xml
|
32 |
-
* @param string $cachedTemplate
|
33 |
-
*/
|
34 |
-
public function __construct($xml, $cachedTemplate)
|
35 |
-
{
|
36 |
-
$this->xml = $xml;
|
37 |
-
$this->cachedTemplate = $cachedTemplate;
|
38 |
-
}
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Parses a template using {@see $this->xml}
|
42 |
-
*
|
43 |
-
* @return string
|
44 |
-
*/
|
45 |
-
public function parse()
|
46 |
-
{
|
47 |
-
|
48 |
-
ob_start();
|
49 |
-
$err_lvl = error_reporting(E_ALL);
|
50 |
-
include $this->cachedTemplate;
|
51 |
-
error_reporting($err_lvl);
|
52 |
-
|
53 |
-
return ob_get_clean();
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Get the value by XPath expression
|
58 |
-
*
|
59 |
-
* @param SimpleXmlElement $xpath XPath result
|
60 |
-
* @return mixed
|
61 |
-
*/
|
62 |
-
protected function getValue($xpath)
|
63 |
-
{
|
64 |
-
|
65 |
-
if (is_array($xpath) && count($xpath) > 0) {
|
66 |
-
$result = array();
|
67 |
-
foreach ($xpath as $xp) { // cancatenate multiple elements into 1 string
|
68 |
-
ob_start();
|
69 |
-
echo $xp;
|
70 |
-
$result[] = trim(ob_get_clean());
|
71 |
-
}
|
72 |
-
return implode(XmlImportConfig::getInstance()->getMultiGlue(), $result);
|
73 |
-
} else {
|
74 |
-
// return null if nothing found
|
75 |
-
return null;
|
76 |
-
}
|
77 |
-
}
|
78 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
5 |
+
* @package General
|
6 |
+
*/
|
7 |
+
|
8 |
+
require_once dirname(__FILE__) . '/XmlImportConfig.php';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Represents a template
|
12 |
+
*/
|
13 |
+
class XmlImportTemplate {
|
14 |
+
/**
|
15 |
+
* Root element of the record that is being parsed
|
16 |
+
*
|
17 |
+
* @var SimpleXMLElement
|
18 |
+
*/
|
19 |
+
protected $xml;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* file name of the cached template
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
protected $cachedTemplate;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Creates new instance
|
30 |
+
*
|
31 |
+
* @param SimpleXmlElement $xml
|
32 |
+
* @param string $cachedTemplate
|
33 |
+
*/
|
34 |
+
public function __construct($xml, $cachedTemplate)
|
35 |
+
{
|
36 |
+
$this->xml = $xml;
|
37 |
+
$this->cachedTemplate = $cachedTemplate;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Parses a template using {@see $this->xml}
|
42 |
+
*
|
43 |
+
* @return string
|
44 |
+
*/
|
45 |
+
public function parse()
|
46 |
+
{
|
47 |
+
|
48 |
+
ob_start();
|
49 |
+
$err_lvl = error_reporting(E_ALL);
|
50 |
+
include $this->cachedTemplate;
|
51 |
+
error_reporting($err_lvl);
|
52 |
+
|
53 |
+
return ob_get_clean();
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Get the value by XPath expression
|
58 |
+
*
|
59 |
+
* @param SimpleXmlElement $xpath XPath result
|
60 |
+
* @return mixed
|
61 |
+
*/
|
62 |
+
protected function getValue($xpath)
|
63 |
+
{
|
64 |
+
|
65 |
+
if (is_array($xpath) && count($xpath) > 0) {
|
66 |
+
$result = array();
|
67 |
+
foreach ($xpath as $xp) { // cancatenate multiple elements into 1 string
|
68 |
+
ob_start();
|
69 |
+
echo $xp;
|
70 |
+
$result[] = trim(ob_get_clean());
|
71 |
+
}
|
72 |
+
return implode(XmlImportConfig::getInstance()->getMultiGlue(), $result);
|
73 |
+
} else {
|
74 |
+
// return null if nothing found
|
75 |
+
return null;
|
76 |
+
}
|
77 |
+
}
|
78 |
}
|
libraries/XmlImportTemplateCodeGenerator.php
CHANGED
@@ -1,383 +1,383 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
require_once dirname(__FILE__) . '/XmlImportConfig.php';
|
8 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstSequence.php';
|
9 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstText.php';
|
10 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstPrint.php';
|
11 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
12 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
13 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
14 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
15 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
16 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
17 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
18 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstMath.php';
|
19 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstSpintax.php';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Is used to generate a PHP code from AST (Abstract Syntax Tree)
|
23 |
-
*/
|
24 |
-
class XmlImportTemplateCodeGenerator
|
25 |
-
{
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Top level statement sequence
|
29 |
-
*
|
30 |
-
* @var XmlImportAstSequence
|
31 |
-
*/
|
32 |
-
private $sequence;
|
33 |
-
|
34 |
-
/**
|
35 |
-
* statement sequence stack
|
36 |
-
*
|
37 |
-
* @var array
|
38 |
-
*/
|
39 |
-
private $sequenceStack = array();
|
40 |
-
|
41 |
-
/**
|
42 |
-
* SimpleXmlElement variable number
|
43 |
-
*
|
44 |
-
* @var int
|
45 |
-
*/
|
46 |
-
private $xmlVariableNumber = 0;
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Previous statement
|
50 |
-
*
|
51 |
-
* @var XmlImportAstStatement
|
52 |
-
*/
|
53 |
-
private $previousStatement = null;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Stack of SimpleXmlElement instances
|
57 |
-
*
|
58 |
-
* @var array
|
59 |
-
*/
|
60 |
-
private $xmlStack = array();
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Whether PHP tag is open
|
64 |
-
*
|
65 |
-
* @var bool
|
66 |
-
*/
|
67 |
-
private $isPhpTagOpen = false;
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Creates new instance
|
71 |
-
*
|
72 |
-
* @param XmlImportAstSequence $sequence
|
73 |
-
*/
|
74 |
-
public function __construct(XmlImportAstSequence $sequence)
|
75 |
-
{
|
76 |
-
$this->sequence = $sequence;
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Generates the code and returns the filename under which it was stored in
|
81 |
-
* cache directory. If $filename is null then it is generated automatically
|
82 |
-
*
|
83 |
-
* @param string $filename
|
84 |
-
* @return string
|
85 |
-
*/
|
86 |
-
public function generate($filename = null)
|
87 |
-
{
|
88 |
-
$result = '';
|
89 |
-
if (count($this->sequence->getVariables()))
|
90 |
-
{
|
91 |
-
$var = '$x' . $this->xmlVariableNumber++;
|
92 |
-
array_push($this->xmlStack, $var);
|
93 |
-
$result .= $this->openPhpTag() . $var . ' = $this->xml;' ;
|
94 |
-
}
|
95 |
-
$result .= $this->generateForSequence($this->sequence);
|
96 |
-
|
97 |
-
if (count($this->sequence->getVariables()))
|
98 |
-
{
|
99 |
-
array_pop($this->xmlStack);
|
100 |
-
}
|
101 |
-
if (is_null($filename))
|
102 |
-
{
|
103 |
-
$filename = tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
|
104 |
-
}
|
105 |
-
|
106 |
-
file_put_contents($filename, $result);
|
107 |
-
return $filename;
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Generates code for a statement sequence
|
112 |
-
*
|
113 |
-
* @param XmlImportAstSequence $sequence
|
114 |
-
* @return string
|
115 |
-
*/
|
116 |
-
private function generateForSequence(XmlImportAstSequence $sequence)
|
117 |
-
{
|
118 |
-
array_push($this->sequenceStack, $sequence);
|
119 |
-
$result = '';
|
120 |
-
if (count($sequence->getVariableDefinitions()) > 0)
|
121 |
-
{
|
122 |
-
$result .= $this->openPhpTag();
|
123 |
-
foreach ($sequence->getVariableDefinitions() as $xpath)
|
124 |
-
{
|
125 |
-
$result .= PHP_EOL . str_replace('{{XML}}', $this->xmlStack[count($this->xmlStack) - 1], $xpath);
|
126 |
-
}
|
127 |
-
$result .= PHP_EOL;
|
128 |
-
}
|
129 |
-
foreach ($sequence->getStatements() as $statement)
|
130 |
-
{
|
131 |
-
$result .= $this->generateForStatement($statement);
|
132 |
-
}
|
133 |
-
array_pop($this->sequenceStack);
|
134 |
-
|
135 |
-
return $result;
|
136 |
-
}
|
137 |
-
|
138 |
-
/**
|
139 |
-
* Generates code for a statement
|
140 |
-
*
|
141 |
-
* @param XmlImportAstStatement $statement
|
142 |
-
* @return string
|
143 |
-
*/
|
144 |
-
private function generateForStatement(XmlImportAstStatement $statement)
|
145 |
-
{
|
146 |
-
$result = '';
|
147 |
-
if ($statement instanceof XmlImportAstText)
|
148 |
-
{
|
149 |
-
$result .= $this->closePhpTag();
|
150 |
-
$text = preg_replace('%<\?|\?>%', '<?php echo "$0"; ?>', $statement->getValue()); // escape php tags
|
151 |
-
if ($this->previousStatement instanceof XmlImportAstPrint && (strpos($text, "\n") === 0 || strpos($text, "\r\n") === 0))
|
152 |
-
{
|
153 |
-
$result .= PHP_EOL;
|
154 |
-
}
|
155 |
-
$result .= $text;
|
156 |
-
}
|
157 |
-
else
|
158 |
-
{
|
159 |
-
$result .= $this->openPhpTag();
|
160 |
-
if ($statement instanceof XmlImportAstPrint)
|
161 |
-
{
|
162 |
-
$result .= 'echo ';
|
163 |
-
$result .= $this->generateForExpression($statement->getValue(), true) . ';';
|
164 |
-
}
|
165 |
-
elseif ($statement instanceof XmlImportAstWith)
|
166 |
-
{
|
167 |
-
$var = '$x' . $this->xmlVariableNumber++;
|
168 |
-
$result .= PHP_EOL . $var . ' = ' ;
|
169 |
-
$result .= $this->generateForExpression($statement->getXpath()) . ';' . PHP_EOL;
|
170 |
-
|
171 |
-
array_push($this->xmlStack, $var);
|
172 |
-
$result .= 'if (' . $var . ' !== false && count(' . $var . ') > 0) :' . PHP_EOL . $var .
|
173 |
-
' = ' . $var . '[0];' . PHP_EOL;
|
174 |
-
$result .= $this->generateForSequence($statement->getBody());
|
175 |
-
array_pop($this->xmlStack);
|
176 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'endif;' . PHP_EOL;
|
177 |
-
}
|
178 |
-
elseif ($statement instanceof XmlImportAstForeach)
|
179 |
-
{
|
180 |
-
$var = '$x' . $this->xmlVariableNumber++;
|
181 |
-
$result .= PHP_EOL . 'foreach (' . $this->generateForExpression($statement->getXPath()) .
|
182 |
-
' as ' . $var . ') :' . PHP_EOL;
|
183 |
-
array_push($this->xmlStack, $var);
|
184 |
-
$result .= $this->generateForSequence($statement->getBody());
|
185 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'endforeach;' . PHP_EOL;
|
186 |
-
array_pop($this->xmlStack);
|
187 |
-
}
|
188 |
-
elseif ($statement instanceof XmlImportAstIf)
|
189 |
-
{
|
190 |
-
$result .= PHP_EOL . 'if (' . $this->generateForExpression($statement->getCondition()) . ') :' . PHP_EOL;
|
191 |
-
$result .= $this->generateForSequence($statement->getIfBody());
|
192 |
-
foreach ($statement->getElseIfs() as $elseif)
|
193 |
-
{
|
194 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'elseif (' . $this->generateForExpression($elseif->getCondition()) . ') :' . PHP_EOL;
|
195 |
-
$result .= $this->generateForSequence($elseif->getBody());
|
196 |
-
}
|
197 |
-
if (!is_null($body = $statement->getElseBody()))
|
198 |
-
{
|
199 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'else :' . PHP_EOL;
|
200 |
-
$result .= $this->generateForSequence($body);
|
201 |
-
}
|
202 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'endif;' . PHP_EOL;
|
203 |
-
}
|
204 |
-
|
205 |
-
}
|
206 |
-
$this->previousStatement = $statement;
|
207 |
-
return $result;
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Generates code for expression
|
212 |
-
*
|
213 |
-
* @param XmlImportAstExpression $expression
|
214 |
-
* @param bool $inPrint whether in print or in clause or function argument
|
215 |
-
* @return string
|
216 |
-
*/
|
217 |
-
private function generateForExpression(XmlImportAstExpression $expression, $inPrint = false)
|
218 |
-
{
|
219 |
-
|
220 |
-
switch (get_class($expression))
|
221 |
-
{
|
222 |
-
case 'XmlImportAstString':
|
223 |
-
$result = '"' . $this->getEscapedValue($expression->getValue()) . '"';
|
224 |
-
break;
|
225 |
-
|
226 |
-
case 'XmlImportAstInteger':
|
227 |
-
case 'XmlImportAstFloat':
|
228 |
-
$result = $expression->getValue();
|
229 |
-
break;
|
230 |
-
|
231 |
-
case 'XmlImportAstXPath':
|
232 |
-
if ($inPrint)
|
233 |
-
{
|
234 |
-
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
235 |
-
$result = '$this->getValue(' . $variables[$expression->getValue()] . ')';
|
236 |
-
}
|
237 |
-
else
|
238 |
-
{
|
239 |
-
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
240 |
-
$result = $variables[$expression->getValue()];
|
241 |
-
}
|
242 |
-
break;
|
243 |
-
|
244 |
-
case 'XmlImportAstMath':
|
245 |
-
$result = $this->generateForMath($expression);
|
246 |
-
break;
|
247 |
-
|
248 |
-
case 'XmlImportAstSpintax':
|
249 |
-
$result = $this->generateForSpintax($expression);
|
250 |
-
break;
|
251 |
-
}
|
252 |
-
return $result;
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* Generates code for a function
|
257 |
-
*
|
258 |
-
* @param XmlImportAstFunction $function
|
259 |
-
* @return string
|
260 |
-
*/
|
261 |
-
private function generateForMath(XmlImportAstMath $math)
|
262 |
-
{
|
263 |
-
$result = '';
|
264 |
-
$arguments = $math->getArguments();
|
265 |
-
for($i = 0; $i < count($arguments); $i++)
|
266 |
-
{
|
267 |
-
$result .= $this->generateForExpression($arguments[$i], true);
|
268 |
-
}
|
269 |
-
|
270 |
-
return 'number_format('.str_replace("\"", "", $result).',2)';
|
271 |
-
}
|
272 |
-
|
273 |
-
/**
|
274 |
-
* Generates code for a function
|
275 |
-
*
|
276 |
-
* @param XmlImportAstSpintax $expression
|
277 |
-
* @return string
|
278 |
-
*/
|
279 |
-
private function generateForSpintax(XmlImportAstSpintax $spintax)
|
280 |
-
{
|
281 |
-
$result = '';
|
282 |
-
$arguments = $spintax->getArguments();
|
283 |
-
$elements = array();
|
284 |
-
$buf = array();
|
285 |
-
|
286 |
-
for($i = 0; $i < count($arguments); $i++)
|
287 |
-
{
|
288 |
-
|
289 |
-
if ($arguments[$i]->getValue() != '|') array_push($buf, $this->generateForExpression($arguments[$i], true)); else { array_push($elements, $buf); $buf = array();}
|
290 |
-
|
291 |
-
}
|
292 |
-
|
293 |
-
array_push($elements, $buf);
|
294 |
-
|
295 |
-
if (!empty($elements) and is_array($elements)){
|
296 |
-
|
297 |
-
$spintax_arr = $this->generateVariation($elements);
|
298 |
-
|
299 |
-
foreach ($spintax_arr as $key => $value) {
|
300 |
-
$result .= "\"<p>\".".implode(".", $value).".\"</p>\""; if ($key != count($spintax_arr) - 1) $result .= ".";
|
301 |
-
}
|
302 |
-
|
303 |
-
}
|
304 |
-
|
305 |
-
return $result;
|
306 |
-
}
|
307 |
-
|
308 |
-
function generateVariation($A, $i = 0)
|
309 |
-
{
|
310 |
-
$result = array();
|
311 |
-
|
312 |
-
if ($i < count($A))
|
313 |
-
{
|
314 |
-
$variations = $this->generateVariation($A, $i + 1);
|
315 |
-
|
316 |
-
for ($j = 0; $j < count($A[$i]); $j++)
|
317 |
-
{
|
318 |
-
if ($variations)
|
319 |
-
{
|
320 |
-
foreach ($variations as $variation)
|
321 |
-
{
|
322 |
-
$result[] = array_merge(array($A[$i][$j]), $variation);
|
323 |
-
}
|
324 |
-
}
|
325 |
-
else
|
326 |
-
{
|
327 |
-
$result[] = array($A[$i][$j]);
|
328 |
-
}
|
329 |
-
}
|
330 |
-
}
|
331 |
-
|
332 |
-
return $result;
|
333 |
-
}
|
334 |
-
/**
|
335 |
-
* Add PHP open tag if needed
|
336 |
-
*
|
337 |
-
* @return string
|
338 |
-
*/
|
339 |
-
private function openPhpTag()
|
340 |
-
{
|
341 |
-
$result = '';
|
342 |
-
if (!$this->isPhpTagOpen)
|
343 |
-
{
|
344 |
-
$this->isPhpTagOpen = true;
|
345 |
-
$result = '<?php ';
|
346 |
-
}
|
347 |
-
return $result;
|
348 |
-
}
|
349 |
-
|
350 |
-
/**
|
351 |
-
* Adds PHP close tag if needed
|
352 |
-
*
|
353 |
-
* @return string
|
354 |
-
*/
|
355 |
-
private function closePhpTag()
|
356 |
-
{
|
357 |
-
$result = '';
|
358 |
-
if ($this->isPhpTagOpen)
|
359 |
-
{
|
360 |
-
$this->isPhpTagOpen = false;
|
361 |
-
$result = '?>';
|
362 |
-
}
|
363 |
-
return $result;
|
364 |
-
}
|
365 |
-
|
366 |
-
/**
|
367 |
-
* Gets escaped value
|
368 |
-
*
|
369 |
-
* @return string
|
370 |
-
*/
|
371 |
-
private function getEscapedValue($value)
|
372 |
-
{
|
373 |
-
$escapedValue = strtr($value, array(
|
374 |
-
"\n" => "\\n",
|
375 |
-
"\t" => "\\t",
|
376 |
-
"\r" => "\\r",
|
377 |
-
"$" => "\\$",
|
378 |
-
"\"" => "\\\"",
|
379 |
-
"\\" => "\\\\",
|
380 |
-
));
|
381 |
-
return $escapedValue;
|
382 |
-
}
|
383 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
require_once dirname(__FILE__) . '/XmlImportConfig.php';
|
8 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstSequence.php';
|
9 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstText.php';
|
10 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstPrint.php';
|
11 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
12 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
13 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
14 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
15 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
16 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
17 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
18 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstMath.php';
|
19 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstSpintax.php';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Is used to generate a PHP code from AST (Abstract Syntax Tree)
|
23 |
+
*/
|
24 |
+
class XmlImportTemplateCodeGenerator
|
25 |
+
{
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Top level statement sequence
|
29 |
+
*
|
30 |
+
* @var XmlImportAstSequence
|
31 |
+
*/
|
32 |
+
private $sequence;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* statement sequence stack
|
36 |
+
*
|
37 |
+
* @var array
|
38 |
+
*/
|
39 |
+
private $sequenceStack = array();
|
40 |
+
|
41 |
+
/**
|
42 |
+
* SimpleXmlElement variable number
|
43 |
+
*
|
44 |
+
* @var int
|
45 |
+
*/
|
46 |
+
private $xmlVariableNumber = 0;
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Previous statement
|
50 |
+
*
|
51 |
+
* @var XmlImportAstStatement
|
52 |
+
*/
|
53 |
+
private $previousStatement = null;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Stack of SimpleXmlElement instances
|
57 |
+
*
|
58 |
+
* @var array
|
59 |
+
*/
|
60 |
+
private $xmlStack = array();
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Whether PHP tag is open
|
64 |
+
*
|
65 |
+
* @var bool
|
66 |
+
*/
|
67 |
+
private $isPhpTagOpen = false;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Creates new instance
|
71 |
+
*
|
72 |
+
* @param XmlImportAstSequence $sequence
|
73 |
+
*/
|
74 |
+
public function __construct(XmlImportAstSequence $sequence)
|
75 |
+
{
|
76 |
+
$this->sequence = $sequence;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Generates the code and returns the filename under which it was stored in
|
81 |
+
* cache directory. If $filename is null then it is generated automatically
|
82 |
+
*
|
83 |
+
* @param string $filename
|
84 |
+
* @return string
|
85 |
+
*/
|
86 |
+
public function generate($filename = null)
|
87 |
+
{
|
88 |
+
$result = '';
|
89 |
+
if (count($this->sequence->getVariables()))
|
90 |
+
{
|
91 |
+
$var = '$x' . $this->xmlVariableNumber++;
|
92 |
+
array_push($this->xmlStack, $var);
|
93 |
+
$result .= $this->openPhpTag() . $var . ' = $this->xml;' ;
|
94 |
+
}
|
95 |
+
$result .= $this->generateForSequence($this->sequence);
|
96 |
+
|
97 |
+
if (count($this->sequence->getVariables()))
|
98 |
+
{
|
99 |
+
array_pop($this->xmlStack);
|
100 |
+
}
|
101 |
+
if (is_null($filename))
|
102 |
+
{
|
103 |
+
$filename = tempnam(XmlImportConfig::getInstance()->getCacheDirectory(), 'xim');
|
104 |
+
}
|
105 |
+
|
106 |
+
file_put_contents($filename, $result);
|
107 |
+
return $filename;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Generates code for a statement sequence
|
112 |
+
*
|
113 |
+
* @param XmlImportAstSequence $sequence
|
114 |
+
* @return string
|
115 |
+
*/
|
116 |
+
private function generateForSequence(XmlImportAstSequence $sequence)
|
117 |
+
{
|
118 |
+
array_push($this->sequenceStack, $sequence);
|
119 |
+
$result = '';
|
120 |
+
if (count($sequence->getVariableDefinitions()) > 0)
|
121 |
+
{
|
122 |
+
$result .= $this->openPhpTag();
|
123 |
+
foreach ($sequence->getVariableDefinitions() as $xpath)
|
124 |
+
{
|
125 |
+
$result .= PHP_EOL . str_replace('{{XML}}', $this->xmlStack[count($this->xmlStack) - 1], $xpath);
|
126 |
+
}
|
127 |
+
$result .= PHP_EOL;
|
128 |
+
}
|
129 |
+
foreach ($sequence->getStatements() as $statement)
|
130 |
+
{
|
131 |
+
$result .= $this->generateForStatement($statement);
|
132 |
+
}
|
133 |
+
array_pop($this->sequenceStack);
|
134 |
+
|
135 |
+
return $result;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Generates code for a statement
|
140 |
+
*
|
141 |
+
* @param XmlImportAstStatement $statement
|
142 |
+
* @return string
|
143 |
+
*/
|
144 |
+
private function generateForStatement(XmlImportAstStatement $statement)
|
145 |
+
{
|
146 |
+
$result = '';
|
147 |
+
if ($statement instanceof XmlImportAstText)
|
148 |
+
{
|
149 |
+
$result .= $this->closePhpTag();
|
150 |
+
$text = preg_replace('%<\?|\?>%', '<?php echo "$0"; ?>', $statement->getValue()); // escape php tags
|
151 |
+
if ($this->previousStatement instanceof XmlImportAstPrint && (strpos($text, "\n") === 0 || strpos($text, "\r\n") === 0))
|
152 |
+
{
|
153 |
+
$result .= PHP_EOL;
|
154 |
+
}
|
155 |
+
$result .= $text;
|
156 |
+
}
|
157 |
+
else
|
158 |
+
{
|
159 |
+
$result .= $this->openPhpTag();
|
160 |
+
if ($statement instanceof XmlImportAstPrint)
|
161 |
+
{
|
162 |
+
$result .= 'echo ';
|
163 |
+
$result .= $this->generateForExpression($statement->getValue(), true) . ';';
|
164 |
+
}
|
165 |
+
elseif ($statement instanceof XmlImportAstWith)
|
166 |
+
{
|
167 |
+
$var = '$x' . $this->xmlVariableNumber++;
|
168 |
+
$result .= PHP_EOL . $var . ' = ' ;
|
169 |
+
$result .= $this->generateForExpression($statement->getXpath()) . ';' . PHP_EOL;
|
170 |
+
|
171 |
+
array_push($this->xmlStack, $var);
|
172 |
+
$result .= 'if (' . $var . ' !== false && count(' . $var . ') > 0) :' . PHP_EOL . $var .
|
173 |
+
' = ' . $var . '[0];' . PHP_EOL;
|
174 |
+
$result .= $this->generateForSequence($statement->getBody());
|
175 |
+
array_pop($this->xmlStack);
|
176 |
+
$result .= $this->openPhpTag() . PHP_EOL . 'endif;' . PHP_EOL;
|
177 |
+
}
|
178 |
+
elseif ($statement instanceof XmlImportAstForeach)
|
179 |
+
{
|
180 |
+
$var = '$x' . $this->xmlVariableNumber++;
|
181 |
+
$result .= PHP_EOL . 'foreach (' . $this->generateForExpression($statement->getXPath()) .
|
182 |
+
' as ' . $var . ') :' . PHP_EOL;
|
183 |
+
array_push($this->xmlStack, $var);
|
184 |
+
$result .= $this->generateForSequence($statement->getBody());
|
185 |
+
$result .= $this->openPhpTag() . PHP_EOL . 'endforeach;' . PHP_EOL;
|
186 |
+
array_pop($this->xmlStack);
|
187 |
+
}
|
188 |
+
elseif ($statement instanceof XmlImportAstIf)
|
189 |
+
{
|
190 |
+
$result .= PHP_EOL . 'if (' . $this->generateForExpression($statement->getCondition()) . ') :' . PHP_EOL;
|
191 |
+
$result .= $this->generateForSequence($statement->getIfBody());
|
192 |
+
foreach ($statement->getElseIfs() as $elseif)
|
193 |
+
{
|
194 |
+
$result .= $this->openPhpTag() . PHP_EOL . 'elseif (' . $this->generateForExpression($elseif->getCondition()) . ') :' . PHP_EOL;
|
195 |
+
$result .= $this->generateForSequence($elseif->getBody());
|
196 |
+
}
|
197 |
+
if (!is_null($body = $statement->getElseBody()))
|
198 |
+
{
|
199 |
+
$result .= $this->openPhpTag() . PHP_EOL . 'else :' . PHP_EOL;
|
200 |
+
$result .= $this->generateForSequence($body);
|
201 |
+
}
|
202 |
+
$result .= $this->openPhpTag() . PHP_EOL . 'endif;' . PHP_EOL;
|
203 |
+
}
|
204 |
+
|
205 |
+
}
|
206 |
+
$this->previousStatement = $statement;
|
207 |
+
return $result;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Generates code for expression
|
212 |
+
*
|
213 |
+
* @param XmlImportAstExpression $expression
|
214 |
+
* @param bool $inPrint whether in print or in clause or function argument
|
215 |
+
* @return string
|
216 |
+
*/
|
217 |
+
private function generateForExpression(XmlImportAstExpression $expression, $inPrint = false)
|
218 |
+
{
|
219 |
+
|
220 |
+
switch (get_class($expression))
|
221 |
+
{
|
222 |
+
case 'XmlImportAstString':
|
223 |
+
$result = '"' . $this->getEscapedValue($expression->getValue()) . '"';
|
224 |
+
break;
|
225 |
+
|
226 |
+
case 'XmlImportAstInteger':
|
227 |
+
case 'XmlImportAstFloat':
|
228 |
+
$result = $expression->getValue();
|
229 |
+
break;
|
230 |
+
|
231 |
+
case 'XmlImportAstXPath':
|
232 |
+
if ($inPrint)
|
233 |
+
{
|
234 |
+
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
235 |
+
$result = '$this->getValue(' . $variables[$expression->getValue()] . ')';
|
236 |
+
}
|
237 |
+
else
|
238 |
+
{
|
239 |
+
$variables = $this->sequenceStack[count($this->sequenceStack) - 1]->getVariables();
|
240 |
+
$result = $variables[$expression->getValue()];
|
241 |
+
}
|
242 |
+
break;
|
243 |
+
|
244 |
+
case 'XmlImportAstMath':
|
245 |
+
$result = $this->generateForMath($expression);
|
246 |
+
break;
|
247 |
+
|
248 |
+
case 'XmlImportAstSpintax':
|
249 |
+
$result = $this->generateForSpintax($expression);
|
250 |
+
break;
|
251 |
+
}
|
252 |
+
return $result;
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Generates code for a function
|
257 |
+
*
|
258 |
+
* @param XmlImportAstFunction $function
|
259 |
+
* @return string
|
260 |
+
*/
|
261 |
+
private function generateForMath(XmlImportAstMath $math)
|
262 |
+
{
|
263 |
+
$result = '';
|
264 |
+
$arguments = $math->getArguments();
|
265 |
+
for($i = 0; $i < count($arguments); $i++)
|
266 |
+
{
|
267 |
+
$result .= $this->generateForExpression($arguments[$i], true);
|
268 |
+
}
|
269 |
+
|
270 |
+
return 'number_format('.str_replace("\"", "", $result).',2)';
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Generates code for a function
|
275 |
+
*
|
276 |
+
* @param XmlImportAstSpintax $expression
|
277 |
+
* @return string
|
278 |
+
*/
|
279 |
+
private function generateForSpintax(XmlImportAstSpintax $spintax)
|
280 |
+
{
|
281 |
+
$result = '';
|
282 |
+
$arguments = $spintax->getArguments();
|
283 |
+
$elements = array();
|
284 |
+
$buf = array();
|
285 |
+
|
286 |
+
for($i = 0; $i < count($arguments); $i++)
|
287 |
+
{
|
288 |
+
|
289 |
+
if ($arguments[$i]->getValue() != '|') array_push($buf, $this->generateForExpression($arguments[$i], true)); else { array_push($elements, $buf); $buf = array();}
|
290 |
+
|
291 |
+
}
|
292 |
+
|
293 |
+
array_push($elements, $buf);
|
294 |
+
|
295 |
+
if (!empty($elements) and is_array($elements)){
|
296 |
+
|
297 |
+
$spintax_arr = $this->generateVariation($elements);
|
298 |
+
|
299 |
+
foreach ($spintax_arr as $key => $value) {
|
300 |
+
$result .= "\"<p>\".".implode(".", $value).".\"</p>\""; if ($key != count($spintax_arr) - 1) $result .= ".";
|
301 |
+
}
|
302 |
+
|
303 |
+
}
|
304 |
+
|
305 |
+
return $result;
|
306 |
+
}
|
307 |
+
|
308 |
+
function generateVariation($A, $i = 0)
|
309 |
+
{
|
310 |
+
$result = array();
|
311 |
+
|
312 |
+
if ($i < count($A))
|
313 |
+
{
|
314 |
+
$variations = $this->generateVariation($A, $i + 1);
|
315 |
+
|
316 |
+
for ($j = 0; $j < count($A[$i]); $j++)
|
317 |
+
{
|
318 |
+
if ($variations)
|
319 |
+
{
|
320 |
+
foreach ($variations as $variation)
|
321 |
+
{
|
322 |
+
$result[] = array_merge(array($A[$i][$j]), $variation);
|
323 |
+
}
|
324 |
+
}
|
325 |
+
else
|
326 |
+
{
|
327 |
+
$result[] = array($A[$i][$j]);
|
328 |
+
}
|
329 |
+
}
|
330 |
+
}
|
331 |
+
|
332 |
+
return $result;
|
333 |
+
}
|
334 |
+
/**
|
335 |
+
* Add PHP open tag if needed
|
336 |
+
*
|
337 |
+
* @return string
|
338 |
+
*/
|
339 |
+
private function openPhpTag()
|
340 |
+
{
|
341 |
+
$result = '';
|
342 |
+
if (!$this->isPhpTagOpen)
|
343 |
+
{
|
344 |
+
$this->isPhpTagOpen = true;
|
345 |
+
$result = '<?php ';
|
346 |
+
}
|
347 |
+
return $result;
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* Adds PHP close tag if needed
|
352 |
+
*
|
353 |
+
* @return string
|
354 |
+
*/
|
355 |
+
private function closePhpTag()
|
356 |
+
{
|
357 |
+
$result = '';
|
358 |
+
if ($this->isPhpTagOpen)
|
359 |
+
{
|
360 |
+
$this->isPhpTagOpen = false;
|
361 |
+
$result = '?>';
|
362 |
+
}
|
363 |
+
return $result;
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Gets escaped value
|
368 |
+
*
|
369 |
+
* @return string
|
370 |
+
*/
|
371 |
+
private function getEscapedValue($value)
|
372 |
+
{
|
373 |
+
$escapedValue = strtr($value, array(
|
374 |
+
"\n" => "\\n",
|
375 |
+
"\t" => "\\t",
|
376 |
+
"\r" => "\\r",
|
377 |
+
"$" => "\\$",
|
378 |
+
"\"" => "\\\"",
|
379 |
+
"\\" => "\\\\",
|
380 |
+
));
|
381 |
+
return $escapedValue;
|
382 |
+
}
|
383 |
}
|
libraries/XmlImportTemplateParser.php
CHANGED
@@ -1,399 +1,399 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstSequence.php';
|
8 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstPrint.php';
|
9 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstText.php';
|
10 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
11 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
12 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
13 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstMath.php';
|
14 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstSpintax.php';
|
15 |
-
|
16 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
17 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
18 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
19 |
-
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Parses a list of nodes into AST (Abstract Syntax Tree)
|
23 |
-
*/
|
24 |
-
class XmlImportTemplateParser
|
25 |
-
{
|
26 |
-
/**
|
27 |
-
* List of tokens
|
28 |
-
*
|
29 |
-
* @var array
|
30 |
-
*/
|
31 |
-
private $tokens;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Current index
|
35 |
-
*
|
36 |
-
* @var int
|
37 |
-
*/
|
38 |
-
private $index = -1;
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Stack that stores possible block endings
|
42 |
-
*
|
43 |
-
* @var array
|
44 |
-
*/
|
45 |
-
private $clauseStack = array();
|
46 |
-
|
47 |
-
/**
|
48 |
-
* Stack of sequences
|
49 |
-
*
|
50 |
-
* @var array
|
51 |
-
*/
|
52 |
-
private $sequenceStack = array();
|
53 |
-
|
54 |
-
/**
|
55 |
-
* Whether else subclause is allowed
|
56 |
-
*
|
57 |
-
* @var bool
|
58 |
-
*/
|
59 |
-
private $elseAllowed = false;
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Creates new instance
|
63 |
-
*
|
64 |
-
* @param array $tokens
|
65 |
-
*/
|
66 |
-
public function __construct(array $tokens)
|
67 |
-
{
|
68 |
-
$this->tokens = $tokens;
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Parses the list of tokens into AST tree
|
73 |
-
*
|
74 |
-
* @return XmlImportAstSequence
|
75 |
-
*/
|
76 |
-
public function parse()
|
77 |
-
{
|
78 |
-
$result = $this->parseSequence();
|
79 |
-
|
80 |
-
if (count($this->clauseStack) > 0)
|
81 |
-
throw new XmlImportException("Unexpected end of template.");
|
82 |
-
|
83 |
-
return $result;
|
84 |
-
}
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Parses sequence
|
88 |
-
*
|
89 |
-
* @return XmlImportAstSequence
|
90 |
-
*/
|
91 |
-
private function parseSequence()
|
92 |
-
{
|
93 |
-
if (($this->index + 1) == count($this->tokens))
|
94 |
-
throw new XmlImportException("Reached end of template but statement sequence expected");
|
95 |
-
$sequence = new XmlImportAstSequence();
|
96 |
-
array_push($this->sequenceStack, $sequence);
|
97 |
-
if (count($this->clauseStack) == 0)
|
98 |
-
{
|
99 |
-
while (($this->index + 1) < count($this->tokens))
|
100 |
-
{
|
101 |
-
$sequence->addStatement($this->parseStatement());
|
102 |
-
}
|
103 |
-
}
|
104 |
-
else
|
105 |
-
{
|
106 |
-
while (($this->index + 1) < count($this->tokens))
|
107 |
-
{
|
108 |
-
if ($this->tokens[$this->index + 1]->getKind() == $this->clauseStack[count($this->clauseStack) - 1])
|
109 |
-
{
|
110 |
-
$this->index++;
|
111 |
-
array_pop($this->clauseStack);
|
112 |
-
break;
|
113 |
-
}
|
114 |
-
$statement = $this->parseStatement();
|
115 |
-
if (is_null($statement))
|
116 |
-
return $sequence;
|
117 |
-
$sequence->addStatement($statement);
|
118 |
-
}
|
119 |
-
}
|
120 |
-
array_pop($this->sequenceStack);
|
121 |
-
|
122 |
-
return $sequence;
|
123 |
-
}
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Parses statement
|
127 |
-
*
|
128 |
-
* @return XmlImportAstText
|
129 |
-
*/
|
130 |
-
private function parseStatement()
|
131 |
-
{
|
132 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_TEXT)
|
133 |
-
{
|
134 |
-
return new XmlImportAstText($this->tokens[++$this->index]->getValue());
|
135 |
-
}
|
136 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_PRINT)
|
137 |
-
{
|
138 |
-
$this->index++;
|
139 |
-
return new XmlImportAstPrint($this->parseExpression());
|
140 |
-
}
|
141 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_WITH)
|
142 |
-
{
|
143 |
-
return $this->parseWith();
|
144 |
-
}
|
145 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_FOREACH)
|
146 |
-
{
|
147 |
-
return $this->parseForeach();
|
148 |
-
}
|
149 |
-
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
150 |
-
{
|
151 |
-
return new XmlImportAstPrint($this->parseExpression());
|
152 |
-
}
|
153 |
-
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_SPINTAX)
|
154 |
-
{
|
155 |
-
return new XmlImportAstPrint($this->parseExpression());
|
156 |
-
}
|
157 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_IF)
|
158 |
-
{
|
159 |
-
return $this->parseIf();
|
160 |
-
}
|
161 |
-
elseif($this->clauseStack[count($this->clauseStack) - 1] == XmlImportToken::KIND_ENDIF &&
|
162 |
-
in_array($this->tokens[$this->index + 1]->getKind(), array(XmlImportToken::KIND_ELSE, XmlImportToken::KIND_ELSEIF)))
|
163 |
-
{
|
164 |
-
if ($this->elseAllowed)
|
165 |
-
{
|
166 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
167 |
-
$this->elseAllowed = false;
|
168 |
-
}
|
169 |
-
else
|
170 |
-
{
|
171 |
-
throw new XmlImportException("ELSEIF or ELSE is not allowed again after ELSE");
|
172 |
-
}
|
173 |
-
return null;
|
174 |
-
}
|
175 |
-
else
|
176 |
-
throw new XmlImportException ("Unexpected token {$this->tokens[$this->index + 1]->getKind()}, statement was expected.");
|
177 |
-
}
|
178 |
-
|
179 |
-
/**
|
180 |
-
* Parses expression
|
181 |
-
*
|
182 |
-
* @return XmlImportAstXPath
|
183 |
-
*/
|
184 |
-
private function parseExpression()
|
185 |
-
{
|
186 |
-
if ($this->index + 1 == count($this->tokens))
|
187 |
-
throw new XmlImportException("Reached end of template but expression was expected");
|
188 |
-
|
189 |
-
if($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
190 |
-
{
|
191 |
-
return $this->parseMath();
|
192 |
-
}
|
193 |
-
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_SPINTAX)
|
194 |
-
{
|
195 |
-
return $this->parseSpintax();
|
196 |
-
}
|
197 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
198 |
-
{
|
199 |
-
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
200 |
-
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
201 |
-
return $xpath;
|
202 |
-
}
|
203 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_STRING || $this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPERATION)
|
204 |
-
{
|
205 |
-
return new XmlImportAstString($this->tokens[++$this->index]->getValue());
|
206 |
-
}
|
207 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_INT)
|
208 |
-
{
|
209 |
-
return new XmlImportAstInteger($this->tokens[++$this->index]->getValue());
|
210 |
-
}
|
211 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_FLOAT)
|
212 |
-
{
|
213 |
-
return new XmlImportAstFloat($this->tokens[++$this->index]->getValue());
|
214 |
-
}
|
215 |
-
else
|
216 |
-
throw new XmlImportException("Unexpected token " . $this->tokens[$this->index + 1]->getKind());
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Parses function
|
221 |
-
*
|
222 |
-
* @return XmlImportAstFunction
|
223 |
-
*/
|
224 |
-
private function parseMath()
|
225 |
-
{
|
226 |
-
$math = new XmlImportAstMath($this->tokens[++$this->index]->getValue());
|
227 |
-
if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
|
228 |
-
throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
229 |
-
$this->index++;
|
230 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
231 |
-
{
|
232 |
-
$this->index++;
|
233 |
-
return $math;
|
234 |
-
}
|
235 |
-
else
|
236 |
-
{
|
237 |
-
while ($this->index < count($this->tokens) - 2)
|
238 |
-
{
|
239 |
-
$math->addArgument($this->parseExpression());
|
240 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
241 |
-
{
|
242 |
-
$this->index++;
|
243 |
-
return $math;
|
244 |
-
break;
|
245 |
-
}
|
246 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
247 |
-
$this->index++;
|
248 |
-
else
|
249 |
-
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
250 |
-
}
|
251 |
-
throw new XmlImportException("Unexpected end of MATH argument list");
|
252 |
-
}
|
253 |
-
}
|
254 |
-
|
255 |
-
/**
|
256 |
-
* Parses function
|
257 |
-
*
|
258 |
-
* @return XmlImportSpintaxFunction
|
259 |
-
*/
|
260 |
-
private function parseSpintax()
|
261 |
-
{
|
262 |
-
$spintax = new XmlImportAstSpintax($this->tokens[++$this->index]->getValue());
|
263 |
-
if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
|
264 |
-
throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
265 |
-
$this->index++;
|
266 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
267 |
-
{
|
268 |
-
$this->index++;
|
269 |
-
return $spintax;
|
270 |
-
}
|
271 |
-
else
|
272 |
-
{
|
273 |
-
while ($this->index < count($this->tokens) - 2)
|
274 |
-
{
|
275 |
-
$spintax->addArgument($this->parseExpression());
|
276 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
277 |
-
{
|
278 |
-
$this->index++;
|
279 |
-
return $spintax;
|
280 |
-
break;
|
281 |
-
}
|
282 |
-
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
283 |
-
$this->index++;
|
284 |
-
else
|
285 |
-
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
286 |
-
}
|
287 |
-
throw new XmlImportException("Unexpected end of {$function->getName()} function argument list");
|
288 |
-
}
|
289 |
-
}
|
290 |
-
|
291 |
-
/**
|
292 |
-
* Parses clause that uses XPath and returns XPath
|
293 |
-
*
|
294 |
-
* @return XmlImportAstXPath
|
295 |
-
*/
|
296 |
-
private function parseXPathDependant()
|
297 |
-
{
|
298 |
-
$this->index++;
|
299 |
-
|
300 |
-
if ($this->index + 1 == count($this->tokens))
|
301 |
-
throw new XmlImportException("Reached end of template but expression was expected");
|
302 |
-
|
303 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPEN)
|
304 |
-
$this->index++;
|
305 |
-
else
|
306 |
-
throw new XmlImportException("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
307 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
308 |
-
{
|
309 |
-
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
310 |
-
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
311 |
-
}
|
312 |
-
else
|
313 |
-
throw new XmlImportException("XPath expression expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
314 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
315 |
-
$this->index++;
|
316 |
-
else
|
317 |
-
throw new XmlImportException("Close brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
318 |
-
return $xpath;
|
319 |
-
}
|
320 |
-
|
321 |
-
/**
|
322 |
-
* Parses WITH clause
|
323 |
-
*
|
324 |
-
* @return XmlImportAstWith
|
325 |
-
*/
|
326 |
-
private function parseWith()
|
327 |
-
{
|
328 |
-
$xpath = $this->parseXPathDependant();
|
329 |
-
//store sequence exit
|
330 |
-
array_push($this->clauseStack, XmlImportToken::KIND_ENDWITH);
|
331 |
-
return new XmlImportAstWith($xpath, $this->parseSequence());
|
332 |
-
}
|
333 |
-
|
334 |
-
/**
|
335 |
-
* Parses FOREACH clause
|
336 |
-
*
|
337 |
-
* @return XmlImportAstForeach
|
338 |
-
*/
|
339 |
-
private function parseForeach()
|
340 |
-
{
|
341 |
-
$xpath = $this->parseXPathDependant();
|
342 |
-
|
343 |
-
array_push($this->clauseStack, XmlImportToken::KIND_ENDFOREACH);
|
344 |
-
return new XmlImportAstForeach($xpath, $this->parseSequence());
|
345 |
-
}
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Parses IF clause
|
349 |
-
*
|
350 |
-
* @return XmlImportAstIf
|
351 |
-
*/
|
352 |
-
private function parseIf()
|
353 |
-
{
|
354 |
-
$this->index++;
|
355 |
-
$this->elseAllowed = true;
|
356 |
-
array_push($this->clauseStack, XmlImportToken::KIND_ENDIF);
|
357 |
-
|
358 |
-
if ($this->index + 1 == count($this->tokens))
|
359 |
-
throw new XmlImportException("Reached end of template but expression was expected");
|
360 |
-
|
361 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPEN)
|
362 |
-
$this->index++;
|
363 |
-
else
|
364 |
-
throw new XmlImportException("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
365 |
-
$if = new XmlImportAstIf($this->parseExpression());
|
366 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
367 |
-
$this->index++;
|
368 |
-
else
|
369 |
-
throw new XmlImportException("Close brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
370 |
-
$if->addIfBody($this->parseSequence());
|
371 |
-
if ($this->index + 1 != count($this->tokens))
|
372 |
-
{
|
373 |
-
while ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSEIF)
|
374 |
-
{
|
375 |
-
$this->index++;
|
376 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPEN)
|
377 |
-
$this->index++;
|
378 |
-
else
|
379 |
-
throw new XmlImportException("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
380 |
-
$condition = $this->parseExpression();
|
381 |
-
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
382 |
-
$this->index++;
|
383 |
-
else
|
384 |
-
throw new XmlImportException("Close brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
385 |
-
$elseif = new XmlImportAstElseif($condition, $this->parseSequence());
|
386 |
-
$if->addElseif($elseif);
|
387 |
-
if ($this->index + 1 == count($this->tokens))
|
388 |
-
break;
|
389 |
-
}
|
390 |
-
if ($this->index + 1 < count($this->tokens) && $this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
391 |
-
{
|
392 |
-
$this->index++;
|
393 |
-
$if->addElseBody($this->parseSequence());
|
394 |
-
}
|
395 |
-
}
|
396 |
-
|
397 |
-
return $if;
|
398 |
-
}
|
399 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstSequence.php';
|
8 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstPrint.php';
|
9 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstText.php';
|
10 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
11 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
12 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
13 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstMath.php';
|
14 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstSpintax.php';
|
15 |
+
|
16 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
17 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
18 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstInteger.php';
|
19 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstFloat.php';
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Parses a list of nodes into AST (Abstract Syntax Tree)
|
23 |
+
*/
|
24 |
+
class XmlImportTemplateParser
|
25 |
+
{
|
26 |
+
/**
|
27 |
+
* List of tokens
|
28 |
+
*
|
29 |
+
* @var array
|
30 |
+
*/
|
31 |
+
private $tokens;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Current index
|
35 |
+
*
|
36 |
+
* @var int
|
37 |
+
*/
|
38 |
+
private $index = -1;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Stack that stores possible block endings
|
42 |
+
*
|
43 |
+
* @var array
|
44 |
+
*/
|
45 |
+
private $clauseStack = array();
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Stack of sequences
|
49 |
+
*
|
50 |
+
* @var array
|
51 |
+
*/
|
52 |
+
private $sequenceStack = array();
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Whether else subclause is allowed
|
56 |
+
*
|
57 |
+
* @var bool
|
58 |
+
*/
|
59 |
+
private $elseAllowed = false;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Creates new instance
|
63 |
+
*
|
64 |
+
* @param array $tokens
|
65 |
+
*/
|
66 |
+
public function __construct(array $tokens)
|
67 |
+
{
|
68 |
+
$this->tokens = $tokens;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Parses the list of tokens into AST tree
|
73 |
+
*
|
74 |
+
* @return XmlImportAstSequence
|
75 |
+
*/
|
76 |
+
public function parse()
|
77 |
+
{
|
78 |
+
$result = $this->parseSequence();
|
79 |
+
|
80 |
+
if (count($this->clauseStack) > 0)
|
81 |
+
throw new XmlImportException("Unexpected end of template.");
|
82 |
+
|
83 |
+
return $result;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Parses sequence
|
88 |
+
*
|
89 |
+
* @return XmlImportAstSequence
|
90 |
+
*/
|
91 |
+
private function parseSequence()
|
92 |
+
{
|
93 |
+
if (($this->index + 1) == count($this->tokens))
|
94 |
+
throw new XmlImportException("Reached end of template but statement sequence expected");
|
95 |
+
$sequence = new XmlImportAstSequence();
|
96 |
+
array_push($this->sequenceStack, $sequence);
|
97 |
+
if (count($this->clauseStack) == 0)
|
98 |
+
{
|
99 |
+
while (($this->index + 1) < count($this->tokens))
|
100 |
+
{
|
101 |
+
$sequence->addStatement($this->parseStatement());
|
102 |
+
}
|
103 |
+
}
|
104 |
+
else
|
105 |
+
{
|
106 |
+
while (($this->index + 1) < count($this->tokens))
|
107 |
+
{
|
108 |
+
if ($this->tokens[$this->index + 1]->getKind() == $this->clauseStack[count($this->clauseStack) - 1])
|
109 |
+
{
|
110 |
+
$this->index++;
|
111 |
+
array_pop($this->clauseStack);
|
112 |
+
break;
|
113 |
+
}
|
114 |
+
$statement = $this->parseStatement();
|
115 |
+
if (is_null($statement))
|
116 |
+
return $sequence;
|
117 |
+
$sequence->addStatement($statement);
|
118 |
+
}
|
119 |
+
}
|
120 |
+
array_pop($this->sequenceStack);
|
121 |
+
|
122 |
+
return $sequence;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Parses statement
|
127 |
+
*
|
128 |
+
* @return XmlImportAstText
|
129 |
+
*/
|
130 |
+
private function parseStatement()
|
131 |
+
{
|
132 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_TEXT)
|
133 |
+
{
|
134 |
+
return new XmlImportAstText($this->tokens[++$this->index]->getValue());
|
135 |
+
}
|
136 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_PRINT)
|
137 |
+
{
|
138 |
+
$this->index++;
|
139 |
+
return new XmlImportAstPrint($this->parseExpression());
|
140 |
+
}
|
141 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_WITH)
|
142 |
+
{
|
143 |
+
return $this->parseWith();
|
144 |
+
}
|
145 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_FOREACH)
|
146 |
+
{
|
147 |
+
return $this->parseForeach();
|
148 |
+
}
|
149 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
150 |
+
{
|
151 |
+
return new XmlImportAstPrint($this->parseExpression());
|
152 |
+
}
|
153 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_SPINTAX)
|
154 |
+
{
|
155 |
+
return new XmlImportAstPrint($this->parseExpression());
|
156 |
+
}
|
157 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_IF)
|
158 |
+
{
|
159 |
+
return $this->parseIf();
|
160 |
+
}
|
161 |
+
elseif($this->clauseStack[count($this->clauseStack) - 1] == XmlImportToken::KIND_ENDIF &&
|
162 |
+
in_array($this->tokens[$this->index + 1]->getKind(), array(XmlImportToken::KIND_ELSE, XmlImportToken::KIND_ELSEIF)))
|
163 |
+
{
|
164 |
+
if ($this->elseAllowed)
|
165 |
+
{
|
166 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
167 |
+
$this->elseAllowed = false;
|
168 |
+
}
|
169 |
+
else
|
170 |
+
{
|
171 |
+
throw new XmlImportException("ELSEIF or ELSE is not allowed again after ELSE");
|
172 |
+
}
|
173 |
+
return null;
|
174 |
+
}
|
175 |
+
else
|
176 |
+
throw new XmlImportException ("Unexpected token {$this->tokens[$this->index + 1]->getKind()}, statement was expected.");
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Parses expression
|
181 |
+
*
|
182 |
+
* @return XmlImportAstXPath
|
183 |
+
*/
|
184 |
+
private function parseExpression()
|
185 |
+
{
|
186 |
+
if ($this->index + 1 == count($this->tokens))
|
187 |
+
throw new XmlImportException("Reached end of template but expression was expected");
|
188 |
+
|
189 |
+
if($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
190 |
+
{
|
191 |
+
return $this->parseMath();
|
192 |
+
}
|
193 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_SPINTAX)
|
194 |
+
{
|
195 |
+
return $this->parseSpintax();
|
196 |
+
}
|
197 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
198 |
+
{
|
199 |
+
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
200 |
+
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
201 |
+
return $xpath;
|
202 |
+
}
|
203 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_STRING || $this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPERATION)
|
204 |
+
{
|
205 |
+
return new XmlImportAstString($this->tokens[++$this->index]->getValue());
|
206 |
+
}
|
207 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_INT)
|
208 |
+
{
|
209 |
+
return new XmlImportAstInteger($this->tokens[++$this->index]->getValue());
|
210 |
+
}
|
211 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_FLOAT)
|
212 |
+
{
|
213 |
+
return new XmlImportAstFloat($this->tokens[++$this->index]->getValue());
|
214 |
+
}
|
215 |
+
else
|
216 |
+
throw new XmlImportException("Unexpected token " . $this->tokens[$this->index + 1]->getKind());
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Parses function
|
221 |
+
*
|
222 |
+
* @return XmlImportAstFunction
|
223 |
+
*/
|
224 |
+
private function parseMath()
|
225 |
+
{
|
226 |
+
$math = new XmlImportAstMath($this->tokens[++$this->index]->getValue());
|
227 |
+
if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
|
228 |
+
throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
229 |
+
$this->index++;
|
230 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
231 |
+
{
|
232 |
+
$this->index++;
|
233 |
+
return $math;
|
234 |
+
}
|
235 |
+
else
|
236 |
+
{
|
237 |
+
while ($this->index < count($this->tokens) - 2)
|
238 |
+
{
|
239 |
+
$math->addArgument($this->parseExpression());
|
240 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
241 |
+
{
|
242 |
+
$this->index++;
|
243 |
+
return $math;
|
244 |
+
break;
|
245 |
+
}
|
246 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
247 |
+
$this->index++;
|
248 |
+
else
|
249 |
+
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
250 |
+
}
|
251 |
+
throw new XmlImportException("Unexpected end of MATH argument list");
|
252 |
+
}
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Parses function
|
257 |
+
*
|
258 |
+
* @return XmlImportSpintaxFunction
|
259 |
+
*/
|
260 |
+
private function parseSpintax()
|
261 |
+
{
|
262 |
+
$spintax = new XmlImportAstSpintax($this->tokens[++$this->index]->getValue());
|
263 |
+
if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
|
264 |
+
throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
265 |
+
$this->index++;
|
266 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
267 |
+
{
|
268 |
+
$this->index++;
|
269 |
+
return $spintax;
|
270 |
+
}
|
271 |
+
else
|
272 |
+
{
|
273 |
+
while ($this->index < count($this->tokens) - 2)
|
274 |
+
{
|
275 |
+
$spintax->addArgument($this->parseExpression());
|
276 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
277 |
+
{
|
278 |
+
$this->index++;
|
279 |
+
return $spintax;
|
280 |
+
break;
|
281 |
+
}
|
282 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
283 |
+
$this->index++;
|
284 |
+
else
|
285 |
+
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
286 |
+
}
|
287 |
+
throw new XmlImportException("Unexpected end of {$function->getName()} function argument list");
|
288 |
+
}
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Parses clause that uses XPath and returns XPath
|
293 |
+
*
|
294 |
+
* @return XmlImportAstXPath
|
295 |
+
*/
|
296 |
+
private function parseXPathDependant()
|
297 |
+
{
|
298 |
+
$this->index++;
|
299 |
+
|
300 |
+
if ($this->index + 1 == count($this->tokens))
|
301 |
+
throw new XmlImportException("Reached end of template but expression was expected");
|
302 |
+
|
303 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPEN)
|
304 |
+
$this->index++;
|
305 |
+
else
|
306 |
+
throw new XmlImportException("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
307 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
308 |
+
{
|
309 |
+
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
310 |
+
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
311 |
+
}
|
312 |
+
else
|
313 |
+
throw new XmlImportException("XPath expression expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
314 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
315 |
+
$this->index++;
|
316 |
+
else
|
317 |
+
throw new XmlImportException("Close brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
318 |
+
return $xpath;
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Parses WITH clause
|
323 |
+
*
|
324 |
+
* @return XmlImportAstWith
|
325 |
+
*/
|
326 |
+
private function parseWith()
|
327 |
+
{
|
328 |
+
$xpath = $this->parseXPathDependant();
|
329 |
+
//store sequence exit
|
330 |
+
array_push($this->clauseStack, XmlImportToken::KIND_ENDWITH);
|
331 |
+
return new XmlImportAstWith($xpath, $this->parseSequence());
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Parses FOREACH clause
|
336 |
+
*
|
337 |
+
* @return XmlImportAstForeach
|
338 |
+
*/
|
339 |
+
private function parseForeach()
|
340 |
+
{
|
341 |
+
$xpath = $this->parseXPathDependant();
|
342 |
+
|
343 |
+
array_push($this->clauseStack, XmlImportToken::KIND_ENDFOREACH);
|
344 |
+
return new XmlImportAstForeach($xpath, $this->parseSequence());
|
345 |
+
}
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Parses IF clause
|
349 |
+
*
|
350 |
+
* @return XmlImportAstIf
|
351 |
+
*/
|
352 |
+
private function parseIf()
|
353 |
+
{
|
354 |
+
$this->index++;
|
355 |
+
$this->elseAllowed = true;
|
356 |
+
array_push($this->clauseStack, XmlImportToken::KIND_ENDIF);
|
357 |
+
|
358 |
+
if ($this->index + 1 == count($this->tokens))
|
359 |
+
throw new XmlImportException("Reached end of template but expression was expected");
|
360 |
+
|
361 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPEN)
|
362 |
+
$this->index++;
|
363 |
+
else
|
364 |
+
throw new XmlImportException("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
365 |
+
$if = new XmlImportAstIf($this->parseExpression());
|
366 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
367 |
+
$this->index++;
|
368 |
+
else
|
369 |
+
throw new XmlImportException("Close brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
370 |
+
$if->addIfBody($this->parseSequence());
|
371 |
+
if ($this->index + 1 != count($this->tokens))
|
372 |
+
{
|
373 |
+
while ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSEIF)
|
374 |
+
{
|
375 |
+
$this->index++;
|
376 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_OPEN)
|
377 |
+
$this->index++;
|
378 |
+
else
|
379 |
+
throw new XmlImportException("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
380 |
+
$condition = $this->parseExpression();
|
381 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
382 |
+
$this->index++;
|
383 |
+
else
|
384 |
+
throw new XmlImportException("Close brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
385 |
+
$elseif = new XmlImportAstElseif($condition, $this->parseSequence());
|
386 |
+
$if->addElseif($elseif);
|
387 |
+
if ($this->index + 1 == count($this->tokens))
|
388 |
+
break;
|
389 |
+
}
|
390 |
+
if ($this->index + 1 < count($this->tokens) && $this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_ELSE)
|
391 |
+
{
|
392 |
+
$this->index++;
|
393 |
+
$if->addElseBody($this->parseSequence());
|
394 |
+
}
|
395 |
+
}
|
396 |
+
|
397 |
+
return $if;
|
398 |
+
}
|
399 |
}
|
libraries/XmlImportTemplateScanner.php
CHANGED
@@ -1,404 +1,404 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
require_once dirname(__FILE__) . '/XmlImportToken.php';
|
8 |
-
require_once dirname(__FILE__) . '/XmlImportException.php';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Used to scan string into a list of tokens
|
12 |
-
*/
|
13 |
-
final class XmlImportTemplateScanner
|
14 |
-
{
|
15 |
-
/**
|
16 |
-
* Language keywords
|
17 |
-
*
|
18 |
-
* @var array
|
19 |
-
*/
|
20 |
-
private $keywords = array(
|
21 |
-
'IF',
|
22 |
-
'ELSEIF',
|
23 |
-
'ELSE',
|
24 |
-
'ENDIF',
|
25 |
-
'FOREACH',
|
26 |
-
'ENDFOREACH',
|
27 |
-
'WITH',
|
28 |
-
'ENDWITH',
|
29 |
-
'MATH',
|
30 |
-
'SPINTAX'
|
31 |
-
);
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Parsing text
|
35 |
-
*/
|
36 |
-
const STATE_TEXT = 'STATE_TEXT';
|
37 |
-
|
38 |
-
/**
|
39 |
-
* Parsing XPath
|
40 |
-
*/
|
41 |
-
const STATE_XPATH = 'STATE_XPATH';
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Parsing Language
|
45 |
-
*/
|
46 |
-
const STATE_LANG = 'STATE_LANG';
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Whether it is lang block start
|
50 |
-
*
|
51 |
-
* @var bool
|
52 |
-
*/
|
53 |
-
private $isLangBegin = false;
|
54 |
-
|
55 |
-
/**
|
56 |
-
* Current parsing state
|
57 |
-
*
|
58 |
-
* @var string
|
59 |
-
*/
|
60 |
-
private $currentState = XmlImportTemplateScanner::STATE_TEXT;
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Scans template from XmlImportReaderInterface and returns the list of tokens
|
64 |
-
*
|
65 |
-
* @param XmlImportReaderInterface $input
|
66 |
-
* @return array
|
67 |
-
*/
|
68 |
-
public function scan(XmlImportReaderInterface $input)
|
69 |
-
{
|
70 |
-
$results = array();
|
71 |
-
while (($ch = $input->peek()) !== false)
|
72 |
-
{
|
73 |
-
switch ($this->currentState)
|
74 |
-
{
|
75 |
-
case XmlImportTemplateScanner::STATE_TEXT:
|
76 |
-
if ($ch == '[')
|
77 |
-
{
|
78 |
-
$this->currentState = XmlImportTemplateScanner::STATE_LANG;
|
79 |
-
$this->isLangBegin = true;
|
80 |
-
//omit [
|
81 |
-
$input->read();
|
82 |
-
}
|
83 |
-
elseif ($ch == '{')
|
84 |
-
{
|
85 |
-
$this->currentState = XmlImportTemplateScanner::STATE_XPATH;
|
86 |
-
//omit {
|
87 |
-
$input->read();
|
88 |
-
}
|
89 |
-
else
|
90 |
-
{
|
91 |
-
$results[] = $this->scanText($input);
|
92 |
-
}
|
93 |
-
break;
|
94 |
-
case XmlImportTemplateScanner::STATE_XPATH:
|
95 |
-
$results = array_merge($results, $this->scanXPath($input, false));
|
96 |
-
break;
|
97 |
-
case XmlImportTemplateScanner::STATE_LANG:
|
98 |
-
$ch = $input->peek();
|
99 |
-
|
100 |
-
if (preg_match('/\s/', $ch))
|
101 |
-
{
|
102 |
-
//omit space
|
103 |
-
$input->read();
|
104 |
-
}
|
105 |
-
elseif (preg_match('/[_a-z]/i', $ch))
|
106 |
-
{
|
107 |
-
$result = $this->scanName($input);
|
108 |
-
if (is_array($result))
|
109 |
-
$results = array_merge($results, $result);
|
110 |
-
else
|
111 |
-
$results[] = $result;
|
112 |
-
}
|
113 |
-
elseif (preg_match('/(\d|-)/', $ch))
|
114 |
-
{
|
115 |
-
$result = $this->scanNumber($input);
|
116 |
-
if (is_array($result))
|
117 |
-
$results = array_merge($results, $result);
|
118 |
-
else
|
119 |
-
$results[] = $result;
|
120 |
-
}
|
121 |
-
elseif ($ch == "+" || $ch == "-" || $ch == "*" || $ch == "/")
|
122 |
-
{
|
123 |
-
$this->isLangBegin = false;
|
124 |
-
$input->read();
|
125 |
-
$results[] = new XmlImportToken(XmlImportToken::KIND_OPERATION, $ch);
|
126 |
-
}
|
127 |
-
elseif ($ch == '"')
|
128 |
-
{
|
129 |
-
//omit "
|
130 |
-
$input->read();
|
131 |
-
$result = $this->scanString($input);
|
132 |
-
if (is_array($result))
|
133 |
-
$results = array_merge($results, $result);
|
134 |
-
else
|
135 |
-
$results[] = $result;
|
136 |
-
}
|
137 |
-
elseif ($ch == '{')
|
138 |
-
{
|
139 |
-
$input->read();
|
140 |
-
$result = $this->scanXPath($input);
|
141 |
-
if (is_array($result))
|
142 |
-
$results = array_merge($results, $result);
|
143 |
-
else
|
144 |
-
$results[] = $result;
|
145 |
-
}
|
146 |
-
elseif ($ch == '(')
|
147 |
-
{
|
148 |
-
$this->isLangBegin = false;
|
149 |
-
$input->read();
|
150 |
-
$results[] = new XmlImportToken(XmlImportToken::KIND_OPEN);
|
151 |
-
}
|
152 |
-
elseif ($ch == ')')
|
153 |
-
{
|
154 |
-
$this->isLangBegin = false;
|
155 |
-
$input->read();
|
156 |
-
$results[] = new XmlImportToken(XmlImportToken::KIND_CLOSE);
|
157 |
-
}
|
158 |
-
elseif ($ch == ',')
|
159 |
-
{
|
160 |
-
$this->isLangBegin = false;
|
161 |
-
$input->read();
|
162 |
-
$results[] = new XmlImportToken(XmlImportToken::KIND_COMMA);
|
163 |
-
}
|
164 |
-
elseif ($ch == ']' or $ch == "|")
|
165 |
-
{
|
166 |
-
$this->isLangBegin = false;
|
167 |
-
$this->currentState = XmlImportTemplateScanner::STATE_TEXT;
|
168 |
-
//omit ]
|
169 |
-
$input->read();
|
170 |
-
}
|
171 |
-
else
|
172 |
-
throw new XmlImportException("Unexpected symbol '$ch'");
|
173 |
-
|
174 |
-
break;
|
175 |
-
}
|
176 |
-
}
|
177 |
-
|
178 |
-
return $results;
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Scans text
|
183 |
-
*
|
184 |
-
* @param XmlImportReaderInterface $input
|
185 |
-
* @return XmlImportToken
|
186 |
-
*/
|
187 |
-
private function scanText($input)
|
188 |
-
{
|
189 |
-
$accum = $input->read();
|
190 |
-
while (($ch = $input->peek()) !== false)
|
191 |
-
{
|
192 |
-
if ($ch == '{' && $accum[strlen($accum) - 1] != "\\")
|
193 |
-
{
|
194 |
-
$this->currentState = XmlImportTemplateScanner::STATE_XPATH;
|
195 |
-
//omit {
|
196 |
-
$input->read();
|
197 |
-
break;
|
198 |
-
}
|
199 |
-
elseif ($ch == '[' && $accum[strlen($accum) - 1] != "\\")
|
200 |
-
{
|
201 |
-
$this->currentState = XmlImportTemplateScanner::STATE_LANG;
|
202 |
-
$this->isLangBegin = true;
|
203 |
-
//omit [
|
204 |
-
$input->read();
|
205 |
-
break;
|
206 |
-
}
|
207 |
-
else
|
208 |
-
$accum .= $input->read();
|
209 |
-
}
|
210 |
-
$accum = str_replace(array("\\[", "\\{"), array('[', '{'), $accum);
|
211 |
-
return new XmlImportToken(XmlImportToken::KIND_TEXT, $accum);
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Scans XPath
|
216 |
-
*
|
217 |
-
* @param XmlImportReaderInterface $input
|
218 |
-
* @param bool $insideLang
|
219 |
-
* @return XmlImportToken
|
220 |
-
*/
|
221 |
-
private function scanXPath($input, $insideLang = true)
|
222 |
-
{
|
223 |
-
$accum = '';
|
224 |
-
while(($ch = $input->peek()) !== false)
|
225 |
-
{
|
226 |
-
if ($ch == '}' && (strlen($accum) == 0 || $accum[strlen($accum) - 1] != "\\"))
|
227 |
-
{
|
228 |
-
//skip }
|
229 |
-
$input->read();
|
230 |
-
$accum = str_replace("\\}", '}', $accum);
|
231 |
-
if ($insideLang)
|
232 |
-
{
|
233 |
-
if ($this->isLangBegin)
|
234 |
-
{
|
235 |
-
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_XPATH, $accum));
|
236 |
-
}
|
237 |
-
else
|
238 |
-
return new XmlImportToken(XmlImportToken::KIND_XPATH, $accum);
|
239 |
-
}
|
240 |
-
else
|
241 |
-
{
|
242 |
-
$this->currentState = XmlImportTemplateScanner::STATE_TEXT;
|
243 |
-
|
244 |
-
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_XPATH, $accum));
|
245 |
-
}
|
246 |
-
}
|
247 |
-
else
|
248 |
-
$accum .= $input->read();
|
249 |
-
}
|
250 |
-
throw new XmlImportException('Unexpected end of XPath expression \'' . $accum . '\'');
|
251 |
-
}
|
252 |
-
|
253 |
-
/**
|
254 |
-
* Scans name
|
255 |
-
*
|
256 |
-
* @param XmlImportReaderInterface $input
|
257 |
-
* @return XmlImportToken
|
258 |
-
*/
|
259 |
-
private function scanName(XmlImportReaderInterface $input)
|
260 |
-
{
|
261 |
-
$accum = $input->read();
|
262 |
-
while (preg_match('/[_a-z0-9]/i', $input->peek()))
|
263 |
-
{
|
264 |
-
$accum .= $input->read();
|
265 |
-
if ($input->peek() === false)
|
266 |
-
throw new XmlImportException("Unexpected end of function or keyword name \"$accum\"");
|
267 |
-
}
|
268 |
-
if (in_array(strtoupper($accum), $this->keywords))
|
269 |
-
{
|
270 |
-
return new XmlImportToken(strtoupper($accum));
|
271 |
-
}
|
272 |
-
else
|
273 |
-
{
|
274 |
-
if ($this->isLangBegin)
|
275 |
-
{
|
276 |
-
$this->isLangBegin = false;
|
277 |
-
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_FUNCTION, $accum));
|
278 |
-
}
|
279 |
-
else
|
280 |
-
return new XmlImportToken(XmlImportToken::KIND_FUNCTION, $accum);
|
281 |
-
}
|
282 |
-
}
|
283 |
-
|
284 |
-
/**
|
285 |
-
* Scans string literal
|
286 |
-
*
|
287 |
-
* @param XmlImportReaderInterface $input
|
288 |
-
* @return XmlImportToken
|
289 |
-
*/
|
290 |
-
private function scanString(XmlImportReaderInterface $input)
|
291 |
-
{
|
292 |
-
$accum = '';
|
293 |
-
while(($ch = $input->peek()) !== false)
|
294 |
-
{
|
295 |
-
if ($ch == '"' && (strlen($accum) == 0 || $accum[strlen($accum) - 1] != "\\"))
|
296 |
-
{
|
297 |
-
//skip "
|
298 |
-
$input->read();
|
299 |
-
$accum = str_replace("\\\"", '"', $accum);
|
300 |
-
if ($this->isLangBegin)
|
301 |
-
{
|
302 |
-
$this->isLangBegin = false;
|
303 |
-
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_STRING, $accum));
|
304 |
-
}
|
305 |
-
else
|
306 |
-
{
|
307 |
-
return new XmlImportToken(XmlImportToken::KIND_STRING, $accum);
|
308 |
-
}
|
309 |
-
}
|
310 |
-
else
|
311 |
-
$accum .= $input->read();
|
312 |
-
}
|
313 |
-
throw new XmlImportException('Unexpected end of string literal "' . $accum . '"');
|
314 |
-
}
|
315 |
-
|
316 |
-
/**
|
317 |
-
* Scans number
|
318 |
-
*
|
319 |
-
* @param XmlImportReaderInterface $input
|
320 |
-
* @return XmlImportToken
|
321 |
-
*/
|
322 |
-
private function scanNumber(XmlImportReaderInterface $input)
|
323 |
-
{
|
324 |
-
$isInt = true;
|
325 |
-
$accum = $this->scanInt($input);
|
326 |
-
if ($input->peek() == '.')
|
327 |
-
{
|
328 |
-
$isInt = false;
|
329 |
-
$accum .= $input->read();
|
330 |
-
$accum .= $this->scanNumberFrac($input);
|
331 |
-
}
|
332 |
-
if (strtolower($input->peek()) == 'e' )
|
333 |
-
{
|
334 |
-
$isInt = false;
|
335 |
-
$accum .= $input->read();
|
336 |
-
$accum .= $this->scanInt($input);
|
337 |
-
}
|
338 |
-
if ($isInt)
|
339 |
-
{
|
340 |
-
if ($this->isLangBegin)
|
341 |
-
{
|
342 |
-
$this->isLangBegin = false;
|
343 |
-
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_INT, intval($accum)));
|
344 |
-
}
|
345 |
-
else
|
346 |
-
{
|
347 |
-
return new XmlImportToken(XmlImportToken::KIND_INT, intval($accum));
|
348 |
-
}
|
349 |
-
}
|
350 |
-
else
|
351 |
-
{
|
352 |
-
if ($this->isLangBegin)
|
353 |
-
{
|
354 |
-
$this->isLangBegin = false;
|
355 |
-
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_FLOAT, floatval($accum)));
|
356 |
-
}
|
357 |
-
else
|
358 |
-
{
|
359 |
-
return new XmlImportToken(XmlImportToken::KIND_FLOAT, floatval($accum));
|
360 |
-
}
|
361 |
-
}
|
362 |
-
}
|
363 |
-
|
364 |
-
/**
|
365 |
-
* Scans integer number
|
366 |
-
*
|
367 |
-
* @param XmlImportReaderInterface $input
|
368 |
-
* @return string
|
369 |
-
*/
|
370 |
-
private function scanInt(XmlImportReaderInterface $input)
|
371 |
-
{
|
372 |
-
if (preg_match('/(\d|-)/', $input->peek()))
|
373 |
-
{
|
374 |
-
$accum = $input->read();
|
375 |
-
if ($accum == '-' && !preg_match('/\d/', $input->peek()))
|
376 |
-
throw new XmlImportException("Expected digit after a minus");
|
377 |
-
while (preg_match('/\d/', $input->peek()))
|
378 |
-
{
|
379 |
-
$accum .= $input->read();
|
380 |
-
}
|
381 |
-
return $accum;
|
382 |
-
}
|
383 |
-
else
|
384 |
-
throw new XmlImportException("digit or '-' expected in a number");
|
385 |
-
}
|
386 |
-
|
387 |
-
/**
|
388 |
-
* Scans fraction part of a number
|
389 |
-
*
|
390 |
-
* @param XmlImportReaderInterface $input
|
391 |
-
* @return string
|
392 |
-
*/
|
393 |
-
private function scanNumberFrac(XmlImportReaderInterface $input)
|
394 |
-
{
|
395 |
-
$accum = '';
|
396 |
-
while (preg_match('/\d/', $input->peek()))
|
397 |
-
{
|
398 |
-
$accum .= $input->read();
|
399 |
-
}
|
400 |
-
if (strlen($accum) == 0)
|
401 |
-
throw new XmlImportException("Digits are expected after a '.'");
|
402 |
-
return $accum;
|
403 |
-
}
|
404 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
require_once dirname(__FILE__) . '/XmlImportToken.php';
|
8 |
+
require_once dirname(__FILE__) . '/XmlImportException.php';
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Used to scan string into a list of tokens
|
12 |
+
*/
|
13 |
+
final class XmlImportTemplateScanner
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* Language keywords
|
17 |
+
*
|
18 |
+
* @var array
|
19 |
+
*/
|
20 |
+
private $keywords = array(
|
21 |
+
'IF',
|
22 |
+
'ELSEIF',
|
23 |
+
'ELSE',
|
24 |
+
'ENDIF',
|
25 |
+
'FOREACH',
|
26 |
+
'ENDFOREACH',
|
27 |
+
'WITH',
|
28 |
+
'ENDWITH',
|
29 |
+
'MATH',
|
30 |
+
'SPINTAX'
|
31 |
+
);
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Parsing text
|
35 |
+
*/
|
36 |
+
const STATE_TEXT = 'STATE_TEXT';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Parsing XPath
|
40 |
+
*/
|
41 |
+
const STATE_XPATH = 'STATE_XPATH';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Parsing Language
|
45 |
+
*/
|
46 |
+
const STATE_LANG = 'STATE_LANG';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Whether it is lang block start
|
50 |
+
*
|
51 |
+
* @var bool
|
52 |
+
*/
|
53 |
+
private $isLangBegin = false;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Current parsing state
|
57 |
+
*
|
58 |
+
* @var string
|
59 |
+
*/
|
60 |
+
private $currentState = XmlImportTemplateScanner::STATE_TEXT;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Scans template from XmlImportReaderInterface and returns the list of tokens
|
64 |
+
*
|
65 |
+
* @param XmlImportReaderInterface $input
|
66 |
+
* @return array
|
67 |
+
*/
|
68 |
+
public function scan(XmlImportReaderInterface $input)
|
69 |
+
{
|
70 |
+
$results = array();
|
71 |
+
while (($ch = $input->peek()) !== false)
|
72 |
+
{
|
73 |
+
switch ($this->currentState)
|
74 |
+
{
|
75 |
+
case XmlImportTemplateScanner::STATE_TEXT:
|
76 |
+
if ($ch == '[')
|
77 |
+
{
|
78 |
+
$this->currentState = XmlImportTemplateScanner::STATE_LANG;
|
79 |
+
$this->isLangBegin = true;
|
80 |
+
//omit [
|
81 |
+
$input->read();
|
82 |
+
}
|
83 |
+
elseif ($ch == '{')
|
84 |
+
{
|
85 |
+
$this->currentState = XmlImportTemplateScanner::STATE_XPATH;
|
86 |
+
//omit {
|
87 |
+
$input->read();
|
88 |
+
}
|
89 |
+
else
|
90 |
+
{
|
91 |
+
$results[] = $this->scanText($input);
|
92 |
+
}
|
93 |
+
break;
|
94 |
+
case XmlImportTemplateScanner::STATE_XPATH:
|
95 |
+
$results = array_merge($results, $this->scanXPath($input, false));
|
96 |
+
break;
|
97 |
+
case XmlImportTemplateScanner::STATE_LANG:
|
98 |
+
$ch = $input->peek();
|
99 |
+
|
100 |
+
if (preg_match('/\s/', $ch))
|
101 |
+
{
|
102 |
+
//omit space
|
103 |
+
$input->read();
|
104 |
+
}
|
105 |
+
elseif (preg_match('/[_a-z]/i', $ch))
|
106 |
+
{
|
107 |
+
$result = $this->scanName($input);
|
108 |
+
if (is_array($result))
|
109 |
+
$results = array_merge($results, $result);
|
110 |
+
else
|
111 |
+
$results[] = $result;
|
112 |
+
}
|
113 |
+
elseif (preg_match('/(\d|-)/', $ch))
|
114 |
+
{
|
115 |
+
$result = $this->scanNumber($input);
|
116 |
+
if (is_array($result))
|
117 |
+
$results = array_merge($results, $result);
|
118 |
+
else
|
119 |
+
$results[] = $result;
|
120 |
+
}
|
121 |
+
elseif ($ch == "+" || $ch == "-" || $ch == "*" || $ch == "/")
|
122 |
+
{
|
123 |
+
$this->isLangBegin = false;
|
124 |
+
$input->read();
|
125 |
+
$results[] = new XmlImportToken(XmlImportToken::KIND_OPERATION, $ch);
|
126 |
+
}
|
127 |
+
elseif ($ch == '"')
|
128 |
+
{
|
129 |
+
//omit "
|
130 |
+
$input->read();
|
131 |
+
$result = $this->scanString($input);
|
132 |
+
if (is_array($result))
|
133 |
+
$results = array_merge($results, $result);
|
134 |
+
else
|
135 |
+
$results[] = $result;
|
136 |
+
}
|
137 |
+
elseif ($ch == '{')
|
138 |
+
{
|
139 |
+
$input->read();
|
140 |
+
$result = $this->scanXPath($input);
|
141 |
+
if (is_array($result))
|
142 |
+
$results = array_merge($results, $result);
|
143 |
+
else
|
144 |
+
$results[] = $result;
|
145 |
+
}
|
146 |
+
elseif ($ch == '(')
|
147 |
+
{
|
148 |
+
$this->isLangBegin = false;
|
149 |
+
$input->read();
|
150 |
+
$results[] = new XmlImportToken(XmlImportToken::KIND_OPEN);
|
151 |
+
}
|
152 |
+
elseif ($ch == ')')
|
153 |
+
{
|
154 |
+
$this->isLangBegin = false;
|
155 |
+
$input->read();
|
156 |
+
$results[] = new XmlImportToken(XmlImportToken::KIND_CLOSE);
|
157 |
+
}
|
158 |
+
elseif ($ch == ',')
|
159 |
+
{
|
160 |
+
$this->isLangBegin = false;
|
161 |
+
$input->read();
|
162 |
+
$results[] = new XmlImportToken(XmlImportToken::KIND_COMMA);
|
163 |
+
}
|
164 |
+
elseif ($ch == ']' or $ch == "|")
|
165 |
+
{
|
166 |
+
$this->isLangBegin = false;
|
167 |
+
$this->currentState = XmlImportTemplateScanner::STATE_TEXT;
|
168 |
+
//omit ]
|
169 |
+
$input->read();
|
170 |
+
}
|
171 |
+
else
|
172 |
+
throw new XmlImportException("Unexpected symbol '$ch'");
|
173 |
+
|
174 |
+
break;
|
175 |
+
}
|
176 |
+
}
|
177 |
+
|
178 |
+
return $results;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Scans text
|
183 |
+
*
|
184 |
+
* @param XmlImportReaderInterface $input
|
185 |
+
* @return XmlImportToken
|
186 |
+
*/
|
187 |
+
private function scanText($input)
|
188 |
+
{
|
189 |
+
$accum = $input->read();
|
190 |
+
while (($ch = $input->peek()) !== false)
|
191 |
+
{
|
192 |
+
if ($ch == '{' && $accum[strlen($accum) - 1] != "\\")
|
193 |
+
{
|
194 |
+
$this->currentState = XmlImportTemplateScanner::STATE_XPATH;
|
195 |
+
//omit {
|
196 |
+
$input->read();
|
197 |
+
break;
|
198 |
+
}
|
199 |
+
elseif ($ch == '[' && $accum[strlen($accum) - 1] != "\\")
|
200 |
+
{
|
201 |
+
$this->currentState = XmlImportTemplateScanner::STATE_LANG;
|
202 |
+
$this->isLangBegin = true;
|
203 |
+
//omit [
|
204 |
+
$input->read();
|
205 |
+
break;
|
206 |
+
}
|
207 |
+
else
|
208 |
+
$accum .= $input->read();
|
209 |
+
}
|
210 |
+
$accum = str_replace(array("\\[", "\\{"), array('[', '{'), $accum);
|
211 |
+
return new XmlImportToken(XmlImportToken::KIND_TEXT, $accum);
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Scans XPath
|
216 |
+
*
|
217 |
+
* @param XmlImportReaderInterface $input
|
218 |
+
* @param bool $insideLang
|
219 |
+
* @return XmlImportToken
|
220 |
+
*/
|
221 |
+
private function scanXPath($input, $insideLang = true)
|
222 |
+
{
|
223 |
+
$accum = '';
|
224 |
+
while(($ch = $input->peek()) !== false)
|
225 |
+
{
|
226 |
+
if ($ch == '}' && (strlen($accum) == 0 || $accum[strlen($accum) - 1] != "\\"))
|
227 |
+
{
|
228 |
+
//skip }
|
229 |
+
$input->read();
|
230 |
+
$accum = str_replace("\\}", '}', $accum);
|
231 |
+
if ($insideLang)
|
232 |
+
{
|
233 |
+
if ($this->isLangBegin)
|
234 |
+
{
|
235 |
+
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_XPATH, $accum));
|
236 |
+
}
|
237 |
+
else
|
238 |
+
return new XmlImportToken(XmlImportToken::KIND_XPATH, $accum);
|
239 |
+
}
|
240 |
+
else
|
241 |
+
{
|
242 |
+
$this->currentState = XmlImportTemplateScanner::STATE_TEXT;
|
243 |
+
|
244 |
+
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_XPATH, $accum));
|
245 |
+
}
|
246 |
+
}
|
247 |
+
else
|
248 |
+
$accum .= $input->read();
|
249 |
+
}
|
250 |
+
throw new XmlImportException('Unexpected end of XPath expression \'' . $accum . '\'');
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Scans name
|
255 |
+
*
|
256 |
+
* @param XmlImportReaderInterface $input
|
257 |
+
* @return XmlImportToken
|
258 |
+
*/
|
259 |
+
private function scanName(XmlImportReaderInterface $input)
|
260 |
+
{
|
261 |
+
$accum = $input->read();
|
262 |
+
while (preg_match('/[_a-z0-9]/i', $input->peek()))
|
263 |
+
{
|
264 |
+
$accum .= $input->read();
|
265 |
+
if ($input->peek() === false)
|
266 |
+
throw new XmlImportException("Unexpected end of function or keyword name \"$accum\"");
|
267 |
+
}
|
268 |
+
if (in_array(strtoupper($accum), $this->keywords))
|
269 |
+
{
|
270 |
+
return new XmlImportToken(strtoupper($accum));
|
271 |
+
}
|
272 |
+
else
|
273 |
+
{
|
274 |
+
if ($this->isLangBegin)
|
275 |
+
{
|
276 |
+
$this->isLangBegin = false;
|
277 |
+
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_FUNCTION, $accum));
|
278 |
+
}
|
279 |
+
else
|
280 |
+
return new XmlImportToken(XmlImportToken::KIND_FUNCTION, $accum);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Scans string literal
|
286 |
+
*
|
287 |
+
* @param XmlImportReaderInterface $input
|
288 |
+
* @return XmlImportToken
|
289 |
+
*/
|
290 |
+
private function scanString(XmlImportReaderInterface $input)
|
291 |
+
{
|
292 |
+
$accum = '';
|
293 |
+
while(($ch = $input->peek()) !== false)
|
294 |
+
{
|
295 |
+
if ($ch == '"' && (strlen($accum) == 0 || $accum[strlen($accum) - 1] != "\\"))
|
296 |
+
{
|
297 |
+
//skip "
|
298 |
+
$input->read();
|
299 |
+
$accum = str_replace("\\\"", '"', $accum);
|
300 |
+
if ($this->isLangBegin)
|
301 |
+
{
|
302 |
+
$this->isLangBegin = false;
|
303 |
+
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_STRING, $accum));
|
304 |
+
}
|
305 |
+
else
|
306 |
+
{
|
307 |
+
return new XmlImportToken(XmlImportToken::KIND_STRING, $accum);
|
308 |
+
}
|
309 |
+
}
|
310 |
+
else
|
311 |
+
$accum .= $input->read();
|
312 |
+
}
|
313 |
+
throw new XmlImportException('Unexpected end of string literal "' . $accum . '"');
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* Scans number
|
318 |
+
*
|
319 |
+
* @param XmlImportReaderInterface $input
|
320 |
+
* @return XmlImportToken
|
321 |
+
*/
|
322 |
+
private function scanNumber(XmlImportReaderInterface $input)
|
323 |
+
{
|
324 |
+
$isInt = true;
|
325 |
+
$accum = $this->scanInt($input);
|
326 |
+
if ($input->peek() == '.')
|
327 |
+
{
|
328 |
+
$isInt = false;
|
329 |
+
$accum .= $input->read();
|
330 |
+
$accum .= $this->scanNumberFrac($input);
|
331 |
+
}
|
332 |
+
if (strtolower($input->peek()) == 'e' )
|
333 |
+
{
|
334 |
+
$isInt = false;
|
335 |
+
$accum .= $input->read();
|
336 |
+
$accum .= $this->scanInt($input);
|
337 |
+
}
|
338 |
+
if ($isInt)
|
339 |
+
{
|
340 |
+
if ($this->isLangBegin)
|
341 |
+
{
|
342 |
+
$this->isLangBegin = false;
|
343 |
+
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_INT, intval($accum)));
|
344 |
+
}
|
345 |
+
else
|
346 |
+
{
|
347 |
+
return new XmlImportToken(XmlImportToken::KIND_INT, intval($accum));
|
348 |
+
}
|
349 |
+
}
|
350 |
+
else
|
351 |
+
{
|
352 |
+
if ($this->isLangBegin)
|
353 |
+
{
|
354 |
+
$this->isLangBegin = false;
|
355 |
+
return array(new XmlImportToken(XmlImportToken::KIND_PRINT), new XmlImportToken(XmlImportToken::KIND_FLOAT, floatval($accum)));
|
356 |
+
}
|
357 |
+
else
|
358 |
+
{
|
359 |
+
return new XmlImportToken(XmlImportToken::KIND_FLOAT, floatval($accum));
|
360 |
+
}
|
361 |
+
}
|
362 |
+
}
|
363 |
+
|
364 |
+
/**
|
365 |
+
* Scans integer number
|
366 |
+
*
|
367 |
+
* @param XmlImportReaderInterface $input
|
368 |
+
* @return string
|
369 |
+
*/
|
370 |
+
private function scanInt(XmlImportReaderInterface $input)
|
371 |
+
{
|
372 |
+
if (preg_match('/(\d|-)/', $input->peek()))
|
373 |
+
{
|
374 |
+
$accum = $input->read();
|
375 |
+
if ($accum == '-' && !preg_match('/\d/', $input->peek()))
|
376 |
+
throw new XmlImportException("Expected digit after a minus");
|
377 |
+
while (preg_match('/\d/', $input->peek()))
|
378 |
+
{
|
379 |
+
$accum .= $input->read();
|
380 |
+
}
|
381 |
+
return $accum;
|
382 |
+
}
|
383 |
+
else
|
384 |
+
throw new XmlImportException("digit or '-' expected in a number");
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Scans fraction part of a number
|
389 |
+
*
|
390 |
+
* @param XmlImportReaderInterface $input
|
391 |
+
* @return string
|
392 |
+
*/
|
393 |
+
private function scanNumberFrac(XmlImportReaderInterface $input)
|
394 |
+
{
|
395 |
+
$accum = '';
|
396 |
+
while (preg_match('/\d/', $input->peek()))
|
397 |
+
{
|
398 |
+
$accum .= $input->read();
|
399 |
+
}
|
400 |
+
if (strlen($accum) == 0)
|
401 |
+
throw new XmlImportException("Digits are expected after a '.'");
|
402 |
+
return $accum;
|
403 |
+
}
|
404 |
}
|
libraries/XmlImportToken.php
CHANGED
@@ -1,172 +1,172 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
-
* @package General
|
5 |
-
*/
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Represents a template token
|
9 |
-
*/
|
10 |
-
class XmlImportToken
|
11 |
-
{
|
12 |
-
/**
|
13 |
-
* Token Kind
|
14 |
-
*
|
15 |
-
* @var string
|
16 |
-
*/
|
17 |
-
private $kind;
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Token value
|
21 |
-
*
|
22 |
-
* @var mixed
|
23 |
-
*/
|
24 |
-
private $value;
|
25 |
-
|
26 |
-
/**
|
27 |
-
* Token is a text
|
28 |
-
*/
|
29 |
-
const KIND_TEXT = 'TEXT';
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Token is a print statement
|
33 |
-
*/
|
34 |
-
const KIND_PRINT = 'PRINT';
|
35 |
-
|
36 |
-
/**
|
37 |
-
* Token is a XPath literal
|
38 |
-
*/
|
39 |
-
const KIND_XPATH = "XPATH";
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Token is an IF keyword
|
43 |
-
*/
|
44 |
-
const KIND_IF = "IF";
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Token is an ENDIF keyword
|
48 |
-
*/
|
49 |
-
const KIND_ENDIF = "ENDIF";
|
50 |
-
|
51 |
-
/**
|
52 |
-
* Token is an ELSEIF keyword
|
53 |
-
*/
|
54 |
-
const KIND_ELSEIF = "ELSEIF";
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Token is an ELSE keyword
|
58 |
-
*/
|
59 |
-
const KIND_ELSE = "ELSE";
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Token is a WITH keyword
|
63 |
-
*/
|
64 |
-
const KIND_WITH = "WITH";
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Token is an ENDWITH keyword
|
68 |
-
*/
|
69 |
-
const KIND_ENDWITH = "ENDWITH";
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Token is a FOREACH keyword
|
73 |
-
*/
|
74 |
-
const KIND_FOREACH = "FOREACH";
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Token is an ENDFOREACH keyword
|
78 |
-
*/
|
79 |
-
const KIND_ENDFOREACH = "ENDFOREACH";
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Token is a function name
|
83 |
-
*/
|
84 |
-
const KIND_FUNCTION = "FUNCTION";
|
85 |
-
|
86 |
-
/**
|
87 |
-
* Token is a comma
|
88 |
-
*/
|
89 |
-
const KIND_COMMA = "COMMA";
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Token is an open brace
|
93 |
-
*/
|
94 |
-
const KIND_OPEN = "OPEN";
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Token is a close brace
|
98 |
-
*/
|
99 |
-
const KIND_CLOSE = "CLOSE";
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Token is a string literal
|
103 |
-
*/
|
104 |
-
const KIND_STRING = "STRING";
|
105 |
-
|
106 |
-
/**
|
107 |
-
* Token is an integer number
|
108 |
-
*/
|
109 |
-
const KIND_INT = "INT";
|
110 |
-
|
111 |
-
/**
|
112 |
-
* Token is a float number
|
113 |
-
*/
|
114 |
-
const KIND_FLOAT = "FLOAT";
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Token is a math on the price element
|
118 |
-
*/
|
119 |
-
const KIND_MATH = "MATH";
|
120 |
-
|
121 |
-
/**
|
122 |
-
* Token is a spintax
|
123 |
-
*/
|
124 |
-
const KIND_SPINTAX = "SPINTAX";
|
125 |
-
|
126 |
-
/**
|
127 |
-
* Token is a math on the price element
|
128 |
-
*/
|
129 |
-
const KIND_OPERATION = "OPERATION";
|
130 |
-
|
131 |
-
/**
|
132 |
-
* Creates new instance of a token
|
133 |
-
*
|
134 |
-
* @param string $kind kind of a token
|
135 |
-
* @param mixed $value value of a token
|
136 |
-
*/
|
137 |
-
public function __construct($kind, $value = null)
|
138 |
-
{
|
139 |
-
$this->kind = $kind;
|
140 |
-
$this->value = $value;
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Gets a kind of a token
|
145 |
-
*
|
146 |
-
* @return string
|
147 |
-
*/
|
148 |
-
public function getKind()
|
149 |
-
{
|
150 |
-
return $this->kind;
|
151 |
-
}
|
152 |
-
|
153 |
-
/**
|
154 |
-
* Gets a value of a token
|
155 |
-
*
|
156 |
-
* @return mixed
|
157 |
-
*/
|
158 |
-
public function getValue()
|
159 |
-
{
|
160 |
-
return $this->value;
|
161 |
-
}
|
162 |
-
|
163 |
-
/**
|
164 |
-
* String representation of a token
|
165 |
-
*
|
166 |
-
* @return string
|
167 |
-
*/
|
168 |
-
public function __toString()
|
169 |
-
{
|
170 |
-
return '--> ' . $this->getKind() . (is_null($this->value) ? '' : ': "' . $this->getValue() . '"');
|
171 |
-
}
|
172 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package General
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Represents a template token
|
9 |
+
*/
|
10 |
+
class XmlImportToken
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Token Kind
|
14 |
+
*
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
private $kind;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Token value
|
21 |
+
*
|
22 |
+
* @var mixed
|
23 |
+
*/
|
24 |
+
private $value;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Token is a text
|
28 |
+
*/
|
29 |
+
const KIND_TEXT = 'TEXT';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Token is a print statement
|
33 |
+
*/
|
34 |
+
const KIND_PRINT = 'PRINT';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Token is a XPath literal
|
38 |
+
*/
|
39 |
+
const KIND_XPATH = "XPATH";
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Token is an IF keyword
|
43 |
+
*/
|
44 |
+
const KIND_IF = "IF";
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Token is an ENDIF keyword
|
48 |
+
*/
|
49 |
+
const KIND_ENDIF = "ENDIF";
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Token is an ELSEIF keyword
|
53 |
+
*/
|
54 |
+
const KIND_ELSEIF = "ELSEIF";
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Token is an ELSE keyword
|
58 |
+
*/
|
59 |
+
const KIND_ELSE = "ELSE";
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Token is a WITH keyword
|
63 |
+
*/
|
64 |
+
const KIND_WITH = "WITH";
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Token is an ENDWITH keyword
|
68 |
+
*/
|
69 |
+
const KIND_ENDWITH = "ENDWITH";
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Token is a FOREACH keyword
|
73 |
+
*/
|
74 |
+
const KIND_FOREACH = "FOREACH";
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Token is an ENDFOREACH keyword
|
78 |
+
*/
|
79 |
+
const KIND_ENDFOREACH = "ENDFOREACH";
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Token is a function name
|
83 |
+
*/
|
84 |
+
const KIND_FUNCTION = "FUNCTION";
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Token is a comma
|
88 |
+
*/
|
89 |
+
const KIND_COMMA = "COMMA";
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Token is an open brace
|
93 |
+
*/
|
94 |
+
const KIND_OPEN = "OPEN";
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Token is a close brace
|
98 |
+
*/
|
99 |
+
const KIND_CLOSE = "CLOSE";
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Token is a string literal
|
103 |
+
*/
|
104 |
+
const KIND_STRING = "STRING";
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Token is an integer number
|
108 |
+
*/
|
109 |
+
const KIND_INT = "INT";
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Token is a float number
|
113 |
+
*/
|
114 |
+
const KIND_FLOAT = "FLOAT";
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Token is a math on the price element
|
118 |
+
*/
|
119 |
+
const KIND_MATH = "MATH";
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Token is a spintax
|
123 |
+
*/
|
124 |
+
const KIND_SPINTAX = "SPINTAX";
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Token is a math on the price element
|
128 |
+
*/
|
129 |
+
const KIND_OPERATION = "OPERATION";
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Creates new instance of a token
|
133 |
+
*
|
134 |
+
* @param string $kind kind of a token
|
135 |
+
* @param mixed $value value of a token
|
136 |
+
*/
|
137 |
+
public function __construct($kind, $value = null)
|
138 |
+
{
|
139 |
+
$this->kind = $kind;
|
140 |
+
$this->value = $value;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Gets a kind of a token
|
145 |
+
*
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
public function getKind()
|
149 |
+
{
|
150 |
+
return $this->kind;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Gets a value of a token
|
155 |
+
*
|
156 |
+
* @return mixed
|
157 |
+
*/
|
158 |
+
public function getValue()
|
159 |
+
{
|
160 |
+
return $this->value;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* String representation of a token
|
165 |
+
*
|
166 |
+
* @return string
|
167 |
+
*/
|
168 |
+
public function __toString()
|
169 |
+
{
|
170 |
+
return '--> ' . $this->getKind() . (is_null($this->value) ? '' : ': "' . $this->getValue() . '"');
|
171 |
+
}
|
172 |
}
|
models/import/record.php
CHANGED
@@ -1,922 +1,1293 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class PMXI_Import_Record extends PMXI_Model_Record {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Some pre-processing logic, such as removing control characters from xml to prevent parsing errors
|
7 |
-
* @param string $xml
|
8 |
-
*/
|
9 |
-
public static function preprocessXml( & $xml) {
|
10 |
-
|
11 |
-
$xml = str_replace("&", "&", str_replace("&","&", $xml));
|
12 |
-
|
13 |
-
}
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Validate XML to be valid for improt
|
17 |
-
* @param string $xml
|
18 |
-
* @param WP_Error[optional] $errors
|
19 |
-
* @return bool Validation status
|
20 |
-
*/
|
21 |
-
public static function validateXml( & $xml, $errors = NULL) {
|
22 |
-
if (FALSE === $xml or '' == $xml) {
|
23 |
-
$errors and $errors->add('form-validation', __('XML file does not exist, not accessible or empty', 'pmxi_plugin'));
|
24 |
-
} else {
|
25 |
-
|
26 |
-
PMXI_Import_Record::preprocessXml($xml);
|
27 |
-
|
28 |
-
libxml_use_internal_errors(true);
|
29 |
-
libxml_clear_errors();
|
30 |
-
$_x = @simplexml_load_string($xml);
|
31 |
-
$xml_errors = libxml_get_errors();
|
32 |
-
libxml_clear_errors();
|
33 |
-
if ($xml_errors) {
|
34 |
-
$error_msg = '<strong>' . __('Invalid XML', 'pmxi_plugin') . '</strong><ul>';
|
35 |
-
foreach($xml_errors as $error) {
|
36 |
-
$error_msg .= '<li>';
|
37 |
-
$error_msg .= __('Line', 'pmxi_plugin') . ' ' . $error->line . ', ';
|
38 |
-
$error_msg .= __('Column', 'pmxi_plugin') . ' ' . $error->column . ', ';
|
39 |
-
$error_msg .= __('Code', 'pmxi_plugin') . ' ' . $error->code . ': ';
|
40 |
-
$error_msg .= '<em>' . trim(esc_html($error->message)) . '</em>';
|
41 |
-
$error_msg .= '</li>';
|
42 |
-
}
|
43 |
-
$error_msg .= '</ul>';
|
44 |
-
$errors and $errors->add('form-validation', $error_msg);
|
45 |
-
} else {
|
46 |
-
return true;
|
47 |
-
}
|
48 |
-
}
|
49 |
-
return false;
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Initialize model instance
|
54 |
-
* @param array[optional] $data Array of record data to initialize object with
|
55 |
-
*/
|
56 |
-
public function __construct($data = array()) {
|
57 |
-
parent::__construct($data);
|
58 |
-
$this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'imports');
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Perform import operation
|
63 |
-
* @param string $xml XML string to import
|
64 |
-
* @param callback[optional] $logger Method where progress messages are submmitted
|
65 |
-
* @return PMXI_Import_Record
|
66 |
-
* @chainable
|
67 |
-
*/
|
68 |
-
public function process($xml, $logger = NULL, $chunk = false, $is_cron = false) {
|
69 |
-
add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
|
70 |
-
|
71 |
-
$this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
|
72 |
-
// If import process NOT in large file mode the save history file
|
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 |
-
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing
|
118 |
-
$
|
119 |
-
if (
|
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 |
-
|
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 |
-
|
777 |
-
|
778 |
-
|
779 |
-
|
780 |
-
|
781 |
-
$this->
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
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 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class PMXI_Import_Record extends PMXI_Model_Record {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Some pre-processing logic, such as removing control characters from xml to prevent parsing errors
|
7 |
+
* @param string $xml
|
8 |
+
*/
|
9 |
+
public static function preprocessXml( & $xml) {
|
10 |
+
|
11 |
+
$xml = str_replace("&", "&", str_replace("&","&", $xml));
|
12 |
+
|
13 |
+
}
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Validate XML to be valid for improt
|
17 |
+
* @param string $xml
|
18 |
+
* @param WP_Error[optional] $errors
|
19 |
+
* @return bool Validation status
|
20 |
+
*/
|
21 |
+
public static function validateXml( & $xml, $errors = NULL) {
|
22 |
+
if (FALSE === $xml or '' == $xml) {
|
23 |
+
$errors and $errors->add('form-validation', __('XML file does not exist, not accessible or empty', 'pmxi_plugin'));
|
24 |
+
} else {
|
25 |
+
|
26 |
+
PMXI_Import_Record::preprocessXml($xml);
|
27 |
+
|
28 |
+
libxml_use_internal_errors(true);
|
29 |
+
libxml_clear_errors();
|
30 |
+
$_x = @simplexml_load_string($xml);
|
31 |
+
$xml_errors = libxml_get_errors();
|
32 |
+
libxml_clear_errors();
|
33 |
+
if ($xml_errors) {
|
34 |
+
$error_msg = '<strong>' . __('Invalid XML', 'pmxi_plugin') . '</strong><ul>';
|
35 |
+
foreach($xml_errors as $error) {
|
36 |
+
$error_msg .= '<li>';
|
37 |
+
$error_msg .= __('Line', 'pmxi_plugin') . ' ' . $error->line . ', ';
|
38 |
+
$error_msg .= __('Column', 'pmxi_plugin') . ' ' . $error->column . ', ';
|
39 |
+
$error_msg .= __('Code', 'pmxi_plugin') . ' ' . $error->code . ': ';
|
40 |
+
$error_msg .= '<em>' . trim(esc_html($error->message)) . '</em>';
|
41 |
+
$error_msg .= '</li>';
|
42 |
+
}
|
43 |
+
$error_msg .= '</ul>';
|
44 |
+
$errors and $errors->add('form-validation', $error_msg);
|
45 |
+
} else {
|
46 |
+
return true;
|
47 |
+
}
|
48 |
+
}
|
49 |
+
return false;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Initialize model instance
|
54 |
+
* @param array[optional] $data Array of record data to initialize object with
|
55 |
+
*/
|
56 |
+
public function __construct($data = array()) {
|
57 |
+
parent::__construct($data);
|
58 |
+
$this->setTable(PMXI_Plugin::getInstance()->getTablePrefix() . 'imports');
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Perform import operation
|
63 |
+
* @param string $xml XML string to import
|
64 |
+
* @param callback[optional] $logger Method where progress messages are submmitted
|
65 |
+
* @return PMXI_Import_Record
|
66 |
+
* @chainable
|
67 |
+
*/
|
68 |
+
public function process($xml, $logger = NULL, $chunk = false, $is_cron = false) {
|
69 |
+
add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
|
70 |
+
|
71 |
+
$this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
|
72 |
+
// If import process NOT in large file mode the save history file
|
73 |
+
|
74 |
+
$avoid_pingbacks = PMXI_Plugin::getInstance()->getOption('pingbacks');
|
75 |
+
|
76 |
+
if ( $avoid_pingbacks and ! defined( 'WP_IMPORTING' ) ) define( 'WP_IMPORTING', true );
|
77 |
+
|
78 |
+
$postRecord = new PMXI_Post_Record();
|
79 |
+
|
80 |
+
$tmp_files = array();
|
81 |
+
// compose records to import
|
82 |
+
$records = array();
|
83 |
+
$chunk_records = array();
|
84 |
+
if ($this->options['is_import_specified']) {
|
85 |
+
foreach (preg_split('% *, *%', $this->options['import_specified'], -1, PREG_SPLIT_NO_EMPTY) as $chank) {
|
86 |
+
if (preg_match('%^(\d+)-(\d+)$%', $chank, $mtch)) {
|
87 |
+
$records = array_merge($records, range(intval($mtch[1]), intval($mtch[2])));
|
88 |
+
} else {
|
89 |
+
$records = array_merge($records, array(intval($chank)));
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
$chunk_records = $records;
|
94 |
+
|
95 |
+
if ($this->large_import == 'Yes' and !empty($records)){
|
96 |
+
|
97 |
+
$_SESSION['pmxi_import']['count'] = count($records);
|
98 |
+
|
99 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
100 |
+
|
101 |
+
if (!in_array($chunk, $records) and (!$this->options['create_chunks'] or $is_cron)){
|
102 |
+
$logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'pmxi_plugin'));
|
103 |
+
$_SESSION['pmxi_import']['warnings']++;
|
104 |
+
// Time Elapsed
|
105 |
+
if ( ! $is_cron ){
|
106 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
107 |
+
$logger and call_user_func($logger, $progress_msg);
|
108 |
+
}
|
109 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
110 |
+
return;
|
111 |
+
}
|
112 |
+
else $records = array();
|
113 |
+
}
|
114 |
+
}
|
115 |
+
try {
|
116 |
+
|
117 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing titles...', 'pmxi_plugin'));
|
118 |
+
$titles = XmlImportParser::factory($xml, $this->xpath, $this->template['title'], $file)->parse($records); $tmp_files[] = $file;
|
119 |
+
if ($this->large_import != 'Yes') $_SESSION['pmxi_import']['count'] = count($titles);
|
120 |
+
|
121 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing excerpts...', 'pmxi_plugin'));
|
122 |
+
$post_excerpt = array();
|
123 |
+
if (!empty($this->options['post_excerpt'])){
|
124 |
+
$post_excerpt = XmlImportParser::factory($xml, $this->xpath, $this->options['post_excerpt'], $file)->parse($records); $tmp_files[] = $file;
|
125 |
+
}
|
126 |
+
else{
|
127 |
+
count($titles) and $post_excerpt = array_fill(0, count($titles), '');
|
128 |
+
}
|
129 |
+
|
130 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing authors...', 'pmxi_plugin'));
|
131 |
+
$post_author = array();
|
132 |
+
$current_user = wp_get_current_user();
|
133 |
+
|
134 |
+
if (!empty($this->options['author'])){
|
135 |
+
$post_author = XmlImportParser::factory($xml, $this->xpath, $this->options['author'], $file)->parse($records); $tmp_files[] = $file;
|
136 |
+
foreach ($post_author as $key => $author) {
|
137 |
+
$user = get_user_by('login', $author) or $user = get_user_by('slug', $author) or $user = get_user_by('email', $author) or ctype_digit($author) and $user = get_user_by('id', $author);
|
138 |
+
$post_author[$key] = (!empty($user)) ? $user->ID : $current_user->ID;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
else{
|
142 |
+
count($titles) and $post_author = array_fill(0, count($titles), $current_user->ID);
|
143 |
+
}
|
144 |
+
|
145 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing slugs...', 'pmxi_plugin'));
|
146 |
+
$post_slug = array();
|
147 |
+
if (!empty($this->options['post_slug'])){
|
148 |
+
$post_slug = XmlImportParser::factory($xml, $this->xpath, $this->options['post_slug'], $file)->parse($records); $tmp_files[] = $file;
|
149 |
+
}
|
150 |
+
else{
|
151 |
+
count($titles) and $post_slug = array_fill(0, count($titles), '');
|
152 |
+
}
|
153 |
+
|
154 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing contents...', 'pmxi_plugin'));
|
155 |
+
$contents = XmlImportParser::factory(
|
156 |
+
(intval($this->template['is_keep_linebreaks']) ? $xml : preg_replace('%\r\n?|\n%', ' ', $xml)),
|
157 |
+
$this->xpath,
|
158 |
+
$this->template['content'],
|
159 |
+
$file)->parse($records
|
160 |
+
); $tmp_files[] = $file;
|
161 |
+
|
162 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing dates...', 'pmxi_plugin'));
|
163 |
+
if ('specific' == $this->options['date_type']) {
|
164 |
+
$dates = XmlImportParser::factory($xml, $this->xpath, $this->options['date'], $file)->parse($records); $tmp_files[] = $file;
|
165 |
+
$warned = array(); // used to prevent the same notice displaying several times
|
166 |
+
foreach ($dates as $i => $d) {
|
167 |
+
$time = strtotime($d);
|
168 |
+
if (FALSE === $time) {
|
169 |
+
in_array($d, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $d));
|
170 |
+
$_SESSION['pmxi_import']['warnings']++;
|
171 |
+
$time = time();
|
172 |
+
}
|
173 |
+
$dates[$i] = date('Y-m-d H:i:s', $time);
|
174 |
+
}
|
175 |
+
} else {
|
176 |
+
$dates_start = XmlImportParser::factory($xml, $this->xpath, $this->options['date_start'], $file)->parse($records); $tmp_files[] = $file;
|
177 |
+
$dates_end = XmlImportParser::factory($xml, $this->xpath, $this->options['date_end'], $file)->parse($records); $tmp_files[] = $file;
|
178 |
+
$warned = array(); // used to prevent the same notice displaying several times
|
179 |
+
foreach ($dates_start as $i => $d) {
|
180 |
+
$time_start = strtotime($dates_start[$i]);
|
181 |
+
if (FALSE === $time_start) {
|
182 |
+
in_array($dates_start[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_start[$i]));
|
183 |
+
$_SESSION['pmxi_import']['warnings']++;
|
184 |
+
$time_start = time();
|
185 |
+
}
|
186 |
+
$time_end = strtotime($dates_end[$i]);
|
187 |
+
if (FALSE === $time_end) {
|
188 |
+
in_array($dates_end[$i], $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: unrecognized date format `%s`, assigning current date', 'pmxi_plugin'), $warned[] = $dates_end[$i]));
|
189 |
+
$_SESSION['pmxi_import']['warnings']++;
|
190 |
+
$time_end = time();
|
191 |
+
}
|
192 |
+
$dates[$i] = date('Y-m-d H:i:s', mt_rand($time_start, $time_end));
|
193 |
+
}
|
194 |
+
}
|
195 |
+
|
196 |
+
$tags = array();
|
197 |
+
if ($this->options['tags']) {
|
198 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing tags...', 'pmxi_plugin'));
|
199 |
+
$tags_raw = XmlImportParser::factory($xml, $this->xpath, $this->options['tags'], $file)->parse($records); $tmp_files[] = $file;
|
200 |
+
foreach ($tags_raw as $i => $t_raw) {
|
201 |
+
$tags[$i] = '';
|
202 |
+
if ('' != $t_raw) $tags[$i] = implode(', ', str_getcsv($t_raw, $this->options['tags_delim']));
|
203 |
+
}
|
204 |
+
} else {
|
205 |
+
count($titles) and $tags = array_fill(0, count($titles), '');
|
206 |
+
}
|
207 |
+
|
208 |
+
// [posts categories]
|
209 |
+
require_once(ABSPATH . 'wp-admin/includes/taxonomy.php');
|
210 |
+
|
211 |
+
if ('post' == $this->options['type']) {
|
212 |
+
|
213 |
+
$cats = array();
|
214 |
+
|
215 |
+
$categories_hierarchy = (!empty($this->options['categories'])) ? json_decode($this->options['categories']) : array();
|
216 |
+
|
217 |
+
if ((!empty($categories_hierarchy) and is_array($categories_hierarchy))){
|
218 |
+
|
219 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing categories...', 'pmxi_plugin'));
|
220 |
+
$categories = array();
|
221 |
+
|
222 |
+
foreach ($categories_hierarchy as $k => $category): if ("" == $category->xpath) continue;
|
223 |
+
$cats_raw = XmlImportParser::factory($xml, $this->xpath, str_replace('\'','"',$category->xpath), $file)->parse($records); $tmp_files[] = $file;
|
224 |
+
$warned = array(); // used to prevent the same notice displaying several times
|
225 |
+
foreach ($cats_raw as $i => $c_raw) {
|
226 |
+
if (empty($categories_hierarchy[$k]->cat_ids[$i])) $categories_hierarchy[$k]->cat_ids[$i] = array();
|
227 |
+
if (empty($cats[$i])) $cats[$i] = array();
|
228 |
+
$count_cats = count($cats[$i]);
|
229 |
+
|
230 |
+
$delimeted_categories = explode(html_entity_decode($this->options['categories_delim']), html_entity_decode($c_raw));
|
231 |
+
|
232 |
+
if ('' != $c_raw) foreach (explode(html_entity_decode($this->options['categories_delim']), html_entity_decode($c_raw)) as $j => $cc) if ('' != $cc) {
|
233 |
+
$cat = get_term_by('name', trim($cc), 'category') or $cat = get_term_by('slug', trim($cc), 'category') or ctype_digit($cc) and $cat = get_term_by('id', trim($cc), 'category');
|
234 |
+
if ( !empty($category->parent_id) ) {
|
235 |
+
foreach ($categories_hierarchy as $key => $value){
|
236 |
+
if ($value->item_id == $category->parent_id and !empty($value->cat_ids[$i])){
|
237 |
+
foreach ($value->cat_ids[$i] as $parent) {
|
238 |
+
if (!$j or !$this->options['categories_auto_nested']){
|
239 |
+
$cats[$i][] = array(
|
240 |
+
'name' => trim($cc),
|
241 |
+
'parent' => (is_array($parent)) ? $parent['name'] : $parent, // if parent taxonomy exists then return ID else return TITLE
|
242 |
+
'assign' => $category->assign
|
243 |
+
);
|
244 |
+
}
|
245 |
+
elseif($this->options['categories_auto_nested']){
|
246 |
+
$cats[$i][] = array(
|
247 |
+
'name' => trim($cc),
|
248 |
+
'parent' => (!empty($delimeted_categories[$j - 1])) ? trim($delimeted_categories[$j - 1]) : false, // if parent taxonomy exists then return ID else return TITLE
|
249 |
+
'assign' => $category->assign
|
250 |
+
);
|
251 |
+
}
|
252 |
+
}
|
253 |
+
}
|
254 |
+
}
|
255 |
+
}
|
256 |
+
else {
|
257 |
+
if (!$j or !$this->options['categories_auto_nested']){
|
258 |
+
$cats[$i][] = array(
|
259 |
+
'name' => trim($cc),
|
260 |
+
'parent' => false,
|
261 |
+
'assign' => $category->assign
|
262 |
+
);
|
263 |
+
}
|
264 |
+
elseif ($this->options['categories_auto_nested']){
|
265 |
+
$cats[$i][] = array(
|
266 |
+
'name' => trim($cc),
|
267 |
+
'parent' => (!empty($delimeted_categories[$j - 1])) ? trim($delimeted_categories[$j - 1]) : false,
|
268 |
+
'assign' => $category->assign
|
269 |
+
);
|
270 |
+
}
|
271 |
+
|
272 |
+
}
|
273 |
+
}
|
274 |
+
if ($count_cats < count($cats[$i])) $categories_hierarchy[$k]->cat_ids[$i][] = $cats[$i][count($cats[$i]) - 1];
|
275 |
+
}
|
276 |
+
endforeach;
|
277 |
+
} else{
|
278 |
+
count($titles) and $cats = array_fill(0, count($titles), '');
|
279 |
+
}
|
280 |
+
|
281 |
+
}
|
282 |
+
// [/posts categories]
|
283 |
+
|
284 |
+
// [custom taxonomies]
|
285 |
+
$taxonomies = array();
|
286 |
+
$taxonomies_param = $this->options['type'].'_taxonomies';
|
287 |
+
if ('page' == $this->options['type']) {
|
288 |
+
$taxonomies_object_type = 'page';
|
289 |
+
} elseif ('' != $this->options['custom_type']) {
|
290 |
+
$taxonomies_object_type = $this->options['custom_type'];
|
291 |
+
} else {
|
292 |
+
$taxonomies_object_type = 'post';
|
293 |
+
}
|
294 |
+
|
295 |
+
if (!empty($this->options[$taxonomies_param]) and is_array($this->options[$taxonomies_param])): foreach ($this->options[$taxonomies_param] as $tx_name => $tx_template) if ('' != $tx_template) {
|
296 |
+
$tx = get_taxonomy($tx_name);
|
297 |
+
if (in_array($taxonomies_object_type, $tx->object_type)) {
|
298 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, sprintf(__('Composing terms for `%s` taxonomy...', 'pmxi_plugin'), $tx->labels->name));
|
299 |
+
$txes = array();
|
300 |
+
|
301 |
+
$taxonomies_hierarchy = json_decode($tx_template);
|
302 |
+
foreach ($taxonomies_hierarchy as $k => $taxonomy){ if ("" == $taxonomy->xpath) continue;
|
303 |
+
$txes_raw = XmlImportParser::factory($xml, $this->xpath, str_replace('\'','"',$taxonomy->xpath), $file)->parse($records); $tmp_files[] = $file;
|
304 |
+
$warned = array();
|
305 |
+
foreach ($txes_raw as $i => $tx_raw) {
|
306 |
+
if (empty($taxonomies_hierarchy[$k]->txn_names[$i])) $taxonomies_hierarchy[$k]->txn_names[$i] = array();
|
307 |
+
if (empty($taxonomies[$tx_name][$i])) $taxonomies[$tx_name][$i] = array();
|
308 |
+
$count_cats = count($taxonomies[$tx_name][$i]);
|
309 |
+
|
310 |
+
$delimeted_taxonomies = explode((!empty($taxonomy->delim)) ? html_entity_decode($taxonomy->delim) : ',', html_entity_decode($tx_raw));
|
311 |
+
|
312 |
+
if ('' != $tx_raw) foreach (explode((!empty($taxonomy->delim)) ? html_entity_decode($taxonomy->delim) : ',', html_entity_decode($tx_raw)) as $j => $cc) if ('' != $cc) {
|
313 |
+
|
314 |
+
$cat = get_term_by('name', trim($cc), $tx_name) or $cat = get_term_by('slug', trim($cc), $tx_name) or ctype_digit($cc) and $cat = get_term_by('id', $cc, $tx_name);
|
315 |
+
if (!empty($taxonomy->parent_id)) {
|
316 |
+
foreach ($taxonomies_hierarchy as $key => $value){
|
317 |
+
if ($value->item_id == $taxonomy->parent_id and !empty($value->txn_names[$i])){
|
318 |
+
foreach ($value->txn_names[$i] as $parent) {
|
319 |
+
if (!$j or !$taxonomy->auto_nested){
|
320 |
+
$taxonomies[$tx_name][$i][] = array(
|
321 |
+
'name' => trim($cc),
|
322 |
+
'parent' => $parent,
|
323 |
+
'assign' => $taxonomy->assign
|
324 |
+
);
|
325 |
+
}
|
326 |
+
elseif ($taxonomy->auto_nested){
|
327 |
+
$taxonomies[$tx_name][$i][] = array(
|
328 |
+
'name' => trim($cc),
|
329 |
+
'parent' => (!empty($delimeted_taxonomies[$j - 1])) ? trim($delimeted_taxonomies[$j - 1]) : false,
|
330 |
+
'assign' => $taxonomy->assign
|
331 |
+
);
|
332 |
+
}
|
333 |
+
}
|
334 |
+
}
|
335 |
+
}
|
336 |
+
|
337 |
+
}
|
338 |
+
else {
|
339 |
+
if (!$j or !$taxonomy->auto_nested){
|
340 |
+
$taxonomies[$tx_name][$i][] = array(
|
341 |
+
'name' => trim($cc),
|
342 |
+
'parent' => false,
|
343 |
+
'assign' => $taxonomy->assign
|
344 |
+
);
|
345 |
+
}
|
346 |
+
elseif ($taxonomy->auto_nested) {
|
347 |
+
$taxonomies[$tx_name][$i][] = array(
|
348 |
+
'name' => trim($cc),
|
349 |
+
'parent' => (!empty($delimeted_taxonomies[$j - 1])) ? trim($delimeted_taxonomies[$j - 1]) : false,
|
350 |
+
'assign' => $taxonomy->assign
|
351 |
+
);
|
352 |
+
}
|
353 |
+
}
|
354 |
+
}
|
355 |
+
if ($count_cats < count($taxonomies[$tx_name][$i])) $taxonomies_hierarchy[$k]->txn_names[$i][] = $taxonomies[$tx_name][$i][count($taxonomies[$tx_name][$i]) - 1];
|
356 |
+
}
|
357 |
+
}
|
358 |
+
}
|
359 |
+
}; endif;
|
360 |
+
// [/custom taxonomies]
|
361 |
+
|
362 |
+
// serialized featured images
|
363 |
+
if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
|
364 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
|
365 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>: No featured images will be created', 'pmxi_plugin'));
|
366 |
+
$_SESSION['pmxi_import']['warnings']++;
|
367 |
+
} else {
|
368 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for featured images...', 'pmxi_plugin'));
|
369 |
+
$featured_images = array();
|
370 |
+
if ($this->options['featured_image']) {
|
371 |
+
// Detect if images is separated by comma
|
372 |
+
$imgs = explode(',',$this->options['featured_image']);
|
373 |
+
if (!empty($imgs)){
|
374 |
+
$parse_multiple = true;
|
375 |
+
foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
|
376 |
+
|
377 |
+
if ($parse_multiple)
|
378 |
+
{
|
379 |
+
foreach($imgs as $img)
|
380 |
+
{
|
381 |
+
$posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
|
382 |
+
foreach($posts_images as $i => $val) $featured_images[$i][] = $val;
|
383 |
+
}
|
384 |
+
}
|
385 |
+
else
|
386 |
+
{
|
387 |
+
$featured_images = XmlImportParser::factory($xml, $this->xpath, $this->options['featured_image'], $file)->parse($records); $tmp_files[] = $file;
|
388 |
+
}
|
389 |
+
}
|
390 |
+
|
391 |
+
} else {
|
392 |
+
count($titles) and $featured_images = array_fill(0, count($titles), '');
|
393 |
+
}
|
394 |
+
}
|
395 |
+
|
396 |
+
// serialized attachments
|
397 |
+
if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
|
398 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
|
399 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>: No attachments will be created', 'pmxi_plugin'));
|
400 |
+
$_SESSION['pmxi_import']['warnings']++;
|
401 |
+
} else {
|
402 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing URLs for attachments files...', 'pmxi_plugin'));
|
403 |
+
$attachments = array();
|
404 |
+
if ($this->options['attachments']) {
|
405 |
+
// Detect if attachments is separated by comma
|
406 |
+
$atchs = explode(',', $this->options['attachments']);
|
407 |
+
if (!empty($atchs)){
|
408 |
+
$parse_multiple = true;
|
409 |
+
foreach($atchs as $atch) if (!preg_match("/{.*}/", trim($atch))) $parse_multiple = false;
|
410 |
+
|
411 |
+
if ($parse_multiple)
|
412 |
+
{
|
413 |
+
foreach($atchs as $atch)
|
414 |
+
{
|
415 |
+
$posts_attachments = XmlImportParser::factory($xml, $this->xpath, trim($atch), $file)->parse($records); $tmp_files[] = $file;
|
416 |
+
foreach($posts_attachments as $i => $val) $attachments[$i][] = $val;
|
417 |
+
}
|
418 |
+
}
|
419 |
+
else
|
420 |
+
{
|
421 |
+
$attachments = XmlImportParser::factory($xml, $this->xpath, $this->options['attachments'], $file)->parse($records); $tmp_files[] = $file;
|
422 |
+
}
|
423 |
+
}
|
424 |
+
|
425 |
+
} else {
|
426 |
+
count($titles) and $attachments = array_fill(0, count($titles), '');
|
427 |
+
}
|
428 |
+
}
|
429 |
+
|
430 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Composing unique keys...', 'pmxi_plugin'));
|
431 |
+
$unique_keys = XmlImportParser::factory($xml, $this->xpath, $this->options['unique_key'], $file)->parse($records); $tmp_files[] = $file;
|
432 |
+
|
433 |
+
($chunk == 1 or (empty($this->large_import) or $this->large_import == 'No')) and $logger and call_user_func($logger, __('Processing posts...', 'pmxi_plugin'));
|
434 |
+
|
435 |
+
if ('post' == $this->options['type'] and '' != $this->options['custom_type']) {
|
436 |
+
$post_type = $this->options['custom_type'];
|
437 |
+
} else {
|
438 |
+
$post_type = $this->options['type'];
|
439 |
+
}
|
440 |
+
|
441 |
+
// Import WooCommerce products
|
442 |
+
if ( $post_type == "product" and class_exists('PMWI_Plugin')) {
|
443 |
+
|
444 |
+
$product = new PMWI_Import_Record();
|
445 |
+
|
446 |
+
extract( $product->process($this, count($titles), $xml, $logger, $chunk) );
|
447 |
+
|
448 |
+
}
|
449 |
+
|
450 |
+
$current_post_ids = array();
|
451 |
+
foreach ($titles as $i => $void) {
|
452 |
+
|
453 |
+
if (!empty($chunk_records) and $this->large_import == 'Yes' and $this->options['create_chunks'] and !$is_cron and !in_array($_SESSION['pmxi_import']['chunk_number'], $chunk_records)) {
|
454 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
455 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
456 |
+
|
457 |
+
$logger and call_user_func($logger, __('<b>SKIPPED</b>: by specified records option', 'pmxi_plugin'));
|
458 |
+
$_SESSION['pmxi_import']['warnings']++;
|
459 |
+
// Time Elapsed
|
460 |
+
if ( ! $is_cron ){
|
461 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
462 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
463 |
+
$logger and call_user_func($logger, $progress_msg);
|
464 |
+
}
|
465 |
+
$this->set(array(
|
466 |
+
'imported' => $this->imported + 1,
|
467 |
+
'created' => $_SESSION['pmxi_import']['created_records'],
|
468 |
+
'updated' => $_SESSION['pmxi_import']['updated_records']
|
469 |
+
))->save();
|
470 |
+
continue;
|
471 |
+
}
|
472 |
+
|
473 |
+
if (empty($titles[$i])) {
|
474 |
+
if (class_exists('PMWI_Plugin') and !empty($single_product_parent_ID[$i])){
|
475 |
+
$titles[$i] = $single_product_parent_ID[$i] . ' Product Variation';
|
476 |
+
}
|
477 |
+
else{
|
478 |
+
$logger and call_user_func($logger, __('<b>SKIPPED</b>: by empty title', 'pmxi_plugin'));
|
479 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
480 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
481 |
+
$_SESSION['pmxi_import']['warnings']++;
|
482 |
+
$this->set(array(
|
483 |
+
'imported' => $this->imported + 1,
|
484 |
+
'created' => $_SESSION['pmxi_import']['created_records'],
|
485 |
+
'updated' => $_SESSION['pmxi_import']['updated_records']
|
486 |
+
))->save();
|
487 |
+
continue;
|
488 |
+
}
|
489 |
+
}
|
490 |
+
|
491 |
+
$articleData = array(
|
492 |
+
'post_type' => $post_type,
|
493 |
+
'post_status' => $this->options['status'],
|
494 |
+
'comment_status' => $this->options['comment_status'],
|
495 |
+
'ping_status' => $this->options['ping_status'],
|
496 |
+
'post_title' => ($this->template['fix_characters']) ? utf8_encode(html_entity_decode($titles[$i])) : (($this->template['is_leave_html']) ? html_entity_decode($titles[$i]) : $titles[$i]),
|
497 |
+
'post_excerpt' => ($this->template['fix_characters']) ? utf8_encode(html_entity_decode($post_excerpt[$i])) : (($this->template['is_leave_html']) ? html_entity_decode($post_excerpt[$i]) : $post_excerpt[$i]),
|
498 |
+
'post_name' => $post_slug[$i],
|
499 |
+
'post_content' => ($this->template['fix_characters']) ? utf8_encode(html_entity_decode($contents[$i])) : (($this->template['is_leave_html']) ? html_entity_decode($contents[$i]) : $contents[$i]),
|
500 |
+
'post_date' => $dates[$i],
|
501 |
+
'post_date_gmt' => get_gmt_from_date($dates[$i]),
|
502 |
+
'post_author' => $post_author[$i] ,
|
503 |
+
'tags_input' => $tags[$i]
|
504 |
+
);
|
505 |
+
|
506 |
+
if ('post' != $articleData['post_type']){
|
507 |
+
$articleData += array(
|
508 |
+
'menu_order' => $this->options['order'],
|
509 |
+
'post_parent' => $this->options['parent'],
|
510 |
+
);
|
511 |
+
}
|
512 |
+
|
513 |
+
// Re-import Records Matching
|
514 |
+
$post_to_update = false; $post_to_update_id = false;
|
515 |
+
|
516 |
+
// if Auto Matching re-import option selected
|
517 |
+
if ("manual" != $this->options['duplicate_matching']){
|
518 |
+
$postRecord->clear();
|
519 |
+
// find corresponding article among previously imported
|
520 |
+
$postRecord->getBy(array(
|
521 |
+
'unique_key' => $unique_keys[$i],
|
522 |
+
'import_id' => $this->id,
|
523 |
+
));
|
524 |
+
if ( ! $postRecord->isEmpty() )
|
525 |
+
$post_to_update = get_post($post_to_update_id = $postRecord->post_id);
|
526 |
+
|
527 |
+
// if Manual Matching re-import option seleted
|
528 |
+
} else {
|
529 |
+
|
530 |
+
$postRecord->clear();
|
531 |
+
// find corresponding article among previously imported
|
532 |
+
$postRecord->getBy(array(
|
533 |
+
'unique_key' => $unique_keys[$i],
|
534 |
+
'import_id' => $this->id,
|
535 |
+
));
|
536 |
+
|
537 |
+
if ('custom field' == $this->options['duplicate_indicator']) {
|
538 |
+
$custom_duplicate_value = XmlImportParser::factory($xml, $this->xpath, $this->options['custom_duplicate_value'], $file)->parse($records); $tmp_files[] = $file;
|
539 |
+
$custom_duplicate_name = XmlImportParser::factory($xml, $this->xpath, $this->options['custom_duplicate_name'], $file)->parse($records); $tmp_files[] = $file;
|
540 |
+
}
|
541 |
+
else{
|
542 |
+
count($titles) and $custom_duplicate_name = $custom_duplicate_value = array_fill(0, count($titles), '');
|
543 |
+
}
|
544 |
+
|
545 |
+
// handle duplicates according to import settings
|
546 |
+
if ($duplicates = $this->findDuplicates($articleData, $custom_duplicate_name[$i], $custom_duplicate_value[$i], $this->options['duplicate_indicator'])) {
|
547 |
+
$duplicate_id = array_shift($duplicates);
|
548 |
+
if ($duplicate_id) {
|
549 |
+
$post_to_update = get_post($post_to_update_id = $duplicate_id);
|
550 |
+
}
|
551 |
+
}
|
552 |
+
}
|
553 |
+
|
554 |
+
// Duplicate record is founded
|
555 |
+
if ($post_to_update){
|
556 |
+
// Do not update already existing records option selected
|
557 |
+
if ("yes" == $this->options['is_keep_former_posts']) {
|
558 |
+
$current_post_ids[] = $_SESSION['pmxi_import']['current_post_ids'][] = $post_to_update_id;
|
559 |
+
if ($is_cron){
|
560 |
+
$tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
|
561 |
+
$tmp_array[] = $post_to_update_id;
|
562 |
+
$this->set(array(
|
563 |
+
'current_post_ids' => json_encode($tmp_array)
|
564 |
+
))->save();
|
565 |
+
}
|
566 |
+
// Do not update product variations
|
567 |
+
if ($post_type == "product" and class_exists('PMWI_Plugin')){
|
568 |
+
|
569 |
+
$children = get_posts( array(
|
570 |
+
'post_parent' => $post_to_update_id,
|
571 |
+
'posts_per_page'=> -1,
|
572 |
+
'post_type' => 'product_variation',
|
573 |
+
'fields' => 'ids',
|
574 |
+
'post_status' => 'publish'
|
575 |
+
) );
|
576 |
+
|
577 |
+
if ( $children ) {
|
578 |
+
foreach ( $children as $child ) {
|
579 |
+
$current_post_ids[] = $_SESSION['pmxi_import']['current_post_ids'][] = $child;
|
580 |
+
if ($is_cron){
|
581 |
+
$tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
|
582 |
+
$tmp_array[] = $child;
|
583 |
+
$this->set(array(
|
584 |
+
'current_post_ids' => json_encode($tmp_array)
|
585 |
+
))->save();
|
586 |
+
}
|
587 |
+
}
|
588 |
+
}
|
589 |
+
}
|
590 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
591 |
+
$logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: Previously imported record found for `%s`', 'pmxi_plugin'), $articleData['post_title']));
|
592 |
+
$_SESSION['pmxi_import']['warnings']++;
|
593 |
+
if ( ! $is_cron ){
|
594 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
595 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
596 |
+
$logger and call_user_func($logger, $progress_msg);
|
597 |
+
}
|
598 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
599 |
+
continue;
|
600 |
+
}
|
601 |
+
$articleData['ID'] = $post_to_update_id;
|
602 |
+
// preserve date of already existing article when duplicate is found
|
603 |
+
if ($this->options['is_keep_categories']) { // preserve categories and tags of already existing article if corresponding setting is specified
|
604 |
+
$cats_list = get_the_category($articleData['ID']);
|
605 |
+
if (is_wp_error($cats_list)) {
|
606 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current categories for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
607 |
+
$_SESSION['pmxi_import']['warnings']++;
|
608 |
+
} else {
|
609 |
+
$cats_new = array();
|
610 |
+
foreach ($cats_list as $c) {
|
611 |
+
$cats_new[] = $c->cat_ID;
|
612 |
+
}
|
613 |
+
$cats[$i] = $cats_new;
|
614 |
+
}
|
615 |
+
|
616 |
+
$tags_list = get_the_tags($articleData['ID']);
|
617 |
+
if (is_wp_error($tags_list)) {
|
618 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current tags for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
619 |
+
$_SESSION['pmxi_import']['warnings']++;
|
620 |
+
} else {
|
621 |
+
$tags_new = array();
|
622 |
+
if ($tags_list) foreach ($tags_list as $t) {
|
623 |
+
$tags_new[] = $t->name;
|
624 |
+
}
|
625 |
+
$articleData['tags_input'] = implode(', ', $tags_new);
|
626 |
+
}
|
627 |
+
|
628 |
+
foreach (array_keys($taxonomies) as $tx_name) {
|
629 |
+
$txes_list = get_the_terms($articleData['ID'], $tx_name);
|
630 |
+
if (is_wp_error($txes_list)) {
|
631 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to get current taxonomies for article #%d, updating with those read from XML file', 'pmxi_plugin'), $articleData['ID']));
|
632 |
+
$_SESSION['pmxi_import']['warnings']++;
|
633 |
+
} else {
|
634 |
+
$txes_new = array();
|
635 |
+
if (!empty($txes_list)):
|
636 |
+
foreach ($txes_list as $t) {
|
637 |
+
$txes_new[] = $t->name;
|
638 |
+
}
|
639 |
+
endif;
|
640 |
+
$taxonomies[$tx_name][$i] = $txes_new;
|
641 |
+
}
|
642 |
+
}
|
643 |
+
}
|
644 |
+
if ($this->options['is_keep_dates']) { // preserve date of already existing article when duplicate is found
|
645 |
+
$articleData['post_date'] = $post_to_update->post_date;
|
646 |
+
$articleData['post_date_gmt'] = $post_to_update->post_date_gmt;
|
647 |
+
}
|
648 |
+
if ($this->options['is_keep_status']) { // preserve status and trashed flag
|
649 |
+
$articleData['post_status'] = $post_to_update->post_status;
|
650 |
+
}
|
651 |
+
if ($this->options['is_keep_content']){
|
652 |
+
$articleData['post_content'] = $post_to_update->post_content;
|
653 |
+
}
|
654 |
+
if ($this->options['is_keep_title']){
|
655 |
+
$articleData['post_title'] = $post_to_update->post_title;
|
656 |
+
}
|
657 |
+
if ($this->options['is_keep_excerpt']){
|
658 |
+
$articleData['post_excerpt'] = $post_to_update->post_excerpt;
|
659 |
+
}
|
660 |
+
if ($this->options['is_keep_menu_order']){
|
661 |
+
$articleData['menu_order'] = $post_to_update->menu_order;
|
662 |
+
}
|
663 |
+
// handle obsolete attachments (i.e. delete or keep) according to import settings
|
664 |
+
if ( ! $this->options['is_keep_images'] and ! $this->options['no_create_featured_image']){
|
665 |
+
wp_delete_attachments($articleData['ID']);
|
666 |
+
}
|
667 |
+
}
|
668 |
+
elseif ( ! $postRecord->isEmpty() ){
|
669 |
+
|
670 |
+
// existing post not found though it's track was found... clear the leftover, plugin will continue to treat record as new
|
671 |
+
$postRecord->delete();
|
672 |
+
|
673 |
+
}
|
674 |
+
|
675 |
+
// no new records are created. it will only update posts it finds matching duplicates for
|
676 |
+
if ($this->options['not_create_records'] and empty($articleData['ID'])){
|
677 |
+
$_SESSION['pmxi_import']['skipped_records']++;
|
678 |
+
$logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: by "Not add new records" option for `%s`', 'pmxi_plugin'), $articleData['post_title']));
|
679 |
+
if ( ! $is_cron ){
|
680 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
681 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
682 |
+
$logger and call_user_func($logger, $progress_msg);
|
683 |
+
}
|
684 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
685 |
+
continue;
|
686 |
+
}
|
687 |
+
|
688 |
+
// cloak urls with `WP Wizard Cloak` if corresponding option is set
|
689 |
+
if ( ! empty($this->options['is_cloak']) and class_exists('PMLC_Plugin')) {
|
690 |
+
if (preg_match_all('%<a\s[^>]*href=(?(?=")"([^"]*)"|(?(?=\')\'([^\']*)\'|([^\s>]*)))%is', $articleData['post_content'], $matches, PREG_PATTERN_ORDER)) {
|
691 |
+
$hrefs = array_unique(array_merge(array_filter($matches[1]), array_filter($matches[2]), array_filter($matches[3])));
|
692 |
+
foreach ($hrefs as $url) {
|
693 |
+
if (preg_match('%^\w+://%i', $url)) { // mask only links having protocol
|
694 |
+
// try to find matching cloaked link among already registered ones
|
695 |
+
$list = new PMLC_Link_List(); $linkTable = $list->getTable();
|
696 |
+
$rule = new PMLC_Rule_Record(); $ruleTable = $rule->getTable();
|
697 |
+
$dest = new PMLC_Destination_Record(); $destTable = $dest->getTable();
|
698 |
+
$list->join($ruleTable, "$ruleTable.link_id = $linkTable.id")
|
699 |
+
->join($destTable, "$destTable.rule_id = $ruleTable.id")
|
700 |
+
->setColumns("$linkTable.*")
|
701 |
+
->getBy(array(
|
702 |
+
"$linkTable.destination_type =" => 'ONE_SET',
|
703 |
+
"$linkTable.is_trashed =" => 0,
|
704 |
+
"$linkTable.preset =" => '',
|
705 |
+
"$linkTable.expire_on =" => '0000-00-00',
|
706 |
+
"$ruleTable.type =" => 'ONE_SET',
|
707 |
+
"$destTable.weight =" => 100,
|
708 |
+
"$destTable.url LIKE" => $url,
|
709 |
+
), NULL, 1, 1)->convertRecords();
|
710 |
+
if ($list->count()) { // matching link found
|
711 |
+
$link = $list[0];
|
712 |
+
} else { // register new cloaked link
|
713 |
+
global $wpdb;
|
714 |
+
$slug = max(
|
715 |
+
intval($wpdb->get_var("SELECT MAX(CONVERT(name, SIGNED)) FROM $linkTable")),
|
716 |
+
intval($wpdb->get_var("SELECT MAX(CONVERT(slug, SIGNED)) FROM $linkTable")),
|
717 |
+
0
|
718 |
+
);
|
719 |
+
$i = 0; do {
|
720 |
+
is_int(++$slug) and $slug > 0 or $slug = 1;
|
721 |
+
$is_slug_found = ! intval($wpdb->get_var("SELECT COUNT(*) FROM $linkTable WHERE name = '$slug' OR slug = '$slug'"));
|
722 |
+
} while( ! $is_slug_found and $i++ < 100000);
|
723 |
+
if ($is_slug_found) {
|
724 |
+
$link = new PMLC_Link_Record(array(
|
725 |
+
'name' => strval($slug),
|
726 |
+
'slug' => strval($slug),
|
727 |
+
'header_tracking_code' => '',
|
728 |
+
'footer_tracking_code' => '',
|
729 |
+
'redirect_type' => '301',
|
730 |
+
'destination_type' => 'ONE_SET',
|
731 |
+
'preset' => '',
|
732 |
+
'forward_url_params' => 1,
|
733 |
+
'no_global_tracking_code' => 0,
|
734 |
+
'expire_on' => '0000-00-00',
|
735 |
+
'created_on' => date('Y-m-d H:i:s'),
|
736 |
+
'is_trashed' => 0,
|
737 |
+
));
|
738 |
+
$link->insert();
|
739 |
+
$rule = new PMLC_Rule_Record(array(
|
740 |
+
'link_id' => $link->id,
|
741 |
+
'type' => 'ONE_SET',
|
742 |
+
'rule' => '',
|
743 |
+
));
|
744 |
+
$rule->insert();
|
745 |
+
$dest = new PMLC_Destination_Record(array(
|
746 |
+
'rule_id' => $rule->id,
|
747 |
+
'url' => $url,
|
748 |
+
'weight' => 100,
|
749 |
+
));
|
750 |
+
$dest->insert();
|
751 |
+
} else {
|
752 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create cloaked link for %s', 'pmxi_plugin'), $url));
|
753 |
+
$_SESSION['pmxi_import']['warnings']++;
|
754 |
+
$link = NULL;
|
755 |
+
}
|
756 |
+
}
|
757 |
+
if ($link) { // cloaked link is found or created for url
|
758 |
+
$articleData['post_content'] = preg_replace('%' . preg_quote($url, '%') . '(?=([\s\'"]|$))%i', $link->getUrl(), $articleData['post_content']);
|
759 |
+
}
|
760 |
+
}
|
761 |
+
}
|
762 |
+
}
|
763 |
+
}
|
764 |
+
|
765 |
+
// insert article being imported
|
766 |
+
$pid = wp_insert_post($articleData, true);
|
767 |
+
|
768 |
+
if (is_wp_error($pid)) {
|
769 |
+
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
770 |
+
$_SESSION['pmxi_import']['errors']++;
|
771 |
+
} else {
|
772 |
+
|
773 |
+
$current_post_ids[] = $_SESSION['pmxi_import']['current_post_ids'][] = $pid;
|
774 |
+
if ($is_cron){
|
775 |
+
$tmp_array = (!empty($this->current_post_ids)) ? json_decode($this->current_post_ids, true) : array();
|
776 |
+
$tmp_array[] = $pid;
|
777 |
+
$this->set(array(
|
778 |
+
'current_post_ids' => json_encode($tmp_array)
|
779 |
+
))->save();
|
780 |
+
}
|
781 |
+
if ("manual" != $this->options['duplicate_matching'] or empty($articleData['ID'])){
|
782 |
+
// associate post with import
|
783 |
+
$postRecord->isEmpty() and $postRecord->set(array(
|
784 |
+
'post_id' => $pid,
|
785 |
+
'import_id' => $this->id,
|
786 |
+
'unique_key' => $unique_keys[$i]
|
787 |
+
))->insert();
|
788 |
+
}
|
789 |
+
|
790 |
+
// Woocommerce add-on
|
791 |
+
if ( $post_type == "product" and class_exists('PMWI_Plugin')){
|
792 |
+
|
793 |
+
$product->import($pid, $i, $this, $articleData, $xml, $is_cron);
|
794 |
+
|
795 |
+
}
|
796 |
+
|
797 |
+
if ('post' != $articleData['post_type'] and !empty($this->options['page_template'])) update_post_meta($pid, '_wp_page_template', $this->options['page_template']);
|
798 |
+
|
799 |
+
// [featured image]
|
800 |
+
if ( ! empty($uploads) and false === $uploads['error'] and !empty($featured_images[$i]) and (empty($articleData['ID']) or empty($this->options['is_keep_images']))) {
|
801 |
+
|
802 |
+
if ( $this->options['no_create_featured_image'] and has_post_thumbnail($pid) ){
|
803 |
+
// do not download files if "no create featured image" is checked
|
804 |
+
$logger and call_user_func($logger, sprintf(__('<b>Featured image SKIPPED</b>: The featured image is always exists fot the %s', 'pmxi_plugin'), $articleData['post_title']));
|
805 |
+
}
|
806 |
+
else{
|
807 |
+
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
808 |
+
|
809 |
+
if ( ! is_array($featured_images[$i]) ) $featured_images[$i] = array($featured_images[$i]);
|
810 |
+
$post_thumbnail = false;
|
811 |
+
$success_images = false;
|
812 |
+
$gallery_attachment_ids = array();
|
813 |
+
foreach ($featured_images[$i] as $featured_image)
|
814 |
+
{
|
815 |
+
$imgs = str_getcsv($featured_image, $this->options['featured_delim']);
|
816 |
+
if (!empty($imgs)) {
|
817 |
+
foreach ($imgs as $img_url) { if (empty($img_url)) continue;
|
818 |
+
$create_image = false;
|
819 |
+
if (base64_decode($img_url, true) !== false){
|
820 |
+
$img = @imagecreatefromstring(base64_decode($img_url));
|
821 |
+
if($img)
|
822 |
+
{
|
823 |
+
$image_filename = md5(time()) . '.jpg';
|
824 |
+
$image_filepath = $uploads['path'] . '/' . $image_filename;
|
825 |
+
imagejpeg($img, $image_filepath);
|
826 |
+
if( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
|
827 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $image_filepath));
|
828 |
+
$_SESSION['pmxi_import']['warnings']++;
|
829 |
+
} else {
|
830 |
+
$create_image = true;
|
831 |
+
}
|
832 |
+
}
|
833 |
+
}
|
834 |
+
else {
|
835 |
+
|
836 |
+
$img_ext = pmxi_get_remote_image_ext($img_url);
|
837 |
+
|
838 |
+
$image_filename = wp_unique_filename($uploads['path'], (($this->options['auto_rename_images'] and "" != $auto_rename_images[$i]) ? url_title($auto_rename_images[$i]) : uniqid()) . (("" != $img_ext) ? '.'.$img_ext : ''));
|
839 |
+
$image_filepath = $uploads['path'] . '/' . url_title($image_filename);
|
840 |
+
|
841 |
+
$img_url = str_replace(" ", "%20", trim($img_url));
|
842 |
+
|
843 |
+
if ( ! get_file_curl($img_url, $image_filepath) and ! @file_put_contents($image_filepath, @file_get_contents($img_url))) {
|
844 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s cannot be saved locally as %s', 'pmxi_plugin'), $img_url, $image_filepath));
|
845 |
+
$_SESSION['pmxi_import']['warnings']++;
|
846 |
+
unlink($image_filepath); // delete file since failed upload may result in empty file created
|
847 |
+
} elseif( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
|
848 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'pmxi_plugin'), $img_url));
|
849 |
+
$_SESSION['pmxi_import']['warnings']++;
|
850 |
+
} else {
|
851 |
+
$create_image = true;
|
852 |
+
}
|
853 |
+
}
|
854 |
+
|
855 |
+
if ($create_image){
|
856 |
+
$attachment = array(
|
857 |
+
'post_mime_type' => image_type_to_mime_type($image_info[2]),
|
858 |
+
'guid' => $uploads['url'] . '/' . $image_filename,
|
859 |
+
'post_title' => $image_filename,
|
860 |
+
'post_content' => '',
|
861 |
+
);
|
862 |
+
if (($image_meta = wp_read_image_metadata($image_filepath))) {
|
863 |
+
if (trim($image_meta['title']) && ! is_numeric(sanitize_title($image_meta['title'])))
|
864 |
+
$attachment['post_title'] = $image_meta['title'];
|
865 |
+
if (trim($image_meta['caption']))
|
866 |
+
$attachment['post_content'] = $image_meta['caption'];
|
867 |
+
}
|
868 |
+
$attid = wp_insert_attachment($attachment, $image_filepath, $pid);
|
869 |
+
if (is_wp_error($attid)) {
|
870 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
871 |
+
$_SESSION['pmxi_import']['warnings']++;
|
872 |
+
} else {
|
873 |
+
// you must first include the image.php file
|
874 |
+
// for the function wp_generate_attachment_metadata() to work
|
875 |
+
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
876 |
+
wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $image_filepath));
|
877 |
+
$success_images = true;
|
878 |
+
if ( ! $post_thumbnail ) {
|
879 |
+
if ( ! $this->options['no_create_featured_image'] or ! has_post_thumbnail($pid)){
|
880 |
+
set_post_thumbnail($pid, $attid);
|
881 |
+
$post_thumbnail = true;
|
882 |
+
}
|
883 |
+
else $gallery_attachment_ids[] = $attid;
|
884 |
+
}
|
885 |
+
else $gallery_attachment_ids[] = $attid;
|
886 |
+
}
|
887 |
+
}
|
888 |
+
}
|
889 |
+
}
|
890 |
+
}
|
891 |
+
// Set product gallery images
|
892 |
+
if ( $post_type == "product" and class_exists('PMWI_Plugin') and !empty($gallery_attachment_ids))
|
893 |
+
update_post_meta($pid, '_product_image_gallery', implode(',', $gallery_attachment_ids));
|
894 |
+
// Create entry as Draft if no images are downloaded successfully
|
895 |
+
if ( ! $success_images and "yes" == $this->options['create_draft'] ) wp_update_post(array('ID' => $pid, 'post_status' => 'draft'));
|
896 |
+
}
|
897 |
+
}
|
898 |
+
// [/featured image]
|
899 |
+
|
900 |
+
// [attachments]
|
901 |
+
if ( ! empty($uploads) and false === $uploads['error'] and !empty($attachments[$i])) {
|
902 |
+
|
903 |
+
// you must first include the image.php file
|
904 |
+
// for the function wp_generate_attachment_metadata() to work
|
905 |
+
require_once(ABSPATH . 'wp-admin/includes/image.php');
|
906 |
+
|
907 |
+
if ( ! is_array($attachments[$i]) ) $attachments[$i] = array($attachments[$i]);
|
908 |
+
|
909 |
+
foreach ($attachments[$i] as $attachment) { if ("" == $attachment) continue;
|
910 |
+
|
911 |
+
$atchs = str_getcsv($attachment, $this->options['atch_delim']);
|
912 |
+
|
913 |
+
if (!empty($atchs)) {
|
914 |
+
foreach ($atchs as $atch_url) { if (empty($atch_url)) continue;
|
915 |
+
|
916 |
+
$attachment_filename = wp_unique_filename($uploads['path'], basename(parse_url(trim($atch_url), PHP_URL_PATH)));
|
917 |
+
$attachment_filepath = $uploads['path'] . '/' . url_title($attachment_filename);
|
918 |
+
|
919 |
+
if ( ! file_put_contents($attachment_filepath, @file_get_contents(trim($atch_url))) and ! get_file_curl(trim($atch_url), $attachment_filepath)) {
|
920 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Attachment file %s cannot be saved locally as %s', 'pmxi_plugin'), trim($atch_url), $attachment_filepath));
|
921 |
+
$_SESSION['pmxi_import']['warnings']++;
|
922 |
+
unlink($attachment_filepath); // delete file since failed upload may result in empty file created
|
923 |
+
} elseif( ! $wp_filetype = wp_check_filetype(basename($attachment_filename), null )) {
|
924 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Can\'t detect attachment file type %s', 'pmxi_plugin'), trim($atch_url)));
|
925 |
+
$_SESSION['pmxi_import']['warnings']++;
|
926 |
+
} else {
|
927 |
+
|
928 |
+
$attachment_data = array(
|
929 |
+
'guid' => $uploads['baseurl'] . _wp_relative_upload_path( $attachment_filepath ),
|
930 |
+
'post_mime_type' => $wp_filetype['type'],
|
931 |
+
'post_title' => preg_replace('/\.[^.]+$/', '', basename($attachment_filepath)),
|
932 |
+
'post_content' => '',
|
933 |
+
'post_status' => 'inherit'
|
934 |
+
);
|
935 |
+
$attach_id = wp_insert_attachment( $attachment_data, $attachment_filepath, $pid );
|
936 |
+
|
937 |
+
if (is_wp_error($attach_id)) {
|
938 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
939 |
+
$_SESSION['pmxi_import']['warnings']++;
|
940 |
+
} else {
|
941 |
+
wp_update_attachment_metadata($attach_id, wp_generate_attachment_metadata($attach_id, $attachment_filepath));
|
942 |
+
}
|
943 |
+
}
|
944 |
+
}
|
945 |
+
}
|
946 |
+
}
|
947 |
+
}
|
948 |
+
// [/attachments]
|
949 |
+
|
950 |
+
// [custom taxonomies]
|
951 |
+
foreach ($taxonomies as $tx_name => $txes) {
|
952 |
+
|
953 |
+
$assign_taxes = array();
|
954 |
+
|
955 |
+
// create term if not exists
|
956 |
+
foreach ($txes[$i] as $key => $single_tax) {
|
957 |
+
if (is_array($single_tax)){
|
958 |
+
|
959 |
+
$parent_id = (!empty($single_tax['parent'])) ? $this->recursion_taxes($single_tax['parent'], $tx_name, $txes[$i], $key) : '';
|
960 |
+
|
961 |
+
$term = term_exists( trim(htmlspecialchars($single_tax['name'])), $tx_name, $parent_id );
|
962 |
+
|
963 |
+
if ( empty($term) and !is_wp_error($term) ){
|
964 |
+
$term_attr = array('parent'=> (!empty($parent_id)) ? $parent_id : 0);
|
965 |
+
$term = wp_insert_term(
|
966 |
+
$single_tax['name'], // the term
|
967 |
+
$tx_name, // the taxonomy
|
968 |
+
$term_attr
|
969 |
+
);
|
970 |
+
}
|
971 |
+
|
972 |
+
if ( is_wp_error($term) ){
|
973 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
|
974 |
+
$_SESSION['pmxi_import']['warnings']++;
|
975 |
+
}
|
976 |
+
elseif (!empty($term)) {
|
977 |
+
$cat_id = $term['term_id'];
|
978 |
+
if ($cat_id and $single_tax['assign'])
|
979 |
+
{
|
980 |
+
$term = get_term_by('id', $cat_id, $tx_name);
|
981 |
+
$assign_taxes[] = $term->slug;
|
982 |
+
}
|
983 |
+
}
|
984 |
+
}
|
985 |
+
}
|
986 |
+
|
987 |
+
// associate taxes with post
|
988 |
+
$term_ids = wp_set_object_terms($pid, $assign_taxes, $tx_name);
|
989 |
+
if (is_wp_error($term_ids)) {
|
990 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$term_ids->get_error_message());
|
991 |
+
$_SESSION['pmxi_import']['warnings']++;
|
992 |
+
}
|
993 |
+
}
|
994 |
+
// [/custom taxonomies]
|
995 |
+
|
996 |
+
// [categories]
|
997 |
+
if (!empty($cats[$i])){
|
998 |
+
|
999 |
+
if ( ! $this->options['is_keep_categories']) wp_set_object_terms( $pid, NULL, 'category' );
|
1000 |
+
|
1001 |
+
$assign_cats = array();
|
1002 |
+
// create categories if it's doesn't exists
|
1003 |
+
foreach ($cats[$i] as $key => $single_cat) {
|
1004 |
+
|
1005 |
+
if (is_array($single_cat)){
|
1006 |
+
|
1007 |
+
$parent_id = (!empty($single_cat['parent'])) ? $this->recursion_taxes($single_cat['parent'], 'category', $cats[$i], $key) : '';
|
1008 |
+
|
1009 |
+
$term = term_exists( trim(htmlspecialchars($single_cat['name'])), 'category', $parent_id );
|
1010 |
+
|
1011 |
+
if ( empty($term) and !is_wp_error($term) ){
|
1012 |
+
$term_attr = array('parent'=> (!empty($parent_id)) ? $parent_id : 0);
|
1013 |
+
$term = wp_insert_term(
|
1014 |
+
$single_cat['name'], // the term
|
1015 |
+
'category', // the taxonomy
|
1016 |
+
$term_attr
|
1017 |
+
);
|
1018 |
+
}
|
1019 |
+
|
1020 |
+
if ( is_wp_error($term) ){
|
1021 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: `%s`', 'pmxi_plugin'), $term->get_error_message()));
|
1022 |
+
$_SESSION['pmxi_import']['warnings']++;
|
1023 |
+
}
|
1024 |
+
elseif ( !empty($term) ) {
|
1025 |
+
$cat_id = $term['term_id'];
|
1026 |
+
if ($cat_id and $single_cat['assign'])
|
1027 |
+
{
|
1028 |
+
$term = get_term_by('id', $cat_id, 'category');
|
1029 |
+
$assign_cats[] = $term->slug;
|
1030 |
+
}
|
1031 |
+
}
|
1032 |
+
}
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
// associate categories with post
|
1036 |
+
$cats_ids = wp_set_object_terms($pid, $assign_cats, 'category');
|
1037 |
+
if (is_wp_error($cats_ids)) {
|
1038 |
+
$logger and call_user_func($logger, __('<b>WARNING</b>', 'pmxi_plugin') . ': '.$cats_ids->get_error_message());
|
1039 |
+
$_SESSION['pmxi_import']['warnings']++;
|
1040 |
+
}
|
1041 |
+
}
|
1042 |
+
// [/categories]
|
1043 |
+
|
1044 |
+
if (empty($articleData['ID'])) {
|
1045 |
+
$_SESSION['pmxi_import']['created_records']++;
|
1046 |
+
$logger and call_user_func($logger, sprintf(__('`%s` post created successfully', 'pmxi_plugin'), $articleData['post_title']));
|
1047 |
+
} else {
|
1048 |
+
$_SESSION['pmxi_import']['updated_records']++;
|
1049 |
+
$logger and call_user_func($logger, sprintf(__('`%s` post updated successfully', 'pmxi_plugin'), $articleData['post_title']));
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
do_action( 'pmxi_saved_post', $pid); // hook that was triggered immediately after post saved
|
1053 |
+
|
1054 |
+
$records_count = 0;
|
1055 |
+
|
1056 |
+
// Time Elapsed
|
1057 |
+
if ( ! $is_cron){
|
1058 |
+
|
1059 |
+
if ($this->large_import == 'No') $_SESSION['pmxi_import']['count'] = count($titles);
|
1060 |
+
|
1061 |
+
$records_count = $_SESSION['pmxi_import']['created_records'] + $_SESSION['pmxi_import']['updated_records'] + $_SESSION['pmxi_import']['skipped_records'] + $_SESSION['pmxi_import']['errors'];
|
1062 |
+
|
1063 |
+
$progress_msg = '<p class="import_process_bar"> Created ' . $_SESSION['pmxi_import']['created_records'] . ' / Updated ' . $_SESSION['pmxi_import']['updated_records'] . ' of '. $_SESSION['pmxi_import']['count'].' records.</p><span class="import_percent">' . ceil(($records_count/$_SESSION['pmxi_import']['count']) * 100) . '</span><span class="warnings_count">' . $_SESSION['pmxi_import']['warnings'] . '</span><span class="errors_count">' . $_SESSION['pmxi_import']['errors'] . '</span>';
|
1064 |
+
$logger and call_user_func($logger, $progress_msg);
|
1065 |
+
}
|
1066 |
+
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
if ($this->large_import == 'Yes' and $chunk){
|
1070 |
+
$this->set(array(
|
1071 |
+
'imported' => $this->imported + 1,
|
1072 |
+
'created' => $_SESSION['pmxi_import']['created_records'],
|
1073 |
+
'updated' => $_SESSION['pmxi_import']['updated_records']
|
1074 |
+
))->save();
|
1075 |
+
$_SESSION['pmxi_import']['chunk_number']++;
|
1076 |
+
}
|
1077 |
+
|
1078 |
+
wp_cache_flush();
|
1079 |
+
}
|
1080 |
+
if (!$is_cron and ($records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and ! empty($this->options['is_delete_missing'])) { // delete posts which are not in current import set
|
1081 |
+
$logger and call_user_func($logger, 'Removing previously imported posts which are no longer actual...');
|
1082 |
+
$postList = new PMXI_Post_List();
|
1083 |
+
|
1084 |
+
$missing_ids = array();
|
1085 |
+
foreach ($postList->getBy(array('import_id' => $this->id, 'post_id NOT IN' => $_SESSION['pmxi_import']['current_post_ids'])) as $missingPost) {
|
1086 |
+
empty($this->options['is_keep_attachments']) and wp_delete_attachments($missingPost['post_id']);
|
1087 |
+
$missing_ids[] = $missingPost['post_id'];
|
1088 |
+
|
1089 |
+
$sql = "delete a
|
1090 |
+
FROM ".PMXI_Plugin::getInstance()->getTablePrefix()."posts a
|
1091 |
+
WHERE a.id=%d";
|
1092 |
+
|
1093 |
+
$this->wpdb->query(
|
1094 |
+
$this->wpdb->prepare($sql, $missingPost['id'])
|
1095 |
+
);
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
if (!empty($missing_ids)){
|
1099 |
+
$sql = "delete a,b,c
|
1100 |
+
FROM ".$this->wpdb->posts." a
|
1101 |
+
LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
|
1102 |
+
LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
|
1103 |
+
WHERE a.ID IN (".implode(',', $missing_ids).");";
|
1104 |
+
|
1105 |
+
$this->wpdb->query(
|
1106 |
+
$this->wpdb->prepare($sql, '')
|
1107 |
+
);
|
1108 |
+
}
|
1109 |
+
|
1110 |
+
}
|
1111 |
+
|
1112 |
+
} catch (XmlImportException $e) {
|
1113 |
+
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $e->getMessage());
|
1114 |
+
$_SESSION['pmxi_import']['errors']++;
|
1115 |
+
}
|
1116 |
+
|
1117 |
+
$this->set('registered_on', date('Y-m-d H:i:s'))->save(); // specify execution is successful
|
1118 |
+
|
1119 |
+
!$is_cron and ($records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and $logger and call_user_func($logger, __('Cleaning temporary data...', 'pmxi_plugin'));
|
1120 |
+
foreach ($tmp_files as $file) { // remove all temporary files created
|
1121 |
+
unlink($file);
|
1122 |
+
}
|
1123 |
+
|
1124 |
+
if (($is_cron or $records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and $this->options['is_delete_source']) {
|
1125 |
+
$logger and call_user_func($logger, __('Deleting source XML file...', 'pmxi_plugin'));
|
1126 |
+
if ( ! @unlink($this->path)) {
|
1127 |
+
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $this->path));
|
1128 |
+
}
|
1129 |
+
}
|
1130 |
+
!$is_cron and ($records_count == $_SESSION['pmxi_import']['count'] + $_SESSION['pmxi_import']['skipped_records']) and $logger and call_user_func($logger, 'Done');
|
1131 |
+
|
1132 |
+
remove_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // return any filtering rules back if they has been disabled for import procedure
|
1133 |
+
|
1134 |
+
return $this;
|
1135 |
+
}
|
1136 |
+
|
1137 |
+
public function recursion_taxes($parent, $tx_name, $txes, $key){
|
1138 |
+
if (is_array($parent)){
|
1139 |
+
$parent['name'] = sanitize_text_field($parent['name']);
|
1140 |
+
if (empty($parent['parent'])){
|
1141 |
+
$term = term_exists( htmlspecialchars($parent['name']), $tx_name);
|
1142 |
+
if ( empty($term) and !is_wp_error($term) ){
|
1143 |
+
$term = wp_insert_term(
|
1144 |
+
$parent['name'], // the term
|
1145 |
+
$tx_name // the taxonomy
|
1146 |
+
);
|
1147 |
+
}
|
1148 |
+
return ( ! is_wp_error($term)) ? $term['term_id'] : '';
|
1149 |
+
}
|
1150 |
+
else{
|
1151 |
+
$parent_id = $this->recursion_taxes($parent['parent'], $tx_name, $txes, $key);
|
1152 |
+
$term = term_exists( htmlspecialchars($parent['name']), $tx_name, $parent_id);
|
1153 |
+
if ( empty($term) and !is_wp_error($term) ){
|
1154 |
+
$term = wp_insert_term(
|
1155 |
+
$parent, // the term
|
1156 |
+
$tx_name, // the taxonomy
|
1157 |
+
array('parent'=> (!empty($parent_id)) ? $parent_id : 0)
|
1158 |
+
);
|
1159 |
+
}
|
1160 |
+
return ( ! is_wp_error($term)) ? $term['term_id'] : '';
|
1161 |
+
}
|
1162 |
+
}
|
1163 |
+
else{
|
1164 |
+
|
1165 |
+
if ( !empty($txes[$key - 1]) and !empty($txes[$key - 1]['parent'])) {
|
1166 |
+
$parent_id = $this->recursion_taxes($txes[$key - 1]['parent'], $tx_name, $txes, $key - 1);
|
1167 |
+
|
1168 |
+
$term = term_exists( htmlspecialchars($parent), $tx_name, $parent_id);
|
1169 |
+
if ( empty($term) and !is_wp_error($term) ){
|
1170 |
+
$term = wp_insert_term(
|
1171 |
+
$parent, // the term
|
1172 |
+
$tx_name, // the taxonomy
|
1173 |
+
array('parent'=> (!empty($parent_id)) ? $parent_id : 0)
|
1174 |
+
);
|
1175 |
+
}
|
1176 |
+
return ( ! is_wp_error($term)) ? $term['term_id'] : '';
|
1177 |
+
}
|
1178 |
+
else{
|
1179 |
+
$term = term_exists( htmlspecialchars($parent), $tx_name);
|
1180 |
+
if ( empty($term) and !is_wp_error($term) ){
|
1181 |
+
$term = wp_insert_term(
|
1182 |
+
$parent, // the term
|
1183 |
+
$tx_name // the taxonomy
|
1184 |
+
);
|
1185 |
+
}
|
1186 |
+
|
1187 |
+
return ( ! is_wp_error($term)) ? $term['term_id'] : '';
|
1188 |
+
}
|
1189 |
+
}
|
1190 |
+
}
|
1191 |
+
|
1192 |
+
public function _filter_has_cap_unfiltered_html($caps)
|
1193 |
+
{
|
1194 |
+
$caps['unfiltered_html'] = true;
|
1195 |
+
return $caps;
|
1196 |
+
}
|
1197 |
+
|
1198 |
+
/**
|
1199 |
+
* Find duplicates according to settings
|
1200 |
+
*/
|
1201 |
+
public function findDuplicates($articleData, $custom_duplicate_name = '', $custom_duplicate_value = '', $duplicate_indicator = 'title')
|
1202 |
+
{
|
1203 |
+
if ('custom field' == $duplicate_indicator){
|
1204 |
+
$duplicate_ids = array();
|
1205 |
+
$args = array(
|
1206 |
+
'post_type' => $articleData['post_type'],
|
1207 |
+
'meta_query' => array(
|
1208 |
+
array(
|
1209 |
+
'key' => $custom_duplicate_name,
|
1210 |
+
'value' => $custom_duplicate_value,
|
1211 |
+
)
|
1212 |
+
)
|
1213 |
+
);
|
1214 |
+
$query = new WP_Query( $args );
|
1215 |
+
|
1216 |
+
if ( $query->have_posts() ) $duplicate_ids[] = $query->post->ID;
|
1217 |
+
|
1218 |
+
wp_reset_postdata();
|
1219 |
+
|
1220 |
+
return $duplicate_ids;
|
1221 |
+
}
|
1222 |
+
else{
|
1223 |
+
$field = 'post_' . $duplicate_indicator; // post_title or post_content
|
1224 |
+
return $this->wpdb->get_col($this->wpdb->prepare("
|
1225 |
+
SELECT ID FROM " . $this->wpdb->posts . "
|
1226 |
+
WHERE
|
1227 |
+
post_type = %s
|
1228 |
+
AND ID != %s
|
1229 |
+
AND REPLACE(REPLACE(REPLACE($field, ' ', ''), '\\t', ''), '\\n', '') = %s
|
1230 |
+
",
|
1231 |
+
$articleData['post_type'],
|
1232 |
+
isset($articleData['ID']) ? $articleData['ID'] : 0,
|
1233 |
+
preg_replace('%[ \\t\\n]%', '', $articleData[$field])
|
1234 |
+
));
|
1235 |
+
}
|
1236 |
+
}
|
1237 |
+
|
1238 |
+
/**
|
1239 |
+
* Clear associations with posts
|
1240 |
+
* @param bool[optional] $keepPosts When set to false associated wordpress posts will be deleted as well
|
1241 |
+
* @return PMXI_Import_Record
|
1242 |
+
* @chainable
|
1243 |
+
*/
|
1244 |
+
public function deletePosts($keepPosts = TRUE) {
|
1245 |
+
$post = new PMXI_Post_List();
|
1246 |
+
if ($keepPosts) {
|
1247 |
+
$this->wpdb->query($this->wpdb->prepare('DELETE FROM ' . $post->getTable() . ' WHERE import_id = %s', $this->id));
|
1248 |
+
} else {
|
1249 |
+
$ids = array();
|
1250 |
+
foreach ($post->getBy('import_id', $this->id)->convertRecords() as $p) {
|
1251 |
+
empty($this->options['is_keep_attachments']) and empty($this->options['is_keep_images']) and wp_delete_attachments($p->post_id);
|
1252 |
+
$ids[] = $p->post_id;
|
1253 |
+
//wp_delete_post($p->post_id, TRUE);
|
1254 |
+
}
|
1255 |
+
if (!empty($ids)){
|
1256 |
+
|
1257 |
+
$sql = "delete a,b,c
|
1258 |
+
FROM ".$this->wpdb->posts." a
|
1259 |
+
LEFT JOIN ".$this->wpdb->term_relationships." b ON ( a.ID = b.object_id )
|
1260 |
+
LEFT JOIN ".$this->wpdb->postmeta." c ON ( a.ID = c.post_id )
|
1261 |
+
WHERE a.ID IN (".implode(',', $ids).");";
|
1262 |
+
|
1263 |
+
$this->wpdb->query(
|
1264 |
+
$this->wpdb->prepare($sql, '')
|
1265 |
+
);
|
1266 |
+
}
|
1267 |
+
}
|
1268 |
+
return $this;
|
1269 |
+
}
|
1270 |
+
/**
|
1271 |
+
* Delete associated files
|
1272 |
+
* @return PMXI_Import_Record
|
1273 |
+
* @chainable
|
1274 |
+
*/
|
1275 |
+
public function deleteFiles() {
|
1276 |
+
$fileList = new PMXI_File_List();
|
1277 |
+
foreach($fileList->getBy('import_id', $this->id)->convertRecords() as $f) {
|
1278 |
+
$f->delete();
|
1279 |
+
}
|
1280 |
+
return $this;
|
1281 |
+
}
|
1282 |
+
|
1283 |
+
/**
|
1284 |
+
* @see parent::delete()
|
1285 |
+
* @param bool[optional] $keepPosts When set to false associated wordpress posts will be deleted as well
|
1286 |
+
*/
|
1287 |
+
public function delete($keepPosts = TRUE) {
|
1288 |
+
$this->deletePosts($keepPosts)->deleteFiles();
|
1289 |
+
|
1290 |
+
return parent::delete();
|
1291 |
+
}
|
1292 |
+
|
1293 |
+
}
|
models/model/record.php
CHANGED
@@ -1,176 +1,176 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Base class for models
|
4 |
-
*
|
5 |
-
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
-
*/
|
7 |
-
class PMXI_Model_Record extends PMXI_Model {
|
8 |
-
/**
|
9 |
-
* Initialize model
|
10 |
-
* @param array[optional] $data Array of record data to initialize object with
|
11 |
-
*/
|
12 |
-
public function __construct($data = array()) {
|
13 |
-
parent::__construct();
|
14 |
-
if (! is_array($data)) {
|
15 |
-
throw new Exception("Array expected as paramenter for " . get_class($this) . "::" . __METHOD__);
|
16 |
-
}
|
17 |
-
$data and $this->set($data);
|
18 |
-
}
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @see PMXI_Model::getBy()
|
22 |
-
* @return PMXI_Model_Record
|
23 |
-
*/
|
24 |
-
public function getBy($field = NULL, $value = NULL) {
|
25 |
-
if (is_null($field)) {
|
26 |
-
throw new Exception("Field parameter is expected at " . get_class($this) . "::" . __METHOD__);
|
27 |
-
}
|
28 |
-
$sql = "SELECT * FROM $this->table WHERE " . $this->buildWhere($field, $value);
|
29 |
-
$result = $this->wpdb->get_row($sql, ARRAY_A);
|
30 |
-
if (is_array($result)) {
|
31 |
-
foreach ($result as $k => $v) {
|
32 |
-
if (is_serialized($v)) {
|
33 |
-
$result[$k] = unserialize($v);
|
34 |
-
}
|
35 |
-
}
|
36 |
-
$this->exchangeArray($result);
|
37 |
-
} else {
|
38 |
-
$this->clear();
|
39 |
-
}
|
40 |
-
return $this;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Ger records related to current one
|
45 |
-
* @param string $model Class name of model of related records
|
46 |
-
* @param array[optoinal] $keyAssoc
|
47 |
-
* @return PMXI_Model_List
|
48 |
-
*/
|
49 |
-
public function getRelated($model, $keyAssoc = NULL) {
|
50 |
-
$related = new $model();
|
51 |
-
if ( ! empty($this->id)) {
|
52 |
-
if (is_null($keyAssoc)) {
|
53 |
-
$defaultPrefix = strtolower(preg_replace('%^' . strtoupper(PMXI_Plugin::PREFIX) . '|_Record$%', '', get_class($this)));
|
54 |
-
$keyAssoc = array();
|
55 |
-
foreach ($this->primary as $key) {
|
56 |
-
$keyAssoc = array($defaultPrefix . '_' . $key => $key);
|
57 |
-
}
|
58 |
-
}
|
59 |
-
foreach ($keyAssoc as $foreign => $local) {
|
60 |
-
$keyAssoc[$foreign] = $this->$local;
|
61 |
-
}
|
62 |
-
$related->getBy($keyAssoc);
|
63 |
-
}
|
64 |
-
return $related instanceof PMXI_Model_List ? $related->convertRecords() : $related;
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Saves currently set object data as database record
|
69 |
-
* @return PMXI_Model_Record
|
70 |
-
*/
|
71 |
-
public function insert() {
|
72 |
-
if ($this->wpdb->insert($this->table, $this->toArray(TRUE))) {
|
73 |
-
if (isset($this->auto_increment)) {
|
74 |
-
$this[$this->primary[0]] = $this->wpdb->insert_id;
|
75 |
-
}
|
76 |
-
return $this;
|
77 |
-
} else {
|
78 |
-
throw new Exception($this->wpdb->last_error);
|
79 |
-
}
|
80 |
-
}
|
81 |
-
/**
|
82 |
-
* Update record in database
|
83 |
-
* @return PMXI_Model_Record
|
84 |
-
*/
|
85 |
-
public function update() {
|
86 |
-
$record = $this->toArray(TRUE);
|
87 |
-
$this->wpdb->update($this->table, $record, array_intersect_key($record, array_flip($this->primary)));
|
88 |
-
if ($this->wpdb->last_error) {
|
89 |
-
throw new Exception($this->wpdb->last_error);
|
90 |
-
}
|
91 |
-
return $this;
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* Delete record form database
|
96 |
-
* @return PMXI_Model_Record
|
97 |
-
*/
|
98 |
-
public function delete() {
|
99 |
-
if ($this->wpdb->query("DELETE FROM $this->table WHERE " . $this->buildWhere(array_intersect_key($this->toArray(TRUE), array_flip($this->primary))))) {
|
100 |
-
return $this;
|
101 |
-
} else {
|
102 |
-
throw new Exception($this->wpdb->last_error);
|
103 |
-
}
|
104 |
-
}
|
105 |
-
/**
|
106 |
-
* Insert or Update the record
|
107 |
-
* WARNING: function doesn't check actual record presents in database, it simply tries to insert if no primary key specified and update otherwise
|
108 |
-
* @return PMXI_Model_Record
|
109 |
-
*/
|
110 |
-
public function save() {
|
111 |
-
if (array_intersect_key($this->toArray(TRUE), array_flip($this->primary))) {
|
112 |
-
$this->update();
|
113 |
-
} else {
|
114 |
-
$this->insert();
|
115 |
-
}
|
116 |
-
return $this;
|
117 |
-
}
|
118 |
-
|
119 |
-
/**
|
120 |
-
* Set record data
|
121 |
-
* When 1st parameter is an array, it expected to be an associative array of field => value pairs
|
122 |
-
* If 2 parameters are set, first one is expected to be a field name and second - it's value
|
123 |
-
*
|
124 |
-
* @param string|array $field
|
125 |
-
* @param mixed[optional] $value
|
126 |
-
* @return PMXI_Model_Record
|
127 |
-
*/
|
128 |
-
public function set($field, $value = NULL) {
|
129 |
-
if (is_array($field) and ( ! is_null($value) or 0 == count($field))) {
|
130 |
-
throw new Exception(__CLASS__ . "::set method expects either not empty associative array as the only paramter or field name and it's value as two seperate parameters.");
|
131 |
-
}
|
132 |
-
if (is_array($field)) {
|
133 |
-
$this->exchangeArray(array_merge($this->toArray(), $field));
|
134 |
-
} else {
|
135 |
-
$this[$field] = $value;
|
136 |
-
}
|
137 |
-
|
138 |
-
return $this;
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Magic method to resolved object-like request to record values in format $obj->%FIELD_NAME%
|
143 |
-
* @param string $field
|
144 |
-
* @return mixed
|
145 |
-
*/
|
146 |
-
public function __get($field) {
|
147 |
-
if ( ! $this->offsetExists($field)) {
|
148 |
-
throw new Exception("Undefined field $field.");
|
149 |
-
}
|
150 |
-
return $this[$field];
|
151 |
-
}
|
152 |
-
/**
|
153 |
-
* Magic method to assign values to record fields in format $obj->%FIELD_NAME = value
|
154 |
-
* @param string $field
|
155 |
-
* @param mixed $value
|
156 |
-
*/
|
157 |
-
public function __set($field, $value) {
|
158 |
-
$this[$field] = $value;
|
159 |
-
}
|
160 |
-
/**
|
161 |
-
* Magic method to check wether some record fields are set
|
162 |
-
* @param string $field
|
163 |
-
* @return bool
|
164 |
-
*/
|
165 |
-
public function __isset($field) {
|
166 |
-
return $this->offsetExists($field);
|
167 |
-
}
|
168 |
-
/**
|
169 |
-
* Magic method to unset record fields
|
170 |
-
* @param string $field
|
171 |
-
*/
|
172 |
-
public function __unset($field) {
|
173 |
-
$this->offsetUnset($field);
|
174 |
-
}
|
175 |
-
|
176 |
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Base class for models
|
4 |
+
*
|
5 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
6 |
+
*/
|
7 |
+
class PMXI_Model_Record extends PMXI_Model {
|
8 |
+
/**
|
9 |
+
* Initialize model
|
10 |
+
* @param array[optional] $data Array of record data to initialize object with
|
11 |
+
*/
|
12 |
+
public function __construct($data = array()) {
|
13 |
+
parent::__construct();
|
14 |
+
if (! is_array($data)) {
|
15 |
+
throw new Exception("Array expected as paramenter for " . get_class($this) . "::" . __METHOD__);
|
16 |
+
}
|
17 |
+
$data and $this->set($data);
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @see PMXI_Model::getBy()
|
22 |
+
* @return PMXI_Model_Record
|
23 |
+
*/
|
24 |
+
public function getBy($field = NULL, $value = NULL) {
|
25 |
+
if (is_null($field)) {
|
26 |
+
throw new Exception("Field parameter is expected at " . get_class($this) . "::" . __METHOD__);
|
27 |
+
}
|
28 |
+
$sql = "SELECT * FROM $this->table WHERE " . $this->buildWhere($field, $value);
|
29 |
+
$result = $this->wpdb->get_row($sql, ARRAY_A);
|
30 |
+
if (is_array($result)) {
|
31 |
+
foreach ($result as $k => $v) {
|
32 |
+
if (is_serialized($v)) {
|
33 |
+
$result[$k] = unserialize($v);
|
34 |
+
}
|
35 |
+
}
|
36 |
+
$this->exchangeArray($result);
|
37 |
+
} else {
|
38 |
+
$this->clear();
|
39 |
+
}
|
40 |
+
return $this;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Ger records related to current one
|
45 |
+
* @param string $model Class name of model of related records
|
46 |
+
* @param array[optoinal] $keyAssoc
|
47 |
+
* @return PMXI_Model_List
|
48 |
+
*/
|
49 |
+
public function getRelated($model, $keyAssoc = NULL) {
|
50 |
+
$related = new $model();
|
51 |
+
if ( ! empty($this->id)) {
|
52 |
+
if (is_null($keyAssoc)) {
|
53 |
+
$defaultPrefix = strtolower(preg_replace('%^' . strtoupper(PMXI_Plugin::PREFIX) . '|_Record$%', '', get_class($this)));
|
54 |
+
$keyAssoc = array();
|
55 |
+
foreach ($this->primary as $key) {
|
56 |
+
$keyAssoc = array($defaultPrefix . '_' . $key => $key);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
foreach ($keyAssoc as $foreign => $local) {
|
60 |
+
$keyAssoc[$foreign] = $this->$local;
|
61 |
+
}
|
62 |
+
$related->getBy($keyAssoc);
|
63 |
+
}
|
64 |
+
return $related instanceof PMXI_Model_List ? $related->convertRecords() : $related;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Saves currently set object data as database record
|
69 |
+
* @return PMXI_Model_Record
|
70 |
+
*/
|
71 |
+
public function insert() {
|
72 |
+
if ($this->wpdb->insert($this->table, $this->toArray(TRUE))) {
|
73 |
+
if (isset($this->auto_increment)) {
|
74 |
+
$this[$this->primary[0]] = $this->wpdb->insert_id;
|
75 |
+
}
|
76 |
+
return $this;
|
77 |
+
} else {
|
78 |
+
throw new Exception($this->wpdb->last_error);
|
79 |
+
}
|
80 |
+
}
|
81 |
+
/**
|
82 |
+
* Update record in database
|
83 |
+
* @return PMXI_Model_Record
|
84 |
+
*/
|
85 |
+
public function update() {
|
86 |
+
$record = $this->toArray(TRUE);
|
87 |
+
$this->wpdb->update($this->table, $record, array_intersect_key($record, array_flip($this->primary)));
|
88 |
+
if ($this->wpdb->last_error) {
|
89 |
+
throw new Exception($this->wpdb->last_error);
|
90 |
+
}
|
91 |
+
return $this;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Delete record form database
|
96 |
+
* @return PMXI_Model_Record
|
97 |
+
*/
|
98 |
+
public function delete() {
|
99 |
+
if ($this->wpdb->query("DELETE FROM $this->table WHERE " . $this->buildWhere(array_intersect_key($this->toArray(TRUE), array_flip($this->primary))))) {
|
100 |
+
return $this;
|
101 |
+
} else {
|
102 |
+
throw new Exception($this->wpdb->last_error);
|
103 |
+
}
|
104 |
+
}
|
105 |
+
/**
|
106 |
+
* Insert or Update the record
|
107 |
+
* WARNING: function doesn't check actual record presents in database, it simply tries to insert if no primary key specified and update otherwise
|
108 |
+
* @return PMXI_Model_Record
|
109 |
+
*/
|
110 |
+
public function save() {
|
111 |
+
if (array_intersect_key($this->toArray(TRUE), array_flip($this->primary))) {
|
112 |
+
$this->update();
|
113 |
+
} else {
|
114 |
+
$this->insert();
|
115 |
+
}
|
116 |
+
return $this;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Set record data
|
121 |
+
* When 1st parameter is an array, it expected to be an associative array of field => value pairs
|
122 |
+
* If 2 parameters are set, first one is expected to be a field name and second - it's value
|
123 |
+
*
|
124 |
+
* @param string|array $field
|
125 |
+
* @param mixed[optional] $value
|
126 |
+
* @return PMXI_Model_Record
|
127 |
+
*/
|
128 |
+
public function set($field, $value = NULL) {
|
129 |
+
if (is_array($field) and ( ! is_null($value) or 0 == count($field))) {
|
130 |
+
throw new Exception(__CLASS__ . "::set method expects either not empty associative array as the only paramter or field name and it's value as two seperate parameters.");
|
131 |
+
}
|
132 |
+
if (is_array($field)) {
|
133 |
+
$this->exchangeArray(array_merge($this->toArray(), $field));
|
134 |
+
} else {
|
135 |
+
$this[$field] = $value;
|
136 |
+
}
|
137 |
+
|
138 |
+
return $this;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Magic method to resolved object-like request to record values in format $obj->%FIELD_NAME%
|
143 |
+
* @param string $field
|
144 |
+
* @return mixed
|
145 |
+
*/
|
146 |
+
public function __get($field) {
|
147 |
+
if ( ! $this->offsetExists($field)) {
|
148 |
+
throw new Exception("Undefined field $field.");
|
149 |
+
}
|
150 |
+
return $this[$field];
|
151 |
+
}
|
152 |
+
/**
|
153 |
+
* Magic method to assign values to record fields in format $obj->%FIELD_NAME = value
|
154 |
+
* @param string $field
|
155 |
+
* @param mixed $value
|
156 |
+
*/
|
157 |
+
public function __set($field, $value) {
|
158 |
+
$this[$field] = $value;
|
159 |
+
}
|
160 |
+
/**
|
161 |
+
* Magic method to check wether some record fields are set
|
162 |
+
* @param string $field
|
163 |
+
* @return bool
|
164 |
+
*/
|
165 |
+
public function __isset($field) {
|
166 |
+
return $this->offsetExists($field);
|
167 |
+
}
|
168 |
+
/**
|
169 |
+
* Magic method to unset record fields
|
170 |
+
* @param string $field
|
171 |
+
*/
|
172 |
+
public function __unset($field) {
|
173 |
+
$this->offsetUnset($field);
|
174 |
+
}
|
175 |
+
|
176 |
}
|
plugin.php
CHANGED
@@ -1,606 +1,624 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Plugin Name: WP All Import
|
4 |
-
Plugin URI: http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=plugins-page&utm_campaign=free+plugin
|
5 |
-
Description: The most powerful solution for importing XML and CSV files to WordPress. Create Posts and Pages with content from any XML or CSV file. Perform scheduled updates and overwrite of existing import jobs. Free lite edition.
|
6 |
-
Version: 3.0.
|
7 |
-
Author: Soflyy
|
8 |
-
*/
|
9 |
-
/**
|
10 |
-
* Plugin root dir with forward slashes as directory separator regardless of actuall DIRECTORY_SEPARATOR value
|
11 |
-
* @var string
|
12 |
-
*/
|
13 |
-
define('PMXI_ROOT_DIR', str_replace('\\', '/', dirname(__FILE__)));
|
14 |
-
/**
|
15 |
-
* Plugin root url for referencing static content
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
define('PMXI_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
|
19 |
-
/**
|
20 |
-
* Plugin prefix for making names unique (be aware that this variable is used in conjuction with naming convention,
|
21 |
-
* i.e. in order to change it one must not only modify this constant but also rename all constants, classes and functions which
|
22 |
-
* names composed using this prefix)
|
23 |
-
* @var string
|
24 |
-
*/
|
25 |
-
define('PMXI_PREFIX', 'pmxi_');
|
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 |
-
if (
|
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 |
-
$this->options =
|
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 |
-
$controller
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
echo
|
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 |
-
if ($
|
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 |
-
if (
|
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 |
-
if ( ! is_dir($uploads['basedir'] . '/
|
424 |
-
die(sprintf(__('Uploads folder %s must be writable', 'pmxi_plugin'), $uploads['basedir'] . '/
|
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 |
-
if ('
|
474 |
-
if ('
|
475 |
-
if ('
|
476 |
-
if ('
|
477 |
-
if ('
|
478 |
-
if ('
|
479 |
-
if ('
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
if (
|
489 |
-
if (!$
|
490 |
-
if (!$
|
491 |
-
if (!$
|
492 |
-
if (!$
|
493 |
-
if (!$
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: WP All Import
|
4 |
+
Plugin URI: http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=plugins-page&utm_campaign=free+plugin
|
5 |
+
Description: The most powerful solution for importing XML and CSV files to WordPress. Create Posts and Pages with content from any XML or CSV file. Perform scheduled updates and overwrite of existing import jobs. Free lite edition.
|
6 |
+
Version: 3.0.2
|
7 |
+
Author: Soflyy
|
8 |
+
*/
|
9 |
+
/**
|
10 |
+
* Plugin root dir with forward slashes as directory separator regardless of actuall DIRECTORY_SEPARATOR value
|
11 |
+
* @var string
|
12 |
+
*/
|
13 |
+
define('PMXI_ROOT_DIR', str_replace('\\', '/', dirname(__FILE__)));
|
14 |
+
/**
|
15 |
+
* Plugin root url for referencing static content
|
16 |
+
* @var string
|
17 |
+
*/
|
18 |
+
define('PMXI_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
|
19 |
+
/**
|
20 |
+
* Plugin prefix for making names unique (be aware that this variable is used in conjuction with naming convention,
|
21 |
+
* i.e. in order to change it one must not only modify this constant but also rename all constants, classes and functions which
|
22 |
+
* names composed using this prefix)
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
define('PMXI_PREFIX', 'pmxi_');
|
26 |
+
|
27 |
+
define('PMXI_VERSION', '3.01');
|
28 |
+
|
29 |
+
define('PMXI_EDITION', 'free');
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Main plugin file, Introduces MVC pattern
|
33 |
+
*
|
34 |
+
* @singletone
|
35 |
+
* @author Pavel Kulbakin <p.kulbakin@gmail.com>
|
36 |
+
*/
|
37 |
+
final class PMXI_Plugin {
|
38 |
+
/**
|
39 |
+
* Singletone instance
|
40 |
+
* @var PMXI_Plugin
|
41 |
+
*/
|
42 |
+
protected static $instance;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Plugin options
|
46 |
+
* @var array
|
47 |
+
*/
|
48 |
+
protected $options = array();
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Plugin root dir
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
const ROOT_DIR = PMXI_ROOT_DIR;
|
55 |
+
/**
|
56 |
+
* Plugin root URL
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
const ROOT_URL = PMXI_ROOT_URL;
|
60 |
+
/**
|
61 |
+
* Prefix used for names of shortcodes, action handlers, filter functions etc.
|
62 |
+
* @var string
|
63 |
+
*/
|
64 |
+
const PREFIX = PMXI_PREFIX;
|
65 |
+
/**
|
66 |
+
* Plugin file path
|
67 |
+
* @var string
|
68 |
+
*/
|
69 |
+
const FILE = __FILE__;
|
70 |
+
/**
|
71 |
+
* Max allowed file size (bytes) to import in default mode
|
72 |
+
* @var int
|
73 |
+
*/
|
74 |
+
const LARGE_SIZE = 0; // all files will importing in large import mode
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Return singletone instance
|
78 |
+
* @return PMXI_Plugin
|
79 |
+
*/
|
80 |
+
static public function getInstance() {
|
81 |
+
if (self::$instance == NULL) {
|
82 |
+
self::$instance = new self();
|
83 |
+
}
|
84 |
+
return self::$instance;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Common logic for requestin plugin info fields
|
89 |
+
*/
|
90 |
+
public function __call($method, $args) {
|
91 |
+
if (preg_match('%^get(.+)%i', $method, $mtch)) {
|
92 |
+
$info = get_plugin_data(self::FILE);
|
93 |
+
if (isset($info[$mtch[1]])) {
|
94 |
+
return $info[$mtch[1]];
|
95 |
+
}
|
96 |
+
}
|
97 |
+
throw new Exception("Requested method " . get_class($this) . "::$method doesn't exist.");
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Get path to plagin dir relative to wordpress root
|
102 |
+
* @param bool[optional] $noForwardSlash Whether path should be returned withot forwarding slash
|
103 |
+
* @return string
|
104 |
+
*/
|
105 |
+
public function getRelativePath($noForwardSlash = false) {
|
106 |
+
$wp_root = str_replace('\\', '/', ABSPATH);
|
107 |
+
return ($noForwardSlash ? '' : '/') . str_replace($wp_root, '', self::ROOT_DIR);
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Check whether plugin is activated as network one
|
112 |
+
* @return bool
|
113 |
+
*/
|
114 |
+
public function isNetwork() {
|
115 |
+
if ( !is_multisite() )
|
116 |
+
return false;
|
117 |
+
|
118 |
+
$plugins = get_site_option('active_sitewide_plugins');
|
119 |
+
if (isset($plugins[plugin_basename(self::FILE)]))
|
120 |
+
return true;
|
121 |
+
|
122 |
+
return false;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Check whether permalinks is enabled
|
127 |
+
* @return bool
|
128 |
+
*/
|
129 |
+
public function isPermalinks() {
|
130 |
+
global $wp_rewrite;
|
131 |
+
|
132 |
+
return $wp_rewrite->using_permalinks();
|
133 |
+
}
|
134 |
+
|
135 |
+
/**
|
136 |
+
* Return prefix for plugin database tables
|
137 |
+
* @return string
|
138 |
+
*/
|
139 |
+
public function getTablePrefix() {
|
140 |
+
global $wpdb;
|
141 |
+
return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix) . self::PREFIX;
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* Return prefix for wordpress database tables
|
146 |
+
* @return string
|
147 |
+
*/
|
148 |
+
public function getWPPrefix() {
|
149 |
+
global $wpdb;
|
150 |
+
return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix);
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Class constructor containing dispatching logic
|
155 |
+
* @param string $rootDir Plugin root dir
|
156 |
+
* @param string $pluginFilePath Plugin main file
|
157 |
+
*/
|
158 |
+
protected function __construct() {
|
159 |
+
|
160 |
+
// create/update required database tables
|
161 |
+
|
162 |
+
// regirster autoloading method
|
163 |
+
if (function_exists('__autoload') and ! in_array('__autoload', spl_autoload_functions())) { // make sure old way of autoloading classes is not broken
|
164 |
+
spl_autoload_register('__autoload');
|
165 |
+
}
|
166 |
+
spl_autoload_register(array($this, '__autoload'));
|
167 |
+
|
168 |
+
// register helpers
|
169 |
+
if (is_dir(self::ROOT_DIR . '/helpers')) foreach (PMXI_Helper::safe_glob(self::ROOT_DIR . '/helpers/*.php', PMXI_Helper::GLOB_RECURSE | PMXI_Helper::GLOB_PATH) as $filePath) {
|
170 |
+
require_once $filePath;
|
171 |
+
}
|
172 |
+
|
173 |
+
// create history folder
|
174 |
+
$uploads = wp_upload_dir();
|
175 |
+
if (!is_dir($uploads['basedir'] . '/wpallimport_history')) wp_mkdir_p($uploads['basedir'] . '/wpallimport_history');
|
176 |
+
// create logs folder
|
177 |
+
if (!is_dir($uploads['basedir'] . '/wpallimport_logs')) wp_mkdir_p($uploads['basedir'] . '/wpallimport_logs');
|
178 |
+
|
179 |
+
// init plugin options
|
180 |
+
$option_name = get_class($this) . '_Options';
|
181 |
+
$options_default = PMXI_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
|
182 |
+
$this->options = array_intersect_key(get_option($option_name, array()), $options_default) + $options_default;
|
183 |
+
$this->options = array_intersect_key($options_default, array_flip(array('info_api_url'))) + $this->options; // make sure hidden options apply upon plugin reactivation
|
184 |
+
if ('' == $this->options['cron_job_key']) $this->options['cron_job_key'] = url_title(rand_char(12));
|
185 |
+
|
186 |
+
update_option($option_name, $this->options);
|
187 |
+
$this->options = get_option(get_class($this) . '_Options');
|
188 |
+
|
189 |
+
register_activation_hook(self::FILE, array($this, '__activation'));
|
190 |
+
|
191 |
+
// register action handlers
|
192 |
+
if (is_dir(self::ROOT_DIR . '/actions')) if (is_dir(self::ROOT_DIR . '/actions')) foreach (PMXI_Helper::safe_glob(self::ROOT_DIR . '/actions/*.php', PMXI_Helper::GLOB_RECURSE | PMXI_Helper::GLOB_PATH) as $filePath) {
|
193 |
+
require_once $filePath;
|
194 |
+
$function = $actionName = basename($filePath, '.php');
|
195 |
+
if (preg_match('%^(.+?)[_-](\d+)$%', $actionName, $m)) {
|
196 |
+
$actionName = $m[1];
|
197 |
+
$priority = intval($m[2]);
|
198 |
+
} else {
|
199 |
+
$priority = 10;
|
200 |
+
}
|
201 |
+
add_action($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
|
202 |
+
}
|
203 |
+
|
204 |
+
// register filter handlers
|
205 |
+
if (is_dir(self::ROOT_DIR . '/filters')) foreach (PMXI_Helper::safe_glob(self::ROOT_DIR . '/filters/*.php', PMXI_Helper::GLOB_RECURSE | PMXI_Helper::GLOB_PATH) as $filePath) {
|
206 |
+
require_once $filePath;
|
207 |
+
$function = $actionName = basename($filePath, '.php');
|
208 |
+
if (preg_match('%^(.+?)[_-](\d+)$%', $actionName, $m)) {
|
209 |
+
$actionName = $m[1];
|
210 |
+
$priority = intval($m[2]);
|
211 |
+
} else {
|
212 |
+
$priority = 10;
|
213 |
+
}
|
214 |
+
add_filter($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
|
215 |
+
}
|
216 |
+
|
217 |
+
// register shortcodes handlers
|
218 |
+
if (is_dir(self::ROOT_DIR . '/shortcodes')) foreach (PMXI_Helper::safe_glob(self::ROOT_DIR . '/shortcodes/*.php', PMXI_Helper::GLOB_RECURSE | PMXI_Helper::GLOB_PATH) as $filePath) {
|
219 |
+
$tag = strtolower(str_replace('/', '_', preg_replace('%^' . preg_quote(self::ROOT_DIR . '/shortcodes/', '%') . '|\.php$%', '', $filePath)));
|
220 |
+
add_shortcode($tag, array($this, 'shortcodeDispatcher'));
|
221 |
+
}
|
222 |
+
|
223 |
+
// register admin page pre-dispatcher
|
224 |
+
add_action('admin_init', array($this, '__adminInit'));
|
225 |
+
|
226 |
+
$this->__add_feed_type_fix(); // feature to version 2.22
|
227 |
+
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* pre-dispatching logic for admin page controllers
|
232 |
+
*/
|
233 |
+
public function __adminInit() {
|
234 |
+
$input = new PMXI_Input();
|
235 |
+
$page = strtolower($input->getpost('page', ''));
|
236 |
+
if (preg_match('%^' . preg_quote(str_replace('_', '-', self::PREFIX), '%') . '([\w-]+)$%', $page)) {
|
237 |
+
$this->adminDispatcher($page, strtolower($input->getpost('action', 'index')));
|
238 |
+
}
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Dispatch shorttag: create corresponding controller instance and call its index method
|
243 |
+
* @param array $args Shortcode tag attributes
|
244 |
+
* @param string $content Shortcode tag content
|
245 |
+
* @param string $tag Shortcode tag name which is being dispatched
|
246 |
+
* @return string
|
247 |
+
*/
|
248 |
+
public function shortcodeDispatcher($args, $content, $tag) {
|
249 |
+
|
250 |
+
$controllerName = self::PREFIX . preg_replace('%(^|_).%e', 'strtoupper("$0")', $tag); // capitalize first letters of class name parts and add prefix
|
251 |
+
$controller = new $controllerName();
|
252 |
+
if ( ! $controller instanceof PMXI_Controller) {
|
253 |
+
throw new Exception("Shortcode `$tag` matches to a wrong controller type.");
|
254 |
+
}
|
255 |
+
ob_start();
|
256 |
+
$controller->index($args, $content);
|
257 |
+
return ob_get_clean();
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* Dispatch admin page: call corresponding controller based on get parameter `page`
|
262 |
+
* The method is called twice: 1st time as handler `parse_header` action and then as admin menu item handler
|
263 |
+
* @param string[optional] $page When $page set to empty string ealier buffered content is outputted, otherwise controller is called based on $page value
|
264 |
+
*/
|
265 |
+
public function adminDispatcher($page = '', $action = 'index') {
|
266 |
+
static $buffer = NULL;
|
267 |
+
static $buffer_callback = NULL;
|
268 |
+
if ('' === $page) {
|
269 |
+
if ( ! is_null($buffer)) {
|
270 |
+
echo '<div class="wrap">';
|
271 |
+
echo $buffer;
|
272 |
+
do_action('pmxi_action_after');
|
273 |
+
echo '</div>';
|
274 |
+
} elseif ( ! is_null($buffer_callback)) {
|
275 |
+
echo '<div class="wrap">';
|
276 |
+
call_user_func($buffer_callback);
|
277 |
+
do_action('pmxi_action_after');
|
278 |
+
echo '</div>';
|
279 |
+
} else {
|
280 |
+
throw new Exception('There is no previousely buffered content to display.');
|
281 |
+
}
|
282 |
+
} else {
|
283 |
+
$controllerName = preg_replace('%(^' . preg_quote(self::PREFIX, '%') . '|_).%e', 'strtoupper("$0")', str_replace('-', '_', $page)); // capitalize prefix and first letters of class name parts
|
284 |
+
$actionName = str_replace('-', '_', $action);
|
285 |
+
if (method_exists($controllerName, $actionName)) {
|
286 |
+
$this->_admin_current_screen = (object)array(
|
287 |
+
'id' => $controllerName,
|
288 |
+
'base' => $controllerName,
|
289 |
+
'action' => $actionName,
|
290 |
+
'is_ajax' => isset($_SERVER['HTTP_X_REQUESTED_WITH']) and strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest',
|
291 |
+
'is_network' => is_network_admin(),
|
292 |
+
'is_user' => is_user_admin(),
|
293 |
+
);
|
294 |
+
add_filter('current_screen', array($this, 'getAdminCurrentScreen'));
|
295 |
+
add_filter('admin_body_class', create_function('', 'return "' . PMXI_Plugin::PREFIX . 'plugin";'));
|
296 |
+
|
297 |
+
$controller = new $controllerName();
|
298 |
+
if ( ! $controller instanceof PMXI_Controller_Admin) {
|
299 |
+
throw new Exception("Administration page `$page` matches to a wrong controller type.");
|
300 |
+
}
|
301 |
+
|
302 |
+
if ($this->_admin_current_screen->is_ajax) { // ajax request
|
303 |
+
$controller->$action();
|
304 |
+
do_action('pmxi_action_after');
|
305 |
+
die(); // stop processing since we want to output only what controller is randered, nothing in addition
|
306 |
+
} elseif ( ! $controller->isInline) {
|
307 |
+
ob_start();
|
308 |
+
$controller->$action();
|
309 |
+
$buffer = ob_get_clean();
|
310 |
+
} else {
|
311 |
+
$buffer_callback = array($controller, $action);
|
312 |
+
}
|
313 |
+
} else { // redirect to dashboard if requested page and/or action don't exist
|
314 |
+
wp_redirect(admin_url()); die();
|
315 |
+
}
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
protected $_admin_current_screen = NULL;
|
320 |
+
public function getAdminCurrentScreen()
|
321 |
+
{
|
322 |
+
return $this->_admin_current_screen;
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Autoloader
|
327 |
+
* It's assumed class name consists of prefix folloed by its name which in turn corresponds to location of source file
|
328 |
+
* if `_` symbols replaced by directory path separator. File name consists of prefix folloed by last part in class name (i.e.
|
329 |
+
* symbols after last `_` in class name)
|
330 |
+
* When class has prefix it's source is looked in `models`, `controllers`, `shortcodes` folders, otherwise it looked in `core` or `library` folder
|
331 |
+
*
|
332 |
+
* @param string $className
|
333 |
+
* @return bool
|
334 |
+
*/
|
335 |
+
public function __autoload($className) {
|
336 |
+
$is_prefix = false;
|
337 |
+
$filePath = str_replace('_', '/', preg_replace('%^' . preg_quote(self::PREFIX, '%') . '%', '', strtolower($className), 1, $is_prefix)) . '.php';
|
338 |
+
if ( ! $is_prefix) { // also check file with original letter case
|
339 |
+
$filePathAlt = $className . '.php';
|
340 |
+
}
|
341 |
+
foreach ($is_prefix ? array('models', 'controllers', 'shortcodes', 'classes') : array('libraries') as $subdir) {
|
342 |
+
$path = self::ROOT_DIR . '/' . $subdir . '/' . $filePath;
|
343 |
+
if (is_file($path)) {
|
344 |
+
require $path;
|
345 |
+
return TRUE;
|
346 |
+
}
|
347 |
+
if ( ! $is_prefix) {
|
348 |
+
$pathAlt = self::ROOT_DIR . '/' . $subdir . '/' . $filePathAlt;
|
349 |
+
if (is_file($pathAlt)) {
|
350 |
+
require $pathAlt;
|
351 |
+
return TRUE;
|
352 |
+
}
|
353 |
+
}
|
354 |
+
}
|
355 |
+
|
356 |
+
return FALSE;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Get plugin option
|
361 |
+
* @param string[optional] $option Parameter to return, all array of options is returned if not set
|
362 |
+
* @return mixed
|
363 |
+
*/
|
364 |
+
public function getOption($option = NULL) {
|
365 |
+
if (is_null($option)) {
|
366 |
+
return $this->options;
|
367 |
+
} else if (isset($this->options[$option])) {
|
368 |
+
return $this->options[$option];
|
369 |
+
} else {
|
370 |
+
throw new Exception("Specified option is not defined for the plugin");
|
371 |
+
}
|
372 |
+
}
|
373 |
+
/**
|
374 |
+
* Update plugin option value
|
375 |
+
* @param string $option Parameter name or array of name => value pairs
|
376 |
+
* @param mixed[optional] $value New value for the option, if not set than 1st parameter is supposed to be array of name => value pairs
|
377 |
+
* @return array
|
378 |
+
*/
|
379 |
+
public function updateOption($option, $value = NULL) {
|
380 |
+
is_null($value) or $option = array($option => $value);
|
381 |
+
if (array_diff_key($option, $this->options)) {
|
382 |
+
throw new Exception("Specified option is not defined for the plugin");
|
383 |
+
}
|
384 |
+
$this->options = $option + $this->options;
|
385 |
+
update_option(get_class($this) . '_Options', $this->options);
|
386 |
+
|
387 |
+
return $this->options;
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Plugin activation logic
|
392 |
+
*/
|
393 |
+
public function __activation() {
|
394 |
+
// uncaught exception doesn't prevent plugin from being activated, therefore replace it with fatal error so it does
|
395 |
+
set_exception_handler(create_function('$e', 'trigger_error($e->getMessage(), E_USER_ERROR);'));
|
396 |
+
|
397 |
+
// create plugin options
|
398 |
+
$option_name = get_class($this) . '_Options';
|
399 |
+
$options_default = PMXI_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
|
400 |
+
update_option($option_name, $options_default);
|
401 |
+
|
402 |
+
// create/update required database tables
|
403 |
+
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
404 |
+
require self::ROOT_DIR . '/schema.php';
|
405 |
+
dbDelta($plugin_queries);
|
406 |
+
|
407 |
+
$this->__ver_1_04_transition_fix();
|
408 |
+
|
409 |
+
// sync data between plugin tables and wordpress (mostly for the case when plugin is reactivated)
|
410 |
+
global $wpdb;
|
411 |
+
$post = new PMXI_Post_Record();
|
412 |
+
$wpdb->query('DELETE FROM ' . $post->getTable() . ' WHERE post_id NOT IN (SELECT ID FROM ' . $wpdb->posts . ')');
|
413 |
+
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Method perfoms transition from version when file uploads has been stored in dabase to the solution when it stored on disk
|
418 |
+
* NOTE: the function can be removed when plugin version progress and it's sure matter nobody has ver 1.03
|
419 |
+
*/
|
420 |
+
public function __ver_1_04_transition_fix() {
|
421 |
+
$uploads = wp_upload_dir();
|
422 |
+
|
423 |
+
if ( ! is_dir($uploads['basedir'] . '/wpallimport_history') or ! is_writable($uploads['basedir'] . '/wpallimport_history')) {
|
424 |
+
die(sprintf(__('Uploads folder %s must be writable', 'pmxi_plugin'), $uploads['basedir'] . '/wpallimport_history'));
|
425 |
+
}
|
426 |
+
|
427 |
+
if ( ! is_dir($uploads['basedir'] . '/wpallimport_logs') or ! is_writable($uploads['basedir'] . '/wpallimport_logs')) {
|
428 |
+
die(sprintf(__('Uploads folder %s must be writable', 'pmxi_plugin'), $uploads['basedir'] . '/wpallimport_logs'));
|
429 |
+
}
|
430 |
+
|
431 |
+
$table = $table = $this->getTablePrefix() . 'files';
|
432 |
+
global $wpdb;
|
433 |
+
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
|
434 |
+
// For every field in the table
|
435 |
+
foreach ($tablefields as $tablefield) {
|
436 |
+
if ('contents' == $tablefield->Field) {
|
437 |
+
$list = new PMXI_File_List();
|
438 |
+
for ($i = 1; $list->getBy(NULL, 'id', $i, 1)->count(); $i++) {
|
439 |
+
foreach ($list->convertRecords() as $file) {
|
440 |
+
$file->save(); // resave file for file to be stored in uploads folder
|
441 |
+
}
|
442 |
+
}
|
443 |
+
|
444 |
+
$wpdb->query("ALTER TABLE {$table} DROP " . $tablefield->Field);
|
445 |
+
break;
|
446 |
+
}
|
447 |
+
}
|
448 |
+
}
|
449 |
+
|
450 |
+
public function __add_feed_type_fix(){
|
451 |
+
|
452 |
+
$table = $this->getTablePrefix() . 'imports';
|
453 |
+
global $wpdb;
|
454 |
+
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
|
455 |
+
$large_import = false;
|
456 |
+
$root_element = false;
|
457 |
+
$processing = false;
|
458 |
+
$triggered = false;
|
459 |
+
$queue_chunk_number = false;
|
460 |
+
$current_post_ids = false;
|
461 |
+
$first_import = false;
|
462 |
+
$count = false;
|
463 |
+
$friendly_name = false;
|
464 |
+
$imported = false;
|
465 |
+
$created = false;
|
466 |
+
$updated = false;
|
467 |
+
$skipped = false;
|
468 |
+
$fix_characters = false;
|
469 |
+
$feed_type = false;
|
470 |
+
|
471 |
+
// Check if field exists
|
472 |
+
foreach ($tablefields as $tablefield) {
|
473 |
+
if ('feed_type' == $tablefield->Field) $feed_type = true;
|
474 |
+
if ('large_import' == $tablefield->Field) $large_import = true;
|
475 |
+
if ('root_element' == $tablefield->Field) $root_element = true;
|
476 |
+
if ('processing' == $tablefield->Field) $processing = true;
|
477 |
+
if ('triggered' == $tablefield->Field) $triggered = true;
|
478 |
+
if ('current_post_ids' == $tablefield->Field) $current_post_ids = true;
|
479 |
+
if ('queue_chunk_number' == $tablefield->Field) $queue_chunk_number = true;
|
480 |
+
if ('first_import' == $tablefield->Field) $first_import = true;
|
481 |
+
if ('count' == $tablefield->Field) $count = true;
|
482 |
+
if ('friendly_name' == $tablefield->Field) $friendly_name = true;
|
483 |
+
if ('imported' == $tablefield->Field) $imported = true;
|
484 |
+
if ('created' == $tablefield->Field) $created = true;
|
485 |
+
if ('updated' == $tablefield->Field) $updated = true;
|
486 |
+
if ('skipped' == $tablefield->Field) $skipped = true;
|
487 |
+
}
|
488 |
+
if ($feed_type) $wpdb->query("ALTER TABLE {$table} CHANGE `feed_type` `feed_type` ENUM( 'xml', 'csv', 'zip', 'gz', '' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';");
|
489 |
+
if (!$feed_type) $wpdb->query("ALTER TABLE {$table} ADD `feed_type` ENUM( 'xml','csv','zip','gz','' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT '';");
|
490 |
+
if (!$large_import) $wpdb->query("ALTER TABLE {$table} ADD `large_import` ENUM( 'Yes', 'No' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'No';");
|
491 |
+
if (!$root_element) $wpdb->query("ALTER TABLE {$table} ADD `root_element` VARCHAR(255) NOT NULL DEFAULT '';");
|
492 |
+
if (!$processing) $wpdb->query("ALTER TABLE {$table} ADD `processing` BOOL NOT NULL DEFAULT 0;");
|
493 |
+
if (!$triggered) $wpdb->query("ALTER TABLE {$table} ADD `triggered` BOOL NOT NULL DEFAULT 0;");
|
494 |
+
if (!$queue_chunk_number) $wpdb->query("ALTER TABLE {$table} ADD `queue_chunk_number` BIGINT(20) NOT NULL DEFAULT 0;");
|
495 |
+
if (!$current_post_ids) $wpdb->query("ALTER TABLE {$table} ADD `current_post_ids` TEXT;");
|
496 |
+
if (!$first_import) $wpdb->query("ALTER TABLE {$table} ADD `first_import` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;");
|
497 |
+
if (!$count) $wpdb->query("ALTER TABLE {$table} ADD `count` BIGINT(20) NOT NULL DEFAULT 0;");
|
498 |
+
if (!$imported) $wpdb->query("ALTER TABLE {$table} ADD `imported` BIGINT(20) NOT NULL DEFAULT 0;");
|
499 |
+
if (!$created) $wpdb->query("ALTER TABLE {$table} ADD `created` BIGINT(20) NOT NULL DEFAULT 0;");
|
500 |
+
if (!$updated) $wpdb->query("ALTER TABLE {$table} ADD `updated` BIGINT(20) NOT NULL DEFAULT 0;");
|
501 |
+
if (!$skipped) $wpdb->query("ALTER TABLE {$table} ADD `skipped` BIGINT(20) NOT NULL DEFAULT 0;");
|
502 |
+
if (!$friendly_name) $wpdb->query("ALTER TABLE {$table} ADD `friendly_name` VARCHAR(255) NOT NULL DEFAULT '';");
|
503 |
+
|
504 |
+
$table = $this->getTablePrefix() . 'templates';
|
505 |
+
global $wpdb;
|
506 |
+
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
|
507 |
+
$is_leave_html = false;
|
508 |
+
// Check if field exists
|
509 |
+
foreach ($tablefields as $tablefield) {
|
510 |
+
if ('is_leave_html' == $tablefield->Field) $is_leave_html = true;
|
511 |
+
if ('fix_characters' == $tablefield->Field) $fix_characters = true;
|
512 |
+
}
|
513 |
+
if (!$is_leave_html) $wpdb->query("ALTER TABLE {$table} ADD `is_leave_html` TINYINT( 1 ) NOT NULL DEFAULT 0;");
|
514 |
+
if (!$fix_characters) $wpdb->query("ALTER TABLE {$table} ADD `fix_characters` TINYINT( 1 ) NOT NULL DEFAULT 0;");
|
515 |
+
|
516 |
+
$table = $this->getTablePrefix() . 'posts';
|
517 |
+
global $wpdb;
|
518 |
+
$tablefields = $wpdb->get_results("DESCRIBE {$table};");
|
519 |
+
$product_key = false;
|
520 |
+
// Check if field exists
|
521 |
+
foreach ($tablefields as $tablefield) {
|
522 |
+
if ('product_key' == $tablefield->Field) $product_key = true;
|
523 |
+
}
|
524 |
+
if (!$product_key) $wpdb->query("ALTER TABLE {$table} ADD `product_key` TEXT NOT NULL DEFAULT '';");
|
525 |
+
|
526 |
+
}
|
527 |
+
|
528 |
+
/**
|
529 |
+
* Method returns default import options, main utility of the method is to avoid warnings when new
|
530 |
+
* option is introduced but already registered imports don't have it
|
531 |
+
*/
|
532 |
+
public static function get_default_import_options() {
|
533 |
+
return array(
|
534 |
+
'type' => 'post',
|
535 |
+
'custom_type' => '',
|
536 |
+
'categories' => '',
|
537 |
+
'tags' => '',
|
538 |
+
'tags_delim' => ',',
|
539 |
+
'categories_delim' => ',',
|
540 |
+
'categories_auto_nested' => 0,
|
541 |
+
'featured_delim' => ',',
|
542 |
+
'atch_delim' => ',',
|
543 |
+
'post_taxonomies' => array(),
|
544 |
+
'parent' => '',
|
545 |
+
'order' => '0',
|
546 |
+
'status' => 'publish',
|
547 |
+
'page_template' => 'default',
|
548 |
+
'page_taxonomies' => array(),
|
549 |
+
'date_type' => 'specific',
|
550 |
+
'date' => 'now',
|
551 |
+
'date_start' => 'now',
|
552 |
+
'date_end' => 'now',
|
553 |
+
'custom_name' => array(),
|
554 |
+
'custom_value' => array(),
|
555 |
+
'comment_status' => 'open',
|
556 |
+
'ping_status' => 'open',
|
557 |
+
'create_draft' => 'no',
|
558 |
+
'author' => '',
|
559 |
+
'featured_image' => '',
|
560 |
+
'attachments' => '',
|
561 |
+
'is_import_specified' => 0,
|
562 |
+
'import_specified' => '',
|
563 |
+
'is_delete_source' => 0,
|
564 |
+
'is_cloak' => 0,
|
565 |
+
'unique_key' => '',
|
566 |
+
'feed_type' => 'auto',
|
567 |
+
|
568 |
+
'is_delete_missing' => 0,
|
569 |
+
'is_keep_former_posts' => 'no',
|
570 |
+
'is_keep_status' => 0,
|
571 |
+
'is_keep_content' => 0,
|
572 |
+
'is_keep_title' => 0,
|
573 |
+
'is_keep_excerpt' => 0,
|
574 |
+
'is_keep_categories' => 0,
|
575 |
+
'is_keep_attachments' => 0,
|
576 |
+
'is_keep_images' => 0,
|
577 |
+
'is_duplicates' => 0,
|
578 |
+
'is_keep_dates' => 0,
|
579 |
+
'is_keep_menu_order' => 0,
|
580 |
+
'records_per_request' => 10,
|
581 |
+
'not_create_records' => 0,
|
582 |
+
'no_create_featured_image' => 0,
|
583 |
+
|
584 |
+
'duplicate_indicator' => 'title',
|
585 |
+
'duplicate_action' => 'keep',
|
586 |
+
'is_update_previous' => 0,
|
587 |
+
'is_scheduled' => '',
|
588 |
+
'scheduled_period' => '',
|
589 |
+
'post_excerpt' => '',
|
590 |
+
'post_slug' => '',
|
591 |
+
'keep_custom_fields' => 0,
|
592 |
+
'keep_custom_fields_specific' => '',
|
593 |
+
'friendly_name' => '',
|
594 |
+
'custom_duplicate_name' => '',
|
595 |
+
'custom_duplicate_value' => '',
|
596 |
+
'duplicate_matching' => 'auto',
|
597 |
+
'create_chunks' => 0,
|
598 |
+
);
|
599 |
+
}
|
600 |
+
|
601 |
+
/*
|
602 |
+
* Convert csv to xml using yahoo API
|
603 |
+
*/
|
604 |
+
public static function csv_to_xml($csv_url){
|
605 |
+
|
606 |
+
include_once(self::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
607 |
+
|
608 |
+
$csv = new PMXI_CsvParser($csv_url);
|
609 |
+
|
610 |
+
$wp_uploads = wp_upload_dir();
|
611 |
+
$tmpname = wp_unique_filename($wp_uploads['path'], str_replace("csv", "xml", basename($csv_url)));
|
612 |
+
$xml_file = $wp_uploads['path'] .'/'. $tmpname;
|
613 |
+
file_put_contents($xml_file, $csv->toXML());
|
614 |
+
return $xml_file;
|
615 |
+
|
616 |
+
}
|
617 |
+
|
618 |
+
public static function is_ajax(){
|
619 |
+
return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') ? true : false ;
|
620 |
+
}
|
621 |
+
|
622 |
+
}
|
623 |
+
|
624 |
+
PMXI_Plugin::getInstance();
|
readme.txt
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
-
===
|
2 |
Contributors: soflyy
|
3 |
Tags: wordpress, xml, csv, datafeed, import
|
4 |
Requires at least: 3.5
|
5 |
-
Tested up to: 3.5.
|
6 |
-
Stable tag: 3.0.
|
7 |
|
8 |
WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
|
9 |
|
@@ -20,7 +20,7 @@ WP All Import can be used for everything from building a store with an affiliate
|
|
20 |
= WP All Import Professional Edition =
|
21 |
[youtube http://www.youtube.com/watch?v=3LfbN7uWcTA /]
|
22 |
|
23 |
-
*WP All Import Pro* is a $
|
24 |
|
25 |
* Import to Custom Post Types - commonly used to import to Automotiv, OpenHouse, Listings, and WooCommerce, as well as any other theme or plugin that makes use of Custom Post Types.
|
26 |
|
@@ -38,13 +38,21 @@ WP All Import can be used for everything from building a store with an affiliate
|
|
38 |
|
39 |
* Pro version customers also get access to our customer portal with documentation and tutorials, and e-mail technical support.
|
40 |
|
41 |
-
|
42 |
[Upgrade to the professional edition of WP All Import.](http://www.wpallimport.com/upgrade-to-pro)
|
|
|
|
|
43 |
|
44 |
== Premium Support ==
|
45 |
Upgrade to the professional edition of WP All Import for premium support.
|
46 |
|
47 |
E-mail: support@soflyy.com
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
== Installation ==
|
50 |
|
@@ -57,7 +65,7 @@ Either: -
|
|
57 |
== Frequently Asked Questions ==
|
58 |
|
59 |
*What Size Files Can WP All Import Handle?*
|
60 |
-
With the release of WP All Import version 3, WP All Import can now handle files of any size and any number of records, as long as the web hosting provider can too. Typically, WP All Import can comfortably import files of
|
61 |
|
62 |
*What are the benefits of the $99 professional version?*
|
63 |
Support for Custom Post Types, Custom Taxonomies, Custom Fields, cron jobs/recurring imports, download and importing of images to the post media gallery, and URL/FTP server uploads.
|
@@ -76,6 +84,9 @@ Does it work with special character encoding like Hebrew, Arabic, Chinese, etc?
|
|
76 |
4. Manage imports.
|
77 |
|
78 |
== Changelog ==
|
|
|
|
|
|
|
79 |
|
80 |
= 3.0 =
|
81 |
* Free edition of 3.0 pro release
|
1 |
+
=== Import any XML or CSV File to WordPress ===
|
2 |
Contributors: soflyy
|
3 |
Tags: wordpress, xml, csv, datafeed, import
|
4 |
Requires at least: 3.5
|
5 |
+
Tested up to: 3.5.2
|
6 |
+
Stable tag: 3.0.2
|
7 |
|
8 |
WP All Import is an extremely powerful plugin that makes it easy to import any XML or CSV file to WordPress.
|
9 |
|
20 |
= WP All Import Professional Edition =
|
21 |
[youtube http://www.youtube.com/watch?v=3LfbN7uWcTA /]
|
22 |
|
23 |
+
*WP All Import Pro* is a $99 upgrade that adds the following features to the free version of WP All Import:
|
24 |
|
25 |
* Import to Custom Post Types - commonly used to import to Automotiv, OpenHouse, Listings, and WooCommerce, as well as any other theme or plugin that makes use of Custom Post Types.
|
26 |
|
38 |
|
39 |
* Pro version customers also get access to our customer portal with documentation and tutorials, and e-mail technical support.
|
40 |
|
|
|
41 |
[Upgrade to the professional edition of WP All Import.](http://www.wpallimport.com/upgrade-to-pro)
|
42 |
+
|
43 |
+
Need to [import XML and CSV to WooCommerce?](http://wordpress.org/plugins/woocommerce-xml-csv-product-import/) Check out our WooCommerce add-on.
|
44 |
|
45 |
== Premium Support ==
|
46 |
Upgrade to the professional edition of WP All Import for premium support.
|
47 |
|
48 |
E-mail: support@soflyy.com
|
49 |
+
|
50 |
+
== Import To WooCommerce ==
|
51 |
+
|
52 |
+
Need to [import XML and CSV to WooCommerce?](http://wordpress.org/plugins/woocommerce-xml-csv-product-import/) Check out our WooCommerce add-on.
|
53 |
+
|
54 |
+
[WooCommerce XML & CSV Import Pro Version](http://www.wpallimport.com/woocommerce-product-import)
|
55 |
+
|
56 |
|
57 |
== Installation ==
|
58 |
|
65 |
== Frequently Asked Questions ==
|
66 |
|
67 |
*What Size Files Can WP All Import Handle?*
|
68 |
+
With the release of WP All Import version 3, WP All Import can now handle files of any size and any number of records, as long as the web hosting provider can too. Typically, WP All Import can comfortably import files of 200Mb and larger in most shared hosting environments (HostGator, etc). Please see this page for more details: http://www.wpallimport.com/how-big
|
69 |
|
70 |
*What are the benefits of the $99 professional version?*
|
71 |
Support for Custom Post Types, Custom Taxonomies, Custom Fields, cron jobs/recurring imports, download and importing of images to the post media gallery, and URL/FTP server uploads.
|
84 |
4. Manage imports.
|
85 |
|
86 |
== Changelog ==
|
87 |
+
|
88 |
+
= 3.0.2 =
|
89 |
+
* Free edition of 3.0 pro release with added support for the WooCommerce add-on
|
90 |
|
91 |
= 3.0 =
|
92 |
* Free edition of 3.0 pro release
|
schema.php
CHANGED
@@ -42,6 +42,7 @@ CREATE TABLE {$table_prefix}imports (
|
|
42 |
name VARCHAR(255) NOT NULL DEFAULT '',
|
43 |
friendly_name VARCHAR(255) NOT NULL DEFAULT '',
|
44 |
type VARCHAR(32) NOT NULL DEFAULT '',
|
|
|
45 |
path TEXT,
|
46 |
xpath VARCHAR(255) NOT NULL DEFAULT '',
|
47 |
template LONGTEXT,
|
@@ -50,16 +51,16 @@ CREATE TABLE {$table_prefix}imports (
|
|
50 |
registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
51 |
large_import ENUM('Yes','No') NOT NULL DEFAULT 'No',
|
52 |
root_element VARCHAR(255) DEFAULT '',
|
53 |
-
processing BOOL NOT NULL DEFAULT
|
54 |
-
triggered BOOL NOT NULL DEFAULT
|
55 |
-
queue_chunk_number BIGINT(20) NOT NULL DEFAULT
|
56 |
-
current_post_ids TEXT
|
57 |
first_import TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
58 |
-
count BIGINT(20) NOT NULL DEFAULT
|
59 |
-
imported BIGINT(20) NOT NULL DEFAULT
|
60 |
-
created BIGINT(20) NOT NULL DEFAULT
|
61 |
-
updated BIGINT(20) NOT NULL DEFAULT
|
62 |
-
skipped BIGINT(20) NOT NULL DEFAULT
|
63 |
PRIMARY KEY (id)
|
64 |
) $charset_collate;
|
65 |
CREATE TABLE {$table_prefix}posts (
|
@@ -67,6 +68,7 @@ CREATE TABLE {$table_prefix}posts (
|
|
67 |
post_id BIGINT(20) UNSIGNED NOT NULL,
|
68 |
import_id BIGINT(20) UNSIGNED NOT NULL,
|
69 |
unique_key TEXT,
|
|
|
70 |
PRIMARY KEY (id)
|
71 |
) $charset_collate;
|
72 |
CREATE TABLE {$table_prefix}files (
|
42 |
name VARCHAR(255) NOT NULL DEFAULT '',
|
43 |
friendly_name VARCHAR(255) NOT NULL DEFAULT '',
|
44 |
type VARCHAR(32) NOT NULL DEFAULT '',
|
45 |
+
feed_type ENUM('xml','csv','zip','gz','') NOT NULL DEFAULT '',
|
46 |
path TEXT,
|
47 |
xpath VARCHAR(255) NOT NULL DEFAULT '',
|
48 |
template LONGTEXT,
|
51 |
registered_on DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
|
52 |
large_import ENUM('Yes','No') NOT NULL DEFAULT 'No',
|
53 |
root_element VARCHAR(255) DEFAULT '',
|
54 |
+
processing BOOL NOT NULL DEFAULT 0,
|
55 |
+
triggered BOOL NOT NULL DEFAULT 0,
|
56 |
+
queue_chunk_number BIGINT(20) NOT NULL DEFAULT 0,
|
57 |
+
current_post_ids TEXT,
|
58 |
first_import TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
59 |
+
count BIGINT(20) NOT NULL DEFAULT 0,
|
60 |
+
imported BIGINT(20) NOT NULL DEFAULT 0,
|
61 |
+
created BIGINT(20) NOT NULL DEFAULT 0,
|
62 |
+
updated BIGINT(20) NOT NULL DEFAULT 0,
|
63 |
+
skipped BIGINT(20) NOT NULL DEFAULT 0,
|
64 |
PRIMARY KEY (id)
|
65 |
) $charset_collate;
|
66 |
CREATE TABLE {$table_prefix}posts (
|
68 |
post_id BIGINT(20) UNSIGNED NOT NULL,
|
69 |
import_id BIGINT(20) UNSIGNED NOT NULL,
|
70 |
unique_key TEXT,
|
71 |
+
product_key TEXT,
|
72 |
PRIMARY KEY (id)
|
73 |
) $charset_collate;
|
74 |
CREATE TABLE {$table_prefix}files (
|
static/css/admin.css
CHANGED
@@ -1,983 +1,997 @@
|
|
1 |
-
/*@+ common */
|
2 |
-
.pmxi_plugin hr {
|
3 |
-
height: 1px;
|
4 |
-
border-width: 0px;
|
5 |
-
color: #ddd;
|
6 |
-
background-color: #ddd;
|
7 |
-
margin-bottom: 15px;
|
8 |
-
}
|
9 |
-
.pmxi_plugin a.button {
|
10 |
-
/*padding: 5px 10px;
|
11 |
-
margin: 1px;
|
12 |
-
font-weight: bold;*/
|
13 |
-
}
|
14 |
-
.pmxi_plugin a.help {
|
15 |
-
overflow: hidden;
|
16 |
-
text-indent: -99999px;
|
17 |
-
display: inline-block;
|
18 |
-
width: 16px;
|
19 |
-
height: 16px;
|
20 |
-
background-repeat: no-repeat;
|
21 |
-
background-image: url("../img/help.png");
|
22 |
-
vertical-align: middle;
|
23 |
-
margin-left: 5px;
|
24 |
-
}
|
25 |
-
.pmxi_plugin input.datepicker {
|
26 |
-
width: 8em;
|
27 |
-
}
|
28 |
-
.pmxi_plugin button.ui-datepicker-trigger {
|
29 |
-
background-image: url("../img/date-picker.gif");
|
30 |
-
background-repeat: no-repeat;
|
31 |
-
cursor: pointer;
|
32 |
-
border: none;
|
33 |
-
margin: 1px;
|
34 |
-
width: 21px;
|
35 |
-
height: 18px;
|
36 |
-
vertical-align: middle;
|
37 |
-
}
|
38 |
-
.pmxi_plugin .progress-msg {
|
39 |
-
font-style: italic;
|
40 |
-
display: none;
|
41 |
-
}
|
42 |
-
.pmxi_plugin .inner-content {
|
43 |
-
max-width: 700px;
|
44 |
-
}
|
45 |
-
.pmxi_plugin .loading {
|
46 |
-
cursor: progress;
|
47 |
-
background-repeat: no-repeat;
|
48 |
-
background-position: center;
|
49 |
-
}
|
50 |
-
.pmxi_plugin .preload {
|
51 |
-
background-image: url("../img/loading.png");
|
52 |
-
background-repeat: no-repeat;
|
53 |
-
background-position: 50% 200px;
|
54 |
-
}
|
55 |
-
.pmxi_plugin a.add-new {
|
56 |
-
font-size: 18px;
|
57 |
-
background-color: #eee;
|
58 |
-
cursor: pointer;
|
59 |
-
padding: 6px 10px 6px 10px;
|
60 |
-
line-height: normal;
|
61 |
-
font-style: normal;
|
62 |
-
color: #464646;
|
63 |
-
border-color: #bbb;
|
64 |
-
-moz-border-radius: 4px 4px 4px 4px;
|
65 |
-
border-radius: 4px;
|
66 |
-
border-style: solid;
|
67 |
-
border-width: 1px;
|
68 |
-
font-family: "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;
|
69 |
-
text-decoration: none;
|
70 |
-
}
|
71 |
-
.pmxi_plugin a.add-new:hover {
|
72 |
-
border-color: #666666;
|
73 |
-
color: #000;
|
74 |
-
}
|
75 |
-
.pmxi_plugin div.input {
|
76 |
-
/*line-height: 25px;
|
77 |
-
height: 25px;*/
|
78 |
-
min-height: 21px;
|
79 |
-
}
|
80 |
-
.pmxi_plugin div.input > * {
|
81 |
-
vertical-align: middle;
|
82 |
-
}
|
83 |
-
.pmxi_plugin .options input[type=text], .pmxi_plugin .options select {
|
84 |
-
background: #fafafa !important;
|
85 |
-
border: 1px solid #aaa !important;
|
86 |
-
}
|
87 |
-
.pmxi_plugin .note {
|
88 |
-
color: #666666;
|
89 |
-
font-size: 9px;
|
90 |
-
}
|
91 |
-
.pmxi_plugin div.sub {
|
92 |
-
padding-left: 20px;
|
93 |
-
font-size: 12px;
|
94 |
-
}
|
95 |
-
/* 2 column layout */
|
96 |
-
.pmxi_plugin table.layout {
|
97 |
-
clear: both;
|
98 |
-
border-collapse: collapse;
|
99 |
-
min-width: 770px;
|
100 |
-
width: 100%;
|
101 |
-
}
|
102 |
-
.pmxi_plugin table.layout td {
|
103 |
-
vertical-align: top;
|
104 |
-
border: none;
|
105 |
-
}
|
106 |
-
.pmxi_plugin table.layout td.left {
|
107 |
-
min-width: 490px;
|
108 |
-
width: 70%;
|
109 |
-
}
|
110 |
-
.pmxi_plugin table.layout td.right {
|
111 |
-
padding: 0px 0 16px 20px;
|
112 |
-
width: 25%;
|
113 |
-
min-width: 260px;
|
114 |
-
}
|
115 |
-
.pmxi_plugin table.layout td.left > h2:first-child {
|
116 |
-
margin-top: -22px;
|
117 |
-
padding: 14px 0 3px 0;
|
118 |
-
}
|
119 |
-
.pmxi_plugin table.layout td.left hr {
|
120 |
-
clear: both;
|
121 |
-
}
|
122 |
-
.pmxi_plugin.no-js table.layout td.left > h2:first-child {
|
123 |
-
margin-top: 0px;
|
124 |
-
}
|
125 |
-
/*@*/
|
126 |
-
|
127 |
-
/*@+ Setting Form */
|
128 |
-
.pmxi_plugin form.settings {
|
129 |
-
width: 700px;
|
130 |
-
}
|
131 |
-
/*@*/
|
132 |
-
|
133 |
-
/*@+ Choose File forms */
|
134 |
-
.pmxi_plugin form.choose-file {
|
135 |
-
padding-top: 20px;
|
136 |
-
position: relative;
|
137 |
-
}
|
138 |
-
.pmxi_plugin form.choose-file h3 {
|
139 |
-
margin-bottom: 5px;
|
140 |
-
}
|
141 |
-
.pmxi_plugin form.choose-file .label {
|
142 |
-
font-size: 15px;
|
143 |
-
}
|
144 |
-
.pmxi_plugin form.choose-file input[type="text"],
|
145 |
-
.pmxi_plugin form.choose-file input[type="password"] {
|
146 |
-
width: 80px;
|
147 |
-
font-size: 12px;
|
148 |
-
}
|
149 |
-
.pmxi_plugin form.choose-file input.regular-text,
|
150 |
-
.pmxi_plugin form.choose-file select.regular-text {
|
151 |
-
width: 100%;
|
152 |
-
}
|
153 |
-
.pmxi_plugin #wpcontent form.choose-file select[name="file"],
|
154 |
-
.pmxi_plugin #wpcontent form.choose-file select[name="reimport"] {
|
155 |
-
font-size: 12px;
|
156 |
-
}
|
157 |
-
.pmxi_plugin form.choose-file input[type="submit"].button {
|
158 |
-
width: 150px;
|
159 |
-
}
|
160 |
-
.pmxi_plugin form.choose-file div.input {
|
161 |
-
margin-top: 20px;
|
162 |
-
}
|
163 |
-
/*@*/
|
164 |
-
|
165 |
-
/*@+ Choose Elements form */
|
166 |
-
.pmxi_plugin form.choose-elements input[type="text"] {
|
167 |
-
width: 100%;
|
168 |
-
max-width: 300px;
|
169 |
-
min-width: 150px;
|
170 |
-
}
|
171 |
-
/*@*/
|
172 |
-
|
173 |
-
/*@+ Template form */
|
174 |
-
.pmxi_plugin form.template.edit {
|
175 |
-
/*width: 700px;*/
|
176 |
-
}
|
177 |
-
.pmxi_plugin form.template .load-template {
|
178 |
-
display: block;
|
179 |
-
font-size: 12px;
|
180 |
-
}
|
181 |
-
.pmxi_plugin form.template .load-template select {
|
182 |
-
width: 126px;
|
183 |
-
}
|
184 |
-
|
185 |
-
.pmxi_plugin #poststuff form.template h3 {
|
186 |
-
margin: 1em 0 5px 2px;
|
187 |
-
font-size: 1.17em;
|
188 |
-
padding: 0px;
|
189 |
-
}
|
190 |
-
.pmxi_plugin #post-preview {
|
191 |
-
font-size: 12px;
|
192 |
-
}
|
193 |
-
.pmxi_plugin #post-preview .error {
|
194 |
-
margin: 5px 0;
|
195 |
-
}
|
196 |
-
.pmxi_plugin h3 .header-option {
|
197 |
-
display: block;
|
198 |
-
float: right;
|
199 |
-
font-size: 12px;
|
200 |
-
font-weight: normal;
|
201 |
-
}
|
202 |
-
/*@*/
|
203 |
-
|
204 |
-
/*@+ Options form */
|
205 |
-
.pmxi_plugin form.options.edit {
|
206 |
-
/*width: 700px;*/
|
207 |
-
}
|
208 |
-
|
209 |
-
.pmxi_plugin .post-type-container,
|
210 |
-
.pmxi_plugin .file-type-container {
|
211 |
-
padding: 4px 10px 5px;
|
212 |
-
border: 1px solid transparent;
|
213 |
-
}
|
214 |
-
.pmxi_plugin .post-type-container.selected,
|
215 |
-
.pmxi_plugin .file-type-container.selected {
|
216 |
-
background-color: #F2FBD9;
|
217 |
-
border: 1px solid #B5E61D;
|
218 |
-
padding-bottom: 10px;
|
219 |
-
}
|
220 |
-
.pmxi_plugin .post-type-container h3,
|
221 |
-
.pmxi_plugin .file-type-container h3 {
|
222 |
-
margin: 0px 0px;
|
223 |
-
}
|
224 |
-
.pmxi_plugin .post-type-container .post-type-options,
|
225 |
-
.pmxi_plugin .file-type-container .file-type-options {
|
226 |
-
margin: 5px 0 0 20px;
|
227 |
-
}
|
228 |
-
|
229 |
-
.pmxi_plugin table.form-table {
|
230 |
-
clear: none;
|
231 |
-
margin-top: 0px;
|
232 |
-
}
|
233 |
-
.pmxi_plugin .post-type-options table.form-table {
|
234 |
-
max-width: 500px;
|
235 |
-
}
|
236 |
-
.pmxi_plugin .post-type-options table.form-table td.delim {
|
237 |
-
width: 50px;
|
238 |
-
position: relative;
|
239 |
-
display: block;
|
240 |
-
}
|
241 |
-
.pmxi_plugin .post-type-options table.form-table td.delim input {
|
242 |
-
width: 20px;
|
243 |
-
}
|
244 |
-
.pmxi_plugin table.form-table.custom-params {
|
245 |
-
max-width: 700px;
|
246 |
-
}
|
247 |
-
.pmxi_plugin table.form-table td,
|
248 |
-
.pmxi_plugin table.form-table th {
|
249 |
-
padding: 2px 4px;
|
250 |
-
vertical-align: top;
|
251 |
-
}
|
252 |
-
.pmxi_plugin .post-type-options table.form-table th {
|
253 |
-
width: 100px;
|
254 |
-
}
|
255 |
-
.pmxi_plugin .post-type-options table.form-table select {
|
256 |
-
max-width: 300px;
|
257 |
-
width:300px;
|
258 |
-
}
|
259 |
-
.pmxi_plugin table.form-table thead td {
|
260 |
-
font-weight: bold;
|
261 |
-
}
|
262 |
-
.pmxi_plugin table.form-table.custom-params input {
|
263 |
-
margin-left: 0;
|
264 |
-
}
|
265 |
-
.pmxi_plugin table.form-table tr.template {
|
266 |
-
display: none;
|
267 |
-
}
|
268 |
-
/*@*/
|
269 |
-
|
270 |
-
/*@+ XML representation */
|
271 |
-
.pmxi_plugin .tag {
|
272 |
-
background-color: #fff;
|
273 |
-
position: fixed;
|
274 |
-
width:22%;
|
275 |
-
margin-top: 45px;
|
276 |
-
border-top: 1px solid #DFDFDF;
|
277 |
-
-moz-border-radius-topleft: 4px;
|
278 |
-
-webkit-border-top-left-radius: 4px;
|
279 |
-
border-top-left-radius: 4px;
|
280 |
-
-moz-border-radius-topright: 4px;
|
281 |
-
-webkit-border-top-right-radius: 4px;
|
282 |
-
border-top-right-radius: 4px;
|
283 |
-
}
|
284 |
-
|
285 |
-
.pmxi_plugin .options .tag{
|
286 |
-
margin-top: 0px;
|
287 |
-
}
|
288 |
-
.pmxi_plugin .tag .title {
|
289 |
-
font-weight: bold;
|
290 |
-
padding: 6px 8px;
|
291 |
-
color: #464646;
|
292 |
-
background: #DFDFDF;
|
293 |
-
font-size: 12px;
|
294 |
-
}
|
295 |
-
.pmxi_plugin .tag .xml {
|
296 |
-
max-height: 525px;
|
297 |
-
overflow: auto;
|
298 |
-
border: 1px solid #DFDFDF;
|
299 |
-
border-top:none;
|
300 |
-
-moz-border-radius-bottomright: 4px;
|
301 |
-
-webkit-border-bottom-right-radius: 4px;
|
302 |
-
border-bottom-right-radius: 4px;
|
303 |
-
-moz-border-radius-bottomleft: 4px;
|
304 |
-
-webkit-border-bottom-left-radius: 4px;
|
305 |
-
border-bottom-left-radius: 4px;
|
306 |
-
}
|
307 |
-
.pmxi_plugin .tag .navigation {
|
308 |
-
float: right;
|
309 |
-
margin: -2px -12px 0 0;
|
310 |
-
}
|
311 |
-
.pmxi_plugin .tag .navigation a,
|
312 |
-
.pmxi_plugin .tag .navigation span {
|
313 |
-
font-weight: bold;
|
314 |
-
padding: 0 12px;
|
315 |
-
text-decoration: none;
|
316 |
-
}
|
317 |
-
|
318 |
-
@media screen and (max-height: 700px) {
|
319 |
-
.pmxi_plugin .tag {
|
320 |
-
height:300px;
|
321 |
-
}
|
322 |
-
.pmxi_plugin .tag .xml {
|
323 |
-
max-height: 265px;
|
324 |
-
}
|
325 |
-
}
|
326 |
-
|
327 |
-
.xml {
|
328 |
-
padding-left: 15px;
|
329 |
-
}
|
330 |
-
.xml-element {
|
331 |
-
border: 1px solid transparent;
|
332 |
-
margin: 1px 1px 1px 0;
|
333 |
-
}
|
334 |
-
.xml-element.selected > .xml-tag.opening .xml-tag-name {
|
335 |
-
background-color: #B5E61D;
|
336 |
-
}
|
337 |
-
.xml-content {
|
338 |
-
padding-left: 14px;
|
339 |
-
}
|
340 |
-
.xml-content.collapsed {
|
341 |
-
display: none;
|
342 |
-
}
|
343 |
-
.xml-content.textonly.short {
|
344 |
-
padding-left: 0px;
|
345 |
-
display: inline;
|
346 |
-
}
|
347 |
-
.xml-tag {
|
348 |
-
display: inline;
|
349 |
-
}
|
350 |
-
.xml-tag-name {
|
351 |
-
color: #906;
|
352 |
-
font-weight: bold;
|
353 |
-
}
|
354 |
-
.xml-tag.opening .xml-tag-name {
|
355 |
-
cursor: pointer;
|
356 |
-
}
|
357 |
-
.xml-attr-name {
|
358 |
-
font-weight: bold;
|
359 |
-
cursor: pointer;
|
360 |
-
}
|
361 |
-
.xml-attr-value {
|
362 |
-
color: blue;
|
363 |
-
}
|
364 |
-
.xml-expander {
|
365 |
-
display: inline-block;
|
366 |
-
width: 12px;
|
367 |
-
margin-left: -12px;
|
368 |
-
-moz-user-select: none;
|
369 |
-
-khtml-user-select: none;
|
370 |
-
-webkit-user-select: none;
|
371 |
-
user-select: none;
|
372 |
-
cursor: pointer;
|
373 |
-
font-family: monospace;
|
374 |
-
line-height: 100%;
|
375 |
-
text-align: left;
|
376 |
-
color: red;
|
377 |
-
}
|
378 |
-
.xml-more {
|
379 |
-
color: red;
|
380 |
-
font-size: 80%;
|
381 |
-
}
|
382 |
-
.xml.resetable .xml-element.lvl-mod4-3 > .xml-content {
|
383 |
-
margin-left: -59px;
|
384 |
-
margin-right: -8px;
|
385 |
-
background-color: #fff;
|
386 |
-
border: 1px dashed #906;
|
387 |
-
border-left: 2px solid #906;
|
388 |
-
border-right: none;
|
389 |
-
}
|
390 |
-
.xml.resetable .xml-element.lvl-mod4-3 > .xml-content.short {
|
391 |
-
margin-left: 0;
|
392 |
-
margin-right: 0;
|
393 |
-
border: none;
|
394 |
-
background-color: inherit;
|
395 |
-
}
|
396 |
-
/* xml table representation */
|
397 |
-
tr.xml-element.selected .xml-tag.opening .xml-tag-name {
|
398 |
-
background-color: #B5E61D;
|
399 |
-
}
|
400 |
-
table.xml td {
|
401 |
-
padding-left: 20px;
|
402 |
-
}
|
403 |
-
table.xml td:first-child {
|
404 |
-
width: 1px;
|
405 |
-
padding-left: 0px;
|
406 |
-
}
|
407 |
-
|
408 |
-
table.xml,
|
409 |
-
table.xml table {
|
410 |
-
width: 100%;
|
411 |
-
border-collapse:collapse;
|
412 |
-
border-spacing:0;
|
413 |
-
}
|
414 |
-
/*@*/
|
415 |
-
|
416 |
-
/*@+ table list */
|
417 |
-
.pmxi_plugin table.widefat th {
|
418 |
-
white-space: nowrap;
|
419 |
-
}
|
420 |
-
.pmxi_plugin table.widefat th.ASC a {
|
421 |
-
background-image: url("../img/screen-options-right-up.gif");
|
422 |
-
background-repeat: no-repeat;
|
423 |
-
background-position: right center;
|
424 |
-
padding-right: 19px;
|
425 |
-
}
|
426 |
-
.pmxi_plugin table.widefat th.DESC a {
|
427 |
-
background-image: url("../img/screen-options-right.gif");
|
428 |
-
background-repeat: no-repeat;
|
429 |
-
background-position: right center;
|
430 |
-
padding-right: 19px;
|
431 |
-
}
|
432 |
-
|
433 |
-
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-id {
|
434 |
-
width: 35px;
|
435 |
-
}
|
436 |
-
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-scheduled {
|
437 |
-
width: 85px;
|
438 |
-
}
|
439 |
-
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-registered_on {
|
440 |
-
width: 130px;
|
441 |
-
}
|
442 |
-
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-post_count {
|
443 |
-
width: 105px;
|
444 |
-
}
|
445 |
-
/*@*/
|
446 |
-
|
447 |
-
/*@+ fixes */
|
448 |
-
.pmxi_plugin input[type="file"] {
|
449 |
-
padding: 0; /* FIX height or <input type="file" /> for Safari & Chrome */
|
450 |
-
}
|
451 |
-
.pmxi_plugin .ui-widget-overlay {
|
452 |
-
position: fixed !important; /* FIX: modal dialog overlay in IE 8 */
|
453 |
-
background-color: #aaa !important; /* FIX: overlay color */
|
454 |
-
}
|
455 |
-
.pmxi_plugin .ui-dialog {
|
456 |
-
position: absolute !important; /* FIX: for wordpress 3.1 not to add empty space */
|
457 |
-
}
|
458 |
-
.pmxi_plugin .ui-autocomplete {
|
459 |
-
position: absolute;
|
460 |
-
border-color: #ccc #444 #444 #aaa;
|
461 |
-
cursor: default;
|
462 |
-
-moz-border-radius: 0;
|
463 |
-
border-radius: 0;
|
464 |
-
max-height: 200px;
|
465 |
-
max-width: 700px;
|
466 |
-
overflow-y: auto;
|
467 |
-
overflow-x: hidden;
|
468 |
-
white-space: nowrap;
|
469 |
-
font-size: 11px;
|
470 |
-
}
|
471 |
-
.pmxi_plugin .ui-autocomplete .ui-menu-item {
|
472 |
-
padding: 0;
|
473 |
-
margin: 0;
|
474 |
-
}
|
475 |
-
.pmxi_plugin .ui-autocomplete .ui-menu-item a {
|
476 |
-
display: block;
|
477 |
-
padding: 2px;
|
478 |
-
padding-right: 20px; /* space for scroll bar */
|
479 |
-
font-size: 11px;
|
480 |
-
border: none;
|
481 |
-
-moz-border-radius: 0;
|
482 |
-
border-radius: 0;
|
483 |
-
}
|
484 |
-
.pmxi_plugin .ui-autocomplete .ui-menu-item a.ui-state-hover {
|
485 |
-
background: #39f;
|
486 |
-
color: #fff;
|
487 |
-
}
|
488 |
-
.pmxi_plugin input.autocomplete {
|
489 |
-
background: url("../img/down.gif") no-repeat right top #fff;
|
490 |
-
padding-right: 20px;
|
491 |
-
cursor: default;
|
492 |
-
font-size: 11px !important;
|
493 |
-
}
|
494 |
-
/*@*/
|
495 |
-
|
496 |
-
.pmxi_plugin .taglines{
|
497 |
-
font-size:13px;
|
498 |
-
font-style: italic;
|
499 |
-
display: block;
|
500 |
-
color: #777;
|
501 |
-
}
|
502 |
-
|
503 |
-
.pmxi_plugin #process{ display:none; }
|
504 |
-
.pmxi_plugin .load-options{ float:right; font-size:13px; position: relative; top: -30px; }
|
505 |
-
.pmxi_plugin form.options table.layout td.right{
|
506 |
-
width: 25%;
|
507 |
-
}
|
508 |
-
.pmxi_plugin .drag-element{
|
509 |
-
background: url("../img/drag.png") top right no-repeat;
|
510 |
-
cursor: pointer;
|
511 |
-
padding-left: 25px;
|
512 |
-
background-position: 0px 1px;
|
513 |
-
}
|
514 |
-
.sortable li{ position: relative;}
|
515 |
-
.pmxi_plugin ol{
|
516 |
-
margin-top: 6px;
|
517 |
-
list-style: none;
|
518 |
-
}
|
519 |
-
.pmxi_plugin .no-margin{ margin:0px; }
|
520 |
-
.pmxi_plugin .icon-item, .pmxi_plugin .add-new-custom{
|
521 |
-
display: inline-block;
|
522 |
-
width: 16px;
|
523 |
-
height: 16px;
|
524 |
-
margin: 0px 3px;
|
525 |
-
}
|
526 |
-
.pmxi_plugin .add-new-ico, .pmxi_plugin .add-new-custom{
|
527 |
-
background: url("../img/ico-add-new.png") no-repeat 0px 4px;
|
528 |
-
width:70px;
|
529 |
-
height:25px;
|
530 |
-
padding-left: 15px;
|
531 |
-
color:#21759B;
|
532 |
-
}
|
533 |
-
|
534 |
-
.pmxi_plugin .remove-ico{
|
535 |
-
background: url("../img/ico-remove.png") no-repeat;
|
536 |
-
top:1px;
|
537 |
-
right:-
|
538 |
-
position: absolute;
|
539 |
-
}
|
540 |
-
|
541 |
-
.pmxi_plugin .hidden{ display: none; }
|
542 |
-
|
543 |
-
.pmxi_plugin .fs11 { font-size:11px; }
|
544 |
-
|
545 |
-
.pmxi_plugin .rel { position: relative; }
|
546 |
-
|
547 |
-
#type_meta_select{ margin-bottom: 10px; height:1.8em; }
|
548 |
-
|
549 |
-
.upload_process{
|
550 |
-
border: none;
|
551 |
-
padding: 1px;
|
552 |
-
}
|
553 |
-
|
554 |
-
#large_import_xpath{ display:none; }
|
555 |
-
#large_import{ margin:0px 5px; }
|
556 |
-
#download_pmxi_log{
|
557 |
-
cursor: pointer;
|
558 |
-
margin: 5px 0;
|
559 |
-
display: none;
|
560 |
-
}
|
561 |
-
.pmxi_plugin .import_process_bar, .pmxi_plugin .import_percent{
|
562 |
-
display: none;
|
563 |
-
}
|
564 |
-
/*.pmxi_plugin .import_progress{
|
565 |
-
font-size: 14px !important;
|
566 |
-
}*/
|
567 |
-
.pmxi_plugin #processbar{
|
568 |
-
text-align: center;
|
569 |
-
visibility: hidden;
|
570 |
-
height: 37px;
|
571 |
-
padding-top: 18px;
|
572 |
-
margin-bottom: 20px;
|
573 |
-
border: 1px solid #AAAAAA;
|
574 |
-
color: #222222;
|
575 |
-
position: relative;
|
576 |
-
}
|
577 |
-
.pmxi_plugin #processbar div{
|
578 |
-
background: #aaa;
|
579 |
-
height: 55px;
|
580 |
-
width: 0%;
|
581 |
-
position: absolute;
|
582 |
-
opacity: 0.5;
|
583 |
-
top:0;
|
584 |
-
}
|
585 |
-
.pmxi_plugin #import_progress{
|
586 |
-
color: #000000;
|
587 |
-
font-size: 13px;
|
588 |
-
font-weight: bold;
|
589 |
-
opacity: 1;
|
590 |
-
}
|
591 |
-
.pmxi_plugin #right_progress{ float:right; padding-right: 5px; }
|
592 |
-
.pmxi_plugin #left_progress{ float:left; padding-left: 5px; }
|
593 |
-
.pmxi_plugin #existing_meta_keys{
|
594 |
-
margin-bottom: 10px;
|
595 |
-
padding: 2px;
|
596 |
-
width: 580px;
|
597 |
-
}
|
598 |
-
.pmxi_plugin #pmxi_tabs{
|
599 |
-
display: none;
|
600 |
-
padding-bottom: 20px;
|
601 |
-
-moz-border-radius: 4px;
|
602 |
-
-khtml-border-radius: 4px;
|
603 |
-
-webkit-border-radius: 4px;
|
604 |
-
border-radius: 4px;
|
605 |
-
}
|
606 |
-
.pmxi_plugin .ui-widget-header{
|
607 |
-
-moz-border-radius: 4px;
|
608 |
-
-khtml-border-radius: 4px;
|
609 |
-
-webkit-border-radius: 4px;
|
610 |
-
border-radius: 4px;
|
611 |
-
}
|
612 |
-
.pmxi_plugin .ui-tabs .ui-tabs-nav li{
|
613 |
-
-moz-border-top-left-radius: 4px;
|
614 |
-
-khtml-border-top-left-radius: 4px;
|
615 |
-
-webkit-border-top-left-radius: 4px;
|
616 |
-
border-top-left-radius: 4px;
|
617 |
-
-moz-border-top-right-radius: 4px;
|
618 |
-
-khtml-border-top-right-radius: 4px;
|
619 |
-
-webkit-border-top-right-radius: 4px;
|
620 |
-
border-top-right-radius: 4px;
|
621 |
-
}
|
622 |
-
/*.pmxi_plugin .ui-widget-header{
|
623 |
-
background: #F2FBD9;
|
624 |
-
border: 1px solid #F2FBD9;
|
625 |
-
}
|
626 |
-
.pmxi_plugin .ui-state-default{
|
627 |
-
border:none;
|
628 |
-
font-size: 12px;
|
629 |
-
font-weight: bold;
|
630 |
-
background: #F2FBD9;
|
631 |
-
}
|
632 |
-
.pmxi_plugin .ui-state-active{
|
633 |
-
background: #fff;
|
634 |
-
}
|
635 |
-
.pmxi_plugin .ui-tabs{
|
636 |
-
padding: 0px;
|
637 |
-
}*/
|
638 |
-
#select-files{
|
639 |
-
font-size: 11px !important;
|
640 |
-
height:25px;
|
641 |
-
}
|
642 |
-
.pmxi_plugin .progress{
|
643 |
-
position: relative;
|
644 |
-
visibility: hidden;
|
645 |
-
color: #009039;
|
646 |
-
font-size: 13px;
|
647 |
-
font-weight: bold;
|
648 |
-
margin-top: 10px;
|
649 |
-
width: 100%;
|
650 |
-
text-align: center;
|
651 |
-
border:1px solid #4297D7;
|
652 |
-
-moz-border-radius: 4px;
|
653 |
-
-khtml-border-radius: 4px;
|
654 |
-
-webkit-border-radius: 4px;
|
655 |
-
border-radius: 4px;
|
656 |
-
}
|
657 |
-
.pmxi_plugin #progressbar{
|
658 |
-
border: medium none;
|
659 |
-
left: 0;
|
660 |
-
position: absolute;
|
661 |
-
text-align: center;
|
662 |
-
top: 8px;
|
663 |
-
width: 100%;
|
664 |
-
font-size: 12px;
|
665 |
-
color:#333;
|
666 |
-
}
|
667 |
-
.pmxi_plugin #file_name{
|
668 |
-
font-size: 16px;
|
669 |
-
font-weight: bold;
|
670 |
-
margin-left: 10px;
|
671 |
-
float: right;
|
672 |
-
}
|
673 |
-
.pmxi_plugin .ui-progressbar .ui-progressbar-value { /*background-image: url("../img/progress_animated.gif");*/ }
|
674 |
-
.pmxi_plugin form.choose-file .submit-buttons{
|
675 |
-
/*bottom: -125px;
|
676 |
-
position: absolute;
|
677 |
-
right: -18px; */
|
678 |
-
}
|
679 |
-
.pmxi_plugin form#basic .submit-buttons{
|
680 |
-
display: none;
|
681 |
-
}
|
682 |
-
.pmxi_plugin fieldset{
|
683 |
-
padding: 20px;
|
684 |
-
width:auto;
|
685 |
-
}
|
686 |
-
.pmxi_plugin .right fieldset{
|
687 |
-
padding: 15px;
|
688 |
-
}
|
689 |
-
.pmxi_plugin .right fieldset input{
|
690 |
-
max-width:none;
|
691 |
-
padding:6px;
|
692 |
-
margin:0px
|
693 |
-
}
|
694 |
-
.pmxi_plugin .right a{
|
695 |
-
text-decoration: underline;
|
696 |
-
}
|
697 |
-
.pmxi_plugin fieldset legend{
|
698 |
-
padding: 0px 5px;
|
699 |
-
font-weight: bold;
|
700 |
-
}
|
701 |
-
.pmxi_plugin .options fieldset legend{
|
702 |
-
font-size: 1.17em;
|
703 |
-
}
|
704 |
-
.pmxi_plugin .matches_count{
|
705 |
-
font-weight: bold;
|
706 |
-
color:#33AA28;
|
707 |
-
}
|
708 |
-
.pmxi_plugin .xpath_help{
|
709 |
-
/*bottom: -40px;*/
|
710 |
-
position: relative;
|
711 |
-
text-align: center;
|
712 |
-
}
|
713 |
-
.pmxi_plugin .btns, .pmxi_plugin .btns input, .pmxi_plugin .btns a{
|
714 |
-
float: right;
|
715 |
-
}
|
716 |
-
.pmxi_plugin .btns input{
|
717 |
-
height: 19px;
|
718 |
-
margin-left: 5px;
|
719 |
-
padding-top: 0;
|
720 |
-
}
|
721 |
-
.pmxi_plugin .btns a{
|
722 |
-
font-weight: bold;
|
723 |
-
margin: 0 5px;
|
724 |
-
padding: 4px 10px;
|
725 |
-
width:70px;
|
726 |
-
text-align: center;
|
727 |
-
}
|
728 |
-
.pmxi_plugin .col3{
|
729 |
-
border-right: 1px solid #CCCCCC;
|
730 |
-
float: left;
|
731 |
-
height: 265px;
|
732 |
-
width:30%;
|
733 |
-
margin-bottom: 10px;
|
734 |
-
padding: 0 1%;
|
735 |
-
}
|
736 |
-
.pmxi_plugin .col3.last{
|
737 |
-
border: none;
|
738 |
-
}
|
739 |
-
.pmxi_plugin .col3 > div{
|
740 |
-
margin-left: 20px;
|
741 |
-
}
|
742 |
-
.pmxi_plugin .col2{
|
743 |
-
float: left;
|
744 |
-
width: 50%;
|
745 |
-
}
|
746 |
-
.pmxi_plugin .col2 fieldset{
|
747 |
-
border: 1px solid #CCCCCC;
|
748 |
-
margin: 0 5px;
|
749 |
-
padding: 5px 2% 5px 5px;
|
750 |
-
text-align: center;
|
751 |
-
}
|
752 |
-
.pmxi_plugin input.small{
|
753 |
-
width:25px;
|
754 |
-
text-align: center;
|
755 |
-
}
|
756 |
-
.pmxi_plugin .post_taxonomy{
|
757 |
-
margin-bottom: 15px;
|
758 |
-
overflow: hidden
|
759 |
-
padding-bottom: 15px;
|
760 |
-
}
|
761 |
-
.pmxi_plugin .post_taxonomy .delim{
|
762 |
-
padding-left: 25px;
|
763 |
-
}
|
764 |
-
.pmxi_plugin .post_taxonomy .delim .add-new-ico{
|
765 |
-
float: right;
|
766 |
-
margin-right:
|
767 |
-
margin-top: 5px;
|
768 |
-
}
|
769 |
-
.pmxi_plugin .post_taxonomy ol.ui-sortable{
|
770 |
-
padding-right: 0px;
|
771 |
-
}
|
772 |
-
.pmxi_plugin .optionsset{
|
773 |
-
border:1px solid #ccc;
|
774 |
-
}
|
775 |
-
.pmxi_plugin .action.remove{
|
776 |
-
display: block;
|
777 |
-
position: relative;
|
778 |
-
}
|
779 |
-
.pmxi_plugin .action.remove a{
|
780 |
-
background: url("../img/ico-remove.png") no-repeat scroll 0 0 transparent;
|
781 |
-
height: 16px;
|
782 |
-
position: absolute;
|
783 |
-
right:
|
784 |
-
width: 16px;
|
785 |
-
}
|
786 |
-
.pmxi_plugin .switcher-target-is_keep_former_posts{
|
787 |
-
padding-left: 25px;
|
788 |
-
}
|
789 |
-
.pmxi_plugin form.options{
|
790 |
-
position: relative;
|
791 |
-
}
|
792 |
-
.pmxi_plugin .options_buttons{
|
793 |
-
bottom: -75px;
|
794 |
-
display: block;
|
795 |
-
position: absolute;
|
796 |
-
right: 0;
|
797 |
-
}
|
798 |
-
.pmxi-button{
|
799 |
-
border: 1px solid #BBBBBB;
|
800 |
-
color: #464646;
|
801 |
-
cursor: pointer;
|
802 |
-
font-size: 18px !important;
|
803 |
-
margin-left: 10px;
|
804 |
-
padding: 15px 25px;
|
805 |
-
text-decoration: none;
|
806 |
-
-moz-border-radius: 3px;
|
807 |
-
-khtml-border-radius: 3px;
|
808 |
-
-webkit-border-radius: 3px;
|
809 |
-
border-radius: 3px;
|
810 |
-
}
|
811 |
-
.pmxi-button:hover{
|
812 |
-
background: #dfdfdf;
|
813 |
-
}
|
814 |
-
.pmxi_plugin .ui-state-default a{
|
815 |
-
font-size: 13px !important;
|
816 |
-
}
|
817 |
-
.pmxi_plugin .preview{
|
818 |
-
float:none;
|
819 |
-
text-decoration: none;
|
820 |
-
}
|
821 |
-
.pmxi_plugin .template-sidebar .tag{
|
822 |
-
max-height:550px;
|
823 |
-
}
|
824 |
-
.pmxi_plugin .options .submit-buttons{
|
825 |
-
float: right;
|
826 |
-
position: relative;
|
827 |
-
text-align: right;
|
828 |
-
top: 30px;
|
829 |
-
right:-18px;
|
830 |
-
}
|
831 |
-
.pmxi_plugin .back{
|
832 |
-
font-size: 16px;
|
833 |
-
color:#21759B;
|
834 |
-
}
|
835 |
-
.pmxi_plugin .separated_by{
|
836 |
-
float: right;
|
837 |
-
font-size: 12px;
|
838 |
-
color: #999999;
|
839 |
-
margin-right: 20px;
|
840 |
-
}
|
841 |
-
.pmxi_plugin .delim > label{
|
842 |
-
color: #999999;
|
843 |
-
font-size: 11px;
|
844 |
-
}
|
845 |
-
.pmxi_plugin .optionsset > table{
|
846 |
-
border-bottom: 1px solid #CCCCCC;
|
847 |
-
margin-bottom: 20px;
|
848 |
-
width: 100%;
|
849 |
-
}
|
850 |
-
/* Log Bar - Step 5 */
|
851 |
-
.pmxi_plugin #logwrapper{
|
852 |
-
border: 1px solid #aaa;
|
853 |
-
margin-bottom: 20px;
|
854 |
-
}
|
855 |
-
.pmxi_plugin #logbar{
|
856 |
-
padding: 5px 0px;
|
857 |
-
text-align: center;
|
858 |
-
margin: 10px 0px;
|
859 |
-
border: 1px solid #aaa;
|
860 |
-
overflow: auto;
|
861 |
-
}
|
862 |
-
.pmxi_plugin .optionsset > table:last-child{
|
863 |
-
border: none;
|
864 |
-
}
|
865 |
-
.pmxi_plugin #download_log_separator, .pmxi_plugin #download_log{
|
866 |
-
display: none;
|
867 |
-
}
|
868 |
-
.pmxi_plugin #loglist{
|
869 |
-
border: 1px solid #AAAAAA;
|
870 |
-
height: 400px;
|
871 |
-
overflow: auto;
|
872 |
-
}
|
873 |
-
.pmxi_plugin #loglist > p{
|
874 |
-
margin: 0;
|
875 |
-
padding: 3px 5px;
|
876 |
-
}
|
877 |
-
.pmxi_plugin #loglist > p.odd{
|
878 |
-
background: #dfdfdf;
|
879 |
-
}
|
880 |
-
.pmxi_plugin #process_notice{
|
881 |
-
color: red;
|
882 |
-
text-align: center;
|
883 |
-
}
|
884 |
-
.pmxi_plugin #reimported_notify{
|
885 |
-
border: 1px solid #AFAFAF;
|
886 |
-
margin-bottom: 20px;
|
887 |
-
padding: 10px 20px;
|
888 |
-
}
|
889 |
-
.pmxi_plugin #reimported_notify p span{
|
890 |
-
color:#ccc;
|
891 |
-
}
|
892 |
-
.pmxi_plugin .action_buttons{
|
893 |
-
overflow: hidden;
|
894 |
-
clear: both;
|
895 |
-
padding-bottom: 10px;
|
896 |
-
}
|
897 |
-
/*.pmxi_plugin .action_buttons a{
|
898 |
-
border: 1px solid #BBBBBB;
|
899 |
-
-moz-border-radius: 3px;
|
900 |
-
-khtml-border-radius: 3px;
|
901 |
-
-webkit-border-radius: 3px;
|
902 |
-
border-radius: 3px;
|
903 |
-
color: #464646;
|
904 |
-
cursor: pointer;
|
905 |
-
font-size: 18px !important;
|
906 |
-
margin-right: 10px;
|
907 |
-
padding: 15px 25px;
|
908 |
-
text-decoration: none;
|
909 |
-
display: block;
|
910 |
-
width:25px;
|
911 |
-
float: left;
|
912 |
-
}
|
913 |
-
.pmxi_plugin .action_buttons a:hover{
|
914 |
-
background: #dfdfdf;
|
915 |
-
}*/
|
916 |
-
.pmxi_plugin #current_element{
|
917 |
-
color:green;
|
918 |
-
}
|
919 |
-
.pmxi_plugin #current_xml{ display: none;}
|
920 |
-
.pmxi_plugin #goto_element{
|
921 |
-
display: block;
|
922 |
-
float: left;
|
923 |
-
height: 47px;
|
924 |
-
margin-right: 10px;
|
925 |
-
width: 70px !important;
|
926 |
-
min-width: 70px;
|
927 |
-
text-align: center;
|
928 |
-
font-size: 18px;
|
929 |
-
}
|
930 |
-
.pmxi_plugin .choose-elements table tbody tr td{
|
931 |
-
overflow: hidden;
|
932 |
-
}
|
933 |
-
.pmxi_plugin #plupload-ui h3{
|
934 |
-
float: left;
|
935 |
-
font-size: 13px;
|
936 |
-
font-weight: normal;
|
937 |
-
margin-bottom: 0;
|
938 |
-
margin-top: 8px;
|
939 |
-
}
|
940 |
-
.pmxi_plugin #wp-content-media-buttons{
|
941 |
-
display: none;
|
942 |
-
}
|
943 |
-
.pmxi_plugin label{
|
944 |
-
-webkit-touch-callout: none;
|
945 |
-
-webkit-user-select: none;
|
946 |
-
-khtml-user-select: none;
|
947 |
-
-moz-user-select: none;
|
948 |
-
-ms-user-select: none;
|
949 |
-
user-select: none;
|
950 |
-
}
|
951 |
-
.pmxi_plugin .large_button{
|
952 |
-
margin-left: 10px;
|
953 |
-
padding: 15px 25px;
|
954 |
-
border: 1px solid #C5DBEC;
|
955 |
-
}
|
956 |
-
.pmxi_plugin .drag-element .assign_post{
|
957 |
-
float: left;
|
958 |
-
}
|
959 |
-
.pmxi_plugin .drag-element .widefat{
|
960 |
-
margin-left: 1%;
|
961 |
-
width:
|
962 |
-
}
|
963 |
-
.pmxi_plugin .upgrade_link{
|
964 |
-
color: #21759B;
|
965 |
-
}
|
966 |
-
.pmxi_stars{
|
967 |
-
display: inline-block;
|
968 |
-
background: url("../img/stars.png") no-repeat;
|
969 |
-
width: 125px;
|
970 |
-
height: 24px;
|
971 |
-
position: relative;
|
972 |
-
top:10px;
|
973 |
-
}
|
974 |
-
.updated_bottom{
|
975 |
-
background-color: #FFFFE0;
|
976 |
-
border-color: #E6DB55;
|
977 |
-
margin: 5px 0 15px;
|
978 |
-
padding: 0 0.6em;
|
979 |
-
-moz-border-radius: 3px 3px 3px 3px;
|
980 |
-
border-radius: 3px;
|
981 |
-
border-style: solid;
|
982 |
-
border-width: 1px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
}
|
1 |
+
/*@+ common */
|
2 |
+
.pmxi_plugin hr {
|
3 |
+
height: 1px;
|
4 |
+
border-width: 0px;
|
5 |
+
color: #ddd;
|
6 |
+
background-color: #ddd;
|
7 |
+
margin-bottom: 15px;
|
8 |
+
}
|
9 |
+
.pmxi_plugin a.button {
|
10 |
+
/*padding: 5px 10px;
|
11 |
+
margin: 1px;
|
12 |
+
font-weight: bold;*/
|
13 |
+
}
|
14 |
+
.pmxi_plugin a.help {
|
15 |
+
overflow: hidden;
|
16 |
+
text-indent: -99999px;
|
17 |
+
display: inline-block;
|
18 |
+
width: 16px;
|
19 |
+
height: 16px;
|
20 |
+
background-repeat: no-repeat;
|
21 |
+
background-image: url("../img/help.png");
|
22 |
+
vertical-align: middle;
|
23 |
+
margin-left: 5px;
|
24 |
+
}
|
25 |
+
.pmxi_plugin input.datepicker {
|
26 |
+
width: 8em;
|
27 |
+
}
|
28 |
+
.pmxi_plugin button.ui-datepicker-trigger {
|
29 |
+
background-image: url("../img/date-picker.gif");
|
30 |
+
background-repeat: no-repeat;
|
31 |
+
cursor: pointer;
|
32 |
+
border: none;
|
33 |
+
margin: 1px;
|
34 |
+
width: 21px;
|
35 |
+
height: 18px;
|
36 |
+
vertical-align: middle;
|
37 |
+
}
|
38 |
+
.pmxi_plugin .progress-msg {
|
39 |
+
font-style: italic;
|
40 |
+
display: none;
|
41 |
+
}
|
42 |
+
.pmxi_plugin .inner-content {
|
43 |
+
max-width: 700px;
|
44 |
+
}
|
45 |
+
.pmxi_plugin .loading {
|
46 |
+
cursor: progress;
|
47 |
+
background-repeat: no-repeat;
|
48 |
+
background-position: center;
|
49 |
+
}
|
50 |
+
.pmxi_plugin .preload {
|
51 |
+
background-image: url("../img/loading.png");
|
52 |
+
background-repeat: no-repeat;
|
53 |
+
background-position: 50% 200px;
|
54 |
+
}
|
55 |
+
.pmxi_plugin a.add-new {
|
56 |
+
font-size: 18px;
|
57 |
+
background-color: #eee;
|
58 |
+
cursor: pointer;
|
59 |
+
padding: 6px 10px 6px 10px;
|
60 |
+
line-height: normal;
|
61 |
+
font-style: normal;
|
62 |
+
color: #464646;
|
63 |
+
border-color: #bbb;
|
64 |
+
-moz-border-radius: 4px 4px 4px 4px;
|
65 |
+
border-radius: 4px;
|
66 |
+
border-style: solid;
|
67 |
+
border-width: 1px;
|
68 |
+
font-family: "Lucida Grande",Verdana,Arial,"Bitstream Vera Sans",sans-serif;
|
69 |
+
text-decoration: none;
|
70 |
+
}
|
71 |
+
.pmxi_plugin a.add-new:hover {
|
72 |
+
border-color: #666666;
|
73 |
+
color: #000;
|
74 |
+
}
|
75 |
+
.pmxi_plugin div.input {
|
76 |
+
/*line-height: 25px;
|
77 |
+
height: 25px;*/
|
78 |
+
min-height: 21px;
|
79 |
+
}
|
80 |
+
.pmxi_plugin div.input > * {
|
81 |
+
vertical-align: middle;
|
82 |
+
}
|
83 |
+
.pmxi_plugin .options input[type=text], .pmxi_plugin .options select {
|
84 |
+
background: #fafafa !important;
|
85 |
+
border: 1px solid #aaa !important;
|
86 |
+
}
|
87 |
+
.pmxi_plugin .note {
|
88 |
+
color: #666666;
|
89 |
+
font-size: 9px;
|
90 |
+
}
|
91 |
+
.pmxi_plugin div.sub {
|
92 |
+
padding-left: 20px;
|
93 |
+
font-size: 12px;
|
94 |
+
}
|
95 |
+
/* 2 column layout */
|
96 |
+
.pmxi_plugin table.layout {
|
97 |
+
clear: both;
|
98 |
+
border-collapse: collapse;
|
99 |
+
min-width: 770px;
|
100 |
+
width: 100%;
|
101 |
+
}
|
102 |
+
.pmxi_plugin table.layout td {
|
103 |
+
vertical-align: top;
|
104 |
+
border: none;
|
105 |
+
}
|
106 |
+
.pmxi_plugin table.layout td.left {
|
107 |
+
min-width: 490px;
|
108 |
+
width: 70%;
|
109 |
+
}
|
110 |
+
.pmxi_plugin table.layout td.right {
|
111 |
+
padding: 0px 0 16px 20px;
|
112 |
+
width: 25%;
|
113 |
+
min-width: 260px;
|
114 |
+
}
|
115 |
+
.pmxi_plugin table.layout td.left > h2:first-child {
|
116 |
+
margin-top: -22px;
|
117 |
+
padding: 14px 0 3px 0;
|
118 |
+
}
|
119 |
+
.pmxi_plugin table.layout td.left hr {
|
120 |
+
clear: both;
|
121 |
+
}
|
122 |
+
.pmxi_plugin.no-js table.layout td.left > h2:first-child {
|
123 |
+
margin-top: 0px;
|
124 |
+
}
|
125 |
+
/*@*/
|
126 |
+
|
127 |
+
/*@+ Setting Form */
|
128 |
+
.pmxi_plugin form.settings {
|
129 |
+
width: 700px;
|
130 |
+
}
|
131 |
+
/*@*/
|
132 |
+
|
133 |
+
/*@+ Choose File forms */
|
134 |
+
.pmxi_plugin form.choose-file {
|
135 |
+
padding-top: 20px;
|
136 |
+
position: relative;
|
137 |
+
}
|
138 |
+
.pmxi_plugin form.choose-file h3 {
|
139 |
+
margin-bottom: 5px;
|
140 |
+
}
|
141 |
+
.pmxi_plugin form.choose-file .label {
|
142 |
+
font-size: 15px;
|
143 |
+
}
|
144 |
+
.pmxi_plugin form.choose-file input[type="text"],
|
145 |
+
.pmxi_plugin form.choose-file input[type="password"] {
|
146 |
+
width: 80px;
|
147 |
+
font-size: 12px;
|
148 |
+
}
|
149 |
+
.pmxi_plugin form.choose-file input.regular-text,
|
150 |
+
.pmxi_plugin form.choose-file select.regular-text {
|
151 |
+
width: 100%;
|
152 |
+
}
|
153 |
+
.pmxi_plugin #wpcontent form.choose-file select[name="file"],
|
154 |
+
.pmxi_plugin #wpcontent form.choose-file select[name="reimport"] {
|
155 |
+
font-size: 12px;
|
156 |
+
}
|
157 |
+
.pmxi_plugin form.choose-file input[type="submit"].button {
|
158 |
+
width: 150px;
|
159 |
+
}
|
160 |
+
.pmxi_plugin form.choose-file div.input {
|
161 |
+
margin-top: 20px;
|
162 |
+
}
|
163 |
+
/*@*/
|
164 |
+
|
165 |
+
/*@+ Choose Elements form */
|
166 |
+
.pmxi_plugin form.choose-elements input[type="text"] {
|
167 |
+
width: 100%;
|
168 |
+
max-width: 300px;
|
169 |
+
min-width: 150px;
|
170 |
+
}
|
171 |
+
/*@*/
|
172 |
+
|
173 |
+
/*@+ Template form */
|
174 |
+
.pmxi_plugin form.template.edit {
|
175 |
+
/*width: 700px;*/
|
176 |
+
}
|
177 |
+
.pmxi_plugin form.template .load-template {
|
178 |
+
display: block;
|
179 |
+
font-size: 12px;
|
180 |
+
}
|
181 |
+
.pmxi_plugin form.template .load-template select {
|
182 |
+
width: 126px;
|
183 |
+
}
|
184 |
+
|
185 |
+
.pmxi_plugin #poststuff form.template h3 {
|
186 |
+
margin: 1em 0 5px 2px;
|
187 |
+
font-size: 1.17em;
|
188 |
+
padding: 0px;
|
189 |
+
}
|
190 |
+
.pmxi_plugin #post-preview {
|
191 |
+
font-size: 12px;
|
192 |
+
}
|
193 |
+
.pmxi_plugin #post-preview .error {
|
194 |
+
margin: 5px 0;
|
195 |
+
}
|
196 |
+
.pmxi_plugin h3 .header-option {
|
197 |
+
display: block;
|
198 |
+
float: right;
|
199 |
+
font-size: 12px;
|
200 |
+
font-weight: normal;
|
201 |
+
}
|
202 |
+
/*@*/
|
203 |
+
|
204 |
+
/*@+ Options form */
|
205 |
+
.pmxi_plugin form.options.edit {
|
206 |
+
/*width: 700px;*/
|
207 |
+
}
|
208 |
+
|
209 |
+
.pmxi_plugin .post-type-container,
|
210 |
+
.pmxi_plugin .file-type-container {
|
211 |
+
padding: 4px 10px 5px;
|
212 |
+
border: 1px solid transparent;
|
213 |
+
}
|
214 |
+
.pmxi_plugin .post-type-container.selected,
|
215 |
+
.pmxi_plugin .file-type-container.selected {
|
216 |
+
background-color: #F2FBD9;
|
217 |
+
border: 1px solid #B5E61D;
|
218 |
+
padding-bottom: 10px;
|
219 |
+
}
|
220 |
+
.pmxi_plugin .post-type-container h3,
|
221 |
+
.pmxi_plugin .file-type-container h3 {
|
222 |
+
margin: 0px 0px;
|
223 |
+
}
|
224 |
+
.pmxi_plugin .post-type-container .post-type-options,
|
225 |
+
.pmxi_plugin .file-type-container .file-type-options {
|
226 |
+
margin: 5px 0 0 20px;
|
227 |
+
}
|
228 |
+
|
229 |
+
.pmxi_plugin table.form-table {
|
230 |
+
clear: none;
|
231 |
+
margin-top: 0px;
|
232 |
+
}
|
233 |
+
.pmxi_plugin .post-type-options table.form-table {
|
234 |
+
max-width: 500px;
|
235 |
+
}
|
236 |
+
.pmxi_plugin .post-type-options table.form-table td.delim {
|
237 |
+
width: 50px;
|
238 |
+
position: relative;
|
239 |
+
display: block;
|
240 |
+
}
|
241 |
+
.pmxi_plugin .post-type-options table.form-table td.delim input {
|
242 |
+
width: 20px;
|
243 |
+
}
|
244 |
+
.pmxi_plugin table.form-table.custom-params {
|
245 |
+
max-width: 700px;
|
246 |
+
}
|
247 |
+
.pmxi_plugin table.form-table td,
|
248 |
+
.pmxi_plugin table.form-table th {
|
249 |
+
padding: 2px 4px;
|
250 |
+
vertical-align: top;
|
251 |
+
}
|
252 |
+
.pmxi_plugin .post-type-options table.form-table th {
|
253 |
+
width: 100px;
|
254 |
+
}
|
255 |
+
.pmxi_plugin .post-type-options table.form-table select {
|
256 |
+
max-width: 300px;
|
257 |
+
width:300px;
|
258 |
+
}
|
259 |
+
.pmxi_plugin table.form-table thead td {
|
260 |
+
font-weight: bold;
|
261 |
+
}
|
262 |
+
.pmxi_plugin table.form-table.custom-params input {
|
263 |
+
margin-left: 0;
|
264 |
+
}
|
265 |
+
.pmxi_plugin table.form-table tr.template {
|
266 |
+
display: none;
|
267 |
+
}
|
268 |
+
/*@*/
|
269 |
+
|
270 |
+
/*@+ XML representation */
|
271 |
+
.pmxi_plugin .tag {
|
272 |
+
background-color: #fff;
|
273 |
+
position: fixed;
|
274 |
+
width:22%;
|
275 |
+
margin-top: 45px;
|
276 |
+
border-top: 1px solid #DFDFDF;
|
277 |
+
-moz-border-radius-topleft: 4px;
|
278 |
+
-webkit-border-top-left-radius: 4px;
|
279 |
+
border-top-left-radius: 4px;
|
280 |
+
-moz-border-radius-topright: 4px;
|
281 |
+
-webkit-border-top-right-radius: 4px;
|
282 |
+
border-top-right-radius: 4px;
|
283 |
+
}
|
284 |
+
|
285 |
+
.pmxi_plugin .options .tag{
|
286 |
+
margin-top: 0px;
|
287 |
+
}
|
288 |
+
.pmxi_plugin .tag .title {
|
289 |
+
font-weight: bold;
|
290 |
+
padding: 6px 8px;
|
291 |
+
color: #464646;
|
292 |
+
background: #DFDFDF;
|
293 |
+
font-size: 12px;
|
294 |
+
}
|
295 |
+
.pmxi_plugin .tag .xml {
|
296 |
+
max-height: 525px;
|
297 |
+
overflow: auto;
|
298 |
+
border: 1px solid #DFDFDF;
|
299 |
+
border-top:none;
|
300 |
+
-moz-border-radius-bottomright: 4px;
|
301 |
+
-webkit-border-bottom-right-radius: 4px;
|
302 |
+
border-bottom-right-radius: 4px;
|
303 |
+
-moz-border-radius-bottomleft: 4px;
|
304 |
+
-webkit-border-bottom-left-radius: 4px;
|
305 |
+
border-bottom-left-radius: 4px;
|
306 |
+
}
|
307 |
+
.pmxi_plugin .tag .navigation {
|
308 |
+
float: right;
|
309 |
+
margin: -2px -12px 0 0;
|
310 |
+
}
|
311 |
+
.pmxi_plugin .tag .navigation a,
|
312 |
+
.pmxi_plugin .tag .navigation span {
|
313 |
+
font-weight: bold;
|
314 |
+
padding: 0 12px;
|
315 |
+
text-decoration: none;
|
316 |
+
}
|
317 |
+
|
318 |
+
@media screen and (max-height: 700px) {
|
319 |
+
.pmxi_plugin .tag {
|
320 |
+
height:300px;
|
321 |
+
}
|
322 |
+
.pmxi_plugin .tag .xml {
|
323 |
+
max-height: 265px;
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
.xml {
|
328 |
+
padding-left: 15px;
|
329 |
+
}
|
330 |
+
.xml-element {
|
331 |
+
border: 1px solid transparent;
|
332 |
+
margin: 1px 1px 1px 0;
|
333 |
+
}
|
334 |
+
.xml-element.selected > .xml-tag.opening .xml-tag-name {
|
335 |
+
background-color: #B5E61D;
|
336 |
+
}
|
337 |
+
.xml-content {
|
338 |
+
padding-left: 14px;
|
339 |
+
}
|
340 |
+
.xml-content.collapsed {
|
341 |
+
display: none;
|
342 |
+
}
|
343 |
+
.xml-content.textonly.short {
|
344 |
+
padding-left: 0px;
|
345 |
+
display: inline;
|
346 |
+
}
|
347 |
+
.xml-tag {
|
348 |
+
display: inline;
|
349 |
+
}
|
350 |
+
.xml-tag-name {
|
351 |
+
color: #906;
|
352 |
+
font-weight: bold;
|
353 |
+
}
|
354 |
+
.xml-tag.opening .xml-tag-name {
|
355 |
+
cursor: pointer;
|
356 |
+
}
|
357 |
+
.xml-attr-name {
|
358 |
+
font-weight: bold;
|
359 |
+
cursor: pointer;
|
360 |
+
}
|
361 |
+
.xml-attr-value {
|
362 |
+
color: blue;
|
363 |
+
}
|
364 |
+
.xml-expander {
|
365 |
+
display: inline-block;
|
366 |
+
width: 12px;
|
367 |
+
margin-left: -12px;
|
368 |
+
-moz-user-select: none;
|
369 |
+
-khtml-user-select: none;
|
370 |
+
-webkit-user-select: none;
|
371 |
+
user-select: none;
|
372 |
+
cursor: pointer;
|
373 |
+
font-family: monospace;
|
374 |
+
line-height: 100%;
|
375 |
+
text-align: left;
|
376 |
+
color: red;
|
377 |
+
}
|
378 |
+
.xml-more {
|
379 |
+
color: red;
|
380 |
+
font-size: 80%;
|
381 |
+
}
|
382 |
+
.xml.resetable .xml-element.lvl-mod4-3 > .xml-content {
|
383 |
+
margin-left: -59px;
|
384 |
+
margin-right: -8px;
|
385 |
+
background-color: #fff;
|
386 |
+
border: 1px dashed #906;
|
387 |
+
border-left: 2px solid #906;
|
388 |
+
border-right: none;
|
389 |
+
}
|
390 |
+
.xml.resetable .xml-element.lvl-mod4-3 > .xml-content.short {
|
391 |
+
margin-left: 0;
|
392 |
+
margin-right: 0;
|
393 |
+
border: none;
|
394 |
+
background-color: inherit;
|
395 |
+
}
|
396 |
+
/* xml table representation */
|
397 |
+
tr.xml-element.selected .xml-tag.opening .xml-tag-name {
|
398 |
+
background-color: #B5E61D;
|
399 |
+
}
|
400 |
+
table.xml td {
|
401 |
+
padding-left: 20px;
|
402 |
+
}
|
403 |
+
table.xml td:first-child {
|
404 |
+
width: 1px;
|
405 |
+
padding-left: 0px;
|
406 |
+
}
|
407 |
+
|
408 |
+
table.xml,
|
409 |
+
table.xml table {
|
410 |
+
width: 100%;
|
411 |
+
border-collapse:collapse;
|
412 |
+
border-spacing:0;
|
413 |
+
}
|
414 |
+
/*@*/
|
415 |
+
|
416 |
+
/*@+ table list */
|
417 |
+
.pmxi_plugin table.widefat th {
|
418 |
+
white-space: nowrap;
|
419 |
+
}
|
420 |
+
.pmxi_plugin table.widefat th.ASC a {
|
421 |
+
background-image: url("../img/screen-options-right-up.gif");
|
422 |
+
background-repeat: no-repeat;
|
423 |
+
background-position: right center;
|
424 |
+
padding-right: 19px;
|
425 |
+
}
|
426 |
+
.pmxi_plugin table.widefat th.DESC a {
|
427 |
+
background-image: url("../img/screen-options-right.gif");
|
428 |
+
background-repeat: no-repeat;
|
429 |
+
background-position: right center;
|
430 |
+
padding-right: 19px;
|
431 |
+
}
|
432 |
+
|
433 |
+
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-id {
|
434 |
+
width: 35px;
|
435 |
+
}
|
436 |
+
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-scheduled {
|
437 |
+
width: 85px;
|
438 |
+
}
|
439 |
+
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-registered_on {
|
440 |
+
width: 130px;
|
441 |
+
}
|
442 |
+
.pmxi_plugin table.widefat.pmxi-admin-imports th.column-post_count {
|
443 |
+
width: 105px;
|
444 |
+
}
|
445 |
+
/*@*/
|
446 |
+
|
447 |
+
/*@+ fixes */
|
448 |
+
.pmxi_plugin input[type="file"] {
|
449 |
+
padding: 0; /* FIX height or <input type="file" /> for Safari & Chrome */
|
450 |
+
}
|
451 |
+
.pmxi_plugin .ui-widget-overlay {
|
452 |
+
position: fixed !important; /* FIX: modal dialog overlay in IE 8 */
|
453 |
+
background-color: #aaa !important; /* FIX: overlay color */
|
454 |
+
}
|
455 |
+
.pmxi_plugin .ui-dialog {
|
456 |
+
position: absolute !important; /* FIX: for wordpress 3.1 not to add empty space */
|
457 |
+
}
|
458 |
+
.pmxi_plugin .ui-autocomplete {
|
459 |
+
position: absolute;
|
460 |
+
border-color: #ccc #444 #444 #aaa;
|
461 |
+
cursor: default;
|
462 |
+
-moz-border-radius: 0;
|
463 |
+
border-radius: 0;
|
464 |
+
max-height: 200px;
|
465 |
+
max-width: 700px;
|
466 |
+
overflow-y: auto;
|
467 |
+
overflow-x: hidden;
|
468 |
+
white-space: nowrap;
|
469 |
+
font-size: 11px;
|
470 |
+
}
|
471 |
+
.pmxi_plugin .ui-autocomplete .ui-menu-item {
|
472 |
+
padding: 0;
|
473 |
+
margin: 0;
|
474 |
+
}
|
475 |
+
.pmxi_plugin .ui-autocomplete .ui-menu-item a {
|
476 |
+
display: block;
|
477 |
+
padding: 2px;
|
478 |
+
padding-right: 20px; /* space for scroll bar */
|
479 |
+
font-size: 11px;
|
480 |
+
border: none;
|
481 |
+
-moz-border-radius: 0;
|
482 |
+
border-radius: 0;
|
483 |
+
}
|
484 |
+
.pmxi_plugin .ui-autocomplete .ui-menu-item a.ui-state-hover {
|
485 |
+
background: #39f;
|
486 |
+
color: #fff;
|
487 |
+
}
|
488 |
+
.pmxi_plugin input.autocomplete {
|
489 |
+
background: url("../img/down.gif") no-repeat right top #fff;
|
490 |
+
padding-right: 20px;
|
491 |
+
cursor: default;
|
492 |
+
font-size: 11px !important;
|
493 |
+
}
|
494 |
+
/*@*/
|
495 |
+
|
496 |
+
.pmxi_plugin .taglines{
|
497 |
+
font-size:13px;
|
498 |
+
font-style: italic;
|
499 |
+
display: block;
|
500 |
+
color: #777;
|
501 |
+
}
|
502 |
+
|
503 |
+
.pmxi_plugin #process{ display:none; }
|
504 |
+
.pmxi_plugin .load-options{ float:right; font-size:13px; position: relative; top: -30px; }
|
505 |
+
.pmxi_plugin form.options table.layout td.right{
|
506 |
+
width: 25%;
|
507 |
+
}
|
508 |
+
.pmxi_plugin .drag-element{
|
509 |
+
background: url("../img/drag.png") top right no-repeat;
|
510 |
+
cursor: pointer;
|
511 |
+
padding-left: 25px;
|
512 |
+
background-position: 0px 1px;
|
513 |
+
}
|
514 |
+
.sortable li{ position: relative;}
|
515 |
+
.pmxi_plugin ol{
|
516 |
+
margin-top: 6px;
|
517 |
+
list-style: none;
|
518 |
+
}
|
519 |
+
.pmxi_plugin .no-margin{ margin:0px; }
|
520 |
+
.pmxi_plugin .icon-item, .pmxi_plugin .add-new-custom{
|
521 |
+
display: inline-block;
|
522 |
+
width: 16px;
|
523 |
+
height: 16px;
|
524 |
+
margin: 0px 3px;
|
525 |
+
}
|
526 |
+
.pmxi_plugin .add-new-ico, .pmxi_plugin .add-new-custom{
|
527 |
+
background: url("../img/ico-add-new.png") no-repeat 0px 4px;
|
528 |
+
width:70px;
|
529 |
+
height:25px;
|
530 |
+
padding-left: 15px;
|
531 |
+
color:#21759B;
|
532 |
+
}
|
533 |
+
|
534 |
+
.pmxi_plugin .remove-ico{
|
535 |
+
background: url("../img/ico-remove.png") no-repeat;
|
536 |
+
top:1px;
|
537 |
+
right:-8px;
|
538 |
+
position: absolute;
|
539 |
+
}
|
540 |
+
|
541 |
+
.pmxi_plugin .hidden{ display: none; }
|
542 |
+
|
543 |
+
.pmxi_plugin .fs11 { font-size:11px; }
|
544 |
+
|
545 |
+
.pmxi_plugin .rel { position: relative; }
|
546 |
+
|
547 |
+
#type_meta_select{ margin-bottom: 10px; height:1.8em; }
|
548 |
+
|
549 |
+
.upload_process{
|
550 |
+
border: none;
|
551 |
+
padding: 1px;
|
552 |
+
}
|
553 |
+
|
554 |
+
#large_import_xpath{ display:none; }
|
555 |
+
#large_import{ margin:0px 5px; }
|
556 |
+
#download_pmxi_log{
|
557 |
+
cursor: pointer;
|
558 |
+
margin: 5px 0;
|
559 |
+
display: none;
|
560 |
+
}
|
561 |
+
.pmxi_plugin .import_process_bar, .pmxi_plugin .import_percent{
|
562 |
+
display: none;
|
563 |
+
}
|
564 |
+
/*.pmxi_plugin .import_progress{
|
565 |
+
font-size: 14px !important;
|
566 |
+
}*/
|
567 |
+
.pmxi_plugin #processbar{
|
568 |
+
text-align: center;
|
569 |
+
visibility: hidden;
|
570 |
+
height: 37px;
|
571 |
+
padding-top: 18px;
|
572 |
+
margin-bottom: 20px;
|
573 |
+
border: 1px solid #AAAAAA;
|
574 |
+
color: #222222;
|
575 |
+
position: relative;
|
576 |
+
}
|
577 |
+
.pmxi_plugin #processbar div{
|
578 |
+
background: #aaa;
|
579 |
+
height: 55px;
|
580 |
+
width: 0%;
|
581 |
+
position: absolute;
|
582 |
+
opacity: 0.5;
|
583 |
+
top:0;
|
584 |
+
}
|
585 |
+
.pmxi_plugin #import_progress{
|
586 |
+
color: #000000;
|
587 |
+
font-size: 13px;
|
588 |
+
font-weight: bold;
|
589 |
+
opacity: 1;
|
590 |
+
}
|
591 |
+
.pmxi_plugin #right_progress{ float:right; padding-right: 5px; }
|
592 |
+
.pmxi_plugin #left_progress{ float:left; padding-left: 5px; }
|
593 |
+
.pmxi_plugin #existing_meta_keys{
|
594 |
+
margin-bottom: 10px;
|
595 |
+
padding: 2px;
|
596 |
+
width: 580px;
|
597 |
+
}
|
598 |
+
.pmxi_plugin #pmxi_tabs{
|
599 |
+
display: none;
|
600 |
+
padding-bottom: 20px;
|
601 |
+
-moz-border-radius: 4px;
|
602 |
+
-khtml-border-radius: 4px;
|
603 |
+
-webkit-border-radius: 4px;
|
604 |
+
border-radius: 4px;
|
605 |
+
}
|
606 |
+
.pmxi_plugin .ui-widget-header{
|
607 |
+
-moz-border-radius: 4px;
|
608 |
+
-khtml-border-radius: 4px;
|
609 |
+
-webkit-border-radius: 4px;
|
610 |
+
border-radius: 4px;
|
611 |
+
}
|
612 |
+
.pmxi_plugin .ui-tabs .ui-tabs-nav li{
|
613 |
+
-moz-border-top-left-radius: 4px;
|
614 |
+
-khtml-border-top-left-radius: 4px;
|
615 |
+
-webkit-border-top-left-radius: 4px;
|
616 |
+
border-top-left-radius: 4px;
|
617 |
+
-moz-border-top-right-radius: 4px;
|
618 |
+
-khtml-border-top-right-radius: 4px;
|
619 |
+
-webkit-border-top-right-radius: 4px;
|
620 |
+
border-top-right-radius: 4px;
|
621 |
+
}
|
622 |
+
/*.pmxi_plugin .ui-widget-header{
|
623 |
+
background: #F2FBD9;
|
624 |
+
border: 1px solid #F2FBD9;
|
625 |
+
}
|
626 |
+
.pmxi_plugin .ui-state-default{
|
627 |
+
border:none;
|
628 |
+
font-size: 12px;
|
629 |
+
font-weight: bold;
|
630 |
+
background: #F2FBD9;
|
631 |
+
}
|
632 |
+
.pmxi_plugin .ui-state-active{
|
633 |
+
background: #fff;
|
634 |
+
}
|
635 |
+
.pmxi_plugin .ui-tabs{
|
636 |
+
padding: 0px;
|
637 |
+
}*/
|
638 |
+
#select-files{
|
639 |
+
font-size: 11px !important;
|
640 |
+
height:25px;
|
641 |
+
}
|
642 |
+
.pmxi_plugin .progress{
|
643 |
+
position: relative;
|
644 |
+
visibility: hidden;
|
645 |
+
color: #009039;
|
646 |
+
font-size: 13px;
|
647 |
+
font-weight: bold;
|
648 |
+
margin-top: 10px;
|
649 |
+
width: 100%;
|
650 |
+
text-align: center;
|
651 |
+
border:1px solid #4297D7;
|
652 |
+
-moz-border-radius: 4px;
|
653 |
+
-khtml-border-radius: 4px;
|
654 |
+
-webkit-border-radius: 4px;
|
655 |
+
border-radius: 4px;
|
656 |
+
}
|
657 |
+
.pmxi_plugin #progressbar{
|
658 |
+
border: medium none;
|
659 |
+
left: 0;
|
660 |
+
position: absolute;
|
661 |
+
text-align: center;
|
662 |
+
top: 8px;
|
663 |
+
width: 100%;
|
664 |
+
font-size: 12px;
|
665 |
+
color:#333;
|
666 |
+
}
|
667 |
+
.pmxi_plugin #file_name{
|
668 |
+
font-size: 16px;
|
669 |
+
font-weight: bold;
|
670 |
+
margin-left: 10px;
|
671 |
+
float: right;
|
672 |
+
}
|
673 |
+
.pmxi_plugin .ui-progressbar .ui-progressbar-value { /*background-image: url("../img/progress_animated.gif");*/ }
|
674 |
+
.pmxi_plugin form.choose-file .submit-buttons{
|
675 |
+
/*bottom: -125px;
|
676 |
+
position: absolute;
|
677 |
+
right: -18px; */
|
678 |
+
}
|
679 |
+
.pmxi_plugin form#basic .submit-buttons{
|
680 |
+
display: none;
|
681 |
+
}
|
682 |
+
.pmxi_plugin fieldset{
|
683 |
+
padding: 20px;
|
684 |
+
width:auto;
|
685 |
+
}
|
686 |
+
.pmxi_plugin .right fieldset{
|
687 |
+
padding: 15px;
|
688 |
+
}
|
689 |
+
.pmxi_plugin .right fieldset input{
|
690 |
+
max-width:none;
|
691 |
+
padding:6px;
|
692 |
+
margin:0px
|
693 |
+
}
|
694 |
+
.pmxi_plugin .right a{
|
695 |
+
text-decoration: underline;
|
696 |
+
}
|
697 |
+
.pmxi_plugin fieldset legend{
|
698 |
+
padding: 0px 5px;
|
699 |
+
font-weight: bold;
|
700 |
+
}
|
701 |
+
.pmxi_plugin .options fieldset legend{
|
702 |
+
font-size: 1.17em;
|
703 |
+
}
|
704 |
+
.pmxi_plugin .matches_count{
|
705 |
+
font-weight: bold;
|
706 |
+
color:#33AA28;
|
707 |
+
}
|
708 |
+
.pmxi_plugin .xpath_help{
|
709 |
+
/*bottom: -40px;*/
|
710 |
+
position: relative;
|
711 |
+
text-align: center;
|
712 |
+
}
|
713 |
+
.pmxi_plugin .btns, .pmxi_plugin .btns input, .pmxi_plugin .btns a{
|
714 |
+
float: right;
|
715 |
+
}
|
716 |
+
.pmxi_plugin .btns input{
|
717 |
+
height: 19px;
|
718 |
+
margin-left: 5px;
|
719 |
+
padding-top: 0;
|
720 |
+
}
|
721 |
+
.pmxi_plugin .btns a{
|
722 |
+
font-weight: bold;
|
723 |
+
margin: 0 5px;
|
724 |
+
padding: 4px 10px;
|
725 |
+
width:70px;
|
726 |
+
text-align: center;
|
727 |
+
}
|
728 |
+
.pmxi_plugin .col3{
|
729 |
+
border-right: 1px solid #CCCCCC;
|
730 |
+
float: left;
|
731 |
+
height: 265px;
|
732 |
+
width:30%;
|
733 |
+
margin-bottom: 10px;
|
734 |
+
padding: 0 1%;
|
735 |
+
}
|
736 |
+
.pmxi_plugin .col3.last{
|
737 |
+
border: none;
|
738 |
+
}
|
739 |
+
.pmxi_plugin .col3 > div{
|
740 |
+
margin-left: 20px;
|
741 |
+
}
|
742 |
+
.pmxi_plugin .col2{
|
743 |
+
float: left;
|
744 |
+
width: 50%;
|
745 |
+
}
|
746 |
+
.pmxi_plugin .col2 fieldset{
|
747 |
+
border: 1px solid #CCCCCC;
|
748 |
+
margin: 0 5px;
|
749 |
+
padding: 5px 2% 5px 5px;
|
750 |
+
text-align: center;
|
751 |
+
}
|
752 |
+
.pmxi_plugin input.small{
|
753 |
+
width:25px;
|
754 |
+
text-align: center;
|
755 |
+
}
|
756 |
+
.pmxi_plugin .post_taxonomy{
|
757 |
+
margin-bottom: 15px;
|
758 |
+
/*overflow: hidden;*/
|
759 |
+
padding-bottom: 15px;
|
760 |
+
}
|
761 |
+
.pmxi_plugin .post_taxonomy .delim{
|
762 |
+
padding-left: 25px;
|
763 |
+
}
|
764 |
+
.pmxi_plugin .post_taxonomy .delim .add-new-ico{
|
765 |
+
float: right;
|
766 |
+
margin-right: 10%;
|
767 |
+
margin-top: 5px;
|
768 |
+
}
|
769 |
+
.pmxi_plugin .post_taxonomy ol.ui-sortable{
|
770 |
+
padding-right: 0px;
|
771 |
+
}
|
772 |
+
.pmxi_plugin .optionsset{
|
773 |
+
border:1px solid #ccc;
|
774 |
+
}
|
775 |
+
.pmxi_plugin .action.remove{
|
776 |
+
display: block;
|
777 |
+
position: relative;
|
778 |
+
}
|
779 |
+
.pmxi_plugin .action.remove a{
|
780 |
+
background: url("../img/ico-remove.png") no-repeat scroll 0 0 transparent;
|
781 |
+
height: 16px;
|
782 |
+
position: absolute;
|
783 |
+
right: 20px;
|
784 |
+
width: 16px;
|
785 |
+
}
|
786 |
+
.pmxi_plugin .switcher-target-is_keep_former_posts{
|
787 |
+
padding-left: 25px;
|
788 |
+
}
|
789 |
+
.pmxi_plugin form.options{
|
790 |
+
position: relative;
|
791 |
+
}
|
792 |
+
.pmxi_plugin .options_buttons{
|
793 |
+
bottom: -75px;
|
794 |
+
display: block;
|
795 |
+
position: absolute;
|
796 |
+
right: 0;
|
797 |
+
}
|
798 |
+
.pmxi-button{
|
799 |
+
border: 1px solid #BBBBBB;
|
800 |
+
color: #464646;
|
801 |
+
cursor: pointer;
|
802 |
+
font-size: 18px !important;
|
803 |
+
margin-left: 10px;
|
804 |
+
padding: 15px 25px;
|
805 |
+
text-decoration: none;
|
806 |
+
-moz-border-radius: 3px;
|
807 |
+
-khtml-border-radius: 3px;
|
808 |
+
-webkit-border-radius: 3px;
|
809 |
+
border-radius: 3px;
|
810 |
+
}
|
811 |
+
.pmxi-button:hover{
|
812 |
+
background: #dfdfdf;
|
813 |
+
}
|
814 |
+
.pmxi_plugin .ui-state-default a{
|
815 |
+
font-size: 13px !important;
|
816 |
+
}
|
817 |
+
.pmxi_plugin .preview{
|
818 |
+
float:none;
|
819 |
+
text-decoration: none;
|
820 |
+
}
|
821 |
+
.pmxi_plugin .template-sidebar .tag{
|
822 |
+
max-height:550px;
|
823 |
+
}
|
824 |
+
.pmxi_plugin .options .submit-buttons{
|
825 |
+
float: right;
|
826 |
+
position: relative;
|
827 |
+
text-align: right;
|
828 |
+
top: 30px;
|
829 |
+
right:-18px;
|
830 |
+
}
|
831 |
+
.pmxi_plugin .back{
|
832 |
+
font-size: 16px;
|
833 |
+
color:#21759B;
|
834 |
+
}
|
835 |
+
.pmxi_plugin .separated_by{
|
836 |
+
float: right;
|
837 |
+
font-size: 12px;
|
838 |
+
color: #999999;
|
839 |
+
margin-right: 20px;
|
840 |
+
}
|
841 |
+
.pmxi_plugin .delim > label{
|
842 |
+
color: #999999;
|
843 |
+
font-size: 11px;
|
844 |
+
}
|
845 |
+
.pmxi_plugin .optionsset > table{
|
846 |
+
border-bottom: 1px solid #CCCCCC;
|
847 |
+
margin-bottom: 20px;
|
848 |
+
width: 100%;
|
849 |
+
}
|
850 |
+
/* Log Bar - Step 5 */
|
851 |
+
.pmxi_plugin #logwrapper{
|
852 |
+
border: 1px solid #aaa;
|
853 |
+
margin-bottom: 20px;
|
854 |
+
}
|
855 |
+
.pmxi_plugin #logbar{
|
856 |
+
padding: 5px 0px;
|
857 |
+
text-align: center;
|
858 |
+
margin: 10px 0px;
|
859 |
+
border: 1px solid #aaa;
|
860 |
+
overflow: auto;
|
861 |
+
}
|
862 |
+
.pmxi_plugin .optionsset > table:last-child{
|
863 |
+
border: none;
|
864 |
+
}
|
865 |
+
.pmxi_plugin #download_log_separator, .pmxi_plugin #download_log{
|
866 |
+
display: none;
|
867 |
+
}
|
868 |
+
.pmxi_plugin #loglist{
|
869 |
+
border: 1px solid #AAAAAA;
|
870 |
+
height: 400px;
|
871 |
+
overflow: auto;
|
872 |
+
}
|
873 |
+
.pmxi_plugin #loglist > p{
|
874 |
+
margin: 0;
|
875 |
+
padding: 3px 5px;
|
876 |
+
}
|
877 |
+
.pmxi_plugin #loglist > p.odd{
|
878 |
+
background: #dfdfdf;
|
879 |
+
}
|
880 |
+
.pmxi_plugin #process_notice{
|
881 |
+
color: red;
|
882 |
+
text-align: center;
|
883 |
+
}
|
884 |
+
.pmxi_plugin #reimported_notify{
|
885 |
+
border: 1px solid #AFAFAF;
|
886 |
+
margin-bottom: 20px;
|
887 |
+
padding: 10px 20px;
|
888 |
+
}
|
889 |
+
.pmxi_plugin #reimported_notify p span{
|
890 |
+
color:#ccc;
|
891 |
+
}
|
892 |
+
.pmxi_plugin .action_buttons{
|
893 |
+
overflow: hidden;
|
894 |
+
clear: both;
|
895 |
+
padding-bottom: 10px;
|
896 |
+
}
|
897 |
+
/*.pmxi_plugin .action_buttons a{
|
898 |
+
border: 1px solid #BBBBBB;
|
899 |
+
-moz-border-radius: 3px;
|
900 |
+
-khtml-border-radius: 3px;
|
901 |
+
-webkit-border-radius: 3px;
|
902 |
+
border-radius: 3px;
|
903 |
+
color: #464646;
|
904 |
+
cursor: pointer;
|
905 |
+
font-size: 18px !important;
|
906 |
+
margin-right: 10px;
|
907 |
+
padding: 15px 25px;
|
908 |
+
text-decoration: none;
|
909 |
+
display: block;
|
910 |
+
width:25px;
|
911 |
+
float: left;
|
912 |
+
}
|
913 |
+
.pmxi_plugin .action_buttons a:hover{
|
914 |
+
background: #dfdfdf;
|
915 |
+
}*/
|
916 |
+
.pmxi_plugin #current_element{
|
917 |
+
color:green;
|
918 |
+
}
|
919 |
+
.pmxi_plugin #current_xml{ display: none;}
|
920 |
+
.pmxi_plugin #goto_element{
|
921 |
+
display: block;
|
922 |
+
float: left;
|
923 |
+
height: 47px;
|
924 |
+
margin-right: 10px;
|
925 |
+
width: 70px !important;
|
926 |
+
min-width: 70px;
|
927 |
+
text-align: center;
|
928 |
+
font-size: 18px;
|
929 |
+
}
|
930 |
+
.pmxi_plugin .choose-elements table tbody tr td{
|
931 |
+
overflow: hidden;
|
932 |
+
}
|
933 |
+
.pmxi_plugin #plupload-ui h3{
|
934 |
+
float: left;
|
935 |
+
font-size: 13px;
|
936 |
+
font-weight: normal;
|
937 |
+
margin-bottom: 0;
|
938 |
+
margin-top: 8px;
|
939 |
+
}
|
940 |
+
.pmxi_plugin #wp-content-media-buttons{
|
941 |
+
display: none;
|
942 |
+
}
|
943 |
+
.pmxi_plugin label{
|
944 |
+
-webkit-touch-callout: none;
|
945 |
+
-webkit-user-select: none;
|
946 |
+
-khtml-user-select: none;
|
947 |
+
-moz-user-select: none;
|
948 |
+
-ms-user-select: none;
|
949 |
+
user-select: none;
|
950 |
+
}
|
951 |
+
.pmxi_plugin .large_button{
|
952 |
+
margin-left: 10px;
|
953 |
+
padding: 15px 25px;
|
954 |
+
border: 1px solid #C5DBEC;
|
955 |
+
}
|
956 |
+
.pmxi_plugin .drag-element .assign_post{
|
957 |
+
float: left;
|
958 |
+
}
|
959 |
+
.pmxi_plugin .drag-element .widefat{
|
960 |
+
margin-left: 1%;
|
961 |
+
width: 85%;
|
962 |
+
}
|
963 |
+
.pmxi_plugin .upgrade_link{
|
964 |
+
color: #21759B;
|
965 |
+
}
|
966 |
+
.pmxi_stars{
|
967 |
+
display: inline-block;
|
968 |
+
background: url("../img/stars.png") no-repeat;
|
969 |
+
width: 125px;
|
970 |
+
height: 24px;
|
971 |
+
position: relative;
|
972 |
+
top:10px;
|
973 |
+
}
|
974 |
+
.updated_bottom{
|
975 |
+
background-color: #FFFFE0;
|
976 |
+
border-color: #E6DB55;
|
977 |
+
margin: 5px 0 15px;
|
978 |
+
padding: 0 0.6em;
|
979 |
+
-moz-border-radius: 3px 3px 3px 3px;
|
980 |
+
border-radius: 3px;
|
981 |
+
border-style: solid;
|
982 |
+
border-width: 1px;
|
983 |
+
}
|
984 |
+
.pmxi_plugin .load_options{
|
985 |
+
height: 0;
|
986 |
+
line-height: 0;
|
987 |
+
margin: 0;
|
988 |
+
padding: 0;
|
989 |
+
position: relative;
|
990 |
+
right: 10px;
|
991 |
+
text-align: right;
|
992 |
+
top: -35px;
|
993 |
+
width: 100%;
|
994 |
+
}
|
995 |
+
.form-field textarea{
|
996 |
+
width:80%;
|
997 |
}
|
static/js/admin.js
CHANGED
@@ -1,550 +1,561 @@
|
|
1 |
-
/**
|
2 |
-
* plugin admin area javascript
|
3 |
-
*/
|
4 |
-
(function($){$(function () {
|
5 |
-
if ( ! $('body.pmxi_plugin').length) return; // do not execute any code if we are not on plugin page
|
6 |
-
|
7 |
-
// fix layout position
|
8 |
-
setTimeout(function () {
|
9 |
-
$('table.layout').length && $('table.layout td.left h2:first-child').css('margin-top', $('.wrap').offset().top - $('table.layout').offset().top);
|
10 |
-
}, 10);
|
11 |
-
|
12 |
-
// help icons
|
13 |
-
$('a.help').tipsy({
|
14 |
-
gravity: function() {
|
15 |
-
var ver = 'n';
|
16 |
-
if ($(document).scrollTop() < $(this).offset().top - $('.tipsy').height() - 2) {
|
17 |
-
ver = 's';
|
18 |
-
}
|
19 |
-
var hor = '';
|
20 |
-
if ($(this).offset().left + $('.tipsy').width() < $(window).width() + $(document).scrollLeft()) {
|
21 |
-
hor = 'w';
|
22 |
-
} else if ($(this).offset().left - $('.tipsy').width() > $(document).scrollLeft()) {
|
23 |
-
hor = 'e';
|
24 |
-
}
|
25 |
-
return ver + hor;
|
26 |
-
},
|
27 |
-
live: true,
|
28 |
-
html: true,
|
29 |
-
opacity: 1
|
30 |
-
}).live('click', function () {
|
31 |
-
return false;
|
32 |
-
}).each(function () { // fix tipsy title for IE
|
33 |
-
$(this).attr('original-title', $(this).attr('title'));
|
34 |
-
$(this).removeAttr('title');
|
35 |
-
});
|
36 |
-
|
37 |
-
// swither show/hide logic
|
38 |
-
$('input.switcher').change(function (e) {
|
39 |
-
if ($(this).is(':radio:checked')) {
|
40 |
-
$(this).parents('form').find('input.switcher:radio[name="' + $(this).attr('name') + '"]').not(this).change();
|
41 |
-
}
|
42 |
-
var $targets = $('.switcher-target-' + $(this).attr('id'));
|
43 |
-
var is_show = $(this).is(':checked'); if ($(this).is('.switcher-reversed')) is_show = ! is_show;
|
44 |
-
if (is_show) {
|
45 |
-
$targets.fadeIn();
|
46 |
-
} else {
|
47 |
-
$targets.hide().find('.clear-on-switch').add($targets.filter('.clear-on-switch')).val('');
|
48 |
-
}
|
49 |
-
}).change();
|
50 |
-
|
51 |
-
// autoselect input content on click
|
52 |
-
$('input.selectable').live('click', function () {
|
53 |
-
$(this).select();
|
54 |
-
});
|
55 |
-
|
56 |
-
// input tags with title
|
57 |
-
$('input[title]').each(function () {
|
58 |
-
var $this = $(this);
|
59 |
-
$this.bind('focus', function () {
|
60 |
-
if ('' == $(this).val() || $(this).val() == $(this).attr('title')) {
|
61 |
-
$(this).removeClass('note').val('');
|
62 |
-
}
|
63 |
-
}).bind('blur', function () {
|
64 |
-
if ('' == $(this).val() || $(this).val() == $(this).attr('title')) {
|
65 |
-
$(this).addClass('note').val($(this).attr('title'));
|
66 |
-
}
|
67 |
-
}).blur();
|
68 |
-
$this.parents('form').bind('submit', function () {
|
69 |
-
if ($this.val() == $this.attr('title')) {
|
70 |
-
$this.val('');
|
71 |
-
}
|
72 |
-
});
|
73 |
-
});
|
74 |
-
|
75 |
-
// datepicker
|
76 |
-
$('input.datepicker').datepicker({
|
77 |
-
dateFormat: 'yy-mm-dd',
|
78 |
-
showOn: 'button',
|
79 |
-
buttonText: '',
|
80 |
-
constrainInput: false,
|
81 |
-
showAnim: 'fadeIn',
|
82 |
-
showOptions: 'fast'
|
83 |
-
}).bind('change', function () {
|
84 |
-
var selectedDate = $(this).val();
|
85 |
-
var instance = $(this).data('datepicker');
|
86 |
-
var date = null;
|
87 |
-
if ('' != selectedDate) {
|
88 |
-
try {
|
89 |
-
date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
|
90 |
-
} catch (e) {
|
91 |
-
date = null;
|
92 |
-
}
|
93 |
-
}
|
94 |
-
if ($(this).hasClass('range-from')) {
|
95 |
-
$(this).parent().find('.datepicker.range-to').datepicker("option", "minDate", date);
|
96 |
-
}
|
97 |
-
if ($(this).hasClass('range-to')) {
|
98 |
-
$(this).parent().find('.datepicker.range-from').datepicker("option", "maxDate", date);
|
99 |
-
}
|
100 |
-
}).change();
|
101 |
-
$('.ui-datepicker').hide(); // fix: make sure datepicker doesn't break wordpress layout upon initialization
|
102 |
-
|
103 |
-
// no-enter-submit forms
|
104 |
-
$('form.no-enter-submit').find('input,select,textarea').not('*[type="submit"]').keydown(function (e) {
|
105 |
-
if (13 == e.keyCode) e.preventDefault();
|
106 |
-
});
|
107 |
-
|
108 |
-
// choose file form: option selection dynamic
|
109 |
-
// options form: highlight options of selected post type
|
110 |
-
$('form.choose-file input[name="type"]').click(function() {
|
111 |
-
if ($(this).val() == 'upload' || $(this).val() == 'file' || $(this).val() == 'reimport' || $(this).val() == 'url') $('#large_import').slideDown(); else { $('#large_import').slideUp(); $('#large_import_toggle').removeAttr('checked'); $('#large_import_xpath').slideUp();}
|
112 |
-
var $container = $(this).parents('.file-type-container');
|
113 |
-
$('.file-type-container').not($container).removeClass('selected').find('.file-type-options').hide();
|
114 |
-
$container.addClass('selected').find('.file-type-options').show();
|
115 |
-
}).filter(':checked').click();
|
116 |
-
|
117 |
-
// template form: auto submit when `load template` list value is picked
|
118 |
-
$('form.template').find('select[name="load_template"]').change(function () {
|
119 |
-
$(this).parents('form').submit();
|
120 |
-
});
|
121 |
-
// template form: preview button
|
122 |
-
$('form.template').each(function () {
|
123 |
-
var $form = $(this);
|
124 |
-
var $modal = $('<div></div>').dialog({
|
125 |
-
autoOpen: false,
|
126 |
-
modal: true,
|
127 |
-
title: 'Preview Post',
|
128 |
-
width: 760,
|
129 |
-
maxHeight: 600,
|
130 |
-
open: function(event, ui) {
|
131 |
-
$(this).dialog('option', 'height', 'auto').css({'max-height': $(this).dialog('option', 'maxHeight') - $(this).prev().height() - 24, 'overflow-y': 'auto'});
|
132 |
-
}
|
133 |
-
});
|
134 |
-
$form.find('.preview').click(function () {
|
135 |
-
$modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
|
136 |
-
tinyMCE.triggerSave(false, false);
|
137 |
-
$.post('admin.php?page=pmxi-admin-import&action=preview', $form.serialize(), function (response) {
|
138 |
-
$modal.removeClass('loading').html(response).dialog('option', 'position', 'center');
|
139 |
-
});
|
140 |
-
return false;
|
141 |
-
});
|
142 |
-
});
|
143 |
-
|
144 |
-
// options form: highlight options of selected post type
|
145 |
-
$('form.options input[name="type"]').click(function() {
|
146 |
-
var $container = $(this).parents('.post-type-container');
|
147 |
-
$('.post-type-container').not($container).removeClass('selected').find('.post-type-options').hide();
|
148 |
-
$container.addClass('selected').find('.post-type-options').show();
|
149 |
-
}).filter(':checked').click();
|
150 |
-
// options form: add / remove custom params
|
151 |
-
$('.form-table a.action[href="#add"]').live('click', function () {
|
152 |
-
var $template = $(this).parents('table').first().find('tr.template');
|
153 |
-
$template.clone(true).insertBefore($template).css('display', 'none').removeClass('template').fadeIn();
|
154 |
-
return false;
|
155 |
-
});
|
156 |
-
// options form: auto submit when `load options` checkbox is checked
|
157 |
-
$('input[name="load_options"]').click(function () {
|
158 |
-
if ($(this).is(':checked')) $(this).parents('form').submit();
|
159 |
-
});
|
160 |
-
// options form: auto submit when `reset options` checkbox is checked
|
161 |
-
$('form.options').find('input[name="reset_options"]').click(function () {
|
162 |
-
if ($(this).is(':checked')) $(this).parents('form').submit();
|
163 |
-
});
|
164 |
-
$('.form-table .action.remove a').live('click', function () {
|
165 |
-
$(this).parents('tr').first().remove();
|
166 |
-
return false;
|
167 |
-
});
|
168 |
-
|
169 |
-
var dblclickbuf = {
|
170 |
-
'selected':false,
|
171 |
-
'value':''
|
172 |
-
};
|
173 |
-
|
174 |
-
function insertxpath(){
|
175 |
-
if (dblclickbuf.selected)
|
176 |
-
{
|
177 |
-
$(this).val($(this).val() + dblclickbuf.value);
|
178 |
-
$('.xml-element[title*="/'+dblclickbuf.value.replace('{','').replace('}','')+'"]').removeClass('selected');
|
179 |
-
dblclickbuf.value = '';
|
180 |
-
dblclickbuf.selected = false;
|
181 |
-
}
|
182 |
-
}
|
183 |
-
|
184 |
-
// [xml representation dynamic]
|
185 |
-
$.fn.xml = function (opt) {
|
186 |
-
if ( ! this.length) return this;
|
187 |
-
|
188 |
-
var $self = this;
|
189 |
-
var opt = opt || {};
|
190 |
-
var action = {};
|
191 |
-
if ('object' == typeof opt) {
|
192 |
-
action = opt;
|
193 |
-
} else {
|
194 |
-
action[opt] = true;
|
195 |
-
}
|
196 |
-
action = $.extend({init: ! this.data('initialized')}, action);
|
197 |
-
|
198 |
-
if (action.init) {
|
199 |
-
this.data('initialized', true);
|
200 |
-
// add expander
|
201 |
-
this.find('.xml-expander').live('click', function () {
|
202 |
-
var method;
|
203 |
-
if ('-' == $(this).text()) {
|
204 |
-
$(this).text('+');
|
205 |
-
method = 'addClass';
|
206 |
-
} else {
|
207 |
-
$(this).text('-');
|
208 |
-
method = 'removeClass';
|
209 |
-
}
|
210 |
-
// for nested representation based on div
|
211 |
-
$(this).parent().find('> .xml-content')[method]('collapsed');
|
212 |
-
// for nested representation based on tr
|
213 |
-
var $tr = $(this).parent().parent().filter('tr.xml-element').next()[method]('collapsed');
|
214 |
-
});
|
215 |
-
}
|
216 |
-
if (action.dragable) { // drag & drop
|
217 |
-
var _w; var _dbl = 0;
|
218 |
-
var $drag = $('__drag'); $drag.length || ($drag = $('<input type="text" id="__drag" readonly="readonly" />'));
|
219 |
-
|
220 |
-
$drag.css({
|
221 |
-
position: 'absolute',
|
222 |
-
background: 'transparent',
|
223 |
-
top: -50,
|
224 |
-
left: 0,
|
225 |
-
margin: 0,
|
226 |
-
border: 'none',
|
227 |
-
lineHeight: 1,
|
228 |
-
opacity: 0,
|
229 |
-
cursor: 'pointer',
|
230 |
-
borderRadius: 0
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
var
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
$drag.
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
$drag.
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
dblclickbuf.
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
dblclickbuf.
|
258 |
-
$(
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
dblclickbuf.
|
265 |
-
$(
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
dblclickbuf.value
|
288 |
-
dblclickbuf.
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
var
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
$form
|
312 |
-
|
313 |
-
var $
|
314 |
-
var $
|
315 |
-
var $
|
316 |
-
var $
|
317 |
-
var $
|
318 |
-
|
319 |
-
|
320 |
-
$
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
var
|
328 |
-
xpath_elements[0]
|
329 |
-
|
330 |
-
$
|
331 |
-
$form.
|
332 |
-
//
|
333 |
-
|
334 |
-
$
|
335 |
-
$xml.
|
336 |
-
$('
|
337 |
-
|
338 |
-
$
|
339 |
-
$
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
$goto_element.val(
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
$goto_element.val(
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
$goto_element.val(
|
353 |
-
|
354 |
-
|
355 |
-
$(
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
$input.
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
$tag
|
369 |
-
|
370 |
-
$tag.find('
|
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 |
-
$(this).parents('td:first').find('
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
$(this).parents('td:first').find('
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
$(this).parents('td:first').find('
|
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 |
-
$form
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* plugin admin area javascript
|
3 |
+
*/
|
4 |
+
(function($){$(function () {
|
5 |
+
if ( ! $('body.pmxi_plugin').length) return; // do not execute any code if we are not on plugin page
|
6 |
+
|
7 |
+
// fix layout position
|
8 |
+
setTimeout(function () {
|
9 |
+
$('table.layout').length && $('table.layout td.left h2:first-child').css('margin-top', $('.wrap').offset().top - $('table.layout').offset().top);
|
10 |
+
}, 10);
|
11 |
+
|
12 |
+
// help icons
|
13 |
+
$('a.help').tipsy({
|
14 |
+
gravity: function() {
|
15 |
+
var ver = 'n';
|
16 |
+
if ($(document).scrollTop() < $(this).offset().top - $('.tipsy').height() - 2) {
|
17 |
+
ver = 's';
|
18 |
+
}
|
19 |
+
var hor = '';
|
20 |
+
if ($(this).offset().left + $('.tipsy').width() < $(window).width() + $(document).scrollLeft()) {
|
21 |
+
hor = 'w';
|
22 |
+
} else if ($(this).offset().left - $('.tipsy').width() > $(document).scrollLeft()) {
|
23 |
+
hor = 'e';
|
24 |
+
}
|
25 |
+
return ver + hor;
|
26 |
+
},
|
27 |
+
live: true,
|
28 |
+
html: true,
|
29 |
+
opacity: 1
|
30 |
+
}).live('click', function () {
|
31 |
+
return false;
|
32 |
+
}).each(function () { // fix tipsy title for IE
|
33 |
+
$(this).attr('original-title', $(this).attr('title'));
|
34 |
+
$(this).removeAttr('title');
|
35 |
+
});
|
36 |
+
|
37 |
+
// swither show/hide logic
|
38 |
+
$('input.switcher').change(function (e) {
|
39 |
+
if ($(this).is(':radio:checked')) {
|
40 |
+
$(this).parents('form').find('input.switcher:radio[name="' + $(this).attr('name') + '"]').not(this).change();
|
41 |
+
}
|
42 |
+
var $targets = $('.switcher-target-' + $(this).attr('id'));
|
43 |
+
var is_show = $(this).is(':checked'); if ($(this).is('.switcher-reversed')) is_show = ! is_show;
|
44 |
+
if (is_show) {
|
45 |
+
$targets.fadeIn();
|
46 |
+
} else {
|
47 |
+
$targets.hide().find('.clear-on-switch').add($targets.filter('.clear-on-switch')).val('');
|
48 |
+
}
|
49 |
+
}).change();
|
50 |
+
|
51 |
+
// autoselect input content on click
|
52 |
+
$('input.selectable').live('click', function () {
|
53 |
+
$(this).select();
|
54 |
+
});
|
55 |
+
|
56 |
+
// input tags with title
|
57 |
+
$('input[title]').each(function () {
|
58 |
+
var $this = $(this);
|
59 |
+
$this.bind('focus', function () {
|
60 |
+
if ('' == $(this).val() || $(this).val() == $(this).attr('title')) {
|
61 |
+
$(this).removeClass('note').val('');
|
62 |
+
}
|
63 |
+
}).bind('blur', function () {
|
64 |
+
if ('' == $(this).val() || $(this).val() == $(this).attr('title')) {
|
65 |
+
$(this).addClass('note').val($(this).attr('title'));
|
66 |
+
}
|
67 |
+
}).blur();
|
68 |
+
$this.parents('form').bind('submit', function () {
|
69 |
+
if ($this.val() == $this.attr('title')) {
|
70 |
+
$this.val('');
|
71 |
+
}
|
72 |
+
});
|
73 |
+
});
|
74 |
+
|
75 |
+
// datepicker
|
76 |
+
$('input.datepicker').datepicker({
|
77 |
+
dateFormat: 'yy-mm-dd',
|
78 |
+
showOn: 'button',
|
79 |
+
buttonText: '',
|
80 |
+
constrainInput: false,
|
81 |
+
showAnim: 'fadeIn',
|
82 |
+
showOptions: 'fast'
|
83 |
+
}).bind('change', function () {
|
84 |
+
var selectedDate = $(this).val();
|
85 |
+
var instance = $(this).data('datepicker');
|
86 |
+
var date = null;
|
87 |
+
if ('' != selectedDate) {
|
88 |
+
try {
|
89 |
+
date = $.datepicker.parseDate(instance.settings.dateFormat || $.datepicker._defaults.dateFormat, selectedDate, instance.settings);
|
90 |
+
} catch (e) {
|
91 |
+
date = null;
|
92 |
+
}
|
93 |
+
}
|
94 |
+
if ($(this).hasClass('range-from')) {
|
95 |
+
$(this).parent().find('.datepicker.range-to').datepicker("option", "minDate", date);
|
96 |
+
}
|
97 |
+
if ($(this).hasClass('range-to')) {
|
98 |
+
$(this).parent().find('.datepicker.range-from').datepicker("option", "maxDate", date);
|
99 |
+
}
|
100 |
+
}).change();
|
101 |
+
$('.ui-datepicker').hide(); // fix: make sure datepicker doesn't break wordpress layout upon initialization
|
102 |
+
|
103 |
+
// no-enter-submit forms
|
104 |
+
$('form.no-enter-submit').find('input,select,textarea').not('*[type="submit"]').keydown(function (e) {
|
105 |
+
if (13 == e.keyCode) e.preventDefault();
|
106 |
+
});
|
107 |
+
|
108 |
+
// choose file form: option selection dynamic
|
109 |
+
// options form: highlight options of selected post type
|
110 |
+
$('form.choose-file input[name="type"]').click(function() {
|
111 |
+
if ($(this).val() == 'upload' || $(this).val() == 'file' || $(this).val() == 'reimport' || $(this).val() == 'url') $('#large_import').slideDown(); else { $('#large_import').slideUp(); $('#large_import_toggle').removeAttr('checked'); $('#large_import_xpath').slideUp();}
|
112 |
+
var $container = $(this).parents('.file-type-container');
|
113 |
+
$('.file-type-container').not($container).removeClass('selected').find('.file-type-options').hide();
|
114 |
+
$container.addClass('selected').find('.file-type-options').show();
|
115 |
+
}).filter(':checked').click();
|
116 |
+
|
117 |
+
// template form: auto submit when `load template` list value is picked
|
118 |
+
$('form.template, form.options').find('select[name="load_template"]').change(function () {
|
119 |
+
$(this).parents('form').submit();
|
120 |
+
});
|
121 |
+
// template form: preview button
|
122 |
+
$('form.template').each(function () {
|
123 |
+
var $form = $(this);
|
124 |
+
var $modal = $('<div></div>').dialog({
|
125 |
+
autoOpen: false,
|
126 |
+
modal: true,
|
127 |
+
title: 'Preview Post',
|
128 |
+
width: 760,
|
129 |
+
maxHeight: 600,
|
130 |
+
open: function(event, ui) {
|
131 |
+
$(this).dialog('option', 'height', 'auto').css({'max-height': $(this).dialog('option', 'maxHeight') - $(this).prev().height() - 24, 'overflow-y': 'auto'});
|
132 |
+
}
|
133 |
+
});
|
134 |
+
$form.find('.preview').click(function () {
|
135 |
+
$modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
|
136 |
+
tinyMCE.triggerSave(false, false);
|
137 |
+
$.post('admin.php?page=pmxi-admin-import&action=preview', $form.serialize(), function (response) {
|
138 |
+
$modal.removeClass('loading').html(response).dialog('option', 'position', 'center');
|
139 |
+
});
|
140 |
+
return false;
|
141 |
+
});
|
142 |
+
});
|
143 |
+
|
144 |
+
// options form: highlight options of selected post type
|
145 |
+
$('form.options input[name="type"]').click(function() {
|
146 |
+
var $container = $(this).parents('.post-type-container');
|
147 |
+
$('.post-type-container').not($container).removeClass('selected').find('.post-type-options').hide();
|
148 |
+
$container.addClass('selected').find('.post-type-options').show();
|
149 |
+
}).filter(':checked').click();
|
150 |
+
// options form: add / remove custom params
|
151 |
+
$('.form-table a.action[href="#add"]').live('click', function () {
|
152 |
+
var $template = $(this).parents('table').first().find('tr.template');
|
153 |
+
$template.clone(true).insertBefore($template).css('display', 'none').removeClass('template').fadeIn();
|
154 |
+
return false;
|
155 |
+
});
|
156 |
+
// options form: auto submit when `load options` checkbox is checked
|
157 |
+
$('input[name="load_options"]').click(function () {
|
158 |
+
if ($(this).is(':checked')) $(this).parents('form').submit();
|
159 |
+
});
|
160 |
+
// options form: auto submit when `reset options` checkbox is checked
|
161 |
+
$('form.options').find('input[name="reset_options"]').click(function () {
|
162 |
+
if ($(this).is(':checked')) $(this).parents('form').submit();
|
163 |
+
});
|
164 |
+
$('.form-table .action.remove a').live('click', function () {
|
165 |
+
$(this).parents('tr').first().remove();
|
166 |
+
return false;
|
167 |
+
});
|
168 |
+
|
169 |
+
var dblclickbuf = {
|
170 |
+
'selected':false,
|
171 |
+
'value':''
|
172 |
+
};
|
173 |
+
|
174 |
+
function insertxpath(){
|
175 |
+
if (dblclickbuf.selected)
|
176 |
+
{
|
177 |
+
$(this).val($(this).val() + dblclickbuf.value);
|
178 |
+
$('.xml-element[title*="/'+dblclickbuf.value.replace('{','').replace('}','')+'"]').removeClass('selected');
|
179 |
+
dblclickbuf.value = '';
|
180 |
+
dblclickbuf.selected = false;
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
// [xml representation dynamic]
|
185 |
+
$.fn.xml = function (opt) {
|
186 |
+
if ( ! this.length) return this;
|
187 |
+
|
188 |
+
var $self = this;
|
189 |
+
var opt = opt || {};
|
190 |
+
var action = {};
|
191 |
+
if ('object' == typeof opt) {
|
192 |
+
action = opt;
|
193 |
+
} else {
|
194 |
+
action[opt] = true;
|
195 |
+
}
|
196 |
+
action = $.extend({init: ! this.data('initialized')}, action);
|
197 |
+
|
198 |
+
if (action.init) {
|
199 |
+
this.data('initialized', true);
|
200 |
+
// add expander
|
201 |
+
this.find('.xml-expander').live('click', function () {
|
202 |
+
var method;
|
203 |
+
if ('-' == $(this).text()) {
|
204 |
+
$(this).text('+');
|
205 |
+
method = 'addClass';
|
206 |
+
} else {
|
207 |
+
$(this).text('-');
|
208 |
+
method = 'removeClass';
|
209 |
+
}
|
210 |
+
// for nested representation based on div
|
211 |
+
$(this).parent().find('> .xml-content')[method]('collapsed');
|
212 |
+
// for nested representation based on tr
|
213 |
+
var $tr = $(this).parent().parent().filter('tr.xml-element').next()[method]('collapsed');
|
214 |
+
});
|
215 |
+
}
|
216 |
+
if (action.dragable) { // drag & drop
|
217 |
+
var _w; var _dbl = 0;
|
218 |
+
var $drag = $('__drag'); $drag.length || ($drag = $('<input type="text" id="__drag" readonly="readonly" />'));
|
219 |
+
|
220 |
+
$drag.css({
|
221 |
+
position: 'absolute',
|
222 |
+
background: 'transparent',
|
223 |
+
top: -50,
|
224 |
+
left: 0,
|
225 |
+
margin: 0,
|
226 |
+
border: 'none',
|
227 |
+
lineHeight: 1,
|
228 |
+
opacity: 0,
|
229 |
+
cursor: 'pointer',
|
230 |
+
borderRadius: 0,
|
231 |
+
zIndex:99
|
232 |
+
}).appendTo(document.body).mousedown(function (e) {
|
233 |
+
if (_dbl) return;
|
234 |
+
var _x = e.pageX - $drag.offset().left;
|
235 |
+
var _y = e.pageY - $drag.offset().top;
|
236 |
+
if (_x < 4 || _y < 4 || $drag.width() - _x < 0 || $drag.height() - _y < 0) {
|
237 |
+
return;
|
238 |
+
}
|
239 |
+
$drag.width($(document.body).width() - $drag.offset().left - 5).css('opacity', 1);
|
240 |
+
$drag.select();
|
241 |
+
_dbl = true; setTimeout(function () {_dbl = false;}, 400);
|
242 |
+
}).mouseup(function () {
|
243 |
+
$drag.css('opacity', 0).css('width', _w);
|
244 |
+
$drag.blur();
|
245 |
+
}).dblclick(function(){
|
246 |
+
if (dblclickbuf.selected)
|
247 |
+
{
|
248 |
+
$('.xml-element[title*="/'+dblclickbuf.value.replace('{','').replace('}','')+'"]').removeClass('selected');
|
249 |
+
|
250 |
+
if ($(this).val() == dblclickbuf.value)
|
251 |
+
{
|
252 |
+
dblclickbuf.value = '';
|
253 |
+
dblclickbuf.selected = false;
|
254 |
+
}
|
255 |
+
else
|
256 |
+
{
|
257 |
+
dblclickbuf.selected = true;
|
258 |
+
dblclickbuf.value = $(this).val();
|
259 |
+
$('.xml-element[title*="/'+$(this).val().replace('{','').replace('}','')+'"]').addClass('selected');
|
260 |
+
}
|
261 |
+
}
|
262 |
+
else
|
263 |
+
{
|
264 |
+
dblclickbuf.selected = true;
|
265 |
+
dblclickbuf.value = $(this).val();
|
266 |
+
$('.xml-element[title*="/'+$(this).val().replace('{','').replace('}','')+'"]').addClass('selected');
|
267 |
+
}
|
268 |
+
});
|
269 |
+
|
270 |
+
$('#title, #content, .widefat, input[name^=custom_name], textarea[name^=custom_value], input[name^=featured_image], input[name^=unique_key]').bind('focus', insertxpath );
|
271 |
+
|
272 |
+
$(document).mousemove(function () {
|
273 |
+
if (parseInt($drag.css('opacity')) != 0) {
|
274 |
+
setTimeout(function () {
|
275 |
+
$drag.css('opacity', 0);
|
276 |
+
}, 50);
|
277 |
+
setTimeout(function () {
|
278 |
+
$drag.css('width', _w);
|
279 |
+
}, 500);
|
280 |
+
}
|
281 |
+
});
|
282 |
+
|
283 |
+
if ($('#content').length && window.tinymce != undefined) tinymce.dom.Event.add('wp-content-editor-container', 'click', function(e) {
|
284 |
+
if (dblclickbuf.selected)
|
285 |
+
{
|
286 |
+
tinyMCE.activeEditor.selection.setContent(dblclickbuf.value);
|
287 |
+
$('.xml-element[title*="'+dblclickbuf.value.replace('{','').replace('}','')+'"]').removeClass('selected');
|
288 |
+
dblclickbuf.value = '';
|
289 |
+
dblclickbuf.selected = false;
|
290 |
+
}
|
291 |
+
});
|
292 |
+
|
293 |
+
this.find('.xml-tag.opening > .xml-tag-name, .xml-attr-name').each(function () {
|
294 |
+
var $this = $(this);
|
295 |
+
var xpath = '.';
|
296 |
+
if ($this.is('.xml-attr-name'))
|
297 |
+
xpath = '{' + ($this.parents('.xml-element:first').attr('title').replace(/^\/[^\/]+\/?/, '') || '.') + '/@' + $this.html().trim() + '}';
|
298 |
+
else
|
299 |
+
xpath = '{' + ($this.parent().parent().attr('title').replace(/^\/[^\/]+\/?/, '') || '.') + '}';
|
300 |
+
|
301 |
+
$this.mouseover(function (e) {
|
302 |
+
$drag.val(xpath).offset({left: $this.offset().left - 2, top: $this.offset().top - 2}).width(_w = $this.width() + 4).height($this.height() + 4);
|
303 |
+
});
|
304 |
+
}).eq(0).mouseover();
|
305 |
+
}
|
306 |
+
return this;
|
307 |
+
};
|
308 |
+
|
309 |
+
// selection logic
|
310 |
+
$('form.choose-elements').each(function () {
|
311 |
+
var $form = $(this);
|
312 |
+
$form.find('.xml').xml();
|
313 |
+
var $input = $form.find('input[name="xpath"]');
|
314 |
+
var $next_element = $form.find('#next_element');
|
315 |
+
var $prev_element = $form.find('#prev_element');
|
316 |
+
var $goto_element = $form.find('#goto_element');
|
317 |
+
var $get_default_xpath = $form.find('#get_default_xpath');
|
318 |
+
var $root_element = $form.find('#root_element');
|
319 |
+
|
320 |
+
var $xml = $('.xml');
|
321 |
+
$form.find('.xml-tag.opening').live('mousedown', function () {return false;}).live('dblclick', function () {
|
322 |
+
if ($form.hasClass('loading')) return; // do nothing if selecting operation is currently under way
|
323 |
+
$input.val($(this).parents('.xml-element').first().attr('title').replace(/\[\d+\]$/, '')).change();
|
324 |
+
});
|
325 |
+
var xpathChanged = function () {
|
326 |
+
if ($input.val() == $input.data('checkedValue')) return;
|
327 |
+
var xpath_elements = $input.val().split('[');
|
328 |
+
var xpath_parts = xpath_elements[0].split('/');
|
329 |
+
xpath_elements[0] = '';
|
330 |
+
$input.val('/' + xpath_parts[xpath_parts.length - 1] + ((xpath_elements.length) ? xpath_elements.join('[') : ''));
|
331 |
+
$form.addClass('loading');
|
332 |
+
$form.find('.xml-element.selected').removeClass('selected'); // clear current selection
|
333 |
+
// request server to return elements which correspond to xpath entered
|
334 |
+
$input.attr('readonly', true).unbind('change', xpathChanged).data('checkedValue', $input.val());
|
335 |
+
$xml.css({'visibility':'hidden'});
|
336 |
+
$xml.parents('fieldset:first').addClass('preload');
|
337 |
+
$('.ajax-console').load('admin.php?page=pmxi-admin-import&action=evaluate', {xpath: $input.val(), show_element: $goto_element.val(), root_element:$root_element.val()}, function () {
|
338 |
+
$input.attr('readonly', false).change(function(){$goto_element.val(1); xpathChanged();});
|
339 |
+
$form.removeClass('loading');
|
340 |
+
$xml.parents('fieldset:first').removeClass('preload');
|
341 |
+
});
|
342 |
+
};
|
343 |
+
$next_element.click(function(){
|
344 |
+
var show_element = Math.min((parseInt($goto_element.val()) + 1), parseInt($('.matches_count').html()));
|
345 |
+
$goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
|
346 |
+
});
|
347 |
+
$prev_element.click(function(){
|
348 |
+
var show_element = Math.max((parseInt($goto_element.val()) - 1), 1);
|
349 |
+
$goto_element.val(show_element).html( show_element ); $input.data('checkedValue', ''); xpathChanged();
|
350 |
+
});
|
351 |
+
$goto_element.change(function(){
|
352 |
+
var show_element = Math.max(Math.min(parseInt($goto_element.val()), parseInt($('.matches_count').html())), 1);
|
353 |
+
$goto_element.val(show_element); $input.data('checkedValue', ''); xpathChanged();
|
354 |
+
});
|
355 |
+
$get_default_xpath.click(function(){$root_element.val($(this).attr('root')); $goto_element.val(1); $input.val($(this).attr('rel')); xpathChanged();});
|
356 |
+
$('.change_root_element').click(function(){
|
357 |
+
$root_element.val($(this).attr('rel')); $goto_element.val(1); $input.val('/' + $(this).attr('rel')); xpathChanged();
|
358 |
+
});
|
359 |
+
$input.change(function(){$goto_element.val(1); xpathChanged();}).change();
|
360 |
+
$input.keyup(function (e) {
|
361 |
+
if (13 == e.keyCode) $(this).change();
|
362 |
+
});
|
363 |
+
});
|
364 |
+
|
365 |
+
// tag preview
|
366 |
+
$.fn.tag = function () {
|
367 |
+
this.each(function () {
|
368 |
+
var $tag = $(this);
|
369 |
+
$tag.xml('dragable');
|
370 |
+
var tagno = parseInt($tag.find('input[name="tagno"]').val());
|
371 |
+
$tag.find('.navigation a').click(function () {
|
372 |
+
tagno += '#prev' == $(this).attr('href') ? -1 : 1;
|
373 |
+
$tag.addClass('loading').css('opacity', 0.7);
|
374 |
+
$.post('admin.php?page=pmxi-admin-import&action=tag', {tagno: tagno}, function (data) {
|
375 |
+
var $indicator = $('<span />').insertBefore($tag);
|
376 |
+
$tag.replaceWith(data);
|
377 |
+
$indicator.next().tag().prevObject.remove();
|
378 |
+
if ($('#variations_xpath').length){
|
379 |
+
$('#variations_xpath').data('checkedValue', '').change();
|
380 |
+
}
|
381 |
+
}, 'html');
|
382 |
+
return false;
|
383 |
+
});
|
384 |
+
});
|
385 |
+
return this;
|
386 |
+
};
|
387 |
+
$('.tag').tag();
|
388 |
+
// [/xml representation dynamic]
|
389 |
+
|
390 |
+
$('input.autocomplete').each(function () {
|
391 |
+
$(this).autocomplete({
|
392 |
+
source: eval($(this).attr('id')),
|
393 |
+
minLength: 0
|
394 |
+
}).click(function () {
|
395 |
+
$(this).autocomplete('search', '');
|
396 |
+
});
|
397 |
+
});
|
398 |
+
|
399 |
+
/* Categories hierarchy */
|
400 |
+
|
401 |
+
$('.sortable').nestedSortable({
|
402 |
+
handle: 'div',
|
403 |
+
items: 'li',
|
404 |
+
toleranceElement: '> div',
|
405 |
+
update: function () {
|
406 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).nestedSortable('toArray', {startDepthCount: 0})));
|
407 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
408 |
+
}
|
409 |
+
});
|
410 |
+
|
411 |
+
$('.drag-element').find('input').live('blur', function(){
|
412 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
413 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
414 |
+
});
|
415 |
+
|
416 |
+
$('.drag-element').find('input').live('change', function(){
|
417 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
418 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
419 |
+
});
|
420 |
+
|
421 |
+
$('.drag-element').find('input').live('hover', function(){},function(){
|
422 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
423 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
424 |
+
});
|
425 |
+
|
426 |
+
$('.taxonomy_auto_nested').live('click', function(){
|
427 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('td:first').find('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
428 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
429 |
+
});
|
430 |
+
|
431 |
+
$('.sortable').find('.remove-ico').live('click', function(){
|
432 |
+
|
433 |
+
var parent_td = $(this).parents('td:first');
|
434 |
+
|
435 |
+
$(this).parents('li:first').remove();
|
436 |
+
parent_td.find('ol.sortable:first').find('li').each(function(i, e){
|
437 |
+
$(this).attr({'id':'item_'+ (i+1)});
|
438 |
+
});
|
439 |
+
parent_td.find('.hierarhy-output').val(window.JSON.stringify(parent_td.find('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
440 |
+
if (parent_td.find('input:first').val() == '') parent_td.find('.hierarhy-output').val('');
|
441 |
+
});
|
442 |
+
|
443 |
+
$('.add-new-ico').click(function(){
|
444 |
+
var count = $(this).parents('tr:first').find('ol.sortable').find('li').length + 1;
|
445 |
+
$(this).parents('tr:first').find('ol.sortable').append('<li id="item_'+count+'"><div class="drag-element"><input type="checkbox" class="assign_post" checked="checked"/><input type="text" value="" class="widefat"></div><a class="icon-item remove-ico" href="javascript:void(0);"></a></li>');
|
446 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
447 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
448 |
+
$('.widefat').bind('focus', insertxpath );
|
449 |
+
});
|
450 |
+
|
451 |
+
$('form.options').find('input[type=submit]').click(function(e){
|
452 |
+
e.preventDefault();
|
453 |
+
|
454 |
+
$('.hierarhy-output').each(function(){
|
455 |
+
$(this).val(window.JSON.stringify($(this).parents('td:first').find('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
456 |
+
if ($(this).parents('td:first').find('input:first').val() == '') $(this).val('');
|
457 |
+
});
|
458 |
+
if ($(this).attr('name') == 'btn_save_only') $('.save_only').val('1');
|
459 |
+
|
460 |
+
$('input[name^=in_variations], input[name^=is_visible], input[name^=is_taxonomy], input[name^=create_taxonomy_in_not_exists], input[name^=variable_create_taxonomy_in_not_exists], input[name^=variable_in_variations], input[name^=variable_is_visible], input[name^=variable_is_taxonomy]').each(function(){
|
461 |
+
if ( ! $(this).is(':checked') && ! $(this).parents('.form-field:first').hasClass('template')){
|
462 |
+
$(this).val('0').attr('checked','checked');
|
463 |
+
}
|
464 |
+
});
|
465 |
+
|
466 |
+
$(this).parents('form:first').submit();
|
467 |
+
});
|
468 |
+
|
469 |
+
/* END Categories hierarchy */
|
470 |
+
|
471 |
+
// manage screen: cron url
|
472 |
+
$('.get_cron_url').each(function () {
|
473 |
+
var $form = $(this);
|
474 |
+
var $modal = $('<div></div>').dialog({
|
475 |
+
autoOpen: false,
|
476 |
+
modal: true,
|
477 |
+
title: 'Cron URLs',
|
478 |
+
width: 760,
|
479 |
+
maxHeight: 600,
|
480 |
+
open: function(event, ui) {
|
481 |
+
$(this).dialog('option', 'height', 'auto').css({'max-height': $(this).dialog('option', 'maxHeight') - $(this).prev().height() - 24, 'overflow-y': 'auto'});
|
482 |
+
}
|
483 |
+
});
|
484 |
+
$form.find('a').click(function () {
|
485 |
+
$modal.addClass('loading').empty().dialog('open').dialog('option', 'position', 'center');
|
486 |
+
$modal.removeClass('loading').html('<textarea style="width:100%; height:100%;">' + $form.find('a').attr('rel') + '</textarea>').dialog('option', 'position', 'center');
|
487 |
+
});
|
488 |
+
});
|
489 |
+
|
490 |
+
// chunk files upload
|
491 |
+
if ($('#plupload-ui').length)
|
492 |
+
{
|
493 |
+
$('#plupload-ui').show();
|
494 |
+
$('#html-upload-ui').hide();
|
495 |
+
|
496 |
+
wplupload = $('#select-files').wplupload({
|
497 |
+
runtimes : 'gears,browserplus,html5,flash,silverlight,html4',
|
498 |
+
url : 'admin.php?page=pmxi-admin-settings&action=upload',
|
499 |
+
container: 'plupload-ui',
|
500 |
+
browse_button : 'select-files',
|
501 |
+
file_data_name : 'async-upload',
|
502 |
+
flash_swf_url : plugin_url + '/static/js/plupload/plupload.flash.swf',
|
503 |
+
silverlight_xap_url : plugin_url + '/static/js/plupload/plupload.silverlight.xap',
|
504 |
+
|
505 |
+
multipart: false,
|
506 |
+
max_file_size: '1000mb',
|
507 |
+
chunk_size: '1mb',
|
508 |
+
drop_element: 'plupload-ui'
|
509 |
+
});
|
510 |
+
}
|
511 |
+
|
512 |
+
/* END plupload scripts */
|
513 |
+
|
514 |
+
if ($('#large_import_toggle').is(':checked')) $('#large_import_xpath').slideToggle();
|
515 |
+
|
516 |
+
$('#large_import_toggle').click(function(){
|
517 |
+
$('#large_import_xpath').slideToggle();
|
518 |
+
});
|
519 |
+
|
520 |
+
// Step 4 - custom meta keys helper
|
521 |
+
|
522 |
+
if ($('#pmxi_tabs').length){
|
523 |
+
if ($('form.options').length){
|
524 |
+
if ($('#selected_post_type').val() != ''){
|
525 |
+
var post_type_founded = false;
|
526 |
+
$('input[name=custom_type]').each(function(i){
|
527 |
+
if ($(this).val() == $('#selected_post_type').val()) { $('#pmxi_tabs').tabs({ selected:i }).show(); post_type_founded = true; }
|
528 |
+
});
|
529 |
+
if ( ! post_type_founded){
|
530 |
+
$('#pmxi_tabs').tabs({ selected: ($('#selected_type').val() == 'post') ? 0 : 1 }).show();
|
531 |
+
}
|
532 |
+
}
|
533 |
+
else if ($('#selected_type').val() != ''){
|
534 |
+
$('#pmxi_tabs').tabs({ selected: ($('#selected_type').val() == 'post') ? 0 : 1 }).show();
|
535 |
+
}
|
536 |
+
}
|
537 |
+
else
|
538 |
+
$('#pmxi_tabs').tabs().show();
|
539 |
+
}
|
540 |
+
|
541 |
+
if ($('#upload_process').length){
|
542 |
+
$('#upload_process').progressbar({ value: (($('#progressbar').html() != '') ? 100 : 0) });
|
543 |
+
if ($('#progressbar').html() != '')
|
544 |
+
$('.submit-buttons').show();
|
545 |
+
}
|
546 |
+
|
547 |
+
$('#view_log').live('click', function(){
|
548 |
+
$('#import_finished').css({'visibility':'hidden'});
|
549 |
+
$('#logwrapper').slideToggle(100, function(){
|
550 |
+
$('#import_finished').css({'visibility':'visible'});
|
551 |
+
});
|
552 |
+
});
|
553 |
+
|
554 |
+
$(document).scroll(function() {
|
555 |
+
if ($(document).scrollTop() > 135)
|
556 |
+
$('.tag').css({'top':'30px'});
|
557 |
+
else
|
558 |
+
$('.tag').css({'top':''});
|
559 |
+
});
|
560 |
+
|
561 |
+
});})(jQuery);
|
static/js/pmxi.js
CHANGED
@@ -1,33 +1,33 @@
|
|
1 |
-
/**
|
2 |
-
* plugin javascript
|
3 |
-
*/
|
4 |
-
(function($){$(function () {
|
5 |
-
|
6 |
-
$('#dismiss').click(function(){
|
7 |
-
|
8 |
-
$(this).parents('div.updated:first').slideUp();
|
9 |
-
$.post('admin.php?page=pmxi-admin-settings&action=dismiss', {dismiss: true}, function (data) {
|
10 |
-
|
11 |
-
}, 'html');
|
12 |
-
|
13 |
-
});
|
14 |
-
|
15 |
-
$('#dismiss_manage_top').click(function(){
|
16 |
-
|
17 |
-
$(this).parents('div.updated:first').slideUp();
|
18 |
-
$.post('admin.php?page=pmxi-admin-settings&action=dismiss_manage_top', {dismiss: true}, function (data) {
|
19 |
-
|
20 |
-
}, 'html');
|
21 |
-
|
22 |
-
});
|
23 |
-
|
24 |
-
$('#dismiss_manage_bottom').click(function(){
|
25 |
-
|
26 |
-
$(this).parents('div.updated_bottom:first').slideUp();
|
27 |
-
$.post('admin.php?page=pmxi-admin-settings&action=dismiss_manage_bottom', {dismiss: true}, function (data) {
|
28 |
-
|
29 |
-
}, 'html');
|
30 |
-
|
31 |
-
});
|
32 |
-
|
33 |
});})(jQuery);
|
1 |
+
/**
|
2 |
+
* plugin javascript
|
3 |
+
*/
|
4 |
+
(function($){$(function () {
|
5 |
+
|
6 |
+
$('#dismiss').click(function(){
|
7 |
+
|
8 |
+
$(this).parents('div.updated:first').slideUp();
|
9 |
+
$.post('admin.php?page=pmxi-admin-settings&action=dismiss', {dismiss: true}, function (data) {
|
10 |
+
|
11 |
+
}, 'html');
|
12 |
+
|
13 |
+
});
|
14 |
+
|
15 |
+
$('#dismiss_manage_top').click(function(){
|
16 |
+
|
17 |
+
$(this).parents('div.updated:first').slideUp();
|
18 |
+
$.post('admin.php?page=pmxi-admin-settings&action=dismiss_manage_top', {dismiss: true}, function (data) {
|
19 |
+
|
20 |
+
}, 'html');
|
21 |
+
|
22 |
+
});
|
23 |
+
|
24 |
+
$('#dismiss_manage_bottom').click(function(){
|
25 |
+
|
26 |
+
$(this).parents('div.updated_bottom:first').slideUp();
|
27 |
+
$.post('admin.php?page=pmxi-admin-settings&action=dismiss_manage_bottom', {dismiss: true}, function (data) {
|
28 |
+
|
29 |
+
}, 'html');
|
30 |
+
|
31 |
+
});
|
32 |
+
|
33 |
});})(jQuery);
|
views/admin/import/element_after.php
CHANGED
@@ -1,60 +1,60 @@
|
|
1 |
-
<form class="choose-elements no-enter-submit" method="post">
|
2 |
-
<h2><?php _e('Import XML/CSV - Step 2: Select Elements', 'pmxi_plugin') ?></h2>
|
3 |
-
|
4 |
-
<h3><?php _e('<b>Double-click on an element below to select it and its siblings.</b>', 'pmxi_plugin') ?></h3>
|
5 |
-
|
6 |
-
<div class="ajax-console">
|
7 |
-
<?php if ($this->errors->get_error_codes()): ?>
|
8 |
-
<?php $this->error() ?>
|
9 |
-
<?php endif ?>
|
10 |
-
</div>
|
11 |
-
<table class="layout">
|
12 |
-
<tr>
|
13 |
-
<td class="left">
|
14 |
-
<fieldset class="widefat">
|
15 |
-
<legend
|
16 |
-
<div class="action_buttons">
|
17 |
-
<a href="javascript:void(0);" id="prev_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left;">⟨⟨</a>
|
18 |
-
<a href="javascript:void(0);" id="next_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left; margin-right:15px;">⟩⟩</a>
|
19 |
-
<div style="float:left;">
|
20 |
-
<span style="font-size:18px; padding-top:15px; float:left; margin-right:10px;"
|
21 |
-
</div>
|
22 |
-
</div>
|
23 |
-
<div class="xml" style="min-height:400px;">
|
24 |
-
<?php //$this->render_xml_element($dom->documentElement) ?>
|
25 |
-
</div>
|
26 |
-
</fieldset>
|
27 |
-
</td>
|
28 |
-
<td class="right">
|
29 |
-
<fieldset class="widefat">
|
30 |
-
<legend
|
31 |
-
<p
|
32 |
-
<div>
|
33 |
-
<input type="text" name="xpath" value="<?php echo esc_attr($post['xpath']) ?>" style="max-width:none;" />
|
34 |
-
<input type="hidden" id="root_element" name="root_element" value="<?php echo $_SESSION['pmxi_import']['source']['root_element']; ?>"/>
|
35 |
-
<?php
|
36 |
-
if (!empty($elements_cloud)){
|
37 |
-
?>
|
38 |
-
<br/><label
|
39 |
-
<?php
|
40 |
-
$root_elements = array();
|
41 |
-
foreach ($elements_cloud as $tag => $count)
|
42 |
-
$root_elements[] = '<a href="javascript:void(0);" rel="'. $tag .'" class="change_root_element">' . $tag . '</a>';
|
43 |
-
echo implode(', ', $root_elements);
|
44 |
-
}
|
45 |
-
?>
|
46 |
-
<br/><br/>or <a href="javascript:void(0);" rel="<?php echo esc_attr($post['xpath']) ?>" root="<?php echo $_SESSION['pmxi_import']['source']['root_element']; ?>" id="get_default_xpath"
|
47 |
-
</div> <br><br>
|
48 |
-
<a href="http://www.w3schools.com/xpath/default.asp" target='_blank'
|
49 |
-
</fieldset>
|
50 |
-
<p class="submit-buttons" style="text-align:right;">
|
51 |
-
<a href="<?php echo $this->baseUrl ?>" class="back"
|
52 |
-
|
53 |
-
<input type="hidden" name="is_submitted" value="1" />
|
54 |
-
<?php wp_nonce_field('choose-elements', '_wpnonce_choose-elements') ?>
|
55 |
-
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" />
|
56 |
-
</p>
|
57 |
-
</td>
|
58 |
-
</tr>
|
59 |
-
</table>
|
60 |
-
</form>
|
1 |
+
<form class="choose-elements no-enter-submit" method="post">
|
2 |
+
<h2><?php _e('Import XML/CSV - Step 2: Select Elements', 'pmxi_plugin') ?></h2>
|
3 |
+
|
4 |
+
<h3><?php _e('<b>Double-click on an element below to select it and its siblings.</b>', 'pmxi_plugin') ?></h3>
|
5 |
+
|
6 |
+
<div class="ajax-console">
|
7 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
8 |
+
<?php $this->error() ?>
|
9 |
+
<?php endif ?>
|
10 |
+
</div>
|
11 |
+
<table class="layout">
|
12 |
+
<tr>
|
13 |
+
<td class="left">
|
14 |
+
<fieldset class="widefat">
|
15 |
+
<legend><?php _e('Current XML tree', 'pmxi_plugin');?></legend>
|
16 |
+
<div class="action_buttons">
|
17 |
+
<a href="javascript:void(0);" id="prev_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left;">⟨⟨</a>
|
18 |
+
<a href="javascript:void(0);" id="next_element" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" style="float:left; margin-right:15px;">⟩⟩</a>
|
19 |
+
<div style="float:left;">
|
20 |
+
<span style="font-size:18px; padding-top:15px; float:left; margin-right:10px;"><?php _e('Go to:','pmxi_plugin');?> </span><input type="text" id="goto_element" value="1"/>
|
21 |
+
</div>
|
22 |
+
</div>
|
23 |
+
<div class="xml" style="min-height:400px;">
|
24 |
+
<?php //$this->render_xml_element($dom->documentElement) ?>
|
25 |
+
</div>
|
26 |
+
</fieldset>
|
27 |
+
</td>
|
28 |
+
<td class="right">
|
29 |
+
<fieldset class="widefat">
|
30 |
+
<legend><?php _e('Advanced','pmxi_plugin');?></legend>
|
31 |
+
<p><?php _e('Current XPath:','pmxi_plugin');?></p>
|
32 |
+
<div>
|
33 |
+
<input type="text" name="xpath" value="<?php echo esc_attr($post['xpath']) ?>" style="max-width:none;" />
|
34 |
+
<input type="hidden" id="root_element" name="root_element" value="<?php echo $_SESSION['pmxi_import']['source']['root_element']; ?>"/>
|
35 |
+
<?php
|
36 |
+
if (!empty($elements_cloud)){
|
37 |
+
?>
|
38 |
+
<br/><label><?php _e('What element are you looking for?','pmxi_plugin');?></label> <br/>
|
39 |
+
<?php
|
40 |
+
$root_elements = array();
|
41 |
+
foreach ($elements_cloud as $tag => $count)
|
42 |
+
$root_elements[] = '<a href="javascript:void(0);" rel="'. $tag .'" class="change_root_element">' . $tag . '</a>';
|
43 |
+
echo implode(', ', $root_elements);
|
44 |
+
}
|
45 |
+
?>
|
46 |
+
<br/><br/>or <a href="javascript:void(0);" rel="<?php echo esc_attr($post['xpath']) ?>" root="<?php echo $_SESSION['pmxi_import']['source']['root_element']; ?>" id="get_default_xpath"><?php _e('get default xPath','pmxi_plugin');?></a>
|
47 |
+
</div> <br><br>
|
48 |
+
<a href="http://www.w3schools.com/xpath/default.asp" target='_blank'><?php _e('XPath Tutorial','pmxi_plugin');?></a> - <?php _e('For further help','pmxi_plugin');?>, <a href="http://www.wpallimport.com/support" target='_blank'><?php _e('contact us','pmxi_plugin');?></a>.
|
49 |
+
</fieldset>
|
50 |
+
<p class="submit-buttons" style="text-align:right;">
|
51 |
+
<a href="<?php echo $this->baseUrl ?>" class="back"><?php _e('Back','pmxi_plugin');?></a>
|
52 |
+
|
53 |
+
<input type="hidden" name="is_submitted" value="1" />
|
54 |
+
<?php wp_nonce_field('choose-elements', '_wpnonce_choose-elements') ?>
|
55 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" />
|
56 |
+
</p>
|
57 |
+
</td>
|
58 |
+
</tr>
|
59 |
+
</table>
|
60 |
+
</form>
|
views/admin/import/index.php
CHANGED
@@ -1,128 +1,128 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
$l10n = array(
|
4 |
-
'queue_limit_exceeded' => 'You have attempted to queue too many files.',
|
5 |
-
'file_exceeds_size_limit' => 'This file exceeds the maximum upload size for this site.',
|
6 |
-
'zero_byte_file' => 'This file is empty. Please try another.',
|
7 |
-
'invalid_filetype' => 'This file type is not allowed. Please try another.',
|
8 |
-
'default_error' => 'An error occurred in the upload. Please try again later.',
|
9 |
-
'missing_upload_url' => 'There was a configuration error. Please contact the server administrator.',
|
10 |
-
'upload_limit_exceeded' => 'You may only upload 1 file.',
|
11 |
-
'http_error' => 'HTTP error.',
|
12 |
-
'upload_failed' => 'Upload failed.',
|
13 |
-
'io_error' => 'IO error.',
|
14 |
-
'security_error' => 'Security error.',
|
15 |
-
'file_cancelled' => 'File canceled.',
|
16 |
-
'upload_stopped' => 'Upload stopped.',
|
17 |
-
'dismiss' => 'Dismiss',
|
18 |
-
'crunching' => 'Crunching…',
|
19 |
-
'deleted' => 'moved to the trash.',
|
20 |
-
'error_uploading' => 'has failed to upload due to an error',
|
21 |
-
'cancel_upload' => 'Cancel upload',
|
22 |
-
'dismiss' => 'Dismiss'
|
23 |
-
);
|
24 |
-
|
25 |
-
?>
|
26 |
-
<script type="text/javascript">
|
27 |
-
var plugin_url = '<?php echo PMXI_ROOT_URL; ?>';
|
28 |
-
var swfuploadL10n = <?php echo json_encode($l10n); ?>;
|
29 |
-
</script>
|
30 |
-
<table class="layout pmxi_step_1">
|
31 |
-
<tr>
|
32 |
-
<td class="left">
|
33 |
-
<h2><?php _e('Import XML/CSV - Step 1: Choose Your File', 'pmxi_plugin') ?></h2>
|
34 |
-
<h3><?php _e('Specify the file containing the data to be imported.', 'pmxi_plugin') ?></h3>
|
35 |
-
|
36 |
-
<?php if ($this->errors->get_error_codes()): ?>
|
37 |
-
<?php $this->error() ?>
|
38 |
-
<?php endif ?>
|
39 |
-
<?php
|
40 |
-
if ( ! $reimported_import->isEmpty()):
|
41 |
-
?>
|
42 |
-
<div id="reimported_notify">
|
43 |
-
<p><?php _e( 'You are importing a new file for: <b>' . $reimported_import->name . '</b>' , 'pmxi_plugin' );?></p>
|
44 |
-
<p><span><?php _e( 'Last imported on ' . date("m-d-Y H:i:s", strtotime($reimported_import->registered_on)) , 'pmxi_plugin' ); ?></span></p>
|
45 |
-
</div>
|
46 |
-
<?php
|
47 |
-
endif;
|
48 |
-
?>
|
49 |
-
<form method="post" class="choose-file no-enter-submit" enctype="multipart/form-data" autocomplete="off">
|
50 |
-
<input type="hidden" name="is_submitted" value="1" />
|
51 |
-
<?php wp_nonce_field('upload-xml', '_wpnonce_upload-xml') ?>
|
52 |
-
<div class="file-type-container">
|
53 |
-
<h3>
|
54 |
-
<input type="radio" id="type_upload" name="type" value="upload" checked="checked" />
|
55 |
-
<label for="type_upload"><?php _e('Upload File From Your Computer', 'pmxi_plugin') ?></label>
|
56 |
-
</h3>
|
57 |
-
<div id="plupload-ui" class="file-type-options">
|
58 |
-
<div>
|
59 |
-
<h3 style="float:left; margin-top:5px;"><label><?php _e( 'Choose file to upload...' ); ?></label></h3>
|
60 |
-
<input type="hidden" name="filepath" value="<?php echo $post['filepath'] ?>" id="filepath"/>
|
61 |
-
<span><input id="select-files" type="button" value="<?php esc_attr_e('Select File'); ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" /></span>
|
62 |
-
<div id="progress" class="progress" <?php if (!empty($post['filepath'])):?>style="visibility: visible;"<?php endif;?>>
|
63 |
-
<div id="upload_process" class="upload_process"></div>
|
64 |
-
<div id="progressbar" class="progressbar"><?php if (!empty($post['filepath'])) _e( 'Import Complete - '.basename($post['filepath']).' 100%', 'pmxi_plugin'); ?></div>
|
65 |
-
</div>
|
66 |
-
</div>
|
67 |
-
</div>
|
68 |
-
</div>
|
69 |
-
<div class="file-type-container">
|
70 |
-
<h3>
|
71 |
-
<input type="radio" id="type_url" name="type" value="url" />
|
72 |
-
<label for="type_url"><?php _e('Download File From URL', 'pmxi_plugin') ?></label>
|
73 |
-
</h3>
|
74 |
-
<div class="file-type-options">
|
75 |
-
<input type="text" class="regular-text" name="url" value="" disabled="disabled" />
|
76 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=step-1&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade to the professional edition of WP All Import to use this feature.</a>
|
77 |
-
</div>
|
78 |
-
</div>
|
79 |
-
<div class="file-type-container">
|
80 |
-
<h3>
|
81 |
-
<input type="radio" id="type_ftp" name="type" value="ftp" />
|
82 |
-
<label for="type_ftp"><?php _e('Download File(s) From FTP Server', 'pmxi_plugin') ?></label>
|
83 |
-
</h3>
|
84 |
-
<div class="file-type-options">
|
85 |
-
<input type="text" class="regular-text" name="ftp[url]" value="<?php echo esc_attr($post['ftp']['url']) ?>" disabled="disabled" /><br />
|
86 |
-
<input type="text" name="ftp[user]" title="username" style='width: 150px;' disabled="disabled"/><strong>:</strong><input type="password" name="ftp[pass]" title="passowrd" style='width: 150px;' disabled="disabled"/>
|
87 |
-
<div class="note"><?php _e('You may use an asterisk to load multiple files. For example, ftp://example.com/datafeeds/*.xml', 'pmxi_plugin') ?></div>
|
88 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=step-1&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade to the professional edition of WP All Import to use this feature.</a>
|
89 |
-
</div>
|
90 |
-
</div>
|
91 |
-
<div class="file-type-container">
|
92 |
-
<h3>
|
93 |
-
<input type="radio" id="type_file" name="type" value="file" />
|
94 |
-
<label for="type_file"><?php _e('Use Already Uploaded File', 'pmxi_plugin') ?></label>
|
95 |
-
</h3>
|
96 |
-
<div class="file-type-options">
|
97 |
-
<input type="text" id="__FILE_SOURCE" class="regular-text autocomplete" name="file" value="" disabled="disabled"/>
|
98 |
-
<?php
|
99 |
-
$local_files = array_merge(
|
100 |
-
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.xml', PMXI_Helper::GLOB_RECURSE),
|
101 |
-
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.gz', PMXI_Helper::GLOB_RECURSE),
|
102 |
-
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.zip', PMXI_Helper::GLOB_RECURSE),
|
103 |
-
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.csv', PMXI_Helper::GLOB_RECURSE)
|
104 |
-
);
|
105 |
-
sort($local_files);
|
106 |
-
?>
|
107 |
-
<script type="text/javascript">
|
108 |
-
__FILE_SOURCE = <?php echo json_encode($local_files) ?>;
|
109 |
-
</script>
|
110 |
-
<div class="note"><?php printf(__('Upload files to <strong>%s</strong> and they will appear in this list', 'pmxi_plugin'), PMXI_Plugin::ROOT_DIR . '/upload/') ?></div>
|
111 |
-
<a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=step-1&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade to the professional edition of WP All Import to use this feature.</a>
|
112 |
-
</div>
|
113 |
-
</div>
|
114 |
-
<div id="url_upload_status"></div>
|
115 |
-
<p class="submit-buttons">
|
116 |
-
<input type="hidden" name="is_submitted" value="1" />
|
117 |
-
<?php wp_nonce_field('choose-file', '_wpnonce_choose-file') ?>
|
118 |
-
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" id="advanced_upload"/>
|
119 |
-
</p>
|
120 |
-
<br />
|
121 |
-
<table><tr><td class="note"></td></tr></table>
|
122 |
-
</form>
|
123 |
-
</td>
|
124 |
-
<td class="right">
|
125 |
-
|
126 |
-
</td>
|
127 |
-
</tr>
|
128 |
-
</table>
|
1 |
+
<?php
|
2 |
+
|
3 |
+
$l10n = array(
|
4 |
+
'queue_limit_exceeded' => 'You have attempted to queue too many files.',
|
5 |
+
'file_exceeds_size_limit' => 'This file exceeds the maximum upload size for this site.',
|
6 |
+
'zero_byte_file' => 'This file is empty. Please try another.',
|
7 |
+
'invalid_filetype' => 'This file type is not allowed. Please try another.',
|
8 |
+
'default_error' => 'An error occurred in the upload. Please try again later.',
|
9 |
+
'missing_upload_url' => 'There was a configuration error. Please contact the server administrator.',
|
10 |
+
'upload_limit_exceeded' => 'You may only upload 1 file.',
|
11 |
+
'http_error' => 'HTTP error.',
|
12 |
+
'upload_failed' => 'Upload failed.',
|
13 |
+
'io_error' => 'IO error.',
|
14 |
+
'security_error' => 'Security error.',
|
15 |
+
'file_cancelled' => 'File canceled.',
|
16 |
+
'upload_stopped' => 'Upload stopped.',
|
17 |
+
'dismiss' => 'Dismiss',
|
18 |
+
'crunching' => 'Crunching…',
|
19 |
+
'deleted' => 'moved to the trash.',
|
20 |
+
'error_uploading' => 'has failed to upload due to an error',
|
21 |
+
'cancel_upload' => 'Cancel upload',
|
22 |
+
'dismiss' => 'Dismiss'
|
23 |
+
);
|
24 |
+
|
25 |
+
?>
|
26 |
+
<script type="text/javascript">
|
27 |
+
var plugin_url = '<?php echo PMXI_ROOT_URL; ?>';
|
28 |
+
var swfuploadL10n = <?php echo json_encode($l10n); ?>;
|
29 |
+
</script>
|
30 |
+
<table class="layout pmxi_step_1">
|
31 |
+
<tr>
|
32 |
+
<td class="left">
|
33 |
+
<h2><?php _e('Import XML/CSV - Step 1: Choose Your File', 'pmxi_plugin') ?></h2>
|
34 |
+
<h3><?php _e('Specify the file containing the data to be imported.', 'pmxi_plugin') ?></h3>
|
35 |
+
|
36 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
37 |
+
<?php $this->error() ?>
|
38 |
+
<?php endif ?>
|
39 |
+
<?php
|
40 |
+
if ( ! $reimported_import->isEmpty()):
|
41 |
+
?>
|
42 |
+
<div id="reimported_notify">
|
43 |
+
<p><?php _e( 'You are importing a new file for: <b>' . $reimported_import->name . '</b>' , 'pmxi_plugin' );?></p>
|
44 |
+
<p><span><?php _e( 'Last imported on ' . date("m-d-Y H:i:s", strtotime($reimported_import->registered_on)) , 'pmxi_plugin' ); ?></span></p>
|
45 |
+
</div>
|
46 |
+
<?php
|
47 |
+
endif;
|
48 |
+
?>
|
49 |
+
<form method="post" class="choose-file no-enter-submit" enctype="multipart/form-data" autocomplete="off">
|
50 |
+
<input type="hidden" name="is_submitted" value="1" />
|
51 |
+
<?php wp_nonce_field('upload-xml', '_wpnonce_upload-xml') ?>
|
52 |
+
<div class="file-type-container">
|
53 |
+
<h3>
|
54 |
+
<input type="radio" id="type_upload" name="type" value="upload" checked="checked" />
|
55 |
+
<label for="type_upload"><?php _e('Upload File From Your Computer', 'pmxi_plugin') ?></label>
|
56 |
+
</h3>
|
57 |
+
<div id="plupload-ui" class="file-type-options">
|
58 |
+
<div>
|
59 |
+
<h3 style="float:left; margin-top:5px;"><label><?php _e( 'Choose file to upload...' ); ?></label></h3>
|
60 |
+
<input type="hidden" name="filepath" value="<?php echo $post['filepath'] ?>" id="filepath"/>
|
61 |
+
<span><input id="select-files" type="button" value="<?php esc_attr_e('Select File'); ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" /></span>
|
62 |
+
<div id="progress" class="progress" <?php if (!empty($post['filepath'])):?>style="visibility: visible;"<?php endif;?>>
|
63 |
+
<div id="upload_process" class="upload_process"></div>
|
64 |
+
<div id="progressbar" class="progressbar"><?php if (!empty($post['filepath'])) _e( 'Import Complete - '.basename($post['filepath']).' 100%', 'pmxi_plugin'); ?></div>
|
65 |
+
</div>
|
66 |
+
</div>
|
67 |
+
</div>
|
68 |
+
</div>
|
69 |
+
<div class="file-type-container">
|
70 |
+
<h3>
|
71 |
+
<input type="radio" id="type_url" name="type" value="url" />
|
72 |
+
<label for="type_url"><?php _e('Download File From URL', 'pmxi_plugin') ?></label>
|
73 |
+
</h3>
|
74 |
+
<div class="file-type-options">
|
75 |
+
<input type="text" class="regular-text" name="url" value="" disabled="disabled" />
|
76 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=step-1&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade to the professional edition of WP All Import to use this feature.</a>
|
77 |
+
</div>
|
78 |
+
</div>
|
79 |
+
<div class="file-type-container">
|
80 |
+
<h3>
|
81 |
+
<input type="radio" id="type_ftp" name="type" value="ftp" />
|
82 |
+
<label for="type_ftp"><?php _e('Download File(s) From FTP Server', 'pmxi_plugin') ?></label>
|
83 |
+
</h3>
|
84 |
+
<div class="file-type-options">
|
85 |
+
<input type="text" class="regular-text" name="ftp[url]" value="<?php echo esc_attr($post['ftp']['url']) ?>" disabled="disabled" /><br />
|
86 |
+
<input type="text" name="ftp[user]" title="username" style='width: 150px;' disabled="disabled"/><strong>:</strong><input type="password" name="ftp[pass]" title="passowrd" style='width: 150px;' disabled="disabled"/>
|
87 |
+
<div class="note"><?php _e('You may use an asterisk to load multiple files. For example, ftp://example.com/datafeeds/*.xml', 'pmxi_plugin') ?></div>
|
88 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=step-1&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade to the professional edition of WP All Import to use this feature.</a>
|
89 |
+
</div>
|
90 |
+
</div>
|
91 |
+
<div class="file-type-container">
|
92 |
+
<h3>
|
93 |
+
<input type="radio" id="type_file" name="type" value="file" />
|
94 |
+
<label for="type_file"><?php _e('Use Already Uploaded File', 'pmxi_plugin') ?></label>
|
95 |
+
</h3>
|
96 |
+
<div class="file-type-options">
|
97 |
+
<input type="text" id="__FILE_SOURCE" class="regular-text autocomplete" name="file" value="" disabled="disabled"/>
|
98 |
+
<?php
|
99 |
+
$local_files = array_merge(
|
100 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.xml', PMXI_Helper::GLOB_RECURSE),
|
101 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.gz', PMXI_Helper::GLOB_RECURSE),
|
102 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.zip', PMXI_Helper::GLOB_RECURSE),
|
103 |
+
PMXI_Helper::safe_glob(PMXI_Plugin::ROOT_DIR . '/upload/*.csv', PMXI_Helper::GLOB_RECURSE)
|
104 |
+
);
|
105 |
+
sort($local_files);
|
106 |
+
?>
|
107 |
+
<script type="text/javascript">
|
108 |
+
__FILE_SOURCE = <?php echo json_encode($local_files) ?>;
|
109 |
+
</script>
|
110 |
+
<div class="note"><?php printf(__('Upload files to <strong>%s</strong> and they will appear in this list', 'pmxi_plugin'), PMXI_Plugin::ROOT_DIR . '/upload/') ?></div>
|
111 |
+
<a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=step-1&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade to the professional edition of WP All Import to use this feature.</a>
|
112 |
+
</div>
|
113 |
+
</div>
|
114 |
+
<div id="url_upload_status"></div>
|
115 |
+
<p class="submit-buttons">
|
116 |
+
<input type="hidden" name="is_submitted" value="1" />
|
117 |
+
<?php wp_nonce_field('choose-file', '_wpnonce_choose-file') ?>
|
118 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Next', 'pmxi_plugin') ?>" id="advanced_upload"/>
|
119 |
+
</p>
|
120 |
+
<br />
|
121 |
+
<table><tr><td class="note"></td></tr></table>
|
122 |
+
</form>
|
123 |
+
</td>
|
124 |
+
<td class="right">
|
125 |
+
|
126 |
+
</td>
|
127 |
+
</tr>
|
128 |
+
</table>
|
views/admin/import/options.php
CHANGED
@@ -1,198 +1,195 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if (!function_exists('reverse_taxonomies_html')) {
|
4 |
-
function reverse_taxonomies_html($post_taxonomies, $item_id, &$i){
|
5 |
-
$childs = array();
|
6 |
-
foreach ($post_taxonomies as $j => $cat) if ($cat->parent_id == $item_id) { $childs[] = $cat; }
|
7 |
-
|
8 |
-
if (!empty($childs)){
|
9 |
-
?>
|
10 |
-
<ol>
|
11 |
-
<?php
|
12 |
-
foreach ($childs as $child_cat){
|
13 |
-
$i++;
|
14 |
-
?>
|
15 |
-
<li id="item_<?php echo $i; ?>">
|
16 |
-
<div class="drag-element">
|
17 |
-
<input type="checkbox" class="assign_post" <?php if ($child_cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
|
18 |
-
<input class="widefat" type="text" value="<?php echo esc_attr($child_cat->xpath); ?>"/>
|
19 |
-
</div>
|
20 |
-
<a href="javascript:void(0);" class="icon-item remove-ico"></a>
|
21 |
-
<?php echo reverse_taxonomies_html($post_taxonomies, $child_cat->item_id, $i); ?>
|
22 |
-
</li>
|
23 |
-
<?php
|
24 |
-
}
|
25 |
-
?>
|
26 |
-
</ol>
|
27 |
-
<?php
|
28 |
-
}
|
29 |
-
}
|
30 |
-
}
|
31 |
-
?>
|
32 |
-
<?php $custom_types = get_post_types(array('_builtin' => false), 'objects'); ?>
|
33 |
-
<input type="hidden" id="selected_post_type" value="<?php echo (!empty($post['custom_type'])) ? $post['custom_type'] : '';?>">
|
34 |
-
<input type="hidden" id="selected_type" value="<?php echo (!empty($post['type'])) ? $post['type'] : '';?>">
|
35 |
-
<h2>
|
36 |
-
<?php if ($this->isWizard): ?>
|
37 |
-
<?php _e('Import XML/CSV - Step 4: Options', 'pmxi_plugin') ?>
|
38 |
-
<?php else: ?>
|
39 |
-
<?php _e('Edit Import Options', 'pmxi_plugin') ?>
|
40 |
-
<?php endif ?>
|
41 |
-
</h2>
|
42 |
-
<h3
|
43 |
-
|
44 |
-
|
45 |
-
<?php $this->
|
46 |
-
<?php
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
</
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
<li><a href="#tabs-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
include( 'options/
|
92 |
-
include( 'options/
|
93 |
-
include( 'options/
|
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 |
-
</td>
|
126 |
-
<td align="center" width="33%">
|
127 |
-
<label><?php _e('
|
128 |
-
|
129 |
-
</td>
|
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 |
-
include( 'options/
|
172 |
-
include( 'options/
|
173 |
-
include( 'options/
|
174 |
-
include( 'options/
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
</td>
|
196 |
-
<?php endif ?>
|
197 |
-
</tr>
|
198 |
</table>
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if (!function_exists('reverse_taxonomies_html')) {
|
4 |
+
function reverse_taxonomies_html($post_taxonomies, $item_id, &$i){
|
5 |
+
$childs = array();
|
6 |
+
foreach ($post_taxonomies as $j => $cat) if ($cat->parent_id == $item_id) { $childs[] = $cat; }
|
7 |
+
|
8 |
+
if (!empty($childs)){
|
9 |
+
?>
|
10 |
+
<ol>
|
11 |
+
<?php
|
12 |
+
foreach ($childs as $child_cat){
|
13 |
+
$i++;
|
14 |
+
?>
|
15 |
+
<li id="item_<?php echo $i; ?>">
|
16 |
+
<div class="drag-element">
|
17 |
+
<input type="checkbox" class="assign_post" <?php if ($child_cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"/>
|
18 |
+
<input class="widefat" type="text" value="<?php echo esc_attr($child_cat->xpath); ?>"/>
|
19 |
+
</div>
|
20 |
+
<a href="javascript:void(0);" class="icon-item remove-ico"></a>
|
21 |
+
<?php echo reverse_taxonomies_html($post_taxonomies, $child_cat->item_id, $i); ?>
|
22 |
+
</li>
|
23 |
+
<?php
|
24 |
+
}
|
25 |
+
?>
|
26 |
+
</ol>
|
27 |
+
<?php
|
28 |
+
}
|
29 |
+
}
|
30 |
+
}
|
31 |
+
?>
|
32 |
+
<?php $custom_types = get_post_types(array('_builtin' => false), 'objects'); ?>
|
33 |
+
<input type="hidden" id="selected_post_type" value="<?php echo (!empty($post['custom_type'])) ? $post['custom_type'] : '';?>">
|
34 |
+
<input type="hidden" id="selected_type" value="<?php echo (!empty($post['type'])) ? $post['type'] : '';?>">
|
35 |
+
<h2>
|
36 |
+
<?php if ($this->isWizard): ?>
|
37 |
+
<?php _e('Import XML/CSV - Step 4: Options', 'pmxi_plugin') ?>
|
38 |
+
<?php else: ?>
|
39 |
+
<?php _e('Edit Import Options', 'pmxi_plugin') ?>
|
40 |
+
<?php endif ?>
|
41 |
+
</h2>
|
42 |
+
<h3><?php _e('Click the appropriate tab to choose the type of posts to create.', 'pmxi_plugin');?></h3>
|
43 |
+
|
44 |
+
<div class="ajax-console">
|
45 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
46 |
+
<?php $this->error() ?>
|
47 |
+
<?php endif ?>
|
48 |
+
</div>
|
49 |
+
|
50 |
+
<table class="layout">
|
51 |
+
<tr>
|
52 |
+
<td class="left">
|
53 |
+
<?php $templates = new PMXI_Template_List() ?>
|
54 |
+
<form class="load_options options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
55 |
+
<div class="load-template">
|
56 |
+
<span><?php _e('Load existing template:','pmxi_plugin');?> </span>
|
57 |
+
<select name="load_template">
|
58 |
+
<option value=""><?php _e('Load Template...', 'pmxi_plugin') ?></option>
|
59 |
+
<?php foreach ($templates->getBy()->convertRecords() as $t): ?>
|
60 |
+
<option value="<?php echo $t->id ?>"><?php echo $t->name ?></option>
|
61 |
+
<?php endforeach ?>
|
62 |
+
<option value="-1"><?php _e('Reset...', 'pmxi_plugin') ?></option>
|
63 |
+
</select>
|
64 |
+
</div>
|
65 |
+
</form>
|
66 |
+
<div id="pmxi_tabs">
|
67 |
+
<ul>
|
68 |
+
<li><a href="#tabs-1">Posts</a></li>
|
69 |
+
<li><a href="#tabs-2">Pages</a></li>
|
70 |
+
<!-- WooCommerce Add-On -->
|
71 |
+
<?php
|
72 |
+
if (class_exists('PMWI_Plugin')):
|
73 |
+
?>
|
74 |
+
<li><a href="#tabs-woo-product">WooCommerce Products</a></li>
|
75 |
+
<?php
|
76 |
+
endif;
|
77 |
+
?>
|
78 |
+
</ul>
|
79 |
+
|
80 |
+
<!-- Post Options -->
|
81 |
+
|
82 |
+
<div id="tabs-1"> <!-- Basic -->
|
83 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
84 |
+
<input type="hidden" name="type" value="post"/>
|
85 |
+
<input type="hidden" name="custom_type" value=""/>
|
86 |
+
<div class="post-type-options">
|
87 |
+
<table class="form-table" style="max-width:none;">
|
88 |
+
<?php
|
89 |
+
$post_type = 'post';
|
90 |
+
$entry = 'post';
|
91 |
+
include( 'options/_main_options_template.php' );
|
92 |
+
include( 'options/_taxonomies_template.php' );
|
93 |
+
include( 'options/_categories_template.php' );
|
94 |
+
include( 'options/_custom_fields_template.php' );
|
95 |
+
include( 'options/_featured_template.php' );
|
96 |
+
include( 'options/_author_template.php' );
|
97 |
+
include( 'options/_reimport_template.php' );
|
98 |
+
?>
|
99 |
+
</table>
|
100 |
+
</div>
|
101 |
+
|
102 |
+
<?php include( 'options/_buttons_template.php' ); ?>
|
103 |
+
|
104 |
+
</form>
|
105 |
+
</div>
|
106 |
+
|
107 |
+
<!-- Page Options -->
|
108 |
+
|
109 |
+
<div id="tabs-2">
|
110 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
111 |
+
<input type="hidden" name="type" value="page"/>
|
112 |
+
<input type="hidden" name="custom_type" value=""/>
|
113 |
+
<div class="post-type-options">
|
114 |
+
<table class="form-table" style="max-width:none;">
|
115 |
+
|
116 |
+
<?php include( 'options/_main_options_template.php' ); ?>
|
117 |
+
|
118 |
+
<tr>
|
119 |
+
<td align="center" width="33%">
|
120 |
+
<label><?php _e('Page Template', 'pmxi_plugin') ?></label> <br>
|
121 |
+
<select name="page_template" id="page_template">
|
122 |
+
<option value='default'><?php _e('Default', 'pmxi_plugin') ?></option>
|
123 |
+
<?php page_template_dropdown($post['page_template']); ?>
|
124 |
+
</select>
|
125 |
+
</td>
|
126 |
+
<td align="center" width="33%">
|
127 |
+
<label><?php _e('Parent Page', 'pmxi_plugin') ?></label> <br>
|
128 |
+
<?php wp_dropdown_pages(array('post_type' => 'page', 'selected' => $post['parent'], 'name' => 'parent', 'show_option_none' => __('(no parent)', 'pmxi_plugin'), 'sort_column'=> 'menu_order, post_title',)) ?>
|
129 |
+
</td>
|
130 |
+
<td align="center" width="33%">
|
131 |
+
<label><?php _e('Order', 'pmxi_plugin') ?></label> <br>
|
132 |
+
<input type="text" class="" name="order" value="<?php echo esc_attr($post['order']) ?>" />
|
133 |
+
</td>
|
134 |
+
</tr>
|
135 |
+
<?php
|
136 |
+
$post_type = 'post';
|
137 |
+
$entry = 'page';
|
138 |
+
include( 'options/_taxonomies_template.php' );
|
139 |
+
include( 'options/_featured_template.php' );
|
140 |
+
include( 'options/_reimport_template.php' );
|
141 |
+
?>
|
142 |
+
</table>
|
143 |
+
</div>
|
144 |
+
|
145 |
+
<?php include( 'options/_buttons_template.php' ); ?>
|
146 |
+
|
147 |
+
</form>
|
148 |
+
</div>
|
149 |
+
|
150 |
+
<!-- WooCommerce Add-On -->
|
151 |
+
<?php
|
152 |
+
if (class_exists('PMWI_Plugin')):
|
153 |
+
?>
|
154 |
+
<div id="tabs-woo-product">
|
155 |
+
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
156 |
+
<input type="hidden" name="custom_type" value="product"/>
|
157 |
+
<input type="hidden" name="type" value="post"/>
|
158 |
+
<div class="post-type-options">
|
159 |
+
<table class="form-table" style="max-width:none;">
|
160 |
+
<?php
|
161 |
+
|
162 |
+
$post_type = $entry = 'product';
|
163 |
+
|
164 |
+
include( 'options/_main_options_template.php' );
|
165 |
+
|
166 |
+
$woo_controller = new PMWI_Admin_Import();
|
167 |
+
$woo_controller->index();
|
168 |
+
|
169 |
+
include( 'options/_taxonomies_template.php' );
|
170 |
+
include( 'options/_custom_fields_template.php' );
|
171 |
+
include( 'options/_featured_template.php' );
|
172 |
+
include( 'options/_author_template.php' );
|
173 |
+
include( 'options/_reimport_template.php' );
|
174 |
+
include( 'options/_scheduling_template.php' );
|
175 |
+
|
176 |
+
?>
|
177 |
+
</table>
|
178 |
+
</div>
|
179 |
+
|
180 |
+
<?php include( 'options/_buttons_template.php' ); ?>
|
181 |
+
|
182 |
+
</form>
|
183 |
+
</div>
|
184 |
+
<?php
|
185 |
+
endif;
|
186 |
+
?>
|
187 |
+
</div>
|
188 |
+
</td>
|
189 |
+
<?php if ($this->isWizard or $this->isTemplateEdit): ?>
|
190 |
+
<td class="right options">
|
191 |
+
<?php $this->tag() ?>
|
192 |
+
</td>
|
193 |
+
<?php endif ?>
|
194 |
+
</tr>
|
|
|
|
|
|
|
195 |
</table>
|
views/admin/import/options/_author_template.php
CHANGED
@@ -1,20 +1,20 @@
|
|
1 |
-
<tr>
|
2 |
-
<td colspan="3">
|
3 |
-
<h3><?php _e('Post Author', 'pmxi_plugin') ?></h3>
|
4 |
-
<div>
|
5 |
-
<input type="text" name="author" value="<?php echo esc_attr($post['author']) ?>"
|
6 |
-
</div>
|
7 |
-
</td>
|
8 |
-
</tr>
|
9 |
-
<tr>
|
10 |
-
<td colspan="3">
|
11 |
-
<h3><?php _e('Post Excerpt', 'pmxi_plugin') ?></h3>
|
12 |
-
<div>
|
13 |
-
<input type="text" name="post_excerpt" style="width:100%;" value="<?php echo esc_attr($post['post_excerpt']) ?>"
|
14 |
-
</div>
|
15 |
-
<h3><?php _e('Post Slug', 'pmxi_plugin') ?></h3>
|
16 |
-
<div>
|
17 |
-
<input type="text" name="post_slug" style="width:100%;" value="<?php echo esc_attr($post['post_slug']) ?>"
|
18 |
-
</div> <br><br>
|
19 |
-
</td>
|
20 |
</tr>
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<h3><?php _e('Post Author', 'pmxi_plugin') ?></h3>
|
4 |
+
<div>
|
5 |
+
<input type="text" name="author" value="<?php echo esc_attr($post['author']) ?>" /> <a href="#help" class="help" title="<?php _e('Value that contains user ID, login, slug or email.', 'pmxi_plugin') ?>">?</a>
|
6 |
+
</div>
|
7 |
+
</td>
|
8 |
+
</tr>
|
9 |
+
<tr>
|
10 |
+
<td colspan="3">
|
11 |
+
<h3><?php _e('Post Excerpt', 'pmxi_plugin') ?></h3>
|
12 |
+
<div>
|
13 |
+
<input type="text" name="post_excerpt" style="width:100%;" value="<?php echo esc_attr($post['post_excerpt']) ?>" />
|
14 |
+
</div>
|
15 |
+
<h3><?php _e('Post Slug', 'pmxi_plugin') ?></h3>
|
16 |
+
<div>
|
17 |
+
<input type="text" name="post_slug" style="width:100%;" value="<?php echo esc_attr($post['post_slug']) ?>" />
|
18 |
+
</div> <br><br>
|
19 |
+
</td>
|
20 |
</tr>
|
views/admin/import/options/_buttons_template.php
CHANGED
@@ -1,61 +1,66 @@
|
|
1 |
-
<br>
|
2 |
-
<div class="input">
|
3 |
-
<label for="save_import_as"
|
4 |
-
</div>
|
5 |
-
<br>
|
6 |
-
<?php if ($_SESSION['pmxi_import']['large_file'] or (!empty($import) and $import->large_import == 'Yes')):?>
|
7 |
-
<div class="input">
|
8 |
-
<label for="records_per_request"
|
9 |
-
<a href="#help" class="help" title="<?php _e('Your feed was detected as a "large" file. The import process will be executed via AJAX requests. To make import process faster you can increase the number of records imported per iteration. Higher numbers put more strain on your server but make the import process take less time. 10 is a very safe number. To speed up the process, try 100 or more, especially if your import settings are simple and you are not downloading images.', 'pmxi_plugin') ?>">?</a>
|
10 |
-
</div>
|
11 |
-
<div class="input">
|
12 |
-
<input type="hidden" name="create_chunks" value="0" />
|
13 |
-
<input type="checkbox" id="create_chunks_<?php echo $entry; ?>" name="create_chunks" value="1" <?php echo $post['create_chunks'] ? 'checked="checked"': ''
|
14 |
-
<label for="create_chunks_<?php echo $entry; ?>"><?php _e('create chunks', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('
|
15 |
-
</div>
|
16 |
-
<br>
|
17 |
-
<?php endif; ?>
|
18 |
-
<div class="input">
|
19 |
-
<input type="hidden" name="is_import_specified" value="0" />
|
20 |
-
<input type="checkbox" id="is_import_specified_<?php echo $entry; ?>" class="switcher" name="is_import_specified" value="1" <?php echo $post['is_import_specified'] ? 'checked="checked"': ''
|
21 |
-
<label for="is_import_specified_<?php echo $entry; ?>"><?php _e('Import only specified records', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter records or record ranges separated by commas, e.g. <b>1,5,7-10</b> would import the first, the fifth, and the seventh to tenth.', 'pmxi_plugin') ?>">?</a></label>
|
22 |
-
<span class="switcher-target-is_import_specified_<?php echo $entry; ?>" style="vertical-align:middle">
|
23 |
-
<div class="input" style="display:inline;">
|
24 |
-
<input type="text" name="import_specified" value="<?php echo esc_attr($post['import_specified']) ?>" style="width:50%;"
|
25 |
-
</div>
|
26 |
-
</span>
|
27 |
-
</div>
|
28 |
-
|
29 |
-
<div class="input">
|
30 |
-
<input type="
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
<
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
<
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
<?php
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
61 |
</p>
|
1 |
+
<br>
|
2 |
+
<div class="input">
|
3 |
+
<label for="save_import_as"><?php _e('Friendly Name','pmxi_plugin');?></label> <input type="text" name="friendly_name" title="<?php _e('Save friendly name...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:11px; background:#fff !important;" value="<?php echo esc_attr($post['friendly_name']) ?>" />
|
4 |
+
</div>
|
5 |
+
<br>
|
6 |
+
<?php if ($_SESSION['pmxi_import']['large_file'] or (!empty($import) and $import->large_import == 'Yes')):?>
|
7 |
+
<div class="input">
|
8 |
+
<label for="records_per_request"><?php _e('Records Per Iteration', 'pmxi_plugin');?></label> <input type="text" name="records_per_request" style="vertical-align:middle; font-size:11px; background:#fff !important; width: 40px;" value="<?php echo esc_attr($post['records_per_request']) ?>" />
|
9 |
+
<a href="#help" class="help" title="<?php _e('Your feed was detected as a "large" file. The import process will be executed via AJAX requests. To make import process faster you can increase the number of records imported per iteration. Higher numbers put more strain on your server but make the import process take less time. 10 is a very safe number. To speed up the process, try 100 or more, especially if your import settings are simple and you are not downloading images.', 'pmxi_plugin') ?>">?</a>
|
10 |
+
</div>
|
11 |
+
<div class="input">
|
12 |
+
<input type="hidden" name="create_chunks" value="0" />
|
13 |
+
<input type="checkbox" id="create_chunks_<?php echo $entry; ?>" name="create_chunks" value="1" <?php echo $post['create_chunks'] ? 'checked="checked"': '' ?>/>
|
14 |
+
<label for="create_chunks_<?php echo $entry; ?>"><?php _e('create chunks', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Check this to split up the file into pieces before import. Will speed up the import of large files.', 'pmxi_plugin') ?>">?</a></label>
|
15 |
+
</div>
|
16 |
+
<br>
|
17 |
+
<?php endif; ?>
|
18 |
+
<div class="input">
|
19 |
+
<input type="hidden" name="is_import_specified" value="0" />
|
20 |
+
<input type="checkbox" id="is_import_specified_<?php echo $entry; ?>" class="switcher" name="is_import_specified" value="1" <?php echo $post['is_import_specified'] ? 'checked="checked"': '' ?>/>
|
21 |
+
<label for="is_import_specified_<?php echo $entry; ?>"><?php _e('Import only specified records', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter records or record ranges separated by commas, e.g. <b>1,5,7-10</b> would import the first, the fifth, and the seventh to tenth.', 'pmxi_plugin') ?>">?</a></label>
|
22 |
+
<span class="switcher-target-is_import_specified_<?php echo $entry; ?>" style="vertical-align:middle">
|
23 |
+
<div class="input" style="display:inline;">
|
24 |
+
<input type="text" name="import_specified" value="<?php echo esc_attr($post['import_specified']) ?>" style="width:50%;"/>
|
25 |
+
</div>
|
26 |
+
</span>
|
27 |
+
</div>
|
28 |
+
<p>
|
29 |
+
<div class="input">
|
30 |
+
<input type="checkbox" id="save_template_as_<?php echo $entry; ?>" name="save_template_as" value="1" <?php echo $post['save_template_as'] ? 'checked="checked"' : '' ?> style="position:relative; top:-2px;"/> <label for="save_template_as_<?php echo $entry; ?>"><?php _e('Save template as:','pmxi_plugin');?></label> <input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo esc_attr($post['name']) ?>" />
|
31 |
+
</div>
|
32 |
+
</p>
|
33 |
+
<?php if (in_array($source_type, array('ftp', 'file'))): ?>
|
34 |
+
<div class="input">
|
35 |
+
<input type="hidden" name="is_delete_source" value="0" />
|
36 |
+
<input type="checkbox" id="is_delete_source_<?php echo $entry; ?>" name="is_delete_source" value="1" <?php echo $post['is_delete_source'] ? 'checked="checked"': '' ?>/>
|
37 |
+
<label for="is_delete_source_<?php echo $entry; ?>"><?php _e('Delete source XML file after importing', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('This setting takes effect only when script has access rights to perform the action, e.g. file is not deleted when pulled via HTTP or delete permission is not granted to the user that script is executed under.', 'pmxi_plugin') ?>">?</a></label>
|
38 |
+
</div>
|
39 |
+
<?php endif; ?>
|
40 |
+
<?php if (class_exists('PMLC_Plugin')): // option is only valid when `WP Wizard Cloak` pluign is enabled ?>
|
41 |
+
<div class="input">
|
42 |
+
<input type="hidden" name="is_cloak" value="0" />
|
43 |
+
<input type="checkbox" id="is_cloak_<?php echo $entry; ?>" name="is_cloak" value="1" <?php echo $post['is_cloak'] ? 'checked="checked"': '' ?>/>
|
44 |
+
<label for="is_cloak_<?php echo $entry; ?>"><?php _e('Auto-Cloak Links', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php printf(__('Automatically process all links present in body of created post or page with <b>%s</b> plugin', 'pmxi_plugin'), PMLC_Plugin::getInstance()->getName()) ?>">?</a></label>
|
45 |
+
</div> <br>
|
46 |
+
<?php endif; ?>
|
47 |
+
<p class="submit-buttons">
|
48 |
+
<?php wp_nonce_field('options', '_wpnonce_options') ?>
|
49 |
+
<input type="hidden" name="is_submitted" value="1" />
|
50 |
+
|
51 |
+
<?php if ($this->isWizard): ?>
|
52 |
+
|
53 |
+
<a href="<?php echo add_query_arg('action', 'template', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
54 |
+
|
55 |
+
<?php if (in_array($source_type, array('url', 'ftp', 'file'))): ?>
|
56 |
+
<input type="hidden" class="save_only" value="0" name="save_only"/>
|
57 |
+
<span style="font-size:16px;">or</span> <input type="submit" name="btn_save_only" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Save Only', 'pmxi_plugin') ?>" />
|
58 |
+
<?php endif ?>
|
59 |
+
|
60 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Finish', 'pmxi_plugin') ?>" />
|
61 |
+
|
62 |
+
<?php else: ?>
|
63 |
+
<a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
64 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e('Save', 'pmxi_plugin') ?>" />
|
65 |
+
<?php endif ?>
|
66 |
</p>
|
views/admin/import/options/_categories_template.php
CHANGED
@@ -1,67 +1,67 @@
|
|
1 |
-
<tr>
|
2 |
-
<td colspan="3">
|
3 |
-
<div class="col2">
|
4 |
-
<fieldset style="margin-left:0px;">
|
5 |
-
<legend><?php _e('Categories', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Uncheck a box and the category will still be created, but the post will not be assigned to it.', 'pmxi_plugin') ?>">?</a></legend>
|
6 |
-
<ol class="sortable no-margin">
|
7 |
-
<?php if (!empty($post['categories'])):?>
|
8 |
-
<?php
|
9 |
-
$categories = json_decode($post['categories']);
|
10 |
-
|
11 |
-
if (empty($categories)) $categories = explode(',', $post['categories']);
|
12 |
-
|
13 |
-
if (!empty($categories) and is_array($categories)): $i = 0; foreach ($categories as $cat) { $i++;
|
14 |
-
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
15 |
-
{
|
16 |
-
?>
|
17 |
-
<li id="item_<?php echo $i; ?>">
|
18 |
-
<div class="drag-element">
|
19 |
-
<input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"
|
20 |
-
<input type="text" class="widefat" value="<?php echo (is_object($cat)) ? esc_attr($cat->xpath) : esc_attr($cat); ?>"
|
21 |
-
</div>
|
22 |
-
<?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
|
23 |
-
<?php if (is_object($cat)) echo reverse_taxonomies_html($categories, $cat->item_id, $i); ?>
|
24 |
-
</li>
|
25 |
-
<?php
|
26 |
-
}
|
27 |
-
}; else: ?>
|
28 |
-
<li id="item_1">
|
29 |
-
<div class="drag-element">
|
30 |
-
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"
|
31 |
-
<input type="text" class="widefat" value=""
|
32 |
-
</div>
|
33 |
-
</li>
|
34 |
-
<?php endif;?>
|
35 |
-
<?php else: ?>
|
36 |
-
<li id="item_1">
|
37 |
-
<div class="drag-element">
|
38 |
-
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"
|
39 |
-
<input type="text" class="widefat" value=""
|
40 |
-
</div>
|
41 |
-
</li>
|
42 |
-
<?php endif; ?>
|
43 |
-
</ol>
|
44 |
-
<?php if ($post_type == "post"):?><a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more', 'pmxi_plugin');?></a><?php endif; ?> <br><br>
|
45 |
-
<input type="hidden" class="hierarhy-output" name="categories" value="<?php echo esc_attr($post['categories']) ?>"/>
|
46 |
-
<div class="hidden" id="dialog-confirm-category-removing" title="Delete categories?"><?php _e('Remove only current category or current category with subcategories?', 'pmxi_plugin');?></div>
|
47 |
-
<div class="delim">
|
48 |
-
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
49 |
-
<input type="text" class="small" name="categories_delim" value="<?php echo esc_attr($post['categories_delim']) ?>"
|
50 |
-
<label for="categories_auto_nested"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
|
51 |
-
<input type="checkbox" id="categories_auto_nested" name="categories_auto_nested" <?php if ($post['categories_auto_nested']):?>checked="checked"<?php endif; ?>
|
52 |
-
<a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>></code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
|
53 |
-
</div>
|
54 |
-
</fieldset>
|
55 |
-
</div>
|
56 |
-
<div class="col2">
|
57 |
-
<fieldset style="padding:5px; margin-right:0px;">
|
58 |
-
<legend><?php _e('Tags', 'pmxi_plugin') ?> </legend>
|
59 |
-
<input type="text" name="tags" class="widefat" value="<?php echo esc_attr($post['tags']) ?>"
|
60 |
-
<div class="delim">
|
61 |
-
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
62 |
-
<input type="text" class="small" name="tags_delim" value="<?php echo esc_attr($post['tags_delim']) ?>"
|
63 |
-
</div>
|
64 |
-
</fieldset>
|
65 |
-
</div>
|
66 |
-
</td>
|
67 |
</tr>
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<div class="col2">
|
4 |
+
<fieldset style="margin-left:0px;">
|
5 |
+
<legend><?php _e('Categories', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Uncheck a box and the category will still be created, but the post will not be assigned to it.', 'pmxi_plugin') ?>">?</a></legend>
|
6 |
+
<ol class="sortable no-margin">
|
7 |
+
<?php if (!empty($post['categories'])):?>
|
8 |
+
<?php
|
9 |
+
$categories = json_decode($post['categories']);
|
10 |
+
|
11 |
+
if (empty($categories)) $categories = explode(',', $post['categories']);
|
12 |
+
|
13 |
+
if (!empty($categories) and is_array($categories)): $i = 0; foreach ($categories as $cat) { $i++;
|
14 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
15 |
+
{
|
16 |
+
?>
|
17 |
+
<li id="item_<?php echo $i; ?>">
|
18 |
+
<div class="drag-element">
|
19 |
+
<input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
|
20 |
+
<input type="text" class="widefat" value="<?php echo (is_object($cat)) ? esc_attr($cat->xpath) : esc_attr($cat); ?>" />
|
21 |
+
</div>
|
22 |
+
<?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
|
23 |
+
<?php if (is_object($cat)) echo reverse_taxonomies_html($categories, $cat->item_id, $i); ?>
|
24 |
+
</li>
|
25 |
+
<?php
|
26 |
+
}
|
27 |
+
}; else: ?>
|
28 |
+
<li id="item_1">
|
29 |
+
<div class="drag-element">
|
30 |
+
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
|
31 |
+
<input type="text" class="widefat" value="" />
|
32 |
+
</div>
|
33 |
+
</li>
|
34 |
+
<?php endif;?>
|
35 |
+
<?php else: ?>
|
36 |
+
<li id="item_1">
|
37 |
+
<div class="drag-element">
|
38 |
+
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
|
39 |
+
<input type="text" class="widefat" value="" />
|
40 |
+
</div>
|
41 |
+
</li>
|
42 |
+
<?php endif; ?>
|
43 |
+
</ol>
|
44 |
+
<?php if ($post_type == "post"):?><a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more', 'pmxi_plugin');?></a><?php endif; ?> <br><br>
|
45 |
+
<input type="hidden" class="hierarhy-output" name="categories" value="<?php echo esc_attr($post['categories']) ?>"/>
|
46 |
+
<div class="hidden" id="dialog-confirm-category-removing" title="Delete categories?"><?php _e('Remove only current category or current category with subcategories?', 'pmxi_plugin');?></div>
|
47 |
+
<div class="delim">
|
48 |
+
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
49 |
+
<input type="text" class="small" name="categories_delim" value="<?php echo esc_attr($post['categories_delim']) ?>" />
|
50 |
+
<label for="categories_auto_nested"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
|
51 |
+
<input type="checkbox" id="categories_auto_nested" name="categories_auto_nested" <?php if ($post['categories_auto_nested']):?>checked="checked"<?php endif; ?> />
|
52 |
+
<a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>></code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
|
53 |
+
</div>
|
54 |
+
</fieldset>
|
55 |
+
</div>
|
56 |
+
<div class="col2">
|
57 |
+
<fieldset style="padding:5px; margin-right:0px;">
|
58 |
+
<legend><?php _e('Tags', 'pmxi_plugin') ?> </legend>
|
59 |
+
<input type="text" name="tags" class="widefat" value="<?php echo esc_attr($post['tags']) ?>" /> <br> <br>
|
60 |
+
<div class="delim">
|
61 |
+
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
62 |
+
<input type="text" class="small" name="tags_delim" value="<?php echo esc_attr($post['tags_delim']) ?>" />
|
63 |
+
</div>
|
64 |
+
</fieldset>
|
65 |
+
</div>
|
66 |
+
</td>
|
67 |
</tr>
|
views/admin/import/options/_custom_fields_template.php
CHANGED
@@ -1,54 +1,54 @@
|
|
1 |
-
<tr>
|
2 |
-
<td colspan="3" style="border-bottom:1px solid #ccc;">
|
3 |
-
<fieldset class="optionsset" style="text-align:center;">
|
4 |
-
<legend>Custom Fields</legend>
|
5 |
-
|
6 |
-
<center>
|
7 |
-
|
8 |
-
<h3>Please upgrade to the professional edition of WP All Import to import data to Custom Fields.</h3>
|
9 |
-
|
10 |
-
<p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=custom-fields&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
|
11 |
-
|
12 |
-
<hr />
|
13 |
-
|
14 |
-
</center>
|
15 |
-
|
16 |
-
|
17 |
-
<table class="form-table custom-params" style="max-width:none; border:none;">
|
18 |
-
<thead>
|
19 |
-
<tr>
|
20 |
-
<td><?php _e('Name', 'pmxi_plugin') ?></td>
|
21 |
-
<td><?php _e('Value', 'pmxi_plugin') ?></td>
|
22 |
-
<td></td>
|
23 |
-
</tr>
|
24 |
-
</thead>
|
25 |
-
<tbody>
|
26 |
-
<tr class="form-field">
|
27 |
-
<td><input type="text" name="custom_name[]" value="" disabled="disabled" /></td>
|
28 |
-
<td class="action remove">
|
29 |
-
<textarea name="custom_value[]" disabled="disabled"></textarea>
|
30 |
-
</td>
|
31 |
-
</tr>
|
32 |
-
<tr>
|
33 |
-
<td colspan="3"><a href="#add" title="<?php _e('add', 'pmxi_plugin')?>" class="action add-new-custom"><?php _e('Add more', 'pmxi_plugin') ?></a></td>
|
34 |
-
</tr>
|
35 |
-
</tbody>
|
36 |
-
</table>
|
37 |
-
<select class="existing_meta_keys">
|
38 |
-
<option value="">Existing Custom Fields...</option>
|
39 |
-
<?php
|
40 |
-
$hide_fields = array('_wp_page_template', '_edit_lock', '_edit_last', '_wp_trash_meta_status', '_wp_trash_meta_time');
|
41 |
-
if (!empty($meta_keys) and $meta_keys->count()):
|
42 |
-
foreach ($meta_keys as $meta_key) { if (in_array($meta_key['meta_key'], $hide_fields) or strpos($meta_key['meta_key'], '_wp') === 0) continue;
|
43 |
-
?>
|
44 |
-
<option value="<?php echo $meta_key['meta_key'];?>"><?php echo $meta_key['meta_key'];?></option>
|
45 |
-
<?php
|
46 |
-
}
|
47 |
-
endif;
|
48 |
-
?>
|
49 |
-
</select>
|
50 |
-
|
51 |
-
</fieldset>
|
52 |
-
<br>
|
53 |
-
</td>
|
54 |
</tr>
|
1 |
+
<tr>
|
2 |
+
<td colspan="3" style="border-bottom:1px solid #ccc;">
|
3 |
+
<fieldset class="optionsset" style="text-align:center;">
|
4 |
+
<legend>Custom Fields</legend>
|
5 |
+
|
6 |
+
<center>
|
7 |
+
|
8 |
+
<h3>Please upgrade to the professional edition of WP All Import to import data to Custom Fields.</h3>
|
9 |
+
|
10 |
+
<p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=custom-fields&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
|
11 |
+
|
12 |
+
<hr />
|
13 |
+
|
14 |
+
</center>
|
15 |
+
|
16 |
+
|
17 |
+
<table class="form-table custom-params" style="max-width:none; border:none;">
|
18 |
+
<thead>
|
19 |
+
<tr>
|
20 |
+
<td><?php _e('Name', 'pmxi_plugin') ?></td>
|
21 |
+
<td><?php _e('Value', 'pmxi_plugin') ?></td>
|
22 |
+
<td></td>
|
23 |
+
</tr>
|
24 |
+
</thead>
|
25 |
+
<tbody>
|
26 |
+
<tr class="form-field">
|
27 |
+
<td><input type="text" name="custom_name[]" value="" disabled="disabled" /></td>
|
28 |
+
<td class="action remove">
|
29 |
+
<textarea name="custom_value[]" disabled="disabled"></textarea>
|
30 |
+
</td>
|
31 |
+
</tr>
|
32 |
+
<tr>
|
33 |
+
<td colspan="3"><a href="#add" title="<?php _e('add', 'pmxi_plugin')?>" class="action add-new-custom"><?php _e('Add more', 'pmxi_plugin') ?></a></td>
|
34 |
+
</tr>
|
35 |
+
</tbody>
|
36 |
+
</table>
|
37 |
+
<select class="existing_meta_keys">
|
38 |
+
<option value="">Existing Custom Fields...</option>
|
39 |
+
<?php
|
40 |
+
$hide_fields = array('_wp_page_template', '_edit_lock', '_edit_last', '_wp_trash_meta_status', '_wp_trash_meta_time');
|
41 |
+
if (!empty($meta_keys) and $meta_keys->count()):
|
42 |
+
foreach ($meta_keys as $meta_key) { if (in_array($meta_key['meta_key'], $hide_fields) or strpos($meta_key['meta_key'], '_wp') === 0) continue;
|
43 |
+
?>
|
44 |
+
<option value="<?php echo $meta_key['meta_key'];?>"><?php echo $meta_key['meta_key'];?></option>
|
45 |
+
<?php
|
46 |
+
}
|
47 |
+
endif;
|
48 |
+
?>
|
49 |
+
</select>
|
50 |
+
|
51 |
+
</fieldset>
|
52 |
+
<br>
|
53 |
+
</td>
|
54 |
</tr>
|
views/admin/import/options/_featured_template.php
CHANGED
@@ -1,37 +1,38 @@
|
|
1 |
-
<tr>
|
2 |
-
<td colspan="3">
|
3 |
-
<h3>
|
4 |
-
<?php _e('Download & Import Images To The Post Media Gallery', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Specify URLs or XPath Template Tags to download and import images to the post media gallery. The first image will be set as the Featured Image. Example: <pre>{image[1]},{image[2]},{image[3]}</pre> Separate your URLs or XPath Template Tags with the comma. <i>Separated by</i> character will use if xPath value contains multiple URLs, for example: <br> \'http://test.com/first.jpg | http://test.com/second.png\'.', 'pmxi_plugin') ?>">?</a>
|
5 |
-
<span class="separated_by">Separated by</span>
|
6 |
-
</h3>
|
7 |
-
<div>
|
8 |
-
<input type="text" name="featured_image" style="width:92%;" value="<?php echo esc_attr($post['featured_image']) ?>" disabled="disabled"
|
9 |
-
<input type="text" class="small" name="featured_delim" maxlength="1" value="<?php echo esc_attr($post['featured_delim']) ?>" style="width:5%; text-align:center;" disabled="disabled"
|
10 |
-
</div>
|
11 |
-
<div class="input">
|
12 |
-
<input type="hidden" name="create_draft" value="no" />
|
13 |
-
<input type="checkbox" id="create_draft_<?php echo $entry; ?>" name="create_draft" value="yes" <?php echo
|
14 |
-
<label for="create_draft_<?php echo $entry; ?>"><?php _e('<small>If no images are downloaded successfully, create entry as Draft.</small>', 'pmxi_plugin') ?></label>
|
15 |
-
</div>
|
16 |
-
|
17 |
-
<center>
|
18 |
-
|
19 |
-
<hr />
|
20 |
-
|
21 |
-
<b>Please upgrade to the professional edition of WP All Import to download and import images to the post media gallery.</b>
|
22 |
-
|
23 |
-
<p style='font-size: 1.1em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=featured-images&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
|
24 |
-
|
25 |
-
</center>
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
<input type="text"
|
34 |
-
|
35 |
-
|
36 |
-
|
|
|
37 |
</tr>
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<h3>
|
4 |
+
<?php _e('Download & Import Images To The Post Media Gallery', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Specify URLs or XPath Template Tags to download and import images to the post media gallery. The first image will be set as the Featured Image. Example: <pre>{image[1]},{image[2]},{image[3]}</pre> Separate your URLs or XPath Template Tags with the comma. <i>Separated by</i> character will use if xPath value contains multiple URLs, for example: <br> \'http://test.com/first.jpg | http://test.com/second.png\'.', 'pmxi_plugin') ?>">?</a>
|
5 |
+
<span class="separated_by">Separated by</span>
|
6 |
+
</h3>
|
7 |
+
<div>
|
8 |
+
<input type="text" name="featured_image" style="width:92%;" value="<?php echo ($post_type == "product") ? esc_attr($post['featured_image']) : ""; ?>" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
|
9 |
+
<input type="text" class="small" name="featured_delim" maxlength="1" value="<?php echo esc_attr($post['featured_delim']) ?>" style="width:5%; text-align:center;" <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
|
10 |
+
</div>
|
11 |
+
<div class="input">
|
12 |
+
<input type="hidden" name="create_draft" value="no" />
|
13 |
+
<input type="checkbox" id="create_draft_<?php echo $entry; ?>" name="create_draft" value="yes" <?php echo ($post_type == "product" and "yes" == $post['create_draft']) ? 'checked="checked"' : '' ?> <?php if ($post_type != "product"):?>disabled="disabled"<?php endif; ?>/>
|
14 |
+
<label for="create_draft_<?php echo $entry; ?>"><?php _e('<small>If no images are downloaded successfully, create entry as Draft.</small>', 'pmxi_plugin') ?></label>
|
15 |
+
</div>
|
16 |
+
<?php if ($post_type != "product"):?>
|
17 |
+
<center>
|
18 |
+
|
19 |
+
<hr />
|
20 |
+
|
21 |
+
<b>Please upgrade to the professional edition of WP All Import to download and import images to the post media gallery.</b>
|
22 |
+
|
23 |
+
<p style='font-size: 1.1em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=featured-images&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
|
24 |
+
|
25 |
+
</center>
|
26 |
+
<?php endif; ?>
|
27 |
+
|
28 |
+
<h3>
|
29 |
+
<?php _e('Download & Import Attachments', 'pmxi_plugin') ?>
|
30 |
+
<span class="separated_by">Separated by</span>
|
31 |
+
</h3>
|
32 |
+
<div>
|
33 |
+
<input type="text" name="attachments" style="width:92%;" value="<?php echo esc_attr($post['attachments']) ?>" />
|
34 |
+
<input type="text" class="small" name="atch_delim" maxlength="1" value="<?php echo esc_attr($post['atch_delim']) ?>" style="width:5%; text-align:center;" />
|
35 |
+
</div>
|
36 |
+
<br>
|
37 |
+
</td>
|
38 |
</tr>
|
views/admin/import/options/_main_options_template.php
CHANGED
@@ -1,56 +1,56 @@
|
|
1 |
-
<tr>
|
2 |
-
<td colspan="3" style="border-bottom:1px solid #ccc;">
|
3 |
-
<div class="col2" style="margin-bottom:20px;">
|
4 |
-
<h3><?php _e('Post Status', 'pmxi_plugin') ?></h3>
|
5 |
-
<div>
|
6 |
-
<div class="input">
|
7 |
-
<input type="radio" id="status_publish_<?php echo $entry; ?>" name="status" value="publish" <?php echo 'publish' == $post['status'] ? 'checked="checked"' : '' ?>
|
8 |
-
<label for="status_publish_<?php echo $entry; ?>"><?php _e('Published', 'pmxi_plugin') ?></label>
|
9 |
-
</div>
|
10 |
-
<div class="input">
|
11 |
-
<input type="radio" id="status_draft_<?php echo $entry; ?>" name="status" value="draft" <?php echo 'draft' == $post['status'] ? 'checked="checked"' : '' ?>
|
12 |
-
<label for="status_draft_<?php echo $entry; ?>"><?php _e('Draft', 'pmxi_plugin') ?></label>
|
13 |
-
</div>
|
14 |
-
<br>
|
15 |
-
<div class="input">
|
16 |
-
<input type="hidden" name="comment_status" value="closed" />
|
17 |
-
<input type="checkbox" id="comment_status_<?php echo $entry; ?>" name="comment_status" value="open" <?php echo 'open' == $post['comment_status'] ? 'checked="checked"' : '' ?>
|
18 |
-
<label for="comment_status_<?php echo $entry; ?>"><?php _e('Allow Comments', 'pmxi_plugin') ?></label>
|
19 |
-
</div>
|
20 |
-
<div class="input">
|
21 |
-
<input type="hidden" name="ping_status" value="closed" />
|
22 |
-
<input type="checkbox" id="ping_status_<?php echo $entry; ?>" name="ping_status" value="open" <?php echo 'open' == $post['ping_status'] ? 'checked="checked"' : '' ?>
|
23 |
-
<label for="ping_status_<?php echo $entry; ?>"><?php _e('Allow Trackbacks and Pingbacks', 'pmxi_plugin') ?></label>
|
24 |
-
</div>
|
25 |
-
</div>
|
26 |
-
</div>
|
27 |
-
<div class="col2">
|
28 |
-
<h3><?php _e('Post Dates', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Use any format supported by the PHP <b>strtotime</b> function. That means pretty much any human-readable date will work.', 'pmxi_plugin') ?>">?</a></h3>
|
29 |
-
<div class="input">
|
30 |
-
<input type="radio" id="date_type_specific_<?php echo $entry; ?>" class="switcher" name="date_type" value="specific" <?php echo 'random' != $post['date_type'] ? 'checked="checked"' : '' ?>
|
31 |
-
<label for="date_type_specific_<?php echo $entry; ?>">
|
32 |
-
<?php _e('As specified', 'pmxi_plugin') ?>
|
33 |
-
</label>
|
34 |
-
<span class="switcher-target-date_type_specific_<?php echo $entry; ?>" style="vertical-align:middle">
|
35 |
-
<input type="text" class="datepicker" name="date" value="<?php echo esc_attr($post['date']) ?>" style="width:40%;"
|
36 |
-
</span>
|
37 |
-
</div>
|
38 |
-
<div class="input">
|
39 |
-
<input type="radio" id="date_type_random_<?php echo $entry; ?>" class="switcher" name="date_type" value="random" <?php echo 'random' == $post['date_type'] ? 'checked="checked"' : '' ?>
|
40 |
-
<label for="date_type_random_<?php echo $entry; ?>">
|
41 |
-
<?php _e('Random dates', 'pmxi_plugin') ?><a href="#help" class="help" title="<?php _e('Posts will be randomly assigned dates in this range. WordPress ensures posts with dates in the future will not appear until their date has been reached.', 'pmxi_plugin') ?>">?</a>
|
42 |
-
</label> <br>
|
43 |
-
<span class="switcher-target-date_type_random_<?php echo $entry; ?>" style="vertical-align:middle">
|
44 |
-
<input type="text" class="datepicker" name="date_start" value="<?php echo esc_attr($post['date_start']) ?>"
|
45 |
-
<?php _e('and', 'pmxi_plugin') ?>
|
46 |
-
<input type="text" class="datepicker" name="date_end" value="<?php echo esc_attr($post['date_end']) ?>"
|
47 |
-
</span>
|
48 |
-
</div>
|
49 |
-
</div>
|
50 |
-
</td>
|
51 |
-
</tr>
|
52 |
-
<tr>
|
53 |
-
<td colspan="3">
|
54 |
-
<h3 style="text-align:center; color:#999;"
|
55 |
-
</td>
|
56 |
</tr>
|
1 |
+
<tr>
|
2 |
+
<td colspan="3" style="border-bottom:1px solid #ccc;">
|
3 |
+
<div class="col2" style="margin-bottom:20px;">
|
4 |
+
<h3><?php _e('Post Status', 'pmxi_plugin') ?></h3>
|
5 |
+
<div>
|
6 |
+
<div class="input">
|
7 |
+
<input type="radio" id="status_publish_<?php echo $entry; ?>" name="status" value="publish" <?php echo 'publish' == $post['status'] ? 'checked="checked"' : '' ?> />
|
8 |
+
<label for="status_publish_<?php echo $entry; ?>"><?php _e('Published', 'pmxi_plugin') ?></label>
|
9 |
+
</div>
|
10 |
+
<div class="input">
|
11 |
+
<input type="radio" id="status_draft_<?php echo $entry; ?>" name="status" value="draft" <?php echo 'draft' == $post['status'] ? 'checked="checked"' : '' ?> />
|
12 |
+
<label for="status_draft_<?php echo $entry; ?>"><?php _e('Draft', 'pmxi_plugin') ?></label>
|
13 |
+
</div>
|
14 |
+
<br>
|
15 |
+
<div class="input">
|
16 |
+
<input type="hidden" name="comment_status" value="closed" />
|
17 |
+
<input type="checkbox" id="comment_status_<?php echo $entry; ?>" name="comment_status" value="open" <?php echo 'open' == $post['comment_status'] ? 'checked="checked"' : '' ?> />
|
18 |
+
<label for="comment_status_<?php echo $entry; ?>"><?php _e('Allow Comments', 'pmxi_plugin') ?></label>
|
19 |
+
</div>
|
20 |
+
<div class="input">
|
21 |
+
<input type="hidden" name="ping_status" value="closed" />
|
22 |
+
<input type="checkbox" id="ping_status_<?php echo $entry; ?>" name="ping_status" value="open" <?php echo 'open' == $post['ping_status'] ? 'checked="checked"' : '' ?> />
|
23 |
+
<label for="ping_status_<?php echo $entry; ?>"><?php _e('Allow Trackbacks and Pingbacks', 'pmxi_plugin') ?></label>
|
24 |
+
</div>
|
25 |
+
</div>
|
26 |
+
</div>
|
27 |
+
<div class="col2">
|
28 |
+
<h3><?php _e('Post Dates', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Use any format supported by the PHP <b>strtotime</b> function. That means pretty much any human-readable date will work.', 'pmxi_plugin') ?>">?</a></h3>
|
29 |
+
<div class="input">
|
30 |
+
<input type="radio" id="date_type_specific_<?php echo $entry; ?>" class="switcher" name="date_type" value="specific" <?php echo 'random' != $post['date_type'] ? 'checked="checked"' : '' ?> />
|
31 |
+
<label for="date_type_specific_<?php echo $entry; ?>">
|
32 |
+
<?php _e('As specified', 'pmxi_plugin') ?>
|
33 |
+
</label>
|
34 |
+
<span class="switcher-target-date_type_specific_<?php echo $entry; ?>" style="vertical-align:middle">
|
35 |
+
<input type="text" class="datepicker" name="date" value="<?php echo esc_attr($post['date']) ?>" style="width:40%;"/>
|
36 |
+
</span>
|
37 |
+
</div>
|
38 |
+
<div class="input">
|
39 |
+
<input type="radio" id="date_type_random_<?php echo $entry; ?>" class="switcher" name="date_type" value="random" <?php echo 'random' == $post['date_type'] ? 'checked="checked"' : '' ?> />
|
40 |
+
<label for="date_type_random_<?php echo $entry; ?>">
|
41 |
+
<?php _e('Random dates', 'pmxi_plugin') ?><a href="#help" class="help" title="<?php _e('Posts will be randomly assigned dates in this range. WordPress ensures posts with dates in the future will not appear until their date has been reached.', 'pmxi_plugin') ?>">?</a>
|
42 |
+
</label> <br>
|
43 |
+
<span class="switcher-target-date_type_random_<?php echo $entry; ?>" style="vertical-align:middle">
|
44 |
+
<input type="text" class="datepicker" name="date_start" value="<?php echo esc_attr($post['date_start']) ?>" />
|
45 |
+
<?php _e('and', 'pmxi_plugin') ?>
|
46 |
+
<input type="text" class="datepicker" name="date_end" value="<?php echo esc_attr($post['date_end']) ?>" />
|
47 |
+
</span>
|
48 |
+
</div>
|
49 |
+
</div>
|
50 |
+
</td>
|
51 |
+
</tr>
|
52 |
+
<tr>
|
53 |
+
<td colspan="3">
|
54 |
+
<h3 style="text-align:center; color:#999;"><?php _e('Drag elements from the XML tree on the right to any textbox below.','pmxi_plugin');?></h3>
|
55 |
+
</td>
|
56 |
</tr>
|
views/admin/import/options/_reimport_template.php
CHANGED
@@ -1,132 +1,132 @@
|
|
1 |
-
<tr>
|
2 |
-
<td colspan="3">
|
3 |
-
<fieldset class="optionsset">
|
4 |
-
<legend>Record Matching</legend>
|
5 |
-
<div class="input" style="margin-bottom:15px;">
|
6 |
-
<input type="radio" id="auto_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="auto" <?php echo 'manual' != $post['duplicate_matching'] ? 'checked="checked"': '' ?>
|
7 |
-
<label for="auto_matching_<?php echo $entry; ?>"><?php _e('Automatic Record Matching', 'pmxi_plugin' )?></label><br>
|
8 |
-
<div class="switcher-target-auto_matching_<?php echo $entry; ?>" style="padding-left:17px;">
|
9 |
-
<div class="input">
|
10 |
-
<label><?php _e("Unique key"); ?></label>
|
11 |
-
<input type="text" class="smaller-text" name="unique_key" style="width:300px;" value="<?php echo esc_attr($post['unique_key']) ?>" <?php echo ! ($this->isWizard && $update_previous->isEmpty()) ? 'disabled="disabled"' : '' ?>
|
12 |
-
<a href="#help" class="help" title="<?php _e('Specify something that is unique for all records. If posts are being updated and not just created during a brand new import, the problem is that the value of the unique key is not unique.', 'pmxi_plugin') ?>">?</a>
|
13 |
-
</div>
|
14 |
-
</div>
|
15 |
-
<input type="radio" id="manual_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="manual" <?php echo 'manual' == $post['duplicate_matching'] ? 'checked="checked"': '' ?>
|
16 |
-
<label for="manual_matching_<?php echo $entry; ?>"><?php _e('Manual Record Matching', 'pmxi_plugin' )?></label>
|
17 |
-
<a href="#help" class="help" title="<?php _e('This allows you to match records by something other than Unique Key.', 'pmxi_plugin') ?>">?</a>
|
18 |
-
<div class="switcher-target-manual_matching_<?php echo $entry; ?>" style="padding-left:17px;">
|
19 |
-
<div class="input">
|
20 |
-
<span style="vertical-align:middle"><?php _e('Match records based on...', 'pmxi_plugin') ?></span><br>
|
21 |
-
<input type="radio" id="duplicate_indicator_title_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="title" <?php echo 'title' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>
|
22 |
-
<label for="duplicate_indicator_title_<?php echo $entry; ?>"><?php _e('title', 'pmxi_plugin' )?></label><br>
|
23 |
-
<input type="radio" id="duplicate_indicator_content_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="content" <?php echo 'content' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>
|
24 |
-
<label for="duplicate_indicator_content_<?php echo $entry; ?>"><?php _e('content', 'pmxi_plugin' )?></label><br>
|
25 |
-
<input type="radio" id="duplicate_indicator_custom_field_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="custom field" <?php echo 'custom field' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?>
|
26 |
-
<label for="duplicate_indicator_custom_field_<?php echo $entry; ?>"><?php _e('custom field', 'pmxi_plugin' )?></label><br>
|
27 |
-
<span class="switcher-target-duplicate_indicator_custom_field_<?php echo $entry; ?>" style="vertical-align:middle" style="padding-left:17px;">
|
28 |
-
<?php _e('Name', 'pmxi_plugin') ?>
|
29 |
-
<input type="text" name="custom_duplicate_name" value="<?php echo esc_attr($post['custom_duplicate_name']) ?>"
|
30 |
-
<?php _e('Value', 'pmxi_plugin') ?>
|
31 |
-
<input type="text" name="custom_duplicate_value" value="<?php echo esc_attr($post['custom_duplicate_value']) ?>"
|
32 |
-
</span>
|
33 |
-
</div>
|
34 |
-
</div>
|
35 |
-
</div>
|
36 |
-
<hr>
|
37 |
-
<div class="input">
|
38 |
-
<input type="hidden" name="not_create_records" value="0" />
|
39 |
-
<input type="checkbox" id="not_create_records_<?php echo $entry; ?>" name="not_create_records" value="1" <?php echo $post['not_create_records'] ? 'checked="checked"' : '' ?>
|
40 |
-
<label for="not_create_records_<?php echo $entry; ?>"><?php _e('Do Not Add New Records', 'pmxi_plugin') ?></label>
|
41 |
-
</div>
|
42 |
-
<div class="input">
|
43 |
-
<input type="hidden" name="is_delete_missing" value="0" />
|
44 |
-
<input type="checkbox" id="is_delete_missing_<?php echo $entry; ?>" name="is_delete_missing" value="1" <?php echo $post['is_delete_missing'] ? 'checked="checked"': '' ?> class="switcher"
|
45 |
-
<label for="is_delete_missing_<?php echo $entry; ?>"><?php _e('Delete missing records', 'pmxi_plugin') ?></label>
|
46 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you want to delete posts from previous import operation which are not found among newly impoprted set.', 'pmxi_plugin') ?>">?</a>
|
47 |
-
</div>
|
48 |
-
<div class="switcher-target-is_delete_missing_<?php echo $entry; ?>" style="padding-left:17px;">
|
49 |
-
<div class="input">
|
50 |
-
<input type="hidden" name="is_keep_attachments" value="0" />
|
51 |
-
<input type="checkbox" id="is_keep_attachments_<?php echo $entry; ?>" name="is_keep_attachments" value="1" <?php echo $post['is_keep_attachments'] ? 'checked="checked"': '' ?>
|
52 |
-
<label for="is_keep_attachments_<?php echo $entry; ?>"><?php _e('Keep attachments when records removed', 'pmxi_plugin') ?></label>
|
53 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you want attachments like featured image to be kept in media library after parent post or page is removed or replaced during reimport operation.', 'pmxi_plugin') ?>">?</a>
|
54 |
-
</div>
|
55 |
-
</div>
|
56 |
-
<div class="input">
|
57 |
-
<input type="radio" id="is_keep_former_posts_<?php echo $entry; ?>" name="is_keep_former_posts" value="yes" <?php echo "yes" == $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher"
|
58 |
-
<label for="is_keep_former_posts_<?php echo $entry; ?>"><?php _e('Do not update already existing records', 'pmxi_plugin') ?></label> <br>
|
59 |
-
<input type="radio" id="is_not_keep_former_posts_<?php echo $entry; ?>" name="is_keep_former_posts" value="no" <?php echo "yes" != $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher"
|
60 |
-
<label for="is_not_keep_former_posts_<?php echo $entry; ?>"><?php _e('Update existing records', 'pmxi_plugin') ?></label>
|
61 |
-
<div class="switcher-target-is_not_keep_former_posts_<?php echo $entry; ?>" style="padding-left:17px;">
|
62 |
-
<div class="input">
|
63 |
-
<input type="hidden" name="is_keep_status" value="0" />
|
64 |
-
<input type="checkbox" id="is_keep_status_<?php echo $entry; ?>" name="is_keep_status" value="1" <?php echo $post['is_keep_status'] ? 'checked="checked"': '' ?>
|
65 |
-
<label for="is_keep_status_<?php echo $entry; ?>"><?php _e('Keep status', 'pmxi_plugin') ?></label>
|
66 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their publish status or being restored from Trash.', 'pmxi_plugin') ?>">?</a>
|
67 |
-
</div>
|
68 |
-
<div class="input">
|
69 |
-
<input type="hidden" name="is_keep_title" value="0" />
|
70 |
-
<input type="checkbox" id="is_keep_title_<?php echo $entry; ?>" name="is_keep_title" value="1" <?php echo $post['is_keep_title'] ? 'checked="checked"': '' ?>
|
71 |
-
<label for="is_keep_title_<?php echo $entry; ?>"><?php _e('Keep title', 'pmxi_plugin') ?></label>
|
72 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their titles.', 'pmxi_plugin') ?>">?</a>
|
73 |
-
</div>
|
74 |
-
<div class="input">
|
75 |
-
<input type="hidden" name="is_keep_excerpt" value="0" />
|
76 |
-
<input type="checkbox" id="is_keep_excerpt_<?php echo $entry; ?>" name="is_keep_excerpt" value="1" <?php echo $post['is_keep_excerpt'] ? 'checked="checked"': '' ?>
|
77 |
-
<label for="is_keep_excerpt_<?php echo $entry; ?>"><?php _e('Keep excerpt', 'pmxi_plugin') ?></label>
|
78 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their excerpts.', 'pmxi_plugin') ?>">?</a>
|
79 |
-
</div>
|
80 |
-
<div class="input">
|
81 |
-
<input type="hidden" name="is_keep_dates" value="0" />
|
82 |
-
<input type="checkbox" id="is_keep_dates_<?php echo $entry; ?>" name="is_keep_dates" value="1" <?php echo $post['is_keep_dates'] ? 'checked="checked"': '' ?>
|
83 |
-
<label for="is_keep_dates_<?php echo $entry; ?>"><?php _e('Keep dates', 'pmxi_plugin') ?></label>
|
84 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their publish dates.', 'pmxi_plugin') ?>">?</a>
|
85 |
-
</div>
|
86 |
-
<div class="input">
|
87 |
-
<input type="hidden" name="is_keep_menu_order" value="0" />
|
88 |
-
<input type="checkbox" id="is_keep_menu_order_<?php echo $entry; ?>" name="is_keep_menu_order" value="1" <?php echo $post['is_keep_menu_order'] ? 'checked="checked"': '' ?>
|
89 |
-
<label for="is_keep_menu_order_<?php echo $entry; ?>"><?php _e('Keep menu order', 'pmxi_plugin') ?></label>
|
90 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their menu order.', 'pmxi_plugin') ?>">?</a>
|
91 |
-
</div>
|
92 |
-
<div class="input">
|
93 |
-
<input type="hidden" name="is_keep_content" value="0" />
|
94 |
-
<input type="checkbox" id="is_keep_content_<?php echo $entry; ?>" name="is_keep_content" value="1" <?php echo $post['is_keep_content'] ? 'checked="checked"': '' ?>
|
95 |
-
<label for="is_keep_content_<?php echo $entry; ?>"><?php _e('Keep content', 'pmxi_plugin') ?></label>
|
96 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their content.', 'pmxi_plugin') ?>">?</a>
|
97 |
-
</div>
|
98 |
-
<div class="input">
|
99 |
-
<input type="hidden" name="is_keep_categories" value="0" />
|
100 |
-
<input type="checkbox" id="is_keep_categories_<?php echo $entry; ?>" name="is_keep_categories" value="1" <?php echo $post['is_keep_categories'] ? 'checked="checked"': '' ?>
|
101 |
-
<label for="is_keep_categories_<?php echo $entry; ?>"><?php _e('Keep categories, tags and taxonomies', 'pmxi_plugin') ?></label>
|
102 |
-
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their category, tag and custom taxonomies associations upon reimport.', 'pmxi_plugin') ?>">?</a>
|
103 |
-
</div>
|
104 |
-
<div class="input">
|
105 |
-
<input type="hidden" name="is_keep_images" value="0" />
|
106 |
-
<input type="checkbox" id="is_keep_images_<?php echo $entry; ?>" name="is_keep_images" value="1" <?php echo $post['is_keep_images'] ? 'checked="checked"': '' ?>
|
107 |
-
<label for="is_keep_images_<?php echo $entry; ?>"><?php _e('Do not import images', 'pmxi_plugin') ?></label>
|
108 |
-
<a href="#help" class="help" title="<?php _e('This will keep the featured image if it exists, so you could modify the post image manually, and then do a reimport, and it would not overwrite the manually modified post image.', 'pmxi_plugin') ?>">?</a>
|
109 |
-
</div>
|
110 |
-
<div class="input">
|
111 |
-
<input type="hidden" name="no_create_featured_image" value="0" />
|
112 |
-
<input type="checkbox" id="no_create_featured_image_<?php echo $entry; ?>" name="no_create_featured_image" value="1" <?php echo $post['no_create_featured_image'] ? 'checked="checked"': '' ?>
|
113 |
-
<label for="no_create_featured_image_<?php echo $entry; ?>"><?php _e('Only keep images for posts that already have images.', 'pmxi_plugin') ?></label>
|
114 |
-
<a href="#help" class="help" title="<?php _e('This option will keep images for posts that already have images, and import images for posts that do not already have images.', 'pmxi_plugin') ?>">?</a>
|
115 |
-
</div>
|
116 |
-
<div class="input">
|
117 |
-
<input type="hidden" name="keep_custom_fields" value="0" />
|
118 |
-
<input type="checkbox" id="keep_custom_fields_<?php echo $entry; ?>" name="keep_custom_fields" value="1" <?php echo $post['keep_custom_fields'] ? 'checked="checked"': '' ?> class="switcher switcher-reversed"
|
119 |
-
<label for="keep_custom_fields_<?php echo $entry; ?>"><?php _e('Keep custom fields', 'pmxi_plugin') ?></label>
|
120 |
-
<a href="#help" class="help" title="<?php _e('If Keep Custom Fields box is checked, it will keep all Custom Fields, and add any new Custom Fields specified in Custom Fields section, as long as they do not overwrite existing fields. If \'Only keep this Custom Fields\' is specified, it will only keep the specified fields.', 'pmxi_plugin') ?>">?</a>
|
121 |
-
</div>
|
122 |
-
<div class="switcher-target-keep_custom_fields_<?php echo $entry; ?>" style="padding-left:17px;">
|
123 |
-
<div class="input">
|
124 |
-
<label for="keep_custom_fields_specific"><?php _e('Only Keep These Custom Fields <small>(separate field names with commas)</small>', 'pmxi_plugin') ?></label>
|
125 |
-
<input type="text" id="keep_custom_fields_specific" name="keep_custom_fields_specific" style="width:100%;" value="<?php echo esc_attr($post['keep_custom_fields_specific']) ?>"
|
126 |
-
</div>
|
127 |
-
</div>
|
128 |
-
</div>
|
129 |
-
</div>
|
130 |
-
</fieldset>
|
131 |
-
</td>
|
132 |
</tr>
|
1 |
+
<tr>
|
2 |
+
<td colspan="3">
|
3 |
+
<fieldset class="optionsset">
|
4 |
+
<legend>Record Matching</legend>
|
5 |
+
<div class="input" style="margin-bottom:15px;">
|
6 |
+
<input type="radio" id="auto_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="auto" <?php echo 'manual' != $post['duplicate_matching'] ? 'checked="checked"': '' ?> />
|
7 |
+
<label for="auto_matching_<?php echo $entry; ?>"><?php _e('Automatic Record Matching', 'pmxi_plugin' )?></label><br>
|
8 |
+
<div class="switcher-target-auto_matching_<?php echo $entry; ?>" style="padding-left:17px;">
|
9 |
+
<div class="input">
|
10 |
+
<label><?php _e("Unique key"); ?></label>
|
11 |
+
<input type="text" class="smaller-text" name="unique_key" style="width:300px;" value="<?php echo esc_attr($post['unique_key']) ?>" <?php echo ! ($this->isWizard && $update_previous->isEmpty()) ? 'disabled="disabled"' : '' ?> />
|
12 |
+
<a href="#help" class="help" title="<?php _e('Specify something that is unique for all records. If posts are being updated and not just created during a brand new import, the problem is that the value of the unique key is not unique.', 'pmxi_plugin') ?>">?</a>
|
13 |
+
</div>
|
14 |
+
</div>
|
15 |
+
<input type="radio" id="manual_matching_<?php echo $entry; ?>" class="switcher" name="duplicate_matching" value="manual" <?php echo 'manual' == $post['duplicate_matching'] ? 'checked="checked"': '' ?> />
|
16 |
+
<label for="manual_matching_<?php echo $entry; ?>"><?php _e('Manual Record Matching', 'pmxi_plugin' )?></label>
|
17 |
+
<a href="#help" class="help" title="<?php _e('This allows you to match records by something other than Unique Key.', 'pmxi_plugin') ?>">?</a>
|
18 |
+
<div class="switcher-target-manual_matching_<?php echo $entry; ?>" style="padding-left:17px;">
|
19 |
+
<div class="input">
|
20 |
+
<span style="vertical-align:middle"><?php _e('Match records based on...', 'pmxi_plugin') ?></span><br>
|
21 |
+
<input type="radio" id="duplicate_indicator_title_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="title" <?php echo 'title' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?> />
|
22 |
+
<label for="duplicate_indicator_title_<?php echo $entry; ?>"><?php _e('title', 'pmxi_plugin' )?></label><br>
|
23 |
+
<input type="radio" id="duplicate_indicator_content_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="content" <?php echo 'content' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?> />
|
24 |
+
<label for="duplicate_indicator_content_<?php echo $entry; ?>"><?php _e('content', 'pmxi_plugin' )?></label><br>
|
25 |
+
<input type="radio" id="duplicate_indicator_custom_field_<?php echo $entry; ?>" class="switcher" name="duplicate_indicator" value="custom field" <?php echo 'custom field' == $post['duplicate_indicator'] ? 'checked="checked"': '' ?> />
|
26 |
+
<label for="duplicate_indicator_custom_field_<?php echo $entry; ?>"><?php _e('custom field', 'pmxi_plugin' )?></label><br>
|
27 |
+
<span class="switcher-target-duplicate_indicator_custom_field_<?php echo $entry; ?>" style="vertical-align:middle" style="padding-left:17px;">
|
28 |
+
<?php _e('Name', 'pmxi_plugin') ?>
|
29 |
+
<input type="text" name="custom_duplicate_name" value="<?php echo esc_attr($post['custom_duplicate_name']) ?>" /><br>
|
30 |
+
<?php _e('Value', 'pmxi_plugin') ?>
|
31 |
+
<input type="text" name="custom_duplicate_value" value="<?php echo esc_attr($post['custom_duplicate_value']) ?>" />
|
32 |
+
</span>
|
33 |
+
</div>
|
34 |
+
</div>
|
35 |
+
</div>
|
36 |
+
<hr>
|
37 |
+
<div class="input">
|
38 |
+
<input type="hidden" name="not_create_records" value="0" />
|
39 |
+
<input type="checkbox" id="not_create_records_<?php echo $entry; ?>" name="not_create_records" value="1" <?php echo $post['not_create_records'] ? 'checked="checked"' : '' ?> />
|
40 |
+
<label for="not_create_records_<?php echo $entry; ?>"><?php _e('Do Not Add New Records', 'pmxi_plugin') ?></label>
|
41 |
+
</div>
|
42 |
+
<div class="input">
|
43 |
+
<input type="hidden" name="is_delete_missing" value="0" />
|
44 |
+
<input type="checkbox" id="is_delete_missing_<?php echo $entry; ?>" name="is_delete_missing" value="1" <?php echo $post['is_delete_missing'] ? 'checked="checked"': '' ?> class="switcher" />
|
45 |
+
<label for="is_delete_missing_<?php echo $entry; ?>"><?php _e('Delete missing records', 'pmxi_plugin') ?></label>
|
46 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you want to delete posts from previous import operation which are not found among newly impoprted set.', 'pmxi_plugin') ?>">?</a>
|
47 |
+
</div>
|
48 |
+
<div class="switcher-target-is_delete_missing_<?php echo $entry; ?>" style="padding-left:17px;">
|
49 |
+
<div class="input">
|
50 |
+
<input type="hidden" name="is_keep_attachments" value="0" />
|
51 |
+
<input type="checkbox" id="is_keep_attachments_<?php echo $entry; ?>" name="is_keep_attachments" value="1" <?php echo $post['is_keep_attachments'] ? 'checked="checked"': '' ?> />
|
52 |
+
<label for="is_keep_attachments_<?php echo $entry; ?>"><?php _e('Keep attachments when records removed', 'pmxi_plugin') ?></label>
|
53 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you want attachments like featured image to be kept in media library after parent post or page is removed or replaced during reimport operation.', 'pmxi_plugin') ?>">?</a>
|
54 |
+
</div>
|
55 |
+
</div>
|
56 |
+
<div class="input">
|
57 |
+
<input type="radio" id="is_keep_former_posts_<?php echo $entry; ?>" name="is_keep_former_posts" value="yes" <?php echo "yes" == $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher" />
|
58 |
+
<label for="is_keep_former_posts_<?php echo $entry; ?>"><?php _e('Do not update already existing records', 'pmxi_plugin') ?></label> <br>
|
59 |
+
<input type="radio" id="is_not_keep_former_posts_<?php echo $entry; ?>" name="is_keep_former_posts" value="no" <?php echo "yes" != $post['is_keep_former_posts'] ? 'checked="checked"': '' ?> class="switcher" />
|
60 |
+
<label for="is_not_keep_former_posts_<?php echo $entry; ?>"><?php _e('Update existing records', 'pmxi_plugin') ?></label>
|
61 |
+
<div class="switcher-target-is_not_keep_former_posts_<?php echo $entry; ?>" style="padding-left:17px;">
|
62 |
+
<div class="input">
|
63 |
+
<input type="hidden" name="is_keep_status" value="0" />
|
64 |
+
<input type="checkbox" id="is_keep_status_<?php echo $entry; ?>" name="is_keep_status" value="1" <?php echo $post['is_keep_status'] ? 'checked="checked"': '' ?> />
|
65 |
+
<label for="is_keep_status_<?php echo $entry; ?>"><?php _e('Keep status', 'pmxi_plugin') ?></label>
|
66 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their publish status or being restored from Trash.', 'pmxi_plugin') ?>">?</a>
|
67 |
+
</div>
|
68 |
+
<div class="input">
|
69 |
+
<input type="hidden" name="is_keep_title" value="0" />
|
70 |
+
<input type="checkbox" id="is_keep_title_<?php echo $entry; ?>" name="is_keep_title" value="1" <?php echo $post['is_keep_title'] ? 'checked="checked"': '' ?> />
|
71 |
+
<label for="is_keep_title_<?php echo $entry; ?>"><?php _e('Keep title', 'pmxi_plugin') ?></label>
|
72 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their titles.', 'pmxi_plugin') ?>">?</a>
|
73 |
+
</div>
|
74 |
+
<div class="input">
|
75 |
+
<input type="hidden" name="is_keep_excerpt" value="0" />
|
76 |
+
<input type="checkbox" id="is_keep_excerpt_<?php echo $entry; ?>" name="is_keep_excerpt" value="1" <?php echo $post['is_keep_excerpt'] ? 'checked="checked"': '' ?> />
|
77 |
+
<label for="is_keep_excerpt_<?php echo $entry; ?>"><?php _e('Keep excerpt', 'pmxi_plugin') ?></label>
|
78 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their excerpts.', 'pmxi_plugin') ?>">?</a>
|
79 |
+
</div>
|
80 |
+
<div class="input">
|
81 |
+
<input type="hidden" name="is_keep_dates" value="0" />
|
82 |
+
<input type="checkbox" id="is_keep_dates_<?php echo $entry; ?>" name="is_keep_dates" value="1" <?php echo $post['is_keep_dates'] ? 'checked="checked"': '' ?> />
|
83 |
+
<label for="is_keep_dates_<?php echo $entry; ?>"><?php _e('Keep dates', 'pmxi_plugin') ?></label>
|
84 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their publish dates.', 'pmxi_plugin') ?>">?</a>
|
85 |
+
</div>
|
86 |
+
<div class="input">
|
87 |
+
<input type="hidden" name="is_keep_menu_order" value="0" />
|
88 |
+
<input type="checkbox" id="is_keep_menu_order_<?php echo $entry; ?>" name="is_keep_menu_order" value="1" <?php echo $post['is_keep_menu_order'] ? 'checked="checked"': '' ?> />
|
89 |
+
<label for="is_keep_menu_order_<?php echo $entry; ?>"><?php _e('Keep menu order', 'pmxi_plugin') ?></label>
|
90 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their menu order.', 'pmxi_plugin') ?>">?</a>
|
91 |
+
</div>
|
92 |
+
<div class="input">
|
93 |
+
<input type="hidden" name="is_keep_content" value="0" />
|
94 |
+
<input type="checkbox" id="is_keep_content_<?php echo $entry; ?>" name="is_keep_content" value="1" <?php echo $post['is_keep_content'] ? 'checked="checked"': '' ?> />
|
95 |
+
<label for="is_keep_content_<?php echo $entry; ?>"><?php _e('Keep content', 'pmxi_plugin') ?></label>
|
96 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their content.', 'pmxi_plugin') ?>">?</a>
|
97 |
+
</div>
|
98 |
+
<div class="input">
|
99 |
+
<input type="hidden" name="is_keep_categories" value="0" />
|
100 |
+
<input type="checkbox" id="is_keep_categories_<?php echo $entry; ?>" name="is_keep_categories" value="1" <?php echo $post['is_keep_categories'] ? 'checked="checked"': '' ?> />
|
101 |
+
<label for="is_keep_categories_<?php echo $entry; ?>"><?php _e('Keep categories, tags and taxonomies', 'pmxi_plugin') ?></label>
|
102 |
+
<a href="#help" class="help" title="<?php _e('Check this option if you do not want previously imported posts to change their category, tag and custom taxonomies associations upon reimport.', 'pmxi_plugin') ?>">?</a>
|
103 |
+
</div>
|
104 |
+
<div class="input">
|
105 |
+
<input type="hidden" name="is_keep_images" value="0" />
|
106 |
+
<input type="checkbox" id="is_keep_images_<?php echo $entry; ?>" name="is_keep_images" value="1" <?php echo $post['is_keep_images'] ? 'checked="checked"': '' ?> />
|
107 |
+
<label for="is_keep_images_<?php echo $entry; ?>"><?php _e('Do not import images', 'pmxi_plugin') ?></label>
|
108 |
+
<a href="#help" class="help" title="<?php _e('This will keep the featured image if it exists, so you could modify the post image manually, and then do a reimport, and it would not overwrite the manually modified post image.', 'pmxi_plugin') ?>">?</a>
|
109 |
+
</div>
|
110 |
+
<div class="input">
|
111 |
+
<input type="hidden" name="no_create_featured_image" value="0" />
|
112 |
+
<input type="checkbox" id="no_create_featured_image_<?php echo $entry; ?>" name="no_create_featured_image" value="1" <?php echo $post['no_create_featured_image'] ? 'checked="checked"': '' ?> />
|
113 |
+
<label for="no_create_featured_image_<?php echo $entry; ?>"><?php _e('Only keep images for posts that already have images.', 'pmxi_plugin') ?></label>
|
114 |
+
<a href="#help" class="help" title="<?php _e('This option will keep images for posts that already have images, and import images for posts that do not already have images.', 'pmxi_plugin') ?>">?</a>
|
115 |
+
</div>
|
116 |
+
<div class="input">
|
117 |
+
<input type="hidden" name="keep_custom_fields" value="0" />
|
118 |
+
<input type="checkbox" id="keep_custom_fields_<?php echo $entry; ?>" name="keep_custom_fields" value="1" <?php echo $post['keep_custom_fields'] ? 'checked="checked"': '' ?> class="switcher switcher-reversed" />
|
119 |
+
<label for="keep_custom_fields_<?php echo $entry; ?>"><?php _e('Keep custom fields', 'pmxi_plugin') ?></label>
|
120 |
+
<a href="#help" class="help" title="<?php _e('If Keep Custom Fields box is checked, it will keep all Custom Fields, and add any new Custom Fields specified in Custom Fields section, as long as they do not overwrite existing fields. If \'Only keep this Custom Fields\' is specified, it will only keep the specified fields.', 'pmxi_plugin') ?>">?</a>
|
121 |
+
</div>
|
122 |
+
<div class="switcher-target-keep_custom_fields_<?php echo $entry; ?>" style="padding-left:17px;">
|
123 |
+
<div class="input">
|
124 |
+
<label for="keep_custom_fields_specific"><?php _e('Only Keep These Custom Fields <small>(separate field names with commas)</small>', 'pmxi_plugin') ?></label>
|
125 |
+
<input type="text" id="keep_custom_fields_specific" name="keep_custom_fields_specific" style="width:100%;" value="<?php echo esc_attr($post['keep_custom_fields_specific']) ?>" />
|
126 |
+
</div>
|
127 |
+
</div>
|
128 |
+
</div>
|
129 |
+
</div>
|
130 |
+
</fieldset>
|
131 |
+
</td>
|
132 |
</tr>
|
views/admin/import/options/_scheduling_template.php
CHANGED
@@ -1,39 +1,39 @@
|
|
1 |
-
<?php if (in_array($source_type, array('url', 'ftp'))): ?>
|
2 |
-
<tr>
|
3 |
-
<td colspan="3">
|
4 |
-
<fieldset class="optionsset">
|
5 |
-
<legend
|
6 |
-
<div class="input">
|
7 |
-
<input type="hidden" name="is_scheduled" value="0" />
|
8 |
-
<input type="checkbox" id="is_scheduled_<?php echo $entry; ?>" class="switcher" name="is_scheduled" value="1" <?php echo $scheduled['is_scheduled'] ? 'checked="checked"': ''
|
9 |
-
<label for="is_scheduled_<?php echo $entry; ?>"><?php _e('Schedule import using WordPress Scheduling Logic', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Using this is not recommended. Unless you are importing a very small file, use cron jobs instead.', 'pmxi_plugin') ?>">?</a></label>
|
10 |
-
<span class="switcher-target-is_scheduled_<?php echo $entry; ?>" style="vertical-align:middle">
|
11 |
-
<select name="scheduled_period"
|
12 |
-
<?php foreach (array(
|
13 |
-
'*/5 * * * *' => __('every 5 min'),
|
14 |
-
'*/10 * * * *' => __('every 10 min'),
|
15 |
-
'*/30 * * * *' => __('half-hourly'),
|
16 |
-
'0 * * * *' => __('hourly'),
|
17 |
-
'0 */4 * * *' => __('every 4 hours'),
|
18 |
-
'0 */12 * * *' => __('half-daily'),
|
19 |
-
'0 0 * * *' => __('daily'),
|
20 |
-
'0 0 * * 1' => __('weekly'),
|
21 |
-
'0 0 1 * 1' => __('monthly'),
|
22 |
-
) as $key => $title): ?>
|
23 |
-
<option value="<?php echo $key ?>" <?php echo $key == $scheduled['scheduled_period'] ? 'selected="selected"' : '' ?>><?php echo esc_html($title) ?></option>
|
24 |
-
<?php endforeach ?>
|
25 |
-
</select>
|
26 |
-
<a href="#help" class="help" title="<?php _e('<b>Warning</b>: Execution periods are not guaranteed due to internal WordPress scheduling logic. Scheduled tasks are only triggered upon a user request/visit to the site. On sites with low user activity, when time span between requests exceeds scheduled periods, those scheduling periods cannot be kept. In most cases though, such behavior achives the goal since delayed tasks are run right when a request is registered and user sees the content after the task has been executed. ', 'pmxi_plugin') ?>">?</a>
|
27 |
-
</span>
|
28 |
-
|
29 |
-
<br /><br />
|
30 |
-
|
31 |
-
<p>
|
32 |
-
<b>This import can be also be scheduled using cron jobs.</b> Save the import, visit the <i>Manage Imports</i> page, and click the <i>Cron Scheduling</i> link to set up cron scheduling. Using WordPress scheduling logic is not recommended for large files.
|
33 |
-
</p>
|
34 |
-
|
35 |
-
</div>
|
36 |
-
</fieldset>
|
37 |
-
</td>
|
38 |
-
</tr>
|
39 |
<?php endif;?>
|
1 |
+
<?php if (in_array($source_type, array('url', 'ftp'))): ?>
|
2 |
+
<tr>
|
3 |
+
<td colspan="3">
|
4 |
+
<fieldset class="optionsset">
|
5 |
+
<legend><?php _e('Scheduling','pmxi_plugin');?></legend>
|
6 |
+
<div class="input">
|
7 |
+
<input type="hidden" name="is_scheduled" value="0" />
|
8 |
+
<input type="checkbox" id="is_scheduled_<?php echo $entry; ?>" class="switcher" name="is_scheduled" value="1" <?php echo $scheduled['is_scheduled'] ? 'checked="checked"': '' ?>/>
|
9 |
+
<label for="is_scheduled_<?php echo $entry; ?>"><?php _e('Schedule import using WordPress Scheduling Logic', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Using this is not recommended. Unless you are importing a very small file, use cron jobs instead.', 'pmxi_plugin') ?>">?</a></label>
|
10 |
+
<span class="switcher-target-is_scheduled_<?php echo $entry; ?>" style="vertical-align:middle">
|
11 |
+
<select name="scheduled_period">
|
12 |
+
<?php foreach (array(
|
13 |
+
'*/5 * * * *' => __('every 5 min'),
|
14 |
+
'*/10 * * * *' => __('every 10 min'),
|
15 |
+
'*/30 * * * *' => __('half-hourly'),
|
16 |
+
'0 * * * *' => __('hourly'),
|
17 |
+
'0 */4 * * *' => __('every 4 hours'),
|
18 |
+
'0 */12 * * *' => __('half-daily'),
|
19 |
+
'0 0 * * *' => __('daily'),
|
20 |
+
'0 0 * * 1' => __('weekly'),
|
21 |
+
'0 0 1 * 1' => __('monthly'),
|
22 |
+
) as $key => $title): ?>
|
23 |
+
<option value="<?php echo $key ?>" <?php echo $key == $scheduled['scheduled_period'] ? 'selected="selected"' : '' ?>><?php echo esc_html($title) ?></option>
|
24 |
+
<?php endforeach ?>
|
25 |
+
</select>
|
26 |
+
<a href="#help" class="help" title="<?php _e('<b>Warning</b>: Execution periods are not guaranteed due to internal WordPress scheduling logic. Scheduled tasks are only triggered upon a user request/visit to the site. On sites with low user activity, when time span between requests exceeds scheduled periods, those scheduling periods cannot be kept. In most cases though, such behavior achives the goal since delayed tasks are run right when a request is registered and user sees the content after the task has been executed. ', 'pmxi_plugin') ?>">?</a>
|
27 |
+
</span>
|
28 |
+
|
29 |
+
<br /><br />
|
30 |
+
|
31 |
+
<p>
|
32 |
+
<?php _e('<b>This import can be also be scheduled using cron jobs.</b> Save the import, visit the <i>Manage Imports</i> page, and click the <i>Cron Scheduling</i> link to set up cron scheduling. Using WordPress scheduling logic is not recommended for large files.','pmxi_plugin');?>
|
33 |
+
</p>
|
34 |
+
|
35 |
+
</div>
|
36 |
+
</fieldset>
|
37 |
+
</td>
|
38 |
+
</tr>
|
39 |
<?php endif;?>
|
views/admin/import/options/_taxonomies_template.php
CHANGED
@@ -1,71 +1,71 @@
|
|
1 |
-
<?php
|
2 |
-
$post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array($post_type), 'object'), array_flip(array('category', 'post_tag', 'post_format')));
|
3 |
-
if ( ! empty($post_taxonomies)): ?>
|
4 |
-
<tr>
|
5 |
-
<td colspan="3">
|
6 |
-
<fieldset class="optionsset">
|
7 |
-
<legend>Custom Taxonomies</legend>
|
8 |
-
<?php foreach ($post_taxonomies as $ctx): ?>
|
9 |
-
<table>
|
10 |
-
<tr>
|
11 |
-
<td>
|
12 |
-
<div class="post_taxonomy">
|
13 |
-
<div class="col2" style="width:35%;">
|
14 |
-
<nobr><?php echo $ctx->labels->name ?></nobr>
|
15 |
-
</div>
|
16 |
-
<div class="col2" style="width:65%;">
|
17 |
-
<ol class="sortable no-margin">
|
18 |
-
<?php
|
19 |
-
if (!empty($post['post_taxonomies'][$ctx->name])):
|
20 |
-
$taxonomies_hierarchy = json_decode($post['post_taxonomies'][$ctx->name]);
|
21 |
-
if (!empty($taxonomies_hierarchy) and is_array($taxonomies_hierarchy)): $i = 0; foreach ($taxonomies_hierarchy as $cat) { $i++;
|
22 |
-
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
23 |
-
{
|
24 |
-
?>
|
25 |
-
<li id="item_<?php echo $i; ?>">
|
26 |
-
<div class="drag-element">
|
27 |
-
<input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"
|
28 |
-
<input type="text" class="widefat" value="<?php echo esc_attr($cat->xpath); ?>"
|
29 |
-
</div>
|
30 |
-
<?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
|
31 |
-
<?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, $i); ?>
|
32 |
-
</li>
|
33 |
-
<?php
|
34 |
-
}
|
35 |
-
}; else:?>
|
36 |
-
<li id="item_1">
|
37 |
-
<div class="drag-element">
|
38 |
-
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"
|
39 |
-
<input type="text" class="widefat" value=""
|
40 |
-
</div>
|
41 |
-
</li>
|
42 |
-
<?php endif;
|
43 |
-
else: ?>
|
44 |
-
<li id="item_1">
|
45 |
-
<div class="drag-element">
|
46 |
-
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>"
|
47 |
-
<input type="text" class="widefat" value=""
|
48 |
-
</div>
|
49 |
-
</li>
|
50 |
-
<?php endif;?>
|
51 |
-
</ol>
|
52 |
-
<input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
|
53 |
-
<div class="delim">
|
54 |
-
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
55 |
-
<input type="text" class="small tax_delim" value="<?php echo (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->delim) ? $taxonomies_hierarchy[0]->delim : ',' ?>"
|
56 |
-
<label for="nested_<?php echo $ctx->name;?>"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
|
57 |
-
<input id="nested_<?php echo $ctx->name;?>" type="checkbox" class="taxonomy_auto_nested" <?php if (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->auto_nested):?>checked="checked"<?php endif; ?>
|
58 |
-
<a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>></code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
|
59 |
-
<!--a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more','pmxi_plugin');?></a-->
|
60 |
-
</div>
|
61 |
-
</div>
|
62 |
-
</div>
|
63 |
-
</td>
|
64 |
-
</tr>
|
65 |
-
</table>
|
66 |
-
<?php endforeach; ?>
|
67 |
-
</fieldset>
|
68 |
-
</td>
|
69 |
-
</tr>
|
70 |
-
<?php endif;
|
71 |
?>
|
1 |
+
<?php
|
2 |
+
$post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array($post_type), 'object'), array_flip(array('category', 'post_tag', 'post_format', 'product_type')));
|
3 |
+
if ( ! empty($post_taxonomies)): ?>
|
4 |
+
<tr>
|
5 |
+
<td colspan="3">
|
6 |
+
<fieldset class="optionsset">
|
7 |
+
<legend>Custom Taxonomies</legend>
|
8 |
+
<?php foreach ($post_taxonomies as $ctx): ?>
|
9 |
+
<table>
|
10 |
+
<tr>
|
11 |
+
<td>
|
12 |
+
<div class="post_taxonomy">
|
13 |
+
<div class="col2" style="width:35%;">
|
14 |
+
<nobr><?php echo $ctx->labels->name ?></nobr>
|
15 |
+
</div>
|
16 |
+
<div class="col2" style="width:65%;">
|
17 |
+
<ol class="sortable no-margin">
|
18 |
+
<?php
|
19 |
+
if (!empty($post['post_taxonomies'][$ctx->name])):
|
20 |
+
$taxonomies_hierarchy = json_decode($post['post_taxonomies'][$ctx->name]);
|
21 |
+
if (!empty($taxonomies_hierarchy) and is_array($taxonomies_hierarchy)): $i = 0; foreach ($taxonomies_hierarchy as $cat) { $i++;
|
22 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
23 |
+
{
|
24 |
+
?>
|
25 |
+
<li id="item_<?php echo $i; ?>">
|
26 |
+
<div class="drag-element">
|
27 |
+
<input type="checkbox" class="assign_post" <?php if ($cat->assign): ?>checked="checked"<?php endif; ?> title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
|
28 |
+
<input type="text" class="widefat" value="<?php echo esc_attr($cat->xpath); ?>" />
|
29 |
+
</div>
|
30 |
+
<?php if ($i>1):?><a href="javascript:void(0);" class="icon-item remove-ico"></a><?php endif;?>
|
31 |
+
<?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, $i); ?>
|
32 |
+
</li>
|
33 |
+
<?php
|
34 |
+
}
|
35 |
+
}; else:?>
|
36 |
+
<li id="item_1">
|
37 |
+
<div class="drag-element">
|
38 |
+
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
|
39 |
+
<input type="text" class="widefat" value="" />
|
40 |
+
</div>
|
41 |
+
</li>
|
42 |
+
<?php endif;
|
43 |
+
else: ?>
|
44 |
+
<li id="item_1">
|
45 |
+
<div class="drag-element">
|
46 |
+
<input type="checkbox" class="assign_post" checked="checked" title="<?php _e('Assign post to the taxonomy.','pmxi_plugin');?>" />
|
47 |
+
<input type="text" class="widefat" value="" />
|
48 |
+
</div>
|
49 |
+
</li>
|
50 |
+
<?php endif;?>
|
51 |
+
</ol>
|
52 |
+
<input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
|
53 |
+
<div class="delim">
|
54 |
+
<label><?php _e('Separated by', 'pmxi_plugin'); ?></label>
|
55 |
+
<input type="text" class="small tax_delim" value="<?php echo (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->delim) ? $taxonomies_hierarchy[0]->delim : ',' ?>" />
|
56 |
+
<label for="nested_<?php echo $ctx->name;?>"><?php _e('Enable Auto Nest', 'pmxi_plugin');?></label>
|
57 |
+
<input id="nested_<?php echo $ctx->name;?>" type="checkbox" class="taxonomy_auto_nested" <?php if (!empty($taxonomies_hierarchy) and $taxonomies_hierarchy[0]->auto_nested):?>checked="checked"<?php endif; ?> />
|
58 |
+
<a href="#help" class="help" title="<?php _e('If this box is checked, a category hierarchy will be created. For example, if your <code>{category}</code> value is <code>Mens > Shoes > Diesel</code>, enter <code>></code> as the separator and enable <code>Auto Nest</code> to create <code>Diesel</code> as a child category of <code>Shoes</code> and <code>Shoes</code> as a child category of <code>Mens.</code>', 'pmxi_plugin') ?>">?</a>
|
59 |
+
<!--a href="javascript:void(0);" class="icon-item add-new-ico"><?php _e('Add more','pmxi_plugin');?></a-->
|
60 |
+
</div>
|
61 |
+
</div>
|
62 |
+
</div>
|
63 |
+
</td>
|
64 |
+
</tr>
|
65 |
+
</table>
|
66 |
+
<?php endforeach; ?>
|
67 |
+
</fieldset>
|
68 |
+
</td>
|
69 |
+
</tr>
|
70 |
+
<?php endif;
|
71 |
?>
|
views/admin/import/process.php
CHANGED
@@ -1,112 +1,112 @@
|
|
1 |
-
<div class="inner-content">
|
2 |
-
<h2><?php _e('Import XML - <span id="status">Processing...</span>', 'pmxi_plugin') ?></h2>
|
3 |
-
<hr />
|
4 |
-
<p id="process_notice"><?php _e('Importing may take some time. Please do not close your browser or refresh the page until the process is complete.', 'pmxi_plugin') ?></p>
|
5 |
-
<?php _e('<div id="processbar"><div></div><span id="import_progress"><span id="left_progress">Time Elapsed <span id="then">00:00:00</span></span><span id="center_progress"> Created 0 / Updated 0 </span><span id="right_progress">0%</span></span></div>', 'pmxi_plugin'); ?>
|
6 |
-
<div id="logbar">
|
7 |
-
<a href="javascript:void(0);" id="view_log"
|
8 |
-
<p
|
9 |
-
</div>
|
10 |
-
<fieldset id="logwrapper" <?php if ($_SESSION['pmxi_import']['large_file']): ?> style="display:none;" <?php endif; ?>>
|
11 |
-
<legend
|
12 |
-
<div id="loglist">
|
13 |
-
|
14 |
-
</div>
|
15 |
-
</fieldset>
|
16 |
-
<a href="<?php echo add_query_arg(array('page' => 'pmxi-admin-manage'), remove_query_arg(array('id','page'), $this->baseUrl)); ?>" style="float:right; display:none;" id="import_finished"><?php _e('Manage Imports', 'pmxi_plugin') ?></a>
|
17 |
-
</div>
|
18 |
-
|
19 |
-
<script type="text/javascript">
|
20 |
-
//<![CDATA[
|
21 |
-
(function($){
|
22 |
-
$('#status').each(function () {
|
23 |
-
|
24 |
-
var then = $('#then');
|
25 |
-
start_date = moment().sod();
|
26 |
-
update = function(){
|
27 |
-
var duration = moment.duration({'seconds' : 1});
|
28 |
-
start_date.add(duration);
|
29 |
-
|
30 |
-
if ( ! $('#download_pmxi_log').length) then.html(start_date.format('HH:mm:ss'));
|
31 |
-
};
|
32 |
-
update();
|
33 |
-
setInterval(update, 1000);
|
34 |
-
|
35 |
-
var $this = $(this);
|
36 |
-
if ($this.html().match(/\.{3}$/)) {
|
37 |
-
var dots = 0;
|
38 |
-
var status = $this.html().replace(/\.{3}$/, '');
|
39 |
-
var interval ;
|
40 |
-
var odd = false;
|
41 |
-
interval = setInterval(function () {
|
42 |
-
var percents = $('.import_percent:last').html();
|
43 |
-
if ($this.html().match(new RegExp(status + '\\.{1,3}$', ''))) {
|
44 |
-
if (percents != null && percents != ''){
|
45 |
-
$this.html(status + '...'.substr(0, dots++ % 3 + 1));
|
46 |
-
var msg = $('.import_process_bar:last').html();
|
47 |
-
if (msg != undefined) $('#center_progress').html(msg);
|
48 |
-
$('#warnings').html($('.warnings_count:last').html());
|
49 |
-
$('#errors').html($('.errors_count:last').html());
|
50 |
-
$('#right_progress').html(((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%');
|
51 |
-
$('#processbar div').css({'width': ((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%'});
|
52 |
-
}
|
53 |
-
} else {
|
54 |
-
var msg = $('.import_process_bar:last').html();
|
55 |
-
if (msg != undefined) $('#center_progress').html(msg);
|
56 |
-
$('#right_progress').html(((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%');
|
57 |
-
$('#warnings').html($('.warnings_count:last').html());
|
58 |
-
$('#errors').html($('.errors_count:last').html());
|
59 |
-
$('#processbar div').css({'width': ((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%'});
|
60 |
-
$('#process_notice').hide();
|
61 |
-
$('#import_finished').show();
|
62 |
-
clearInterval(update);
|
63 |
-
clearInterval(interval);
|
64 |
-
}
|
65 |
-
if ($('#download_pmxi_log').length){
|
66 |
-
$('#download_log').attr('href', $('#download_pmxi_log').attr('href')).show();
|
67 |
-
$('#download_log_separator').show();
|
68 |
-
}
|
69 |
-
// fill log bar
|
70 |
-
$('.progress-msg').each(function(i){
|
71 |
-
if ( ! $(this).find('.import_process_bar').length){
|
72 |
-
<?php if ($_SESSION['pmxi_import']['large_file']): ?>
|
73 |
-
if ($('#loglist').find('p').length > 100) $('#loglist').html('');
|
74 |
-
<?php endif; ?>
|
75 |
-
$('#loglist').append('<p ' + ((odd) ? 'class="odd"' : 'class="even"') + '>' + $(this).html() + '</p>');
|
76 |
-
$('#loglist').animate({ scrollTop: $('#loglist').get(0).scrollHeight }, 0);
|
77 |
-
$(this).remove();
|
78 |
-
odd = !odd;
|
79 |
-
}
|
80 |
-
});
|
81 |
-
|
82 |
-
}, 1000);
|
83 |
-
$('#processbar').css({'visibility':'visible'});
|
84 |
-
}
|
85 |
-
});
|
86 |
-
window.onbeforeunload = function () {
|
87 |
-
return 'WARNING:\nImport process in under way, leaving the page will interrupt\nthe operation and most likely to cause leftovers in posts.';
|
88 |
-
};
|
89 |
-
})(jQuery);
|
90 |
-
|
91 |
-
//]]>
|
92 |
-
</script>
|
93 |
-
|
94 |
-
<?php if ($_SESSION['pmxi_import']['large_file']): ?>
|
95 |
-
|
96 |
-
<script type="text/javascript">
|
97 |
-
//<![CDATA[
|
98 |
-
(function($){
|
99 |
-
function parse_element(){
|
100 |
-
$.post('admin.php?page=pmxi-admin-import&action=process', {}, function (data) {
|
101 |
-
$('#loglist').append(data);
|
102 |
-
if ( ! $('#download_pmxi_log').length) parse_element();
|
103 |
-
}, 'html').fail(function() {
|
104 |
-
if ( ! $('#download_pmxi_log').length) parse_element();
|
105 |
-
});
|
106 |
-
}
|
107 |
-
parse_element();
|
108 |
-
})(jQuery);
|
109 |
-
//]]>
|
110 |
-
</script>
|
111 |
-
|
112 |
<?php endif; ?>
|
1 |
+
<div class="inner-content">
|
2 |
+
<h2><?php _e('Import XML - <span id="status">Processing...</span>', 'pmxi_plugin') ?></h2>
|
3 |
+
<hr />
|
4 |
+
<p id="process_notice"><?php _e('Importing may take some time. Please do not close your browser or refresh the page until the process is complete.', 'pmxi_plugin') ?></p>
|
5 |
+
<?php _e('<div id="processbar"><div></div><span id="import_progress"><span id="left_progress">Time Elapsed <span id="then">00:00:00</span></span><span id="center_progress"> Created 0 / Updated 0 </span><span id="right_progress">0%</span></span></div>', 'pmxi_plugin'); ?>
|
6 |
+
<div id="logbar">
|
7 |
+
<a href="javascript:void(0);" id="view_log"><?php _e('View Log','pmxi_plugin');?></a><span id="download_log_separator"> | </span> <a href="javascript:void(0);" id="download_log"><?php _e('Download Log','pmxi_plugin');?></a>
|
8 |
+
<p><?php _e('Warnings','pmxi_plugin');?> (<span id="warnings">0</span>), <?php _e('Errors','pmxi_plugin');?> (<span id="errors">0</span>)</p>
|
9 |
+
</div>
|
10 |
+
<fieldset id="logwrapper" <?php if ($_SESSION['pmxi_import']['large_file']): ?> style="display:none;" <?php endif; ?>>
|
11 |
+
<legend><?php _e('Log','pmxi_plugin');?></legend>
|
12 |
+
<div id="loglist">
|
13 |
+
|
14 |
+
</div>
|
15 |
+
</fieldset>
|
16 |
+
<a href="<?php echo add_query_arg(array('page' => 'pmxi-admin-manage'), remove_query_arg(array('id','page'), $this->baseUrl)); ?>" style="float:right; display:none;" id="import_finished"><?php _e('Manage Imports', 'pmxi_plugin') ?></a>
|
17 |
+
</div>
|
18 |
+
|
19 |
+
<script type="text/javascript">
|
20 |
+
//<![CDATA[
|
21 |
+
(function($){
|
22 |
+
$('#status').each(function () {
|
23 |
+
|
24 |
+
var then = $('#then');
|
25 |
+
start_date = moment().sod();
|
26 |
+
update = function(){
|
27 |
+
var duration = moment.duration({'seconds' : 1});
|
28 |
+
start_date.add(duration);
|
29 |
+
|
30 |
+
if ( ! $('#download_pmxi_log').length) then.html(start_date.format('HH:mm:ss'));
|
31 |
+
};
|
32 |
+
update();
|
33 |
+
setInterval(update, 1000);
|
34 |
+
|
35 |
+
var $this = $(this);
|
36 |
+
if ($this.html().match(/\.{3}$/)) {
|
37 |
+
var dots = 0;
|
38 |
+
var status = $this.html().replace(/\.{3}$/, '');
|
39 |
+
var interval ;
|
40 |
+
var odd = false;
|
41 |
+
interval = setInterval(function () {
|
42 |
+
var percents = $('.import_percent:last').html();
|
43 |
+
if ($this.html().match(new RegExp(status + '\\.{1,3}$', ''))) {
|
44 |
+
if (percents != null && percents != ''){
|
45 |
+
$this.html(status + '...'.substr(0, dots++ % 3 + 1));
|
46 |
+
var msg = $('.import_process_bar:last').html();
|
47 |
+
if (msg != undefined) $('#center_progress').html(msg);
|
48 |
+
$('#warnings').html($('.warnings_count:last').html());
|
49 |
+
$('#errors').html($('.errors_count:last').html());
|
50 |
+
$('#right_progress').html(((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%');
|
51 |
+
$('#processbar div').css({'width': ((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%'});
|
52 |
+
}
|
53 |
+
} else {
|
54 |
+
var msg = $('.import_process_bar:last').html();
|
55 |
+
if (msg != undefined) $('#center_progress').html(msg);
|
56 |
+
$('#right_progress').html(((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%');
|
57 |
+
$('#warnings').html($('.warnings_count:last').html());
|
58 |
+
$('#errors').html($('.errors_count:last').html());
|
59 |
+
$('#processbar div').css({'width': ((parseInt(percents) > 100 || percents == undefined) ? 100 : percents) + '%'});
|
60 |
+
$('#process_notice').hide();
|
61 |
+
$('#import_finished').show();
|
62 |
+
clearInterval(update);
|
63 |
+
clearInterval(interval);
|
64 |
+
}
|
65 |
+
if ($('#download_pmxi_log').length){
|
66 |
+
$('#download_log').attr('href', $('#download_pmxi_log').attr('href')).show();
|
67 |
+
$('#download_log_separator').show();
|
68 |
+
}
|
69 |
+
// fill log bar
|
70 |
+
$('.progress-msg').each(function(i){
|
71 |
+
if ( ! $(this).find('.import_process_bar').length){
|
72 |
+
<?php if ($_SESSION['pmxi_import']['large_file']): ?>
|
73 |
+
if ($('#loglist').find('p').length > 100) $('#loglist').html('');
|
74 |
+
<?php endif; ?>
|
75 |
+
$('#loglist').append('<p ' + ((odd) ? 'class="odd"' : 'class="even"') + '>' + $(this).html() + '</p>');
|
76 |
+
$('#loglist').animate({ scrollTop: $('#loglist').get(0).scrollHeight }, 0);
|
77 |
+
$(this).remove();
|
78 |
+
odd = !odd;
|
79 |
+
}
|
80 |
+
});
|
81 |
+
|
82 |
+
}, 1000);
|
83 |
+
$('#processbar').css({'visibility':'visible'});
|
84 |
+
}
|
85 |
+
});
|
86 |
+
window.onbeforeunload = function () {
|
87 |
+
return 'WARNING:\nImport process in under way, leaving the page will interrupt\nthe operation and most likely to cause leftovers in posts.';
|
88 |
+
};
|
89 |
+
})(jQuery);
|
90 |
+
|
91 |
+
//]]>
|
92 |
+
</script>
|
93 |
+
|
94 |
+
<?php if ($_SESSION['pmxi_import']['large_file']): ?>
|
95 |
+
|
96 |
+
<script type="text/javascript">
|
97 |
+
//<![CDATA[
|
98 |
+
(function($){
|
99 |
+
function parse_element(){
|
100 |
+
$.post('admin.php?page=pmxi-admin-import&action=process', {}, function (data) {
|
101 |
+
$('#loglist').append(data);
|
102 |
+
if ( ! $('#download_pmxi_log').length) parse_element();
|
103 |
+
}, 'html').fail(function() {
|
104 |
+
if ( ! $('#download_pmxi_log').length) parse_element();
|
105 |
+
});
|
106 |
+
}
|
107 |
+
parse_element();
|
108 |
+
})(jQuery);
|
109 |
+
//]]>
|
110 |
+
</script>
|
111 |
+
|
112 |
<?php endif; ?>
|
views/admin/import/tag.php
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
<?php if (!empty($elements->length)):?>
|
2 |
-
<div class="tag">
|
3 |
-
<input type="hidden" name="tagno" value="<?php echo $tagno ?>" />
|
4 |
-
<div class="title">
|
5 |
-
<?php printf(__('Record #<strong>%s</strong> out of <strong>%s</strong>', 'pmxi_plugin'), $tagno, ( ! $_SESSION['pmxi_import']['large_file']) ? $elements->length : $_SESSION['pmxi_import']['count']); ?>
|
6 |
-
<div class="navigation">
|
7 |
-
<?php if ($tagno > 1): ?><a href="#prev">⟨⟨</a><?php else: ?><span>⟨⟨</span><?php endif ?>
|
8 |
-
<?php if ($tagno < $elements->length or ($_SESSION['pmxi_import']['large_file'] and $tagno < $_SESSION['pmxi_import']['count'])): ?><a href="#next">⟩⟩</a><?php else: ?><span>⟩⟩</span><?php endif ?>
|
9 |
-
</div>
|
10 |
-
</div>
|
11 |
-
<div class="clear"></div>
|
12 |
-
<div class="xml resetable"> <?php if (!empty($elements->length)) $this->render_xml_element(( ! $_SESSION['pmxi_import']['large_file']) ? $elements->item($tagno - 1) : $elements->item(0), true); ?></div>
|
13 |
-
<p class="xpath_help">
|
14 |
-
<?php _e('Operate on elements using your own PHP functions, use FOREACH loops, and more.<br />Read the <a href="http://www.wpallimport.com/portal/" target="_blank">documentation</a> to learn how.', 'pmxi_plugin') ?>
|
15 |
-
</p>
|
16 |
-
</div>
|
17 |
-
<?php else: ?>
|
18 |
-
<div class="error inline below-h2" style="padding:10px; margin-top:45px;">
|
19 |
-
<?php printf(__('History file not found.', 'pmxi_plugin')); ?>
|
20 |
-
</div>
|
21 |
<?php endif; ?>
|
1 |
+
<?php if (!empty($elements->length)):?>
|
2 |
+
<div class="tag">
|
3 |
+
<input type="hidden" name="tagno" value="<?php echo $tagno ?>" />
|
4 |
+
<div class="title">
|
5 |
+
<?php printf(__('Record #<strong>%s</strong> out of <strong>%s</strong>', 'pmxi_plugin'), $tagno, ( ! $_SESSION['pmxi_import']['large_file']) ? $elements->length : $_SESSION['pmxi_import']['count']); ?>
|
6 |
+
<div class="navigation">
|
7 |
+
<?php if ($tagno > 1): ?><a href="#prev">⟨⟨</a><?php else: ?><span>⟨⟨</span><?php endif ?>
|
8 |
+
<?php if ($tagno < $elements->length or ($_SESSION['pmxi_import']['large_file'] and $tagno < $_SESSION['pmxi_import']['count'])): ?><a href="#next">⟩⟩</a><?php else: ?><span>⟩⟩</span><?php endif ?>
|
9 |
+
</div>
|
10 |
+
</div>
|
11 |
+
<div class="clear"></div>
|
12 |
+
<div class="xml resetable"> <?php if (!empty($elements->length)) $this->render_xml_element(( ! $_SESSION['pmxi_import']['large_file']) ? $elements->item($tagno - 1) : $elements->item(0), true); ?></div>
|
13 |
+
<p class="xpath_help">
|
14 |
+
<?php _e('Operate on elements using your own PHP functions, use FOREACH loops, and more.<br />Read the <a href="http://www.wpallimport.com/portal/" target="_blank">documentation</a> to learn how.', 'pmxi_plugin') ?>
|
15 |
+
</p>
|
16 |
+
</div>
|
17 |
+
<?php else: ?>
|
18 |
+
<div class="error inline below-h2" style="padding:10px; margin-top:45px;">
|
19 |
+
<?php printf(__('History file not found.', 'pmxi_plugin')); ?>
|
20 |
+
</div>
|
21 |
<?php endif; ?>
|
views/admin/import/template.php
CHANGED
@@ -1,97 +1,97 @@
|
|
1 |
-
<form class="template <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
2 |
-
<h2>
|
3 |
-
<?php if ($this->isWizard): ?>
|
4 |
-
<?php _e('Import XML/CSV - Step 3: Template Builder', 'pmxi_plugin') ?>
|
5 |
-
<?php else: ?>
|
6 |
-
<?php _e('Edit Import Template', 'pmxi_plugin') ?>
|
7 |
-
<?php endif ?>
|
8 |
-
</h2>
|
9 |
-
|
10 |
-
<?php if ($this->errors->get_error_codes()): ?>
|
11 |
-
<?php $this->error() ?>
|
12 |
-
<?php endif ?>
|
13 |
-
|
14 |
-
<h3
|
15 |
-
|
16 |
-
<table class="layout">
|
17 |
-
<tr>
|
18 |
-
<td class="left">
|
19 |
-
<h3
|
20 |
-
<div style="width:100%">
|
21 |
-
<input id="title" class="widefat" type="text" name="title" value="<?php echo esc_attr($post['title']) ?>" />
|
22 |
-
</div>
|
23 |
-
|
24 |
-
<h3>
|
25 |
-
Post Content
|
26 |
-
</h3>
|
27 |
-
<div id="poststuff">
|
28 |
-
<div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
|
29 |
-
|
30 |
-
<?php the_editor($post['content']) ?>
|
31 |
-
<table id="post-status-info" cellspacing="0">
|
32 |
-
<tbody>
|
33 |
-
<tr>
|
34 |
-
<td id="wp-word-count"></td>
|
35 |
-
<td class="autosave-info">
|
36 |
-
<span id="autosave"> </span>
|
37 |
-
</td>
|
38 |
-
</tr>
|
39 |
-
</tbody>
|
40 |
-
</table>
|
41 |
-
</div>
|
42 |
-
</div>
|
43 |
-
<p>
|
44 |
-
<span class="header-option">
|
45 |
-
<input type="hidden" name="is_keep_linebreaks" value="0" />
|
46 |
-
<input type="checkbox" id="is_keep_linebreaks" name="is_keep_linebreaks" value="1" <?php echo $post['is_keep_linebreaks'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
|
47 |
-
<label for="is_keep_linebreaks"><?php _e('Keep line breaks from XML', 'pmxi_plugin') ?></label> <br>
|
48 |
-
<input type="hidden" name="is_leave_html" value="0" />
|
49 |
-
<input type="checkbox" id="is_leave_html" name="is_leave_html" value="1" <?php echo $post['is_leave_html'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;" class="switcher"/>
|
50 |
-
<label for="is_leave_html"><?php _e('Decode HTML entities with <b>html_entity_decode</b>', 'pmxi_plugin') ?></label><a class="help" href="#help" original-title="If HTML code is showing up in your posts, use this option. You can also use <br /><br /><i>[html_entity_decode({my/xpath})]</i><br /><br /> or <br /><br /><i>[htmlentities({my/xpath})]</i><br /><br /> to decode or encode HTML in your file.">?</a>
|
51 |
-
<div class="switcher-target-is_leave_html" style="padding-left:17px;">
|
52 |
-
<input type="hidden" name="fix_characters" value="0" />
|
53 |
-
<input type="checkbox" id="fix_characters" name="fix_characters" value="1" <?php echo $post['fix_characters'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
|
54 |
-
<label for="fix_characters"><?php _e('Auto-fix broken special characters', 'pmxi_plugin') ?></label>
|
55 |
-
</div>
|
56 |
-
</span>
|
57 |
-
</p>
|
58 |
-
<hr>
|
59 |
-
<p style="clear:both;">
|
60 |
-
<?php wp_nonce_field('template', '_wpnonce_template'); ?>
|
61 |
-
<input type="hidden" name="is_submitted" value="1" />
|
62 |
-
<div class="input">
|
63 |
-
<input type="checkbox" id="save_template_as" name="save_template_as" value="1" <?php echo $post['save_template_as'] ? 'checked="checked"' : '' ?> style="position:relative; top:-2px;"/> <label for="save_template_as"
|
64 |
-
</div>
|
65 |
-
</p>
|
66 |
-
|
67 |
-
<?php $templates = new PMXI_Template_List() ?>
|
68 |
-
<div class="load-template">
|
69 |
-
<span
|
70 |
-
<select name="load_template">
|
71 |
-
<option value=""><?php _e('Load Template...', 'pmxi_plugin') ?></option>
|
72 |
-
<?php foreach ($templates->getBy()->convertRecords() as $t): ?>
|
73 |
-
<option value="<?php echo $t->id ?>"><?php echo $t->name ?></option>
|
74 |
-
<?php endforeach ?>
|
75 |
-
</select>
|
76 |
-
</div>
|
77 |
-
|
78 |
-
<p>
|
79 |
-
<span class="submit-buttons" style="float:right;">
|
80 |
-
<?php if ($this->isWizard):?>
|
81 |
-
<a href="<?php echo add_query_arg('action', 'element', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
82 |
-
<?php else: ?>
|
83 |
-
<a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
84 |
-
<?php endif; ?>
|
85 |
-
<a href="#preview" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button preview" title="<?php _e('Preview Post', 'pmxi_plugin') ?>"><?php _e('Preview', 'pmxi_plugin') ?></a>
|
86 |
-
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e( ($this->isWizard) ? 'Next' : 'Update', 'pmxi_plugin') ?>" />
|
87 |
-
</span>
|
88 |
-
</p>
|
89 |
-
</td>
|
90 |
-
<?php if ($this->isWizard or $this->isTemplateEdit): ?>
|
91 |
-
<td class="right template-sidebar">
|
92 |
-
<?php $this->tag() ?>
|
93 |
-
</td>
|
94 |
-
<?php endif ?>
|
95 |
-
</tr>
|
96 |
-
</table>
|
97 |
-
</form>
|
1 |
+
<form class="template <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
2 |
+
<h2>
|
3 |
+
<?php if ($this->isWizard): ?>
|
4 |
+
<?php _e('Import XML/CSV - Step 3: Template Builder', 'pmxi_plugin') ?>
|
5 |
+
<?php else: ?>
|
6 |
+
<?php _e('Edit Import Template', 'pmxi_plugin') ?>
|
7 |
+
<?php endif ?>
|
8 |
+
</h2>
|
9 |
+
|
10 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
11 |
+
<?php $this->error() ?>
|
12 |
+
<?php endif ?>
|
13 |
+
|
14 |
+
<h3><?php _e('Drag-and-drop an element from the right to the left to build your template','pmxi_plugin');?></h3>
|
15 |
+
|
16 |
+
<table class="layout">
|
17 |
+
<tr>
|
18 |
+
<td class="left">
|
19 |
+
<h3><?php _e('Post Title','pmxi_plugin');?></h3>
|
20 |
+
<div style="width:100%">
|
21 |
+
<input id="title" class="widefat" type="text" name="title" value="<?php echo esc_attr($post['title']) ?>" />
|
22 |
+
</div>
|
23 |
+
|
24 |
+
<h3>
|
25 |
+
<?php _e('Post Content','pmxi_plugin');?>
|
26 |
+
</h3>
|
27 |
+
<div id="poststuff">
|
28 |
+
<div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
|
29 |
+
|
30 |
+
<?php the_editor($post['content']) ?>
|
31 |
+
<table id="post-status-info" cellspacing="0">
|
32 |
+
<tbody>
|
33 |
+
<tr>
|
34 |
+
<td id="wp-word-count"></td>
|
35 |
+
<td class="autosave-info">
|
36 |
+
<span id="autosave"> </span>
|
37 |
+
</td>
|
38 |
+
</tr>
|
39 |
+
</tbody>
|
40 |
+
</table>
|
41 |
+
</div>
|
42 |
+
</div>
|
43 |
+
<p>
|
44 |
+
<span class="header-option">
|
45 |
+
<input type="hidden" name="is_keep_linebreaks" value="0" />
|
46 |
+
<input type="checkbox" id="is_keep_linebreaks" name="is_keep_linebreaks" value="1" <?php echo $post['is_keep_linebreaks'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
|
47 |
+
<label for="is_keep_linebreaks"><?php _e('Keep line breaks from XML', 'pmxi_plugin') ?></label> <br>
|
48 |
+
<input type="hidden" name="is_leave_html" value="0" />
|
49 |
+
<input type="checkbox" id="is_leave_html" name="is_leave_html" value="1" <?php echo $post['is_leave_html'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;" class="switcher"/>
|
50 |
+
<label for="is_leave_html"><?php _e('Decode HTML entities with <b>html_entity_decode</b>', 'pmxi_plugin') ?></label><a class="help" href="#help" original-title="If HTML code is showing up in your posts, use this option. You can also use <br /><br /><i>[html_entity_decode({my/xpath})]</i><br /><br /> or <br /><br /><i>[htmlentities({my/xpath})]</i><br /><br /> to decode or encode HTML in your file.">?</a>
|
51 |
+
<div class="switcher-target-is_leave_html" style="padding-left:17px;">
|
52 |
+
<input type="hidden" name="fix_characters" value="0" />
|
53 |
+
<input type="checkbox" id="fix_characters" name="fix_characters" value="1" <?php echo $post['fix_characters'] ? 'checked="checked"' : '' ?> style="position:relative; top:-3px;"/>
|
54 |
+
<label for="fix_characters"><?php _e('Auto-fix broken special characters', 'pmxi_plugin') ?></label>
|
55 |
+
</div>
|
56 |
+
</span>
|
57 |
+
</p>
|
58 |
+
<hr>
|
59 |
+
<p style="clear:both;">
|
60 |
+
<?php wp_nonce_field('template', '_wpnonce_template'); ?>
|
61 |
+
<input type="hidden" name="is_submitted" value="1" />
|
62 |
+
<div class="input">
|
63 |
+
<input type="checkbox" id="save_template_as" name="save_template_as" value="1" <?php echo $post['save_template_as'] ? 'checked="checked"' : '' ?> style="position:relative; top:-2px;"/> <label for="save_template_as"><?php _e('Save template as:','pmxi_plugin');?></label> <input type="text" name="name" title="<?php _e('Save Template As...', 'pmxi_plugin') ?>" style="vertical-align:middle; font-size:13px;" value="<?php echo esc_attr($post['name']) ?>" />
|
64 |
+
</div>
|
65 |
+
</p>
|
66 |
+
|
67 |
+
<?php $templates = new PMXI_Template_List() ?>
|
68 |
+
<div class="load-template">
|
69 |
+
<span><?php _e('Load existing template:','pmxi_plugin');?> </span>
|
70 |
+
<select name="load_template">
|
71 |
+
<option value=""><?php _e('Load Template...', 'pmxi_plugin') ?></option>
|
72 |
+
<?php foreach ($templates->getBy()->convertRecords() as $t): ?>
|
73 |
+
<option value="<?php echo $t->id ?>"><?php echo $t->name ?></option>
|
74 |
+
<?php endforeach ?>
|
75 |
+
</select>
|
76 |
+
</div>
|
77 |
+
|
78 |
+
<p>
|
79 |
+
<span class="submit-buttons" style="float:right;">
|
80 |
+
<?php if ($this->isWizard):?>
|
81 |
+
<a href="<?php echo add_query_arg('action', 'element', $this->baseUrl) ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
82 |
+
<?php else: ?>
|
83 |
+
<a href="<?php echo remove_query_arg('id', remove_query_arg('action', $this->baseUrl)); ?>" class="back"><?php _e('Back', 'pmxi_plugin') ?></a>
|
84 |
+
<?php endif; ?>
|
85 |
+
<a href="#preview" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button preview" title="<?php _e('Preview Post', 'pmxi_plugin') ?>"><?php _e('Preview', 'pmxi_plugin') ?></a>
|
86 |
+
<input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only large_button" value="<?php _e( ($this->isWizard) ? 'Next' : 'Update', 'pmxi_plugin') ?>" />
|
87 |
+
</span>
|
88 |
+
</p>
|
89 |
+
</td>
|
90 |
+
<?php if ($this->isWizard or $this->isTemplateEdit): ?>
|
91 |
+
<td class="right template-sidebar">
|
92 |
+
<?php $this->tag() ?>
|
93 |
+
</td>
|
94 |
+
<?php endif ?>
|
95 |
+
</tr>
|
96 |
+
</table>
|
97 |
+
</form>
|
views/admin/manage/index.php
CHANGED
@@ -1,249 +1,249 @@
|
|
1 |
-
<h2>
|
2 |
-
<?php _e('Manage Imports', 'pmxi_plugin') ?>
|
3 |
-
|
4 |
-
<a href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import'), admin_url('admin.php'))) ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" style="font-size:15px; padding:10px 20px; text-decoration:none;"><?php echo esc_html_x('New Import', 'pmxi_plugin'); ?></a>
|
5 |
-
</h2>
|
6 |
-
|
7 |
-
<?php
|
8 |
-
// notify user
|
9 |
-
if (!PMXI_Plugin::getInstance()->getOption('dismiss_manage_top')) {
|
10 |
-
?>
|
11 |
-
<div class="updated"><p>
|
12 |
-
<?php printf(
|
13 |
-
__('Need help with WP All Import? Please visit <a href="http://www.wpallimport.com/support">http://www.wpallimport.com/support</a> or send an e-mail to <a href="mailto:support@soflyy.com">support@soflyy.com</a>. We give priority to professional edition customers, but we respond to most inquiries from free version users within 24 hours during business days.<br/><br/>Please note that we are unable to handle technical support requests in the WordPress.org community forums. <br/><br/><a href="javascript:void(0);" id="dismiss_manage_top"><u>dismiss</u></a>', 'pmxi_plugin')
|
14 |
-
) ?>
|
15 |
-
</p></div>
|
16 |
-
<?php
|
17 |
-
}
|
18 |
-
?>
|
19 |
-
|
20 |
-
<?php if ($this->errors->get_error_codes()): ?>
|
21 |
-
<?php $this->error() ?>
|
22 |
-
<?php endif ?>
|
23 |
-
|
24 |
-
<form method="get">
|
25 |
-
<input type="hidden" name="page" value="<?php echo esc_attr($this->input->get('page')) ?>" />
|
26 |
-
<p class="search-box">
|
27 |
-
<label for="search-input" class="screen-reader-text"><?php _e('Search Imports', 'pmxi_plugin') ?>:</label>
|
28 |
-
<input id="search-input" type="text" name="s" value="<?php echo esc_attr($s) ?>" />
|
29 |
-
<input type="submit" class="button" value="<?php _e('Search Imports', 'pmxi_plugin') ?>">
|
30 |
-
</p>
|
31 |
-
</form>
|
32 |
-
|
33 |
-
<?php
|
34 |
-
// define the columns to display, the syntax is 'internal name' => 'display name'
|
35 |
-
$columns = array(
|
36 |
-
'id' => __('ID', 'pmxi_plugin'),
|
37 |
-
'name' => __('File', 'pmxi_plugin'),
|
38 |
-
'xpath' => __('XPath', 'pmxi_plugin'),
|
39 |
-
'post_count' => __('Records', 'pmxi_plugin'),
|
40 |
-
'first_import' => __('First Import', 'pmxi_plugin'),
|
41 |
-
'registered_on' => __('Last Import', 'pmxi_plugin'),
|
42 |
-
/*'scheduled' => __('Reimport Schedule', 'pmxi_plugin'),
|
43 |
-
'next_import' => __('Next Import', 'pmxi_plugin'),*/
|
44 |
-
);
|
45 |
-
?>
|
46 |
-
<form method="post" id="import-list" action="<?php echo remove_query_arg('pmxi_nt') ?>">
|
47 |
-
<input type="hidden" name="action" value="bulk" />
|
48 |
-
<?php wp_nonce_field('bulk-imports', '_wpnonce_bulk-imports') ?>
|
49 |
-
|
50 |
-
<div class="tablenav">
|
51 |
-
<div class="alignleft actions">
|
52 |
-
<select name="bulk-action">
|
53 |
-
<option value="" selected="selected"><?php _e('Bulk Actions', 'pmxi_plugin') ?></option>
|
54 |
-
<option value="delete"><?php _e('Delete', 'pmxi_plugin') ?></option>
|
55 |
-
</select>
|
56 |
-
<input type="submit" value="<?php esc_attr_e('Apply', 'pmxi_plugin') ?>" name="doaction" id="doaction" class="button-secondary action" />
|
57 |
-
</div>
|
58 |
-
|
59 |
-
<?php if ($page_links): ?>
|
60 |
-
<div class="tablenav-pages">
|
61 |
-
<?php echo $page_links_html = sprintf(
|
62 |
-
'<span class="displaying-num">' . __('Displaying %s–%s of %s', 'pmxi_plugin') . '</span>%s',
|
63 |
-
number_format_i18n(($pagenum - 1) * $perPage + 1),
|
64 |
-
number_format_i18n(min($pagenum * $perPage, $list->total())),
|
65 |
-
number_format_i18n($list->total()),
|
66 |
-
$page_links
|
67 |
-
) ?>
|
68 |
-
</div>
|
69 |
-
<?php endif ?>
|
70 |
-
</div>
|
71 |
-
<div class="clear"></div>
|
72 |
-
|
73 |
-
<table class="widefat pmxi-admin-imports">
|
74 |
-
<thead>
|
75 |
-
<tr>
|
76 |
-
<th class="manage-column column-cb check-column" scope="col">
|
77 |
-
<input type="checkbox" />
|
78 |
-
</th>
|
79 |
-
<?php
|
80 |
-
$col_html = '';
|
81 |
-
foreach ($columns as $column_id => $column_display_name) {
|
82 |
-
$column_link = "<a href='";
|
83 |
-
$order2 = 'ASC';
|
84 |
-
if ($order_by == $column_id)
|
85 |
-
$order2 = ($order == 'DESC') ? 'ASC' : 'DESC';
|
86 |
-
|
87 |
-
$column_link .= esc_url(add_query_arg(array('order' => $order2, 'order_by' => $column_id), $this->baseUrl));
|
88 |
-
$column_link .= "'>{$column_display_name}</a>";
|
89 |
-
$col_html .= '<th scope="col" class="column-' . $column_id . ' ' . ($order_by == $column_id ? $order : '') . '">' . $column_link . '</th>';
|
90 |
-
}
|
91 |
-
echo $col_html;
|
92 |
-
?>
|
93 |
-
</tr>
|
94 |
-
</thead>
|
95 |
-
<tfoot>
|
96 |
-
<tr>
|
97 |
-
<th class="manage-column column-cb check-column" scope="col">
|
98 |
-
<input type="checkbox" />
|
99 |
-
</th>
|
100 |
-
<?php echo $col_html; ?>
|
101 |
-
</tr>
|
102 |
-
</tfoot>
|
103 |
-
<tbody id="the-pmxi-admin-import-list" class="list:pmxi-admin-imports">
|
104 |
-
<?php if ($list->isEmpty()): ?>
|
105 |
-
<tr>
|
106 |
-
<td colspan="<?php echo count($columns) + 1 ?>"><?php _e('No previous imports found.', 'pmxi_plugin') ?></td>
|
107 |
-
</tr>
|
108 |
-
<?php else: ?>
|
109 |
-
<?php $class = ''; foreach ($list as $item): ?>
|
110 |
-
<?php $class = ('alternate' == $class) ? '' : 'alternate'; ?>
|
111 |
-
<tr class="<?php echo $class; ?>" valign="middle">
|
112 |
-
<th scope="row" class="check-column">
|
113 |
-
<input type="checkbox" id="item_<?php echo $item['id'] ?>" name="items[]" value="<?php echo esc_attr($item['id']) ?>" />
|
114 |
-
</th>
|
115 |
-
<?php foreach ($columns as $column_id => $column_display_name): ?>
|
116 |
-
<?php
|
117 |
-
switch ($column_id):
|
118 |
-
case 'id':
|
119 |
-
?>
|
120 |
-
<th valign="top" scope="row">
|
121 |
-
<?php echo $item['id'] ?>
|
122 |
-
</th>
|
123 |
-
<?php
|
124 |
-
break;
|
125 |
-
case 'first_import':
|
126 |
-
?>
|
127 |
-
<td>
|
128 |
-
<?php if ('0000-00-00 00:00:00' == $item['first_import']): ?>
|
129 |
-
<em>never</em>
|
130 |
-
<?php else: ?>
|
131 |
-
<?php echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $item['first_import']) ?>
|
132 |
-
<?php endif ?>
|
133 |
-
</td>
|
134 |
-
<?php
|
135 |
-
break;
|
136 |
-
case 'registered_on':
|
137 |
-
?>
|
138 |
-
<td>
|
139 |
-
<?php if ('0000-00-00 00:00:00' == $item['registered_on']): ?>
|
140 |
-
<em>never</em>
|
141 |
-
<?php else: ?>
|
142 |
-
<?php echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $item['registered_on']) ?>
|
143 |
-
<?php endif ?>
|
144 |
-
</td>
|
145 |
-
<?php
|
146 |
-
break;
|
147 |
-
case 'next_import':
|
148 |
-
?>
|
149 |
-
<td>
|
150 |
-
<?php if ('0000-00-00 00:00:00' == $item['registered_on'] or empty($item['scheduled'])): ?>
|
151 |
-
<em>never</em>
|
152 |
-
<?php
|
153 |
-
else:
|
154 |
-
$task = new _PMXI_Import_Record_Cron_Parser($item['scheduled']);
|
155 |
-
$task_date = $task->getNextRunDate();
|
156 |
-
echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $task_date->format('Y-m-d H:i:s'));
|
157 |
-
endif;
|
158 |
-
?>
|
159 |
-
</td>
|
160 |
-
<?php
|
161 |
-
break;
|
162 |
-
case 'name':
|
163 |
-
?>
|
164 |
-
<td>
|
165 |
-
<strong><?php echo (!empty($item['friendly_name'])) ? $item['friendly_name'] : $item['name']; ?></strong> <br>
|
166 |
-
<?php if ($item['path']): ?>
|
167 |
-
<em><?php echo str_replace("\\", '/', preg_replace('%^(\w+://[^:]+:)[^@]+@%', '$1*****@', $item['path'])); ?></em>
|
168 |
-
<?php endif ?>
|
169 |
-
<div class="row-actions">
|
170 |
-
|
171 |
-
<span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'edit'), $this->baseUrl)) ?>"><?php _e('Edit Template', 'pmxi_plugin') ?></a></span> |
|
172 |
-
<span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'options'), $this->baseUrl)) ?>"><?php _e('Edit Options', 'pmxi_plugin') ?></a></span> |
|
173 |
-
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update'), $this->baseUrl)) ?>"><?php _e('Update', 'pmxi_plugin') ?></a></span> |
|
174 |
-
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import', 'id' => $item['id']), admin_url('admin.php'))) ?>"><?php _e('Use New File', 'pmxi_plugin') ?></a></span> |
|
175 |
-
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'log'), $this->baseUrl)) ?>"><?php _e('Download Log', 'pmxi_plugin') ?></a></span> |
|
176 |
-
<span class="delete"><a class="delete" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'delete'), $this->baseUrl)) ?>"><?php _e('Delete', 'pmxi_plugin') ?></a></span>
|
177 |
-
<?php if ( "Yes" == $item['large_import'] and $item['imported'] != $item['count']):?>
|
178 |
-
| <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update', 'type' => 'continue'), $this->baseUrl)) ?>"><?php _e('Continue import', 'pmxi_plugin') ?></a></span>
|
179 |
-
<?php endif; ?>
|
180 |
-
</div>
|
181 |
-
</td>
|
182 |
-
<?php
|
183 |
-
break;
|
184 |
-
case 'xpath':
|
185 |
-
?>
|
186 |
-
<td>
|
187 |
-
<?php echo $item['xpath'];?>
|
188 |
-
</td>
|
189 |
-
<?php
|
190 |
-
break;
|
191 |
-
case 'post_count':
|
192 |
-
?>
|
193 |
-
<td>
|
194 |
-
<strong><?php echo $item['post_count'] ?></strong>
|
195 |
-
</td>
|
196 |
-
<?php
|
197 |
-
break;
|
198 |
-
default:
|
199 |
-
?>
|
200 |
-
<td>
|
201 |
-
<?php echo $item[$column_id] ?>
|
202 |
-
</td>
|
203 |
-
<?php
|
204 |
-
break;
|
205 |
-
endswitch;
|
206 |
-
?>
|
207 |
-
<?php endforeach; ?>
|
208 |
-
</tr>
|
209 |
-
<?php endforeach; ?>
|
210 |
-
<?php endif ?>
|
211 |
-
</tbody>
|
212 |
-
</table>
|
213 |
-
|
214 |
-
<div class="tablenav">
|
215 |
-
<?php if ($page_links): ?><div class="tablenav-pages"><?php echo $page_links_html ?></div><?php endif ?>
|
216 |
-
|
217 |
-
<div class="alignleft actions">
|
218 |
-
<select name="bulk-action2">
|
219 |
-
<option value="" selected="selected"><?php _e('Bulk Actions', 'pmxi_plugin') ?></option>
|
220 |
-
<?php if ('trash' != $type): ?>
|
221 |
-
<option value="delete"><?php _e('Delete', 'pmxi_plugin') ?></option>
|
222 |
-
<?php else: ?>
|
223 |
-
<option value="restore"><?php _e('Restore', 'pmxi_plugin')?></option>
|
224 |
-
<option value="delete"><?php _e('Delete Permanently', 'pmxi_plugin')?></option>
|
225 |
-
<?php endif ?>
|
226 |
-
</select>
|
227 |
-
<input type="submit" value="<?php esc_attr_e('Apply', 'pmxi_plugin') ?>" name="doaction2" id="doaction2" class="button-secondary action" />
|
228 |
-
</div>
|
229 |
-
</div>
|
230 |
-
<div class="clear"></div>
|
231 |
-
<?php
|
232 |
-
// notify user
|
233 |
-
if (!PMXI_Plugin::getInstance()->getOption('dismiss_manage_bottom')) {
|
234 |
-
?>
|
235 |
-
<div class="updated_bottom"><p>
|
236 |
-
<?php printf(
|
237 |
-
__('<a href="http://wordpress.org/extend/plugins/wp-all-import" target="_blank">If you like WPAllImport, please rate us five stars on WordPress.org!</a> <a href="http://wordpress.org/extend/plugins/wp-all-import" class="pmxi_stars" target="_blank"></a> <br/><br/><a href="javascript:void(0);" id="dismiss_manage_bottom">dismiss</a>', 'pmxi_plugin')
|
238 |
-
) ?>
|
239 |
-
</p></div>
|
240 |
-
<?php
|
241 |
-
}
|
242 |
-
?>
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
<p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=manage&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Find out more about the professional edition of WP All Import.</a></p>
|
247 |
-
|
248 |
-
|
249 |
</form>
|
1 |
+
<h2>
|
2 |
+
<?php _e('Manage Imports', 'pmxi_plugin') ?>
|
3 |
+
|
4 |
+
<a href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import'), admin_url('admin.php'))) ?>" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" style="font-size:15px; padding:10px 20px; text-decoration:none;"><?php echo esc_html_x('New Import', 'pmxi_plugin'); ?></a>
|
5 |
+
</h2>
|
6 |
+
|
7 |
+
<?php
|
8 |
+
// notify user
|
9 |
+
if (!PMXI_Plugin::getInstance()->getOption('dismiss_manage_top')) {
|
10 |
+
?>
|
11 |
+
<div class="updated"><p>
|
12 |
+
<?php printf(
|
13 |
+
__('Need help with WP All Import? Please visit <a href="http://www.wpallimport.com/support">http://www.wpallimport.com/support</a> or send an e-mail to <a href="mailto:support@soflyy.com">support@soflyy.com</a>. We give priority to professional edition customers, but we respond to most inquiries from free version users within 24 hours during business days.<br/><br/>Please note that we are unable to handle technical support requests in the WordPress.org community forums. <br/><br/><a href="javascript:void(0);" id="dismiss_manage_top"><u>dismiss</u></a>', 'pmxi_plugin')
|
14 |
+
) ?>
|
15 |
+
</p></div>
|
16 |
+
<?php
|
17 |
+
}
|
18 |
+
?>
|
19 |
+
|
20 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
21 |
+
<?php $this->error() ?>
|
22 |
+
<?php endif ?>
|
23 |
+
|
24 |
+
<form method="get">
|
25 |
+
<input type="hidden" name="page" value="<?php echo esc_attr($this->input->get('page')) ?>" />
|
26 |
+
<p class="search-box">
|
27 |
+
<label for="search-input" class="screen-reader-text"><?php _e('Search Imports', 'pmxi_plugin') ?>:</label>
|
28 |
+
<input id="search-input" type="text" name="s" value="<?php echo esc_attr($s) ?>" />
|
29 |
+
<input type="submit" class="button" value="<?php _e('Search Imports', 'pmxi_plugin') ?>">
|
30 |
+
</p>
|
31 |
+
</form>
|
32 |
+
|
33 |
+
<?php
|
34 |
+
// define the columns to display, the syntax is 'internal name' => 'display name'
|
35 |
+
$columns = array(
|
36 |
+
'id' => __('ID', 'pmxi_plugin'),
|
37 |
+
'name' => __('File', 'pmxi_plugin'),
|
38 |
+
'xpath' => __('XPath', 'pmxi_plugin'),
|
39 |
+
'post_count' => __('Records', 'pmxi_plugin'),
|
40 |
+
'first_import' => __('First Import', 'pmxi_plugin'),
|
41 |
+
'registered_on' => __('Last Import', 'pmxi_plugin'),
|
42 |
+
/*'scheduled' => __('Reimport Schedule', 'pmxi_plugin'),
|
43 |
+
'next_import' => __('Next Import', 'pmxi_plugin'),*/
|
44 |
+
);
|
45 |
+
?>
|
46 |
+
<form method="post" id="import-list" action="<?php echo remove_query_arg('pmxi_nt') ?>">
|
47 |
+
<input type="hidden" name="action" value="bulk" />
|
48 |
+
<?php wp_nonce_field('bulk-imports', '_wpnonce_bulk-imports') ?>
|
49 |
+
|
50 |
+
<div class="tablenav">
|
51 |
+
<div class="alignleft actions">
|
52 |
+
<select name="bulk-action">
|
53 |
+
<option value="" selected="selected"><?php _e('Bulk Actions', 'pmxi_plugin') ?></option>
|
54 |
+
<option value="delete"><?php _e('Delete', 'pmxi_plugin') ?></option>
|
55 |
+
</select>
|
56 |
+
<input type="submit" value="<?php esc_attr_e('Apply', 'pmxi_plugin') ?>" name="doaction" id="doaction" class="button-secondary action" />
|
57 |
+
</div>
|
58 |
+
|
59 |
+
<?php if ($page_links): ?>
|
60 |
+
<div class="tablenav-pages">
|
61 |
+
<?php echo $page_links_html = sprintf(
|
62 |
+
'<span class="displaying-num">' . __('Displaying %s–%s of %s', 'pmxi_plugin') . '</span>%s',
|
63 |
+
number_format_i18n(($pagenum - 1) * $perPage + 1),
|
64 |
+
number_format_i18n(min($pagenum * $perPage, $list->total())),
|
65 |
+
number_format_i18n($list->total()),
|
66 |
+
$page_links
|
67 |
+
) ?>
|
68 |
+
</div>
|
69 |
+
<?php endif ?>
|
70 |
+
</div>
|
71 |
+
<div class="clear"></div>
|
72 |
+
|
73 |
+
<table class="widefat pmxi-admin-imports">
|
74 |
+
<thead>
|
75 |
+
<tr>
|
76 |
+
<th class="manage-column column-cb check-column" scope="col">
|
77 |
+
<input type="checkbox" />
|
78 |
+
</th>
|
79 |
+
<?php
|
80 |
+
$col_html = '';
|
81 |
+
foreach ($columns as $column_id => $column_display_name) {
|
82 |
+
$column_link = "<a href='";
|
83 |
+
$order2 = 'ASC';
|
84 |
+
if ($order_by == $column_id)
|
85 |
+
$order2 = ($order == 'DESC') ? 'ASC' : 'DESC';
|
86 |
+
|
87 |
+
$column_link .= esc_url(add_query_arg(array('order' => $order2, 'order_by' => $column_id), $this->baseUrl));
|
88 |
+
$column_link .= "'>{$column_display_name}</a>";
|
89 |
+
$col_html .= '<th scope="col" class="column-' . $column_id . ' ' . ($order_by == $column_id ? $order : '') . '">' . $column_link . '</th>';
|
90 |
+
}
|
91 |
+
echo $col_html;
|
92 |
+
?>
|
93 |
+
</tr>
|
94 |
+
</thead>
|
95 |
+
<tfoot>
|
96 |
+
<tr>
|
97 |
+
<th class="manage-column column-cb check-column" scope="col">
|
98 |
+
<input type="checkbox" />
|
99 |
+
</th>
|
100 |
+
<?php echo $col_html; ?>
|
101 |
+
</tr>
|
102 |
+
</tfoot>
|
103 |
+
<tbody id="the-pmxi-admin-import-list" class="list:pmxi-admin-imports">
|
104 |
+
<?php if ($list->isEmpty()): ?>
|
105 |
+
<tr>
|
106 |
+
<td colspan="<?php echo count($columns) + 1 ?>"><?php _e('No previous imports found.', 'pmxi_plugin') ?></td>
|
107 |
+
</tr>
|
108 |
+
<?php else: ?>
|
109 |
+
<?php $class = ''; foreach ($list as $item): ?>
|
110 |
+
<?php $class = ('alternate' == $class) ? '' : 'alternate'; ?>
|
111 |
+
<tr class="<?php echo $class; ?>" valign="middle">
|
112 |
+
<th scope="row" class="check-column">
|
113 |
+
<input type="checkbox" id="item_<?php echo $item['id'] ?>" name="items[]" value="<?php echo esc_attr($item['id']) ?>" />
|
114 |
+
</th>
|
115 |
+
<?php foreach ($columns as $column_id => $column_display_name): ?>
|
116 |
+
<?php
|
117 |
+
switch ($column_id):
|
118 |
+
case 'id':
|
119 |
+
?>
|
120 |
+
<th valign="top" scope="row">
|
121 |
+
<?php echo $item['id'] ?>
|
122 |
+
</th>
|
123 |
+
<?php
|
124 |
+
break;
|
125 |
+
case 'first_import':
|
126 |
+
?>
|
127 |
+
<td>
|
128 |
+
<?php if ('0000-00-00 00:00:00' == $item['first_import']): ?>
|
129 |
+
<em>never</em>
|
130 |
+
<?php else: ?>
|
131 |
+
<?php echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $item['first_import']) ?>
|
132 |
+
<?php endif ?>
|
133 |
+
</td>
|
134 |
+
<?php
|
135 |
+
break;
|
136 |
+
case 'registered_on':
|
137 |
+
?>
|
138 |
+
<td>
|
139 |
+
<?php if ('0000-00-00 00:00:00' == $item['registered_on']): ?>
|
140 |
+
<em>never</em>
|
141 |
+
<?php else: ?>
|
142 |
+
<?php echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $item['registered_on']) ?>
|
143 |
+
<?php endif ?>
|
144 |
+
</td>
|
145 |
+
<?php
|
146 |
+
break;
|
147 |
+
case 'next_import':
|
148 |
+
?>
|
149 |
+
<td>
|
150 |
+
<?php if ('0000-00-00 00:00:00' == $item['registered_on'] or empty($item['scheduled'])): ?>
|
151 |
+
<em>never</em>
|
152 |
+
<?php
|
153 |
+
else:
|
154 |
+
$task = new _PMXI_Import_Record_Cron_Parser($item['scheduled']);
|
155 |
+
$task_date = $task->getNextRunDate();
|
156 |
+
echo mysql2date(__('Y/m/d g:i a', 'pmxi_plugin'), $task_date->format('Y-m-d H:i:s'));
|
157 |
+
endif;
|
158 |
+
?>
|
159 |
+
</td>
|
160 |
+
<?php
|
161 |
+
break;
|
162 |
+
case 'name':
|
163 |
+
?>
|
164 |
+
<td>
|
165 |
+
<strong><?php echo (!empty($item['friendly_name'])) ? $item['friendly_name'] : $item['name']; ?></strong> <br>
|
166 |
+
<?php if ($item['path']): ?>
|
167 |
+
<em><?php echo str_replace("\\", '/', preg_replace('%^(\w+://[^:]+:)[^@]+@%', '$1*****@', $item['path'])); ?></em>
|
168 |
+
<?php endif ?>
|
169 |
+
<div class="row-actions">
|
170 |
+
|
171 |
+
<span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'edit'), $this->baseUrl)) ?>"><?php _e('Edit Template', 'pmxi_plugin') ?></a></span> |
|
172 |
+
<span class="edit"><a class="edit" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'options'), $this->baseUrl)) ?>"><?php _e('Edit Options', 'pmxi_plugin') ?></a></span> |
|
173 |
+
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update'), $this->baseUrl)) ?>"><?php _e('Update', 'pmxi_plugin') ?></a></span> |
|
174 |
+
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('page' => 'pmxi-admin-import', 'id' => $item['id']), admin_url('admin.php'))) ?>"><?php _e('Use New File', 'pmxi_plugin') ?></a></span> |
|
175 |
+
<span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'log'), $this->baseUrl)) ?>"><?php _e('Download Log', 'pmxi_plugin') ?></a></span> |
|
176 |
+
<span class="delete"><a class="delete" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'delete'), $this->baseUrl)) ?>"><?php _e('Delete', 'pmxi_plugin') ?></a></span>
|
177 |
+
<?php if ( "Yes" == $item['large_import'] and $item['imported'] != $item['count']):?>
|
178 |
+
| <span class="update"><a class="update" href="<?php echo esc_url(add_query_arg(array('id' => $item['id'], 'action' => 'update', 'type' => 'continue'), $this->baseUrl)) ?>"><?php _e('Continue import', 'pmxi_plugin') ?></a></span>
|
179 |
+
<?php endif; ?>
|
180 |
+
</div>
|
181 |
+
</td>
|
182 |
+
<?php
|
183 |
+
break;
|
184 |
+
case 'xpath':
|
185 |
+
?>
|
186 |
+
<td>
|
187 |
+
<?php echo $item['xpath'];?>
|
188 |
+
</td>
|
189 |
+
<?php
|
190 |
+
break;
|
191 |
+
case 'post_count':
|
192 |
+
?>
|
193 |
+
<td>
|
194 |
+
<strong><?php echo $item['post_count'] ?></strong>
|
195 |
+
</td>
|
196 |
+
<?php
|
197 |
+
break;
|
198 |
+
default:
|
199 |
+
?>
|
200 |
+
<td>
|
201 |
+
<?php echo $item[$column_id] ?>
|
202 |
+
</td>
|
203 |
+
<?php
|
204 |
+
break;
|
205 |
+
endswitch;
|
206 |
+
?>
|
207 |
+
<?php endforeach; ?>
|
208 |
+
</tr>
|
209 |
+
<?php endforeach; ?>
|
210 |
+
<?php endif ?>
|
211 |
+
</tbody>
|
212 |
+
</table>
|
213 |
+
|
214 |
+
<div class="tablenav">
|
215 |
+
<?php if ($page_links): ?><div class="tablenav-pages"><?php echo $page_links_html ?></div><?php endif ?>
|
216 |
+
|
217 |
+
<div class="alignleft actions">
|
218 |
+
<select name="bulk-action2">
|
219 |
+
<option value="" selected="selected"><?php _e('Bulk Actions', 'pmxi_plugin') ?></option>
|
220 |
+
<?php if ('trash' != $type): ?>
|
221 |
+
<option value="delete"><?php _e('Delete', 'pmxi_plugin') ?></option>
|
222 |
+
<?php else: ?>
|
223 |
+
<option value="restore"><?php _e('Restore', 'pmxi_plugin')?></option>
|
224 |
+
<option value="delete"><?php _e('Delete Permanently', 'pmxi_plugin')?></option>
|
225 |
+
<?php endif ?>
|
226 |
+
</select>
|
227 |
+
<input type="submit" value="<?php esc_attr_e('Apply', 'pmxi_plugin') ?>" name="doaction2" id="doaction2" class="button-secondary action" />
|
228 |
+
</div>
|
229 |
+
</div>
|
230 |
+
<div class="clear"></div>
|
231 |
+
<?php
|
232 |
+
// notify user
|
233 |
+
if (!PMXI_Plugin::getInstance()->getOption('dismiss_manage_bottom')) {
|
234 |
+
?>
|
235 |
+
<div class="updated_bottom"><p>
|
236 |
+
<?php printf(
|
237 |
+
__('<a href="http://wordpress.org/extend/plugins/wp-all-import" target="_blank">If you like WPAllImport, please rate us five stars on WordPress.org!</a> <a href="http://wordpress.org/extend/plugins/wp-all-import" class="pmxi_stars" target="_blank"></a> <br/><br/><a href="javascript:void(0);" id="dismiss_manage_bottom">dismiss</a>', 'pmxi_plugin')
|
238 |
+
) ?>
|
239 |
+
</p></div>
|
240 |
+
<?php
|
241 |
+
}
|
242 |
+
?>
|
243 |
+
|
244 |
+
|
245 |
+
|
246 |
+
<p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=manage&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Find out more about the professional edition of WP All Import.</a></p>
|
247 |
+
|
248 |
+
|
249 |
</form>
|
views/admin/settings/index.php
CHANGED
@@ -1,67 +1,72 @@
|
|
1 |
-
<form class="settings" method="post" action="<?php echo $this->baseUrl ?>">
|
2 |
-
|
3 |
-
<h2><?php _e('WP All Import Settings', 'pmxi_plugin') ?></h2>
|
4 |
-
<hr />
|
5 |
-
<?php if ($this->errors->get_error_codes()): ?>
|
6 |
-
<?php $this->error() ?>
|
7 |
-
<?php endif ?>
|
8 |
-
|
9 |
-
<h3><?php _e('Saved Templates', 'pmxi_plugin') ?></h3>
|
10 |
-
<?php $templates = new PMXI_Template_List(); $templates->getBy()->convertRecords() ?>
|
11 |
-
<?php if ($templates->total()): ?>
|
12 |
-
<table>
|
13 |
-
<?php foreach ($templates as $t): ?>
|
14 |
-
<tr>
|
15 |
-
<td><input id="template-<?php echo $t->id ?>" type="checkbox" name="templates[]" value="<?php echo $t->id ?>" /></td>
|
16 |
-
<td><label for="template-<?php echo $t->id ?>"><?php echo $t->name ?></label></td>
|
17 |
-
</tr>
|
18 |
-
<?php endforeach ?>
|
19 |
-
</table>
|
20 |
-
<p class="submit-buttons">
|
21 |
-
<?php wp_nonce_field('delete-templates', '_wpnonce_delete-templates') ?>
|
22 |
-
<input type="hidden" name="is_templates_submitted" value="1" />
|
23 |
-
<input type="submit" class="button-primary" value="<?php _e('Delete Selected', 'pmxi_plugin') ?>" />
|
24 |
-
</p>
|
25 |
-
<?php else: ?>
|
26 |
-
<em><?php _e('There are no templates saved', 'pmxi_plugin') ?></em>
|
27 |
-
<?php endif ?>
|
28 |
-
</form>
|
29 |
-
<br />
|
30 |
-
|
31 |
-
<form name="settings" method="post" action="<?php echo $this->baseUrl ?>">
|
32 |
-
<h3><?php _e('History', 'pmxi_plugin') ?></h3>
|
33 |
-
<div><?php printf(__('Store maximum of %s of the most recent files imported. 0 = unlimited', 'pmxi_plugin'), '<input class="small-text" type="text" name="history_file_count" value="' . esc_attr($post['history_file_count']) . '" />') ?></div>
|
34 |
-
<div><?php printf(__('Store imported file history for a maximum of %s of days. 0 = unlimited', 'pmxi_plugin'), '<input class="small-text" type="text" name="history_file_age" value="' . esc_attr($post['history_file_age']) . '" />') ?></div>
|
35 |
-
<h3><?php _e('Your server setting', 'pmxi_plugin') ?></h3>
|
36 |
-
<div><?php printf(__('upload_max_filesize %s', 'pmxi_plugin'), ini_get('upload_max_filesize')) ?></div>
|
37 |
-
<div><?php printf(__('post_max_size %s', 'pmxi_plugin'), ini_get('post_max_size')) ?></div>
|
38 |
-
<div><?php printf(__('max_execution_time %s', 'pmxi_plugin'), ini_get('max_execution_time')) ?></div>
|
39 |
-
<div><?php printf(__('max_input_time %s', 'pmxi_plugin'), ini_get('max_input_time')) ?></div>
|
40 |
-
|
41 |
-
<h3><?php _e('Recurring & Scheduled Imports', 'pmxi_plugin') ?></h3>
|
42 |
-
|
43 |
-
|
44 |
-
<hr />
|
45 |
-
|
46 |
-
<h3>Please upgrade to the professional edition of WP All Import to perform recurring and scheduled imports.</h3>
|
47 |
-
|
48 |
-
<p>WP All Import can periodically check your XML/CSV for updates on the schedule you define, and overwrite your existing import with new data. New posts will be made for new entries in the XML/CSV. Entries that haven't changed will be left alone. WP All Import can even delete "expired" posts (if their data is no longer in the updated XML/CSV).</p>
|
49 |
-
|
50 |
-
<p>You can configure recurring imports from within WP All Import, or by setting up a cron job in your web hosting control panel.</p>
|
51 |
-
|
52 |
-
<p>WP All Import can perform recurring imports with a file online at an http:// URL, or a file on an FTP server.</p>
|
53 |
-
|
54 |
-
<p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=recurring&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
|
55 |
-
|
56 |
-
<hr />
|
57 |
-
|
58 |
-
|
59 |
-
<h3><?php _e('Import Settings', 'pmxi_plugin') ?></h3>
|
60 |
-
<div><?php printf(__('Chunk maximum size %s (Kb)', 'pmxi_plugin'), '<input type="text" name="chunk_size" value="' . esc_attr($post['chunk_size']) . '"/>') ?></div>
|
61 |
-
<p
|
62 |
-
|
63 |
-
<input type="
|
64 |
-
<
|
65 |
-
</p>
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
67 |
</form>
|
1 |
+
<form class="settings" method="post" action="<?php echo $this->baseUrl ?>">
|
2 |
+
|
3 |
+
<h2><?php _e('WP All Import Settings', 'pmxi_plugin') ?></h2>
|
4 |
+
<hr />
|
5 |
+
<?php if ($this->errors->get_error_codes()): ?>
|
6 |
+
<?php $this->error() ?>
|
7 |
+
<?php endif ?>
|
8 |
+
|
9 |
+
<h3><?php _e('Saved Templates', 'pmxi_plugin') ?></h3>
|
10 |
+
<?php $templates = new PMXI_Template_List(); $templates->getBy()->convertRecords() ?>
|
11 |
+
<?php if ($templates->total()): ?>
|
12 |
+
<table>
|
13 |
+
<?php foreach ($templates as $t): ?>
|
14 |
+
<tr>
|
15 |
+
<td><input id="template-<?php echo $t->id ?>" type="checkbox" name="templates[]" value="<?php echo $t->id ?>" /></td>
|
16 |
+
<td><label for="template-<?php echo $t->id ?>"><?php echo $t->name ?></label></td>
|
17 |
+
</tr>
|
18 |
+
<?php endforeach ?>
|
19 |
+
</table>
|
20 |
+
<p class="submit-buttons">
|
21 |
+
<?php wp_nonce_field('delete-templates', '_wpnonce_delete-templates') ?>
|
22 |
+
<input type="hidden" name="is_templates_submitted" value="1" />
|
23 |
+
<input type="submit" class="button-primary" value="<?php _e('Delete Selected', 'pmxi_plugin') ?>" />
|
24 |
+
</p>
|
25 |
+
<?php else: ?>
|
26 |
+
<em><?php _e('There are no templates saved', 'pmxi_plugin') ?></em>
|
27 |
+
<?php endif ?>
|
28 |
+
</form>
|
29 |
+
<br />
|
30 |
+
|
31 |
+
<form name="settings" method="post" action="<?php echo $this->baseUrl ?>">
|
32 |
+
<h3><?php _e('History', 'pmxi_plugin') ?></h3>
|
33 |
+
<div><?php printf(__('Store maximum of %s of the most recent files imported. 0 = unlimited', 'pmxi_plugin'), '<input class="small-text" type="text" name="history_file_count" value="' . esc_attr($post['history_file_count']) . '" />') ?></div>
|
34 |
+
<div><?php printf(__('Store imported file history for a maximum of %s of days. 0 = unlimited', 'pmxi_plugin'), '<input class="small-text" type="text" name="history_file_age" value="' . esc_attr($post['history_file_age']) . '" />') ?></div>
|
35 |
+
<h3><?php _e('Your server setting', 'pmxi_plugin') ?></h3>
|
36 |
+
<div><?php printf(__('upload_max_filesize %s', 'pmxi_plugin'), ini_get('upload_max_filesize')) ?></div>
|
37 |
+
<div><?php printf(__('post_max_size %s', 'pmxi_plugin'), ini_get('post_max_size')) ?></div>
|
38 |
+
<div><?php printf(__('max_execution_time %s', 'pmxi_plugin'), ini_get('max_execution_time')) ?></div>
|
39 |
+
<div><?php printf(__('max_input_time %s', 'pmxi_plugin'), ini_get('max_input_time')) ?></div>
|
40 |
+
|
41 |
+
<h3><?php _e('Recurring & Scheduled Imports', 'pmxi_plugin') ?></h3>
|
42 |
+
|
43 |
+
|
44 |
+
<hr />
|
45 |
+
|
46 |
+
<h3>Please upgrade to the professional edition of WP All Import to perform recurring and scheduled imports.</h3>
|
47 |
+
|
48 |
+
<p>WP All Import can periodically check your XML/CSV for updates on the schedule you define, and overwrite your existing import with new data. New posts will be made for new entries in the XML/CSV. Entries that haven't changed will be left alone. WP All Import can even delete "expired" posts (if their data is no longer in the updated XML/CSV).</p>
|
49 |
+
|
50 |
+
<p>You can configure recurring imports from within WP All Import, or by setting up a cron job in your web hosting control panel.</p>
|
51 |
+
|
52 |
+
<p>WP All Import can perform recurring imports with a file online at an http:// URL, or a file on an FTP server.</p>
|
53 |
+
|
54 |
+
<p style='font-size: 1.3em; font-weight: bold;'><a href="http://www.wpallimport.com/upgrade-to-pro?utm_source=wordpress.org&utm_medium=recurring&utm_campaign=free+plugin" target="_blank" class="upgrade_link">Upgrade Now</a></p>
|
55 |
+
|
56 |
+
<hr />
|
57 |
+
|
58 |
+
|
59 |
+
<h3><?php _e('Import Settings', 'pmxi_plugin') ?></h3>
|
60 |
+
<div><?php printf(__('Chunk maximum size %s (Kb)', 'pmxi_plugin'), '<input type="text" name="chunk_size" value="' . esc_attr($post['chunk_size']) . '"/>') ?></div>
|
61 |
+
<p>
|
62 |
+
<input type="hidden" name="pingbacks" value="0"/>
|
63 |
+
<?php printf(__('Enable WP_IMPORTING %s', 'pmxi_plugin'), '<input type="checkbox" name="pingbacks" value="1" style="position:relative; top:-2px;" '. (($post['pingbacks']) ? 'checked="checked"' : '') .'/>') ?>
|
64 |
+
<a href="#help" class="help" title="<?php _e('Avoid triggering pingback.', 'pmxi_plugin') ?>">?</a>
|
65 |
+
</p>
|
66 |
+
<p class="submit-buttons">
|
67 |
+
<?php wp_nonce_field('edit-settings', '_wpnonce_edit-settings') ?>
|
68 |
+
<input type="hidden" name="is_settings_submitted" value="1" />
|
69 |
+
<input type="submit" class="button-primary" value="Save Settings" />
|
70 |
+
</p>
|
71 |
+
|
72 |
</form>
|