Version Description
- Category list delimiter bug fix
Download this release
Release Info
Developer | soflyy |
Plugin | Import any XML or CSV File to WordPress |
Version | 2.14 |
Comparing to | |
See all releases |
Code changes from version 2.13 to 2.14
- actions/admin_menu.php +5 -5
- config/options.php +2 -1
- controllers/admin/import.php +211 -116
- controllers/admin/manage.php +92 -2
- controllers/admin/settings.php +2 -1
- controllers/controller/admin.php +1 -0
- libraries/XmlImportConfig.php +2 -2
- libraries/XmlImportCsvParse.php +5 -3
- libraries/XmlImportParser.php +1 -1
- libraries/XmlImportTemplateCodeGenerator.php +52 -8
- libraries/XmlImportTemplateParser.php +64 -9
- libraries/XmlImportTemplateScanner.php +5 -4
- libraries/XmlImportToken.php +5 -0
- libraries/ast/XmlImportAstSpintax.php +76 -0
- models/import/record.php +241 -64
- plugin.php +1 -1
- readme.txt +5 -2
- schema.php +2 -1
- screenshot-1.png +0 -0
- screenshot-2.png +0 -0
- screenshot-3.png +0 -0
- screenshot-4.png +0 -0
- static/css/admin.css +36 -1
- static/img/drag.png +0 -0
- static/img/ico-add-new.png +0 -0
- static/img/ico-remove.png +0 -0
- static/js/admin.js +46 -67
- static/js/jquery/jquery.mjs.nestedSortable.js +426 -0
- views/admin/import/index.php +2 -1
- views/admin/import/options.php +116 -20
- views/admin/import/process.php +26 -1
- views/admin/import/tag.php +1 -1
- views/admin/manage/update.php +0 -3
- views/admin/settings/index.php +1 -0
actions/admin_menu.php
CHANGED
@@ -5,18 +5,18 @@
|
|
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', __('WP All Import', 'pmxi_plugin'), __('About', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-home', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
18 |
// add_submenu_page('pmxi-admin-home', __('Help', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Help', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-help', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
19 |
-
|
20 |
-
}
|
21 |
}
|
22 |
|
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', __('WP All Import', 'pmxi_plugin'), __('About', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-home', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
18 |
// add_submenu_page('pmxi-admin-home', __('Help', 'pmxi_plugin') . ' ‹ ' . __('WP All Import', 'pmxi_plugin'), __('Help', 'pmxi_plugin'), 'manage_options', 'pmxi-admin-help', array(PMXI_Plugin::getInstance(), 'adminDispatcher'));
|
19 |
+
|
20 |
+
}
|
21 |
}
|
22 |
|
config/options.php
CHANGED
@@ -13,5 +13,6 @@ $config = array(
|
|
13 |
"max_input_time" => -1,
|
14 |
"max_execution_time" => -1,
|
15 |
"dismiss" => 0,
|
16 |
-
"html_entities" => 0
|
|
|
17 |
);
|
13 |
"max_input_time" => -1,
|
14 |
"max_execution_time" => -1,
|
15 |
"dismiss" => 0,
|
16 |
+
"html_entities" => 0,
|
17 |
+
"utf8_decode" => 0
|
18 |
);
|
controllers/admin/import.php
CHANGED
@@ -7,8 +7,7 @@
|
|
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 |
-
protected $csv_mimes = array('text/comma-separated-values','text/csv','application/csv','application/excel','application/vnd.ms-excel','application/vnd.msexcel','text/anytext');
|
12 |
|
13 |
protected function init() {
|
14 |
parent::init();
|
@@ -122,20 +121,89 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
122 |
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
123 |
} elseif (empty($_FILES['upload']['size'])) {
|
124 |
$this->errors->add('form-validation', __('Uploaded file is empty', 'pmxi_plugin'));
|
125 |
-
} elseif ( ! preg_match('%\W(xml|gzip|csv)$%i', trim($_FILES['upload']['name'])) and
|
126 |
-
$this->errors->add('form-validation', __('Uploaded file must be XML, CSV or GZIP', 'pmxi_plugin'));
|
127 |
-
} elseif (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
$uploads = wp_upload_dir();
|
129 |
if($uploads['error']){
|
130 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
131 |
}
|
132 |
// copy file in temporary folder
|
133 |
-
$fdata = file_get_contents($_FILES['upload']['tmp_name']);
|
134 |
-
$fdata = utf8_encode($fdata);
|
135 |
file_put_contents($uploads['path'] . '/' . trim(basename($_FILES['upload']['name'])), $fdata);
|
136 |
chmod($uploads['path'] . '/'. trim(basename($_FILES['upload']['name'])), "0777");
|
137 |
// end file convertion
|
138 |
-
$xml =
|
139 |
if( is_array($xml) && isset($xml['error'])){
|
140 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
141 |
}
|
@@ -181,13 +249,89 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
181 |
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
182 |
} elseif ( ! preg_match('%^https?://%i', $post['url'])) {
|
183 |
$this->errors->add('form-validation', __('Specified URL has wrong format'), 'pmxi_plugin');
|
184 |
-
} elseif (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
185 |
$uploads = wp_upload_dir();
|
186 |
-
$fdata = file_get_contents($post['url']);
|
187 |
-
$fdata = utf8_encode($fdata);
|
188 |
$tmpname = md5(time()).'.csv';
|
189 |
file_put_contents($uploads['path'] .'/'. $tmpname, $fdata);
|
190 |
-
$xml =
|
191 |
if( is_array($xml) && isset($xml['error'])){
|
192 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
193 |
}
|
@@ -279,11 +423,10 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
279 |
$url = $uploads['url'] . basename($local_file);
|
280 |
// convert file to utf8
|
281 |
chmod($uploads['path'] . basename($local_file), '0755');
|
282 |
-
$fdata = file_get_contents($url);
|
283 |
-
$fdata = utf8_encode($fdata);
|
284 |
file_put_contents($uploads['path'] . basename($local_file), $fdata);
|
285 |
// end file convertion
|
286 |
-
$xml =
|
287 |
if( is_array($xml) && isset($xml['error'])){
|
288 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
289 |
}
|
@@ -344,11 +487,10 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
344 |
$url = $wp_uploads['url'] . basename($post['file']);
|
345 |
// convert file to utf8
|
346 |
chmod($wp_uploads['path'] . basename($post['file']), '0755');
|
347 |
-
$fdata = file_get_contents($url);
|
348 |
-
$fdata = utf8_encode($fdata);
|
349 |
file_put_contents($wp_uploads['path'] . basename($post['file']), $fdata);
|
350 |
// end file convertion
|
351 |
-
$xml =
|
352 |
if( is_array($xml) && isset($xml['error'])){
|
353 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
354 |
}
|
@@ -408,12 +550,16 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
408 |
if ( ! $reimport_id or $file->getById($reimport_id)->isEmpty()) {
|
409 |
$xml = FALSE;
|
410 |
} else {
|
411 |
-
$xml = $file->
|
|
|
|
|
|
|
412 |
$source = array(
|
413 |
'name' => $file->name,
|
414 |
'type' => 'reimport',
|
415 |
'path' => $file->path,
|
416 |
);
|
|
|
417 |
}
|
418 |
} else {
|
419 |
if (in_array($this->input->post('type'), array('ftp', 'file'))) { // file may be specified by pattern
|
@@ -424,12 +570,19 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
424 |
$filePath = FALSE;
|
425 |
}
|
426 |
}
|
427 |
-
|
428 |
ob_start();
|
429 |
$filePath && @readgzfile($filePath);
|
430 |
|
431 |
$xml = ob_get_clean();
|
432 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
433 |
}
|
434 |
|
435 |
if (PMXI_Import_Record::validateXml($xml, $this->errors)) {
|
@@ -808,7 +961,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
808 |
$this->errors->add('form-validation', __('Order must be an integer number', 'pmxi_plugin'));
|
809 |
}
|
810 |
if ('post' == $post['type']) {
|
811 |
-
'' == $post['categories'] or $this->_validate_template($post['categories'], __('Categories', 'pmxi_plugin'))
|
812 |
'' == $post['tags'] or $this->_validate_template($post['tags'], __('Tags', 'pmxi_plugin'));
|
813 |
}
|
814 |
if ('specific' == $post['date_type']) {
|
@@ -816,10 +969,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
816 |
} else {
|
817 |
'' == $post['date_start'] or $this->_validate_template($post['date_start'], __('Start Date', 'pmxi_plugin'));
|
818 |
'' == $post['date_end'] or $this->_validate_template($post['date_end'], __('Start Date', 'pmxi_plugin'));
|
819 |
-
}
|
820 |
-
if ('' == $post['categories_delim']) {
|
821 |
-
$this->errors->add('form-validation', __('Category list delimiter cannot be empty', 'pmxi_plugin'));
|
822 |
-
}
|
823 |
if ('' == $post['tags_delim']) {
|
824 |
$this->errors->add('form-validation', __('Tag list delimiter must cannot be empty', 'pmxi_plugin'));
|
825 |
}
|
@@ -832,7 +982,10 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
832 |
if ( ! preg_match('%^([1-9]\d*)( *- *([1-9]\d*))?$%', $chank, $mtch)) {
|
833 |
$this->errors->add('form-validation', __('Wrong format of `Import only specified records` value', 'pmxi_plugin'));
|
834 |
break;
|
835 |
-
}
|
|
|
|
|
|
|
836 |
}
|
837 |
}
|
838 |
}
|
@@ -868,7 +1021,7 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
868 |
}
|
869 |
|
870 |
if ( ! $this->input->post('save_only')) {
|
871 |
-
$this->
|
872 |
} else {
|
873 |
$import = $this->data['update_previous'];
|
874 |
$is_update = ! $import->isEmpty();
|
@@ -895,6 +1048,13 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
895 |
}
|
896 |
} else {
|
897 |
$this->data['import']->set('options', $post)->set('scheduled', $scheduled['is_scheduled'] ? $scheduled['scheduled_period'] : '')->save();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
898 |
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();
|
899 |
}
|
900 |
}
|
@@ -904,65 +1064,40 @@ class PMXI_Admin_Import extends PMXI_Controller_Admin {
|
|
904 |
|
905 |
$this->render();
|
906 |
}
|
907 |
-
|
908 |
/**
|
909 |
* Import processing step (status console)
|
910 |
*/
|
911 |
public function process()
|
912 |
-
{
|
913 |
-
|
|
|
|
|
|
|
914 |
|
915 |
// store import info in database
|
916 |
$import = $this->data['update_previous'];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
917 |
|
918 |
-
if ($_SESSION['pmxi_import']['options']['is_first_chank'] or !$_SESSION['pmxi_import']['options']['is_update_previous'])
|
919 |
-
{
|
920 |
-
$_SESSION['pmxi_import']['step'] = 0;
|
921 |
-
$import->set(
|
922 |
-
$_SESSION['pmxi_import']['source']
|
923 |
-
+ array(
|
924 |
-
'xpath' => $_SESSION['pmxi_import']['xpath'],
|
925 |
-
'template' => $_SESSION['pmxi_import']['template'],
|
926 |
-
'options' => $_SESSION['pmxi_import']['options'],
|
927 |
-
'scheduled' => $_SESSION['pmxi_import']['scheduled']
|
928 |
-
)
|
929 |
-
)->save();
|
930 |
-
|
931 |
-
$history_file = new PMXI_File_Record();
|
932 |
-
$history_file->set(array(
|
933 |
-
'name' => $import->name,
|
934 |
-
'import_id' => $import->id,
|
935 |
-
'path' => $import->path,
|
936 |
-
'contents' => $_SESSION['pmxi_import']['xml'],
|
937 |
-
'registered_on' => date('Y-m-d H:i:s'),
|
938 |
-
))->save();
|
939 |
-
|
940 |
-
$_SESSION['pmxi_import']['import_start'] = date('H:i:s');
|
941 |
-
}
|
942 |
-
else
|
943 |
-
{
|
944 |
-
$_SESSION['pmxi_import']['step']++;
|
945 |
-
$import = new PMXI_Import_Record();
|
946 |
-
$import->getById($_SESSION['pmxi_import']['options']['is_update_previous']);
|
947 |
-
}
|
948 |
-
|
949 |
$logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; flush();');
|
|
|
950 |
if (in_array($import->type, array('ftp', 'file'))) { // process files by patten
|
951 |
$import->execute($logger);
|
952 |
} else { // directly process XML
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
if (count($xml->xpath($_SESSION['pmxi_import']['xpath'])))
|
959 |
-
{
|
960 |
-
ob_start();
|
961 |
-
$import->process($xml->asXML(), $logger, ((count($rootNodes) < 10) ? true : false));
|
962 |
|
963 |
-
|
964 |
-
{
|
965 |
-
// [indicate in header process is complete]
|
966 |
$msg = addcslashes(__('Complete', 'pmxi_plugin'), "'\n\r");
|
967 |
echo <<<COMPLETE
|
968 |
<script type="text/javascript">
|
@@ -975,29 +1110,8 @@ echo <<<COMPLETE
|
|
975 |
</script>
|
976 |
COMPLETE;
|
977 |
// [/indicate in header process is complete]
|
978 |
-
}
|
979 |
-
$log = ob_get_clean();
|
980 |
-
}
|
981 |
-
unset($xml);
|
982 |
-
|
983 |
-
$xml_chank = new SimpleXMLElement($_SESSION['pmxi_import']['xml']);
|
984 |
-
$this->removeNode($xml_chank, $_SESSION['pmxi_import']['xpath'].'[position() < 10]');
|
985 |
-
|
986 |
-
$_SESSION['pmxi_import']['xml'] = (count($rootNodes) >= 10) ? $xml_chank->asXML() : NULL;
|
987 |
-
unset($xml_chank);
|
988 |
-
}
|
989 |
-
|
990 |
-
if (!empty($_SESSION['pmxi_import']['xml']))
|
991 |
-
exit(json_encode(array('status' => 'process','update_previous' => $import->__get('id'), 'count' => count($rootNodes), 'is_last_chank' => ((count($rootNodes) < 10) ? true : false), 'is_first_chank' => $_SESSION['pmxi_import']['options']['is_first_chank'], 'log' => $log)));
|
992 |
-
else {
|
993 |
-
$start_time = $_SESSION['pmxi_import']['import_start'];
|
994 |
-
$end_time = date('H:i:s');
|
995 |
-
unset($_SESSION['pmxi_import']); // clear session data (prevent from reimporting the same data on page refresh)
|
996 |
-
exit(json_encode(array('status' => 'stop', 'log' => $log, 'start_time' => $start_time, 'end_time' => $end_time, 'import_time' => date('H:i:s', strtotime($end_time) - strtotime($start_time)))));
|
997 |
-
};
|
998 |
-
|
999 |
-
|
1000 |
}
|
|
|
1001 |
/**
|
1002 |
* Remove xml document nodes by xpath expression
|
1003 |
*/
|
@@ -1281,25 +1395,6 @@ COMPLETE;
|
|
1281 |
}
|
1282 |
|
1283 |
return NULL;
|
1284 |
-
}
|
1285 |
-
|
1286 |
-
* Convert csv to xml using yahoo API
|
1287 |
-
*/
|
1288 |
-
protected function csv_to_xml($csv_url){
|
1289 |
-
|
1290 |
-
include_once(PMXI_Plugin::ROOT_DIR.'/libraries/XmlImportCsvParse.php');
|
1291 |
-
|
1292 |
-
$csv = new PMXI_CsvParser($csv_url);
|
1293 |
-
|
1294 |
-
return $csv->toXML();
|
1295 |
-
|
1296 |
-
}
|
1297 |
-
/*
|
1298 |
-
*
|
1299 |
-
* Detect CSV file
|
1300 |
-
*
|
1301 |
-
*/
|
1302 |
-
protected function detect_csv($type){
|
1303 |
-
return in_array($type, $this->csv_mimes);
|
1304 |
-
}
|
1305 |
}
|
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();
|
121 |
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
122 |
} elseif (empty($_FILES['upload']['size'])) {
|
123 |
$this->errors->add('form-validation', __('Uploaded file is empty', 'pmxi_plugin'));
|
124 |
+
} elseif ( ! preg_match('%\W(xml|gzip|zip|csv|gz)$%i', trim($_FILES['upload']['name'])) and !PMXI_Plugin::detect_csv($_FILES['upload']['type'])) {
|
125 |
+
$this->errors->add('form-validation', __('Uploaded file must be XML, CSV or ZIP, GZIP', 'pmxi_plugin'));
|
126 |
+
} elseif (preg_match('%\W(zip)$%i', trim($_FILES['upload']['name']))) {
|
127 |
+
|
128 |
+
$zip = zip_open(trim($_FILES['upload']['tmp_name']));
|
129 |
+
if (is_resource($zip)) {
|
130 |
+
$uploads = wp_upload_dir();
|
131 |
+
if($uploads['error']){
|
132 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
133 |
+
}
|
134 |
+
$filename = '';
|
135 |
+
while ($zip_entry = zip_read($zip)) {
|
136 |
+
$filename = zip_entry_name($zip_entry);
|
137 |
+
$fp = fopen($uploads['path']."/".$filename, "w");
|
138 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
139 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
140 |
+
fwrite($fp,"$buf");
|
141 |
+
zip_entry_close($zip_entry);
|
142 |
+
fclose($fp);
|
143 |
+
}
|
144 |
+
break;
|
145 |
+
}
|
146 |
+
zip_close($zip);
|
147 |
+
|
148 |
+
if (preg_match('%\W(csv)$%i', trim($filename))){
|
149 |
+
|
150 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] . '/' . trim($filename));
|
151 |
+
if( is_array($xml) && isset($xml['error'])){
|
152 |
+
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
153 |
+
}
|
154 |
+
else {
|
155 |
+
|
156 |
+
// delete file in temporary folder
|
157 |
+
unlink( $uploads['path'] .'/'. trim($filename));
|
158 |
+
$fullfilename = $uploads['path']."/".$filename;
|
159 |
+
// Let's make sure the file exists and is writable first.
|
160 |
+
|
161 |
+
if (!$handle = fopen($fullfilename, 'w')) {
|
162 |
+
$this->errors->add('form-validation', __('Cannot open file ' . $fullfilename, 'pmxi_plugin'));
|
163 |
+
}
|
164 |
+
|
165 |
+
// Write $somecontent to our opened file.
|
166 |
+
if (fwrite($handle, $xml) === FALSE) {
|
167 |
+
$this->errors->add('form-validation', __('Cannot write to file ' . $fullfilename, 'pmxi_plugin'));
|
168 |
+
}
|
169 |
+
|
170 |
+
fclose($handle);
|
171 |
+
|
172 |
+
|
173 |
+
$filePath = $fullfilename;
|
174 |
+
$source = array(
|
175 |
+
'name' => $filename,
|
176 |
+
'type' => 'upload',
|
177 |
+
'path' => '',
|
178 |
+
);
|
179 |
+
}
|
180 |
+
|
181 |
+
}
|
182 |
+
else
|
183 |
+
{
|
184 |
+
$filePath = $uploads['path']."/".$filename;
|
185 |
+
$source = array(
|
186 |
+
'name' => $filename,
|
187 |
+
'type' => 'upload',
|
188 |
+
'path' => '',
|
189 |
+
);
|
190 |
+
}
|
191 |
+
|
192 |
+
} else {
|
193 |
+
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive', 'pmxi_plugin'));
|
194 |
+
}
|
195 |
+
|
196 |
+
} elseif ( preg_match('%\W(csv)$%i', trim($_FILES['upload']['name'])) or PMXI_Plugin::detect_csv($_FILES['upload']['type'])) {
|
197 |
$uploads = wp_upload_dir();
|
198 |
if($uploads['error']){
|
199 |
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
200 |
}
|
201 |
// copy file in temporary folder
|
202 |
+
$fdata = file_get_contents($_FILES['upload']['tmp_name']);
|
|
|
203 |
file_put_contents($uploads['path'] . '/' . trim(basename($_FILES['upload']['name'])), $fdata);
|
204 |
chmod($uploads['path'] . '/'. trim(basename($_FILES['upload']['name'])), "0777");
|
205 |
// end file convertion
|
206 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] . '/' . trim(basename($_FILES['upload']['name'])));
|
207 |
if( is_array($xml) && isset($xml['error'])){
|
208 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
209 |
}
|
249 |
$this->errors->add('form-validation', __('XML/CSV file must be specified', 'pmxi_plugin'));
|
250 |
} elseif ( ! preg_match('%^https?://%i', $post['url'])) {
|
251 |
$this->errors->add('form-validation', __('Specified URL has wrong format'), 'pmxi_plugin');
|
252 |
+
} elseif (preg_match('%\W(zip)$%i', trim($post['url']))) {
|
253 |
+
|
254 |
+
$uploads = wp_upload_dir();
|
255 |
+
|
256 |
+
$newfile = $uploads['path']."/".md5(time()).'.zip';
|
257 |
+
|
258 |
+
if (!copy($post['url'], $newfile)) {
|
259 |
+
$this->errors->add('form-validation', __('Failed upload ZIP archive', 'pmxi_plugin'));
|
260 |
+
}
|
261 |
+
|
262 |
+
$zip = zip_open($newfile);
|
263 |
+
if (is_resource($zip)) {
|
264 |
+
$uploads = wp_upload_dir();
|
265 |
+
if($uploads['error']){
|
266 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
267 |
+
}
|
268 |
+
$filename = '';
|
269 |
+
while ($zip_entry = zip_read($zip)) {
|
270 |
+
$filename = zip_entry_name($zip_entry);
|
271 |
+
$fp = fopen($uploads['path']."/".$filename, "w");
|
272 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
273 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
274 |
+
fwrite($fp,"$buf");
|
275 |
+
zip_entry_close($zip_entry);
|
276 |
+
fclose($fp);
|
277 |
+
}
|
278 |
+
break;
|
279 |
+
}
|
280 |
+
zip_close($zip);
|
281 |
+
unlink($newfile);
|
282 |
+
if (preg_match('%\W(csv)$%i', trim($filename))){
|
283 |
+
|
284 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] . '/' . trim($filename));
|
285 |
+
if( is_array($xml) && isset($xml['error'])){
|
286 |
+
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
287 |
+
}
|
288 |
+
else {
|
289 |
+
|
290 |
+
// delete file in temporary folder
|
291 |
+
unlink( $uploads['path'] .'/'. trim($filename));
|
292 |
+
$fullfilename = $uploads['path']."/".$filename;
|
293 |
+
// Let's make sure the file exists and is writable first.
|
294 |
+
|
295 |
+
if (!$handle = fopen($fullfilename, 'w')) {
|
296 |
+
$this->errors->add('form-validation', __('Cannot open file ' . $fullfilename, 'pmxi_plugin'));
|
297 |
+
}
|
298 |
+
|
299 |
+
// Write $somecontent to our opened file.
|
300 |
+
if (fwrite($handle, $xml) === FALSE) {
|
301 |
+
$this->errors->add('form-validation', __('Cannot write to file ' . $fullfilename, 'pmxi_plugin'));
|
302 |
+
}
|
303 |
+
|
304 |
+
fclose($handle);
|
305 |
+
|
306 |
+
|
307 |
+
$filePath = $fullfilename;
|
308 |
+
$source = array(
|
309 |
+
'name' => $filename,
|
310 |
+
'type' => 'url',
|
311 |
+
'path' => $post['url'],
|
312 |
+
);
|
313 |
+
}
|
314 |
+
|
315 |
+
}
|
316 |
+
else
|
317 |
+
{
|
318 |
+
$filePath = $uploads['path']."/".$filename;
|
319 |
+
$source = array(
|
320 |
+
'name' => $filename,
|
321 |
+
'type' => 'url',
|
322 |
+
'path' => $post['url'],
|
323 |
+
);
|
324 |
+
}
|
325 |
+
|
326 |
+
} else {
|
327 |
+
$this->errors->add('form-validation', __('Failed to open uploaded ZIP archive', 'pmxi_plugin'));
|
328 |
+
}
|
329 |
+
} elseif ( preg_match('%\W(csv)$%i', trim($post['url'])) or $contents = get_headers($post['url'],1 ) and PMXI_Plugin::detect_csv($contents['Content-Type'])) {
|
330 |
$uploads = wp_upload_dir();
|
331 |
+
$fdata = file_get_contents($post['url']);
|
|
|
332 |
$tmpname = md5(time()).'.csv';
|
333 |
file_put_contents($uploads['path'] .'/'. $tmpname, $fdata);
|
334 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] .'/'. $tmpname);
|
335 |
if( is_array($xml) && isset($xml['error'])){
|
336 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
337 |
}
|
423 |
$url = $uploads['url'] . basename($local_file);
|
424 |
// convert file to utf8
|
425 |
chmod($uploads['path'] . basename($local_file), '0755');
|
426 |
+
$fdata = file_get_contents($url);
|
|
|
427 |
file_put_contents($uploads['path'] . basename($local_file), $fdata);
|
428 |
// end file convertion
|
429 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] . basename($local_file));
|
430 |
if( is_array($xml) && isset($xml['error'])){
|
431 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
432 |
}
|
487 |
$url = $wp_uploads['url'] . basename($post['file']);
|
488 |
// convert file to utf8
|
489 |
chmod($wp_uploads['path'] . basename($post['file']), '0755');
|
490 |
+
$fdata = file_get_contents($url);
|
|
|
491 |
file_put_contents($wp_uploads['path'] . basename($post['file']), $fdata);
|
492 |
// end file convertion
|
493 |
+
$xml = PMXI_Plugin::csv_to_xml($wp_uploads['path'] . basename($post['file']));
|
494 |
if( is_array($xml) && isset($xml['error'])){
|
495 |
$this->errors->add('form-validation', __($xml['error'], 'pmxi_plugin'));
|
496 |
}
|
550 |
if ( ! $reimport_id or $file->getById($reimport_id)->isEmpty()) {
|
551 |
$xml = FALSE;
|
552 |
} else {
|
553 |
+
$xml = @file_get_contents($file->path);
|
554 |
+
|
555 |
+
if ($contents = get_headers($file->path,1 ) and PMXI_Plugin::detect_csv($contents['Content-Type'])) $xml = PMXI_Plugin::csv_to_xml($file->path);
|
556 |
+
|
557 |
$source = array(
|
558 |
'name' => $file->name,
|
559 |
'type' => 'reimport',
|
560 |
'path' => $file->path,
|
561 |
);
|
562 |
+
|
563 |
}
|
564 |
} else {
|
565 |
if (in_array($this->input->post('type'), array('ftp', 'file'))) { // file may be specified by pattern
|
570 |
$filePath = FALSE;
|
571 |
}
|
572 |
}
|
573 |
+
|
574 |
ob_start();
|
575 |
$filePath && @readgzfile($filePath);
|
576 |
|
577 |
$xml = ob_get_clean();
|
578 |
|
579 |
+
$wp_uploads = wp_upload_dir();
|
580 |
+
$url = $wp_uploads['url'] .'/'. basename($filePath);
|
581 |
+
file_put_contents($wp_uploads['path'] .'/'. basename($filePath), $xml);
|
582 |
+
chmod($wp_uploads['path'] .'/'. basename($filePath), '0755');
|
583 |
+
|
584 |
+
if ($contents = get_headers($url,1 ) and PMXI_Plugin::detect_csv($contents['Content-Type'])) $xml = PMXI_Plugin::csv_to_xml($wp_uploads['path']. basename($filePath));
|
585 |
+
|
586 |
}
|
587 |
|
588 |
if (PMXI_Import_Record::validateXml($xml, $this->errors)) {
|
961 |
$this->errors->add('form-validation', __('Order must be an integer number', 'pmxi_plugin'));
|
962 |
}
|
963 |
if ('post' == $post['type']) {
|
964 |
+
/*'' == $post['categories'] or $this->_validate_template($post['categories'], __('Categories', 'pmxi_plugin'));*/
|
965 |
'' == $post['tags'] or $this->_validate_template($post['tags'], __('Tags', 'pmxi_plugin'));
|
966 |
}
|
967 |
if ('specific' == $post['date_type']) {
|
969 |
} else {
|
970 |
'' == $post['date_start'] or $this->_validate_template($post['date_start'], __('Start Date', 'pmxi_plugin'));
|
971 |
'' == $post['date_end'] or $this->_validate_template($post['date_end'], __('Start Date', 'pmxi_plugin'));
|
972 |
+
}
|
|
|
|
|
|
|
973 |
if ('' == $post['tags_delim']) {
|
974 |
$this->errors->add('form-validation', __('Tag list delimiter must cannot be empty', 'pmxi_plugin'));
|
975 |
}
|
982 |
if ( ! preg_match('%^([1-9]\d*)( *- *([1-9]\d*))?$%', $chank, $mtch)) {
|
983 |
$this->errors->add('form-validation', __('Wrong format of `Import only specified records` value', 'pmxi_plugin'));
|
984 |
break;
|
985 |
+
} elseif ($this->isWizard and (intval($mtch[1]) > $this->data['elements']->length or isset($mtch[3]) and intval($mtch[3]) > $this->data['elements']->length)) {
|
986 |
+
$this->errors->add('form-validation', __('One of the numbers in `Import only specified records` value exceeds record quantity in XML file', 'pmxi_plugin'));
|
987 |
+
break;
|
988 |
+
}
|
989 |
}
|
990 |
}
|
991 |
}
|
1021 |
}
|
1022 |
|
1023 |
if ( ! $this->input->post('save_only')) {
|
1024 |
+
wp_redirect(add_query_arg('action', 'process', $this->baseUrl)); die();
|
1025 |
} else {
|
1026 |
$import = $this->data['update_previous'];
|
1027 |
$is_update = ! $import->isEmpty();
|
1048 |
}
|
1049 |
} else {
|
1050 |
$this->data['import']->set('options', $post)->set('scheduled', $scheduled['is_scheduled'] ? $scheduled['scheduled_period'] : '')->save();
|
1051 |
+
$template = new PMXI_Template_Record();
|
1052 |
+
|
1053 |
+
if (!$template->getByName($this->data['import']->template['name'])->isEmpty()){
|
1054 |
+
$template->set(array(
|
1055 |
+
'options' => $post,
|
1056 |
+
'scheduled' => ($scheduled['is_scheduled'] ? $scheduled['scheduled_period'] : '')))->update();
|
1057 |
+
}
|
1058 |
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();
|
1059 |
}
|
1060 |
}
|
1064 |
|
1065 |
$this->render();
|
1066 |
}
|
1067 |
+
|
1068 |
/**
|
1069 |
* Import processing step (status console)
|
1070 |
*/
|
1071 |
public function process()
|
1072 |
+
{
|
1073 |
+
$this->render();
|
1074 |
+
wp_ob_end_flush_all(); flush();
|
1075 |
+
|
1076 |
+
set_time_limit(0);
|
1077 |
|
1078 |
// store import info in database
|
1079 |
$import = $this->data['update_previous'];
|
1080 |
+
$import->set(
|
1081 |
+
$_SESSION['pmxi_import']['source']
|
1082 |
+
+ array(
|
1083 |
+
'xpath' => $_SESSION['pmxi_import']['xpath'],
|
1084 |
+
'template' => $_SESSION['pmxi_import']['template'],
|
1085 |
+
'options' => $_SESSION['pmxi_import']['options'],
|
1086 |
+
'scheduled' => $_SESSION['pmxi_import']['scheduled']
|
1087 |
+
)
|
1088 |
+
)->save();
|
1089 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1090 |
$logger = create_function('$m', 'echo "<div class=\\"progress-msg\\">$m</div>\\n"; flush();');
|
1091 |
+
|
1092 |
if (in_array($import->type, array('ftp', 'file'))) { // process files by patten
|
1093 |
$import->execute($logger);
|
1094 |
} else { // directly process XML
|
1095 |
+
$import->process($_SESSION['pmxi_import']['xml'], $logger);
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
unset($_SESSION['pmxi_import']); // clear session data (prevent from reimporting the same data on page refresh)
|
|
|
|
|
|
|
|
|
|
|
1099 |
|
1100 |
+
// [indicate in header process is complete]
|
|
|
|
|
1101 |
$msg = addcslashes(__('Complete', 'pmxi_plugin'), "'\n\r");
|
1102 |
echo <<<COMPLETE
|
1103 |
<script type="text/javascript">
|
1110 |
</script>
|
1111 |
COMPLETE;
|
1112 |
// [/indicate in header process is complete]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1113 |
}
|
1114 |
+
|
1115 |
/**
|
1116 |
* Remove xml document nodes by xpath expression
|
1117 |
*/
|
1395 |
}
|
1396 |
|
1397 |
return NULL;
|
1398 |
+
}
|
1399 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1400 |
}
|
controllers/admin/manage.php
CHANGED
@@ -22,8 +22,8 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
|
22 |
|
23 |
$get = $this->input->get(array(
|
24 |
's' => '',
|
25 |
-
'order_by' => '
|
26 |
-
'order' => '
|
27 |
'pagenum' => 1,
|
28 |
'perPage' => 10,
|
29 |
));
|
@@ -58,6 +58,96 @@ class PMXI_Admin_Manage extends PMXI_Controller_Admin {
|
|
58 |
$this->render();
|
59 |
}
|
60 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
/**
|
62 |
* Delete an import
|
63 |
*/
|
22 |
|
23 |
$get = $this->input->get(array(
|
24 |
's' => '',
|
25 |
+
'order_by' => 'ID',
|
26 |
+
'order' => 'DESC',
|
27 |
'pagenum' => 1,
|
28 |
'perPage' => 10,
|
29 |
));
|
58 |
$this->render();
|
59 |
}
|
60 |
|
61 |
+
/**
|
62 |
+
* Reimport
|
63 |
+
*/
|
64 |
+
public function update() {
|
65 |
+
$id = $this->input->get('id');
|
66 |
+
$this->data['item'] = $item = new PMXI_Import_Record();
|
67 |
+
if ( ! $id or $item->getById($id)->isEmpty()) {
|
68 |
+
wp_redirect($this->baseUrl); die();
|
69 |
+
}
|
70 |
+
|
71 |
+
if ($this->input->post('is_confirmed')) {
|
72 |
+
check_admin_referer('update-import', '_wpnonce_update-import');
|
73 |
+
|
74 |
+
if (in_array($item->type, array('ftp', 'file'))) {
|
75 |
+
$xml = '';
|
76 |
+
} else {
|
77 |
+
|
78 |
+
$contents = get_headers($item->path,1 );
|
79 |
+
|
80 |
+
if (preg_match('%\W(zip)$%i', trim($item->path))){
|
81 |
+
|
82 |
+
$uploads = wp_upload_dir();
|
83 |
+
|
84 |
+
$newfile = $uploads['path']."/".md5(time()).'.zip';
|
85 |
+
|
86 |
+
if (!copy($item->path, $newfile)) {
|
87 |
+
$this->errors->add('form-validation', __('Failed upload ZIP archive', 'pmxi_plugin'));
|
88 |
+
}
|
89 |
+
|
90 |
+
$zip = zip_open($newfile);
|
91 |
+
if (is_resource($zip)) {
|
92 |
+
$uploads = wp_upload_dir();
|
93 |
+
if($uploads['error']){
|
94 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
95 |
+
}
|
96 |
+
$filename = '';
|
97 |
+
while ($zip_entry = zip_read($zip)) {
|
98 |
+
$filename = zip_entry_name($zip_entry);
|
99 |
+
$fp = fopen($uploads['path']."/".$filename, "w");
|
100 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
101 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
102 |
+
fwrite($fp,"$buf");
|
103 |
+
zip_entry_close($zip_entry);
|
104 |
+
fclose($fp);
|
105 |
+
}
|
106 |
+
break;
|
107 |
+
}
|
108 |
+
zip_close($zip);
|
109 |
+
unlink($newfile);
|
110 |
+
if (preg_match('%\W(csv)$%i', trim($filename)) or PMXI_Plugin::detect_csv($contents['Content-Type']))
|
111 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] .'/'. $filename);
|
112 |
+
else
|
113 |
+
$xml = @file_get_contents($uploads['path'] .'/'. $filename);
|
114 |
+
}
|
115 |
+
|
116 |
+
} elseif (preg_match('%\W(csv)$%i', trim($item->path)) or PMXI_Plugin::detect_csv($contents['Content-Type'])) {
|
117 |
+
$uploads = wp_upload_dir();
|
118 |
+
$fdata = file_get_contents($item->path);
|
119 |
+
$tmpname = md5(time()).'.csv';
|
120 |
+
file_put_contents($uploads['path'] .'/'. $tmpname, $fdata);
|
121 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] .'/'. $tmpname);
|
122 |
+
}
|
123 |
+
else
|
124 |
+
$xml = @file_get_contents($item->path);
|
125 |
+
}
|
126 |
+
if (in_array($item->type, array('ftp', 'file')) or PMXI_Import_Record::validateXml($xml, $this->errors)) { // xml is valid
|
127 |
+
// compose data to look like result of wizard steps
|
128 |
+
$_SESSION['pmxi_import'] = array(
|
129 |
+
'xml' => $xml,
|
130 |
+
'source' => array(
|
131 |
+
'name' => $item->name,
|
132 |
+
'type' => $item->type,
|
133 |
+
'path' => $item->path,
|
134 |
+
),
|
135 |
+
'update_previous' => $item->id,
|
136 |
+
'xpath' => $item->xpath,
|
137 |
+
'template' => $item->template,
|
138 |
+
'options' => $item->options,
|
139 |
+
);
|
140 |
+
// deligate operation to other controller
|
141 |
+
$controller = new PMXI_Admin_Import();
|
142 |
+
$controller->data['update_previous'] = $item;
|
143 |
+
$controller->process();
|
144 |
+
return;
|
145 |
+
}
|
146 |
+
|
147 |
+
}
|
148 |
+
$this->render();
|
149 |
+
}
|
150 |
+
|
151 |
/**
|
152 |
* Delete an import
|
153 |
*/
|
controllers/admin/settings.php
CHANGED
@@ -19,6 +19,7 @@ class PMXI_Admin_Settings extends PMXI_Controller_Admin {
|
|
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 |
|
23 |
if ( ! $this->errors->get_error_codes()) { // no validation errors detected
|
24 |
|
@@ -52,5 +53,5 @@ class PMXI_Admin_Settings extends PMXI_Controller_Admin {
|
|
52 |
|
53 |
exit('OK');
|
54 |
}
|
55 |
-
|
56 |
}
|
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 |
|
53 |
|
54 |
exit('OK');
|
55 |
}
|
56 |
+
|
57 |
}
|
controllers/controller/admin.php
CHANGED
@@ -54,6 +54,7 @@ abstract class PMXI_Controller_Admin extends PMXI_Controller {
|
|
54 |
wp_enqueue_script('jquery-ui-datepicker', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/ui.datepicker.js', 'jquery-ui-core');
|
55 |
wp_enqueue_script('jquery-ui-autocomplete', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/ui.autocomplete.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'));
|
56 |
wp_enqueue_script('jquery-tipsy', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/jquery.tipsy.js', 'jquery');
|
|
|
57 |
|
58 |
wp_enqueue_script('pmxi-admin-script', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
|
59 |
|
54 |
wp_enqueue_script('jquery-ui-datepicker', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/ui.datepicker.js', 'jquery-ui-core');
|
55 |
wp_enqueue_script('jquery-ui-autocomplete', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/ui.autocomplete.js', array('jquery-ui-core', 'jquery-ui-widget', 'jquery-ui-position'));
|
56 |
wp_enqueue_script('jquery-tipsy', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/jquery.tipsy.js', 'jquery');
|
57 |
+
wp_enqueue_script('jquery-nestable', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/jquery/jquery.mjs.nestedSortable.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable'));
|
58 |
|
59 |
wp_enqueue_script('pmxi-admin-script', PMXI_Plugin::getInstance()->getRelativePath() . '/static/js/admin.js', array('jquery', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable'));
|
60 |
|
libraries/XmlImportConfig.php
CHANGED
@@ -43,10 +43,10 @@ if (!class_exists('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 |
|
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 |
|
libraries/XmlImportCsvParse.php
CHANGED
@@ -110,6 +110,8 @@ class PMXI_CsvParser
|
|
110 |
*/
|
111 |
public function __construct($filename = null)
|
112 |
{
|
|
|
|
|
113 |
ini_set('auto_detect_line_endings', true);
|
114 |
|
115 |
$file_params = self::analyse_file($filename, 10);
|
@@ -2165,7 +2167,7 @@ class PMXI_CsvParser
|
|
2165 |
|
2166 |
if ($c == 0) {
|
2167 |
foreach ($keys as $key => $value) {
|
2168 |
-
if (preg_match('%\W(http:|https:|ftp:)$%i', $value) or
|
2169 |
$create_new_headers = true;
|
2170 |
break;
|
2171 |
}
|
@@ -2285,7 +2287,7 @@ class PMXI_CsvParser
|
|
2285 |
}
|
2286 |
|
2287 |
public function toXml() {
|
2288 |
-
$this->symmetrize();
|
2289 |
return ArrayToXML::toXml($this->getRawArray());
|
2290 |
}
|
2291 |
|
@@ -2411,7 +2413,7 @@ class ArrayToXML
|
|
2411 |
else
|
2412 |
{
|
2413 |
// add single node.
|
2414 |
-
|
2415 |
$xml->addChild($key,$value);
|
2416 |
}
|
2417 |
|
110 |
*/
|
111 |
public function __construct($filename = null)
|
112 |
{
|
113 |
+
|
114 |
+
ini_set( "display_errors", 0);
|
115 |
ini_set('auto_detect_line_endings', true);
|
116 |
|
117 |
$file_params = self::analyse_file($filename, 10);
|
2167 |
|
2168 |
if ($c == 0) {
|
2169 |
foreach ($keys as $key => $value) {
|
2170 |
+
if (preg_match('%\W(http:|https:|ftp:)$%i', $value) or is_numeric($value)) {
|
2171 |
$create_new_headers = true;
|
2172 |
break;
|
2173 |
}
|
2287 |
}
|
2288 |
|
2289 |
public function toXml() {
|
2290 |
+
$this->symmetrize();
|
2291 |
return ArrayToXML::toXml($this->getRawArray());
|
2292 |
}
|
2293 |
|
2413 |
else
|
2414 |
{
|
2415 |
// add single node.
|
2416 |
+
$value = htmlspecialchars($value);
|
2417 |
$xml->addChild($key,$value);
|
2418 |
}
|
2419 |
|
libraries/XmlImportParser.php
CHANGED
@@ -72,7 +72,7 @@ class XmlImportParser {
|
|
72 |
throw new XmlImportException('Invalid root node XPath \'' . $this->rootNodeXPath . '\' specified');
|
73 |
|
74 |
for ($i = 0; $i < count($rootNodes); $i++) {
|
75 |
-
if (empty($records) or in_array(
|
76 |
$rootNode = $rootNodes[$i];
|
77 |
$template = new XmlImportTemplate($rootNode, $this->cachedTemplate);
|
78 |
$result[] = $template->parse();
|
72 |
throw new XmlImportException('Invalid root node XPath \'' . $this->rootNodeXPath . '\' specified');
|
73 |
|
74 |
for ($i = 0; $i < count($rootNodes); $i++) {
|
75 |
+
if (empty($records) or in_array($i + 1, $records)) {
|
76 |
$rootNode = $rootNodes[$i];
|
77 |
$template = new XmlImportTemplate($rootNode, $this->cachedTemplate);
|
78 |
$result[] = $template->parse();
|
libraries/XmlImportTemplateCodeGenerator.php
CHANGED
@@ -17,6 +17,7 @@ require_once dirname(__FILE__) . '/ast/XmlImportAstWith.php';
|
|
17 |
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
18 |
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
19 |
require_once dirname(__FILE__) . '/ast/XmlImportAstMath.php';
|
|
|
20 |
|
21 |
/**
|
22 |
* Is used to generate a PHP code from AST (Abstract Syntax Tree)
|
@@ -127,7 +128,7 @@ class XmlImportTemplateCodeGenerator
|
|
127 |
$result .= PHP_EOL;
|
128 |
}
|
129 |
foreach ($sequence->getStatements() as $statement)
|
130 |
-
{
|
131 |
$result .= $this->generateForStatement($statement);
|
132 |
}
|
133 |
array_pop($this->sequenceStack);
|
@@ -181,11 +182,11 @@ class XmlImportTemplateCodeGenerator
|
|
181 |
' as ' . $var . ') :' . PHP_EOL;
|
182 |
array_push($this->xmlStack, $var);
|
183 |
$result .= $this->generateForSequence($statement->getBody());
|
184 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'endforeach;' . PHP_EOL;
|
185 |
array_pop($this->xmlStack);
|
186 |
}
|
187 |
elseif ($statement instanceof XmlImportAstIf)
|
188 |
-
{
|
189 |
$result .= PHP_EOL . 'if (' . $this->generateForExpression($statement->getCondition()) . ') :' . PHP_EOL;
|
190 |
$result .= $this->generateForSequence($statement->getIfBody());
|
191 |
foreach ($statement->getElseIfs() as $elseif)
|
@@ -198,7 +199,7 @@ class XmlImportTemplateCodeGenerator
|
|
198 |
$result .= $this->openPhpTag() . PHP_EOL . 'else :' . PHP_EOL;
|
199 |
$result .= $this->generateForSequence($body);
|
200 |
}
|
201 |
-
$result .= $this->openPhpTag() . PHP_EOL . 'endif;' . PHP_EOL;
|
202 |
}
|
203 |
|
204 |
}
|
@@ -242,9 +243,14 @@ class XmlImportTemplateCodeGenerator
|
|
242 |
|
243 |
case 'XmlImportAstFunction':
|
244 |
$result = $this->generateForFunction($expression);
|
245 |
-
|
246 |
-
|
247 |
-
|
|
|
|
|
|
|
|
|
|
|
248 |
break;
|
249 |
}
|
250 |
return $result;
|
@@ -262,7 +268,7 @@ class XmlImportTemplateCodeGenerator
|
|
262 |
$arguments = $function->getArguments();
|
263 |
for($i = 0; $i < count($arguments); $i++)
|
264 |
{
|
265 |
-
$result .= $this->generateForExpression($arguments[$i]);
|
266 |
if ($i < (count($arguments) - 1))
|
267 |
$result .= ', ';
|
268 |
}
|
@@ -289,6 +295,44 @@ class XmlImportTemplateCodeGenerator
|
|
289 |
return 'number_format('.str_replace("\"", "", $result).',2)';
|
290 |
}
|
291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
/**
|
293 |
* Add PHP open tag if needed
|
294 |
*
|
17 |
require_once dirname(__FILE__) . '/ast/XmlImportAstForeach.php';
|
18 |
require_once dirname(__FILE__) . '/ast/XmlImportAstIf.php';
|
19 |
require_once dirname(__FILE__) . '/ast/XmlImportAstMath.php';
|
20 |
+
require_once dirname(__FILE__) . '/ast/XmlImportAstSpintax.php';
|
21 |
|
22 |
/**
|
23 |
* Is used to generate a PHP code from AST (Abstract Syntax Tree)
|
128 |
$result .= PHP_EOL;
|
129 |
}
|
130 |
foreach ($sequence->getStatements() as $statement)
|
131 |
+
{
|
132 |
$result .= $this->generateForStatement($statement);
|
133 |
}
|
134 |
array_pop($this->sequenceStack);
|
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)
|
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 |
}
|
243 |
|
244 |
case 'XmlImportAstFunction':
|
245 |
$result = $this->generateForFunction($expression);
|
246 |
+
break;
|
247 |
+
|
248 |
+
case 'XmlImportAstMath':
|
249 |
+
$result = $this->generateForMath($expression);
|
250 |
+
break;
|
251 |
+
|
252 |
+
case 'XmlImportAstSpintax':
|
253 |
+
$result = $this->generateForSpintax($expression);
|
254 |
break;
|
255 |
}
|
256 |
return $result;
|
268 |
$arguments = $function->getArguments();
|
269 |
for($i = 0; $i < count($arguments); $i++)
|
270 |
{
|
271 |
+
$result .= $this->generateForExpression($arguments[$i], true);
|
272 |
if ($i < (count($arguments) - 1))
|
273 |
$result .= ', ';
|
274 |
}
|
295 |
return 'number_format('.str_replace("\"", "", $result).',2)';
|
296 |
}
|
297 |
|
298 |
+
/**
|
299 |
+
* Generates code for a function
|
300 |
+
*
|
301 |
+
* @param XmlImportAstSpintax $expression
|
302 |
+
* @return string
|
303 |
+
*/
|
304 |
+
private function generateForSpintax(XmlImportAstSpintax $spintax)
|
305 |
+
{
|
306 |
+
$result = '';
|
307 |
+
$arguments = $spintax->getArguments();
|
308 |
+
|
309 |
+
$spintax_begin = array();
|
310 |
+
$spintax_end = array();
|
311 |
+
$context = '';
|
312 |
+
$first_arg = true;
|
313 |
+
for ($i = 0; $i < count($arguments); $i++) {
|
314 |
+
if ($first_arg and $arguments[$i]['type'] == 'xpath') {
|
315 |
+
$spintax_begin[] = $this->generateForExpression($arguments[$i]['argument'], true);
|
316 |
+
}
|
317 |
+
elseif ($arguments[$i]['type'] == 'context')
|
318 |
+
{
|
319 |
+
$first_arg = false;
|
320 |
+
$context = $this->generateForExpression($arguments[$i]['argument'], true);
|
321 |
+
}
|
322 |
+
else
|
323 |
+
$spintax_end[] = $this->generateForExpression($arguments[$i]['argument'], true);
|
324 |
+
}
|
325 |
+
|
326 |
+
for($i = 0; $i < count($spintax_begin); $i++)
|
327 |
+
{
|
328 |
+
for ($j = 0; $j < count($spintax_end); $j++) {
|
329 |
+
$result .= '"<p>".'.$spintax_begin[$i].'." ".'.$context.'." ".'.$spintax_end[$j].'."</p>".';
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
return substr_replace($result ,"",-1);
|
334 |
+
}
|
335 |
+
|
336 |
/**
|
337 |
* Add PHP open tag if needed
|
338 |
*
|
libraries/XmlImportTemplateParser.php
CHANGED
@@ -11,6 +11,7 @@ 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 |
|
15 |
require_once dirname(__FILE__) . '/ast/XmlImportAstXPath.php';
|
16 |
require_once dirname(__FILE__) . '/ast/XmlImportAstString.php';
|
@@ -146,10 +147,14 @@ class XmlImportTemplateParser
|
|
146 |
{
|
147 |
return $this->parseForeach();
|
148 |
}
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
|
|
|
|
|
|
|
|
153 |
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_IF)
|
154 |
{
|
155 |
return $this->parseIf();
|
@@ -185,12 +190,16 @@ class XmlImportTemplateParser
|
|
185 |
{
|
186 |
return $this->parseFunction();
|
187 |
}
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
elseif
|
193 |
{
|
|
|
|
|
|
|
|
|
194 |
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
195 |
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
196 |
return $xpath;
|
@@ -283,6 +292,52 @@ class XmlImportTemplateParser
|
|
283 |
}
|
284 |
}
|
285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
286 |
/**
|
287 |
* Parses clause that uses XPath and returns XPath
|
288 |
*
|
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';
|
147 |
{
|
148 |
return $this->parseForeach();
|
149 |
}
|
150 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
151 |
+
{
|
152 |
+
return new XmlImportAstPrint($this->parseExpression());
|
153 |
+
}
|
154 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_SPINTAX)
|
155 |
+
{
|
156 |
+
return new XmlImportAstPrint($this->parseExpression());
|
157 |
+
}
|
158 |
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_IF)
|
159 |
{
|
160 |
return $this->parseIf();
|
190 |
{
|
191 |
return $this->parseFunction();
|
192 |
}
|
193 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_MATH)
|
194 |
+
{
|
195 |
+
return $this->parseMath();
|
196 |
+
}
|
197 |
+
elseif($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_SPINTAX)
|
198 |
{
|
199 |
+
return $this->parseSpintax();
|
200 |
+
}
|
201 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
202 |
+
{
|
203 |
$xpath = new XmlImportAstXPath($this->tokens[++$this->index]->getValue());
|
204 |
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
205 |
return $xpath;
|
292 |
}
|
293 |
}
|
294 |
|
295 |
+
/**
|
296 |
+
* Parses function
|
297 |
+
*
|
298 |
+
* @return XmlImportSpintaxFunction
|
299 |
+
*/
|
300 |
+
private function parseSpintax()
|
301 |
+
{
|
302 |
+
$spintax = new XmlImportAstSpintax($this->tokens[++$this->index]->getValue());
|
303 |
+
if ($this->tokens[$this->index + 1]->getKind() != XmlImportToken::KIND_OPEN)
|
304 |
+
throw new XmlImportException ("Open brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
305 |
+
$this->index++;
|
306 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
307 |
+
{
|
308 |
+
$this->index++;
|
309 |
+
return $spintax;
|
310 |
+
}
|
311 |
+
else
|
312 |
+
{
|
313 |
+
while ($this->index < count($this->tokens) - 2)
|
314 |
+
{
|
315 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_XPATH)
|
316 |
+
{
|
317 |
+
$xpath_parts = explode('|', str_replace(array('{', '}'), '', $this->tokens[++$this->index]->getValue()));
|
318 |
+
for ($i = 0; $i < count($xpath_parts); $i++) {
|
319 |
+
$xpath = new XmlImportAstXPath($xpath_parts[$i]);
|
320 |
+
$this->sequenceStack[count($this->sequenceStack) - 1]->addVariable($xpath);
|
321 |
+
$spintax->addArgument($xpath, 'xpath');
|
322 |
+
}
|
323 |
+
}
|
324 |
+
else $spintax->addArgument($this->parseExpression(), 'context');
|
325 |
+
|
326 |
+
if ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_CLOSE)
|
327 |
+
{
|
328 |
+
$this->index++;
|
329 |
+
return $spintax;
|
330 |
+
break;
|
331 |
+
}
|
332 |
+
elseif ($this->tokens[$this->index + 1]->getKind() == XmlImportToken::KIND_COMMA)
|
333 |
+
$this->index++;
|
334 |
+
else
|
335 |
+
throw new XmlImportException("Comma or closing brace expected instead of " . $this->tokens[$this->index + 1]->getKind());
|
336 |
+
}
|
337 |
+
throw new XmlImportException("Unexpected end of MATH argument list");
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
/**
|
342 |
* Parses clause that uses XPath and returns XPath
|
343 |
*
|
libraries/XmlImportTemplateScanner.php
CHANGED
@@ -26,7 +26,8 @@ final class XmlImportTemplateScanner
|
|
26 |
'ENDFOREACH',
|
27 |
'WITH',
|
28 |
'ENDWITH',
|
29 |
-
|
|
|
30 |
);
|
31 |
|
32 |
/**
|
@@ -117,10 +118,10 @@ final class XmlImportTemplateScanner
|
|
117 |
else
|
118 |
$results[] = $result;
|
119 |
}
|
120 |
-
|
121 |
{
|
122 |
$this->isLangBegin = false;
|
123 |
-
|
124 |
$results[] = new XmlImportToken(XmlImportToken::KIND_OPERATION, $ch);
|
125 |
}
|
126 |
elseif ($ch == '"')
|
@@ -160,7 +161,7 @@ final class XmlImportTemplateScanner
|
|
160 |
$input->read();
|
161 |
$results[] = new XmlImportToken(XmlImportToken::KIND_COMMA);
|
162 |
}
|
163 |
-
elseif ($ch == ']')
|
164 |
{
|
165 |
$this->isLangBegin = false;
|
166 |
$this->currentState = XmlImportTemplateScanner::STATE_TEXT;
|
26 |
'ENDFOREACH',
|
27 |
'WITH',
|
28 |
'ENDWITH',
|
29 |
+
'MATH',
|
30 |
+
'SPINTAX'
|
31 |
);
|
32 |
|
33 |
/**
|
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 == '"')
|
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;
|
libraries/XmlImportToken.php
CHANGED
@@ -117,6 +117,11 @@ class XmlImportToken
|
|
117 |
* Token is a math on the price element
|
118 |
*/
|
119 |
const KIND_MATH = "MATH";
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
/**
|
122 |
* Token is a math on the price element
|
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
|
libraries/ast/XmlImportAstSpintax.php
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @author Olexandr Zanichkovsky <olexandr.zanichkovsky@zophiatech.com>
|
4 |
+
* @package AST
|
5 |
+
*/
|
6 |
+
|
7 |
+
require_once dirname(__FILE__) . '/XmlImportAstExpression.php';
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Represents a function
|
11 |
+
*/
|
12 |
+
class XmlImportAstSpintax extends XmlImportAstExpression
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
* Function arguments
|
16 |
+
*
|
17 |
+
* @var array
|
18 |
+
*/
|
19 |
+
private $arguments = array();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Creates new instance
|
23 |
+
*
|
24 |
+
* @param string $name
|
25 |
+
*/
|
26 |
+
public function __construct($name)
|
27 |
+
{
|
28 |
+
$this->name = $name;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Adds argument to a function
|
33 |
+
*
|
34 |
+
* @param XmlImportAstExpression $argument
|
35 |
+
*/
|
36 |
+
public function addArgument(XmlImportAstExpression $argument, $type = false)
|
37 |
+
{
|
38 |
+
$this->arguments[] = array(
|
39 |
+
'argument' => $argument,
|
40 |
+
'type' => $type
|
41 |
+
);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Gets function arguments
|
46 |
+
*
|
47 |
+
* @return array
|
48 |
+
*/
|
49 |
+
public function getArguments()
|
50 |
+
{
|
51 |
+
return $this->arguments;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* String representation of a function
|
56 |
+
*
|
57 |
+
* @return string
|
58 |
+
*/
|
59 |
+
public function __toString()
|
60 |
+
{
|
61 |
+
$result = "--> begin " . get_class($this) . "\n";
|
62 |
+
foreach ($this->getArguments() as $argument)
|
63 |
+
{
|
64 |
+
$array = explode("\n", $argument);
|
65 |
+
for ($i = 0; $i < count($array); $i++)
|
66 |
+
{
|
67 |
+
$array[$i] = ' ' . $array[$i];
|
68 |
+
}
|
69 |
+
$result .= implode("\n", $array) . "\n";
|
70 |
+
}
|
71 |
+
|
72 |
+
$result .= "--> end " . get_class($this);
|
73 |
+
|
74 |
+
return $result;
|
75 |
+
}
|
76 |
+
}
|
models/import/record.php
CHANGED
@@ -8,10 +8,18 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
8 |
*/
|
9 |
public static function preprocessXml( & $xml) {
|
10 |
//$xml = preg_replace('%\pC(?<!\s)%u', '', $xml); // remove control chars but not white-spacing ones
|
11 |
-
//use HTML::Entities;
|
12 |
-
|
|
|
|
|
13 |
}
|
14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
/**
|
16 |
* Validate XML to be valid for improt
|
17 |
* @param string $xml
|
@@ -21,8 +29,11 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
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 |
libxml_use_internal_errors(true);
|
27 |
libxml_clear_errors();
|
28 |
$_x = @simplexml_load_string($xml);
|
@@ -85,18 +96,77 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
85 |
} else { // single file path
|
86 |
$files = array($this->path);
|
87 |
}
|
|
|
88 |
foreach ($files as $ind => $path) {
|
89 |
$logger and call_user_func($logger, sprintf(__('Importing %s (%s of %s)', 'pmxi_plugin'), $path, $ind + 1, count($files)));
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
|
91 |
-
|
92 |
-
|
93 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
if ( ! $xml) {
|
95 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': file is not accessible or empty');
|
96 |
} elseif ( ! PMXI_Import_Record::validateXml($xml)) {
|
97 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': file is not a properly fromatted XML document');
|
98 |
} else {
|
|
|
99 |
$this->process($xml, $logger);
|
|
|
100 |
}
|
101 |
}
|
102 |
$logger and call_user_func($logger, __('Complete', 'pmxi_plugin'));
|
@@ -111,12 +181,19 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
111 |
* @return PMXI_Import_Record
|
112 |
* @chainable
|
113 |
*/
|
114 |
-
public function process($xml, $logger = NULL
|
115 |
add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
|
116 |
|
117 |
-
$this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
|
118 |
-
|
119 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
$postRecord = new PMXI_Post_Record();
|
122 |
|
@@ -134,18 +211,18 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
134 |
}
|
135 |
try {
|
136 |
|
137 |
-
$
|
|
|
|
|
|
|
138 |
$contents = XmlImportParser::factory(
|
139 |
(intval($this->template['is_keep_linebreaks']) ? $xml : preg_replace('%\r\n?|\n%', ' ', $xml)),
|
140 |
$this->xpath,
|
141 |
$this->template['content'],
|
142 |
$file)->parse($records
|
143 |
-
); $tmp_files[] = $file;
|
144 |
-
|
145 |
-
$first_chank and $logger and call_user_func($logger, __('Composing titles...', 'pmxi_plugin'));
|
146 |
-
$titles = XmlImportParser::factory($xml, $this->xpath, $this->template['title'], $file)->parse($records); $tmp_files[] = $file;
|
147 |
|
148 |
-
$
|
149 |
|
150 |
$dates = XmlImportParser::factory($xml, $this->xpath, $this->options['date'], $file)->parse($records); $tmp_files[] = $file;
|
151 |
$warned = array(); // used to prevent the same notice displaying several times
|
@@ -157,11 +234,11 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
157 |
}
|
158 |
$dates[$i] = date('Y-m-d H:i:s', $time);
|
159 |
}
|
160 |
-
|
161 |
if ('post' == $this->options['type']) {
|
162 |
$tags = array();
|
163 |
if ($this->options['tags']) {
|
164 |
-
$
|
165 |
$tags_raw = XmlImportParser::factory($xml, $this->xpath, $this->options['tags'], $file)->parse($records); $tmp_files[] = $file;
|
166 |
foreach ($tags_raw as $i => $t_raw) {
|
167 |
$tags[$i] = '';
|
@@ -170,30 +247,50 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
170 |
} else {
|
171 |
count($titles) and $tags = array_fill(0, count($titles), '');
|
172 |
}
|
|
|
173 |
$cats = array();
|
174 |
-
|
175 |
-
|
176 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
$warned = array(); // used to prevent the same notice displaying several times
|
178 |
foreach ($cats_raw as $i => $c_raw) {
|
179 |
$cats[$i] = array();
|
180 |
-
if ('' != $c_raw) foreach (str_getcsv($c_raw,
|
181 |
$cat = get_term_by('name', $c, 'category') or ctype_digit($c) and $cat = get_term_by('id', $c, 'category');
|
182 |
if ( ! $cat) { // create category automatically
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
188 |
}
|
189 |
} else {
|
190 |
$cats[$i][] = $cat->term_id;
|
191 |
}
|
192 |
}
|
193 |
-
}
|
194 |
} else {
|
195 |
count($titles) and $cats = array_fill(0, count($titles), '');
|
196 |
-
}
|
197 |
}
|
198 |
// [custom taxonomies]
|
199 |
$taxonomies = array();
|
@@ -205,71 +302,113 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
205 |
} else {
|
206 |
$taxonomies_object_type = 'post';
|
207 |
}
|
208 |
-
foreach ($this->options[$taxonomies_param] as $tx_name => $tx_template) if ('' != $tx_template) {
|
209 |
$tx = get_taxonomy($tx_name);
|
210 |
if (in_array($taxonomies_object_type, $tx->object_type)) {
|
211 |
-
$
|
212 |
$txes = array();
|
213 |
-
|
|
|
|
|
|
|
|
|
|
|
214 |
foreach ($txes_raw as $i => $tx_raw) {
|
215 |
-
$taxonomies[$tx_name][$i] =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
}
|
217 |
}
|
218 |
-
}
|
219 |
// [/custom taxonomies]
|
220 |
|
221 |
-
$
|
222 |
$meta_keys = array(); $meta_values = array();
|
223 |
foreach ($this->options['custom_name'] as $j => $custom_name) {
|
224 |
$meta_keys[$j] = XmlImportParser::factory($xml, $this->xpath, $custom_name, $file)->parse($records); $tmp_files[] = $file;
|
225 |
$meta_values[$j] = XmlImportParser::factory($xml, $this->xpath, $this->options['custom_value'][$j], $file)->parse($records); $tmp_files[] = $file;
|
226 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
|
228 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
|
229 |
$logger and call_user_func($logger, __('<b>WARNING</b>: No featured images will be created', 'pmxi_plugin'));
|
230 |
} else {
|
231 |
-
$
|
232 |
$featured_images = array();
|
233 |
if ($this->options['featured_image']) {
|
234 |
// Detect if images is separated by comma
|
235 |
-
$imgs = explode(',',$this->options['featured_image']);
|
236 |
if (!empty($imgs)){
|
237 |
$parse_multiple = true;
|
238 |
-
foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
|
|
|
239 |
if ($parse_multiple)
|
240 |
{
|
241 |
foreach($imgs as $img)
|
242 |
-
{
|
243 |
-
$posts_images = XmlImportParser::factory($xml, $this->xpath, $img, $file)->parse($records); $tmp_files[] = $file;
|
244 |
-
foreach($posts_images as $i => $val)
|
245 |
-
{
|
246 |
-
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(\/\S*)?/";
|
247 |
-
preg_match_all($reg_exUrl, $val, $matches);
|
248 |
-
$usedPatterns = array();
|
249 |
-
foreach($matches[0] as $pattern){
|
250 |
-
if(!array_key_exists($pattern, $usedPatterns)){
|
251 |
-
$usedPatterns[$pattern]=true;
|
252 |
-
$featured_images[$i][] = str_replace(',','',$pattern);
|
253 |
-
}
|
254 |
-
}
|
255 |
-
}
|
256 |
-
|
257 |
}
|
258 |
}
|
259 |
else
|
260 |
{
|
261 |
-
$featured_images = XmlImportParser::factory($xml, $this->xpath, $this->options['featured_image'], $file)->parse($records); $tmp_files[] = $file;
|
262 |
}
|
263 |
}
|
264 |
|
265 |
} else {
|
266 |
count($titles) and $featured_images = array_fill(0, count($titles), '');
|
267 |
}
|
268 |
-
}
|
269 |
-
$
|
270 |
$unique_keys = XmlImportParser::factory($xml, $this->xpath, $this->options['unique_key'], $file)->parse($records); $tmp_files[] = $file;
|
271 |
|
272 |
-
$
|
273 |
|
274 |
if ('post' == $this->options['type'] and '' != $this->options['custom_type']) {
|
275 |
$post_type = $this->options['custom_type'];
|
@@ -311,6 +450,7 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
311 |
$post_to_update = get_post($post_to_update_id = $postRecord->post_id);
|
312 |
if ($post_to_update) { // existing post is found
|
313 |
if ($this->options['is_keep_former_posts']) {
|
|
|
314 |
$logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: Previously imported record found for `%s`', 'pmxi_plugin'), $articleData['post_title']));
|
315 |
continue;
|
316 |
}
|
@@ -357,6 +497,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
357 |
if ($this->options['is_keep_status']) { // preserve status and trashed flag
|
358 |
$articleData['post_status'] = $post_to_update->post_status;
|
359 |
}
|
|
|
|
|
|
|
360 |
} else { // existing post not found though it's track was found... clear the leftover, plugin will continue to treat record as new
|
361 |
$postRecord->delete();
|
362 |
}
|
@@ -445,13 +588,16 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
445 |
if (is_wp_error($pid)) {
|
446 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
447 |
} else {
|
|
|
|
|
|
|
448 |
$current_post_ids[] = $pid;
|
449 |
// associate post with import
|
450 |
$postRecord->isEmpty() and $postRecord->set(array(
|
451 |
'post_id' => $pid,
|
452 |
'import_id' => $this->id,
|
453 |
'unique_key' => $unique_keys[$i],
|
454 |
-
))->insert();
|
455 |
|
456 |
// [custom taxonomies]
|
457 |
foreach ($taxonomies as $tx_name => $txes) {
|
@@ -482,9 +628,9 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
482 |
} catch (XmlImportException $e) {
|
483 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $e->getMessage());
|
484 |
}
|
485 |
-
$
|
486 |
|
487 |
-
$
|
488 |
foreach ($tmp_files as $file) { // remove all temporary files created
|
489 |
unlink($file);
|
490 |
}
|
@@ -495,12 +641,43 @@ class PMXI_Import_Record extends PMXI_Model_Record {
|
|
495 |
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $this->path));
|
496 |
}
|
497 |
}
|
498 |
-
$logger and
|
499 |
|
500 |
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
|
501 |
|
502 |
return $this;
|
503 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
504 |
|
505 |
public function _filter_has_cap_unfiltered_html($caps)
|
506 |
{
|
8 |
*/
|
9 |
public static function preprocessXml( & $xml) {
|
10 |
//$xml = preg_replace('%\pC(?<!\s)%u', '', $xml); // remove control chars but not white-spacing ones
|
11 |
+
//use HTML::Entities;
|
12 |
+
|
13 |
+
$xml = preg_replace("/&.{0,}?;/",'',$xml);
|
14 |
+
|
15 |
}
|
16 |
+
|
17 |
+
public static function uft8decodeXml( & $xml ){
|
18 |
+
|
19 |
+
$xml = str_replace(array("&"), array("&"), utf8_decode($xml));
|
20 |
+
|
21 |
+
}
|
22 |
+
|
23 |
/**
|
24 |
* Validate XML to be valid for improt
|
25 |
* @param string $xml
|
29 |
public static function validateXml( & $xml, $errors = NULL) {
|
30 |
if (FALSE === $xml or '' == $xml) {
|
31 |
$errors and $errors->add('form-validation', __('XML file does not exist, not accessible or empty', 'pmxi_plugin'));
|
32 |
+
} else {
|
33 |
+
|
34 |
+
if (PMXI_Plugin::getInstance()->getOption('utf8_decode')) PMXI_Import_Record::uft8decodeXml($xml);
|
35 |
+
if (PMXI_Plugin::getInstance()->getOption('html_entities')) PMXI_Import_Record::preprocessXml($xml);
|
36 |
+
|
37 |
libxml_use_internal_errors(true);
|
38 |
libxml_clear_errors();
|
39 |
$_x = @simplexml_load_string($xml);
|
96 |
} else { // single file path
|
97 |
$files = array($this->path);
|
98 |
}
|
99 |
+
|
100 |
foreach ($files as $ind => $path) {
|
101 |
$logger and call_user_func($logger, sprintf(__('Importing %s (%s of %s)', 'pmxi_plugin'), $path, $ind + 1, count($files)));
|
102 |
+
|
103 |
+
$contents = get_headers($path,1 );
|
104 |
+
|
105 |
+
if (preg_match('%\W(zip)$%i', trim($path))){
|
106 |
+
|
107 |
+
$uploads = wp_upload_dir();
|
108 |
|
109 |
+
$newfile = $uploads['path']."/".md5(time()).'.zip';
|
110 |
+
|
111 |
+
if (!copy($path, $newfile)) {
|
112 |
+
$this->errors->add('form-validation', __('Failed upload ZIP archive', 'pmxi_plugin'));
|
113 |
+
}
|
114 |
+
|
115 |
+
$zip = zip_open($newfile);
|
116 |
+
if (is_resource($zip)) {
|
117 |
+
$uploads = wp_upload_dir();
|
118 |
+
if($uploads['error']){
|
119 |
+
$this->errors->add('form-validation', __('Can not create upload folder. Permision denied', 'pmxi_plugin'));
|
120 |
+
}
|
121 |
+
$filename = '';
|
122 |
+
while ($zip_entry = zip_read($zip)) {
|
123 |
+
$filename = zip_entry_name($zip_entry);
|
124 |
+
$fp = fopen($uploads['path']."/".$filename, "w");
|
125 |
+
if (zip_entry_open($zip, $zip_entry, "r")) {
|
126 |
+
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
|
127 |
+
fwrite($fp,"$buf");
|
128 |
+
zip_entry_close($zip_entry);
|
129 |
+
fclose($fp);
|
130 |
+
}
|
131 |
+
break;
|
132 |
+
}
|
133 |
+
zip_close($zip);
|
134 |
+
unlink($newfile);
|
135 |
+
if (preg_match('%\W(csv)$%i', trim($filename)) or PMXI_Plugin::detect_csv($contents['Content-Type']))
|
136 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] .'/'. $filename);
|
137 |
+
else
|
138 |
+
$xml = @file_get_contents($uploads['path'] .'/'. $filename);
|
139 |
+
}
|
140 |
+
|
141 |
+
} elseif (preg_match('%\W(csv)$%i', trim($path)) or PMXI_Plugin::detect_csv($contents['Content-Type'])) {
|
142 |
+
$uploads = wp_upload_dir();
|
143 |
+
$fdata = file_get_contents($path);
|
144 |
+
$fdata = utf8_encode($fdata);
|
145 |
+
$tmpname = md5(time()).'.csv';
|
146 |
+
file_put_contents($uploads['path'] .'/'. $tmpname, $fdata);
|
147 |
+
$xml = PMXI_Plugin::csv_to_xml($uploads['path'] .'/'. $tmpname);
|
148 |
+
}
|
149 |
+
else
|
150 |
+
{
|
151 |
+
ob_start();
|
152 |
+
readgzfile($path);
|
153 |
+
$xml = ob_get_clean();
|
154 |
+
|
155 |
+
$wp_uploads = wp_upload_dir();
|
156 |
+
$url = $wp_uploads['url'] .'/'. basename($path);
|
157 |
+
file_put_contents($wp_uploads['path'] .'/'. basename($path), $xml);
|
158 |
+
chmod($wp_uploads['path'] .'/'. basename($path), '0755');
|
159 |
+
|
160 |
+
if ($contents = get_headers($url,1 ) and PMXI_Plugin::detect_csv($contents['Content-Type'])) $xml = PMXI_Plugin::csv_to_xml($wp_uploads['path']. basename($path));
|
161 |
+
}
|
162 |
if ( ! $xml) {
|
163 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': file is not accessible or empty');
|
164 |
} elseif ( ! PMXI_Import_Record::validateXml($xml)) {
|
165 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': file is not a properly fromatted XML document');
|
166 |
} else {
|
167 |
+
do_action( 'pmxi_before_xml_import' );
|
168 |
$this->process($xml, $logger);
|
169 |
+
do_action( 'pmxi_after_xml_import' );
|
170 |
}
|
171 |
}
|
172 |
$logger and call_user_func($logger, __('Complete', 'pmxi_plugin'));
|
181 |
* @return PMXI_Import_Record
|
182 |
* @chainable
|
183 |
*/
|
184 |
+
public function process($xml, $logger = NULL) {
|
185 |
add_filter('user_has_cap', array($this, '_filter_has_cap_unfiltered_html')); kses_init(); // do not perform special filtering for imported content
|
186 |
|
187 |
+
$this->options += PMXI_Plugin::get_default_import_options(); // make sure all options are defined
|
188 |
+
|
189 |
+
$history_file = new PMXI_File_Record();
|
190 |
+
$history_file->set(array(
|
191 |
+
'name' => $this->name,
|
192 |
+
'import_id' => $this->id,
|
193 |
+
'path' => $this->path,
|
194 |
+
'contents' => $xml,
|
195 |
+
'registered_on' => date('Y-m-d H:i:s'),
|
196 |
+
))->save();
|
197 |
|
198 |
$postRecord = new PMXI_Post_Record();
|
199 |
|
211 |
}
|
212 |
try {
|
213 |
|
214 |
+
$logger and call_user_func($logger, __('Composing titles...', 'pmxi_plugin'));
|
215 |
+
$titles = XmlImportParser::factory($xml, $this->xpath, $this->template['title'], $file)->parse($records); $tmp_files[] = $file;
|
216 |
+
|
217 |
+
$logger and call_user_func($logger, __('Composing contents...', 'pmxi_plugin'));
|
218 |
$contents = XmlImportParser::factory(
|
219 |
(intval($this->template['is_keep_linebreaks']) ? $xml : preg_replace('%\r\n?|\n%', ' ', $xml)),
|
220 |
$this->xpath,
|
221 |
$this->template['content'],
|
222 |
$file)->parse($records
|
223 |
+
); $tmp_files[] = $file;
|
|
|
|
|
|
|
224 |
|
225 |
+
$logger and call_user_func($logger, __('Composing dates...', 'pmxi_plugin'));
|
226 |
|
227 |
$dates = XmlImportParser::factory($xml, $this->xpath, $this->options['date'], $file)->parse($records); $tmp_files[] = $file;
|
228 |
$warned = array(); // used to prevent the same notice displaying several times
|
234 |
}
|
235 |
$dates[$i] = date('Y-m-d H:i:s', $time);
|
236 |
}
|
237 |
+
|
238 |
if ('post' == $this->options['type']) {
|
239 |
$tags = array();
|
240 |
if ($this->options['tags']) {
|
241 |
+
$logger and call_user_func($logger, __('Composing tags...', 'pmxi_plugin'));
|
242 |
$tags_raw = XmlImportParser::factory($xml, $this->xpath, $this->options['tags'], $file)->parse($records); $tmp_files[] = $file;
|
243 |
foreach ($tags_raw as $i => $t_raw) {
|
244 |
$tags[$i] = '';
|
247 |
} else {
|
248 |
count($titles) and $tags = array_fill(0, count($titles), '');
|
249 |
}
|
250 |
+
|
251 |
$cats = array();
|
252 |
+
|
253 |
+
$categories_hierarchy = (!empty($this->options['categories'])) ? json_decode($this->options['categories']) : array();
|
254 |
+
|
255 |
+
if ((!empty($categories_hierarchy) and is_array($categories_hierarchy))){
|
256 |
+
|
257 |
+
$logger and call_user_func($logger, __('Composing categories...', 'pmxi_plugin'));
|
258 |
+
$categories = array();
|
259 |
+
|
260 |
+
foreach ($categories_hierarchy as $category) $categories[] = $category->xpath;
|
261 |
+
|
262 |
+
$cats_raw = XmlImportParser::factory($xml, $this->xpath, ((!empty($categories)) ? implode(',', $categories) : ''), $file)->parse($records); $tmp_files[] = $file;
|
263 |
$warned = array(); // used to prevent the same notice displaying several times
|
264 |
foreach ($cats_raw as $i => $c_raw) {
|
265 |
$cats[$i] = array();
|
266 |
+
if ('' != $c_raw) foreach (str_getcsv($c_raw, ',') as $j => $c) if ('' != $c) {
|
267 |
$cat = get_term_by('name', $c, 'category') or ctype_digit($c) and $cat = get_term_by('id', $c, 'category');
|
268 |
if ( ! $cat) { // create category automatically
|
269 |
+
if (!empty($categories_hierarchy[$j]->parent_id)) {
|
270 |
+
$parent_id = $this->reverse_hierarchy($categories_hierarchy, $c_raw, $categories_hierarchy[$j]->parent_id, $warned);
|
271 |
+
$cat_id = wp_create_category($c, $parent_id);
|
272 |
+
if ( ! $cat_id) {
|
273 |
+
in_array($c, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create category `%s`, skipping', 'pmxi_plugin'), $warned[] = $c));
|
274 |
+
} else {
|
275 |
+
$cats[$i][] = $cat_id;
|
276 |
+
}
|
277 |
+
}
|
278 |
+
else {
|
279 |
+
$cat_id = wp_create_category($c);
|
280 |
+
if ( ! $cat_id) {
|
281 |
+
in_array($c, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create category `%s`, skipping', 'pmxi_plugin'), $warned[] = $c));
|
282 |
+
} else {
|
283 |
+
$cats[$i][] = $cat_id;
|
284 |
+
}
|
285 |
}
|
286 |
} else {
|
287 |
$cats[$i][] = $cat->term_id;
|
288 |
}
|
289 |
}
|
290 |
+
}
|
291 |
} else {
|
292 |
count($titles) and $cats = array_fill(0, count($titles), '');
|
293 |
+
}
|
294 |
}
|
295 |
// [custom taxonomies]
|
296 |
$taxonomies = array();
|
302 |
} else {
|
303 |
$taxonomies_object_type = 'post';
|
304 |
}
|
305 |
+
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) {
|
306 |
$tx = get_taxonomy($tx_name);
|
307 |
if (in_array($taxonomies_object_type, $tx->object_type)) {
|
308 |
+
$logger and call_user_func($logger, sprintf(__('Composing terms for `%s` taxonomy...', 'pmxi_plugin'), $tx->labels->name));
|
309 |
$txes = array();
|
310 |
+
|
311 |
+
$taxonomies_hierarchy = json_decode($tx_template);
|
312 |
+
foreach ($taxonomies_hierarchy as $taxonomy) $txes[] = $taxonomy->xpath;
|
313 |
+
|
314 |
+
$txes_raw = XmlImportParser::factory($xml, $this->xpath, ((!empty($txes)) ? implode(',', $txes) : ''), $file)->parse($records); $tmp_files[] = $file;
|
315 |
+
$warned = array();
|
316 |
foreach ($txes_raw as $i => $tx_raw) {
|
317 |
+
$taxonomies[$tx_name][$i] = array();
|
318 |
+
if ('' != $tx_raw) foreach (str_getcsv($tx_raw, ',') as $j => $c) if ('' != $c) {
|
319 |
+
$cat = get_term_by('name', $c, $tx_name) or ctype_digit($c) and $cat = get_term_by('id', $c, $tx_name);
|
320 |
+
if ( ! $cat) { // create taxonomy automatically
|
321 |
+
if (!empty($taxonomies_hierarchy[$j]->parent_id)) {
|
322 |
+
$parent_term_id = $this->reverse_hierarchy($taxonomies_hierarchy, $tx_raw, $taxonomies_hierarchy[$j]->parent_id, $warned);
|
323 |
+
|
324 |
+
$term = wp_insert_term(
|
325 |
+
$c, // the term
|
326 |
+
$tx_name, // the taxonomy
|
327 |
+
array(
|
328 |
+
'parent'=> $parent_term_id
|
329 |
+
)
|
330 |
+
);
|
331 |
+
$cat_id = $term['term_id'];
|
332 |
+
if ( ! $cat_id) {
|
333 |
+
in_array($c, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create category `%s`, skipping', 'pmxi_plugin'), $warned[] = $c));
|
334 |
+
} else {
|
335 |
+
$taxonomies[$tx_name][$i][] = $c;
|
336 |
+
}
|
337 |
+
}
|
338 |
+
else {
|
339 |
+
$term = wp_insert_term(
|
340 |
+
$c, // the term
|
341 |
+
$tx_name // the taxonomy
|
342 |
+
);
|
343 |
+
$cat_id = $term['term_id'];
|
344 |
+
if ( ! $cat_id) {
|
345 |
+
in_array($c, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create category `%s`, skipping', 'pmxi_plugin'), $warned[] = $c));
|
346 |
+
} else {
|
347 |
+
$taxonomies[$tx_name][$i][] = $c;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
} else {
|
351 |
+
$taxonomies[$tx_name][$i][] = $cat->name;
|
352 |
+
}
|
353 |
+
}
|
354 |
}
|
355 |
}
|
356 |
+
}; endif;
|
357 |
// [/custom taxonomies]
|
358 |
|
359 |
+
$logger and call_user_func($logger, __('Composing custom parameters...', 'pmxi_plugin'));
|
360 |
$meta_keys = array(); $meta_values = array();
|
361 |
foreach ($this->options['custom_name'] as $j => $custom_name) {
|
362 |
$meta_keys[$j] = XmlImportParser::factory($xml, $this->xpath, $custom_name, $file)->parse($records); $tmp_files[] = $file;
|
363 |
$meta_values[$j] = XmlImportParser::factory($xml, $this->xpath, $this->options['custom_value'][$j], $file)->parse($records); $tmp_files[] = $file;
|
364 |
+
}
|
365 |
+
// serialized custom post fields
|
366 |
+
$serialized_meta = array();
|
367 |
+
if (!empty($meta_keys)){
|
368 |
+
foreach ($meta_keys as $j => $custom_name) {
|
369 |
+
if (!in_array($custom_name[0], array_keys($serialized_meta))){
|
370 |
+
$serialized_meta[$custom_name[0]] = array($meta_values[$j]);
|
371 |
+
}
|
372 |
+
else{
|
373 |
+
$serialized_meta[$custom_name[0]][] = $meta_values[$j];
|
374 |
+
}
|
375 |
+
}
|
376 |
+
}
|
377 |
if ( ! (($uploads = wp_upload_dir()) && false === $uploads['error'])) {
|
378 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $uploads['error']);
|
379 |
$logger and call_user_func($logger, __('<b>WARNING</b>: No featured images will be created', 'pmxi_plugin'));
|
380 |
} else {
|
381 |
+
$logger and call_user_func($logger, __('Composing URLs for featured images...', 'pmxi_plugin'));
|
382 |
$featured_images = array();
|
383 |
if ($this->options['featured_image']) {
|
384 |
// Detect if images is separated by comma
|
385 |
+
$imgs = explode(',',$this->options['featured_image']);
|
386 |
if (!empty($imgs)){
|
387 |
$parse_multiple = true;
|
388 |
+
foreach($imgs as $img) if (!preg_match("/{.*}/", trim($img))) $parse_multiple = false;
|
389 |
+
|
390 |
if ($parse_multiple)
|
391 |
{
|
392 |
foreach($imgs as $img)
|
393 |
+
{
|
394 |
+
$posts_images = XmlImportParser::factory($xml, $this->xpath, trim($img), $file)->parse($records); $tmp_files[] = $file;
|
395 |
+
foreach($posts_images as $i => $val) $featured_images[$i][] = $val;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
}
|
397 |
}
|
398 |
else
|
399 |
{
|
400 |
+
$featured_images = XmlImportParser::factory($xml, $this->xpath, $this->options['featured_image'], $file)->parse($records); $tmp_files[] = $file;
|
401 |
}
|
402 |
}
|
403 |
|
404 |
} else {
|
405 |
count($titles) and $featured_images = array_fill(0, count($titles), '');
|
406 |
}
|
407 |
+
}
|
408 |
+
$logger and call_user_func($logger, __('Composing unique keys...', 'pmxi_plugin'));
|
409 |
$unique_keys = XmlImportParser::factory($xml, $this->xpath, $this->options['unique_key'], $file)->parse($records); $tmp_files[] = $file;
|
410 |
|
411 |
+
$logger and call_user_func($logger, __('Processing posts...', 'pmxi_plugin'));
|
412 |
|
413 |
if ('post' == $this->options['type'] and '' != $this->options['custom_type']) {
|
414 |
$post_type = $this->options['custom_type'];
|
450 |
$post_to_update = get_post($post_to_update_id = $postRecord->post_id);
|
451 |
if ($post_to_update) { // existing post is found
|
452 |
if ($this->options['is_keep_former_posts']) {
|
453 |
+
$current_post_ids[] = $postRecord->post_id;
|
454 |
$logger and call_user_func($logger, sprintf(__('<b>SKIPPED</b>: Previously imported record found for `%s`', 'pmxi_plugin'), $articleData['post_title']));
|
455 |
continue;
|
456 |
}
|
497 |
if ($this->options['is_keep_status']) { // preserve status and trashed flag
|
498 |
$articleData['post_status'] = $post_to_update->post_status;
|
499 |
}
|
500 |
+
if ($this->options['is_keep_content']){ // Re-run an importer to pull in one more custom field... without nuking their edits in the process..
|
501 |
+
$articleData['post_content'] = $post_to_update->post_content;
|
502 |
+
}
|
503 |
} else { // existing post not found though it's track was found... clear the leftover, plugin will continue to treat record as new
|
504 |
$postRecord->delete();
|
505 |
}
|
588 |
if (is_wp_error($pid)) {
|
589 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $pid->get_error_message());
|
590 |
} else {
|
591 |
+
|
592 |
+
do_action( 'pmxi_saved_post', $pid); // hook that was triggered immediately after post saved
|
593 |
+
|
594 |
$current_post_ids[] = $pid;
|
595 |
// associate post with import
|
596 |
$postRecord->isEmpty() and $postRecord->set(array(
|
597 |
'post_id' => $pid,
|
598 |
'import_id' => $this->id,
|
599 |
'unique_key' => $unique_keys[$i],
|
600 |
+
))->insert();
|
601 |
|
602 |
// [custom taxonomies]
|
603 |
foreach ($taxonomies as $tx_name => $txes) {
|
628 |
} catch (XmlImportException $e) {
|
629 |
$logger and call_user_func($logger, __('<b>ERROR</b>', 'pmxi_plugin') . ': ' . $e->getMessage());
|
630 |
}
|
631 |
+
$this->set('registered_on', date('Y-m-d H:i:s'))->save(); // specify execution is successful
|
632 |
|
633 |
+
$logger and call_user_func($logger, __('Cleaning temporary data...', 'pmxi_plugin'));
|
634 |
foreach ($tmp_files as $file) { // remove all temporary files created
|
635 |
unlink($file);
|
636 |
}
|
641 |
$logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to remove %s', 'pmxi_plugin'), $this->path));
|
642 |
}
|
643 |
}
|
644 |
+
$logger and call_user_func($logger, 'Done');
|
645 |
|
646 |
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
|
647 |
|
648 |
return $this;
|
649 |
}
|
650 |
+
|
651 |
+
public function reverse_hierarchy($categories_hierarchy, $c_raw, $parent_id = null, &$warned, $taxonomy = 'category'){
|
652 |
+
foreach (str_getcsv($c_raw, ',') as $j => $c) if ('' != $c and $categories_hierarchy[$j]->item_id == $parent_id) {
|
653 |
+
$cat = get_term_by('name', $c, $taxonomy) or ctype_digit($c) and $cat = get_term_by('id', $c, $taxonomy);
|
654 |
+
if ( ! $cat) { // create category automatically
|
655 |
+
if (!empty($categories_hierarchy[$j]->parent_id)) {
|
656 |
+
return $this->reverse_hierarchy($categories_hierarchy, $c_raw, $categories_hierarchy[$j]->parent_id, $warned, $taxonomy);
|
657 |
+
}
|
658 |
+
else {
|
659 |
+
if ($taxonomy == 'category')
|
660 |
+
{
|
661 |
+
$cat_id = wp_create_category($c);
|
662 |
+
}
|
663 |
+
else{
|
664 |
+
$term = wp_insert_term(
|
665 |
+
$c,
|
666 |
+
$taxonomy
|
667 |
+
);
|
668 |
+
$cat_id = $term['term_id'];
|
669 |
+
}
|
670 |
+
if ( ! $cat_id) {
|
671 |
+
in_array($c, $warned) or $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Unable to create category `%s`, skipping', 'pmxi_plugin'), $warned[] = $c));
|
672 |
+
} else {
|
673 |
+
return $cat_id;
|
674 |
+
}
|
675 |
+
}
|
676 |
+
} else {
|
677 |
+
return $cat->term_id;
|
678 |
+
}
|
679 |
+
}
|
680 |
+
}
|
681 |
|
682 |
public function _filter_has_cap_unfiltered_html($caps)
|
683 |
{
|
plugin.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: WP All Import
|
4 |
Plugin URI: http://www.wpallimport.com/upgrade-to-pro
|
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: 2.
|
7 |
Author: Soflyy
|
8 |
*/
|
9 |
/**
|
3 |
Plugin Name: WP All Import
|
4 |
Plugin URI: http://www.wpallimport.com/upgrade-to-pro
|
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: 2.14
|
7 |
Author: Soflyy
|
8 |
*/
|
9 |
/**
|
readme.txt
CHANGED
@@ -3,9 +3,9 @@ Contributors: soflyy
|
|
3 |
Tags: wordpress, xml, csv, datafeed, import
|
4 |
Requires at least: 3.0
|
5 |
Tested up to: 3.4.2
|
6 |
-
Stable tag: 2.
|
7 |
|
8 |
-
The most powerful tool for importing any CSV or XML feed to WordPress.
|
9 |
|
10 |
== Description ==
|
11 |
|
@@ -65,6 +65,9 @@ Use pretty much any delimiter you want. It has to work with the [fgetcsv](http:/
|
|
65 |
|
66 |
== Changelog ==
|
67 |
|
|
|
|
|
|
|
68 |
= 2.13 =
|
69 |
* Tons of bug fixes, updates, and additional features.
|
70 |
|
3 |
Tags: wordpress, xml, csv, datafeed, import
|
4 |
Requires at least: 3.0
|
5 |
Tested up to: 3.4.2
|
6 |
+
Stable tag: 2.14
|
7 |
|
8 |
+
The most powerful tool for importing any CSV or XML feed to WordPress. --tag
|
9 |
|
10 |
== Description ==
|
11 |
|
65 |
|
66 |
== Changelog ==
|
67 |
|
68 |
+
= 2.14 =
|
69 |
+
* Category list delimiter bug fix
|
70 |
+
|
71 |
= 2.13 =
|
72 |
* Tons of bug fixes, updates, and additional features.
|
73 |
|
schema.php
CHANGED
@@ -48,10 +48,11 @@ CREATE TABLE {$table_prefix}imports (
|
|
48 |
PRIMARY KEY (id)
|
49 |
) $charset_collate;
|
50 |
CREATE TABLE {$table_prefix}posts (
|
|
|
51 |
post_id BIGINT(20) UNSIGNED NOT NULL,
|
52 |
import_id BIGINT(20) UNSIGNED NOT NULL,
|
53 |
unique_key TEXT,
|
54 |
-
PRIMARY KEY (
|
55 |
) $charset_collate;
|
56 |
CREATE TABLE {$table_prefix}files (
|
57 |
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
48 |
PRIMARY KEY (id)
|
49 |
) $charset_collate;
|
50 |
CREATE TABLE {$table_prefix}posts (
|
51 |
+
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
52 |
post_id BIGINT(20) UNSIGNED NOT NULL,
|
53 |
import_id BIGINT(20) UNSIGNED NOT NULL,
|
54 |
unique_key TEXT,
|
55 |
+
PRIMARY KEY (id)
|
56 |
) $charset_collate;
|
57 |
CREATE TABLE {$table_prefix}files (
|
58 |
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
screenshot-1.png
ADDED
Binary file
|
screenshot-2.png
ADDED
Binary file
|
screenshot-3.png
ADDED
Binary file
|
screenshot-4.png
ADDED
Binary file
|
static/css/admin.css
CHANGED
@@ -225,6 +225,8 @@
|
|
225 |
}
|
226 |
.pmxi_plugin .post-type-options table.form-table td.delim {
|
227 |
width: 50px;
|
|
|
|
|
228 |
}
|
229 |
.pmxi_plugin .post-type-options table.form-table td.delim input {
|
230 |
width: 20px;
|
@@ -466,4 +468,37 @@ table.xml table {
|
|
466 |
.pmxi_plugin form.options table.layout td.right{
|
467 |
position: fixed;
|
468 |
width: 25%;
|
469 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
}
|
226 |
.pmxi_plugin .post-type-options table.form-table td.delim {
|
227 |
width: 50px;
|
228 |
+
position: relative;
|
229 |
+
display: block;
|
230 |
}
|
231 |
.pmxi_plugin .post-type-options table.form-table td.delim input {
|
232 |
width: 20px;
|
468 |
.pmxi_plugin form.options table.layout td.right{
|
469 |
position: fixed;
|
470 |
width: 25%;
|
471 |
+
}
|
472 |
+
.pmxi_plugin .drag-element{
|
473 |
+
background: url("../img/drag.png") top right no-repeat;
|
474 |
+
cursor: pointer;
|
475 |
+
padding-right: 25px;
|
476 |
+
background-position: 100% 1px;
|
477 |
+
}
|
478 |
+
.sortable li{ position: relative;}
|
479 |
+
.pmxi_plugin ol{
|
480 |
+
margin-top: 6px;
|
481 |
+
list-style: none;
|
482 |
+
}
|
483 |
+
.pmxi_plugin .no-margin{ margin:0px; }
|
484 |
+
.pmxi_plugin .icon-item{
|
485 |
+
display: inline-block;;
|
486 |
+
width: 16px;
|
487 |
+
height: 16px;
|
488 |
+
margin: 0px 3px;
|
489 |
+
}
|
490 |
+
.pmxi_plugin .add-new-ico{
|
491 |
+
background: url("../img/ico-add-new.png") no-repeat;
|
492 |
+
position: absolute;
|
493 |
+
top:5px;
|
494 |
+
right: 0px;
|
495 |
+
}
|
496 |
+
|
497 |
+
.pmxi_plugin .remove-ico{
|
498 |
+
background: url("../img/ico-remove.png") no-repeat;
|
499 |
+
top:1px;
|
500 |
+
right:-30px;
|
501 |
+
position: absolute;
|
502 |
+
}
|
503 |
+
|
504 |
+
.pmxi_plugin .hidden{ display: none; }
|
static/img/drag.png
ADDED
Binary file
|
static/img/ico-add-new.png
ADDED
Binary file
|
static/img/ico-remove.png
ADDED
Binary file
|
static/js/admin.js
CHANGED
@@ -109,7 +109,7 @@
|
|
109 |
// choose file form: option selection dynamic
|
110 |
// options form: highlight options of selected post type
|
111 |
$('form.choose-file input[name="type"]').click(function() {
|
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();
|
@@ -171,6 +171,16 @@
|
|
171 |
'value':''
|
172 |
};
|
173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
// [xml representation dynamic]
|
175 |
$.fn.xml = function (opt) {
|
176 |
if ( ! this.length) return this;
|
@@ -255,16 +265,7 @@
|
|
255 |
$('.xml-element[title*="/'+$(this).val().replace('{','').replace('}','')+'"]').addClass('selected');
|
256 |
}
|
257 |
});
|
258 |
-
|
259 |
-
var insertxpath = function(){
|
260 |
-
if (dblclickbuf.selected)
|
261 |
-
{
|
262 |
-
$(this).val($(this).val() + dblclickbuf.value);
|
263 |
-
$('.xml-element[title*="/'+dblclickbuf.value.replace('{','').replace('}','')+'"]').removeClass('selected');
|
264 |
-
dblclickbuf.value = '';
|
265 |
-
dblclickbuf.selected = false;
|
266 |
-
}
|
267 |
-
}
|
268 |
$('#title, #content, .widefat, input[name^=custom_name], textarea[name^=custom_value], input[name^=featured_image], input[name^=unique_key]').bind('focus', insertxpath );
|
269 |
|
270 |
$(document).mousemove(function () {
|
@@ -357,65 +358,43 @@
|
|
357 |
});
|
358 |
});
|
359 |
|
360 |
-
|
361 |
-
$('input[name=is_first_chank],input[name=is_update_previous]').remove();
|
362 |
-
$("form").append('<input type="hidden" name="is_first_chank" value="'+((first_chank) ? 1 : 0)+'"/>');
|
363 |
-
$("form").append('<input type="hidden" name="is_update_previous" value="'+update_previous+'"/>');
|
364 |
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
$(window).scrollTop($(document).height());
|
375 |
-
process(false, data.update_previous);
|
376 |
-
break;
|
377 |
-
case 'stop':
|
378 |
-
$('form.options').remove();
|
379 |
-
var import_stats = '';
|
380 |
-
import_stats = '<p><b> Import started at</b> ' + data.start_time + '</p>';
|
381 |
-
import_stats += '<p><b> Import ended at</b> ' + data.end_time + '</p>';
|
382 |
-
import_stats += '<p><b> Import time</b> ' + data.import_time + '</p>';
|
383 |
-
$('.wrap').append(data.log + import_stats);
|
384 |
-
break;
|
385 |
-
}
|
386 |
-
},
|
387 |
-
error: function(request, status, error){
|
388 |
-
$('form.options').hide();
|
389 |
-
var error = "<script type='text/javascript'>(function($){$('#status').html('Error');window.onbeforeunload = false;})(jQuery);</script>";
|
390 |
-
if (request.responseText.indexOf('options') === -1) $('.wrap').append(error + request.responseText); else $('form.options').append(error).submit();
|
391 |
-
},
|
392 |
-
dataType: "json"
|
393 |
-
});
|
394 |
-
}
|
395 |
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
$this.html(status + '...'.substr(0, dots++ % 3 + 1));
|
409 |
-
} else {
|
410 |
-
clearInterval(interval);
|
411 |
-
}
|
412 |
-
}, 1000);
|
413 |
-
}
|
414 |
});
|
415 |
-
window.
|
416 |
-
|
417 |
-
};
|
418 |
-
process(true, 0);
|
419 |
});
|
420 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
});})(jQuery);
|
109 |
// choose file form: option selection dynamic
|
110 |
// options form: highlight options of selected post type
|
111 |
$('form.choose-file input[name="type"]').click(function() {
|
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();
|
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;
|
265 |
$('.xml-element[title*="/'+$(this).val().replace('{','').replace('}','')+'"]').addClass('selected');
|
266 |
}
|
267 |
});
|
268 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
$('#title, #content, .widefat, input[name^=custom_name], textarea[name^=custom_value], input[name^=featured_image], input[name^=unique_key]').bind('focus', insertxpath );
|
270 |
|
271 |
$(document).mousemove(function () {
|
358 |
});
|
359 |
});
|
360 |
|
361 |
+
/* Categories hierarchy */
|
|
|
|
|
|
|
362 |
|
363 |
+
$('.sortable').nestedSortable({
|
364 |
+
handle: 'div',
|
365 |
+
items: 'li',
|
366 |
+
toleranceElement: '> div',
|
367 |
+
update: function () {
|
368 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).nestedSortable('toArray', {startDepthCount: 0})));
|
369 |
+
if ($('.drag-element:first').find('input').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
370 |
+
}
|
371 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
372 |
|
373 |
+
$('.drag-element').find('input').live('blur', function(){
|
374 |
+
$(this).parents('td:first').find('.hierarhy-output').val(window.JSON.stringify($(this).parents('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
375 |
+
if ($('.drag-element:first').find('input').val() == '') $(this).parents('td:first').find('.hierarhy-output').val('');
|
376 |
+
});
|
377 |
+
|
378 |
+
$('.sortable').find('.remove-ico').live('click', function(){
|
379 |
+
|
380 |
+
var parent_td = $(this).parents('td:first');
|
381 |
+
|
382 |
+
$(this).parents('li:first').remove();
|
383 |
+
parent_td.find('ol.sortable:first').find('li').each(function(i, e){
|
384 |
+
$(this).attr({'id':'item_'+ (i+1)});
|
|
|
|
|
|
|
|
|
|
|
|
|
385 |
});
|
386 |
+
parent_td.find('.hierarhy-output').val(window.JSON.stringify(parent_td.find('.sortable:first').nestedSortable('toArray', {startDepthCount: 0})));
|
387 |
+
if ($('.drag-element:first').find('input').val() == '') parent_td.find('.hierarhy-output').val('');
|
|
|
|
|
388 |
});
|
389 |
|
390 |
+
$('.add-new-ico').click(function(){
|
391 |
+
var count = $(this).parents('tr:first').find('ol.sortable').find('li').length + 1;
|
392 |
+
$(this).parents('tr:first').find('ol.sortable').append('<li id="item_'+count+'"><div class="drag-element"><input type="text" value="" class="widefat"></div><a class="icon-item remove-ico" href="javascript:void(0);"></a></li>');
|
393 |
+
$('.widefat').bind('focus', insertxpath );
|
394 |
+
});
|
395 |
+
|
396 |
+
/* END Categories hierarchy */
|
397 |
+
|
398 |
+
|
399 |
+
|
400 |
});})(jQuery);
|
static/js/jquery/jquery.mjs.nestedSortable.js
ADDED
@@ -0,0 +1,426 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
* jQuery UI Nested Sortable
|
3 |
+
* v 1.3.5 / 21 jun 2012
|
4 |
+
* http://mjsarfatti.com/code/nestedSortable
|
5 |
+
*
|
6 |
+
* Depends on:
|
7 |
+
* jquery.ui.sortable.js 1.8+
|
8 |
+
*
|
9 |
+
* Copyright (c) 2010-2012 Manuele J Sarfatti
|
10 |
+
* Licensed under the MIT License
|
11 |
+
* http://www.opensource.org/licenses/mit-license.php
|
12 |
+
*/
|
13 |
+
|
14 |
+
(function($) {
|
15 |
+
|
16 |
+
$.widget("mjs.nestedSortable", $.extend({}, $.ui.sortable.prototype, {
|
17 |
+
|
18 |
+
options: {
|
19 |
+
tabSize: 20,
|
20 |
+
disableNesting: 'mjs-nestedSortable-no-nesting',
|
21 |
+
errorClass: 'mjs-nestedSortable-error',
|
22 |
+
listType: 'ol',
|
23 |
+
maxLevels: 0,
|
24 |
+
protectRoot: false,
|
25 |
+
rootID: null,
|
26 |
+
rtl: false,
|
27 |
+
isAllowed: function(item, parent) { return true; }
|
28 |
+
},
|
29 |
+
|
30 |
+
_create: function() {
|
31 |
+
this.element.data('sortable', this.element.data('nestedSortable'));
|
32 |
+
|
33 |
+
if (!this.element.is(this.options.listType))
|
34 |
+
throw new Error('nestedSortable: Please check the listType option is set to your actual list type');
|
35 |
+
|
36 |
+
return $.ui.sortable.prototype._create.apply(this, arguments);
|
37 |
+
},
|
38 |
+
|
39 |
+
destroy: function() {
|
40 |
+
this.element
|
41 |
+
.removeData("nestedSortable")
|
42 |
+
.unbind(".nestedSortable");
|
43 |
+
return $.ui.sortable.prototype.destroy.apply(this, arguments);
|
44 |
+
},
|
45 |
+
|
46 |
+
_mouseDrag: function(event) {
|
47 |
+
|
48 |
+
//Compute the helpers position
|
49 |
+
this.position = this._generatePosition(event);
|
50 |
+
this.positionAbs = this._convertPositionTo("absolute");
|
51 |
+
|
52 |
+
if (!this.lastPositionAbs) {
|
53 |
+
this.lastPositionAbs = this.positionAbs;
|
54 |
+
}
|
55 |
+
|
56 |
+
//Do scrolling
|
57 |
+
if(this.options.scroll) {
|
58 |
+
var o = this.options, scrolled = false;
|
59 |
+
if(this.scrollParent[0] != document && this.scrollParent[0].tagName != 'HTML') {
|
60 |
+
|
61 |
+
if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)
|
62 |
+
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
|
63 |
+
else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity)
|
64 |
+
this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
|
65 |
+
|
66 |
+
if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)
|
67 |
+
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
|
68 |
+
else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity)
|
69 |
+
this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
|
70 |
+
|
71 |
+
} else {
|
72 |
+
|
73 |
+
if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)
|
74 |
+
scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
|
75 |
+
else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)
|
76 |
+
scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
|
77 |
+
|
78 |
+
if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)
|
79 |
+
scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
|
80 |
+
else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)
|
81 |
+
scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
|
82 |
+
|
83 |
+
}
|
84 |
+
|
85 |
+
if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)
|
86 |
+
$.ui.ddmanager.prepareOffsets(this, event);
|
87 |
+
}
|
88 |
+
|
89 |
+
//Regenerate the absolute position used for position checks
|
90 |
+
this.positionAbs = this._convertPositionTo("absolute");
|
91 |
+
|
92 |
+
// Find the top offset before rearrangement,
|
93 |
+
var previousTopOffset = this.placeholder.offset().top;
|
94 |
+
|
95 |
+
//Set the helper position
|
96 |
+
if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
|
97 |
+
if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';
|
98 |
+
|
99 |
+
//Rearrange
|
100 |
+
for (var i = this.items.length - 1; i >= 0; i--) {
|
101 |
+
|
102 |
+
//Cache variables and intersection, continue if no intersection
|
103 |
+
var item = this.items[i], itemElement = item.item[0], intersection = this._intersectsWithPointer(item);
|
104 |
+
if (!intersection) continue;
|
105 |
+
|
106 |
+
if(itemElement != this.currentItem[0] //cannot intersect with itself
|
107 |
+
&& this.placeholder[intersection == 1 ? "next" : "prev"]()[0] != itemElement //no useless actions that have been done before
|
108 |
+
&& !$.contains(this.placeholder[0], itemElement) //no action if the item moved is the parent of the item checked
|
109 |
+
&& (this.options.type == 'semi-dynamic' ? !$.contains(this.element[0], itemElement) : true)
|
110 |
+
//&& itemElement.parentNode == this.placeholder[0].parentNode // only rearrange items within the same container
|
111 |
+
) {
|
112 |
+
|
113 |
+
$(itemElement).mouseenter();
|
114 |
+
|
115 |
+
this.direction = intersection == 1 ? "down" : "up";
|
116 |
+
|
117 |
+
if (this.options.tolerance == "pointer" || this._intersectsWithSides(item)) {
|
118 |
+
$(itemElement).mouseleave();
|
119 |
+
this._rearrange(event, item);
|
120 |
+
} else {
|
121 |
+
break;
|
122 |
+
}
|
123 |
+
|
124 |
+
// Clear emtpy ul's/ol's
|
125 |
+
this._clearEmpty(itemElement);
|
126 |
+
|
127 |
+
this._trigger("change", event, this._uiHash());
|
128 |
+
break;
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
var parentItem = (this.placeholder[0].parentNode.parentNode &&
|
133 |
+
$(this.placeholder[0].parentNode.parentNode).closest('.ui-sortable').length)
|
134 |
+
? $(this.placeholder[0].parentNode.parentNode)
|
135 |
+
: null,
|
136 |
+
level = this._getLevel(this.placeholder),
|
137 |
+
childLevels = this._getChildLevels(this.helper);
|
138 |
+
|
139 |
+
// To find the previous sibling in the list, keep backtracking until we hit a valid list item.
|
140 |
+
var previousItem = this.placeholder[0].previousSibling ? $(this.placeholder[0].previousSibling) : null;
|
141 |
+
if (previousItem != null) {
|
142 |
+
while (previousItem[0].nodeName.toLowerCase() != 'li' || previousItem[0] == this.currentItem[0] || previousItem[0] == this.helper[0]) {
|
143 |
+
if (previousItem[0].previousSibling) {
|
144 |
+
previousItem = $(previousItem[0].previousSibling);
|
145 |
+
} else {
|
146 |
+
previousItem = null;
|
147 |
+
break;
|
148 |
+
}
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
// To find the next sibling in the list, keep stepping forward until we hit a valid list item.
|
153 |
+
var nextItem = this.placeholder[0].nextSibling ? $(this.placeholder[0].nextSibling) : null;
|
154 |
+
if (nextItem != null) {
|
155 |
+
while (nextItem[0].nodeName.toLowerCase() != 'li' || nextItem[0] == this.currentItem[0] || nextItem[0] == this.helper[0]) {
|
156 |
+
if (nextItem[0].nextSibling) {
|
157 |
+
nextItem = $(nextItem[0].nextSibling);
|
158 |
+
} else {
|
159 |
+
nextItem = null;
|
160 |
+
break;
|
161 |
+
}
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
var newList = document.createElement(o.listType);
|
166 |
+
|
167 |
+
this.beyondMaxLevels = 0;
|
168 |
+
|
169 |
+
// If the item is moved to the left, send it to its parent's level unless there are siblings below it.
|
170 |
+
if (parentItem != null && nextItem == null &&
|
171 |
+
(o.rtl && (this.positionAbs.left + this.helper.outerWidth() > parentItem.offset().left + parentItem.outerWidth()) ||
|
172 |
+
!o.rtl && (this.positionAbs.left < parentItem.offset().left))) {
|
173 |
+
parentItem.after(this.placeholder[0]);
|
174 |
+
this._clearEmpty(parentItem[0]);
|
175 |
+
this._trigger("change", event, this._uiHash());
|
176 |
+
}
|
177 |
+
// If the item is below a sibling and is moved to the right, make it a child of that sibling.
|
178 |
+
else if (previousItem != null &&
|
179 |
+
(o.rtl && (this.positionAbs.left + this.helper.outerWidth() < previousItem.offset().left + previousItem.outerWidth() - o.tabSize) ||
|
180 |
+
!o.rtl && (this.positionAbs.left > previousItem.offset().left + o.tabSize))) {
|
181 |
+
this._isAllowed(previousItem, level, level+childLevels+1);
|
182 |
+
if (!previousItem.children(o.listType).length) {
|
183 |
+
previousItem[0].appendChild(newList);
|
184 |
+
}
|
185 |
+
// If this item is being moved from the top, add it to the top of the list.
|
186 |
+
if (previousTopOffset && (previousTopOffset <= previousItem.offset().top)) {
|
187 |
+
previousItem.children(o.listType).prepend(this.placeholder);
|
188 |
+
}
|
189 |
+
// Otherwise, add it to the bottom of the list.
|
190 |
+
else {
|
191 |
+
previousItem.children(o.listType)[0].appendChild(this.placeholder[0]);
|
192 |
+
}
|
193 |
+
this._trigger("change", event, this._uiHash());
|
194 |
+
}
|
195 |
+
else {
|
196 |
+
this._isAllowed(parentItem, level, level+childLevels);
|
197 |
+
}
|
198 |
+
|
199 |
+
//Post events to containers
|
200 |
+
this._contactContainers(event);
|
201 |
+
|
202 |
+
//Interconnect with droppables
|
203 |
+
if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);
|
204 |
+
|
205 |
+
//Call callbacks
|
206 |
+
this._trigger('sort', event, this._uiHash());
|
207 |
+
|
208 |
+
this.lastPositionAbs = this.positionAbs;
|
209 |
+
return false;
|
210 |
+
|
211 |
+
},
|
212 |
+
|
213 |
+
_mouseStop: function(event, noPropagation) {
|
214 |
+
|
215 |
+
// If the item is in a position not allowed, send it back
|
216 |
+
if (this.beyondMaxLevels) {
|
217 |
+
|
218 |
+
this.placeholder.removeClass(this.options.errorClass);
|
219 |
+
|
220 |
+
if (this.domPosition.prev) {
|
221 |
+
$(this.domPosition.prev).after(this.placeholder);
|
222 |
+
} else {
|
223 |
+
$(this.domPosition.parent).prepend(this.placeholder);
|
224 |
+
}
|
225 |
+
|
226 |
+
this._trigger("revert", event, this._uiHash());
|
227 |
+
|
228 |
+
}
|
229 |
+
|
230 |
+
// Clean last empty ul/ol
|
231 |
+
for (var i = this.items.length - 1; i >= 0; i--) {
|
232 |
+
var item = this.items[i].item[0];
|
233 |
+
this._clearEmpty(item);
|
234 |
+
}
|
235 |
+
|
236 |
+
$.ui.sortable.prototype._mouseStop.apply(this, arguments);
|
237 |
+
|
238 |
+
},
|
239 |
+
|
240 |
+
serialize: function(options) {
|
241 |
+
|
242 |
+
var o = $.extend({}, this.options, options),
|
243 |
+
items = this._getItemsAsjQuery(o && o.connected),
|
244 |
+
str = [];
|
245 |
+
|
246 |
+
$(items).each(function() {
|
247 |
+
var res = ($(o.item || this).attr(o.attribute || 'id') || '')
|
248 |
+
.match(o.expression || (/(.+)[-=_](.+)/)),
|
249 |
+
pid = ($(o.item || this).parent(o.listType)
|
250 |
+
.parent(o.items)
|
251 |
+
.attr(o.attribute || 'id') || '')
|
252 |
+
.match(o.expression || (/(.+)[-=_](.+)/));
|
253 |
+
|
254 |
+
if (res) {
|
255 |
+
str.push(((o.key || res[1]) + '[' + (o.key && o.expression ? res[1] : res[2]) + ']')
|
256 |
+
+ '='
|
257 |
+
+ (pid ? (o.key && o.expression ? pid[1] : pid[2]) : o.rootID));
|
258 |
+
}
|
259 |
+
});
|
260 |
+
|
261 |
+
if(!str.length && o.key) {
|
262 |
+
str.push(o.key + '=');
|
263 |
+
}
|
264 |
+
|
265 |
+
return str.join('&');
|
266 |
+
|
267 |
+
},
|
268 |
+
|
269 |
+
toHierarchy: function(options) {
|
270 |
+
|
271 |
+
var o = $.extend({}, this.options, options),
|
272 |
+
sDepth = o.startDepthCount || 0,
|
273 |
+
ret = [];
|
274 |
+
|
275 |
+
$(this.element).children(o.items).each(function () {
|
276 |
+
var level = _recursiveItems(this);
|
277 |
+
ret.push(level);
|
278 |
+
});
|
279 |
+
|
280 |
+
return ret;
|
281 |
+
|
282 |
+
function _recursiveItems(item) {
|
283 |
+
var id = ($(item).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
|
284 |
+
if (id) {
|
285 |
+
var currentItem = {"id" : id[2]};
|
286 |
+
if ($(item).children(o.listType).children(o.items).length > 0) {
|
287 |
+
currentItem.children = [];
|
288 |
+
$(item).children(o.listType).children(o.items).each(function() {
|
289 |
+
var level = _recursiveItems(this);
|
290 |
+
currentItem.children.push(level);
|
291 |
+
});
|
292 |
+
}
|
293 |
+
return currentItem;
|
294 |
+
}
|
295 |
+
}
|
296 |
+
},
|
297 |
+
|
298 |
+
toArray: function(options) {
|
299 |
+
|
300 |
+
var o = $.extend({}, this.options, options),
|
301 |
+
sDepth = o.startDepthCount || 0,
|
302 |
+
ret = [],
|
303 |
+
left = 2;
|
304 |
+
|
305 |
+
/*ret.push({
|
306 |
+
"item_id": o.rootID,
|
307 |
+
"parent_id": 'none',
|
308 |
+
"depth": sDepth,
|
309 |
+
"left": '1',
|
310 |
+
"right": ($(o.items, this.element).length + 1) * 2
|
311 |
+
});*/
|
312 |
+
|
313 |
+
$(this.element).children(o.items).each(function () {
|
314 |
+
left = _recursiveArray(this, sDepth + 1, left);
|
315 |
+
});
|
316 |
+
|
317 |
+
ret = ret.sort(function(a,b){ return (a.left - b.left); });
|
318 |
+
|
319 |
+
return ret;
|
320 |
+
|
321 |
+
function _recursiveArray(item, depth, left) {
|
322 |
+
|
323 |
+
var right = left + 1,
|
324 |
+
id,
|
325 |
+
pid;
|
326 |
+
|
327 |
+
if ($(item).children(o.listType).children(o.items).length > 0) {
|
328 |
+
depth ++;
|
329 |
+
$(item).children(o.listType).children(o.items).each(function () {
|
330 |
+
right = _recursiveArray($(this), depth, right);
|
331 |
+
});
|
332 |
+
depth --;
|
333 |
+
}
|
334 |
+
|
335 |
+
id = ($(item).attr(o.attribute || 'id')).match(o.expression || (/(.+)[-=_](.+)/));
|
336 |
+
|
337 |
+
if (depth === sDepth + 1) {
|
338 |
+
pid = o.rootID;
|
339 |
+
} else {
|
340 |
+
var parentItem = ($(item).parent(o.listType)
|
341 |
+
.parent(o.items)
|
342 |
+
.attr(o.attribute || 'id'))
|
343 |
+
.match(o.expression || (/(.+)[-=_](.+)/));
|
344 |
+
pid = parentItem[2];
|
345 |
+
}
|
346 |
+
|
347 |
+
if (id) {
|
348 |
+
ret.push({"item_id": id[2], "parent_id": pid, "depth": depth, "left": left, "right": right, "xpath":$(item).find('input').val()});
|
349 |
+
}
|
350 |
+
|
351 |
+
left = right + 1;
|
352 |
+
return left;
|
353 |
+
}
|
354 |
+
|
355 |
+
},
|
356 |
+
|
357 |
+
_clearEmpty: function(item) {
|
358 |
+
|
359 |
+
var emptyList = $(item).children(this.options.listType);
|
360 |
+
if (emptyList.length && !emptyList.children().length) {
|
361 |
+
emptyList.remove();
|
362 |
+
}
|
363 |
+
|
364 |
+
},
|
365 |
+
|
366 |
+
_getLevel: function(item) {
|
367 |
+
|
368 |
+
var level = 1;
|
369 |
+
|
370 |
+
if (this.options.listType) {
|
371 |
+
var list = item.closest(this.options.listType);
|
372 |
+
while (list && list.length > 0 &&
|
373 |
+
!list.is('.ui-sortable')) {
|
374 |
+
level++;
|
375 |
+
list = list.parent().closest(this.options.listType);
|
376 |
+
}
|
377 |
+
}
|
378 |
+
|
379 |
+
return level;
|
380 |
+
},
|
381 |
+
|
382 |
+
_getChildLevels: function(parent, depth) {
|
383 |
+
var self = this,
|
384 |
+
o = this.options,
|
385 |
+
result = 0;
|
386 |
+
depth = depth || 0;
|
387 |
+
|
388 |
+
$(parent).children(o.listType).children(o.items).each(function (index, child) {
|
389 |
+
result = Math.max(self._getChildLevels(child, depth + 1), result);
|
390 |
+
});
|
391 |
+
|
392 |
+
return depth ? result + 1 : result;
|
393 |
+
},
|
394 |
+
|
395 |
+
_isAllowed: function(parentItem, level, levels) {
|
396 |
+
var o = this.options,
|
397 |
+
isRoot = $(this.domPosition.parent).hasClass('ui-sortable') ? true : false,
|
398 |
+
maxLevels = this.placeholder.closest('.ui-sortable').nestedSortable('option', 'maxLevels'); // this takes into account the maxLevels set to the recipient list
|
399 |
+
|
400 |
+
// Is the root protected?
|
401 |
+
// Are we trying to nest under a no-nest?
|
402 |
+
// Are we nesting too deep?
|
403 |
+
if (!o.isAllowed(parentItem, this.placeholder) ||
|
404 |
+
parentItem && parentItem.hasClass(o.disableNesting) ||
|
405 |
+
o.protectRoot && (parentItem == null && !isRoot || isRoot && level > 1)) {
|
406 |
+
this.placeholder.addClass(o.errorClass);
|
407 |
+
if (maxLevels < levels && maxLevels != 0) {
|
408 |
+
this.beyondMaxLevels = levels - maxLevels;
|
409 |
+
} else {
|
410 |
+
this.beyondMaxLevels = 1;
|
411 |
+
}
|
412 |
+
} else {
|
413 |
+
if (maxLevels < levels && maxLevels != 0) {
|
414 |
+
this.placeholder.addClass(o.errorClass);
|
415 |
+
this.beyondMaxLevels = levels - maxLevels;
|
416 |
+
} else {
|
417 |
+
this.placeholder.removeClass(o.errorClass);
|
418 |
+
this.beyondMaxLevels = 0;
|
419 |
+
}
|
420 |
+
}
|
421 |
+
}
|
422 |
+
|
423 |
+
}));
|
424 |
+
|
425 |
+
$.mjs.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.mjs.nestedSortable.prototype.options);
|
426 |
+
})(jQuery);
|
views/admin/import/index.php
CHANGED
@@ -39,6 +39,7 @@
|
|
39 |
<div class="file-type-options">
|
40 |
<input type="text" class="regular-text" name="ftp[url]" value="<?php echo esc_attr($post['ftp']['url']) ?>" /><br />
|
41 |
<input type="text" name="ftp[user]" title="username" /><strong>:</strong><input type="password" name="ftp[pass]" title="passowrd" />
|
|
|
42 |
</div>
|
43 |
</div>
|
44 |
<div class="file-type-container">
|
@@ -96,7 +97,7 @@
|
|
96 |
</p>
|
97 |
</div>
|
98 |
<br />
|
99 |
-
<table><tr><td class="note"
|
100 |
</form>
|
101 |
</td>
|
102 |
<td class="right">
|
39 |
<div class="file-type-options">
|
40 |
<input type="text" class="regular-text" name="ftp[url]" value="<?php echo esc_attr($post['ftp']['url']) ?>" /><br />
|
41 |
<input type="text" name="ftp[user]" title="username" /><strong>:</strong><input type="password" name="ftp[pass]" title="passowrd" />
|
42 |
+
<div class="note"><b>*</b> <?php _e('These options support shell wildcard patterns<a href="#help" class="help" title="A shell wildcard pattern is a string used by *nix systems for referencing several files at once. The most common case is using asterisk symbol in the place of any set of characters, e.g. `*.xml` would correspond to any file with `xml` extension.">?</a> which enables linking several XML files to the same import. The option is useful when the exact source path is not known upfront or is going to change, e.g. some content providers submit XML files each time with a new name.', 'pmxi_plugin') ?></div>
|
43 |
</div>
|
44 |
</div>
|
45 |
<div class="file-type-container">
|
97 |
</p>
|
98 |
</div>
|
99 |
<br />
|
100 |
+
<table><tr><td class="note"></td></tr></table>
|
101 |
</form>
|
102 |
</td>
|
103 |
<td class="right">
|
views/admin/import/options.php
CHANGED
@@ -1,3 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
2 |
<table class="layout">
|
3 |
<tr>
|
@@ -30,13 +56,37 @@
|
|
30 |
<label for="type_post"><?php _e('Create Posts', 'pmxi_plugin') ?></label>
|
31 |
</h3>
|
32 |
<div class="post-type-options">
|
33 |
-
<table class="form-table">
|
34 |
-
|
35 |
-
<th><?php _e('Categories', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter Category IDs or Names
|
36 |
-
<td
|
37 |
-
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
</td>
|
41 |
</tr>
|
42 |
<tr>
|
@@ -53,14 +103,36 @@
|
|
53 |
<?php $post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array('post'), 'object'), array_flip(array('category', 'post_tag', 'post_format'))) ?>
|
54 |
<?php foreach ($post_taxonomies as $ctx): ?>
|
55 |
<tr class="post_taxonomy" data-type="<?php echo implode(' ', $ctx->object_type) ?>">
|
56 |
-
<th><nobr><?php echo $ctx->labels->name ?> <a href="#help" class="help" title="<?php _e('Enter
|
57 |
-
<td
|
58 |
-
|
59 |
-
|
60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
</td>
|
62 |
</tr>
|
63 |
-
<?php endforeach ?>
|
64 |
</table>
|
65 |
</div>
|
66 |
</div>
|
@@ -93,11 +165,32 @@
|
|
93 |
<?php $page_taxonomies = get_taxonomies_by_object_type('page', 'object') ?>
|
94 |
<?php foreach ($page_taxonomies as $ctx): ?>
|
95 |
<tr class="page_taxonomy" data-type="<?php echo implode(' ', $ctx->object_type) ?>">
|
96 |
-
<th><nobr><?php echo $ctx->labels->name ?> <a href="#help" class="help" title="<?php _e('Enter
|
97 |
-
<td
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
<td class="delim">
|
99 |
-
<
|
100 |
-
<a href="#help" class="help" title="<?php _e('
|
101 |
</td>
|
102 |
</tr>
|
103 |
<?php endforeach ?>
|
@@ -250,6 +343,12 @@
|
|
250 |
<label for="is_keep_status"><?php _e('Keep status', 'pmxi_plugin') ?></label>
|
251 |
<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>
|
252 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
253 |
<div>
|
254 |
<input type="hidden" name="is_keep_categories" value="0" />
|
255 |
<input type="checkbox" id="is_keep_categories" name="is_keep_categories" value="1" <?php echo $post['is_keep_categories'] ? 'checked="checked"': '' ?> />
|
@@ -294,9 +393,6 @@
|
|
294 |
</tr>
|
295 |
</table>
|
296 |
</form>
|
297 |
-
<div id="process" style="display:none;">
|
298 |
-
<?php include PMXI_Plugin::ROOT_DIR . '/views/admin/import/process.php'; ?>
|
299 |
-
</div>
|
300 |
<script type="text/javascript">
|
301 |
(function($){$(function(){
|
302 |
$('select[name="custom_type"]').change(function () {
|
1 |
+
<?php
|
2 |
+
if (!function_exists('reverse_taxonomies_html')) {
|
3 |
+
function reverse_taxonomies_html($post_taxonomies, $item_id, $i){
|
4 |
+
$childs = array();
|
5 |
+
foreach ($post_taxonomies as $j => $cat) if ($cat->parent_id == $item_id) { $childs[] = $cat; }
|
6 |
+
|
7 |
+
if (!empty($childs)){
|
8 |
+
?>
|
9 |
+
<ol>
|
10 |
+
<?php
|
11 |
+
foreach ($childs as $child_cat){
|
12 |
+
$i++;
|
13 |
+
?>
|
14 |
+
<li id="item_<?php echo $i; ?>">
|
15 |
+
<div class="drag-element"><input class="widefat" type="text" value="<?php echo $child_cat->xpath; ?>"/></div><a href="javascript:void(0);" class="icon-item remove-ico"></a>
|
16 |
+
<?php echo reverse_taxonomies_html($post_taxonomies, $child_cat->item_id, $i); ?>
|
17 |
+
</li>
|
18 |
+
<?php
|
19 |
+
}
|
20 |
+
?>
|
21 |
+
</ol>
|
22 |
+
<?php
|
23 |
+
}
|
24 |
+
}
|
25 |
+
}
|
26 |
+
?>
|
27 |
<form class="options <?php echo ! $this->isWizard ? 'edit' : '' ?>" method="post">
|
28 |
<table class="layout">
|
29 |
<tr>
|
56 |
<label for="type_post"><?php _e('Create Posts', 'pmxi_plugin') ?></label>
|
57 |
</h3>
|
58 |
<div class="post-type-options">
|
59 |
+
<table class="form-table">
|
60 |
+
<tr>
|
61 |
+
<th><?php _e('Categories', 'pmxi_plugin') ?> <a href="#help" class="help" title="<?php _e('Enter Category IDs or Names.', 'pmxi_plugin') ?>">?</a></th>
|
62 |
+
<td>
|
63 |
+
<ol class="sortable no-margin">
|
64 |
+
<?php if (!empty($post['categories'])):?>
|
65 |
+
<?php
|
66 |
+
$categories = json_decode($post['categories']);
|
67 |
+
if (!empty($categories) and is_array($categories)): foreach ($categories as $i => $cat) {
|
68 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
69 |
+
{
|
70 |
+
?>
|
71 |
+
<li id="item_<?php echo ($i+1); ?>">
|
72 |
+
<div class="drag-element"><input type="text" class="widefat" value="<?php echo $cat->xpath; ?>"/></div>
|
73 |
+
<?php echo reverse_taxonomies_html($categories, $cat->item_id, ($i+1)); ?>
|
74 |
+
</li>
|
75 |
+
<?php
|
76 |
+
}
|
77 |
+
}; else: ?>
|
78 |
+
<li id="item_1"><div class="drag-element"><input type="text" class="widefat" value=""/></div></li>
|
79 |
+
<?php endif;?>
|
80 |
+
<?php else: ?>
|
81 |
+
<li id="item_1"><div class="drag-element"><input type="text" class="widefat" value=""/></div></li>
|
82 |
+
<?php endif; ?>
|
83 |
+
</ol>
|
84 |
+
<input type="hidden" class="hierarhy-output" name="categories" value="<?php echo esc_attr($post['categories']) ?>"/>
|
85 |
+
<div class="hidden" id="dialog-confirm-category-removing" title="Delete categories?">Remove only current category or current category with subcategories?</div>
|
86 |
+
</td>
|
87 |
+
<td class="delim">
|
88 |
+
<a href="javascript:void(0);" class="icon-item add-new-ico"></a>
|
89 |
+
<a href="#help" class="help" title="<?php _e('Drag&Drop inputs to create categories hierarchy', 'pmxi_plugin') ?>">?</a>
|
90 |
</td>
|
91 |
</tr>
|
92 |
<tr>
|
103 |
<?php $post_taxonomies = array_diff_key(get_taxonomies_by_object_type(array('post'), 'object'), array_flip(array('category', 'post_tag', 'post_format'))) ?>
|
104 |
<?php foreach ($post_taxonomies as $ctx): ?>
|
105 |
<tr class="post_taxonomy" data-type="<?php echo implode(' ', $ctx->object_type) ?>">
|
106 |
+
<th><nobr><?php echo $ctx->labels->name ?> <a href="#help" class="help" title="<?php _e('Enter taxonomy <b>'.$ctx->labels->name.'</b> terms IDs or Names.', 'pmxi_plugin') ?>">?</a></nobr></th>
|
107 |
+
<td>
|
108 |
+
<ol class="sortable no-margin">
|
109 |
+
<?php if (!empty($post['post_taxonomies'][$ctx->name])):
|
110 |
+
$taxonomies_hierarchy = json_decode($post['post_taxonomies'][$ctx->name]);
|
111 |
+
if (!empty($taxonomies_hierarchy) and is_array($taxonomies_hierarchy)): foreach ($taxonomies_hierarchy as $i => $cat) {
|
112 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
113 |
+
{
|
114 |
+
?>
|
115 |
+
<li id="item_<?php echo ($i+1); ?>">
|
116 |
+
<div class="drag-element"><input type="text" class="widefat" value="<?php echo $cat->xpath; ?>"/></div>
|
117 |
+
<?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, ($i+1)); ?>
|
118 |
+
</li>
|
119 |
+
<?php
|
120 |
+
}
|
121 |
+
}; else:?>
|
122 |
+
<li id="item_1"><div class="drag-element"><input type="text" class="widefat" value=""/></div></li>
|
123 |
+
<?php endif;
|
124 |
+
else: ?>
|
125 |
+
<li id="item_1"><div class="drag-element"><input type="text" class="widefat" value=""/></div></li>
|
126 |
+
<?php endif; ?>
|
127 |
+
</ol>
|
128 |
+
<input type="hidden" class="hierarhy-output" name="post_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['post_taxonomies'][$ctx->name]) ?>"/>
|
129 |
+
</td>
|
130 |
+
<td class="delim">
|
131 |
+
<a href="javascript:void(0);" class="icon-item add-new-ico"></a>
|
132 |
+
<a href="#help" class="help" title="<?php _e('Drag&Drop inputs to create taxonomies hierarchy', 'pmxi_plugin') ?>">?</a>
|
133 |
</td>
|
134 |
</tr>
|
135 |
+
<?php endforeach; ?>
|
136 |
</table>
|
137 |
</div>
|
138 |
</div>
|
165 |
<?php $page_taxonomies = get_taxonomies_by_object_type('page', 'object') ?>
|
166 |
<?php foreach ($page_taxonomies as $ctx): ?>
|
167 |
<tr class="page_taxonomy" data-type="<?php echo implode(' ', $ctx->object_type) ?>">
|
168 |
+
<th><nobr><?php echo $ctx->labels->name ?> <a href="#help" class="help" title="<?php _e('Enter taxonomy <b>'.$ctx->labels->name.'</b> terms IDs or Names.', 'pmxi_plugin') ?>">?</a></nobr></th>
|
169 |
+
<td>
|
170 |
+
<ol class="sortable no-margin">
|
171 |
+
<?php if (!empty($post['page_taxonomies'][$ctx->name])):
|
172 |
+
$taxonomies_hierarchy = json_decode($post['page_taxonomies'][$ctx->name]);
|
173 |
+
foreach ($taxonomies_hierarchy as $i => $cat) {
|
174 |
+
if (is_null($cat->parent_id) or empty($cat->parent_id))
|
175 |
+
{
|
176 |
+
?>
|
177 |
+
<li id="item_<?php echo ($i+1); ?>">
|
178 |
+
<div class="drag-element"><input type="text" class="widefat" value="<?php echo $cat->xpath; ?>"/></div>
|
179 |
+
<?php echo reverse_taxonomies_html($taxonomies_hierarchy, $cat->item_id, ($i+1)); ?>
|
180 |
+
</li>
|
181 |
+
<?php
|
182 |
+
}
|
183 |
+
}
|
184 |
+
else: ?>
|
185 |
+
<li id="item_1"><div class="drag-element"><input type="text" class="widefat" value=""/></div></li>
|
186 |
+
<?php endif; ?>
|
187 |
+
</ol>
|
188 |
+
<input type="hidden" class="hierarhy-output" name="page_taxonomies[<?php echo $ctx->name ?>]" value="<?php echo esc_attr($post['page_taxonomies'][$ctx->name]) ?>"/>
|
189 |
+
<!--input type="text" name="page_taxonomies[<?php echo $ctx->name ?>]" class="widefat" value="<?php echo esc_attr(isset($post['page_taxonomies'][$ctx->name]) ? $post['page_taxonomies'][$ctx->name] : '') ?>" /-->
|
190 |
+
</td>
|
191 |
<td class="delim">
|
192 |
+
<a href="javascript:void(0);" class="icon-item add-new-ico"></a>
|
193 |
+
<a href="#help" class="help" title="<?php _e('Drag&Drop inputs to create taxonomies hierarchy', 'pmxi_plugin') ?>">?</a>
|
194 |
</td>
|
195 |
</tr>
|
196 |
<?php endforeach ?>
|
343 |
<label for="is_keep_status"><?php _e('Keep status', 'pmxi_plugin') ?></label>
|
344 |
<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>
|
345 |
</div>
|
346 |
+
<div>
|
347 |
+
<input type="hidden" name="is_keep_content" value="0" />
|
348 |
+
<input type="checkbox" id="is_keep_content" name="is_keep_content" value="1" <?php echo $post['is_keep_content'] ? 'checked="checked"': '' ?> />
|
349 |
+
<label for="is_keep_content"><?php _e('Keep content', 'pmxi_plugin') ?></label>
|
350 |
+
<a href="#help" class="help" title="<?php _e('Re-run an importer to pull in one more custom field... without nuking their edits in the process..', 'pmxi_plugin') ?>">?</a>
|
351 |
+
</div>
|
352 |
<div>
|
353 |
<input type="hidden" name="is_keep_categories" value="0" />
|
354 |
<input type="checkbox" id="is_keep_categories" name="is_keep_categories" value="1" <?php echo $post['is_keep_categories'] ? 'checked="checked"': '' ?> />
|
393 |
</tr>
|
394 |
</table>
|
395 |
</form>
|
|
|
|
|
|
|
396 |
<script type="text/javascript">
|
397 |
(function($){$(function(){
|
398 |
$('select[name="custom_type"]').change(function () {
|
views/admin/import/process.php
CHANGED
@@ -3,4 +3,29 @@
|
|
3 |
<hr />
|
4 |
|
5 |
<p><?php _e('Importing may take some time. Please do not close browser or refresh the page untill process is complete.', 'pmxi_plugin') ?></p>
|
6 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
<hr />
|
4 |
|
5 |
<p><?php _e('Importing may take some time. Please do not close browser or refresh the page untill process is complete.', 'pmxi_plugin') ?></p>
|
6 |
+
</div>
|
7 |
+
|
8 |
+
<script type="text/javascript">
|
9 |
+
//<![CDATA[
|
10 |
+
(function($){
|
11 |
+
$('#status').each(function () {
|
12 |
+
var $this = $(this);
|
13 |
+
if ($this.html().match(/\.{3}$/)) {
|
14 |
+
var dots = 0;
|
15 |
+
var status = $this.html().replace(/\.{3}$/, '');
|
16 |
+
var interval ;
|
17 |
+
interval = setInterval(function () {
|
18 |
+
if ($this.html().match(new RegExp(status + '\\.{1,3}$', ''))) {
|
19 |
+
$this.html(status + '...'.substr(0, dots++ % 3 + 1));
|
20 |
+
} else {
|
21 |
+
clearInterval(interval);
|
22 |
+
}
|
23 |
+
}, 1000);
|
24 |
+
}
|
25 |
+
});
|
26 |
+
window.onbeforeunload = function () {
|
27 |
+
return 'WARNING:\nImport process in under way, leaving the page will interrupt\nthe operation and most likely to cause leftovers in posts.';
|
28 |
+
};
|
29 |
+
})(jQuery);
|
30 |
+
//]]>
|
31 |
+
</script>
|
views/admin/import/tag.php
CHANGED
@@ -8,5 +8,5 @@
|
|
8 |
</div>
|
9 |
</div>
|
10 |
<div class="clear"></div>
|
11 |
-
<div class="xml resetable"
|
12 |
</div>
|
8 |
</div>
|
9 |
</div>
|
10 |
<div class="clear"></div>
|
11 |
+
<div class="xml resetable"> <?php if (!empty($elements)) $this->render_xml_element($elements->item($tagno - 1), true); ?></div>
|
12 |
</div>
|
views/admin/manage/update.php
CHANGED
@@ -16,9 +16,6 @@
|
|
16 |
</p>
|
17 |
|
18 |
</form>
|
19 |
-
<div id="process" style="display:none;">
|
20 |
-
<?php include PMXI_Plugin::ROOT_DIR . '/views/admin/import/process.php'; ?>
|
21 |
-
</div>
|
22 |
<?php else: ?>
|
23 |
<div class="error">
|
24 |
<p><?php _e('Update feature is not available for this import since it has no external path linked.') ?></p>
|
16 |
</p>
|
17 |
|
18 |
</form>
|
|
|
|
|
|
|
19 |
<?php else: ?>
|
20 |
<div class="error">
|
21 |
<p><?php _e('Update feature is not available for this import since it has no external path linked.') ?></p>
|
views/admin/settings/index.php
CHANGED
@@ -40,6 +40,7 @@
|
|
40 |
<h3><?php _e('XML parsing filters', 'pmxi_plugin') ?></h3>
|
41 |
|
42 |
<div><?php printf(__('Filter XML contains HTML entities %s', 'pmxi_plugin'), '<input type="radio" name="html_entities" value="1" '.((!empty($post['html_entities'])) ? 'checked="checked"' : '').' /> Yes <input type="radio" name="html_entities" value="0" '.((empty($post['html_entities'])) ? 'checked="checked"' : '').' /> No') ?></div>
|
|
|
43 |
<p class="submit-buttons">
|
44 |
<?php wp_nonce_field('edit-settings', '_wpnonce_edit-settings') ?>
|
45 |
<input type="hidden" name="is_settings_submitted" value="1" />
|
40 |
<h3><?php _e('XML parsing filters', 'pmxi_plugin') ?></h3>
|
41 |
|
42 |
<div><?php printf(__('Filter XML contains HTML entities %s', 'pmxi_plugin'), '<input type="radio" name="html_entities" value="1" '.((!empty($post['html_entities'])) ? 'checked="checked"' : '').' /> Yes <input type="radio" name="html_entities" value="0" '.((empty($post['html_entities'])) ? 'checked="checked"' : '').' /> No') ?></div>
|
43 |
+
<div><?php printf(__('UTF-8 decode %s', 'pmxi_plugin'), '<input type="radio" name="utf8_decode" value="1" '.((!empty($post['utf8_decode'])) ? 'checked="checked"' : '').' /> Yes <input type="radio" name="utf8_decode" value="0" '.((empty($post['utf8_decode'])) ? 'checked="checked"' : '').' /> No') ?></div>
|
44 |
<p class="submit-buttons">
|
45 |
<?php wp_nonce_field('edit-settings', '_wpnonce_edit-settings') ?>
|
46 |
<input type="hidden" name="is_settings_submitted" value="1" />
|